}
}
-static zend_always_inline int _zend_quick_get_constant(
+static zend_always_inline zend_constant* _zend_quick_get_constant(
const zval *key, uint32_t flags, int check_defined_only)
{
#ifndef HAVE_GCC_GLOBAL_REGS
ZVAL_UNDEF(EX_VAR(opline->result.var));
}
CACHE_PTR(opline->extended_value, ENCODE_SPECIAL_CACHE_NUM(zend_hash_num_elements(EG(zend_constants))));
- return FAILURE;
+ return NULL;
}
if (!check_defined_only) {
- ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), &c->value);
if (ZEND_CONSTANT_FLAGS(c) & CONST_DEPRECATED) {
zend_error(E_DEPRECATED, "Constant %s is deprecated", ZSTR_VAL(c->name));
if (EG(exception)) {
- return FAILURE;
+ return NULL;
}
- return SUCCESS;
+ return c;
}
}
CACHE_PTR(opline->extended_value, c);
- return SUCCESS;
+ return c;
}
-int ZEND_FASTCALL zend_jit_get_constant(const zval *key, uint32_t flags)
+zend_constant* ZEND_FASTCALL zend_jit_get_constant(const zval *key, uint32_t flags)
{
return _zend_quick_get_constant(key, flags, 0);
}
-int ZEND_FASTCALL zend_jit_check_constant(const zval *key)
+zend_constant* ZEND_FASTCALL zend_jit_check_constant(const zval *key)
{
return _zend_quick_get_constant(key, 0, 1);
}
| test r0, r0
if (exit_addr) {
if (smart_branch_opcode == ZEND_JMPNZ) {
- | jnz >3
- } else {
| jz >3
+ } else {
+ | jnz >3
}
| jmp &exit_addr
} else if (smart_branch_opcode) {
if (undefined_label != (uint32_t)-1) {
- | jnz =>undefined_label
+ | jz =>undefined_label
} else {
- | jnz >3
+ | jz >3
}
if (defined_label != (uint32_t)-1) {
| jmp =>defined_label
}
} else {
res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var);
- | jz >1
+ | jnz >1
|2:
| SET_ZVAL_TYPE_INFO res_addr, IS_FALSE
| jmp >3
return 1;
}
-static int zend_jit_fetch_constant(dasm_State **Dst, const zend_op *opline)
+static int zend_jit_fetch_constant(dasm_State **Dst,
+ const zend_op *opline,
+ const zend_op_array *op_array,
+ zend_ssa *ssa,
+ const zend_ssa_op *ssa_op)
{
zval *zv = RT_CONSTANT(opline, opline->op2) + 1;
zend_jit_addr res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var);
- zend_jit_addr const_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0);
+ zend_jit_addr const_addr = ZEND_ADDR_MEM_ZVAL(ZREG_R0, 0);
+ uint32_t res_info = RES_INFO();
| // c = CACHED_PTR(opline->extended_value);
| mov FCARG1a, EX->run_time_cache
- | mov FCARG1a, aword [FCARG1a + opline->extended_value]
+ | mov r0, aword [FCARG1a + opline->extended_value]
| // if (c != NULL)
- | test FCARG1a, FCARG1a
+ | test r0, r0
| jz >9
| // if (!IS_SPECIAL_CACHE_VAL(c))
- | test FCARG1a, CACHE_SPECIAL
+ | test r0, CACHE_SPECIAL
| jnz >9
- | // ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), &c->value); (no dup)
- | ZVAL_COPY_VALUE res_addr, MAY_BE_ANY, const_addr, MAY_BE_ANY, ZREG_R0, ZREG_FCARG2a
- | TRY_ADDREF MAY_BE_ANY, ah, FCARG2a
|8:
+ if ((res_info & MAY_BE_GUARD) && JIT_G(current_frame)) {
+ zend_jit_trace_stack *stack = JIT_G(current_frame)->stack;
+ uint32_t old_info = STACK_INFO(stack, EX_VAR_TO_NUM(opline->result.var));
+ int32_t exit_point;
+ const void *exit_addr = NULL;
+
+ SET_STACK_TYPE(stack, EX_VAR_TO_NUM(opline->result.var), IS_UNKNOWN, 1);
+ SET_STACK_REG(stack, EX_VAR_TO_NUM(opline->result.var), ZREG_ZVAL_COPY_R0);
+ exit_point = zend_jit_trace_get_exit_point(opline+1, 0);
+ SET_STACK_INFO(stack, EX_VAR_TO_NUM(opline->result.var), old_info);
+ exit_addr = zend_jit_trace_get_exit_addr(exit_point);
+ if (!exit_addr) {
+ return 0;
+ }
+ res_info &= ~MAY_BE_GUARD;
+ ssa->var_info[ssa_op->result_def].type &= ~MAY_BE_GUARD;
+
+ zend_uchar type = concrete_type(res_info);
+
+ if (type < IS_STRING) {
+ | IF_NOT_ZVAL_TYPE const_addr, type, &exit_addr
+ } else {
+ | GET_ZVAL_TYPE_INFO edx, const_addr
+ | IF_NOT_TYPE dl, type, &exit_addr
+ }
+ | ZVAL_COPY_VALUE_V res_addr, -1, const_addr, res_info, ZREG_R0, ZREG_R1
+ if (type < IS_STRING) {
+ | SET_ZVAL_TYPE_INFO res_addr, type
+ } else {
+ | SET_ZVAL_TYPE_INFO res_addr, edx
+ | TRY_ADDREF res_info, dh, r1
+ }
+ } else {
+ | // ZVAL_COPY_OR_DUP(EX_VAR(opline->result.var), &c->value); (no dup)
+ | ZVAL_COPY_VALUE res_addr, MAY_BE_ANY, const_addr, MAY_BE_ANY, ZREG_R0, ZREG_R1
+ | TRY_ADDREF MAY_BE_ANY, ah, r1
+ }
+
|.cold_code
|9:
| // SAVE_OPLINE();
| EXT_CALL zend_jit_get_constant, r0
| // ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
| test r0, r0
- | jz <8
+ | jnz <8
| jmp ->exception_handler
|.code