Skip to content

Commit 70a0b18

Browse files
shqkingdstogov
authored andcommitted
Support failed JIT test case: assign_026.phpt
For statement "$a = new stdClass;", opcode NEW is used and JIT would invoke the original handler at runtime. Our major changes are made to support statements "$a->a=1;" and "$a->b=2;" where opcode ASSIGN_OBJ are used.
1 parent 5538a4c commit 70a0b18

File tree

1 file changed

+151
-1
lines changed

1 file changed

+151
-1
lines changed

ext/opcache/jit/zend_jit_arm64.dasc

Lines changed: 151 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6071,7 +6071,157 @@ static int zend_jit_assign_obj(dasm_State **Dst,
60716071
zend_jit_addr prop_addr;
60726072
bool needs_slow_path = 0;
60736073

6074-
| brk #0 // TODO
6074+
if (RETURN_VALUE_USED(opline)) {
6075+
res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var);
6076+
}
6077+
6078+
ZEND_ASSERT(opline->op2_type == IS_CONST);
6079+
ZEND_ASSERT(op1_info & MAY_BE_OBJECT);
6080+
6081+
member = RT_CONSTANT(opline, opline->op2);
6082+
ZEND_ASSERT(Z_TYPE_P(member) == IS_STRING && Z_STRVAL_P(member)[0] != '\0');
6083+
name = Z_STR_P(member);
6084+
prop_info = zend_get_known_property_info(op_array, ce, name, opline->op1_type == IS_UNUSED, op_array->filename);
6085+
6086+
if (opline->op1_type == IS_UNUSED || use_this) {
6087+
| brk #0 // TODO
6088+
} else {
6089+
if (opline->op1_type == IS_VAR
6090+
&& (op1_info & MAY_BE_INDIRECT)
6091+
&& Z_REG(op1_addr) == ZREG_FP) {
6092+
| brk #0 // TODO
6093+
|1:
6094+
op1_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1x, 0);
6095+
}
6096+
if (op1_info & MAY_BE_REF) {
6097+
if (Z_REG(op1_addr) != ZREG_FCARG1x || Z_OFFSET(op1_addr) != 0) {
6098+
| LOAD_ZVAL_ADDR FCARG1x, op1_addr
6099+
}
6100+
| ZVAL_DEREF FCARG1x, op1_info, TMP1w
6101+
op1_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1x, 0);
6102+
}
6103+
if (op1_info & ((MAY_BE_UNDEF|MAY_BE_ANY)- MAY_BE_OBJECT)) {
6104+
if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) {
6105+
int32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM);
6106+
const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point);
6107+
6108+
if (!exit_addr) {
6109+
return 0;
6110+
}
6111+
| brk #0 // TODO
6112+
} else {
6113+
| IF_NOT_ZVAL_TYPE op1_addr, IS_OBJECT, >1, TMP1w, TMP2
6114+
|.cold_code
6115+
|1:
6116+
| brk #0 // TODO
6117+
|.code
6118+
}
6119+
}
6120+
| GET_ZVAL_PTR FCARG1x, op1_addr, TMP1
6121+
}
6122+
6123+
if (!prop_info && trace_ce && (trace_ce->ce_flags & ZEND_ACC_IMMUTABLE)) {
6124+
prop_info = zend_get_known_property_info(op_array, trace_ce, name, opline->op1_type == IS_UNUSED, op_array->filename);
6125+
prop_info = zend_get_known_property_info(op_array, trace_ce, name, opline->op1_type == IS_UNUSED, op_array->filename);
6126+
if (prop_info) {
6127+
ce = trace_ce;
6128+
ce_is_instanceof = 0;
6129+
if (!(op1_info & MAY_BE_CLASS_GUARD)) {
6130+
if (!zend_jit_class_guard(Dst, opline, trace_ce)) {
6131+
return 0;
6132+
}
6133+
if (ssa->var_info && ssa_op->op1_use >= 0) {
6134+
ssa->var_info[ssa_op->op1_use].type |= MAY_BE_CLASS_GUARD;
6135+
ssa->var_info[ssa_op->op1_use].ce = ce;
6136+
ssa->var_info[ssa_op->op1_use].is_instanceof = ce_is_instanceof;
6137+
}
6138+
if (ssa->var_info && ssa_op->op1_def >= 0) {
6139+
ssa->var_info[ssa_op->op1_def].type |= MAY_BE_CLASS_GUARD;
6140+
ssa->var_info[ssa_op->op1_def].ce = ce;
6141+
ssa->var_info[ssa_op->op1_def].is_instanceof = ce_is_instanceof;
6142+
}
6143+
}
6144+
}
6145+
}
6146+
6147+
if (!prop_info) {
6148+
needs_slow_path = 1;
6149+
6150+
| ldr REG0, EX->run_time_cache
6151+
| LOAD_32BIT_VAL TMP1w, opline->extended_value
6152+
| add TMP1, REG0, TMP1
6153+
| ldr REG2, [TMP1]
6154+
| ldr TMP1, [FCARG1x, #offsetof(zend_object, ce)]
6155+
| cmp REG2, TMP1
6156+
| bne >5
6157+
if (!ce || ce_is_instanceof || (ce->ce_flags & ZEND_ACC_HAS_TYPE_HINTS)) {
6158+
| brk #0 // TODO
6159+
}
6160+
| brk #0 // TODO
6161+
prop_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1x, 0);
6162+
if (!ce || ce_is_instanceof || (ce->ce_flags & ZEND_ACC_HAS_TYPE_HINTS)) {
6163+
| brk #0 // TODO
6164+
}
6165+
} else {
6166+
prop_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1x, prop_info->offset);
6167+
| brk #0 // TODO
6168+
}
6169+
6170+
if (!prop_info || !ZEND_TYPE_IS_SET(prop_info->type)) {
6171+
// value = zend_assign_to_variable(property_val, value, OP_DATA_TYPE, EX_USES_STRICT_TYPES());
6172+
if (opline->result_type == IS_UNUSED) {
6173+
if (!zend_jit_assign_to_variable_call(Dst, opline, prop_addr, prop_addr, -1, -1, (opline+1)->op1_type, val_addr, val_info, res_addr, 0)) {
6174+
return 0;
6175+
}
6176+
} else {
6177+
if (!zend_jit_assign_to_variable(Dst, opline, prop_addr, prop_addr, -1, -1, (opline+1)->op1_type, val_addr, val_info, res_addr, 0)) {
6178+
return 0;
6179+
}
6180+
}
6181+
}
6182+
6183+
if (needs_slow_path) {
6184+
|.cold_code
6185+
|5:
6186+
| SET_EX_OPLINE opline, REG0
6187+
| // value = zobj->handlers->write_property(zobj, name, value, CACHE_ADDR(opline->extended_value));
6188+
| LOAD_ADDR FCARG2x, name
6189+
6190+
| LOAD_ZVAL_ADDR CARG3, val_addr
6191+
| ldr CARG4, EX->run_time_cache
6192+
| LOAD_32BIT_VAL TMP1w, opline->extended_value
6193+
| add CARG4, CARG4, TMP1
6194+
if (RETURN_VALUE_USED(opline)) {
6195+
| brk #0 // TODO
6196+
| LOAD_ZVAL_ADDR CARG5, res_addr
6197+
} else {
6198+
| mov CARG5, xzr
6199+
}
6200+
6201+
| EXT_CALL zend_jit_assign_obj_helper, REG0
6202+
6203+
if (val_info & (MAY_BE_REF|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)) {
6204+
val_info |= MAY_BE_RC1|MAY_BE_RCN;
6205+
}
6206+
6207+
|8:
6208+
| // FREE_OP_DATA();
6209+
| FREE_OP (opline+1)->op1_type, (opline+1)->op1, val_info, 0, opline
6210+
| b >9
6211+
|.code
6212+
}
6213+
6214+
|9:
6215+
if (opline->op1_type != IS_UNUSED && !use_this && !op1_indirect) {
6216+
| FREE_OP opline->op1_type, opline->op1, op1_info, 1, opline
6217+
}
6218+
6219+
if (may_throw) {
6220+
if (!zend_jit_check_exception(Dst)) {
6221+
return 0;
6222+
}
6223+
}
6224+
60756225
return 1;
60766226
}
60776227

0 commit comments

Comments
 (0)