ce = NULL;
if (opline->op1_type == IS_UNUSED) {
op1_info = MAY_BE_OBJECT|MAY_BE_RC1|MAY_BE_RCN;
+ op1_addr = 0;
ce = op_array->scope;
} else {
op1_info = OP1_INFO();
+ if (!(op1_info & MAY_BE_OBJECT)) {
+ break;
+ }
+ op1_addr = OP1_REG_ADDR();
if (ssa->var_info && ssa->ops) {
zend_ssa_op *ssa_op = &ssa->ops[opline - op_array->opcodes];
if (ssa_op->op1_use >= 0) {
}
}
}
- if (!(op1_info & MAY_BE_OBJECT)) {
- break;
- }
if (!zend_jit_fetch_obj_read(&dasm_state, opline, op_array,
- op1_info, ce,
+ op1_info, op1_addr, ce,
zend_may_throw(opline, ssa_op, op_array, ssa))) {
goto jit_failure;
}
}
}
break;
+ case ZEND_FETCH_OBJ_FUNC_ARG:
+ if (!frame
+ || !frame->call
+ || !frame->call->func
+ || !TRACE_FRAME_IS_LAST_SEND_BY_VAL(frame->call)) {
+ break;
+ }
+ /* break missing intentionally */
+ case ZEND_FETCH_OBJ_R:
+ case ZEND_FETCH_OBJ_IS:
+ if (opline->op2_type != IS_CONST
+ || Z_TYPE_P(RT_CONSTANT(opline, opline->op2)) != IS_STRING
+ || Z_STRVAL_P(RT_CONSTANT(opline, opline->op2))[0] == '\0') {
+ break;
+ }
+ ADD_OP1_TRACE_GUARD();
+ break;
default:
break;
}
if (opline->op1_type == IS_UNUSED) {
op1_info = MAY_BE_OBJECT|MAY_BE_RC1|MAY_BE_RCN;
ce = op_array->scope;
+ op1_addr = 0;
} else {
op1_info = OP1_INFO();
+ if (!(op1_info & MAY_BE_OBJECT)) {
+ break;
+ }
+ op1_addr = OP1_REG_ADDR();
+ if (orig_op1_type != IS_UNKNOWN
+ && (orig_op1_type & IS_TRACE_REFERENCE)) {
+ if (!zend_jit_fetch_reference(&dasm_state, opline, orig_op1_type, &op1_info, &op1_addr, 1)) {
+ goto jit_failure;
+ }
+ } else {
+ CHECK_OP1_TRACE_TYPE();
+ }
if (ssa->var_info && ssa->ops) {
if (ssa_op->op1_use >= 0) {
zend_ssa_var_info *op1_ssa = ssa->var_info + ssa_op->op1_use;
}
}
}
- if (!(op1_info & MAY_BE_OBJECT)) {
- break;
- }
if (!zend_jit_fetch_obj_read(&dasm_state, opline, op_array,
- op1_info, ce,
+ op1_info, op1_addr, ce,
zend_may_throw(opline, ssa_op, op_array, ssa))) {
goto jit_failure;
}
return 0;
}
-static int zend_jit_fetch_obj_read(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array, uint32_t op1_info, zend_class_entry *ce, int may_throw)
+static int zend_jit_fetch_obj_read(dasm_State **Dst, const zend_op *opline, const zend_op_array *op_array, uint32_t op1_info, zend_jit_addr op1_addr, zend_class_entry *ce, int may_throw)
{
zval *member;
uint32_t offset;
zend_bool may_be_dynamic = 1;
- zend_jit_addr op1_addr = 0, orig_op1_addr = 0;
zend_jit_addr res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var);
zend_jit_addr this_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, offsetof(zend_execute_data, This));
zend_jit_addr prop_addr;
if (opline->op1_type == IS_UNUSED) {
| GET_ZVAL_PTR FCARG1a, this_addr
} else {
- op1_addr = orig_op1_addr = OP1_ADDR();
if (op1_info & MAY_BE_REF) {
- | LOAD_ZVAL_ADDR r0, op1_addr
- | ZVAL_DEREF r0, op1_info
- op1_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R0, 0);
+ | LOAD_ZVAL_ADDR FCARG1a, op1_addr
+ | ZVAL_DEREF FCARG1a, op1_info
+ op1_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0);
}
if (op1_info & ((MAY_BE_UNDEF|MAY_BE_ANY)- MAY_BE_OBJECT)) {
if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) {
if (opline->opcode != ZEND_FETCH_OBJ_IS) {
| SAVE_VALID_OPLINE opline, r1
if (op1_info & MAY_BE_UNDEF) {
+ zend_jit_addr orig_op1_addr = OP1_ADDR();
+
if (op1_info & MAY_BE_ANY) {
| IF_NOT_ZVAL_TYPE op1_addr, IS_UNDEF, >1
}
| mov FCARG1d, opline->op1.var
| EXT_CALL zend_jit_undefined_op_helper, r0
|1:
+ | LOAD_ZVAL_ADDR FCARG1a, orig_op1_addr
+ } else {
+ | LOAD_ZVAL_ADDR FCARG1a, op1_addr
}
- | LOAD_ZVAL_ADDR FCARG1a, orig_op1_addr
| LOAD_ADDR FCARG2a, Z_STRVAL_P(member)
| EXT_CALL zend_jit_invalid_property_read, r0
}