1
0
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:
Nikita Popov
2021-12-25 21:51:29 +01:00
parent 046096f265
commit 2cf93032ee
7 changed files with 22 additions and 20 deletions

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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 &&

View File

@@ -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);

View File

@@ -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)

View File

@@ -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);

View File

@@ -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;
}