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)
{
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) {
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;
+}
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);
}
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))) {
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);
}
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)) {