mirror of
https://github.com/php/php-src.git
synced 2026-04-03 14:12:38 +02:00
Sink op_array scope case into get_class_entry()
This handles references to the current class through its name rather than self (and for cases where is is not linked yet and thus not covered by the context lookup). Rather than handling this only for FETCH_CLASS_CONSTANT optimization, integrate this into the generic get_class_entry() utility.
This commit is contained in:
@@ -293,7 +293,7 @@ static inline bool can_elide_return_type_check(
|
||||
ZEND_TYPE_FOREACH(arg_info->type, single_type) {
|
||||
if (ZEND_TYPE_HAS_NAME(*single_type)) {
|
||||
zend_string *lcname = zend_string_tolower(ZEND_TYPE_NAME(*single_type));
|
||||
zend_class_entry *ce = zend_optimizer_get_class_entry(script, lcname);
|
||||
zend_class_entry *ce = zend_optimizer_get_class_entry(script, op_array, lcname);
|
||||
zend_string_release(lcname);
|
||||
bool result = ce && safe_instanceof(use_info->ce, ce);
|
||||
if (result == !is_intersection) {
|
||||
|
||||
@@ -160,7 +160,7 @@ static bool is_allocation_def(zend_op_array *op_array, zend_ssa *ssa, int def, i
|
||||
/* objects with destructors should escape */
|
||||
if (opline->op1_type == IS_CONST) {
|
||||
zend_class_entry *ce = zend_optimizer_get_class_entry(
|
||||
script, Z_STR_P(CRT_CONSTANT(opline->op1)+1));
|
||||
script, op_array, Z_STR_P(CRT_CONSTANT(opline->op1)+1));
|
||||
uint32_t forbidden_flags =
|
||||
/* These flags will always cause an exception */
|
||||
ZEND_ACC_IMPLICIT_ABSTRACT_CLASS | ZEND_ACC_EXPLICIT_ABSTRACT_CLASS
|
||||
@@ -228,7 +228,7 @@ static bool is_local_def(zend_op_array *op_array, zend_ssa *ssa, int def, int va
|
||||
/* objects with destructors should escape */
|
||||
if (opline->op1_type == IS_CONST) {
|
||||
zend_class_entry *ce = zend_optimizer_get_class_entry(
|
||||
script, Z_STR_P(CRT_CONSTANT(opline->op1)+1));
|
||||
script, op_array, Z_STR_P(CRT_CONSTANT(opline->op1)+1));
|
||||
if (ce && !ce->create_object && !ce->constructor &&
|
||||
!ce->destructor && !ce->__get && !ce->__set && !ce->parent) {
|
||||
return 1;
|
||||
|
||||
@@ -179,15 +179,10 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx)
|
||||
if (opline->op1_type == IS_CONST &&
|
||||
Z_TYPE(ZEND_OP1_LITERAL(opline)) == IS_STRING) {
|
||||
/* for A::B */
|
||||
if (op_array->scope &&
|
||||
zend_string_equals_ci(Z_STR(ZEND_OP1_LITERAL(opline)), op_array->scope->name)) {
|
||||
ce = op_array->scope;
|
||||
} else {
|
||||
ce = zend_optimizer_get_class_entry(
|
||||
ctx->script, Z_STR(op_array->literals[opline->op1.constant + 1]));
|
||||
if (!ce) {
|
||||
break;
|
||||
}
|
||||
ce = zend_optimizer_get_class_entry(
|
||||
ctx->script, op_array, Z_STR(op_array->literals[opline->op1.constant + 1]));
|
||||
if (!ce) {
|
||||
break;
|
||||
}
|
||||
} else if (op_array->scope &&
|
||||
opline->op1_type == IS_UNUSED &&
|
||||
|
||||
@@ -2143,7 +2143,8 @@ static uint32_t zend_convert_type(const zend_script *script, zend_type type, zen
|
||||
* we use a plain object type for class unions. */
|
||||
if (ZEND_TYPE_HAS_NAME(type)) {
|
||||
zend_string *lcname = zend_string_tolower(ZEND_TYPE_NAME(type));
|
||||
*pce = zend_optimizer_get_class_entry(script, lcname);
|
||||
// TODO: Pass through op_array.
|
||||
*pce = zend_optimizer_get_class_entry(script, NULL, lcname);
|
||||
zend_string_release_ex(lcname, 0);
|
||||
}
|
||||
}
|
||||
@@ -2231,7 +2232,7 @@ static zend_property_info *zend_fetch_static_prop_info(const zend_script *script
|
||||
}
|
||||
} else if (opline->op2_type == IS_CONST) {
|
||||
zval *zv = CRT_CONSTANT(opline->op2);
|
||||
ce = zend_optimizer_get_class_entry(script, Z_STR_P(zv + 1));
|
||||
ce = zend_optimizer_get_class_entry(script, op_array, Z_STR_P(zv + 1));
|
||||
}
|
||||
|
||||
if (ce) {
|
||||
@@ -3015,7 +3016,7 @@ static zend_always_inline zend_result _zend_update_type_info(
|
||||
} else if (opline->op2_type == IS_CONST) {
|
||||
zval *zv = CRT_CONSTANT(opline->op2);
|
||||
if (Z_TYPE_P(zv) == IS_STRING) {
|
||||
ce = zend_optimizer_get_class_entry(script, Z_STR_P(zv+1));
|
||||
ce = zend_optimizer_get_class_entry(script, op_array, Z_STR_P(zv+1));
|
||||
UPDATE_SSA_OBJ_TYPE(ce, 0, ssa_op->result_def);
|
||||
} else {
|
||||
UPDATE_SSA_OBJ_TYPE(NULL, 0, ssa_op->result_def);
|
||||
@@ -3027,7 +3028,7 @@ static zend_always_inline zend_result _zend_update_type_info(
|
||||
case ZEND_NEW:
|
||||
tmp = MAY_BE_RC1|MAY_BE_RCN|MAY_BE_OBJECT;
|
||||
if (opline->op1_type == IS_CONST &&
|
||||
(ce = zend_optimizer_get_class_entry(script, Z_STR_P(CRT_CONSTANT(opline->op1)+1))) != NULL) {
|
||||
(ce = zend_optimizer_get_class_entry(script, op_array, Z_STR_P(CRT_CONSTANT(opline->op1)+1))) != NULL) {
|
||||
UPDATE_SSA_OBJ_TYPE(ce, 0, ssa_op->result_def);
|
||||
} else if ((t1 & MAY_BE_CLASS) && ssa_op->op1_use >= 0 && ssa_var_info[ssa_op->op1_use].ce) {
|
||||
UPDATE_SSA_OBJ_TYPE(ssa_var_info[ssa_op->op1_use].ce, ssa_var_info[ssa_op->op1_use].is_instanceof, ssa_op->result_def);
|
||||
|
||||
@@ -694,7 +694,8 @@ void zend_optimizer_shift_jump(zend_op_array *op_array, zend_op *opline, uint32_
|
||||
}
|
||||
}
|
||||
|
||||
zend_class_entry *zend_optimizer_get_class_entry(const zend_script *script, zend_string *lcname) {
|
||||
zend_class_entry *zend_optimizer_get_class_entry(
|
||||
const zend_script *script, const zend_op_array *op_array, zend_string *lcname) {
|
||||
zend_class_entry *ce = script ? zend_hash_find_ptr(&script->class_table, lcname) : NULL;
|
||||
if (ce) {
|
||||
return ce;
|
||||
@@ -705,6 +706,10 @@ zend_class_entry *zend_optimizer_get_class_entry(const zend_script *script, zend
|
||||
return ce;
|
||||
}
|
||||
|
||||
if (op_array && op_array->scope && zend_string_equals_ci(op_array->scope->name, lcname)) {
|
||||
return op_array->scope;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -713,7 +718,7 @@ static zend_class_entry *get_class_entry_from_op1(
|
||||
if (opline->op1_type == IS_CONST) {
|
||||
zval *op1 = CRT_CONSTANT(opline->op1);
|
||||
if (Z_TYPE_P(op1) == IS_STRING) {
|
||||
return zend_optimizer_get_class_entry(script, Z_STR_P(op1 + 1));
|
||||
return zend_optimizer_get_class_entry(script, op_array, Z_STR_P(op1 + 1));
|
||||
}
|
||||
} else if (opline->op1_type == IS_UNUSED && op_array->scope
|
||||
&& !(op_array->scope->ce_flags & ZEND_ACC_TRAIT)
|
||||
|
||||
@@ -96,7 +96,8 @@ bool zend_optimizer_replace_by_const(zend_op_array *op_array,
|
||||
uint32_t var,
|
||||
zval *val);
|
||||
zend_op *zend_optimizer_get_loop_var_def(const zend_op_array *op_array, zend_op *free_opline);
|
||||
zend_class_entry *zend_optimizer_get_class_entry(const zend_script *script, zend_string *lcname);
|
||||
zend_class_entry *zend_optimizer_get_class_entry(
|
||||
const zend_script *script, const zend_op_array *op_array, zend_string *lcname);
|
||||
|
||||
void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx);
|
||||
void zend_optimizer_pass3(zend_op_array *op_array, zend_optimizer_ctx *ctx);
|
||||
|
||||
@@ -527,7 +527,7 @@ static void place_essa_pis(
|
||||
(opline-1)->op2_type == IS_CONST) {
|
||||
int var = EX_VAR_TO_NUM((opline-1)->op1.var);
|
||||
zend_string *lcname = Z_STR_P(CRT_CONSTANT_EX(op_array, (opline-1), (opline-1)->op2) + 1);
|
||||
zend_class_entry *ce = zend_optimizer_get_class_entry(script, lcname);
|
||||
zend_class_entry *ce = zend_optimizer_get_class_entry(script, op_array, lcname);
|
||||
if (!ce) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user