diff --git a/Zend/tests/lazy_objects/array_walk.phpt b/Zend/tests/lazy_objects/array_walk.phpt new file mode 100644 index 00000000000..afee146025c --- /dev/null +++ b/Zend/tests/lazy_objects/array_walk.phpt @@ -0,0 +1,36 @@ +--TEST-- +Lazy Objects: array_walk() +--FILE-- +newLazyProxy(function () { + return new C(); +}); + +array_walk($obj, function (&$value, $key) { + try { + $value = 'string'; + } catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + $value = 2; +}); + +var_dump($obj); + +?> +--EXPECTF-- +TypeError: Cannot assign string to reference held by property C::$a of type int +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (1) { + ["a"]=> + int(2) + } +} diff --git a/Zend/tests/lazy_objects/oss_fuzz_71446.phpt b/Zend/tests/lazy_objects/oss_fuzz_71446.phpt new file mode 100644 index 00000000000..ae2db55c73f --- /dev/null +++ b/Zend/tests/lazy_objects/oss_fuzz_71446.phpt @@ -0,0 +1,22 @@ +--TEST-- +oss-fuzz #71446 +--FILE-- +newLazyProxy(function() { + $c = new C; + return $c; +}); + +serialize($obj); +?> +--EXPECTF-- diff --git a/Zend/tests/lazy_objects/serialize___sleep.phpt b/Zend/tests/lazy_objects/serialize___sleep.phpt new file mode 100644 index 00000000000..d21f0fe09c9 --- /dev/null +++ b/Zend/tests/lazy_objects/serialize___sleep.phpt @@ -0,0 +1,42 @@ +--TEST-- +Lazy Objects: serialize with __sleep fetches property info from the real instance +--FILE-- +newLazyProxy(function() { + $c = new C; + return $c; +}); + +var_dump(serialize($obj)); + +print "Init on serialize and failed initialization\n"; + +$obj = $reflector->newLazyProxy(function() { + throw new \Exception('initializer'); +}); + +try { + var_dump(serialize($obj)); +} catch (Exception $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); +} + +?> +--EXPECTF-- +Init on serialize and successful initialization +string(27) "O:1:"C":1:{s:4:"%0C%0b";i:1;}" +Init on serialize and failed initialization +Exception: initializer diff --git a/Zend/tests/lazy_objects/typed_properties_001.phpt b/Zend/tests/lazy_objects/typed_properties_001.phpt new file mode 100644 index 00000000000..1f457531d87 --- /dev/null +++ b/Zend/tests/lazy_objects/typed_properties_001.phpt @@ -0,0 +1,37 @@ +--TEST-- +Typed property assignment by ref with variable name on proxy +--FILE-- +newLazyProxy(function () { + return new Test(); +}); +$ref = "foobar"; +try { + $test->$name =& $ref; +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} +var_dump($test); + +?> +--EXPECTF-- +Cannot assign string to property Test::$prop of type int +lazy proxy object(Test)#%d (1) { + ["instance"]=> + object(Test)#%d (0) { + ["prop"]=> + uninitialized(int) + } +} diff --git a/Zend/tests/lazy_objects/typed_properties_002.phpt b/Zend/tests/lazy_objects/typed_properties_002.phpt new file mode 100644 index 00000000000..528605246a9 --- /dev/null +++ b/Zend/tests/lazy_objects/typed_properties_002.phpt @@ -0,0 +1,60 @@ +--TEST-- +Typed property assignment by ref with variable name on proxy +--FILE-- +$b =& $obj->$a; + try { + $obj->$a = new B; + } catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + try { + $obj->$b = new A; + } catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + $obj->$a = new C; + unset($obj->$a); + $obj->$b = new B; +} + +$reflector = new ReflectionClass(Test::class); +$obj = $reflector->newLazyProxy(function () { + return new Test(new C, new C); +}); + +test($obj, 'a', 'b'); + +var_dump($obj); + +?> +--EXPECTF-- +TypeError: Cannot assign B to property Test::$a of type I +TypeError: Cannot assign A to property Test::$b of type J +lazy proxy object(Test)#%d (1) { + ["instance"]=> + object(Test)#%d (1) { + ["a"]=> + uninitialized(I) + ["b"]=> + object(B)#%d (0) { + } + } +} diff --git a/Zend/tests/lazy_objects/typed_properties_003.phpt b/Zend/tests/lazy_objects/typed_properties_003.phpt new file mode 100644 index 00000000000..af47e54bc3f --- /dev/null +++ b/Zend/tests/lazy_objects/typed_properties_003.phpt @@ -0,0 +1,44 @@ +--TEST-- +Typed property assign op cached +--FILE-- +$prop += 1; +} +function pre($obj, $prop) { + return ++$obj->$prop; +} +function post($obj, $prop) { + return $obj->$prop++; +} + +$reflector = new ReflectionClass(Test::class); +$obj = $reflector->newLazyProxy(function () { + return new Test(); +}); + +op($obj, 'prop'); +op($obj, 'prop'); + +pre($obj, 'prop'); +pre($obj, 'prop'); + +post($obj, 'prop'); +post($obj, 'prop'); + +var_dump($obj); + +?> +--EXPECTF-- +lazy proxy object(Test)#%d (1) { + ["instance"]=> + object(Test)#%d (1) { + ["prop"]=> + int(6) + } +} diff --git a/Zend/tests/lazy_objects/typed_properties_004.phpt b/Zend/tests/lazy_objects/typed_properties_004.phpt new file mode 100644 index 00000000000..d8474a769f8 --- /dev/null +++ b/Zend/tests/lazy_objects/typed_properties_004.phpt @@ -0,0 +1,45 @@ +--TEST-- +Lazy Objects: Foreach by ref over typed properties +--FILE-- +_b; return $value; } + } +} + +$reflector = new ReflectionClass(C::class); +$obj = $reflector->newLazyProxy(function () { + return new C(); +}); + +foreach ($obj as $key => &$value) { + var_dump($key); + try { + $value = 'string'; + } catch (Error $e) { + printf("%s: %s\n", $e::class, $e->getMessage()); + } + $value = 2; +} + +var_dump($obj); + +?> +--EXPECTF-- +string(1) "a" +TypeError: Cannot assign string to reference held by property C::$a of type int +string(1) "b" +TypeError: Cannot assign string to reference held by property C::$_b of type int +lazy proxy object(C)#%d (1) { + ["instance"]=> + object(C)#%d (2) { + ["a"]=> + int(2) + ["_b":"C":private]=> + &int(2) + } +} diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 70e7a2b5fd1..a0eacb14dcf 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -3290,22 +3290,6 @@ ZEND_API bool zend_verify_ref_array_assignable(zend_reference *ref) { return 1; } -static zend_property_info *zend_object_fetch_property_type_info( - zend_object *obj, zval *slot) -{ - if (EXPECTED(!ZEND_CLASS_HAS_TYPE_HINTS(obj->ce))) { - return NULL; - } - - /* Not a declared property */ - if (UNEXPECTED(slot < obj->properties_table || - slot >= obj->properties_table + obj->ce->default_properties_count)) { - return NULL; - } - - return zend_get_typed_property_info_for_slot(obj, slot); -} - static zend_never_inline bool zend_handle_fetch_obj_flags( zval *result, zval *ptr, zend_object *obj, zend_property_info *prop_info, uint32_t flags) { @@ -3313,10 +3297,7 @@ static zend_never_inline bool zend_handle_fetch_obj_flags( case ZEND_FETCH_DIM_WRITE: if (promotes_to_array(ptr)) { if (!prop_info) { - prop_info = zend_object_fetch_property_type_info(obj, ptr); - if (!prop_info) { - break; - } + break; } if (!check_type_array_assignable(prop_info->type)) { zend_throw_auto_init_in_prop_error(prop_info); @@ -3328,10 +3309,7 @@ static zend_never_inline bool zend_handle_fetch_obj_flags( case ZEND_FETCH_REF: if (Z_TYPE_P(ptr) != IS_REFERENCE) { if (!prop_info) { - prop_info = zend_object_fetch_property_type_info(obj, ptr); - if (!prop_info) { - break; - } + break; } if (Z_TYPE_P(ptr) == IS_UNDEF) { if (!ZEND_TYPE_ALLOW_NULL(prop_info->type)) { @@ -3351,11 +3329,17 @@ static zend_never_inline bool zend_handle_fetch_obj_flags( return 1; } -static zend_always_inline void zend_fetch_property_address(zval *result, zval *container, uint32_t container_op_type, zval *prop_ptr, uint32_t prop_op_type, void **cache_slot, int type, uint32_t flags OPLINE_DC EXECUTE_DATA_DC) +static zend_always_inline void zend_fetch_property_address(zval *result, zval *container, uint32_t container_op_type, zval *prop_ptr, uint32_t prop_op_type, void **cache_slot, int type, uint32_t flags, zend_property_info **prop_info_p OPLINE_DC EXECUTE_DATA_DC) { zval *ptr; zend_object *zobj; zend_string *name, *tmp_name; + void *_cache_slot[3] = {0}; + if (prop_op_type != IS_CONST) { + cache_slot = _cache_slot; + } else { + ZEND_ASSERT(cache_slot); + } if (container_op_type != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) { do { @@ -3386,6 +3370,9 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c if (prop_op_type == IS_CONST && EXPECTED(zobj->ce == CACHED_PTR_EX(cache_slot))) { uintptr_t prop_offset = (uintptr_t)CACHED_PTR_EX(cache_slot + 1); + if (prop_info_p) { + *prop_info_p = CACHED_PTR_EX(cache_slot + 2); + } if (EXPECTED(IS_VALID_PROPERTY_OFFSET(prop_offset))) { ptr = OBJ_PROP(zobj, prop_offset); @@ -3465,23 +3452,18 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c ZVAL_INDIRECT(result, ptr); flags &= ZEND_FETCH_OBJ_FLAGS; if (flags) { - zend_property_info *prop_info; - - if (prop_op_type == IS_CONST) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - if (prop_info && ZEND_TYPE_IS_SET(prop_info->type)) { - if (UNEXPECTED(!zend_handle_fetch_obj_flags(result, ptr, NULL, prop_info, flags))) { - goto end; - } - } - } else { - if (UNEXPECTED(!zend_handle_fetch_obj_flags(result, ptr, Z_OBJ_P(container), NULL, flags))) { + zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); + if (prop_info && ZEND_TYPE_IS_SET(prop_info->type)) { + if (UNEXPECTED(!zend_handle_fetch_obj_flags(result, ptr, NULL, prop_info, flags))) { goto end; } } } end: + if (prop_info_p) { + *prop_info_p = CACHED_PTR_EX(cache_slot + 2); + } if (prop_op_type != IS_CONST) { zend_tmp_string_release(tmp_name); } @@ -3492,9 +3474,10 @@ static zend_always_inline void zend_assign_to_property_reference(zval *container zval variable, *variable_ptr = &variable; void **cache_addr = (prop_op_type == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_RETURNS_FUNCTION) : NULL; zend_refcounted *garbage = NULL; + zend_property_info *prop_info = NULL; zend_fetch_property_address(variable_ptr, container, container_op_type, prop_ptr, prop_op_type, - cache_addr, BP_VAR_W, 0 OPLINE_CC EXECUTE_DATA_CC); + cache_addr, BP_VAR_W, 0, &prop_info OPLINE_CC EXECUTE_DATA_CC); if (EXPECTED(Z_TYPE_P(variable_ptr) == IS_INDIRECT)) { variable_ptr = Z_INDIRECT_P(variable_ptr); @@ -3504,21 +3487,10 @@ static zend_always_inline void zend_assign_to_property_reference(zval *container variable_ptr = zend_wrong_assign_to_variable_reference( variable_ptr, value_ptr, &garbage OPLINE_CC EXECUTE_DATA_CC); + } else if (prop_info) { + variable_ptr = zend_assign_to_typed_property_reference(prop_info, variable_ptr, value_ptr, &garbage EXECUTE_DATA_CC); } else { - zend_property_info *prop_info = NULL; - - if (prop_op_type == IS_CONST) { - prop_info = (zend_property_info *) CACHED_PTR_EX(cache_addr + 2); - } else { - ZVAL_DEREF(container); - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(container), variable_ptr); - } - - if (prop_info) { - variable_ptr = zend_assign_to_typed_property_reference(prop_info, variable_ptr, value_ptr, &garbage EXECUTE_DATA_CC); - } else { - zend_assign_to_variable_reference(variable_ptr, value_ptr, &garbage); - } + zend_assign_to_variable_reference(variable_ptr, value_ptr, &garbage); } } else if (Z_ISERROR_P(variable_ptr)) { variable_ptr = &EG(uninitialized_zval); diff --git a/Zend/zend_lazy_objects.c b/Zend/zend_lazy_objects.c index 357150bc638..8be8e8b7b77 100644 --- a/Zend/zend_lazy_objects.c +++ b/Zend/zend_lazy_objects.c @@ -734,3 +734,21 @@ HashTable *zend_lazy_object_get_gc(zend_object *zobj, zval **table, int *n) zend_get_gc_buffer_use(gc_buffer, table, n); return NULL; } + +zend_property_info *zend_lazy_object_get_property_info_for_slot(zend_object *obj, zval *slot) +{ + ZEND_ASSERT(zend_object_is_lazy_proxy(obj)); + + zend_property_info **table = obj->ce->properties_info_table; + intptr_t prop_num = slot - obj->properties_table; + if (prop_num >= 0 && prop_num < obj->ce->default_properties_count) { + return table[prop_num]; + } + + if (!zend_lazy_object_initialized(obj)) { + return NULL; + } + + obj = zend_lazy_object_get_instance(obj); + return zend_get_property_info_for_slot(obj, slot); +} diff --git a/Zend/zend_lazy_objects.h b/Zend/zend_lazy_objects.h index addb07173c3..64f68d66360 100644 --- a/Zend/zend_lazy_objects.h +++ b/Zend/zend_lazy_objects.h @@ -53,6 +53,7 @@ typedef struct _zend_lazy_objects_store { HashTable infos; } zend_lazy_objects_store; +typedef struct _zend_property_info zend_property_info; typedef struct _zend_fcall_info zend_fcall_info; typedef struct _zend_fcall_info_cache zend_fcall_info_cache; @@ -75,6 +76,7 @@ HashTable *zend_lazy_object_debug_info(zend_object *object, int *is_temp); HashTable *zend_lazy_object_get_gc(zend_object *zobj, zval **table, int *n); bool zend_lazy_object_decr_lazy_props(zend_object *obj); void zend_lazy_object_realize(zend_object *obj); +ZEND_API zend_property_info *zend_lazy_object_get_property_info_for_slot(zend_object *obj, zval *slot); static zend_always_inline bool zend_object_is_lazy(zend_object *obj) { diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c index 348b3f3416b..fd0e97c5f41 100644 --- a/Zend/zend_objects.c +++ b/Zend/zend_objects.c @@ -65,7 +65,7 @@ void zend_object_dtor_property(zend_object *object, zval *p) if (Z_REFCOUNTED_P(p)) { if (UNEXPECTED(Z_ISREF_P(p)) && (ZEND_DEBUG || ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(p)))) { - zend_property_info *prop_info = zend_get_property_info_for_slot(object, p); + zend_property_info *prop_info = zend_get_property_info_for_slot_self(object, p); if (ZEND_TYPE_IS_SET(prop_info->type)) { ZEND_REF_DEL_TYPE_SOURCE(Z_REF_P(p), prop_info); } @@ -233,7 +233,7 @@ ZEND_API void ZEND_FASTCALL zend_objects_clone_members(zend_object *new_object, if (UNEXPECTED(Z_ISREF_P(dst)) && (ZEND_DEBUG || ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(dst)))) { - zend_property_info *prop_info = zend_get_property_info_for_slot(new_object, dst); + zend_property_info *prop_info = zend_get_property_info_for_slot_self(new_object, dst); if (ZEND_TYPE_IS_SET(prop_info->type)) { ZEND_REF_ADD_TYPE_SOURCE(Z_REF_P(dst), prop_info); } diff --git a/Zend/zend_objects_API.h b/Zend/zend_objects_API.h index 95fa5acf62f..02326f2b314 100644 --- a/Zend/zend_objects_API.h +++ b/Zend/zend_objects_API.h @@ -96,8 +96,21 @@ static zend_always_inline void *zend_object_alloc(size_t obj_size, zend_class_en return obj; } +/* Use when 'slot' was obtained directly from obj->properties_table, or when + * 'obj' can not be lazy. Otherwise, use zend_get_property_info_for_slot(). */ +static inline zend_property_info *zend_get_property_info_for_slot_self(zend_object *obj, zval *slot) +{ + zend_property_info **table = obj->ce->properties_info_table; + intptr_t prop_num = slot - obj->properties_table; + ZEND_ASSERT(prop_num >= 0 && prop_num < obj->ce->default_properties_count); + return table[prop_num]; +} + static inline zend_property_info *zend_get_property_info_for_slot(zend_object *obj, zval *slot) { + if (UNEXPECTED(zend_object_is_lazy_proxy(obj))) { + return zend_lazy_object_get_property_info_for_slot(obj, slot); + } zend_property_info **table = obj->ce->properties_info_table; intptr_t prop_num = slot - obj->properties_table; ZEND_ASSERT(prop_num >= 0 && prop_num < obj->ce->default_properties_count); diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 1934ba4afa6..55675e4a0b5 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -1012,6 +1012,7 @@ ZEND_VM_HANDLER(28, ZEND_ASSIGN_OBJ_OP, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, OP) zval *property; zval *value; zval *zptr; + void *_cache_slot[3] = {0}; void **cache_slot; zend_property_info *prop_info; zend_object *zobj; @@ -1049,14 +1050,13 @@ ZEND_VM_C_LABEL(assign_op_object): break; } } - cache_slot = (OP2_TYPE == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL; + cache_slot = (OP2_TYPE == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - zval *orig_zptr = zptr; zend_reference *ref; do { @@ -1069,11 +1069,7 @@ ZEND_VM_C_LABEL(assign_op_object): } } - if (OP2_TYPE == IS_CONST) { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); - } + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); if (prop_info) { /* special case for typed properties */ zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC); @@ -1286,6 +1282,7 @@ ZEND_VM_HANDLER(132, ZEND_PRE_INC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACH zval *object; zval *property; zval *zptr; + void *_cache_slot[3] = {0}; void **cache_slot; zend_property_info *prop_info; zend_object *zobj; @@ -1321,18 +1318,14 @@ ZEND_VM_C_LABEL(pre_incdec_object): break; } } - cache_slot = (OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL; + cache_slot = (OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - if (OP2_TYPE == IS_CONST) { - prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), zptr); - } + prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); } } else { @@ -1359,6 +1352,7 @@ ZEND_VM_HANDLER(134, ZEND_POST_INC_OBJ, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CAC zval *object; zval *property; zval *zptr; + void *_cache_slot[3] = {0}; void **cache_slot; zend_property_info *prop_info; zend_object *zobj; @@ -1394,17 +1388,12 @@ ZEND_VM_C_LABEL(post_incdec_object): break; } } - cache_slot = (OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL; + cache_slot = (OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { - if (OP2_TYPE == IS_CONST) { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), zptr); - } - + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); } } else { @@ -2217,7 +2206,7 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, FETCH zend_fetch_property_address( result, container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), - BP_VAR_W, opline->extended_value OPLINE_CC EXECUTE_DATA_CC); + BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC); FREE_OP2(); if (OP1_TYPE == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -2234,7 +2223,7 @@ ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, CACH container = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW); property = GET_OP2_ZVAL_PTR(BP_VAR_R); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0 OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_property_address(result, container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); FREE_OP2(); if (OP1_TYPE == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -2389,7 +2378,7 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|THIS|CV, CONST|TMPVAR|CV, C container = GET_OP1_OBJ_ZVAL_PTR_PTR_UNDEF(BP_VAR_UNSET); property = GET_OP2_ZVAL_PTR(BP_VAR_R); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0 OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_property_address(result, container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); FREE_OP2(); if (OP1_TYPE == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index faf761c1c39..088c29cf408 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -23427,6 +23427,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CONST_H zval *property; zval *value; zval *zptr; + void *_cache_slot[3] = {0}; void **cache_slot; zend_property_info *prop_info; zend_object *zobj; @@ -23464,14 +23465,13 @@ assign_op_object: break; } } - cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL; + cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - zval *orig_zptr = zptr; zend_reference *ref; do { @@ -23484,11 +23484,7 @@ assign_op_object: } } - if (IS_CONST == IS_CONST) { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); - } + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); if (prop_info) { /* special case for typed properties */ zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC); @@ -23653,6 +23649,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_VAR_CONST_HAN zval *object; zval *property; zval *zptr; + void *_cache_slot[3] = {0}; void **cache_slot; zend_property_info *prop_info; zend_object *zobj; @@ -23688,18 +23685,14 @@ pre_incdec_object: break; } } - cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL; + cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - if (IS_CONST == IS_CONST) { - prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), zptr); - } + prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); } } else { @@ -23720,6 +23713,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_VAR_CONST_HA zval *object; zval *property; zval *zptr; + void *_cache_slot[3] = {0}; void **cache_slot; zend_property_info *prop_info; zend_object *zobj; @@ -23755,17 +23749,12 @@ post_incdec_object: break; } } - cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL; + cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { - if (IS_CONST == IS_CONST) { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), zptr); - } - + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); } } else { @@ -23857,7 +23846,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HAN zend_fetch_property_address( result, container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), - BP_VAR_W, opline->extended_value OPLINE_CC EXECUTE_DATA_CC); + BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC); if (IS_VAR == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -23874,7 +23863,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_HA container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); property = RT_CONSTANT(opline, opline->op2); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0 OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_property_address(result, container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); if (IS_VAR == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -23908,7 +23897,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); property = RT_CONSTANT(opline, opline->op2); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0 OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_property_address(result, container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); if (IS_VAR == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -26424,6 +26413,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_VAR_TMPVAR_ zval *property; zval *value; zval *zptr; + void *_cache_slot[3] = {0}; void **cache_slot; zend_property_info *prop_info; zend_object *zobj; @@ -26461,14 +26451,13 @@ assign_op_object: break; } } - cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL; + cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - zval *orig_zptr = zptr; zend_reference *ref; do { @@ -26481,11 +26470,7 @@ assign_op_object: } } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); - } + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); if (prop_info) { /* special case for typed properties */ zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC); @@ -26652,6 +26637,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_VAR_TMPVAR_HA zval *object; zval *property; zval *zptr; + void *_cache_slot[3] = {0}; void **cache_slot; zend_property_info *prop_info; zend_object *zobj; @@ -26687,18 +26673,14 @@ pre_incdec_object: break; } } - cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL; + cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), zptr); - } + prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); } } else { @@ -26720,6 +26702,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_VAR_TMPVAR_H zval *object; zval *property; zval *zptr; + void *_cache_slot[3] = {0}; void **cache_slot; zend_property_info *prop_info; zend_object *zobj; @@ -26755,17 +26738,12 @@ post_incdec_object: break; } } - cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL; + cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), zptr); - } - + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); } } else { @@ -26858,7 +26836,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_TMPVAR_HA zend_fetch_property_address( result, container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), - BP_VAR_W, opline->extended_value OPLINE_CC EXECUTE_DATA_CC); + BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); if (IS_VAR == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -26875,7 +26853,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_TMPVAR_H container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0 OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_property_address(result, container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); if (IS_VAR == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -26909,7 +26887,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMPVA container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0 OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_property_address(result, container, IS_VAR, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); if (IS_VAR == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -30793,6 +30771,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_VAR_CV_HAND zval *property; zval *value; zval *zptr; + void *_cache_slot[3] = {0}; void **cache_slot; zend_property_info *prop_info; zend_object *zobj; @@ -30830,14 +30809,13 @@ assign_op_object: break; } } - cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL; + cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - zval *orig_zptr = zptr; zend_reference *ref; do { @@ -30850,11 +30828,7 @@ assign_op_object: } } - if (IS_CV == IS_CONST) { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); - } + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); if (prop_info) { /* special case for typed properties */ zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC); @@ -31019,6 +30993,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_VAR_CV_HANDLE zval *object; zval *property; zval *zptr; + void *_cache_slot[3] = {0}; void **cache_slot; zend_property_info *prop_info; zend_object *zobj; @@ -31054,18 +31029,14 @@ pre_incdec_object: break; } } - cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL; + cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - if (IS_CV == IS_CONST) { - prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), zptr); - } + prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); } } else { @@ -31086,6 +31057,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_VAR_CV_HANDL zval *object; zval *property; zval *zptr; + void *_cache_slot[3] = {0}; void **cache_slot; zend_property_info *prop_info; zend_object *zobj; @@ -31121,17 +31093,12 @@ post_incdec_object: break; } } - cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL; + cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { - if (IS_CV == IS_CONST) { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), zptr); - } - + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); } } else { @@ -31223,7 +31190,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLE zend_fetch_property_address( result, container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), - BP_VAR_W, opline->extended_value OPLINE_CC EXECUTE_DATA_CC); + BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC); if (IS_VAR == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -31240,7 +31207,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_HANDL container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0 OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_property_address(result, container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); if (IS_VAR == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -31274,7 +31241,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HA container = _get_zval_ptr_ptr_var(opline->op1.var EXECUTE_DATA_CC); property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0 OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_property_address(result, container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); if (IS_VAR == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -33473,6 +33440,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CONS zval *property; zval *value; zval *zptr; + void *_cache_slot[3] = {0}; void **cache_slot; zend_property_info *prop_info; zend_object *zobj; @@ -33510,14 +33478,13 @@ assign_op_object: break; } } - cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL; + cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - zval *orig_zptr = zptr; zend_reference *ref; do { @@ -33530,11 +33497,7 @@ assign_op_object: } } - if (IS_CONST == IS_CONST) { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); - } + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); if (prop_info) { /* special case for typed properties */ zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC); @@ -33569,6 +33532,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_UNUSED_CONST_ zval *object; zval *property; zval *zptr; + void *_cache_slot[3] = {0}; void **cache_slot; zend_property_info *prop_info; zend_object *zobj; @@ -33604,18 +33568,14 @@ pre_incdec_object: break; } } - cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL; + cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - if (IS_CONST == IS_CONST) { - prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), zptr); - } + prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); } } else { @@ -33636,6 +33596,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_UNUSED_CONST zval *object; zval *property; zval *zptr; + void *_cache_slot[3] = {0}; void **cache_slot; zend_property_info *prop_info; zend_object *zobj; @@ -33671,17 +33632,12 @@ post_incdec_object: break; } } - cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL; + cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { - if (IS_CONST == IS_CONST) { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), zptr); - } - + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); } } else { @@ -33882,7 +33838,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_ zend_fetch_property_address( result, container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), - BP_VAR_W, opline->extended_value OPLINE_CC EXECUTE_DATA_CC); + BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC); if (IS_UNUSED == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -33899,7 +33855,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST container = &EX(This); property = RT_CONSTANT(opline, opline->op2); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0 OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); if (IS_UNUSED == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -34054,7 +34010,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CO container = &EX(This); property = RT_CONSTANT(opline, opline->op2); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0 OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); if (IS_UNUSED == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -35655,6 +35611,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_TMPV zval *property; zval *value; zval *zptr; + void *_cache_slot[3] = {0}; void **cache_slot; zend_property_info *prop_info; zend_object *zobj; @@ -35692,14 +35649,13 @@ assign_op_object: break; } } - cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL; + cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - zval *orig_zptr = zptr; zend_reference *ref; do { @@ -35712,11 +35668,7 @@ assign_op_object: } } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); - } + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); if (prop_info) { /* special case for typed properties */ zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC); @@ -35751,6 +35703,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_UNUSED_TMPVAR zval *object; zval *property; zval *zptr; + void *_cache_slot[3] = {0}; void **cache_slot; zend_property_info *prop_info; zend_object *zobj; @@ -35786,18 +35739,14 @@ pre_incdec_object: break; } } - cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL; + cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), zptr); - } + prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); } } else { @@ -35819,6 +35768,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_UNUSED_TMPVA zval *object; zval *property; zval *zptr; + void *_cache_slot[3] = {0}; void **cache_slot; zend_property_info *prop_info; zend_object *zobj; @@ -35854,17 +35804,12 @@ post_incdec_object: break; } } - cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL; + cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), zptr); - } - + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); } } else { @@ -36061,7 +36006,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMPVAR zend_fetch_property_address( result, container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), - BP_VAR_W, opline->extended_value OPLINE_CC EXECUTE_DATA_CC); + BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); if (IS_UNUSED == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -36078,7 +36023,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMPVA container = &EX(This); property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0 OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_property_address(result, container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); if (IS_UNUSED == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -36233,7 +36178,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TM container = &EX(This); property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0 OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_property_address(result, container, IS_UNUSED, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); if (IS_UNUSED == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -38314,6 +38259,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_UNUSED_CV_H zval *property; zval *value; zval *zptr; + void *_cache_slot[3] = {0}; void **cache_slot; zend_property_info *prop_info; zend_object *zobj; @@ -38351,14 +38297,13 @@ assign_op_object: break; } } - cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL; + cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - zval *orig_zptr = zptr; zend_reference *ref; do { @@ -38371,11 +38316,7 @@ assign_op_object: } } - if (IS_CV == IS_CONST) { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); - } + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); if (prop_info) { /* special case for typed properties */ zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC); @@ -38410,6 +38351,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_UNUSED_CV_HAN zval *object; zval *property; zval *zptr; + void *_cache_slot[3] = {0}; void **cache_slot; zend_property_info *prop_info; zend_object *zobj; @@ -38445,18 +38387,14 @@ pre_incdec_object: break; } } - cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL; + cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - if (IS_CV == IS_CONST) { - prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), zptr); - } + prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); } } else { @@ -38477,6 +38415,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_UNUSED_CV_HA zval *object; zval *property; zval *zptr; + void *_cache_slot[3] = {0}; void **cache_slot; zend_property_info *prop_info; zend_object *zobj; @@ -38512,17 +38451,12 @@ post_incdec_object: break; } } - cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL; + cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { - if (IS_CV == IS_CONST) { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), zptr); - } - + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); } } else { @@ -38718,7 +38652,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HAN zend_fetch_property_address( result, container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), - BP_VAR_W, opline->extended_value OPLINE_CC EXECUTE_DATA_CC); + BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC); if (IS_UNUSED == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -38735,7 +38669,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_HA container = &EX(This); property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0 OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); if (IS_UNUSED == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -38890,7 +38824,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV container = &EX(This); property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0 OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_property_address(result, container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); if (IS_UNUSED == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -42461,6 +42395,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_CV_CONST_HA zval *property; zval *value; zval *zptr; + void *_cache_slot[3] = {0}; void **cache_slot; zend_property_info *prop_info; zend_object *zobj; @@ -42498,14 +42433,13 @@ assign_op_object: break; } } - cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL; + cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - zval *orig_zptr = zptr; zend_reference *ref; do { @@ -42518,11 +42452,7 @@ assign_op_object: } } - if (IS_CONST == IS_CONST) { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); - } + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); if (prop_info) { /* special case for typed properties */ zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC); @@ -42687,6 +42617,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_CV_CONST_HAND zval *object; zval *property; zval *zptr; + void *_cache_slot[3] = {0}; void **cache_slot; zend_property_info *prop_info; zend_object *zobj; @@ -42722,18 +42653,14 @@ pre_incdec_object: break; } } - cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL; + cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - if (IS_CONST == IS_CONST) { - prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), zptr); - } + prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); } } else { @@ -42754,6 +42681,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_CV_CONST_HAN zval *object; zval *property; zval *zptr; + void *_cache_slot[3] = {0}; void **cache_slot; zend_property_info *prop_info; zend_object *zobj; @@ -42789,17 +42717,12 @@ post_incdec_object: break; } } - cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL; + cache_slot = (IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { - if (IS_CONST == IS_CONST) { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), zptr); - } - + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); } } else { @@ -43112,7 +43035,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HAND zend_fetch_property_address( result, container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), - BP_VAR_W, opline->extended_value OPLINE_CC EXECUTE_DATA_CC); + BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC); if (IS_CV == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -43129,7 +43052,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_HAN container = EX_VAR(opline->op1.var); property = RT_CONSTANT(opline, opline->op2); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0 OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_property_address(result, container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); if (IS_CV == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -43284,7 +43207,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_ container = EX_VAR(opline->op1.var); property = RT_CONSTANT(opline, opline->op2); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0 OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_property_address(result, container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); if (IS_CV == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -46425,6 +46348,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_CV_TMPVAR_H zval *property; zval *value; zval *zptr; + void *_cache_slot[3] = {0}; void **cache_slot; zend_property_info *prop_info; zend_object *zobj; @@ -46462,14 +46386,13 @@ assign_op_object: break; } } - cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL; + cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - zval *orig_zptr = zptr; zend_reference *ref; do { @@ -46482,11 +46405,7 @@ assign_op_object: } } - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); - } + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); if (prop_info) { /* special case for typed properties */ zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC); @@ -46653,6 +46572,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_CV_TMPVAR_HAN zval *object; zval *property; zval *zptr; + void *_cache_slot[3] = {0}; void **cache_slot; zend_property_info *prop_info; zend_object *zobj; @@ -46688,18 +46608,14 @@ pre_incdec_object: break; } } - cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL; + cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), zptr); - } + prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); } } else { @@ -46721,6 +46637,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_CV_TMPVAR_HA zval *object; zval *property; zval *zptr; + void *_cache_slot[3] = {0}; void **cache_slot; zend_property_info *prop_info; zend_object *zobj; @@ -46756,17 +46673,12 @@ post_incdec_object: break; } } - cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL; + cache_slot = ((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { - if ((IS_TMP_VAR|IS_VAR) == IS_CONST) { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), zptr); - } - + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); } } else { @@ -47075,7 +46987,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_TMPVAR_HAN zend_fetch_property_address( result, container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), - BP_VAR_W, opline->extended_value OPLINE_CC EXECUTE_DATA_CC); + BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); if (IS_CV == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -47092,7 +47004,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_TMPVAR_HA container = EX_VAR(opline->op1.var); property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0 OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_property_address(result, container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); if (IS_CV == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -47247,7 +47159,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMPVAR container = EX_VAR(opline->op1.var); property = _get_zval_ptr_var(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0 OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_property_address(result, container, IS_CV, property, (IS_TMP_VAR|IS_VAR), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); zval_ptr_dtor_nogc(EX_VAR(opline->op2.var)); if (IS_CV == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -51939,6 +51851,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSIGN_OBJ_OP_SPEC_CV_CV_HANDL zval *property; zval *value; zval *zptr; + void *_cache_slot[3] = {0}; void **cache_slot; zend_property_info *prop_info; zend_object *zobj; @@ -51976,14 +51889,13 @@ assign_op_object: break; } } - cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : NULL; + cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR((opline+1)->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - zval *orig_zptr = zptr; zend_reference *ref; do { @@ -51996,11 +51908,7 @@ assign_op_object: } } - if (IS_CV == IS_CONST) { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), orig_zptr); - } + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); if (prop_info) { /* special case for typed properties */ zend_binary_assign_op_typed_prop(prop_info, zptr, value OPLINE_CC EXECUTE_DATA_CC); @@ -52165,6 +52073,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_OBJ_SPEC_CV_CV_HANDLER zval *object; zval *property; zval *zptr; + void *_cache_slot[3] = {0}; void **cache_slot; zend_property_info *prop_info; zend_object *zobj; @@ -52200,18 +52109,14 @@ pre_incdec_object: break; } } - cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL; + cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { if (UNEXPECTED(RETURN_VALUE_USED(opline))) { ZVAL_NULL(EX_VAR(opline->result.var)); } } else { - if (IS_CV == IS_CONST) { - prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), zptr); - } + prop_info = (zend_property_info *) CACHED_PTR_EX(cache_slot + 2); zend_pre_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); } } else { @@ -52232,6 +52137,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_OBJ_SPEC_CV_CV_HANDLE zval *object; zval *property; zval *zptr; + void *_cache_slot[3] = {0}; void **cache_slot; zend_property_info *prop_info; zend_object *zobj; @@ -52267,17 +52173,12 @@ post_incdec_object: break; } } - cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL; + cache_slot = (IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : _cache_slot; if (EXPECTED((zptr = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_RW, cache_slot)) != NULL)) { if (UNEXPECTED(Z_ISERROR_P(zptr))) { ZVAL_NULL(EX_VAR(opline->result.var)); } else { - if (IS_CV == IS_CONST) { - prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); - } else { - prop_info = zend_object_fetch_property_type_info(Z_OBJ_P(object), zptr); - } - + prop_info = (zend_property_info*)CACHED_PTR_EX(cache_slot + 2); zend_post_incdec_property_zval(zptr, prop_info OPLINE_CC EXECUTE_DATA_CC); } } else { @@ -52585,7 +52486,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER zend_fetch_property_address( result, container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS) : NULL), - BP_VAR_W, opline->extended_value OPLINE_CC EXECUTE_DATA_CC); + BP_VAR_W, opline->extended_value, NULL OPLINE_CC EXECUTE_DATA_CC); if (IS_CV == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -52602,7 +52503,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLE container = EX_VAR(opline->op1.var); property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0 OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_property_address(result, container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_RW, 0, NULL OPLINE_CC EXECUTE_DATA_CC); if (IS_CV == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); @@ -52757,7 +52658,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HAN container = EX_VAR(opline->op1.var); property = _get_zval_ptr_cv_BP_VAR_R(opline->op2.var EXECUTE_DATA_CC); result = EX_VAR(opline->result.var); - zend_fetch_property_address(result, container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0 OPLINE_CC EXECUTE_DATA_CC); + zend_fetch_property_address(result, container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? CACHE_ADDR(opline->extended_value) : NULL), BP_VAR_UNSET, 0, NULL OPLINE_CC EXECUTE_DATA_CC); if (IS_CV == IS_VAR) { FREE_VAR_PTR_AND_EXTRACT_RESULT_IF_NECESSARY(opline->op1.var); diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index a1370ea0723..4172cd6697e 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -2065,22 +2065,6 @@ static zend_always_inline bool check_type_array_assignable(zend_type type) { return (ZEND_TYPE_FULL_MASK(type) & MAY_BE_ARRAY) != 0; } -static zend_property_info *zend_object_fetch_property_type_info( - zend_object *obj, zval *slot) -{ - if (EXPECTED(!ZEND_CLASS_HAS_TYPE_HINTS(obj->ce))) { - return NULL; - } - - /* Not a declared property */ - if (UNEXPECTED(slot < obj->properties_table || - slot >= obj->properties_table + obj->ce->default_properties_count)) { - return NULL; - } - - return zend_get_typed_property_info_for_slot(obj, slot); -} - static zend_never_inline ZEND_COLD void zend_throw_auto_init_in_prop_error(zend_property_info *prop, const char *type) { zend_string *type_str = zend_type_to_string(prop->type); zend_type_error( @@ -2107,10 +2091,7 @@ static zend_never_inline bool zend_handle_fetch_obj_flags( case ZEND_FETCH_DIM_WRITE: if (promotes_to_array(ptr)) { if (!prop_info) { - prop_info = zend_object_fetch_property_type_info(obj, ptr); - if (!prop_info) { - break; - } + break; } if (!check_type_array_assignable(prop_info->type)) { zend_throw_auto_init_in_prop_error(prop_info, "array"); @@ -2122,10 +2103,7 @@ static zend_never_inline bool zend_handle_fetch_obj_flags( case ZEND_FETCH_REF: if (Z_TYPE_P(ptr) != IS_REFERENCE) { if (!prop_info) { - prop_info = zend_object_fetch_property_type_info(obj, ptr); - if (!prop_info) { - break; - } + break; } if (Z_TYPE_P(ptr) == IS_UNDEF) { if (!ZEND_TYPE_ALLOW_NULL(prop_info->type)) { @@ -2154,6 +2132,7 @@ static void ZEND_FASTCALL zend_jit_fetch_obj_w_slow(zend_object *zobj) zend_string *name = Z_STR_P(RT_CONSTANT(opline, opline->op2)); zval *result = EX_VAR(opline->result.var); void **cache_slot = CACHE_ADDR(opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS); + ZEND_ASSERT(cache_slot); retval = zobj->handlers->get_property_ptr_ptr(zobj, name, BP_VAR_W, cache_slot); if (NULL == retval) { @@ -2180,13 +2159,10 @@ static void ZEND_FASTCALL zend_jit_fetch_obj_w_slow(zend_object *zobj) uint32_t flags = opline->extended_value & ZEND_FETCH_OBJ_FLAGS; if (flags) { - zend_property_info *prop_info = NULL; + zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 2); - if (opline->op2_type == IS_CONST) { - prop_info = CACHED_PTR_EX(cache_slot + 2); - if (!prop_info) { - break; - } + if (!prop_info) { + break; } if (UNEXPECTED(!zend_handle_fetch_obj_flags(result, retval, zobj, prop_info, flags))) { return;