mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
JIT: Handle typed refs in assign dim
This commit is contained in:
parent
e7335eb420
commit
fe6c420b02
5 changed files with 48 additions and 7 deletions
|
@ -612,8 +612,6 @@ static zend_never_inline ZEND_COLD void zend_throw_access_uninit_prop_by_ref_err
|
|||
zend_get_unmangled_property_name(prop->name));
|
||||
}
|
||||
|
||||
static zend_never_inline zend_bool zend_verify_ref_array_assignable(zend_reference *ref);
|
||||
|
||||
/* this should modify object only if it's empty */
|
||||
static zend_never_inline ZEND_COLD void ZEND_FASTCALL zend_throw_non_object_error(zval *object, zval *property OPLINE_DC EXECUTE_DATA_DC)
|
||||
{
|
||||
|
@ -2531,9 +2529,8 @@ static zend_always_inline zend_bool check_type_array_assignable(zend_type type)
|
|||
return ZEND_TYPE_IS_MASK(type) && (ZEND_TYPE_MASK(type) & (MAY_BE_ITERABLE|MAY_BE_ARRAY));
|
||||
}
|
||||
|
||||
/* Checks whether an array can be assigned to the reference. Returns conflicting property if
|
||||
* assignment is not possible, NULL otherwise. */
|
||||
static zend_never_inline zend_bool zend_verify_ref_array_assignable(zend_reference *ref) {
|
||||
/* Checks whether an array can be assigned to the reference. Throws error if not assignable. */
|
||||
ZEND_API zend_bool zend_verify_ref_array_assignable(zend_reference *ref) {
|
||||
zend_property_info *prop;
|
||||
ZEND_ASSERT(ZEND_REF_HAS_TYPE_SOURCES(ref));
|
||||
ZEND_REF_FOREACH_TYPE_SOURCES(ref, prop) {
|
||||
|
|
|
@ -64,6 +64,7 @@ ZEND_API zend_bool zend_verify_scalar_type_hint(uint32_t type_mask, zval *arg, z
|
|||
ZEND_API ZEND_COLD void zend_verify_arg_error(
|
||||
const zend_function *zf, const zend_arg_info *arg_info,
|
||||
int arg_num, void **cache_slot, zval *value);
|
||||
ZEND_API zend_bool zend_verify_ref_array_assignable(zend_reference *ref);
|
||||
|
||||
#define ZEND_REF_TYPE_SOURCES(ref) \
|
||||
(ref)->sources
|
||||
|
|
|
@ -444,6 +444,7 @@ static int zend_jit_disasm_init(void)
|
|||
REGISTER_HELPER(zend_jit_assign_op_to_typed_ref);
|
||||
REGISTER_HELPER(zend_jit_only_vars_by_reference);
|
||||
REGISTER_HELPER(zend_jit_invalid_array_access);
|
||||
REGISTER_HELPER(zend_jit_prepare_assign_dim_ref);
|
||||
REGISTER_HELPER(zend_runtime_jit);
|
||||
REGISTER_HELPER(zend_jit_hot_func);
|
||||
#undef REGISTER_HELPER
|
||||
|
|
|
@ -1465,3 +1465,15 @@ static void ZEND_FASTCALL zend_jit_invalid_array_access(zval *container)
|
|||
const char *type = Z_ISUNDEF_P(container) ? "null" : zend_zval_type_name(container);
|
||||
zend_error(E_WARNING, "Trying to access array offset on value of type %s", type);
|
||||
}
|
||||
|
||||
static zval * ZEND_FASTCALL zend_jit_prepare_assign_dim_ref(zval *ref) {
|
||||
zval *val = Z_REFVAL_P(ref);
|
||||
if (Z_TYPE_P(val) <= IS_FALSE) {
|
||||
if (ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(ref))
|
||||
&& !zend_verify_ref_array_assignable(Z_REF_P(ref))) {
|
||||
return NULL;
|
||||
}
|
||||
ZVAL_ARR(val, zend_new_array(8));
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
|
|
@ -4610,7 +4610,21 @@ static int zend_jit_assign_dim(dasm_State **Dst, const zend_op *opline, const ze
|
|||
|
||||
if (op1_info & MAY_BE_REF) {
|
||||
| LOAD_ZVAL_ADDR FCARG1a, op1_addr
|
||||
| ZVAL_DEREF FCARG1a, op1_info
|
||||
| IF_NOT_Z_TYPE FCARG1a, IS_REFERENCE, >1
|
||||
| GET_Z_PTR FCARG2a, FCARG1a
|
||||
| IF_NOT_TYPE byte [FCARG2a + offsetof(zend_reference, val) + offsetof(zval, u1.v.type)], IS_ARRAY, >2
|
||||
| lea FCARG1a, [FCARG2a + offsetof(zend_reference, val)]
|
||||
| jmp >3
|
||||
|.cold_code
|
||||
|2:
|
||||
| SAVE_VALID_OPLINE opline
|
||||
| EXT_CALL zend_jit_prepare_assign_dim_ref, r0
|
||||
| test r0, r0
|
||||
| jz ->exception_handler_undef
|
||||
| mov FCARG1a, r0
|
||||
| jmp >1
|
||||
|.code
|
||||
|1:
|
||||
op1_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0);
|
||||
}
|
||||
|
||||
|
@ -4618,6 +4632,7 @@ static int zend_jit_assign_dim(dasm_State **Dst, const zend_op *opline, const ze
|
|||
if (op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF) - MAY_BE_ARRAY)) {
|
||||
| IF_NOT_ZVAL_TYPE op1_addr, IS_ARRAY, >7
|
||||
}
|
||||
|3:
|
||||
| SEPARATE_ARRAY op1_addr, op1_info, 1
|
||||
} else if (op1_info & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE)) {
|
||||
if (op1_info & (MAY_BE_ANY-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_ARRAY))) {
|
||||
|
@ -4821,7 +4836,21 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, const
|
|||
|
||||
if (op1_info & MAY_BE_REF) {
|
||||
| LOAD_ZVAL_ADDR FCARG1a, op1_addr
|
||||
| ZVAL_DEREF FCARG1a, op1_info
|
||||
| IF_NOT_Z_TYPE FCARG1a, IS_REFERENCE, >1
|
||||
| GET_Z_PTR FCARG2a, FCARG1a
|
||||
| IF_NOT_TYPE byte [FCARG2a + offsetof(zend_reference, val) + offsetof(zval, u1.v.type)], IS_ARRAY, >2
|
||||
| lea FCARG1a, [FCARG2a + offsetof(zend_reference, val)]
|
||||
| jmp >3
|
||||
|.cold_code
|
||||
|2:
|
||||
| SAVE_VALID_OPLINE opline
|
||||
| EXT_CALL zend_jit_prepare_assign_dim_ref, r0
|
||||
| test r0, r0
|
||||
| jz ->exception_handler_undef
|
||||
| mov FCARG1a, r0
|
||||
| jmp >1
|
||||
|.code
|
||||
|1:
|
||||
op1_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, 0);
|
||||
}
|
||||
|
||||
|
@ -4829,6 +4858,7 @@ static int zend_jit_assign_dim_op(dasm_State **Dst, const zend_op *opline, const
|
|||
if (op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF) - MAY_BE_ARRAY)) {
|
||||
| IF_NOT_ZVAL_TYPE op1_addr, IS_ARRAY, >7
|
||||
}
|
||||
|3:
|
||||
| SEPARATE_ARRAY op1_addr, op1_info, 1
|
||||
}
|
||||
if (op1_info & (MAY_BE_UNDEF|MAY_BE_NULL|MAY_BE_FALSE)) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue