diff options
author | krakjoe <joe.watkins@live.co.uk> | 2014-11-25 08:37:02 +0000 |
---|---|---|
committer | krakjoe <joe.watkins@live.co.uk> | 2014-11-25 08:37:02 +0000 |
commit | e07feeaf8b91f16a89e9903b461042a0f6a63ac0 (patch) | |
tree | 4a94cd382fcffefff920f7733562e1860a66cc44 /Zend | |
parent | 9b6836ebd36eccc9e81ca51e2efe172e1d334f0b (diff) | |
parent | d4f42289ddde002cb4d3ed9d1a4f2219f68df48e (diff) | |
download | php-git-e07feeaf8b91f16a89e9903b461042a0f6a63ac0.tar.gz |
Merge branch 'master' of https://github.com/php/php-src
Diffstat (limited to 'Zend')
37 files changed, 3836 insertions, 2793 deletions
diff --git a/Zend/ZEND_CHANGES b/Zend/ZEND_CHANGES index afb3595595..94e164c290 100644 --- a/Zend/ZEND_CHANGES +++ b/Zend/ZEND_CHANGES @@ -1103,7 +1103,7 @@ Changes in the Zend Engine 1.0 Use ob_start() to begin output buffering, ob_end_flush() to end buffering and send out the buffered contents, ob_end_clean() to end buffering without sending the buffered contents, and - ob_get_contents() to retreive the current contents of the output + ob_get_contents() to retrieve the current contents of the output buffer. Header information (header(), content type, cookies) are not buffered. By turning on output buffering, you can effectively send header information all throughout your file, diff --git a/Zend/tests/bug21478.phpt b/Zend/tests/bug21478.phpt index 8b38f24d6e..5955c4c1dc 100644 --- a/Zend/tests/bug21478.phpt +++ b/Zend/tests/bug21478.phpt @@ -27,7 +27,7 @@ stream_filter_append($fp, "myfilter"); fwrite($fp, "This is a test.\n"); print "Done.\n"; fclose($fp); -// Uncommenting the following 'print' line causes the segfault to stop occuring +// Uncommenting the following 'print' line causes the segfault to stop occurring // print "2\n"; readfile(dirname(__FILE__)."/test.txt"); unlink(dirname(__FILE__)."/test.txt"); diff --git a/Zend/tests/bug33512.phpt b/Zend/tests/bug33512.phpt index 9dd4e4e5f9..dcb8f0417e 100644 --- a/Zend/tests/bug33512.phpt +++ b/Zend/tests/bug33512.phpt @@ -53,7 +53,7 @@ class TheObj { unset($SomeObj->Virtual1); unset($SomeObj->{'Virtual'.(3)}); - //but, these variables are still available??? eventhough they're "unset"-ed + //but, these variables are still available??? even though they're "unset"-ed print $SomeObj->Virtual1."\n"; print $SomeObj->{'Virtual'.(3)}."\n"; ?> diff --git a/Zend/tests/bug38779_1.phpt b/Zend/tests/bug38779_1.phpt index eefa952e36..e2a5b208c6 100644 --- a/Zend/tests/bug38779_1.phpt +++ b/Zend/tests/bug38779_1.phpt @@ -39,6 +39,14 @@ include $filename; echo "Done\n"; ?> +--CLEAN-- +<?php + +$filename = dirname(__FILE__)."/bug38779.txt"; +if (file_exists($filename)) { + @unlink(dirname(__FILE__)."/bug38779.txt"); +} +?> --EXPECTF-- Parse error: %s error%sin %s on line %d string(6) "flush!" diff --git a/Zend/tests/bug40809.phpt b/Zend/tests/bug40809.phpt index 08fc89f553..9ff4e6f1b6 100644 --- a/Zend/tests/bug40809.phpt +++ b/Zend/tests/bug40809.phpt @@ -1,5 +1,5 @@ --TEST-- -Bug #40809 (Poor perfomance of ".=") +Bug #40809 (Poor performance of ".=") --FILE-- <?php error_reporting(E_ALL|E_STRICT); diff --git a/Zend/tests/bug43200.phpt b/Zend/tests/bug43200.phpt index 24a8bbb1d7..7a995aab3e 100644 --- a/Zend/tests/bug43200.phpt +++ b/Zend/tests/bug43200.phpt @@ -1,5 +1,5 @@ --TEST-- -Bug #43200 (Interface implementation / inheritence not possible in abstract classes) +Bug #43200 (Interface implementation / inheritance not possible in abstract classes) --FILE-- <?php diff --git a/Zend/tests/bug43200_2.phpt b/Zend/tests/bug43200_2.phpt index 5efc5facff..3c8a98bddc 100644 --- a/Zend/tests/bug43200_2.phpt +++ b/Zend/tests/bug43200_2.phpt @@ -1,5 +1,5 @@ --TEST-- -Bug #43200.2 (Interface implementation / inheritence not possible in abstract classes) +Bug #43200.2 (Interface implementation / inheritance not possible in abstract classes) --FILE-- <?php diff --git a/Zend/tests/bug68370.phpt b/Zend/tests/bug68370.phpt new file mode 100644 index 0000000000..25589bf455 --- /dev/null +++ b/Zend/tests/bug68370.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #68370 "unset($this)" can make the program crash +--FILE-- +<?php +class C { + public function test() { + unset($this); + return get_defined_vars(); + } +} +$c = new C(); +$x = $c->test(); +print_r($x); +unset($c, $x); +--EXPECTF-- +Array +( +) diff --git a/Zend/tests/bug68446.phpt b/Zend/tests/bug68446.phpt new file mode 100644 index 0000000000..48e6f52f1c --- /dev/null +++ b/Zend/tests/bug68446.phpt @@ -0,0 +1,36 @@ +--TEST-- +Bug #68446 (Array constant not accepted for array parameter default) +--FILE-- +<?php +const FOO = [1]; +const BAR = null; + +function a(array $a = FOO) { + var_dump($a); +} + +function b(array $b = BAR) { + var_dump($b); +} + +b(null); +b([]); +b(); +a([]); +a(); +a(null); +?> +--EXPECTF-- +NULL +array(0) { +} +NULL +array(0) { +} +array(1) { + [0]=> + int(1) +} + +Catchable fatal error: Argument 1 passed to a() must be of the type array, null given, called in %s on line %d and defined in %s on line %d + diff --git a/Zend/tests/class_properties_const.phpt b/Zend/tests/class_properties_const.phpt new file mode 100644 index 0000000000..ac871b5c2b --- /dev/null +++ b/Zend/tests/class_properties_const.phpt @@ -0,0 +1,25 @@ +--TEST-- +Const class properties(runtime cache) +--FILE-- +<?php +class A { +} + +$a = new A; + +echo "runtime\n"; +var_dump($a->{array()}); +var_dump($a->{1}); +var_dump($a->{function(){}}); +?> +--EXPECTF-- +Notice: Array to string conversion in %sclass_properties_const.php on line %d +runtime + +Notice: Undefined property: A::$Array in %sclass_properties_const.php on line %d +NULL + +Notice: Undefined property: A::$1 in %sclass_properties_const.php on line %d +NULL + +Catchable fatal error: Object of class Closure could not be converted to string in %sclass_properties_const.php on line %d diff --git a/Zend/tests/debug_backtrace_with_include_and_this.phpt b/Zend/tests/debug_backtrace_with_include_and_this.phpt index 171ad9f451..2827ab1b74 100644 --- a/Zend/tests/debug_backtrace_with_include_and_this.phpt +++ b/Zend/tests/debug_backtrace_with_include_and_this.phpt @@ -23,15 +23,15 @@ set_error_handler(function($code, $msg, $file, $line) { }); try { - (new CL())->load('class://non.existant.Class'); + (new CL())->load('class://non.existent.Class'); } catch (CLException $e) { echo $e."\n"; } --EXPECTF-- -ERR#2: include(class://non.existant.Class): failed to open stream: "CLWrapper::stream_open" call failed @ include -ERR#2: include(): Failed opening 'class://non.existant.Class' for inclusion (include_path='%s') @ include +ERR#2: include(class://non.existent.Class): failed to open stream: "CLWrapper::stream_open" call failed @ include +ERR#2: include(): Failed opening 'class://non.existent.Class' for inclusion (include_path='%s') @ include -Fatal error: Uncaught exception 'Exception' with message 'Failed loading class://non.existant.Class' in %s +Fatal error: Uncaught exception 'Exception' with message 'Failed loading class://non.existent.Class' in %s Stack trace: #0 %s(%d): CL->load('class://non.exi...') #1 {main} diff --git a/Zend/tests/traits/bug54441.phpt b/Zend/tests/traits/bug54441.phpt index 84139f326b..3fe688b3b1 100644 --- a/Zend/tests/traits/bug54441.phpt +++ b/Zend/tests/traits/bug54441.phpt @@ -16,4 +16,4 @@ class Boo { ?> --EXPECTF-- -Fatal error: The modifiers for the trait alias dontKnow() need to be changed in the same statment in which the alias is defined. Error in %s on line %d +Fatal error: The modifiers for the trait alias dontKnow() need to be changed in the same statement in which the alias is defined. Error in %s on line %d diff --git a/Zend/tests/try_finally_010.phpt b/Zend/tests/try_finally_010.phpt index bbac8dd1e5..91eb7821ee 100644 --- a/Zend/tests/try_finally_010.phpt +++ b/Zend/tests/try_finally_010.phpt @@ -1,5 +1,5 @@ --TEST-- -Try finally (function call in the finaly block after exception) +Try finally (function call in the finally block after exception) --FILE-- <?php function foo() { diff --git a/Zend/tests/varSyntax/tempDimFetchByRefError.phpt b/Zend/tests/varSyntax/tempDimFetchByRefError.phpt index dbcac75ea9..492627302f 100644 --- a/Zend/tests/varSyntax/tempDimFetchByRefError.phpt +++ b/Zend/tests/varSyntax/tempDimFetchByRefError.phpt @@ -1,5 +1,5 @@ --TEST-- -Passing a dimention fetch on a temporary by reference is not allowed +Passing a dimension fetch on a temporary by reference is not allowed --FILE-- <?php diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 3643bfc8e2..e22b557451 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -1207,7 +1207,7 @@ ZEND_API void zend_update_class_constants(zend_class_entry *class_type TSRMLS_DC for (i = 0; i < class_type->default_properties_count; i++) { if (Z_TYPE(class_type->default_properties_table[i]) != IS_UNDEF) { - zval_update_class_constant(&class_type->default_properties_table[i], 0, i TSRMLS_CC); + zval_update_class_constant(&class_type->default_properties_table[i], 0, OBJ_PROP_TO_OFFSET(i) TSRMLS_CC); } } @@ -1251,8 +1251,9 @@ ZEND_API void object_properties_init_ex(zend_object *object, HashTable *properti if (property_info != ZEND_WRONG_PROPERTY_INFO && property_info && (property_info->flags & ZEND_ACC_STATIC) == 0) { - ZVAL_COPY_VALUE(&object->properties_table[property_info->offset], prop); - ZVAL_INDIRECT(prop, &object->properties_table[property_info->offset]); + zval *slot = OBJ_PROP(object, property_info->offset); + ZVAL_COPY_VALUE(slot, prop); + ZVAL_INDIRECT(prop, slot); } } ZEND_HASH_FOREACH_END(); } @@ -1270,11 +1271,12 @@ ZEND_API void object_properties_load(zend_object *object, HashTable *properties if (property_info != ZEND_WRONG_PROPERTY_INFO && property_info && (property_info->flags & ZEND_ACC_STATIC) == 0) { - zval_ptr_dtor(&object->properties_table[property_info->offset]); - ZVAL_COPY_VALUE(&object->properties_table[property_info->offset], prop); - zval_add_ref(&object->properties_table[property_info->offset]); + zval *slot = OBJ_PROP(object, property_info->offset); + zval_ptr_dtor(slot); + ZVAL_COPY_VALUE(slot, prop); + zval_add_ref(slot); if (object->properties) { - ZVAL_INDIRECT(&tmp, &object->properties_table[property_info->offset]); + ZVAL_INDIRECT(&tmp, slot); zend_hash_update(object->properties, key, &tmp); } } else { @@ -3618,13 +3620,14 @@ ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, z if ((property_info_ptr = zend_hash_find_ptr(&ce->properties_info, name)) != NULL && (property_info_ptr->flags & ZEND_ACC_STATIC) == 0) { property_info->offset = property_info_ptr->offset; - zval_ptr_dtor(&ce->default_properties_table[property_info->offset]); + zval_ptr_dtor(&ce->default_properties_table[OBJ_PROP_TO_NUM(property_info->offset)]); zend_hash_del(&ce->properties_info, name); } else { - property_info->offset = ce->default_properties_count++; + property_info->offset = OBJ_PROP_TO_OFFSET(ce->default_properties_count); + ce->default_properties_count++; ce->default_properties_table = perealloc(ce->default_properties_table, sizeof(zval) * ce->default_properties_count, ce->type == ZEND_INTERNAL_CLASS); } - ZVAL_COPY_VALUE(&ce->default_properties_table[property_info->offset], property); + ZVAL_COPY_VALUE(&ce->default_properties_table[OBJ_PROP_TO_NUM(property_info->offset)], property); } if (ce->type & ZEND_INTERNAL_CLASS) { switch(Z_TYPE_P(property)) { diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index cd8cc50000..9d5e079dfa 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -30,7 +30,7 @@ * performed using mmap(). The result is aligned on 2M boundary. * * Large - a number of 4096K pages inside a CHUNK. Large blocks - * are always alligned on page boundary. + * are always aligned on page boundary. * * Small - less than 3/4 of page size. Small sizes are rounded up to nearest * greater predefined small size (there are 30 predefined sizes: @@ -272,7 +272,7 @@ struct _zend_mm_page { }; /* - * bin - is one or few continuous pages (up to 8) used for alocation of + * bin - is one or few continuous pages (up to 8) used for allocation of * a particular "small size". */ struct _zend_mm_bin { @@ -395,10 +395,10 @@ stderr_last_error(char *msg) MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buf, 0, NULL)) { - fprintf(stderr, "\n%s: [0x%08x]\n", msg, err); + fprintf(stderr, "\n%s: [0x%08lx]\n", msg, err); } else { - fprintf(stderr, "\n%s: [0x%08x] %s\n", msg, err, buf); + fprintf(stderr, "\n%s: [0x%08lx] %s\n", msg, err, buf); } } #endif diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index ddec6a7ddb..ecb8f4e0d1 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -954,12 +954,10 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value continue; } prop = NULL; - if (prop_info->offset >= 0) { - if (statics && (prop_info->flags & ZEND_ACC_STATIC) != 0) { - prop = &ce->default_static_members_table[prop_info->offset]; - } else if (!statics && (prop_info->flags & ZEND_ACC_STATIC) == 0) { - prop = &ce->default_properties_table[prop_info->offset]; - } + if (statics && (prop_info->flags & ZEND_ACC_STATIC) != 0) { + prop = &ce->default_static_members_table[prop_info->offset]; + } else if (!statics && (prop_info->flags & ZEND_ACC_STATIC) == 0) { + prop = &ce->default_properties_table[OBJ_PROP_TO_NUM(prop_info->offset)]; } if (!prop || Z_TYPE_P(prop) == IS_UNDEF) { continue; diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index babf39ff40..ee3aa75ad1 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -2109,7 +2109,8 @@ static zend_op *zend_delayed_compile_prop(znode *result, zend_ast *ast, uint32_t zend_compile_expr(&prop_node, prop_ast TSRMLS_CC); opline = zend_delayed_emit_op(result, ZEND_FETCH_OBJ_R, &obj_node, &prop_node TSRMLS_CC); - if (opline->op2_type == IS_CONST && Z_TYPE(CONSTANT(opline->op2.constant)) == IS_STRING) { + if (opline->op2_type == IS_CONST) { + convert_to_string(&CONSTANT(opline->op2.constant)); zend_alloc_polymorphic_cache_slot(opline->op2.constant TSRMLS_CC); } @@ -2477,7 +2478,12 @@ uint32_t zend_compile_args(zend_ast *ast, zend_function *fbc TSRMLS_DC) /* {{{ * if (fbc) { flags |= ZEND_ARG_COMPILE_TIME_BOUND; } - opline->extended_value = flags; + if ((flags & ZEND_ARG_COMPILE_TIME_BOUND) && !(flags & ZEND_ARG_SEND_BY_REF)) { + opline->opcode = ZEND_SEND_VAR; + opline->extended_value = ZEND_ARG_COMPILE_TIME_BOUND; + } else { + opline->extended_value = flags; + } } else if (fbc) { opline->extended_value = ZEND_ARG_COMPILE_TIME_BOUND; } @@ -2984,9 +2990,7 @@ void zend_compile_global_var(zend_ast *ast TSRMLS_DC) /* {{{ */ zend_compile_expr(&name_node, name_ast TSRMLS_CC); if (name_node.op_type == IS_CONST) { - if (Z_TYPE(name_node.u.constant) != IS_STRING) { - convert_to_string(&name_node.u.constant); - } + convert_to_string(&name_node.u.constant); } if (zend_try_compile_cv(&result, var_ast TSRMLS_CC) == SUCCESS) { @@ -3827,11 +3831,15 @@ void zend_compile_params(zend_ast *ast TSRMLS_DC) /* {{{ */ arg_info->class_name_len = 0; if (type_ast) { - zend_bool has_null_default = default_ast - && (Z_TYPE(default_node.u.constant) == IS_NULL - || (Z_TYPE(default_node.u.constant) == IS_CONSTANT - && strcasecmp(Z_STRVAL(default_node.u.constant), "NULL") == 0) - || Z_TYPE(default_node.u.constant) == IS_CONSTANT_AST); // ??? + zend_bool has_null_default = 0; + + if (default_ast) { + if (!(has_null_default = (Z_TYPE(default_node.u.constant) == IS_NULL || (Z_TYPE(default_node.u.constant) == IS_CONSTANT && strcasecmp(Z_STRVAL(default_node.u.constant), "NULL") == 0)))) { + if (Z_OPT_CONSTANT(default_node.u.constant)) { + has_null_default = 2; + } + } + } op_array->fn_flags |= ZEND_ACC_HAS_TYPE_HINTS; arg_info->allow_null = has_null_default; @@ -5469,7 +5477,7 @@ void zend_compile_isset_or_empty(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ zend_ast *var_ast = ast->child[0]; znode var_node; - zend_op *opline; + zend_op *opline = NULL; ZEND_ASSERT(ast->kind == ZEND_AST_ISSET || ast->kind == ZEND_AST_EMPTY); diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index bc9b88227f..f9a66a37d8 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -227,13 +227,23 @@ typedef struct _zend_try_catch_element { char *zend_visibility_string(uint32_t fn_flags); typedef struct _zend_property_info { + uint32_t offset; /* property offset for object properties or + property index for static properties */ uint32_t flags; - int offset; zend_string *name; zend_string *doc_comment; zend_class_entry *ce; } zend_property_info; +#define OBJ_PROP(obj, offset) \ + ((zval*)((char*)(obj) + offset)) +#define OBJ_PROP_NUM(obj, num) \ + (&(obj)->properties_table[(num)]) +#define OBJ_PROP_TO_OFFSET(num) \ + ((uint32_t)(zend_uintptr_t)OBJ_PROP_NUM(((zend_object*)NULL), num)) +#define OBJ_PROP_TO_NUM(offset) \ + ((offset - OBJ_PROP_TO_OFFSET(0)) / sizeof(zval)) + typedef struct _zend_arg_info { const char *name; // TODO: convert into zend_string ??? uint32_t name_len; diff --git a/Zend/zend_config.w32.h b/Zend/zend_config.w32.h index 6ea67602b4..5353064be1 100644 --- a/Zend/zend_config.w32.h +++ b/Zend/zend_config.w32.h @@ -47,7 +47,9 @@ typedef unsigned int uint; #define HAVE_CLASS_ISTDIOSTREAM #define istdiostream stdiostream +#if _MSC_VER < 1900 #define snprintf _snprintf +#endif #if _MSC_VER < 1500 #define vsnprintf _vsnprintf #endif diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 61a605971e..9ef06d25c1 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -99,13 +99,13 @@ static const zend_internal_function zend_pass_function = { } while (0) #define FREE_OP(should_free) \ - if (should_free.var) { \ - zval_ptr_dtor_nogc(should_free.var); \ + if (should_free) { \ + zval_ptr_dtor_nogc(should_free); \ } #define FREE_OP_VAR_PTR(should_free) \ - if (should_free.var) { \ - zval_ptr_dtor_nogc(should_free.var); \ + if (should_free) { \ + zval_ptr_dtor_nogc(should_free); \ } /* End of zend_execute_locks.h */ @@ -183,29 +183,29 @@ ZEND_API zval* zend_get_compiled_variable_value(const zend_execute_data *execute return EX_VAR(var); } -static zend_always_inline zval *_get_zval_ptr_tmp(uint32_t var, const zend_execute_data *execute_data, zend_free_op *should_free TSRMLS_DC) +static zend_always_inline zval *_get_zval_ptr_tmp(uint32_t var, const zend_execute_data *execute_data, zend_free_op *should_free) { zval *ret = EX_VAR(var); - should_free->var = ret; + *should_free = ret; ZEND_ASSERT(Z_TYPE_P(ret) != IS_REFERENCE); return ret; } -static zend_always_inline zval *_get_zval_ptr_var(uint32_t var, const zend_execute_data *execute_data, zend_free_op *should_free TSRMLS_DC) +static zend_always_inline zval *_get_zval_ptr_var(uint32_t var, const zend_execute_data *execute_data, zend_free_op *should_free) { zval *ret = EX_VAR(var); - should_free->var = ret; + *should_free = ret; return ret; } -static zend_always_inline zval *_get_zval_ptr_var_deref(uint32_t var, const zend_execute_data *execute_data, zend_free_op *should_free TSRMLS_DC) +static zend_always_inline zval *_get_zval_ptr_var_deref(uint32_t var, const zend_execute_data *execute_data, zend_free_op *should_free) { zval *ret = EX_VAR(var); - should_free->var = ret; + *should_free = ret; ZVAL_DEREF(ret); return ret; } @@ -392,93 +392,71 @@ static zend_always_inline zval *_get_zval_ptr_cv_deref_BP_VAR_W(const zend_execu static inline zval *_get_zval_ptr(int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type TSRMLS_DC) { - zval *ret; - switch (op_type) { case IS_CONST: - should_free->var = NULL; + *should_free = NULL; return node->zv; - break; case IS_TMP_VAR: - ret = EX_VAR(node->var); - should_free->var = ret; - return ret; - break; + return _get_zval_ptr_tmp(node->var, execute_data, should_free); case IS_VAR: - return _get_zval_ptr_var(node->var, execute_data, should_free TSRMLS_CC); - break; - case IS_UNUSED: - should_free->var = NULL; - return NULL; - break; + return _get_zval_ptr_var(node->var, execute_data, should_free); case IS_CV: - default: - should_free->var = NULL; + *should_free = NULL; return _get_zval_ptr_cv(execute_data, node->var, type TSRMLS_CC); - break; + default: + *should_free = NULL; + return NULL; } - return NULL; } static inline zval *_get_zval_ptr_deref(int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type TSRMLS_DC) { - zval *ret; - switch (op_type) { case IS_CONST: - should_free->var = NULL; + *should_free = NULL; return node->zv; - break; case IS_TMP_VAR: - ret = EX_VAR(node->var); - should_free->var = ret; - return ret; - break; + return _get_zval_ptr_tmp(node->var, execute_data, should_free); case IS_VAR: - return _get_zval_ptr_var_deref(node->var, execute_data, should_free TSRMLS_CC); - break; - case IS_UNUSED: - should_free->var = NULL; - return NULL; - break; + return _get_zval_ptr_var_deref(node->var, execute_data, should_free); case IS_CV: - default: - should_free->var = NULL; + *should_free = NULL; return _get_zval_ptr_cv_deref(execute_data, node->var, type TSRMLS_CC); - break; + default: + *should_free = NULL; + return NULL; } - return NULL; } -static zend_always_inline zval *_get_zval_ptr_ptr_var(uint32_t var, const zend_execute_data *execute_data, zend_free_op *should_free TSRMLS_DC) +static zend_always_inline zval *_get_zval_ptr_ptr_var(uint32_t var, const zend_execute_data *execute_data, zend_free_op *should_free) { zval *ret = EX_VAR(var); if (EXPECTED(Z_TYPE_P(ret) == IS_INDIRECT)) { - should_free->var = NULL; - return Z_INDIRECT_P(ret); - } else if (!Z_REFCOUNTED_P(ret) || Z_REFCOUNT_P(ret) == 1) { - should_free->var = ret; - return ret; + *should_free = NULL; + ret = Z_INDIRECT_P(ret); } else { - Z_DELREF_P(ret); - should_free->var = NULL; - return ret; + *should_free = ret; + if (Z_REFCOUNTED_P(ret) && Z_REFCOUNT_P(ret) > 1) { + *should_free = NULL; + Z_DELREF_P(ret); + } } + return ret; } static inline zval *_get_zval_ptr_ptr(int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type TSRMLS_DC) { if (op_type == IS_CV) { - should_free->var = NULL; + *should_free = NULL; return _get_zval_ptr_cv(execute_data, node->var, type TSRMLS_CC); } else /* if (op_type == IS_VAR) */ { ZEND_ASSERT(op_type == IS_VAR); - return _get_zval_ptr_ptr_var(node->var, execute_data, should_free TSRMLS_CC); + return _get_zval_ptr_ptr_var(node->var, execute_data, should_free); } } -static zend_always_inline zval *_get_obj_zval_ptr_unused(zend_execute_data *execute_data TSRMLS_DC) +static zend_always_inline zval *_get_obj_zval_ptr_unused(zend_execute_data *execute_data) { if (EXPECTED(Z_OBJ(EX(This)) != NULL)) { return &EX(This); @@ -492,7 +470,7 @@ static inline zval *_get_obj_zval_ptr(int op_type, znode_op *op, zend_execute_da { if (op_type == IS_UNUSED) { if (EXPECTED(Z_OBJ(EX(This)) != NULL)) { - should_free->var = NULL; + *should_free = NULL; return &EX(This); } else { zend_error_noreturn(E_ERROR, "Using $this when not in object context"); @@ -505,7 +483,7 @@ static inline zval *_get_obj_zval_ptr_ptr(int op_type, const znode_op *node, zen { if (op_type == IS_UNUSED) { if (EXPECTED(Z_OBJ(EX(This)) != NULL)) { - should_free->var = NULL; + *should_free = NULL; return &EX(This); } else { zend_error_noreturn(E_ERROR, "Using $this when not in object context"); @@ -596,7 +574,17 @@ ZEND_API void zend_verify_arg_error(int error_type, const zend_function *zf, uin } } -static void zend_verify_arg_type(zend_function *zf, uint32_t arg_num, zval *arg TSRMLS_DC) +static inline int zend_arg_allows_null(zend_bool allow_null, zval *default_value TSRMLS_DC) +{ + if (allow_null < 2 || !default_value) { + return allow_null; + } + + /* assuming update_constant_ex done before */ + return Z_TYPE_P(default_value) == IS_NULL; +} + +static void zend_verify_arg_type(zend_function *zf, uint32_t arg_num, zval *arg, zval *defaultval TSRMLS_DC) { zend_arg_info *cur_arg_info; char *need_msg; @@ -623,18 +611,18 @@ static void zend_verify_arg_type(zend_function *zf, uint32_t arg_num, zval *arg if (!ce || !instanceof_function(Z_OBJCE_P(arg), ce TSRMLS_CC)) { zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, "instance of ", Z_OBJCE_P(arg)->name->val, arg TSRMLS_CC); } - } else if (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null) { + } else if (Z_TYPE_P(arg) != IS_NULL || !zend_arg_allows_null(cur_arg_info->allow_null, defaultval TSRMLS_CC)) { need_msg = zend_verify_arg_class_kind(cur_arg_info, &class_name, &ce TSRMLS_CC); zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, zend_zval_type_name(arg), "", arg TSRMLS_CC); } } else if (cur_arg_info->type_hint) { if (cur_arg_info->type_hint == IS_ARRAY) { ZVAL_DEREF(arg); - if (Z_TYPE_P(arg) != IS_ARRAY && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) { + if (Z_TYPE_P(arg) != IS_ARRAY && (Z_TYPE_P(arg) != IS_NULL || !zend_arg_allows_null(cur_arg_info->allow_null, defaultval TSRMLS_CC))) { zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be of the type array", "", zend_zval_type_name(arg), "", arg TSRMLS_CC); } } else if (cur_arg_info->type_hint == IS_CALLABLE) { - if (!zend_is_callable(arg, IS_CALLABLE_CHECK_SILENT, NULL TSRMLS_CC) && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) { + if (!zend_is_callable(arg, IS_CALLABLE_CHECK_SILENT, NULL TSRMLS_CC) && (Z_TYPE_P(arg) != IS_NULL || !zend_arg_allows_null(cur_arg_info->allow_null, defaultval TSRMLS_CC))) { zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be callable", "", zend_zval_type_name(arg), "", arg TSRMLS_CC); } #if ZEND_DEBUG @@ -704,7 +692,7 @@ static void zend_verify_missing_arg(zend_execute_data *execute_data, uint32_t ar static zend_always_inline void zend_assign_to_object(zval *retval, zval *object, uint32_t object_op_type, zval *property_name, int value_type, const znode_op *value_op, const zend_execute_data *execute_data, int opcode, void **cache_slot TSRMLS_DC) { zend_free_op free_value; - zval *value = get_zval_ptr(value_type, value_op, execute_data, &free_value, BP_VAR_R); + zval *value = get_zval_ptr_deref(value_type, value_op, execute_data, &free_value, BP_VAR_R); zval tmp; if (object_op_type != IS_UNUSED) { @@ -748,38 +736,101 @@ static zend_always_inline void zend_assign_to_object(zval *retval, zval *object, } } - /* separate our value if necessary */ - if (value_type == IS_TMP_VAR) { - ZVAL_COPY_VALUE(&tmp, value); - value = &tmp; - } else if (value_type == IS_CONST) { - if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { - ZVAL_COPY_VALUE(&tmp, value); - zval_copy_ctor_func(&tmp); - value = &tmp; - } - } else if (Z_REFCOUNTED_P(value)) { - Z_ADDREF_P(value); - } - if (opcode == ZEND_ASSIGN_OBJ) { if (!Z_OBJ_HT_P(object)->write_property) { zend_error(E_WARNING, "Attempt to assign property of non-object"); if (retval) { ZVAL_NULL(retval); } - if (value_type == IS_CONST) { - zval_ptr_dtor(value); - } FREE_OP(free_value); return; } + + if (cache_slot && + EXPECTED(Z_OBJCE_P(object) == CACHED_PTR_EX(cache_slot))) { + zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 1); + zend_object *zobj = Z_OBJ_P(object); + zval *property; + + if (EXPECTED(prop_info)) { + property = OBJ_PROP(zobj, prop_info->offset); + if (Z_TYPE_P(property) != IS_UNDEF) { +fast_assign: + value = zend_assign_to_variable(property, value, value_type TSRMLS_CC); + if (retval && !EG(exception)) { + ZVAL_COPY(retval, value); + } + if (value_type == IS_VAR) { + FREE_OP(free_value); + } + return; + } + } else { + if (EXPECTED(zobj->properties != NULL)) { + property = zend_hash_find(zobj->properties, Z_STR_P(property_name)); + if (property) { + goto fast_assign; + } + } + + if (!zobj->ce->__set) { + if (EXPECTED(zobj->properties == NULL)) { + rebuild_object_properties(zobj); + } + /* separate our value if necessary */ + if (value_type == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (value_type != IS_TMP_VAR && + Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + zend_hash_add_new(zobj->properties, Z_STR_P(property_name), value); + if (retval && !EG(exception)) { + ZVAL_COPY(retval, value); + } + if (value_type == IS_VAR) { + FREE_OP(free_value); + } + return; + } + } + } + + /* separate our value if necessary */ + if (value_type == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (value_type != IS_TMP_VAR && + Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + Z_OBJ_HT_P(object)->write_property(object, property_name, value, cache_slot TSRMLS_CC); } else { /* Note: property_name in this case is really the array index! */ if (!Z_OBJ_HT_P(object)->write_dimension) { zend_error_noreturn(E_ERROR, "Cannot use object as array"); } + + /* separate our value if necessary */ + if (value_type == IS_CONST) { + if (UNEXPECTED(Z_OPT_COPYABLE_P(value))) { + ZVAL_COPY_VALUE(&tmp, value); + zval_copy_ctor_func(&tmp); + value = &tmp; + } + } else if (value_type != IS_TMP_VAR && + Z_REFCOUNTED_P(value)) { + Z_ADDREF_P(value); + } + Z_OBJ_HT_P(object)->write_dimension(object, property_name, value TSRMLS_CC); } @@ -842,65 +893,6 @@ static void zend_assign_to_string_offset(zval *str, zend_long offset, zval *valu } } -static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval *value, zend_uchar value_type TSRMLS_DC) -{ - do { - if (UNEXPECTED(Z_REFCOUNTED_P(variable_ptr))) { - zend_refcounted *garbage; - - if (Z_ISREF_P(variable_ptr)) { - variable_ptr = Z_REFVAL_P(variable_ptr); - if (EXPECTED(!Z_REFCOUNTED_P(variable_ptr))) { - break; - } - } - if (Z_TYPE_P(variable_ptr) == IS_OBJECT && - UNEXPECTED(Z_OBJ_HANDLER_P(variable_ptr, set) != NULL)) { - Z_OBJ_HANDLER_P(variable_ptr, set)(variable_ptr, value TSRMLS_CC); - return variable_ptr; - } - if ((value_type & (IS_VAR|IS_CV)) && variable_ptr == value) { - return variable_ptr; - } - garbage = Z_COUNTED_P(variable_ptr); - if (--GC_REFCOUNT(garbage) == 0) { - ZVAL_COPY_VALUE(variable_ptr, value); - if (value_type == IS_CONST) { - /* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */ - if (UNEXPECTED(Z_OPT_COPYABLE_P(variable_ptr))) { - zval_copy_ctor_func(variable_ptr); - } - } else if (value_type != IS_TMP_VAR) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(variable_ptr))) { - Z_ADDREF_P(variable_ptr); - } - } - _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC); - return variable_ptr; - } else { /* we need to split */ - /* optimized version of GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr) */ - if ((Z_COLLECTABLE_P(variable_ptr)) && - UNEXPECTED(!GC_INFO(garbage))) { - gc_possible_root(garbage TSRMLS_CC); - } - } - } - } while (0); - - ZVAL_COPY_VALUE(variable_ptr, value); - if (value_type == IS_CONST) { - /* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */ - if (UNEXPECTED(Z_OPT_COPYABLE_P(variable_ptr))) { - zval_copy_ctor_func(variable_ptr); - } - } else if (value_type != IS_TMP_VAR) { - if (UNEXPECTED(Z_OPT_REFCOUNTED_P(variable_ptr))) { - Z_ADDREF_P(variable_ptr); - } - } - return variable_ptr; -} - /* Utility Functions for Extensions */ static void zend_extension_statement_handler(const zend_extension *extension, zend_op_array *op_array TSRMLS_DC) { @@ -1292,7 +1284,7 @@ ZEND_API void zend_fetch_dimension_by_zval(zval *result, zval *container, zval * zend_fetch_dimension_address_read_R(result, container, dim, IS_TMP_VAR TSRMLS_CC); } -static zend_always_inline void zend_fetch_property_address(zval *result, zval *container, uint32_t container_op_type, zval *prop_ptr, void **cache_slot, int type TSRMLS_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 TSRMLS_DC) { if (container_op_type != IS_UNUSED) { ZVAL_DEREF(container); @@ -1316,6 +1308,26 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c } } } + if (prop_op_type == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR_EX(cache_slot))) { + zend_property_info *prop_info = CACHED_PTR_EX(cache_slot + 1); + zend_object *zobj = Z_OBJ_P(container); + zval *retval; + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_INDIRECT(result, retval); + return; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(prop_ptr)); + if (EXPECTED(retval)) { + ZVAL_INDIRECT(result, retval); + return; + } + } + } if (EXPECTED(Z_OBJ_HT_P(container)->get_property_ptr_ptr)) { zval *ptr = Z_OBJ_HT_P(container)->get_property_ptr_ptr(container, prop_ptr, type, cache_slot TSRMLS_CC); if (NULL == ptr) { diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index 982413e032..38b52820b5 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -55,7 +55,6 @@ static zend_always_inline void i_zval_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC { if (Z_REFCOUNTED_P(zval_ptr)) { if (!Z_DELREF_P(zval_ptr)) { - ZEND_ASSERT(zval_ptr != &EG(uninitialized_zval)); _zval_dtor_func_for_ptr(Z_COUNTED_P(zval_ptr) ZEND_FILE_LINE_RELAY_CC); } else { GC_ZVAL_CHECK_POSSIBLE_ROOT(zval_ptr); @@ -129,6 +128,65 @@ again: return result; } +static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval *value, zend_uchar value_type TSRMLS_DC) +{ + do { + if (UNEXPECTED(Z_REFCOUNTED_P(variable_ptr))) { + zend_refcounted *garbage; + + if (Z_ISREF_P(variable_ptr)) { + variable_ptr = Z_REFVAL_P(variable_ptr); + if (EXPECTED(!Z_REFCOUNTED_P(variable_ptr))) { + break; + } + } + if (Z_TYPE_P(variable_ptr) == IS_OBJECT && + UNEXPECTED(Z_OBJ_HANDLER_P(variable_ptr, set) != NULL)) { + Z_OBJ_HANDLER_P(variable_ptr, set)(variable_ptr, value TSRMLS_CC); + return variable_ptr; + } + if ((value_type & (IS_VAR|IS_CV)) && variable_ptr == value) { + return variable_ptr; + } + garbage = Z_COUNTED_P(variable_ptr); + if (--GC_REFCOUNT(garbage) == 0) { + ZVAL_COPY_VALUE(variable_ptr, value); + if (value_type == IS_CONST) { + /* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */ + if (UNEXPECTED(Z_OPT_COPYABLE_P(variable_ptr))) { + zval_copy_ctor_func(variable_ptr); + } + } else if (value_type != IS_TMP_VAR) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(variable_ptr))) { + Z_ADDREF_P(variable_ptr); + } + } + _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC); + return variable_ptr; + } else { /* we need to split */ + /* optimized version of GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr) */ + if ((Z_COLLECTABLE_P(variable_ptr)) && + UNEXPECTED(!GC_INFO(garbage))) { + gc_possible_root(garbage TSRMLS_CC); + } + } + } + } while (0); + + ZVAL_COPY_VALUE(variable_ptr, value); + if (value_type == IS_CONST) { + /* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */ + if (UNEXPECTED(Z_OPT_COPYABLE_P(variable_ptr))) { + zval_copy_ctor_func(variable_ptr); + } + } else if (value_type != IS_TMP_VAR) { + if (UNEXPECTED(Z_OPT_REFCOUNTED_P(variable_ptr))) { + Z_ADDREF_P(variable_ptr); + } + } + return variable_ptr; +} + ZEND_API int zval_update_constant(zval *pp, zend_bool inline_change TSRMLS_DC); ZEND_API int zval_update_constant_inline_change(zval *pp, zend_class_entry *scope TSRMLS_DC); ZEND_API int zval_update_constant_no_inline_change(zval *pp, zend_class_entry *scope TSRMLS_DC); @@ -261,10 +319,7 @@ ZEND_API int zend_set_user_opcode_handler(zend_uchar opcode, user_opcode_handler ZEND_API user_opcode_handler_t zend_get_user_opcode_handler(zend_uchar opcode); /* former zend_execute_locks.h */ -typedef struct _zend_free_op { - zval *var; -/* int is_var; */ -} zend_free_op; +typedef zval* zend_free_op; ZEND_API zval *zend_get_zval_ptr(int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type TSRMLS_DC); diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 5edc65e93e..5b31f465ca 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -51,8 +51,8 @@ static WNDCLASS wc; static HWND timeout_window; static HANDLE timeout_thread_event; static HANDLE timeout_thread_handle; -static DWORD timeout_thread_id; -static int timeout_thread_initialized=0; +static unsigned timeout_thread_id; +static volatile long timeout_thread_initialized=0; #endif #if 0&&ZEND_DEBUG @@ -1166,6 +1166,10 @@ ZEND_API void zend_timeout(int dummy) /* {{{ */ #ifdef ZEND_WIN32 static LRESULT CALLBACK zend_timeout_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) /* {{{ */ { +#ifdef ZTS + THREAD_T thread_id = (THREAD_T)wParam; +#endif + switch (message) { case WM_DESTROY: PostQuitMessage(0); @@ -1180,7 +1184,7 @@ static LRESULT CALLBACK zend_timeout_WndProc(HWND hWnd, UINT message, WPARAM wPa #endif SetTimer(timeout_window, wParam, lParam*1000, NULL); #ifdef ZTS - tsrm_ls = ts_resource_ex(0, &wParam); + tsrm_ls = ts_resource_ex(0, &thread_id); if (!tsrm_ls) { /* shouldn't normally happen */ break; @@ -1197,7 +1201,7 @@ static LRESULT CALLBACK zend_timeout_WndProc(HWND hWnd, UINT message, WPARAM wPa #ifdef ZTS void ***tsrm_ls; - tsrm_ls = ts_resource_ex(0, &wParam); + tsrm_ls = ts_resource_ex(0, &thread_id); if (!tsrm_ls) { /* Thread died before receiving its timeout? */ break; diff --git a/Zend/zend_float.h b/Zend/zend_float.h index 33f8e93fbf..008bf07854 100644 --- a/Zend/zend_float.h +++ b/Zend/zend_float.h @@ -21,6 +21,8 @@ #ifndef ZEND_FLOAT_H #define ZEND_FLOAT_H +BEGIN_EXTERN_C() + /* Define functions for FP initialization and de-initialization. */ @@ -28,6 +30,8 @@ extern ZEND_API void zend_init_fpu(TSRMLS_D); extern ZEND_API void zend_shutdown_fpu(TSRMLS_D); extern ZEND_API void zend_ensure_fpu_mode(TSRMLS_D); +END_EXTERN_C() + /* Copy of the contents of xpfpa.h (which is under public domain) See http://wiki.php.net/rfc/rounding for details. @@ -53,7 +57,7 @@ extern ZEND_API void zend_ensure_fpu_mode(TSRMLS_D); Implementation notes: x86_64: - - Since all x86_64 compilers use SSE by default, it is probably unecessary + - Since all x86_64 compilers use SSE by default, it is probably unnecessary to use these macros there. We define them anyway since we are too lazy to differentiate the architecture. Also, the compiler option -mfpmath=i387 justifies this decision. diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c index b331f979fd..e47b5350d4 100644 --- a/Zend/zend_gc.c +++ b/Zend/zend_gc.c @@ -469,7 +469,7 @@ tail_call: ht = NULL; GC_SET_BLACK(GC_INFO(ref)); - /* don't count references for compatibilty ??? */ + /* don't count references for compatibility ??? */ if (GC_TYPE(ref) != IS_REFERENCE) { count++; } @@ -515,7 +515,7 @@ tail_call: ZVAL_OBJ(&tmp, obj); props = get_gc(&tmp, &table, &n TSRMLS_CC); while (n > 0 && !Z_REFCOUNTED(table[n-1])) { - /* count non-refcounted for compatibilty ??? */ + /* count non-refcounted for compatibility ??? */ if (Z_TYPE(table[n-1]) != IS_UNDEF) { count++; } @@ -532,7 +532,7 @@ tail_call: } else { count += gc_collect_white(ref TSRMLS_CC); } - /* count non-refcounted for compatibilty ??? */ + /* count non-refcounted for compatibility ??? */ } else if (Z_TYPE(table[i]) != IS_UNDEF) { count++; } @@ -563,7 +563,7 @@ tail_call: for (idx = 0; idx < ht->nNumUsed; idx++) { p = ht->arData + idx; if (!Z_REFCOUNTED(p->val)) { - /* count non-refcounted for compatibilty ??? */ + /* count non-refcounted for compatibility ??? */ if (Z_TYPE(p->val) != IS_UNDEF && Z_TYPE(p->val) != IS_INDIRECT) { count++; } diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index 6dc0941c6f..24be94f0d9 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -100,7 +100,7 @@ static const uint32_t uninitialized_bucket = {INVALID_IDX}; ZEND_API void _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent ZEND_FILE_LINE_DC) { /* Use big enough power of 2 */ -#ifdef PHP_WIN32 +#if defined(PHP_WIN32) && !defined(__clang__) if (nSize <= 8) { ht->nTableSize = 8; } else if (nSize >= 0x80000000) { @@ -269,14 +269,12 @@ static zend_always_inline zval *_zend_hash_add_or_update_i(HashTable *ht, zend_s IS_CONSISTENT(ht); - CHECK_INIT(ht, 0); - if (ht->u.flags & HASH_FLAG_PACKED) { + if (UNEXPECTED(ht->nTableMask == 0)) { + CHECK_INIT(ht, 0); + goto add_to_hash; + } else if (ht->u.flags & HASH_FLAG_PACKED) { zend_hash_packed_to_hash(ht); - } - - h = zend_string_hash_val(key); - - if ((flag & HASH_ADD_NEW) == 0) { + } else if ((flag & HASH_ADD_NEW) == 0) { p = zend_hash_find_bucket(ht, key); if (p) { @@ -302,6 +300,7 @@ static zend_always_inline zval *_zend_hash_add_or_update_i(HashTable *ht, zend_s ZEND_HASH_IF_FULL_DO_RESIZE(ht); /* If the Hash table is full, resize it */ +add_to_hash: HANDLE_BLOCK_INTERRUPTIONS(); idx = ht->nNumUsed++; ht->nNumOfElements++; @@ -309,7 +308,7 @@ static zend_always_inline zval *_zend_hash_add_or_update_i(HashTable *ht, zend_s ht->nInternalPointer = idx; } p = ht->arData + idx; - p->h = h; + p->h = h = zend_string_hash_val(key); p->key = key; zend_string_addref(key); ZVAL_COPY_VALUE(&p->val, pData); @@ -423,9 +422,15 @@ static zend_always_inline zval *_zend_hash_index_add_or_update_i(HashTable *ht, #endif IS_CONSISTENT(ht); - CHECK_INIT(ht, h < ht->nTableSize); - if (ht->u.flags & HASH_FLAG_PACKED) { + if (UNEXPECTED(ht->nTableMask == 0)) { + CHECK_INIT(ht, h < ht->nTableSize); + if (h < ht->nTableSize) { + p = ht->arData + h; + goto add_to_packed; + } + goto add_to_hash; + } else if (ht->u.flags & HASH_FLAG_PACKED) { if (h < ht->nNumUsed) { p = ht->arData + h; if (Z_TYPE(p->val) != IS_UNDEF) { @@ -453,6 +458,7 @@ static zend_always_inline zval *_zend_hash_index_add_or_update_i(HashTable *ht, goto convert_to_hash; } +add_to_packed: HANDLE_BLOCK_INTERRUPTIONS(); /* incremental initialization of empty Buckets */ if ((flag & (HASH_ADD_NEW|HASH_ADD_NEXT)) == (HASH_ADD_NEW|HASH_ADD_NEXT)) { @@ -477,7 +483,6 @@ static zend_always_inline zval *_zend_hash_index_add_or_update_i(HashTable *ht, p->h = h; p->key = NULL; ZVAL_COPY_VALUE(&p->val, pData); - Z_NEXT(p->val) = INVALID_IDX; HANDLE_UNBLOCK_INTERRUPTIONS(); @@ -485,9 +490,7 @@ static zend_always_inline zval *_zend_hash_index_add_or_update_i(HashTable *ht, convert_to_hash: zend_hash_packed_to_hash(ht); - } - - if ((flag & HASH_ADD_NEW) == 0) { + } else if ((flag & HASH_ADD_NEW) == 0) { p = zend_hash_index_find_bucket(ht, h); if (p) { if (flag & HASH_ADD) { @@ -509,6 +512,7 @@ convert_to_hash: ZEND_HASH_IF_FULL_DO_RESIZE(ht); /* If the Hash table is full, resize it */ +add_to_hash: HANDLE_BLOCK_INTERRUPTIONS(); idx = ht->nNumUsed++; ht->nNumOfElements++; @@ -1693,8 +1697,7 @@ ZEND_API int zend_hash_sort(HashTable *ht, sort_func_t sort_func, p->key = NULL; } } - } - if (renumber) { + ht->nNextFreeElement = i; } if (ht->u.flags & HASH_FLAG_PACKED) { diff --git a/Zend/zend_inheritance.c b/Zend/zend_inheritance.c index c6f8c6ae15..43ef22074f 100644 --- a/Zend/zend_inheritance.c +++ b/Zend/zend_inheritance.c @@ -602,9 +602,12 @@ static zend_bool do_inherit_property_access_check(HashTable *target_ht, zend_pro if ((child_info->flags & ZEND_ACC_PPP_MASK) > (parent_info->flags & ZEND_ACC_PPP_MASK)) { zend_error_noreturn(E_COMPILE_ERROR, "Access level to %s::$%s must be %s (as in class %s)%s", ce->name->val, key->val, zend_visibility_string(parent_info->flags), parent_ce->name->val, (parent_info->flags&ZEND_ACC_PUBLIC) ? "" : " or weaker"); } else if ((child_info->flags & ZEND_ACC_STATIC) == 0) { - zval_ptr_dtor(&(ce->default_properties_table[parent_info->offset])); - ce->default_properties_table[parent_info->offset] = ce->default_properties_table[child_info->offset]; - ZVAL_UNDEF(&ce->default_properties_table[child_info->offset]); + int parent_num = OBJ_PROP_TO_NUM(parent_info->offset); + int child_num = OBJ_PROP_TO_NUM(child_info->offset); + + zval_ptr_dtor(&(ce->default_properties_table[parent_num])); + ce->default_properties_table[parent_num] = ce->default_properties_table[child_num]; + ZVAL_UNDEF(&ce->default_properties_table[child_num]); child_info->offset = parent_info->offset; } return 0; /* Don't copy from parent */ @@ -797,7 +800,7 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent if (property_info->flags & ZEND_ACC_STATIC) { property_info->offset += parent_ce->default_static_members_count; } else { - property_info->offset += parent_ce->default_properties_count; + property_info->offset += parent_ce->default_properties_count * sizeof(zval); } } } ZEND_HASH_FOREACH_END(); @@ -1203,7 +1206,7 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce TSRMLS_DC) /* } zend_check_trait_usage(ce, cur_precedence->trait_method->ce TSRMLS_CC); - /** Ensure that the prefered method is actually available. */ + /** Ensure that the preferred method is actually available. */ lcname = zend_string_alloc(cur_method_ref->method_name->len, 0); zend_str_tolower_copy(lcname->val, cur_method_ref->method_name->val, @@ -1235,7 +1238,7 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce TSRMLS_DC) /* /* make sure that the trait method is not from a class mentioned in exclude_from_classes, for consistency */ - if (cur_precedence->trait_method->ce == cur_precedence->exclude_from_classes[i].ce) { + if (cur_precedence->trait_method->ce == cur_precedence->exclude_from_classes[j].ce) { zend_error_noreturn(E_COMPILE_ERROR, "Inconsistent insteadof definition. " "The method %s is to be used from %s, but %s is also on the exclude list", @@ -1421,8 +1424,8 @@ static void zend_do_traits_property_binding(zend_class_entry *ce TSRMLS_DC) /* { || (Z_LVAL(compare_result) != 0); } else { not_compatible = (FAILURE == compare_function(&compare_result, - &ce->default_properties_table[coliding_prop->offset], - &ce->traits[i]->default_properties_table[property_info->offset] TSRMLS_CC)) + &ce->default_properties_table[OBJ_PROP_TO_NUM(coliding_prop->offset)], + &ce->traits[i]->default_properties_table[OBJ_PROP_TO_NUM(property_info->offset)] TSRMLS_CC)) || (Z_LVAL(compare_result) != 0); } } else { @@ -1454,7 +1457,7 @@ static void zend_do_traits_property_binding(zend_class_entry *ce TSRMLS_DC) /* { if (flags & ZEND_ACC_STATIC) { prop_value = &ce->traits[i]->default_static_members_table[property_info->offset]; } else { - prop_value = &ce->traits[i]->default_properties_table[property_info->offset]; + prop_value = &ce->traits[i]->default_properties_table[OBJ_PROP_TO_NUM(property_info->offset)]; } if (Z_REFCOUNTED_P(prop_value)) Z_ADDREF_P(prop_value); @@ -1504,7 +1507,7 @@ static void zend_do_check_for_inconsistent_traits_aliasing(zend_class_entry *ce lc_method_name)) { zend_string_free(lc_method_name); zend_error_noreturn(E_COMPILE_ERROR, - "The modifiers for the trait alias %s() need to be changed in the same statment in which the alias is defined. Error", + "The modifiers for the trait alias %s() need to be changed in the same statement in which the alias is defined. Error", cur_alias->trait_method->method_name->val); } else { zend_string_free(lc_method_name); diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 6b4e8f1a97..c474fa8662 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -80,11 +80,10 @@ ZEND_API void rebuild_object_properties(zend_object *zobj) /* {{{ */ ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop_info) { if (/*prop_info->ce == ce &&*/ (prop_info->flags & ZEND_ACC_STATIC) == 0 && - prop_info->offset >= 0 && - Z_TYPE(zobj->properties_table[prop_info->offset]) != IS_UNDEF) { + Z_TYPE_P(OBJ_PROP(zobj, prop_info->offset)) != IS_UNDEF) { zval zv; - ZVAL_INDIRECT(&zv, &zobj->properties_table[prop_info->offset]); + ZVAL_INDIRECT(&zv, OBJ_PROP(zobj, prop_info->offset)); zend_hash_add_new(zobj->properties, prop_info->name, &zv); } } ZEND_HASH_FOREACH_END(); @@ -94,11 +93,10 @@ ZEND_API void rebuild_object_properties(zend_object *zobj) /* {{{ */ if (prop_info->ce == ce && (prop_info->flags & ZEND_ACC_STATIC) == 0 && (prop_info->flags & ZEND_ACC_PRIVATE) != 0 && - prop_info->offset >= 0 && - Z_TYPE(zobj->properties_table[prop_info->offset]) != IS_UNDEF) { + Z_TYPE_P(OBJ_PROP(zobj, prop_info->offset)) != IS_UNDEF) { zval zv; - ZVAL_INDIRECT(&zv, &zobj->properties_table[prop_info->offset]); + ZVAL_INDIRECT(&zv, OBJ_PROP(zobj, prop_info->offset)); zend_hash_add(zobj->properties, prop_info->name, &zv); } } ZEND_HASH_FOREACH_END(); @@ -186,7 +184,7 @@ static void zend_std_call_getter(zval *object, zval *member, zval *retval TSRMLS /* __get handler is called with one argument: property name - it should return whether the call was successfull or not + it should return whether the call was successful or not */ if (Z_REFCOUNTED_P(member)) Z_ADDREF_P(member); @@ -209,7 +207,7 @@ static int zend_std_call_setter(zval *object, zval *member, zval *value TSRMLS_D property name value to be set - it should return whether the call was successfull or not + it should return whether the call was successful or not */ zend_call_method_with_2_params(object, ce, &ce->__set, ZEND_SET_FUNC_NAME, &retval, member, value); @@ -288,7 +286,7 @@ static zend_always_inline zend_bool is_derived_class(zend_class_entry *child_cla } /* }}} */ -static zend_always_inline zend_property_info *zend_get_property_info_quick(zend_class_entry *ce, zend_string *member, int silent, void **cache_slot TSRMLS_DC) /* {{{ */ +static zend_always_inline zend_property_info *zend_get_property_info_quick(zend_class_entry *ce, zend_string *member, int silent, int allow_static, void **cache_slot TSRMLS_DC) /* {{{ */ { zval *zv; zend_property_info *property_info = NULL; @@ -324,8 +322,13 @@ static zend_always_inline zend_property_info *zend_get_property_info_quick(zend_ if (EXPECTED(zend_verify_property_access(property_info, ce TSRMLS_CC) != 0)) { if (UNEXPECTED(!(flags & ZEND_ACC_CHANGED)) || UNEXPECTED((flags & ZEND_ACC_PRIVATE))) { - if (UNEXPECTED((flags & ZEND_ACC_STATIC) != 0) && !silent) { - zend_error(E_STRICT, "Accessing static property %s::$%s as non static", ce->name->val, member->val); + if (UNEXPECTED((flags & ZEND_ACC_STATIC) != 0)) { + if (!silent) { + zend_error(E_STRICT, "Accessing static property %s::$%s as non static", ce->name->val, member->val); + } + if (!allow_static) { + return NULL; + } } goto exit; } @@ -342,7 +345,9 @@ static zend_always_inline zend_property_info *zend_get_property_info_quick(zend_ && (zv = zend_hash_find(&EG(scope)->properties_info, member)) != NULL && ((zend_property_info*)Z_PTR_P(zv))->flags & ZEND_ACC_PRIVATE) { property_info = (zend_property_info*)Z_PTR_P(zv); - goto exit; + if (!allow_static && UNEXPECTED((property_info->flags & ZEND_ACC_STATIC) != 0)) { + return NULL; + } } else if (UNEXPECTED(property_info == NULL)) { exit_dynamic: if (cache_slot) { @@ -354,9 +359,6 @@ exit_dynamic: if (!silent) { zend_error_noreturn(E_ERROR, "Cannot access %s property %s::$%s", zend_visibility_string(flags), ce->name->val, member->val); } - if (cache_slot) { - CACHE_POLYMORPHIC_PTR_EX(cache_slot, ce, ZEND_WRONG_PROPERTY_INFO); - } return ZEND_WRONG_PROPERTY_INFO; } @@ -370,7 +372,7 @@ exit: ZEND_API zend_property_info *zend_get_property_info(zend_class_entry *ce, zend_string *member, int silent TSRMLS_DC) /* {{{ */ { - return zend_get_property_info_quick(ce, member, silent, NULL TSRMLS_CC); + return zend_get_property_info_quick(ce, member, silent, 1, NULL TSRMLS_CC); } /* }}} */ @@ -388,7 +390,7 @@ ZEND_API int zend_check_property_access(zend_object *zobj, zend_string *prop_inf } else { member = zend_string_copy(prop_info_name); } - property_info = zend_get_property_info_quick(zobj->ce, member, 1, NULL TSRMLS_CC); + property_info = zend_get_property_info_quick(zobj->ce, member, 1, 1, NULL TSRMLS_CC); zend_string_release(member); if (property_info == NULL) { /* undefined public property */ @@ -451,13 +453,11 @@ zval *zend_std_read_property(zval *object, zval *member, int type, void **cache_ #endif /* make zend_get_property_info silent if we have getter - we may want to use it */ - property_info = zend_get_property_info_quick(zobj->ce, Z_STR_P(member), (type == BP_VAR_IS) || (zobj->ce->__get != NULL), cache_slot TSRMLS_CC); + property_info = zend_get_property_info_quick(zobj->ce, Z_STR_P(member), (type == BP_VAR_IS) || (zobj->ce->__get != NULL), 0, cache_slot TSRMLS_CC); if (EXPECTED(property_info != ZEND_WRONG_PROPERTY_INFO)) { - if (EXPECTED(property_info != NULL) && - EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0)) { - - retval = &zobj->properties_table[property_info->offset]; + if (EXPECTED(property_info != NULL)) { + retval = OBJ_PROP(zobj, property_info->offset); if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { goto exit; } @@ -534,64 +534,18 @@ ZEND_API void zend_std_write_property(zval *object, zval *member, zval *value, v cache_slot = NULL; } - property_info = zend_get_property_info_quick(zobj->ce, Z_STR_P(member), (zobj->ce->__set != NULL), cache_slot TSRMLS_CC); + property_info = zend_get_property_info_quick(zobj->ce, Z_STR_P(member), (zobj->ce->__set != NULL), 0, cache_slot TSRMLS_CC); if (EXPECTED(property_info != ZEND_WRONG_PROPERTY_INFO)) { - if (EXPECTED(property_info != NULL) && - EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0)) { - - variable_ptr = &zobj->properties_table[property_info->offset]; + if (EXPECTED(property_info != NULL)) { + variable_ptr = OBJ_PROP(zobj, property_info->offset); if (Z_TYPE_P(variable_ptr) != IS_UNDEF) { goto found; } } else if (EXPECTED(zobj->properties != NULL)) { if ((variable_ptr = zend_hash_find(zobj->properties, Z_STR_P(member))) != NULL) { found: - /* if we already have this value there, we don't actually need to do anything */ - if (EXPECTED(variable_ptr != value)) { - /* if we are assigning reference, we shouldn't move it, but instead assign variable - to the same pointer */ - if (Z_ISREF_P(variable_ptr)) { - zval garbage; - - ZVAL_COPY_VALUE(&garbage, Z_REFVAL_P(variable_ptr)); /* old value should be destroyed */ - - /* To check: can't *variable_ptr be some system variable like error_zval here? */ - if (UNEXPECTED(Z_REFCOUNTED_P(value))) { - if (EXPECTED(!Z_ISREF_P(value))) { - Z_ADDREF_P(value); - } else { - if (Z_REFCOUNT_P(value) == 1) { - ZVAL_UNREF(value); - } else { - value = Z_REFVAL_P(value); - } - if (Z_REFCOUNTED_P(value)) { - if (UNEXPECTED(Z_REFVAL_P(variable_ptr) == value)) { - goto exit; - } - Z_ADDREF_P(value); - } - } - } - ZVAL_COPY_VALUE(Z_REFVAL_P(variable_ptr), value); - zval_ptr_dtor(&garbage); - } else { - zval garbage; - - ZVAL_COPY_VALUE(&garbage, variable_ptr); - - /* if we assign referenced variable, we should separate it */ - ZVAL_COPY_VALUE(variable_ptr, value); - if (Z_REFCOUNTED_P(variable_ptr)) { - Z_ADDREF_P(variable_ptr); - if (Z_ISREF_P(variable_ptr)) { - SEPARATE_ZVAL(variable_ptr); - } - } - zval_ptr_dtor(&garbage); - } - } + zend_assign_to_variable(variable_ptr, value, (IS_VAR|IS_TMP_VAR) TSRMLS_CC); goto exit; } } @@ -638,12 +592,12 @@ write_std_property: if (EXPECTED(property_info != NULL) && EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0)) { - ZVAL_COPY_VALUE(&zobj->properties_table[property_info->offset], value); + ZVAL_COPY_VALUE(OBJ_PROP(zobj, property_info->offset), value); } else { if (!zobj->properties) { rebuild_object_properties(zobj); } - zend_hash_update(zobj->properties, Z_STR_P(member), value); + zend_hash_add_new(zobj->properties, Z_STR_P(member), value); } } @@ -754,13 +708,11 @@ static zval *zend_std_get_property_ptr_ptr(zval *object, zval *member, int type, fprintf(stderr, "Ptr object #%d property: %s\n", Z_OBJ_HANDLE_P(object), name->val); #endif - property_info = zend_get_property_info_quick(zobj->ce, name, (zobj->ce->__get != NULL), cache_slot TSRMLS_CC); + property_info = zend_get_property_info_quick(zobj->ce, name, (zobj->ce->__get != NULL), 0, cache_slot TSRMLS_CC); if (EXPECTED(property_info != ZEND_WRONG_PROPERTY_INFO)) { - if (EXPECTED(property_info != NULL) && - EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0)) { - - retval = &zobj->properties_table[property_info->offset]; + if (EXPECTED(property_info != NULL)) { + retval = OBJ_PROP(zobj, property_info->offset); if (UNEXPECTED(Z_TYPE_P(retval) == IS_UNDEF)) { if (EXPECTED(!zobj->ce->__get) || UNEXPECTED((*zend_get_property_guard(zobj, name)) & IN_GET)) { @@ -816,15 +768,15 @@ static void zend_std_unset_property(zval *object, zval *member, void **cache_slo cache_slot = NULL; } - property_info = zend_get_property_info_quick(zobj->ce, Z_STR_P(member), (zobj->ce->__unset != NULL), cache_slot TSRMLS_CC); + property_info = zend_get_property_info_quick(zobj->ce, Z_STR_P(member), (zobj->ce->__unset != NULL), 0, cache_slot TSRMLS_CC); if (EXPECTED(property_info != ZEND_WRONG_PROPERTY_INFO)) { - if (EXPECTED(property_info != NULL) && - EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0)) { + if (EXPECTED(property_info != NULL)) { + zval *slot = OBJ_PROP(zobj, property_info->offset); - if (Z_TYPE(zobj->properties_table[property_info->offset]) != IS_UNDEF) { - zval_ptr_dtor(&zobj->properties_table[property_info->offset]); - ZVAL_UNDEF(&zobj->properties_table[property_info->offset]); + if (Z_TYPE_P(slot) != IS_UNDEF) { + zval_ptr_dtor(slot); + ZVAL_UNDEF(slot); goto exit; } } else if (EXPECTED(zobj->properties != NULL) && @@ -1413,13 +1365,11 @@ static int zend_std_has_property(zval *object, zval *member, int has_set_exists, cache_slot = NULL; } - property_info = zend_get_property_info_quick(zobj->ce, Z_STR_P(member), 1, cache_slot TSRMLS_CC); + property_info = zend_get_property_info_quick(zobj->ce, Z_STR_P(member), 1, 0, cache_slot TSRMLS_CC); if (EXPECTED(property_info != ZEND_WRONG_PROPERTY_INFO)) { - if (EXPECTED(property_info != NULL) && - EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0)) { - - value = &zobj->properties_table[property_info->offset]; + if (EXPECTED(property_info != NULL)) { + value = OBJ_PROP(zobj, property_info->offset); if (Z_TYPE_P(value) != IS_UNDEF) { goto found; } diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c index 58c034163e..9068dceb8b 100644 --- a/Zend/zend_objects.c +++ b/Zend/zend_objects.c @@ -47,7 +47,7 @@ ZEND_API void zend_object_std_init(zend_object *object, zend_class_entry *ce TSR ZEND_API void zend_object_std_dtor(zend_object *object TSRMLS_DC) { - int i; + int i, count; if (object->guards) { zend_hash_destroy(object->guards); @@ -57,8 +57,9 @@ ZEND_API void zend_object_std_dtor(zend_object *object TSRMLS_DC) zend_hash_destroy(object->properties); FREE_HASHTABLE(object->properties); } - for (i = 0; i < object->ce->default_properties_count; i++) { - zval_ptr_dtor(&object->properties_table[i]); + count = object->ce->default_properties_count; + for (i = 0; i < count; i++) { + i_zval_ptr_dtor(&object->properties_table[i] ZEND_FILE_LINE_CC TSRMLS_CC); } } diff --git a/Zend/zend_portability.h b/Zend/zend_portability.h index c159fdc77b..73a4f3b962 100644 --- a/Zend/zend_portability.h +++ b/Zend/zend_portability.h @@ -74,6 +74,10 @@ # include <alloca.h> #endif +#if defined(ZEND_WIN32) +#include <intrin.h> +#endif + /* Only use this macro if you know for sure that all of the switches values are covered by its case statements */ #if ZEND_DEBUG @@ -390,6 +394,13 @@ char *alloca(); #define ZEND_SECURE_ZERO(var, size) memset((var), 0, (size)) #endif +/* This check should only be used on network socket, not file descriptors */ +#ifdef ZEND_WIN32 +#define ZEND_VALID_SOCKET(sock) (INVALID_SOCKET != (sock)) +#else +#define ZEND_VALID_SOCKET(sock) ((sock) >= 0) +#endif + #endif /* ZEND_PORTABILITY_H */ /* diff --git a/Zend/zend_types.h b/Zend/zend_types.h index 383f77caa4..b07a62668c 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -145,9 +145,9 @@ struct _zend_string { }; typedef struct _Bucket { + zval val; zend_ulong h; /* hash value (or numeric index) */ zend_string *key; /* string key or NULL for numerics */ - zval val; } Bucket; typedef struct _HashTable { diff --git a/Zend/zend_virtual_cwd.c b/Zend/zend_virtual_cwd.c index 385df393bf..509b33e369 100644 --- a/Zend/zend_virtual_cwd.c +++ b/Zend/zend_virtual_cwd.c @@ -347,7 +347,7 @@ CWD_API int php_sys_stat_ex(const char *path, zend_stat_t *buf, int lstat) /* {{ /* File is a reparse point. Get the target */ HANDLE hLink = NULL; REPARSE_DATA_BUFFER * pbuffer; - unsigned int retlength = 0; + DWORD retlength = 0; hLink = CreateFile(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, NULL); if(hLink == INVALID_HANDLE_VALUE) { @@ -898,7 +898,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i /* File is a reparse point. Get the target */ HANDLE hLink = NULL; REPARSE_DATA_BUFFER * pbuffer; - unsigned int retlength = 0; + DWORD retlength = 0; int bufindex = 0, isabsolute = 0; wchar_t * reparsetarget; BOOL isVolume = FALSE; @@ -1540,55 +1540,6 @@ CWD_API int virtual_access(const char *pathname, int mode TSRMLS_DC) /* {{{ */ /* }}} */ #if HAVE_UTIME -#ifdef TSRM_WIN32 -static void UnixTimeToFileTime(time_t t, LPFILETIME pft) /* {{{ */ -{ - // Note that LONGLONG is a 64-bit value - LONGLONG ll; - - ll = Int32x32To64(t, 10000000) + 116444736000000000; - pft->dwLowDateTime = (DWORD)ll; - pft->dwHighDateTime = ll >> 32; -} -/* }}} */ - -TSRM_API int win32_utime(const char *filename, struct utimbuf *buf) /* {{{ */ -{ - FILETIME mtime, atime; - HANDLE hFile; - - hFile = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_WRITE|FILE_SHARE_READ, NULL, - OPEN_ALWAYS, FILE_FLAG_BACKUP_SEMANTICS, NULL); - - /* OPEN_ALWAYS mode sets the last error to ERROR_ALREADY_EXISTS but - the CreateFile operation succeeds */ - if (GetLastError() == ERROR_ALREADY_EXISTS) { - SetLastError(0); - } - - if ( hFile == INVALID_HANDLE_VALUE ) { - return -1; - } - - if (!buf) { - SYSTEMTIME st; - GetSystemTime(&st); - SystemTimeToFileTime(&st, &mtime); - atime = mtime; - } else { - UnixTimeToFileTime(buf->modtime, &mtime); - UnixTimeToFileTime(buf->actime, &atime); - } - if (!SetFileTime(hFile, NULL, &atime, &mtime)) { - CloseHandle(hFile); - return -1; - } - CloseHandle(hFile); - return 1; -} -/* }}} */ -#endif - CWD_API int virtual_utime(const char *filename, struct utimbuf *buf TSRMLS_DC) /* {{{ */ { cwd_state new_state; diff --git a/Zend/zend_vm.h b/Zend/zend_vm.h index 078be15b74..e403e7cc92 100644 --- a/Zend/zend_vm.h +++ b/Zend/zend_vm.h @@ -21,9 +21,13 @@ #ifndef ZEND_VM_H #define ZEND_VM_H +BEGIN_EXTERN_C() + ZEND_API void zend_vm_use_old_executor(void); ZEND_API void zend_vm_set_opcode_handler(zend_op* opcode); +END_EXTERN_C() + #define ZEND_VM_SET_OPCODE_HANDLER(opline) zend_vm_set_opcode_handler(opline) #endif diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 60983e516f..95968d8ac6 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -385,7 +385,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -711,7 +711,7 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR| zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -798,7 +798,7 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMP|VAR zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -1199,7 +1199,7 @@ ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VAR|CV, CONST|TMP|VAR|UNUSED|CV) ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC); FREE_OP2(); - if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } FREE_OP1_VAR_PTR(); @@ -1222,7 +1222,7 @@ ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, VAR|CV, CONST|TMP|VAR|UNUSED|CV) ZVAL_DEREF(container); zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC); FREE_OP2(); - if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } FREE_OP1_VAR_PTR(); @@ -1263,7 +1263,7 @@ ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_ARG, CONST|TMP|VAR|CV, CONST|TMP|VAR|UNU } ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC); - if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } FREE_OP2(); @@ -1296,7 +1296,7 @@ ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET, VAR|CV, CONST|TMP|VAR|CV) ZVAL_DEREF(container); zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R), OP2_TYPE TSRMLS_CC); FREE_OP2(); - if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } FREE_OP1_VAR_PTR(); @@ -1324,11 +1324,33 @@ ZEND_VM_HANDLER(82, ZEND_FETCH_OBJ_R, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV) zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (OP2_TYPE == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } FREE_OP2(); @@ -1352,9 +1374,9 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|CV, CONST|TMP|VAR|CV) zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); FREE_OP2(); - if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } FREE_OP1_VAR_PTR(); @@ -1376,9 +1398,9 @@ ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|CV, CONST|TMP|VAR|CV) if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); FREE_OP2(); - if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } FREE_OP1_VAR_PTR(); @@ -1405,11 +1427,33 @@ ZEND_VM_HANDLER(91, ZEND_FETCH_OBJ_IS, CONST|TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (OP2_TYPE == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } FREE_OP2(); @@ -1438,9 +1482,9 @@ ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|CV, CONST|TMP| if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); FREE_OP2(); - if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } FREE_OP1_VAR_PTR(); @@ -1464,9 +1508,9 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|CV, CONST|TMP|VAR|CV) if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); FREE_OP2(); - if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } FREE_OP1_VAR_PTR(); @@ -2036,7 +2080,7 @@ ZEND_VM_HANDLER(56, ZEND_ADD_VAR, TMP|UNUSED, TMP|VAR|CV) add_string_to_string(str, str, var); if (use_copy) { - zval_dtor(var); + zend_string_release(Z_STR_P(var)); } /* original comment, possibly problematic: * FREE_OP is missing intentionally here - we're always working on the same temporary variable @@ -2631,7 +2675,7 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY) zval *p = ZEND_CALL_ARG(call, 1); for (i = 0; i < call->num_args; ++i) { - zend_verify_arg_type(fbc, i + 1, p TSRMLS_CC); + zend_verify_arg_type(fbc, i + 1, p, NULL TSRMLS_CC); p++; } if (UNEXPECTED(EG(exception) != NULL)) { @@ -2936,9 +2980,7 @@ ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV) } exception = EG(exception); - if (Z_REFCOUNTED_P(EX_VAR(opline->op2.var))) { - zval_ptr_dtor(EX_VAR(opline->op2.var)); - } + zval_ptr_dtor(EX_VAR(opline->op2.var)); ZVAL_OBJ(EX_VAR(opline->op2.var), EG(exception)); if (UNEXPECTED(EG(exception) != exception)) { GC_REFCOUNT(EG(exception))++; @@ -3018,11 +3060,8 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY) zval *varptr, *arg; SAVE_OPLINE(); - if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) { /* Had function_ptr at compile_time */ - if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) { - ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_VAR); - } - } else { + + if (!(opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND)) { if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) { ZEND_VM_DISPATCH_TO_HANDLER(ZEND_SEND_VAR); } @@ -3037,20 +3076,18 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY) if (OP1_TYPE == IS_CV) { Z_ADDREF_P(varptr); } - arg = ZEND_CALL_ARG(EX(call), opline->op2.num); - EX(call)->num_args = opline->op2.num; - ZVAL_COPY_VALUE(arg, varptr); } else { if ((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ? !(opline->extended_value & ZEND_ARG_SEND_SILENT) : !ARG_MAY_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) { zend_error(E_STRICT, "Only variables should be passed by reference"); } - arg = ZEND_CALL_ARG(EX(call), opline->op2.num); - EX(call)->num_args = opline->op2.num; - ZVAL_COPY(arg, varptr); - FREE_OP1_IF_VAR(); } + + arg = ZEND_CALL_ARG(EX(call), opline->op2.num); + EX(call)->num_args = opline->op2.num; + ZVAL_COPY_VALUE(arg, varptr); + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -3080,12 +3117,11 @@ ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, ANY) ZVAL_COPY_VALUE(arg, varptr); } else if (OP1_TYPE == IS_VAR && UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT)) { - ZVAL_COPY_VALUE(arg, varptr); - ZVAL_MAKE_REF(arg); + ZVAL_NEW_REF(arg, varptr); } else { - ZVAL_MAKE_REF(varptr); - Z_ADDREF_P(varptr); - ZVAL_REF(arg, Z_REF_P(varptr)); + ZVAL_NEW_REF(arg, varptr); + Z_ADDREF_P(arg); + ZVAL_REF(varptr, Z_REF_P(arg)); } FREE_OP1_VAR_PTR(); @@ -3231,7 +3267,7 @@ ZEND_VM_C_LABEL(send_again): if (Z_TYPE(key) == IS_STRING) { zend_error(E_RECOVERABLE_ERROR, "Cannot unpack Traversable with string keys"); - zval_dtor(&key); + zend_string_release(Z_STR(key)); ZEND_VM_C_GOTO(unpack_iter_dtor); } @@ -3490,7 +3526,7 @@ ZEND_VM_HANDLER(63, ZEND_RECV, ANY, ANY) } else if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) { zval *param = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC); - zend_verify_arg_type(EX(func), arg_num, param TSRMLS_CC); + zend_verify_arg_type(EX(func), arg_num, param, NULL TSRMLS_CC); CHECK_EXCEPTION(); } @@ -3501,15 +3537,20 @@ ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST) { USE_OPLINE uint32_t arg_num = opline->op1.num; - zval *param; + zval *param, default_val = {{0}}; SAVE_OPLINE(); + if (Z_OPT_CONSTANT_P(opline->op2.zv)) { + ZVAL_COPY_VALUE(&default_val, opline->op2.zv); + zval_update_constant(&default_val, 0 TSRMLS_CC); + } + param = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC); if (arg_num > EX(num_args)) { - ZVAL_COPY_VALUE(param, opline->op2.zv); - if (Z_OPT_CONSTANT_P(param)) { - zval_update_constant(param, 0 TSRMLS_CC); + if (Z_TYPE(default_val) != IS_UNDEF) { + *param = default_val; } else { + ZVAL_COPY_VALUE(param, opline->op2.zv); /* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */ if (UNEXPECTED(Z_OPT_COPYABLE_P(param))) { zval_copy_ctor_func(param); @@ -3518,7 +3559,11 @@ ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST) } if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) { - zend_verify_arg_type(EX(func), arg_num, param TSRMLS_CC); + zend_verify_arg_type(EX(func), arg_num, param, Z_TYPE(default_val) == IS_UNDEF ? NULL : &default_val TSRMLS_CC); + } + + if (Z_TYPE(default_val) != IS_UNDEF && arg_num <= EX(num_args)) { + zval_dtor(&default_val); } CHECK_EXCEPTION(); @@ -3543,7 +3588,7 @@ ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, ANY, ANY) param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T); if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) { do { - zend_verify_arg_type(EX(func), arg_num, param TSRMLS_CC); + zend_verify_arg_type(EX(func), arg_num, param, NULL TSRMLS_CC); zend_hash_next_index_insert_new(Z_ARRVAL_P(params), param); if (Z_REFCOUNTED_P(param)) Z_ADDREF_P(param); param++; @@ -3674,7 +3719,7 @@ ZEND_VM_HANDLER(68, ZEND_NEW, CONST|VAR, ANY) if (RETURN_VALUE_USED(opline)) { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), &object_zval); } else { - zval_ptr_dtor(&object_zval); + OBJ_RELEASE(Z_OBJ(object_zval)); } ZEND_VM_JMP(opline->op2.jmp_addr); } else { @@ -3752,7 +3797,7 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMP|VAR|UNUSED|CV, ANY) if (EXPECTED(EG(exception) == NULL)) { ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj TSRMLS_CC)); if (!RETURN_VALUE_USED(opline) || UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor(EX_VAR(opline->result.var)); + OBJ_RELEASE(Z_OBJ_P(EX_VAR(opline->result.var))); } } FREE_OP1_IF_VAR(); @@ -4159,7 +4204,7 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMP|VAR|CV, ANY) } } if (Z_TYPE(tmp_inc_filename) != IS_UNDEF) { - zval_ptr_dtor(&tmp_inc_filename); + zend_string_release(Z_STR(tmp_inc_filename)); } FREE_OP1(); if (UNEXPECTED(EG(exception) != NULL)) { @@ -4250,8 +4295,8 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMP|VAR|CV, UNUSED|CONST|VAR) } else { ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - if (OP1_TYPE != IS_CONST) { - zval_dtor(&tmp); + if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } FREE_OP1(); HANDLE_EXCEPTION(); @@ -4270,8 +4315,8 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMP|VAR|CV, UNUSED|CONST|VAR) zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); } - if (OP1_TYPE != IS_CONST) { - zval_dtor(&tmp); + if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } FREE_OP1(); CHECK_EXCEPTION(); @@ -4854,6 +4899,7 @@ ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMP|VAR|CV, UNUSED|CONST|VAR) zend_free_op free_op1; zval tmp, *varname = GET_OP1_ZVAL_PTR(BP_VAR_IS); + ZVAL_UNDEF(&tmp); if (OP1_TYPE != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { ZVAL_STR(&tmp, zval_get_string(varname)); varname = &tmp; @@ -4882,8 +4928,8 @@ ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMP|VAR|CV, UNUSED|CONST|VAR) value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); } - if (OP1_TYPE != IS_CONST && varname == &tmp) { - zval_dtor(&tmp); + if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } FREE_OP1(); @@ -4982,7 +5028,7 @@ ZEND_VM_C_LABEL(num_index_prop): result = 0; if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) { - if (OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) { + if (OP2_TYPE == IS_CV || OP2_TYPE == IS_VAR) { ZVAL_DEREF(offset); } if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */ @@ -5860,23 +5906,39 @@ ZEND_VM_HANDLER(168, ZEND_BIND_GLOBAL, CV, CONST) zval *varname; zval *value; zval *variable_ptr; - Bucket *p; uint32_t idx; SAVE_OPLINE(); varname = GET_OP2_ZVAL_PTR(BP_VAR_R); - idx = (uint32_t)(uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(varname)); - /* index 0 can't be cached (NULL is a mark of uninitialized cache slot) */ - p = EG(symbol_table).ht.arData + idx; - if (EXPECTED(idx > 0) && - EXPECTED(idx < EG(symbol_table).ht.nNumUsed) && - EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && - (EXPECTED(p->key == Z_STR_P(varname)) || - (EXPECTED(p->h == Z_STR_P(varname)->h) && - EXPECTED(p->key != NULL) && - EXPECTED(p->key->len == Z_STRLEN_P(varname)) && - EXPECTED(memcmp(p->key->val, Z_STRVAL_P(varname), Z_STRLEN_P(varname)) == 0)))) { - value = &EG(symbol_table).ht.arData[idx].val; + + /* We store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ + idx = (uint32_t)(uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(varname)) - 1; + if (EXPECTED(idx < EG(symbol_table).ht.nNumUsed)) { + Bucket *p = EG(symbol_table).ht.arData + idx; + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(varname)) || + (EXPECTED(p->h == Z_STR_P(varname)->h) && + EXPECTED(p->key != NULL) && + EXPECTED(p->key->len == Z_STRLEN_P(varname)) && + EXPECTED(memcmp(p->key->val, Z_STRVAL_P(varname), Z_STRLEN_P(varname)) == 0)))) { + + value = &EG(symbol_table).ht.arData[idx].val; + ZEND_VM_C_GOTO(check_indirect); + } + } + + value = zend_hash_find(&EG(symbol_table).ht, Z_STR_P(varname)); + if (UNEXPECTED(value == NULL)) { + value = zend_hash_add_new(&EG(symbol_table).ht, Z_STR_P(varname), &EG(uninitialized_zval)); + idx = ((char*)value - (char*)EG(symbol_table).ht.arData) / sizeof(Bucket); + /* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ + CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)(idx + 1)); + } else { + idx = ((char*)value - (char*)EG(symbol_table).ht.arData) / sizeof(Bucket); + /* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ + CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)(idx + 1)); +ZEND_VM_C_LABEL(check_indirect): /* GLOBAL variable may be an INDIRECT pointer to CV */ if (UNEXPECTED(Z_TYPE_P(value) == IS_INDIRECT)) { value = Z_INDIRECT_P(value); @@ -5884,23 +5946,6 @@ ZEND_VM_HANDLER(168, ZEND_BIND_GLOBAL, CV, CONST) ZVAL_NULL(value); } } - } else { - value = zend_hash_find(&EG(symbol_table).ht, Z_STR_P(varname)); - if (UNEXPECTED(value == NULL)) { - value = zend_hash_add_new(&EG(symbol_table).ht, Z_STR_P(varname), &EG(uninitialized_zval)); - idx = ((char*)value - (char*)EG(symbol_table).ht.arData) / sizeof(Bucket); - CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)idx); - } else { - idx = ((char*)value - (char*)EG(symbol_table).ht.arData) / sizeof(Bucket); - CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)idx); - /* GLOBAL variable may be an INDIRECT pointer to CV */ - if (UNEXPECTED(Z_TYPE_P(value) == IS_INDIRECT)) { - value = Z_INDIRECT_P(value); - if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - ZVAL_NULL(value); - } - } - } } variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index c4d4b135d9..cd4a91f27a 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -538,7 +538,7 @@ static int ZEND_FASTCALL ZEND_DO_FCALL_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval *p = ZEND_CALL_ARG(call, 1); for (i = 0; i < call->num_args; ++i) { - zend_verify_arg_type(fbc, i + 1, p TSRMLS_CC); + zend_verify_arg_type(fbc, i + 1, p, NULL TSRMLS_CC); p++; } if (UNEXPECTED(EG(exception) != NULL)) { @@ -798,7 +798,7 @@ send_again: if (Z_TYPE(key) == IS_STRING) { zend_error(E_RECOVERABLE_ERROR, "Cannot unpack Traversable with string keys"); - zval_dtor(&key); + zend_string_release(Z_STR(key)); goto unpack_iter_dtor; } @@ -978,7 +978,7 @@ static int ZEND_FASTCALL ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } else if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) { zval *param = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC); - zend_verify_arg_type(EX(func), arg_num, param TSRMLS_CC); + zend_verify_arg_type(EX(func), arg_num, param, NULL TSRMLS_CC); CHECK_EXCEPTION(); } @@ -1003,7 +1003,7 @@ static int ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR param = EX_VAR_NUM(EX(func)->op_array.last_var + EX(func)->op_array.T); if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) { do { - zend_verify_arg_type(EX(func), arg_num, param TSRMLS_CC); + zend_verify_arg_type(EX(func), arg_num, param, NULL TSRMLS_CC); zend_hash_next_index_insert_new(Z_ARRVAL_P(params), param); if (Z_REFCOUNTED_P(param)) Z_ADDREF_P(param); param++; @@ -1645,15 +1645,20 @@ static int ZEND_FASTCALL ZEND_RECV_INIT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ { USE_OPLINE uint32_t arg_num = opline->op1.num; - zval *param; + zval *param, default_val = {{0}}; SAVE_OPLINE(); + if (Z_OPT_CONSTANT_P(opline->op2.zv)) { + ZVAL_COPY_VALUE(&default_val, opline->op2.zv); + zval_update_constant(&default_val, 0 TSRMLS_CC); + } + param = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC); if (arg_num > EX(num_args)) { - ZVAL_COPY_VALUE(param, opline->op2.zv); - if (Z_OPT_CONSTANT_P(param)) { - zval_update_constant(param, 0 TSRMLS_CC); + if (Z_TYPE(default_val) != IS_UNDEF) { + *param = default_val; } else { + ZVAL_COPY_VALUE(param, opline->op2.zv); /* IS_CONST can't be IS_OBJECT, IS_RESOURCE or IS_REFERENCE */ if (UNEXPECTED(Z_OPT_COPYABLE_P(param))) { zval_copy_ctor_func(param); @@ -1662,7 +1667,11 @@ static int ZEND_FASTCALL ZEND_RECV_INIT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ } if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) { - zend_verify_arg_type(EX(func), arg_num, param TSRMLS_CC); + zend_verify_arg_type(EX(func), arg_num, param, Z_TYPE(default_val) == IS_UNDEF ? NULL : &default_val TSRMLS_CC); + } + + if (Z_TYPE(default_val) != IS_UNDEF && arg_num <= EX(num_args)) { + zval_dtor(&default_val); } CHECK_EXCEPTION(); @@ -1752,7 +1761,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ ZEND_VM_NEXT_OPCODE(); } else { zend_free_op free_op2; - zval *class_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *class_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if (IS_TMP_VAR == IS_CONST) { if (CACHED_PTR(Z_CACHE_SLOT_P(class_name))) { @@ -1772,7 +1781,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string"); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -1809,7 +1818,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H zval *function_name_ptr; SAVE_OPLINE(); - function_name_ptr = function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + function_name_ptr = function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); ZVAL_DEREF(function_name); if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { @@ -1824,7 +1833,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(function_name)); } zend_string_free(lcname); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); fbc = Z_FUNC_P(func); called_scope = NULL; @@ -1841,7 +1850,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H /* Delay closure destruction until its invocation */ fbc->common.prototype = (zend_function*)Z_OBJ_P(function_name_ptr); } else if (IS_TMP_VAR == IS_CV) { - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) { @@ -1908,7 +1917,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_TMP_HANDLER(ZEND_OPCODE_H GC_REFCOUNT(object)++; /* For $this pointer */ } } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else { if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); @@ -1938,7 +1947,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ ZEND_VM_NEXT_OPCODE(); } else { zend_free_op free_op2; - zval *class_name = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *class_name = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2); if (IS_VAR == IS_CONST) { if (CACHED_PTR(Z_CACHE_SLOT_P(class_name))) { @@ -1958,7 +1967,7 @@ static int ZEND_FASTCALL ZEND_FETCH_CLASS_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string"); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -1995,7 +2004,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H zval *function_name_ptr; SAVE_OPLINE(); - function_name_ptr = function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + function_name_ptr = function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); ZVAL_DEREF(function_name); if (EXPECTED(Z_TYPE_P(function_name) == IS_STRING)) { @@ -2010,7 +2019,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(function_name)); } zend_string_free(lcname); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); fbc = Z_FUNC_P(func); called_scope = NULL; @@ -2022,12 +2031,12 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H if (object) { GC_REFCOUNT(object)++; } - if (IS_VAR == IS_VAR && (free_op2.var != NULL) && Z_REFCOUNT_P(function_name) == 1 && + if (IS_VAR == IS_VAR && (free_op2 != NULL) && Z_REFCOUNT_P(function_name) == 1 && fbc->common.fn_flags & ZEND_ACC_CLOSURE) { /* Delay closure destruction until its invocation */ fbc->common.prototype = (zend_function*)Z_OBJ_P(function_name_ptr); } else if (IS_VAR == IS_CV) { - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } } else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) && zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) { @@ -2094,7 +2103,7 @@ static int ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME_SPEC_VAR_HANDLER(ZEND_OPCODE_H GC_REFCOUNT(object)++; /* For $this pointer */ } } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else { if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); @@ -2757,7 +2766,7 @@ static int ZEND_FASTCALL ZEND_NEW_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (RETURN_VALUE_USED(opline)) { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), &object_zval); } else { - zval_ptr_dtor(&object_zval); + OBJ_RELEASE(Z_OBJ(object_zval)); } ZEND_VM_JMP(opline->op2.jmp_addr); } else { @@ -2835,7 +2844,7 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS if (EXPECTED(EG(exception) == NULL)) { ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj TSRMLS_CC)); if (!RETURN_VALUE_USED(opline) || UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor(EX_VAR(opline->result.var)); + OBJ_RELEASE(Z_OBJ_P(EX_VAR(opline->result.var))); } } @@ -3023,7 +3032,7 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER(ZEND_OPCODE_HA } } if (Z_TYPE(tmp_inc_filename) != IS_UNDEF) { - zval_ptr_dtor(&tmp_inc_filename); + zend_string_release(Z_STR(tmp_inc_filename)); } if (UNEXPECTED(EG(exception) != NULL)) { @@ -3946,7 +3955,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CONST_HANDLER(ZEND_ } ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); - if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -3984,11 +3993,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_ zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } @@ -4015,11 +4046,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } @@ -4047,9 +4100,9 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CONST_HANDLER(ZEND_ if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -4549,8 +4602,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HA } else { ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_CONST != IS_CONST) { - zval_dtor(&tmp); + if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } HANDLE_EXCEPTION(); @@ -4569,8 +4622,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HA zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_CONST != IS_CONST) { - zval_dtor(&tmp); + if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } CHECK_EXCEPTION(); @@ -4601,6 +4654,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_CONST_HANDLER(ZEND_O zval tmp, *varname = opline->op1.zv; + ZVAL_UNDEF(&tmp); if (IS_CONST != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { ZVAL_STR(&tmp, zval_get_string(varname)); varname = &tmp; @@ -4629,8 +4683,8 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_CONST_HANDLER(ZEND_O value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_CONST != IS_CONST && varname == &tmp) { - zval_dtor(&tmp); + if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } if (opline->extended_value & ZEND_ISSET) { @@ -4979,9 +5033,9 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); fast_add_function(EX_VAR(opline->result.var), opline->op1.zv, - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -4994,9 +5048,9 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); fast_sub_function(EX_VAR(opline->result.var), opline->op1.zv, - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5009,9 +5063,9 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); fast_mul_function(EX_VAR(opline->result.var), opline->op1.zv, - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5024,9 +5078,9 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); fast_div_function(EX_VAR(opline->result.var), opline->op1.zv, - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5039,9 +5093,9 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); fast_mod_function(EX_VAR(opline->result.var), opline->op1.zv, - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5054,9 +5108,9 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG SAVE_OPLINE(); shift_left_function(EX_VAR(opline->result.var), opline->op1.zv, - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5069,9 +5123,9 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG SAVE_OPLINE(); shift_right_function(EX_VAR(opline->result.var), opline->op1.zv, - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5084,9 +5138,9 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER SAVE_OPLINE(); concat_function(EX_VAR(opline->result.var), opline->op1.zv, - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5099,9 +5153,9 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_H SAVE_OPLINE(); fast_is_identical_function(EX_VAR(opline->result.var), opline->op1.zv, - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5115,9 +5169,9 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CONST_TMP_HANDLER(ZEND_OPCO SAVE_OPLINE(); fast_is_not_identical_function(result, opline->op1.zv, - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5131,9 +5185,9 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); fast_equal_function(result, opline->op1.zv, - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5147,9 +5201,9 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_H SAVE_OPLINE(); fast_not_equal_function(result, opline->op1.zv, - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5163,9 +5217,9 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HAN SAVE_OPLINE(); fast_is_smaller_function(result, opline->op1.zv, - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5179,9 +5233,9 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_TMP_HANDLER(ZEND_O SAVE_OPLINE(); fast_is_smaller_or_equal_function(result, opline->op1.zv, - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5194,9 +5248,9 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ SAVE_OPLINE(); bitwise_or_function(EX_VAR(opline->result.var), opline->op1.zv, - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5209,9 +5263,9 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER SAVE_OPLINE(); bitwise_and_function(EX_VAR(opline->result.var), opline->op1.zv, - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5224,9 +5278,9 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER SAVE_OPLINE(); bitwise_xor_function(EX_VAR(opline->result.var), opline->op1.zv, - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5239,9 +5293,9 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); boolean_xor_function(EX_VAR(opline->result.var), opline->op1.zv, - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5254,8 +5308,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HA SAVE_OPLINE(); container = opline->op1.zv; - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2), IS_TMP_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -5269,8 +5323,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_H SAVE_OPLINE(); container = opline->op1.zv; - zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2), IS_TMP_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -5293,19 +5347,19 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_TMP_HANDLER(ZEND_OP zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } ZVAL_DEREF(container); - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); - if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2), IS_TMP_VAR TSRMLS_CC); + if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else { if (IS_TMP_VAR == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } container = opline->op1.zv; - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2), IS_TMP_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); } CHECK_EXCEPTION(); @@ -5322,7 +5376,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HA SAVE_OPLINE(); container = opline->op1.zv; - offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if ((IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { @@ -5332,14 +5386,36 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HA zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_TMP_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -5355,7 +5431,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_H SAVE_OPLINE(); container = opline->op1.zv; - offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if ((IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { @@ -5364,14 +5440,36 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_H zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_TMP_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -5388,7 +5486,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMP_HANDLER(ZEND_OP zval *property; SAVE_OPLINE(); - property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); container = NULL; if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) { @@ -5397,9 +5495,9 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_TMP_HANDLER(ZEND_OP if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -5449,7 +5547,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZE } else if (IS_TMP_VAR != IS_UNUSED) { zend_free_op free_op2; - function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if (IS_TMP_VAR != IS_CONST) { if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { if (UNEXPECTED(EG(exception) != NULL)) { @@ -5477,7 +5575,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMP_HANDLER(ZE } } if (IS_TMP_VAR != IS_CONST) { - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } } else { if (UNEXPECTED(ce->constructor == NULL)) { @@ -5538,7 +5636,7 @@ static int ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE { USE_OPLINE zend_free_op free_op2; - zval *function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); zend_fcall_info_cache fcc; char *error = NULL; zend_function *func; @@ -5583,7 +5681,7 @@ static int ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE EX(call) = zend_vm_stack_push_call_frame(VM_FRAME_NESTED_FUNCTION, func, opline->extended_value, called_scope, object, EX(call) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5597,9 +5695,9 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_A SAVE_OPLINE(); fast_equal_function(result, opline->op1.zv, - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -5641,7 +5739,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_HANDLER(ZEND_OPC if (IS_TMP_VAR != IS_UNUSED) { zend_free_op free_op2; - zval *offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); zend_string *str; zend_ulong hval; @@ -5684,7 +5782,7 @@ str_index: /* do nothing */ break; } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else { zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr); } @@ -5734,7 +5832,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_TMP_HANDLER(ZEND SAVE_OPLINE(); container = opline->op1.zv; - offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if (IS_CONST != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht = Z_ARRVAL_P(container); @@ -5804,7 +5902,7 @@ num_index_prop: result = 0; if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) { - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { + if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { ZVAL_DEREF(offset); } if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */ @@ -5830,7 +5928,7 @@ num_index_prop: result = ((opline->extended_value & ZEND_ISSET) == 0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); ZVAL_BOOL(EX_VAR(opline->result.var), result); CHECK_EXCEPTION(); @@ -5847,7 +5945,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMP_HANDLER(ZEN SAVE_OPLINE(); container = opline->op1.zv; - offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if (IS_CONST == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (EXPECTED(Z_OBJ_HT_P(container)->has_property)) { @@ -5863,7 +5961,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_TMP_HANDLER(ZEN result = ((opline->extended_value & ZEND_ISSET) == 0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); ZVAL_BOOL(EX_VAR(opline->result.var), result); CHECK_EXCEPTION(); @@ -5953,7 +6051,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_ /* Set the new yielded key */ if (IS_TMP_VAR != IS_UNUSED) { zend_free_op free_op2; - zval *key = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *key = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); /* Consts, temporary variables and references need copying */ if (IS_TMP_VAR == IS_CONST) { @@ -6009,9 +6107,9 @@ static int ZEND_FASTCALL ZEND_POW_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); pow_function(EX_VAR(opline->result.var), opline->op1.zv, - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -6024,9 +6122,9 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); fast_add_function(EX_VAR(opline->result.var), opline->op1.zv, - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -6039,9 +6137,9 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); fast_sub_function(EX_VAR(opline->result.var), opline->op1.zv, - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -6054,9 +6152,9 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); fast_mul_function(EX_VAR(opline->result.var), opline->op1.zv, - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -6069,9 +6167,9 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); fast_div_function(EX_VAR(opline->result.var), opline->op1.zv, - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -6084,9 +6182,9 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); fast_mod_function(EX_VAR(opline->result.var), opline->op1.zv, - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -6099,9 +6197,9 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG SAVE_OPLINE(); shift_left_function(EX_VAR(opline->result.var), opline->op1.zv, - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -6114,9 +6212,9 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG SAVE_OPLINE(); shift_right_function(EX_VAR(opline->result.var), opline->op1.zv, - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -6129,9 +6227,9 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER SAVE_OPLINE(); concat_function(EX_VAR(opline->result.var), opline->op1.zv, - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -6144,9 +6242,9 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_H SAVE_OPLINE(); fast_is_identical_function(EX_VAR(opline->result.var), opline->op1.zv, - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -6160,9 +6258,9 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCO SAVE_OPLINE(); fast_is_not_identical_function(result, opline->op1.zv, - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -6176,9 +6274,9 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); fast_equal_function(result, opline->op1.zv, - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -6192,9 +6290,9 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_H SAVE_OPLINE(); fast_not_equal_function(result, opline->op1.zv, - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -6208,9 +6306,9 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HAN SAVE_OPLINE(); fast_is_smaller_function(result, opline->op1.zv, - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -6224,9 +6322,9 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST_VAR_HANDLER(ZEND_O SAVE_OPLINE(); fast_is_smaller_or_equal_function(result, opline->op1.zv, - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -6239,9 +6337,9 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ SAVE_OPLINE(); bitwise_or_function(EX_VAR(opline->result.var), opline->op1.zv, - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -6254,9 +6352,9 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER SAVE_OPLINE(); bitwise_and_function(EX_VAR(opline->result.var), opline->op1.zv, - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -6269,9 +6367,9 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER SAVE_OPLINE(); bitwise_xor_function(EX_VAR(opline->result.var), opline->op1.zv, - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -6284,9 +6382,9 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); boolean_xor_function(EX_VAR(opline->result.var), opline->op1.zv, - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -6447,8 +6545,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HA SAVE_OPLINE(); container = opline->op1.zv; - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2), IS_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -6462,8 +6560,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_H SAVE_OPLINE(); container = opline->op1.zv; - zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2), IS_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -6486,19 +6584,19 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_VAR_HANDLER(ZEND_OP zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } ZVAL_DEREF(container); - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); - if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2), IS_VAR TSRMLS_CC); + if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else { if (IS_VAR == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } container = opline->op1.zv; - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2), IS_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); } CHECK_EXCEPTION(); @@ -6515,7 +6613,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HA SAVE_OPLINE(); container = opline->op1.zv; - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if ((IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { @@ -6525,14 +6623,36 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HA zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -6548,7 +6668,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_H SAVE_OPLINE(); container = opline->op1.zv; - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if ((IS_CONST != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { @@ -6557,14 +6677,36 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_H zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -6581,7 +6723,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_VAR_HANDLER(ZEND_OP zval *property; SAVE_OPLINE(); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); container = NULL; if (IS_CONST == IS_CONST || IS_CONST == IS_TMP_VAR) { @@ -6590,9 +6732,9 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_VAR_HANDLER(ZEND_OP if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, IS_VAR, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -6642,7 +6784,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZE } else if (IS_VAR != IS_UNUSED) { zend_free_op free_op2; - function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_VAR != IS_CONST) { if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { if (UNEXPECTED(EG(exception) != NULL)) { @@ -6670,7 +6812,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_VAR_HANDLER(ZE } } if (IS_VAR != IS_CONST) { - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } } else { if (UNEXPECTED(ce->constructor == NULL)) { @@ -6731,7 +6873,7 @@ static int ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE { USE_OPLINE zend_free_op free_op2; - zval *function_name = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *function_name = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2); zend_fcall_info_cache fcc; char *error = NULL; zend_function *func; @@ -6776,7 +6918,7 @@ static int ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE EX(call) = zend_vm_stack_push_call_frame(VM_FRAME_NESTED_FUNCTION, func, opline->extended_value, called_scope, object, EX(call) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -6790,9 +6932,9 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_A SAVE_OPLINE(); fast_equal_function(result, opline->op1.zv, - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -6834,7 +6976,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_VAR_HANDLER(ZEND_OPC if (IS_VAR != IS_UNUSED) { zend_free_op free_op2; - zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); zend_string *str; zend_ulong hval; @@ -6877,7 +7019,7 @@ str_index: /* do nothing */ break; } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else { zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr); } @@ -6963,8 +7105,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HAND } else { ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_CONST != IS_CONST) { - zval_dtor(&tmp); + if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } HANDLE_EXCEPTION(); @@ -6983,8 +7125,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HAND zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_CONST != IS_CONST) { - zval_dtor(&tmp); + if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } CHECK_EXCEPTION(); @@ -7015,6 +7157,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_VAR_HANDLER(ZEND_OPC zval tmp, *varname = opline->op1.zv; + ZVAL_UNDEF(&tmp); if (IS_CONST != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { ZVAL_STR(&tmp, zval_get_string(varname)); varname = &tmp; @@ -7043,8 +7186,8 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_VAR_HANDLER(ZEND_OPC value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_CONST != IS_CONST && varname == &tmp) { - zval_dtor(&tmp); + if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } if (opline->extended_value & ZEND_ISSET) { @@ -7072,7 +7215,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CONST_VAR_HANDLER(ZEND SAVE_OPLINE(); container = opline->op1.zv; - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_CONST != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht = Z_ARRVAL_P(container); @@ -7142,7 +7285,7 @@ num_index_prop: result = 0; if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) { - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { + if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { ZVAL_DEREF(offset); } if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */ @@ -7168,7 +7311,7 @@ num_index_prop: result = ((opline->extended_value & ZEND_ISSET) == 0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); ZVAL_BOOL(EX_VAR(opline->result.var), result); CHECK_EXCEPTION(); @@ -7185,7 +7328,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_VAR_HANDLER(ZEN SAVE_OPLINE(); container = opline->op1.zv; - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_CONST == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (EXPECTED(Z_OBJ_HT_P(container)->has_property)) { @@ -7201,7 +7344,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CONST_VAR_HANDLER(ZEN result = ((opline->extended_value & ZEND_ISSET) == 0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); ZVAL_BOOL(EX_VAR(opline->result.var), result); CHECK_EXCEPTION(); @@ -7291,7 +7434,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ /* Set the new yielded key */ if (IS_VAR != IS_UNUSED) { zend_free_op free_op2; - zval *key = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *key = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); /* Consts, temporary variables and references need copying */ if (IS_VAR == IS_CONST) { @@ -7300,7 +7443,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_ ZVAL_COPY_VALUE(&generator->key, key); } else if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && Z_ISREF_P(key)) { ZVAL_DUP(&generator->key, Z_REFVAL_P(key)); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else { ZVAL_COPY_VALUE(&generator->key, key); if (IS_VAR == IS_CV) { @@ -7347,9 +7490,9 @@ static int ZEND_FASTCALL ZEND_POW_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); pow_function(EX_VAR(opline->result.var), opline->op1.zv, - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -7520,7 +7663,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_UNUSED_HANDLER(ZEND } ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC); - if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -7828,8 +7971,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_H } else { ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_CONST != IS_CONST) { - zval_dtor(&tmp); + if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } HANDLE_EXCEPTION(); @@ -7848,8 +7991,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_H zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_CONST != IS_CONST) { - zval_dtor(&tmp); + if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } CHECK_EXCEPTION(); @@ -7880,6 +8023,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED_HANDLER(ZEND_ zval tmp, *varname = opline->op1.zv; + ZVAL_UNDEF(&tmp); if (IS_CONST != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { ZVAL_STR(&tmp, zval_get_string(varname)); varname = &tmp; @@ -7908,8 +8052,8 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED_HANDLER(ZEND_ value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_CONST != IS_CONST && varname == &tmp) { - zval_dtor(&tmp); + if (IS_CONST != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } if (opline->extended_value & ZEND_ISSET) { @@ -8405,7 +8549,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CONST_CV_HANDLER(ZEND_OPC } ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); - if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -8443,11 +8587,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HAN zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } @@ -8474,11 +8640,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HA zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } @@ -8506,9 +8694,9 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CONST_CV_HANDLER(ZEND_OPC if (IS_CONST == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CONST, property, IS_CV, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_CONST == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -8736,9 +8924,7 @@ static int ZEND_FASTCALL ZEND_CATCH_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_A } exception = EG(exception); - if (Z_REFCOUNTED_P(EX_VAR(opline->op2.var))) { - zval_ptr_dtor(EX_VAR(opline->op2.var)); - } + zval_ptr_dtor(EX_VAR(opline->op2.var)); ZVAL_OBJ(EX_VAR(opline->op2.var), EG(exception)); if (UNEXPECTED(EG(exception) != exception)) { GC_REFCOUNT(EG(exception))++; @@ -8964,7 +9150,7 @@ num_index_prop: result = 0; if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) { - if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { + if (IS_CV == IS_CV || IS_CV == IS_VAR) { ZVAL_DEREF(offset); } if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */ @@ -9181,8 +9367,8 @@ static int ZEND_FASTCALL ZEND_BW_NOT_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); bitwise_not_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -9194,8 +9380,8 @@ static int ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG SAVE_OPLINE(); boolean_not_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -9207,11 +9393,11 @@ static int ZEND_FASTCALL ZEND_ECHO_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval *z; SAVE_OPLINE(); - z = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + z = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); zend_print_variable(z TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -9231,7 +9417,7 @@ static int ZEND_FASTCALL ZEND_JMPZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval *val; SAVE_OPLINE(); - val = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + val = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); if (IS_TMP_VAR == IS_TMP_VAR) { if (Z_TYPE_P(val) == IS_TRUE) { @@ -9248,7 +9434,7 @@ static int ZEND_FASTCALL ZEND_JMPZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } else { opline = opline->op2.jmp_addr; } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -9262,7 +9448,7 @@ static int ZEND_FASTCALL ZEND_JMPNZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval *val; SAVE_OPLINE(); - val = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + val = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); if (IS_TMP_VAR == IS_TMP_VAR) { if (Z_TYPE_P(val) == IS_TRUE) { @@ -9279,7 +9465,7 @@ static int ZEND_FASTCALL ZEND_JMPNZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } else { opline++; } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -9293,7 +9479,7 @@ static int ZEND_FASTCALL ZEND_JMPZNZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval *val; SAVE_OPLINE(); - val = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + val = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); if (IS_TMP_VAR == IS_TMP_VAR) { if (EXPECTED(Z_TYPE_P(val) == IS_TRUE)) { @@ -9310,7 +9496,7 @@ static int ZEND_FASTCALL ZEND_JMPZNZ_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } else { opline = opline->op2.jmp_addr; } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -9324,7 +9510,7 @@ static int ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS zval *val; SAVE_OPLINE(); - val = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + val = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); if (IS_TMP_VAR == IS_TMP_VAR) { if (Z_TYPE_P(val) == IS_TRUE) { @@ -9339,11 +9525,11 @@ static int ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS } if (i_zend_is_true(val TSRMLS_CC)) { - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); ZVAL_TRUE(EX_VAR(opline->result.var)); opline++; } else { - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); ZVAL_FALSE(EX_VAR(opline->result.var)); opline = opline->op2.jmp_addr; } @@ -9360,7 +9546,7 @@ static int ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG zval *val; SAVE_OPLINE(); - val = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + val = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); if (IS_TMP_VAR == IS_TMP_VAR) { if (Z_TYPE_P(val) == IS_TRUE) { @@ -9380,7 +9566,7 @@ static int ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG ZVAL_FALSE(EX_VAR(opline->result.var)); opline++; } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -9404,10 +9590,10 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_free_op free_op1; SAVE_OPLINE(); - retval_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + retval_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); if (!EX(return_value)) { - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } else { if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) { ZVAL_COPY_VALUE(EX(return_value), retval_ptr); @@ -9443,10 +9629,10 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLE /* Not supposed to happen, but we'll allow it */ zend_error(E_NOTICE, "Only variable references should be returned by reference"); - retval_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + retval_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); if (!EX(return_value)) { if (IS_TMP_VAR == IS_TMP_VAR) { - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } } else { ZVAL_COPY_VALUE(EX(return_value), retval_ptr); @@ -9496,7 +9682,7 @@ static int ZEND_FASTCALL ZEND_THROW_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_free_op free_op1; SAVE_OPLINE(); - value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); if (IS_TMP_VAR == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) { if (UNEXPECTED(EG(exception) != NULL)) { @@ -9523,7 +9709,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG zend_free_op free_op1; SAVE_OPLINE(); - value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); arg = ZEND_CALL_ARG(EX(call), opline->op2.num); EX(call)->num_args = opline->op2.num; ZVAL_COPY_VALUE(arg, value); @@ -9545,7 +9731,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAL_EX_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ if (ARG_MUST_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) { zend_error_noreturn(E_ERROR, "Cannot pass parameter %d by reference", opline->op2.num); } - value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); arg = ZEND_CALL_ARG(EX(call), opline->op2.num); EX(call)->num_args = opline->op2.num; ZVAL_COPY_VALUE(arg, value); @@ -9565,8 +9751,8 @@ static int ZEND_FASTCALL ZEND_BOOL_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); /* PHP 3.0 returned "" for false and 1 for true, here we use 0 and 1 for now */ - ZVAL_BOOL(retval, i_zend_is_true(_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC) TSRMLS_CC)); - zval_ptr_dtor_nogc(free_op1.var); + ZVAL_BOOL(retval, i_zend_is_true(_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1) TSRMLS_CC)); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -9582,7 +9768,7 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_object_clone_obj_t clone_call; SAVE_OPLINE(); - obj = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + obj = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); if (IS_TMP_VAR == IS_CONST || (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) { @@ -9622,7 +9808,7 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (EXPECTED(EG(exception) == NULL)) { ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj TSRMLS_CC)); if (!RETURN_VALUE_USED(opline) || UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor(EX_VAR(opline->result.var)); + OBJ_RELEASE(Z_OBJ_P(EX_VAR(opline->result.var))); } } @@ -9638,7 +9824,7 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval *result = EX_VAR(opline->result.var); SAVE_OPLINE(); - expr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + expr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); switch (opline->extended_value) { case IS_NULL: @@ -9726,7 +9912,7 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -9741,7 +9927,7 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HAND zend_bool failure_retval=0; SAVE_OPLINE(); - inc_filename = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + inc_filename = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); ZVAL_UNDEF(&tmp_inc_filename); if (Z_TYPE_P(inc_filename) != IS_STRING) { @@ -9811,9 +9997,9 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMP_HANDLER(ZEND_OPCODE_HAND } } if (Z_TYPE(tmp_inc_filename) != IS_UNDEF) { - zval_ptr_dtor(&tmp_inc_filename); + zend_string_release(Z_STR(tmp_inc_filename)); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } else if (EXPECTED(new_op_array != NULL)) { @@ -9888,7 +10074,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG if (Z_REFCOUNTED_P(array_ref)) Z_ADDREF_P(array_ref); } } else { - array_ptr = array_ref = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + array_ptr = array_ref = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); ZVAL_DEREF(array_ptr); if (IS_TMP_VAR == IS_TMP_VAR) { ZVAL_COPY_VALUE(&tmp, array_ptr); @@ -10052,14 +10238,14 @@ static int ZEND_FASTCALL ZEND_EXIT_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); if (IS_TMP_VAR != IS_UNUSED) { zend_free_op free_op1; - zval *ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zval *ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); if (Z_TYPE_P(ptr) == IS_LONG) { EG(exit_status) = Z_LVAL_P(ptr); } else { zend_print_variable(ptr TSRMLS_CC); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } #endif zend_bailout(); @@ -10088,7 +10274,7 @@ static int ZEND_FASTCALL ZEND_JMP_SET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS int is_ref = 0; SAVE_OPLINE(); - value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && Z_ISREF_P(value)) { is_ref = 1; @@ -10104,12 +10290,12 @@ static int ZEND_FASTCALL ZEND_JMP_SET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } else if (IS_TMP_VAR == IS_VAR && is_ref) { if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } ZEND_VM_JMP(opline->op2.jmp_addr); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10122,7 +10308,7 @@ static int ZEND_FASTCALL ZEND_COALESCE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG int is_ref = 0; SAVE_OPLINE(); - value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && Z_ISREF_P(value)) { is_ref = 1; @@ -10139,12 +10325,12 @@ static int ZEND_FASTCALL ZEND_COALESCE_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } else if (IS_TMP_VAR == IS_VAR && is_ref) { if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } ZEND_VM_JMP(opline->op2.jmp_addr); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10156,11 +10342,11 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR zval *value; SAVE_OPLINE(); - value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && Z_ISREF_P(value)) { ZVAL_COPY(EX_VAR(opline->result.var), Z_REFVAL_P(value)); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } else { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); if (IS_TMP_VAR == IS_CONST) { @@ -10181,7 +10367,7 @@ static int ZEND_FASTCALL ZEND_STRLEN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_free_op free_op1; SAVE_OPLINE(); - value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); } else { @@ -10209,7 +10395,7 @@ strlen_error: ZVAL_NULL(EX_VAR(opline->result.var)); } } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10221,7 +10407,7 @@ static int ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_A zend_free_op free_op1; SAVE_OPLINE(); - value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); switch (opline->extended_value) { case IS_NULL: case IS_LONG: @@ -10256,7 +10442,7 @@ static int ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_A break; EMPTY_SWITCH_DEFAULT_CASE() } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10268,9 +10454,9 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); fast_add_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -10283,9 +10469,9 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); fast_sub_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -10298,9 +10484,9 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); fast_mul_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -10313,9 +10499,9 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); fast_div_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -10328,9 +10514,9 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); fast_mod_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -10343,9 +10529,9 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG SAVE_OPLINE(); shift_left_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -10358,9 +10544,9 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG SAVE_OPLINE(); shift_right_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -10373,9 +10559,9 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER SAVE_OPLINE(); concat_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -10388,9 +10574,9 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_H SAVE_OPLINE(); fast_is_identical_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -10404,9 +10590,9 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCO SAVE_OPLINE(); fast_is_not_identical_function(result, - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -10420,9 +10606,9 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); fast_equal_function(result, - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -10436,9 +10622,9 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_H SAVE_OPLINE(); fast_not_equal_function(result, - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -10452,9 +10638,9 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HAN SAVE_OPLINE(); fast_is_smaller_function(result, - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -10468,9 +10654,9 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMP_CONST_HANDLER(ZEND_O SAVE_OPLINE(); fast_is_smaller_or_equal_function(result, - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -10483,9 +10669,9 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ SAVE_OPLINE(); bitwise_or_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -10498,9 +10684,9 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER SAVE_OPLINE(); bitwise_and_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -10513,9 +10699,9 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER SAVE_OPLINE(); bitwise_xor_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -10528,9 +10714,9 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); boolean_xor_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -10546,7 +10732,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_CONST(int type, HashTable *target_symbol_table; SAVE_OPLINE(); - varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); if (IS_TMP_VAR == IS_CONST) { name = Z_STR_P(varname); @@ -10569,7 +10755,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_CONST(int type, if (IS_TMP_VAR != IS_CONST) { zend_string_release(name); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10579,7 +10765,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_CONST(int type, ce = Z_CE_P(EX_VAR(opline->op2.var)); } retval = zend_std_get_static_property(ce, name, 0, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(varname)) : NULL) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } else { target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC); retval = zend_hash_find(target_symbol_table, name); @@ -10627,7 +10813,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_CONST(int type, zval_update_constant(retval, 1 TSRMLS_CC); } } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } } @@ -10691,10 +10877,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HA zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10706,10 +10892,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_H zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10732,7 +10918,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OP } ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); - if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -10741,10 +10927,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OP if (IS_CONST == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -10759,7 +10945,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HA zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); offset = opline->op2.zv; if ((IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || @@ -10770,14 +10956,36 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HA zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10791,7 +10999,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_H zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); offset = opline->op2.zv; if ((IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || @@ -10801,14 +11009,36 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_H zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10833,9 +11063,9 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CONST_HANDLER(ZEND_OP if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -10853,7 +11083,7 @@ static int ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HAN zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { @@ -10939,7 +11169,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST_HANDLER(ZEND_OPCO zend_error_noreturn(E_ERROR, "Method name must be a string"); } - object = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + object = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); if (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { uint32_t nesting = 1; @@ -11031,7 +11261,7 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_A SAVE_OPLINE(); fast_equal_function(result, - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); CHECK_EXCEPTION(); @@ -11055,7 +11285,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPC Z_ADDREF_P(expr_ptr); } else { - expr_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + expr_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); if (IS_TMP_VAR == IS_TMP_VAR) { ZVAL_COPY_VALUE(&new_expr, expr_ptr); expr_ptr = &new_expr; @@ -11187,7 +11417,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HAND ZEND_VM_NEXT_OPCODE(); } - varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); ZVAL_UNDEF(&tmp); if (IS_TMP_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { @@ -11204,10 +11434,10 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HAND } else { ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_TMP_VAR != IS_CONST) { - zval_dtor(&tmp); + if (IS_TMP_VAR != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); HANDLE_EXCEPTION(); } if (UNEXPECTED(ce == NULL)) { @@ -11224,10 +11454,10 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HAND zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_TMP_VAR != IS_CONST) { - zval_dtor(&tmp); + if (IS_TMP_VAR != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -11254,8 +11484,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPC ZEND_VM_NEXT_OPCODE(); } else { zend_free_op free_op1; - zval tmp, *varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zval tmp, *varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); + ZVAL_UNDEF(&tmp); if (IS_TMP_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { ZVAL_STR(&tmp, zval_get_string(varname)); varname = &tmp; @@ -11284,10 +11515,10 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPC value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_TMP_VAR != IS_CONST && varname == &tmp) { - zval_dtor(&tmp); + if (IS_TMP_VAR != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); if (opline->extended_value & ZEND_ISSET) { ZVAL_BOOL(EX_VAR(opline->result.var), @@ -11313,7 +11544,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CONST_HANDLER(ZEND zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); offset = opline->op2.zv; if (IS_TMP_VAR != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { @@ -11384,7 +11615,7 @@ num_index_prop: result = 0; if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) { - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { + if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { ZVAL_DEREF(offset); } if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */ @@ -11411,7 +11642,7 @@ num_index_prop: } ZVAL_BOOL(EX_VAR(opline->result.var), result); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -11425,7 +11656,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CONST_HANDLER(ZEN zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); offset = opline->op2.zv; if (IS_TMP_VAR == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { @@ -11443,7 +11674,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CONST_HANDLER(ZEN } ZVAL_BOOL(EX_VAR(opline->result.var), result); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -11456,7 +11687,7 @@ static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HAN zend_bool result; SAVE_OPLINE(); - expr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + expr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); if (Z_TYPE_P(expr) == IS_OBJECT) { zend_class_entry *ce; @@ -11468,7 +11699,7 @@ static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HAN ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC); if (UNEXPECTED(ce == NULL)) { ZVAL_FALSE(EX_VAR(opline->result.var)); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -11482,7 +11713,7 @@ static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HAN result = 0; } ZVAL_BOOL(EX_VAR(opline->result.var), result); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -11516,7 +11747,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); ZVAL_COPY_VALUE(&generator->value, value); if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1); @@ -11545,7 +11776,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_ } } else { - zval *value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zval *value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); /* Consts, temporary variables and references need copying */ if (IS_TMP_VAR == IS_CONST) { @@ -11625,9 +11856,9 @@ static int ZEND_FASTCALL ZEND_POW_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); pow_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -11640,10 +11871,10 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); fast_add_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -11655,10 +11886,10 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); fast_sub_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -11670,10 +11901,10 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); fast_mul_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -11685,10 +11916,10 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); fast_div_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -11700,10 +11931,10 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); fast_mod_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -11715,10 +11946,10 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); shift_left_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -11730,10 +11961,10 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); shift_right_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -11745,10 +11976,10 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_A SAVE_OPLINE(); concat_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -11760,10 +11991,10 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HAN SAVE_OPLINE(); fast_is_identical_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -11776,10 +12007,10 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE SAVE_OPLINE(); fast_is_not_identical_function(result, - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -11792,10 +12023,10 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER SAVE_OPLINE(); fast_equal_function(result, - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -11808,10 +12039,10 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HAN SAVE_OPLINE(); fast_not_equal_function(result, - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -11824,10 +12055,10 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); fast_is_smaller_function(result, - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -11840,10 +12071,10 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMP_TMP_HANDLER(ZEND_OPC SAVE_OPLINE(); fast_is_smaller_or_equal_function(result, - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -11855,10 +12086,10 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); bitwise_or_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -11870,10 +12101,10 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_A SAVE_OPLINE(); bitwise_and_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -11885,10 +12116,10 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_A SAVE_OPLINE(); bitwise_xor_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -11900,10 +12131,10 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER SAVE_OPLINE(); boolean_xor_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -11915,10 +12146,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HAND zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - zval_ptr_dtor_nogc(free_op1.var); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); + zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2), IS_TMP_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -11930,10 +12161,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HAN zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - zval_ptr_dtor_nogc(free_op1.var); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); + zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2), IS_TMP_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -11955,20 +12186,20 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_TMP_HANDLER(ZEND_OPCO zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } ZVAL_DEREF(container); - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); - if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2), IS_TMP_VAR TSRMLS_CC); + if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else { if (IS_TMP_VAR == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - zval_ptr_dtor_nogc(free_op1.var); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); + zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2), IS_TMP_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -11983,8 +12214,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HAND zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); + offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if ((IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { @@ -11994,15 +12225,37 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HAND zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_TMP_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } - zval_ptr_dtor_nogc(free_op2.var); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12016,8 +12269,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HAN zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); + offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if ((IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { @@ -12026,15 +12279,37 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HAN zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_TMP_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } - zval_ptr_dtor_nogc(free_op2.var); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12050,7 +12325,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMP_HANDLER(ZEND_OPCO zval *property; SAVE_OPLINE(); - property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); container = NULL; if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) { @@ -12059,9 +12334,9 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_TMP_HANDLER(ZEND_OPCO if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -12082,7 +12357,7 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ int use_copy = 0; SAVE_OPLINE(); - var = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + var = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if (IS_TMP_VAR == IS_UNUSED) { /* Initialize for erealloc in add_string_to_string */ @@ -12102,7 +12377,7 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ add_string_to_string(str, str, var); if (use_copy) { - zval_dtor(var); + zend_string_release(Z_STR_P(var)); } /* original comment, possibly problematic: * FREE_OP is missing intentionally here - we're always working on the same temporary variable @@ -12110,7 +12385,7 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ * which aren't affected by FREE_OP(Ts, )'s anyway, unless they're * string offsets or overloaded objects */ - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -12128,7 +12403,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE SAVE_OPLINE(); - function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if (IS_TMP_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { @@ -12138,18 +12413,18 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE zend_error_noreturn(E_ERROR, "Method name must be a string"); } - object = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + object = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); if (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { uint32_t nesting = 1; if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); if (EG(exception) != NULL) { HANDLE_EXCEPTION(); @@ -12217,7 +12492,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE EX(call) = zend_vm_stack_push_call_frame(VM_FRAME_NESTED_FUNCTION, fbc, opline->extended_value, called_scope, obj, EX(call) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -12231,10 +12506,10 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG SAVE_OPLINE(); fast_equal_function(result, - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12256,7 +12531,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_HANDLER(ZEND_OPCOD Z_ADDREF_P(expr_ptr); } else { - expr_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + expr_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); if (IS_TMP_VAR == IS_TMP_VAR) { ZVAL_COPY_VALUE(&new_expr, expr_ptr); expr_ptr = &new_expr; @@ -12276,7 +12551,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_HANDLER(ZEND_OPCOD if (IS_TMP_VAR != IS_UNUSED) { zend_free_op free_op2; - zval *offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); zend_string *str; zend_ulong hval; @@ -12319,7 +12594,7 @@ str_index: /* do nothing */ break; } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else { zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr); } @@ -12368,8 +12643,8 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_TMP_HANDLER(ZEND_O zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); + offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if (IS_TMP_VAR != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht = Z_ARRVAL_P(container); @@ -12465,9 +12740,9 @@ num_index_prop: result = ((opline->extended_value & ZEND_ISSET) == 0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); ZVAL_BOOL(EX_VAR(opline->result.var), result); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12481,8 +12756,8 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_TMP_HANDLER(ZEND_ zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); + offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if (IS_TMP_VAR == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (EXPECTED(Z_OBJ_HT_P(container)->has_property)) { @@ -12498,9 +12773,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_TMP_HANDLER(ZEND_ result = ((opline->extended_value & ZEND_ISSET) == 0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); ZVAL_BOOL(EX_VAR(opline->result.var), result); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12534,7 +12809,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); ZVAL_COPY_VALUE(&generator->value, value); if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1); @@ -12563,7 +12838,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR } } else { - zval *value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zval *value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); /* Consts, temporary variables and references need copying */ if (IS_TMP_VAR == IS_CONST) { @@ -12588,7 +12863,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR /* Set the new yielded key */ if (IS_TMP_VAR != IS_UNUSED) { zend_free_op free_op2; - zval *key = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *key = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); /* Consts, temporary variables and references need copying */ if (IS_TMP_VAR == IS_CONST) { @@ -12643,10 +12918,10 @@ static int ZEND_FASTCALL ZEND_POW_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); pow_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12658,10 +12933,10 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); fast_add_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12673,10 +12948,10 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); fast_sub_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12688,10 +12963,10 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); fast_mul_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12703,10 +12978,10 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); fast_div_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12718,10 +12993,10 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); fast_mod_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12733,10 +13008,10 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); shift_left_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12748,10 +13023,10 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); shift_right_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12763,10 +13038,10 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_A SAVE_OPLINE(); concat_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12778,10 +13053,10 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HAN SAVE_OPLINE(); fast_is_identical_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12794,10 +13069,10 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE SAVE_OPLINE(); fast_is_not_identical_function(result, - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12810,10 +13085,10 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER SAVE_OPLINE(); fast_equal_function(result, - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12826,10 +13101,10 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HAN SAVE_OPLINE(); fast_not_equal_function(result, - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12842,10 +13117,10 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); fast_is_smaller_function(result, - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12858,10 +13133,10 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMP_VAR_HANDLER(ZEND_OPC SAVE_OPLINE(); fast_is_smaller_or_equal_function(result, - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12873,10 +13148,10 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); bitwise_or_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12888,10 +13163,10 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_A SAVE_OPLINE(); bitwise_and_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12903,10 +13178,10 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_A SAVE_OPLINE(); bitwise_xor_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12918,10 +13193,10 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER SAVE_OPLINE(); boolean_xor_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12936,7 +13211,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_VAR(int type, ZE HashTable *target_symbol_table; SAVE_OPLINE(); - varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); if (IS_TMP_VAR == IS_CONST) { name = Z_STR_P(varname); @@ -12959,7 +13234,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_VAR(int type, ZE if (IS_TMP_VAR != IS_CONST) { zend_string_release(name); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12969,7 +13244,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_VAR(int type, ZE ce = Z_CE_P(EX_VAR(opline->op2.var)); } retval = zend_std_get_static_property(ce, name, 0, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(varname)) : NULL) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } else { target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC); retval = zend_hash_find(target_symbol_table, name); @@ -13017,7 +13292,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_VAR(int type, ZE zval_update_constant(retval, 1 TSRMLS_CC); } } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } } @@ -13081,10 +13356,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HAND zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - zval_ptr_dtor_nogc(free_op1.var); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); + zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2), IS_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -13096,10 +13371,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HAN zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - zval_ptr_dtor_nogc(free_op1.var); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); + zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2), IS_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -13121,20 +13396,20 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_VAR_HANDLER(ZEND_OPCO zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } ZVAL_DEREF(container); - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); - if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2), IS_VAR TSRMLS_CC); + if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else { if (IS_VAR == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - zval_ptr_dtor_nogc(free_op1.var); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); + zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2), IS_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -13149,8 +13424,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HAND zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if ((IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { @@ -13160,15 +13435,37 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HAND zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } - zval_ptr_dtor_nogc(free_op2.var); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -13182,8 +13479,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HAN zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if ((IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { @@ -13192,15 +13489,37 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HAN zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } - zval_ptr_dtor_nogc(free_op2.var); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -13216,7 +13535,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_VAR_HANDLER(ZEND_OPCO zval *property; SAVE_OPLINE(); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); container = NULL; if (IS_TMP_VAR == IS_CONST || IS_TMP_VAR == IS_TMP_VAR) { @@ -13225,9 +13544,9 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_VAR_HANDLER(ZEND_OPCO if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, IS_VAR, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -13248,7 +13567,7 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ int use_copy = 0; SAVE_OPLINE(); - var = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + var = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_TMP_VAR == IS_UNUSED) { /* Initialize for erealloc in add_string_to_string */ @@ -13268,7 +13587,7 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ add_string_to_string(str, str, var); if (use_copy) { - zval_dtor(var); + zend_string_release(Z_STR_P(var)); } /* original comment, possibly problematic: * FREE_OP is missing intentionally here - we're always working on the same temporary variable @@ -13276,7 +13595,7 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ * which aren't affected by FREE_OP(Ts, )'s anyway, unless they're * string offsets or overloaded objects */ - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -13294,7 +13613,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE SAVE_OPLINE(); - function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { @@ -13304,18 +13623,18 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE zend_error_noreturn(E_ERROR, "Method name must be a string"); } - object = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + object = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); if (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { uint32_t nesting = 1; if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); if (EG(exception) != NULL) { HANDLE_EXCEPTION(); @@ -13383,7 +13702,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE EX(call) = zend_vm_stack_push_call_frame(VM_FRAME_NESTED_FUNCTION, fbc, opline->extended_value, called_scope, obj, EX(call) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -13397,10 +13716,10 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG SAVE_OPLINE(); fast_equal_function(result, - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -13422,7 +13741,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_VAR_HANDLER(ZEND_OPCOD Z_ADDREF_P(expr_ptr); } else { - expr_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + expr_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); if (IS_TMP_VAR == IS_TMP_VAR) { ZVAL_COPY_VALUE(&new_expr, expr_ptr); expr_ptr = &new_expr; @@ -13442,7 +13761,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_VAR_HANDLER(ZEND_OPCOD if (IS_VAR != IS_UNUSED) { zend_free_op free_op2; - zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); zend_string *str; zend_ulong hval; @@ -13485,7 +13804,7 @@ str_index: /* do nothing */ break; } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else { zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr); } @@ -13554,7 +13873,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLE ZEND_VM_NEXT_OPCODE(); } - varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); ZVAL_UNDEF(&tmp); if (IS_TMP_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { @@ -13571,10 +13890,10 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLE } else { ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_TMP_VAR != IS_CONST) { - zval_dtor(&tmp); + if (IS_TMP_VAR != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); HANDLE_EXCEPTION(); } if (UNEXPECTED(ce == NULL)) { @@ -13591,10 +13910,10 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLE zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_TMP_VAR != IS_CONST) { - zval_dtor(&tmp); + if (IS_TMP_VAR != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -13621,8 +13940,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCOD ZEND_VM_NEXT_OPCODE(); } else { zend_free_op free_op1; - zval tmp, *varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zval tmp, *varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); + ZVAL_UNDEF(&tmp); if (IS_TMP_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { ZVAL_STR(&tmp, zval_get_string(varname)); varname = &tmp; @@ -13651,10 +13971,10 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCOD value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_TMP_VAR != IS_CONST && varname == &tmp) { - zval_dtor(&tmp); + if (IS_TMP_VAR != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); if (opline->extended_value & ZEND_ISSET) { ZVAL_BOOL(EX_VAR(opline->result.var), @@ -13680,8 +14000,8 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_VAR_HANDLER(ZEND_O zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_TMP_VAR != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht = Z_ARRVAL_P(container); @@ -13751,7 +14071,7 @@ num_index_prop: result = 0; if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) { - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { + if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { ZVAL_DEREF(offset); } if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */ @@ -13777,9 +14097,9 @@ num_index_prop: result = ((opline->extended_value & ZEND_ISSET) == 0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); ZVAL_BOOL(EX_VAR(opline->result.var), result); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -13793,8 +14113,8 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_VAR_HANDLER(ZEND_ zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_TMP_VAR == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (EXPECTED(Z_OBJ_HT_P(container)->has_property)) { @@ -13810,9 +14130,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_VAR_HANDLER(ZEND_ result = ((opline->extended_value & ZEND_ISSET) == 0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); ZVAL_BOOL(EX_VAR(opline->result.var), result); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -13825,7 +14145,7 @@ static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDL zend_bool result; SAVE_OPLINE(); - expr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + expr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); if (Z_TYPE_P(expr) == IS_OBJECT) { zend_class_entry *ce; @@ -13837,7 +14157,7 @@ static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDL ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC); if (UNEXPECTED(ce == NULL)) { ZVAL_FALSE(EX_VAR(opline->result.var)); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -13851,7 +14171,7 @@ static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDL result = 0; } ZVAL_BOOL(EX_VAR(opline->result.var), result); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -13885,7 +14205,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); ZVAL_COPY_VALUE(&generator->value, value); if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1); @@ -13914,7 +14234,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR } } else { - zval *value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zval *value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); /* Consts, temporary variables and references need copying */ if (IS_TMP_VAR == IS_CONST) { @@ -13939,7 +14259,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR /* Set the new yielded key */ if (IS_VAR != IS_UNUSED) { zend_free_op free_op2; - zval *key = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *key = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); /* Consts, temporary variables and references need copying */ if (IS_VAR == IS_CONST) { @@ -13948,7 +14268,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR ZVAL_COPY_VALUE(&generator->key, key); } else if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && Z_ISREF_P(key)) { ZVAL_DUP(&generator->key, Z_REFVAL_P(key)); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else { ZVAL_COPY_VALUE(&generator->key, key); if (IS_VAR == IS_CV) { @@ -13994,10 +14314,10 @@ static int ZEND_FASTCALL ZEND_POW_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); pow_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -14012,7 +14332,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_UNUSED(int type, HashTable *target_symbol_table; SAVE_OPLINE(); - varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); if (IS_TMP_VAR == IS_CONST) { name = Z_STR_P(varname); @@ -14035,7 +14355,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_UNUSED(int type, if (IS_TMP_VAR != IS_CONST) { zend_string_release(name); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -14045,7 +14365,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_UNUSED(int type, ce = Z_CE_P(EX_VAR(opline->op2.var)); } retval = zend_std_get_static_property(ce, name, 0, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(varname)) : NULL) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } else { target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC); retval = zend_hash_find(target_symbol_table, name); @@ -14093,7 +14413,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_UNUSED(int type, zval_update_constant(retval, 1 TSRMLS_CC); } } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } } @@ -14168,7 +14488,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED_HANDLER(ZEND_O } ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC); - if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -14177,10 +14497,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_UNUSED_HANDLER(ZEND_O if (IS_UNUSED == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14203,7 +14523,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OP Z_ADDREF_P(expr_ptr); } else { - expr_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + expr_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); if (IS_TMP_VAR == IS_TMP_VAR) { ZVAL_COPY_VALUE(&new_expr, expr_ptr); expr_ptr = &new_expr; @@ -14335,7 +14655,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HAN ZEND_VM_NEXT_OPCODE(); } - varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); ZVAL_UNDEF(&tmp); if (IS_TMP_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { @@ -14352,10 +14672,10 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HAN } else { ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_TMP_VAR != IS_CONST) { - zval_dtor(&tmp); + if (IS_TMP_VAR != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); HANDLE_EXCEPTION(); } if (UNEXPECTED(ce == NULL)) { @@ -14372,10 +14692,10 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HAN zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_TMP_VAR != IS_CONST) { - zval_dtor(&tmp); + if (IS_TMP_VAR != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -14402,8 +14722,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_UNUSED_HANDLER(ZEND_OP ZEND_VM_NEXT_OPCODE(); } else { zend_free_op free_op1; - zval tmp, *varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zval tmp, *varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); + ZVAL_UNDEF(&tmp); if (IS_TMP_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { ZVAL_STR(&tmp, zval_get_string(varname)); varname = &tmp; @@ -14432,10 +14753,10 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_UNUSED_HANDLER(ZEND_OP value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_TMP_VAR != IS_CONST && varname == &tmp) { - zval_dtor(&tmp); + if (IS_TMP_VAR != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); if (opline->extended_value & ZEND_ISSET) { ZVAL_BOOL(EX_VAR(opline->result.var), @@ -14480,7 +14801,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); ZVAL_COPY_VALUE(&generator->value, value); if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1); @@ -14509,7 +14830,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER } } else { - zval *value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zval *value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); /* Consts, temporary variables and references need copying */ if (IS_TMP_VAR == IS_CONST) { @@ -14589,9 +14910,9 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); fast_add_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14604,9 +14925,9 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); fast_sub_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14619,9 +14940,9 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); fast_mul_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14634,9 +14955,9 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); fast_div_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14649,9 +14970,9 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); fast_mod_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14664,9 +14985,9 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); shift_left_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14679,9 +15000,9 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); shift_right_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14694,9 +15015,9 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); concat_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14709,9 +15030,9 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); fast_is_identical_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14725,9 +15046,9 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_ SAVE_OPLINE(); fast_is_not_identical_function(result, - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14741,9 +15062,9 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ SAVE_OPLINE(); fast_equal_function(result, - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14757,9 +15078,9 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); fast_not_equal_function(result, - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14773,9 +15094,9 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLE SAVE_OPLINE(); fast_is_smaller_function(result, - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14789,9 +15110,9 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMP_CV_HANDLER(ZEND_OPCO SAVE_OPLINE(); fast_is_smaller_or_equal_function(result, - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14804,9 +15125,9 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG SAVE_OPLINE(); bitwise_or_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14819,9 +15140,9 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); bitwise_and_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14834,9 +15155,9 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); bitwise_xor_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14849,9 +15170,9 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ SAVE_OPLINE(); boolean_xor_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14864,10 +15185,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDL zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -14879,10 +15200,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HAND zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -14905,7 +15226,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCOD } ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); - if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -14914,10 +15235,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCOD if (IS_CV == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -14932,7 +15253,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDL zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); if ((IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || @@ -14943,14 +15264,36 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDL zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -14964,7 +15307,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HAND zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); if ((IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || @@ -14974,14 +15317,36 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HAND zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -15006,9 +15371,9 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_TMP_CV_HANDLER(ZEND_OPCOD if (IS_TMP_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_TMP_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_TMP_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -15049,7 +15414,7 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_A add_string_to_string(str, str, var); if (use_copy) { - zval_dtor(var); + zend_string_release(Z_STR_P(var)); } /* original comment, possibly problematic: * FREE_OP is missing intentionally here - we're always working on the same temporary variable @@ -15084,7 +15449,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_ zend_error_noreturn(E_ERROR, "Method name must be a string"); } - object = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + object = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); if (IS_TMP_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { uint32_t nesting = 1; @@ -15176,7 +15541,7 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); fast_equal_function(result, - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); CHECK_EXCEPTION(); @@ -15200,7 +15565,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE Z_ADDREF_P(expr_ptr); } else { - expr_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + expr_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); if (IS_TMP_VAR == IS_TMP_VAR) { ZVAL_COPY_VALUE(&new_expr, expr_ptr); expr_ptr = &new_expr; @@ -15312,7 +15677,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP_CV_HANDLER(ZEND_OP zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); if (IS_TMP_VAR != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { @@ -15383,7 +15748,7 @@ num_index_prop: result = 0; if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) { - if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { + if (IS_CV == IS_CV || IS_CV == IS_VAR) { ZVAL_DEREF(offset); } if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */ @@ -15410,7 +15775,7 @@ num_index_prop: } ZVAL_BOOL(EX_VAR(opline->result.var), result); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -15424,7 +15789,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CV_HANDLER(ZEND_O zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); if (IS_TMP_VAR == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { @@ -15442,7 +15807,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_TMP_CV_HANDLER(ZEND_O } ZVAL_BOOL(EX_VAR(opline->result.var), result); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -15476,7 +15841,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); ZVAL_COPY_VALUE(&generator->value, value); if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1); @@ -15505,7 +15870,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG } } else { - zval *value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zval *value = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1); /* Consts, temporary variables and references need copying */ if (IS_TMP_VAR == IS_CONST) { @@ -15585,9 +15950,9 @@ static int ZEND_FASTCALL ZEND_POW_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); pow_function(EX_VAR(opline->result.var), - _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -15600,8 +15965,8 @@ static int ZEND_FASTCALL ZEND_BW_NOT_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); bitwise_not_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -15613,8 +15978,8 @@ static int ZEND_FASTCALL ZEND_BOOL_NOT_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG SAVE_OPLINE(); boolean_not_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -15626,7 +15991,7 @@ static int ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS zval *var_ptr; SAVE_OPLINE(); - var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); @@ -15657,7 +16022,7 @@ static int ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -15669,7 +16034,7 @@ static int ZEND_FASTCALL ZEND_PRE_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS zval *var_ptr; SAVE_OPLINE(); - var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); @@ -15700,7 +16065,7 @@ static int ZEND_FASTCALL ZEND_PRE_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS ZVAL_COPY(EX_VAR(opline->result.var), var_ptr); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -15712,7 +16077,7 @@ static int ZEND_FASTCALL ZEND_POST_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG zval *var_ptr; SAVE_OPLINE(); - var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); @@ -15740,7 +16105,7 @@ static int ZEND_FASTCALL ZEND_POST_INC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG increment_function(var_ptr); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -15752,7 +16117,7 @@ static int ZEND_FASTCALL ZEND_POST_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG zval *var_ptr; SAVE_OPLINE(); - var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets"); @@ -15780,7 +16145,7 @@ static int ZEND_FASTCALL ZEND_POST_DEC_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG decrement_function(var_ptr); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -15792,11 +16157,11 @@ static int ZEND_FASTCALL ZEND_ECHO_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval *z; SAVE_OPLINE(); - z = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + z = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); zend_print_variable(z TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -15816,7 +16181,7 @@ static int ZEND_FASTCALL ZEND_JMPZ_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval *val; SAVE_OPLINE(); - val = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + val = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_TMP_VAR) { if (Z_TYPE_P(val) == IS_TRUE) { @@ -15833,7 +16198,7 @@ static int ZEND_FASTCALL ZEND_JMPZ_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } else { opline = opline->op2.jmp_addr; } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -15847,7 +16212,7 @@ static int ZEND_FASTCALL ZEND_JMPNZ_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval *val; SAVE_OPLINE(); - val = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + val = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_TMP_VAR) { if (Z_TYPE_P(val) == IS_TRUE) { @@ -15864,7 +16229,7 @@ static int ZEND_FASTCALL ZEND_JMPNZ_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } else { opline++; } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -15878,7 +16243,7 @@ static int ZEND_FASTCALL ZEND_JMPZNZ_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval *val; SAVE_OPLINE(); - val = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + val = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_TMP_VAR) { if (EXPECTED(Z_TYPE_P(val) == IS_TRUE)) { @@ -15895,7 +16260,7 @@ static int ZEND_FASTCALL ZEND_JMPZNZ_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } else { opline = opline->op2.jmp_addr; } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -15909,7 +16274,7 @@ static int ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS zval *val; SAVE_OPLINE(); - val = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + val = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_TMP_VAR) { if (Z_TYPE_P(val) == IS_TRUE) { @@ -15924,11 +16289,11 @@ static int ZEND_FASTCALL ZEND_JMPZ_EX_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS } if (i_zend_is_true(val TSRMLS_CC)) { - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); ZVAL_TRUE(EX_VAR(opline->result.var)); opline++; } else { - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); ZVAL_FALSE(EX_VAR(opline->result.var)); opline = opline->op2.jmp_addr; } @@ -15945,7 +16310,7 @@ static int ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG zval *val; SAVE_OPLINE(); - val = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + val = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_TMP_VAR) { if (Z_TYPE_P(val) == IS_TRUE) { @@ -15965,7 +16330,7 @@ static int ZEND_FASTCALL ZEND_JMPNZ_EX_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG ZVAL_FALSE(EX_VAR(opline->result.var)); opline++; } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } @@ -15989,10 +16354,10 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_free_op free_op1; SAVE_OPLINE(); - retval_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + retval_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); if (!EX(return_value)) { - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } else { if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { ZVAL_COPY_VALUE(EX(return_value), retval_ptr); @@ -16003,7 +16368,7 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } } else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_ISREF_P(retval_ptr)) { ZVAL_COPY(EX(return_value), Z_REFVAL_P(retval_ptr)); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } else { ZVAL_COPY_VALUE(EX(return_value), retval_ptr); if (IS_VAR == IS_CV) { @@ -16028,10 +16393,10 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE /* Not supposed to happen, but we'll allow it */ zend_error(E_NOTICE, "Only variable references should be returned by reference"); - retval_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + retval_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); if (!EX(return_value)) { if (IS_VAR == IS_TMP_VAR) { - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } } else { ZVAL_COPY_VALUE(EX(return_value), retval_ptr); @@ -16043,7 +16408,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE break; } - retval_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + retval_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(retval_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot return string offsets by reference"); @@ -16071,7 +16436,7 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE } } while (0); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } @@ -16082,7 +16447,7 @@ static int ZEND_FASTCALL ZEND_THROW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_free_op free_op1; SAVE_OPLINE(); - value = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + value = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) { if (UNEXPECTED(EG(exception) != NULL)) { @@ -16098,7 +16463,7 @@ static int ZEND_FASTCALL ZEND_THROW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_throw_exception_object(value TSRMLS_CC); zend_exception_restore(TSRMLS_C); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); HANDLE_EXCEPTION(); } @@ -16108,12 +16473,12 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG zval *varptr, *arg; zend_free_op free_op1; - varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); arg = ZEND_CALL_ARG(EX(call), opline->op2.num); EX(call)->num_args = opline->op2.num; if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_ISREF_P(varptr)) { ZVAL_COPY(arg, Z_REFVAL_P(varptr)); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } else { ZVAL_COPY_VALUE(arg, varptr); if (IS_VAR == IS_CV) { @@ -16130,17 +16495,14 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND zval *varptr, *arg; SAVE_OPLINE(); - if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) { /* Had function_ptr at compile_time */ - if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) { - return ZEND_SEND_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - } - } else { + + if (!(opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND)) { if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) { return ZEND_SEND_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } } - varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); if ((!(opline->extended_value & ZEND_ARG_SEND_FUNCTION) || (Z_VAR_FLAGS_P(varptr) & IS_VAR_RET_REF)) && (Z_ISREF_P(varptr) || Z_TYPE_P(varptr) == IS_OBJECT)) { @@ -16149,20 +16511,18 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND if (IS_VAR == IS_CV) { Z_ADDREF_P(varptr); } - arg = ZEND_CALL_ARG(EX(call), opline->op2.num); - EX(call)->num_args = opline->op2.num; - ZVAL_COPY_VALUE(arg, varptr); } else { if ((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ? !(opline->extended_value & ZEND_ARG_SEND_SILENT) : !ARG_MAY_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) { zend_error(E_STRICT, "Only variables should be passed by reference"); } - arg = ZEND_CALL_ARG(EX(call), opline->op2.num); - EX(call)->num_args = opline->op2.num; - ZVAL_COPY(arg, varptr); - zval_ptr_dtor_nogc(free_op1.var); } + + arg = ZEND_CALL_ARG(EX(call), opline->op2.num); + EX(call)->num_args = opline->op2.num; + ZVAL_COPY_VALUE(arg, varptr); + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -16174,7 +16534,7 @@ static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG zval *varptr, *arg; SAVE_OPLINE(); - varptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + varptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(varptr == NULL)) { zend_error_noreturn(E_ERROR, "Only variables can be passed by reference"); @@ -16192,15 +16552,14 @@ static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG ZVAL_COPY_VALUE(arg, varptr); } else if (IS_VAR == IS_VAR && UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT)) { - ZVAL_COPY_VALUE(arg, varptr); - ZVAL_MAKE_REF(arg); + ZVAL_NEW_REF(arg, varptr); } else { - ZVAL_MAKE_REF(varptr); - Z_ADDREF_P(varptr); - ZVAL_REF(arg, Z_REF_P(varptr)); + ZVAL_NEW_REF(arg, varptr); + Z_ADDREF_P(arg); + ZVAL_REF(varptr, Z_REF_P(arg)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; ZEND_VM_NEXT_OPCODE(); } @@ -16213,12 +16572,12 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_EX_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) { return ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } - varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); arg = ZEND_CALL_ARG(EX(call), opline->op2.num); EX(call)->num_args = opline->op2.num; if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_ISREF_P(varptr)) { ZVAL_COPY(arg, Z_REFVAL_P(varptr)); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } else { ZVAL_COPY_VALUE(arg, varptr); if (IS_VAR == IS_CV) { @@ -16234,7 +16593,7 @@ static int ZEND_FASTCALL ZEND_SEND_USER_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR zval *arg, *param, tmp; zend_free_op free_op1; - arg = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + arg = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); param = ZEND_CALL_ARG(EX(call), opline->op2.num); if (ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) { @@ -16274,7 +16633,7 @@ static int ZEND_FASTCALL ZEND_SEND_USER_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR EX(call)->called_scope = NULL; Z_OBJ(EX(call)->This) = NULL; - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -16302,7 +16661,7 @@ static int ZEND_FASTCALL ZEND_SEND_USER_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR EX(call)->num_args = opline->op2.num; - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -16315,8 +16674,8 @@ static int ZEND_FASTCALL ZEND_BOOL_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); /* PHP 3.0 returned "" for false and 1 for true, here we use 0 and 1 for now */ - ZVAL_BOOL(retval, i_zend_is_true(_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC) TSRMLS_CC)); - zval_ptr_dtor_nogc(free_op1.var); + ZVAL_BOOL(retval, i_zend_is_true(_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1) TSRMLS_CC)); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -16360,7 +16719,7 @@ static int ZEND_FASTCALL ZEND_NEW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (RETURN_VALUE_USED(opline)) { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), &object_zval); } else { - zval_ptr_dtor(&object_zval); + OBJ_RELEASE(Z_OBJ(object_zval)); } ZEND_VM_JMP(opline->op2.jmp_addr); } else { @@ -16398,7 +16757,7 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_object_clone_obj_t clone_call; SAVE_OPLINE(); - obj = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + obj = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_CONST || (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) { @@ -16438,10 +16797,10 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (EXPECTED(EG(exception) == NULL)) { ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj TSRMLS_CC)); if (!RETURN_VALUE_USED(opline) || UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor(EX_VAR(opline->result.var)); + OBJ_RELEASE(Z_OBJ_P(EX_VAR(opline->result.var))); } } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -16454,7 +16813,7 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zval *result = EX_VAR(opline->result.var); SAVE_OPLINE(); - expr = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + expr = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); switch (opline->extended_value) { case IS_NULL: @@ -16498,7 +16857,7 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (Z_OPT_REFCOUNTED_P(expr)) Z_ADDREF_P(expr); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -16543,7 +16902,7 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) } } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -16558,7 +16917,7 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND zend_bool failure_retval=0; SAVE_OPLINE(); - inc_filename = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + inc_filename = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); ZVAL_UNDEF(&tmp_inc_filename); if (Z_TYPE_P(inc_filename) != IS_STRING) { @@ -16628,9 +16987,9 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND } } if (Z_TYPE(tmp_inc_filename) != IS_UNDEF) { - zval_ptr_dtor(&tmp_inc_filename); + zend_string_release(Z_STR(tmp_inc_filename)); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); if (UNEXPECTED(EG(exception) != NULL)) { HANDLE_EXCEPTION(); } else if (EXPECTED(new_op_array != NULL)) { @@ -16686,7 +17045,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && (opline->extended_value & ZEND_FE_FETCH_BYREF)) { - array_ptr = array_ref = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + array_ptr = array_ref = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); ZVAL_DEREF(array_ptr); if (Z_TYPE_P(array_ptr) == IS_ARRAY) { SEPARATE_ARRAY(array_ptr); @@ -16705,7 +17064,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG if (Z_REFCOUNTED_P(array_ref)) Z_ADDREF_P(array_ref); } } else { - array_ptr = array_ref = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + array_ptr = array_ref = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); ZVAL_DEREF(array_ptr); if (IS_VAR == IS_TMP_VAR) { ZVAL_COPY_VALUE(&tmp, array_ptr); @@ -16772,14 +17131,14 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG iter = ce->get_iterator(ce, array_ptr, opline->extended_value & ZEND_FE_FETCH_BYREF TSRMLS_CC); if (IS_VAR == IS_VAR && !(opline->extended_value & ZEND_FE_FETCH_BYREF)) { - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } if (iter && EXPECTED(EG(exception) == NULL)) { ZVAL_OBJ(&iterator, &iter->std); array_ptr = array_ref = &iterator; } else { if (IS_VAR == IS_VAR && opline->extended_value & ZEND_FE_FETCH_BYREF) { - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; } if (!EG(exception)) { zend_throw_exception_ex(NULL, 0 TSRMLS_CC, "Object of type %s did not create an Iterator", ce->name->val); @@ -16798,7 +17157,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG if (UNEXPECTED(EG(exception) != NULL)) { zval_ptr_dtor(array_ref); if (IS_VAR == IS_VAR && opline->extended_value & ZEND_FE_FETCH_BYREF) { - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; } HANDLE_EXCEPTION(); } @@ -16807,7 +17166,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG if (UNEXPECTED(EG(exception) != NULL)) { zval_ptr_dtor(array_ref); if (IS_VAR == IS_VAR && opline->extended_value & ZEND_FE_FETCH_BYREF) { - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; } HANDLE_EXCEPTION(); } @@ -16821,7 +17180,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG if (pos >= fe_ht->nNumUsed) { is_empty = 1; if (IS_VAR == IS_VAR && opline->extended_value & ZEND_FE_FETCH_BYREF) { - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; } ZEND_VM_JMP(opline->op2.jmp_addr); } @@ -16851,7 +17210,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG } if (IS_VAR == IS_VAR && opline->extended_value & ZEND_FE_FETCH_BYREF) { - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; } if (is_empty) { ZEND_VM_JMP(opline->op2.jmp_addr); @@ -17119,14 +17478,14 @@ static int ZEND_FASTCALL ZEND_EXIT_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); if (IS_VAR != IS_UNUSED) { zend_free_op free_op1; - zval *ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zval *ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); if (Z_TYPE_P(ptr) == IS_LONG) { EG(exit_status) = Z_LVAL_P(ptr); } else { zend_print_variable(ptr TSRMLS_CC); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } #endif zend_bailout(); @@ -17141,7 +17500,7 @@ static int ZEND_FASTCALL ZEND_JMP_SET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS int is_ref = 0; SAVE_OPLINE(); - value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && Z_ISREF_P(value)) { is_ref = 1; @@ -17157,12 +17516,12 @@ static int ZEND_FASTCALL ZEND_JMP_SET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } else if (IS_VAR == IS_VAR && is_ref) { if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } ZEND_VM_JMP(opline->op2.jmp_addr); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -17175,7 +17534,7 @@ static int ZEND_FASTCALL ZEND_COALESCE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG int is_ref = 0; SAVE_OPLINE(); - value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && Z_ISREF_P(value)) { is_ref = 1; @@ -17192,12 +17551,12 @@ static int ZEND_FASTCALL ZEND_COALESCE_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); } else if (IS_VAR == IS_VAR && is_ref) { if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } ZEND_VM_JMP(opline->op2.jmp_addr); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -17209,11 +17568,11 @@ static int ZEND_FASTCALL ZEND_QM_ASSIGN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR zval *value; SAVE_OPLINE(); - value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && Z_ISREF_P(value)) { ZVAL_COPY(EX_VAR(opline->result.var), Z_REFVAL_P(value)); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } else { ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value); if (IS_VAR == IS_CONST) { @@ -17234,7 +17593,7 @@ static int ZEND_FASTCALL ZEND_STRLEN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) zend_free_op free_op1; SAVE_OPLINE(); - value = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + value = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); if (EXPECTED(Z_TYPE_P(value) == IS_STRING)) { ZVAL_LONG(EX_VAR(opline->result.var), Z_STRLEN_P(value)); } else { @@ -17262,7 +17621,7 @@ strlen_error: ZVAL_NULL(EX_VAR(opline->result.var)); } } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -17274,7 +17633,7 @@ static int ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_A zend_free_op free_op1; SAVE_OPLINE(); - value = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + value = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); switch (opline->extended_value) { case IS_NULL: case IS_LONG: @@ -17309,7 +17668,7 @@ static int ZEND_FASTCALL ZEND_TYPE_CHECK_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_A break; EMPTY_SWITCH_DEFAULT_CASE() } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -17321,9 +17680,9 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); fast_add_function(EX_VAR(opline->result.var), - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -17336,9 +17695,9 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); fast_sub_function(EX_VAR(opline->result.var), - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -17351,9 +17710,9 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); fast_mul_function(EX_VAR(opline->result.var), - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -17366,9 +17725,9 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); fast_div_function(EX_VAR(opline->result.var), - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -17381,9 +17740,9 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); fast_mod_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -17396,9 +17755,9 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG SAVE_OPLINE(); shift_left_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -17411,9 +17770,9 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG SAVE_OPLINE(); shift_right_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -17426,9 +17785,9 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER SAVE_OPLINE(); concat_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -17441,9 +17800,9 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H SAVE_OPLINE(); fast_is_identical_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -17457,9 +17816,9 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCO SAVE_OPLINE(); fast_is_not_identical_function(result, - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -17473,9 +17832,9 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); fast_equal_function(result, - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -17489,9 +17848,9 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H SAVE_OPLINE(); fast_not_equal_function(result, - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -17505,9 +17864,9 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN SAVE_OPLINE(); fast_is_smaller_function(result, - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -17521,9 +17880,9 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_CONST_HANDLER(ZEND_O SAVE_OPLINE(); fast_is_smaller_or_equal_function(result, - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -17536,9 +17895,9 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ SAVE_OPLINE(); bitwise_or_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -17551,9 +17910,9 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER SAVE_OPLINE(); bitwise_and_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -17566,9 +17925,9 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER SAVE_OPLINE(); bitwise_xor_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -17581,9 +17940,9 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); boolean_xor_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -17593,7 +17952,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b { USE_OPLINE zend_free_op free_op1, free_op_data1; - zval *object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zval *object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); zval *property = opline->op2.zv; zval *value; zval *zptr; @@ -17648,7 +18007,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -17675,7 +18034,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b FREE_OP(free_op_data1); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; /* assign_obj has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -17690,7 +18049,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CONST(int (*b zval *value, *container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } @@ -17698,7 +18057,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CONST(int (*b ZVAL_DEREF(container); } if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) { + if (IS_VAR == IS_VAR && !(free_op1 != NULL)) { Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */ } return zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -17731,7 +18090,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CONST(int (*b } FREE_OP(free_op_data1); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); ZEND_VM_NEXT_OPCODE(); @@ -17746,7 +18105,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CONST(int (*binar SAVE_OPLINE(); value = opline->op2.zv; - var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); @@ -17767,7 +18126,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CONST(int (*binar } } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -17925,7 +18284,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t zval *zptr; SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); property = opline->op2.zv; retval = EX_VAR(opline->result.var); @@ -17943,7 +18302,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t if (RETURN_VALUE_USED(opline)) { ZVAL_NULL(retval); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -17971,7 +18330,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -17990,7 +18349,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CONST(incdec_t } } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18015,7 +18374,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_ zval *zptr; SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); property = opline->op2.zv; retval = EX_VAR(opline->result.var); @@ -18031,7 +18390,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_ zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); ZVAL_NULL(retval); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18057,7 +18416,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_ zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -18074,7 +18433,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CONST(incdec_ } } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18099,7 +18458,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_CONST(int type, HashTable *target_symbol_table; SAVE_OPLINE(); - varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_CONST) { name = Z_STR_P(varname); @@ -18122,7 +18481,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_CONST(int type, if (IS_VAR != IS_CONST) { zend_string_release(name); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18132,7 +18491,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_CONST(int type, ce = Z_CE_P(EX_VAR(opline->op2.var)); } retval = zend_std_get_static_property(ce, name, 0, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(varname)) : NULL) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } else { target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC); retval = zend_hash_find(target_symbol_table, name); @@ -18180,7 +18539,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_CONST(int type, zval_update_constant(retval, 1 TSRMLS_CC); } } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } } @@ -18244,10 +18603,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18259,7 +18618,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); @@ -18267,10 +18626,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18282,7 +18641,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); @@ -18290,10 +18649,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H ZVAL_DEREF(container); zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18305,10 +18664,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18325,25 +18684,25 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OP if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); } - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; } else { if (IS_CONST == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -18356,7 +18715,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCOD zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); @@ -18364,10 +18723,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCOD ZVAL_DEREF(container); zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18381,7 +18740,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); offset = opline->op2.zv; if ((IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || @@ -18392,14 +18751,36 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18414,17 +18795,17 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HA SAVE_OPLINE(); property = opline->op2.zv; - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18438,17 +18819,17 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H SAVE_OPLINE(); property = opline->op2.zv; - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18462,7 +18843,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); offset = opline->op2.zv; if ((IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || @@ -18472,14 +18853,36 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_H zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18496,7 +18899,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OP SAVE_OPLINE(); property = opline->op2.zv; - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); @@ -18504,12 +18907,12 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CONST_HANDLER(ZEND_OP if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } else { @@ -18524,18 +18927,18 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CONST_HANDLER(ZEND_OPCOD zval *container, *property; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); property = opline->op2.zv; if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18547,7 +18950,7 @@ static int ZEND_FASTCALL ZEND_FETCH_LIST_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); if (EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { @@ -18581,7 +18984,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN zval *property_name; SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); property_name = opline->op2.zv; if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { @@ -18589,7 +18992,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN } zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; /* assign_obj has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -18603,7 +19006,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN zval *object_ptr; SAVE_OPLINE(); - object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); @@ -18651,7 +19054,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN } } } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; /* assign_dim has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -18667,7 +19070,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER SAVE_OPLINE(); value = opline->op2.zv; - variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) { if (IS_CONST == IS_TMP_VAR) { @@ -18681,7 +19084,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER if (RETURN_VALUE_USED(opline)) { ZVAL_COPY(EX_VAR(opline->result.var), value); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; } /* zend_assign_to_variable() always takes care of op2, never free it! */ @@ -18712,7 +19115,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZEND_OPCO zend_error_noreturn(E_ERROR, "Method name must be a string"); } - object = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + object = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { uint32_t nesting = 1; @@ -18724,7 +19127,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZEND_OPCO zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); if (EG(exception) != NULL) { HANDLE_EXCEPTION(); @@ -18792,7 +19195,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZEND_OPCO EX(call) = zend_vm_stack_push_call_frame(VM_FRAME_NESTED_FUNCTION, fbc, opline->extended_value, called_scope, obj, EX(call) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -18930,7 +19333,7 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_A SAVE_OPLINE(); fast_equal_function(result, - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); CHECK_EXCEPTION(); @@ -19044,15 +19447,15 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPC SAVE_OPLINE(); if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { - expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; } else { - expr_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + expr_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_TMP_VAR) { ZVAL_COPY_VALUE(&new_expr, expr_ptr); expr_ptr = &new_expr; @@ -19064,7 +19467,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPC } else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_ISREF_P(expr_ptr)) { expr_ptr = Z_REFVAL_P(expr_ptr); if (Z_REFCOUNTED_P(expr_ptr)) Z_ADDREF_P(expr_ptr); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } else if (IS_VAR == IS_CV && Z_REFCOUNTED_P(expr_ptr)) { Z_ADDREF_P(expr_ptr); } @@ -19184,7 +19587,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND ZEND_VM_NEXT_OPCODE(); } - varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); ZVAL_UNDEF(&tmp); if (IS_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { @@ -19201,10 +19604,10 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND } else { ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_VAR != IS_CONST) { - zval_dtor(&tmp); + if (IS_VAR != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); HANDLE_EXCEPTION(); } if (UNEXPECTED(ce == NULL)) { @@ -19221,10 +19624,10 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_VAR != IS_CONST) { - zval_dtor(&tmp); + if (IS_VAR != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19238,7 +19641,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND zend_ulong hval; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); } @@ -19309,7 +19712,7 @@ num_index_dim: } else { } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19322,7 +19725,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); } @@ -19337,7 +19740,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND } } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19364,8 +19767,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPC ZEND_VM_NEXT_OPCODE(); } else { zend_free_op free_op1; - zval tmp, *varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zval tmp, *varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); + ZVAL_UNDEF(&tmp); if (IS_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { ZVAL_STR(&tmp, zval_get_string(varname)); varname = &tmp; @@ -19394,10 +19798,10 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPC value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_VAR != IS_CONST && varname == &tmp) { - zval_dtor(&tmp); + if (IS_VAR != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); if (opline->extended_value & ZEND_ISSET) { ZVAL_BOOL(EX_VAR(opline->result.var), @@ -19423,7 +19827,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_VAR_CONST_HANDLER(ZEND zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); offset = opline->op2.zv; if (IS_VAR != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { @@ -19494,7 +19898,7 @@ num_index_prop: result = 0; if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) { - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { + if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { ZVAL_DEREF(offset); } if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */ @@ -19521,7 +19925,7 @@ num_index_prop: } ZVAL_BOOL(EX_VAR(opline->result.var), result); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19535,7 +19939,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_CONST_HANDLER(ZEN zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); offset = opline->op2.zv; if (IS_VAR == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { @@ -19553,7 +19957,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_CONST_HANDLER(ZEN } ZVAL_BOOL(EX_VAR(opline->result.var), result); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19566,7 +19970,7 @@ static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN zend_bool result; SAVE_OPLINE(); - expr = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + expr = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); if (Z_TYPE_P(expr) == IS_OBJECT) { zend_class_entry *ce; @@ -19578,7 +19982,7 @@ static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC); if (UNEXPECTED(ce == NULL)) { ZVAL_FALSE(EX_VAR(opline->result.var)); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19592,7 +19996,7 @@ static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAN result = 0; } ZVAL_BOOL(EX_VAR(opline->result.var), result); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19626,7 +20030,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); ZVAL_COPY_VALUE(&generator->value, value); if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1); @@ -19635,7 +20039,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ zval_opt_copy_ctor(&generator->value); } } else { - zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); @@ -19653,10 +20057,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ } ZVAL_COPY(&generator->value, value_ptr); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; } } else { - zval *value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zval *value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); /* Consts, temporary variables and references need copying */ if (IS_VAR == IS_CONST) { @@ -19665,7 +20069,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ ZVAL_COPY_VALUE(&generator->value, value); } else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_ISREF_P(value)) { ZVAL_DUP(&generator->value, Z_REFVAL_P(value)); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } else { ZVAL_COPY_VALUE(&generator->value, value); if (IS_VAR == IS_CV) { @@ -19736,9 +20140,9 @@ static int ZEND_FASTCALL ZEND_POW_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); pow_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), opline->op2.zv TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -19756,10 +20160,10 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); fast_add_function(EX_VAR(opline->result.var), - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19771,10 +20175,10 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); fast_sub_function(EX_VAR(opline->result.var), - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19786,10 +20190,10 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); fast_mul_function(EX_VAR(opline->result.var), - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19801,10 +20205,10 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); fast_div_function(EX_VAR(opline->result.var), - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19816,10 +20220,10 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); fast_mod_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19831,10 +20235,10 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); shift_left_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19846,10 +20250,10 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); shift_right_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19861,10 +20265,10 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_A SAVE_OPLINE(); concat_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19876,10 +20280,10 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN SAVE_OPLINE(); fast_is_identical_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19892,10 +20296,10 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE SAVE_OPLINE(); fast_is_not_identical_function(result, - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19908,10 +20312,10 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER SAVE_OPLINE(); fast_equal_function(result, - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19924,10 +20328,10 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN SAVE_OPLINE(); fast_not_equal_function(result, - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19940,10 +20344,10 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); fast_is_smaller_function(result, - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19956,10 +20360,10 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_TMP_HANDLER(ZEND_OPC SAVE_OPLINE(); fast_is_smaller_or_equal_function(result, - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19971,10 +20375,10 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); bitwise_or_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -19986,10 +20390,10 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_A SAVE_OPLINE(); bitwise_and_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -20001,10 +20405,10 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_A SAVE_OPLINE(); bitwise_xor_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -20016,10 +20420,10 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER SAVE_OPLINE(); boolean_xor_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -20028,8 +20432,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin { USE_OPLINE zend_free_op free_op1, free_op2, free_op_data1; - zval *object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - zval *property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); + zval *property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); zval *value; zval *zptr; @@ -20045,7 +20449,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to assign property of non-object"); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); FREE_OP(free_op_data1); if (RETURN_VALUE_USED(opline)) { @@ -20083,7 +20487,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -20107,11 +20511,11 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin } } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); FREE_OP(free_op_data1); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; /* assign_obj has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -20126,7 +20530,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_TMP(int (*bin zval *value, *container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } @@ -20134,12 +20538,12 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_TMP(int (*bin ZVAL_DEREF(container); } if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) { + if (IS_VAR == IS_VAR && !(free_op1 != NULL)) { Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */ } return zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } else { - zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); zend_fetch_dimension_address_RW(&rv, container, dim, IS_TMP_VAR TSRMLS_CC); value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); @@ -20166,9 +20570,9 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_TMP(int (*bin } } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); FREE_OP(free_op_data1); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); ZEND_VM_NEXT_OPCODE(); @@ -20182,8 +20586,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_TMP(int (*binary_ zval *value; SAVE_OPLINE(); - value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); + var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); @@ -20204,8 +20608,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_TMP(int (*binary_ } } - zval_ptr_dtor_nogc(free_op2.var); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + zval_ptr_dtor_nogc(free_op2); + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -20363,8 +20767,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMP(incdec_t i zval *zptr; SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); + property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); retval = EX_VAR(opline->result.var); if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { @@ -20377,11 +20781,11 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMP(incdec_t i if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); if (RETURN_VALUE_USED(opline)) { ZVAL_NULL(retval); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -20409,7 +20813,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMP(incdec_t i zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -20428,8 +20832,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_TMP(incdec_t i } } - zval_ptr_dtor_nogc(free_op2.var); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + zval_ptr_dtor_nogc(free_op2); + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -20454,8 +20858,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMP(incdec_t zval *zptr; SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); + property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); retval = EX_VAR(opline->result.var); if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { @@ -20468,9 +20872,9 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMP(incdec_t if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); ZVAL_NULL(retval); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -20496,7 +20900,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMP(incdec_t zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -20513,8 +20917,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_TMP(incdec_t } } - zval_ptr_dtor_nogc(free_op2.var); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + zval_ptr_dtor_nogc(free_op2); + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -20536,10 +20940,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - zval_ptr_dtor_nogc(free_op1.var); + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); + zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2), IS_TMP_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -20551,18 +20955,18 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } ZVAL_DEREF(container); - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2), IS_TMP_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -20574,18 +20978,18 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } ZVAL_DEREF(container); - zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2), IS_TMP_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -20597,10 +21001,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - zval_ptr_dtor_nogc(free_op1.var); + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); + zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2), IS_TMP_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -20617,25 +21021,25 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCO if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); } - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } ZVAL_DEREF(container); - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2), IS_TMP_VAR TSRMLS_CC); + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - zval_ptr_dtor_nogc(free_op2.var); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + zval_ptr_dtor_nogc(free_op2); + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; } else { if (IS_TMP_VAR == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - zval_ptr_dtor_nogc(free_op1.var); + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); + zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2), IS_TMP_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -20648,18 +21052,18 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_ zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } ZVAL_DEREF(container); - zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2), IS_TMP_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -20673,8 +21077,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); + offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if ((IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { @@ -20684,15 +21088,37 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_TMP_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } - zval_ptr_dtor_nogc(free_op2.var); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -20705,19 +21131,19 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAND zval *container; SAVE_OPLINE(); - property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -20730,18 +21156,18 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN zval *container; SAVE_OPLINE(); - property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -20755,8 +21181,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); + offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if ((IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { @@ -20765,15 +21191,37 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HAN zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_TMP_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } - zval_ptr_dtor_nogc(free_op2.var); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -20789,8 +21237,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCO zval *property; SAVE_OPLINE(); - property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); @@ -20798,12 +21246,12 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_TMP_HANDLER(ZEND_OPCO if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } else { @@ -20818,18 +21266,18 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_ zval *container, *property; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); + property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -20842,15 +21290,15 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL zval *property_name; SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); + property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + zval_ptr_dtor_nogc(free_op2); + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; /* assign_obj has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -20864,7 +21312,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL zval *object_ptr; SAVE_OPLINE(); - object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); @@ -20872,27 +21320,27 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL ZVAL_DEREF(object_ptr); if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_free_op free_op2; - zval *property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else { zend_free_op free_op2, free_op_data1; zval rv; zval *value; - zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); zval *variable_ptr; if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) && EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); FREE_OP(free_op_data1); } else { zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_TMP_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); variable_ptr = Z_INDIRECT(rv); @@ -20912,7 +21360,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDL } } } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; /* assign_dim has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -20927,12 +21375,12 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_A zval *variable_ptr; SAVE_OPLINE(); - value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); + variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) { if (IS_TMP_VAR == IS_TMP_VAR) { - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } if (RETURN_VALUE_USED(opline)) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -20942,7 +21390,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_A if (RETURN_VALUE_USED(opline)) { ZVAL_COPY(EX_VAR(opline->result.var), value); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; } /* zend_assign_to_variable() always takes care of op2, never free it! */ @@ -20963,7 +21411,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE SAVE_OPLINE(); - function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if (IS_TMP_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { @@ -20973,19 +21421,19 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE zend_error_noreturn(E_ERROR, "Method name must be a string"); } - object = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + object = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { uint32_t nesting = 1; if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); - zval_ptr_dtor_nogc(free_op2.var); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); if (EG(exception) != NULL) { HANDLE_EXCEPTION(); @@ -21053,8 +21501,8 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE EX(call) = zend_vm_stack_push_call_frame(VM_FRAME_NESTED_FUNCTION, fbc, opline->extended_value, called_scope, obj, EX(call) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -21099,7 +21547,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND } else if (IS_TMP_VAR != IS_UNUSED) { zend_free_op free_op2; - function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if (IS_TMP_VAR != IS_CONST) { if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { if (UNEXPECTED(EG(exception) != NULL)) { @@ -21127,7 +21575,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND } } if (IS_TMP_VAR != IS_CONST) { - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } } else { if (UNEXPECTED(ce->constructor == NULL)) { @@ -21192,10 +21640,10 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG SAVE_OPLINE(); fast_equal_function(result, - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -21209,15 +21657,15 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER(ZEND_OPCOD SAVE_OPLINE(); if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { - expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; } else { - expr_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + expr_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_TMP_VAR) { ZVAL_COPY_VALUE(&new_expr, expr_ptr); expr_ptr = &new_expr; @@ -21229,7 +21677,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER(ZEND_OPCOD } else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_ISREF_P(expr_ptr)) { expr_ptr = Z_REFVAL_P(expr_ptr); if (Z_REFCOUNTED_P(expr_ptr)) Z_ADDREF_P(expr_ptr); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } else if (IS_VAR == IS_CV && Z_REFCOUNTED_P(expr_ptr)) { Z_ADDREF_P(expr_ptr); } @@ -21237,7 +21685,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER(ZEND_OPCOD if (IS_TMP_VAR != IS_UNUSED) { zend_free_op free_op2; - zval *offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); zend_string *str; zend_ulong hval; @@ -21280,7 +21728,7 @@ str_index: /* do nothing */ break; } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else { zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr); } @@ -21328,7 +21776,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLE zend_ulong hval; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); } @@ -21336,7 +21784,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLE ZVAL_DEREF(container); SEPARATE_ZVAL_NOREF(container); } - offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if (IS_VAR != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht = Z_ARRVAL_P(container); @@ -21383,7 +21831,7 @@ num_index_dim: zend_error(E_WARNING, "Illegal offset type in unset"); break; } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else if (IS_VAR == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use object as array"); @@ -21392,14 +21840,14 @@ num_index_dim: //??? zval_copy_ctor(offset); //??? } Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_CONTINUE(); /* bailed out before */ } else { - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -21412,11 +21860,11 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLE zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); } - offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); ZVAL_DEREF(container); if (IS_VAR == IS_UNUSED || Z_TYPE_P(container) == IS_OBJECT) { @@ -21426,8 +21874,8 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLE zend_error(E_NOTICE, "Trying to unset property of non-object"); } } - zval_ptr_dtor_nogc(free_op2.var); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + zval_ptr_dtor_nogc(free_op2); + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -21442,8 +21890,8 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_O zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); + offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if (IS_VAR != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht = Z_ARRVAL_P(container); @@ -21513,7 +21961,7 @@ num_index_prop: result = 0; if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) { - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { + if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { ZVAL_DEREF(offset); } if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */ @@ -21539,9 +21987,9 @@ num_index_prop: result = ((opline->extended_value & ZEND_ISSET) == 0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); ZVAL_BOOL(EX_VAR(opline->result.var), result); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -21555,8 +22003,8 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_ zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); + offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if (IS_VAR == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (EXPECTED(Z_OBJ_HT_P(container)->has_property)) { @@ -21572,9 +22020,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_TMP_HANDLER(ZEND_ result = ((opline->extended_value & ZEND_ISSET) == 0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); ZVAL_BOOL(EX_VAR(opline->result.var), result); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -21608,7 +22056,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); ZVAL_COPY_VALUE(&generator->value, value); if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1); @@ -21617,7 +22065,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR zval_opt_copy_ctor(&generator->value); } } else { - zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); @@ -21635,10 +22083,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR } ZVAL_COPY(&generator->value, value_ptr); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; } } else { - zval *value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zval *value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); /* Consts, temporary variables and references need copying */ if (IS_VAR == IS_CONST) { @@ -21647,7 +22095,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR ZVAL_COPY_VALUE(&generator->value, value); } else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_ISREF_P(value)) { ZVAL_DUP(&generator->value, Z_REFVAL_P(value)); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } else { ZVAL_COPY_VALUE(&generator->value, value); if (IS_VAR == IS_CV) { @@ -21663,7 +22111,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR /* Set the new yielded key */ if (IS_TMP_VAR != IS_UNUSED) { zend_free_op free_op2; - zval *key = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *key = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); /* Consts, temporary variables and references need copying */ if (IS_TMP_VAR == IS_CONST) { @@ -21718,10 +22166,10 @@ static int ZEND_FASTCALL ZEND_POW_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); pow_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -21738,10 +22186,10 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); fast_add_function(EX_VAR(opline->result.var), - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -21753,10 +22201,10 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); fast_sub_function(EX_VAR(opline->result.var), - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -21768,10 +22216,10 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); fast_mul_function(EX_VAR(opline->result.var), - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -21783,10 +22231,10 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); fast_div_function(EX_VAR(opline->result.var), - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -21798,10 +22246,10 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); fast_mod_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -21813,10 +22261,10 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); shift_left_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -21828,10 +22276,10 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); shift_right_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -21843,10 +22291,10 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_A SAVE_OPLINE(); concat_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -21858,10 +22306,10 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN SAVE_OPLINE(); fast_is_identical_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -21874,10 +22322,10 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE SAVE_OPLINE(); fast_is_not_identical_function(result, - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -21890,10 +22338,10 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER SAVE_OPLINE(); fast_equal_function(result, - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -21906,10 +22354,10 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN SAVE_OPLINE(); fast_not_equal_function(result, - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -21922,10 +22370,10 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); fast_is_smaller_function(result, - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -21938,10 +22386,10 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_VAR_HANDLER(ZEND_OPC SAVE_OPLINE(); fast_is_smaller_or_equal_function(result, - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -21953,10 +22401,10 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); bitwise_or_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -21968,10 +22416,10 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_A SAVE_OPLINE(); bitwise_and_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -21983,10 +22431,10 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_A SAVE_OPLINE(); bitwise_xor_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -21998,10 +22446,10 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER SAVE_OPLINE(); boolean_xor_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22010,8 +22458,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin { USE_OPLINE zend_free_op free_op1, free_op2, free_op_data1; - zval *object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - zval *property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); + zval *property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); zval *value; zval *zptr; @@ -22027,7 +22475,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to assign property of non-object"); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); FREE_OP(free_op_data1); if (RETURN_VALUE_USED(opline)) { @@ -22065,7 +22513,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -22089,11 +22537,11 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin } } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); FREE_OP(free_op_data1); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; /* assign_obj has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -22108,7 +22556,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_VAR(int (*bin zval *value, *container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } @@ -22116,12 +22564,12 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_VAR(int (*bin ZVAL_DEREF(container); } if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) { + if (IS_VAR == IS_VAR && !(free_op1 != NULL)) { Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */ } return zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } else { - zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2); zend_fetch_dimension_address_RW(&rv, container, dim, IS_VAR TSRMLS_CC); value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); @@ -22148,9 +22596,9 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_VAR(int (*bin } } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); FREE_OP(free_op_data1); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); ZEND_VM_NEXT_OPCODE(); @@ -22164,8 +22612,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_VAR(int (*binary_ zval *value; SAVE_OPLINE(); - value = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + value = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2); + var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); @@ -22186,8 +22634,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_VAR(int (*binary_ } } - zval_ptr_dtor_nogc(free_op2.var); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + zval_ptr_dtor_nogc(free_op2); + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22345,8 +22793,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_VAR(incdec_t i zval *zptr; SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); retval = EX_VAR(opline->result.var); if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { @@ -22359,11 +22807,11 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_VAR(incdec_t i if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); if (RETURN_VALUE_USED(opline)) { ZVAL_NULL(retval); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22391,7 +22839,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_VAR(incdec_t i zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -22410,8 +22858,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_VAR(incdec_t i } } - zval_ptr_dtor_nogc(free_op2.var); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + zval_ptr_dtor_nogc(free_op2); + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22436,8 +22884,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_VAR(incdec_t zval *zptr; SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); retval = EX_VAR(opline->result.var); if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { @@ -22450,9 +22898,9 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_VAR(incdec_t if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); ZVAL_NULL(retval); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22478,7 +22926,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_VAR(incdec_t zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -22495,8 +22943,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_VAR(incdec_t } } - zval_ptr_dtor_nogc(free_op2.var); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + zval_ptr_dtor_nogc(free_op2); + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22521,7 +22969,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_VAR(int type, ZE HashTable *target_symbol_table; SAVE_OPLINE(); - varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_CONST) { name = Z_STR_P(varname); @@ -22544,7 +22992,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_VAR(int type, ZE if (IS_VAR != IS_CONST) { zend_string_release(name); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22554,7 +23002,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_VAR(int type, ZE ce = Z_CE_P(EX_VAR(opline->op2.var)); } retval = zend_std_get_static_property(ce, name, 0, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(varname)) : NULL) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } else { target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC); retval = zend_hash_find(target_symbol_table, name); @@ -22602,7 +23050,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_VAR(int type, ZE zval_update_constant(retval, 1 TSRMLS_CC); } } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } } @@ -22666,10 +23114,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - zval_ptr_dtor_nogc(free_op1.var); + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); + zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2), IS_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22681,18 +23129,18 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } ZVAL_DEREF(container); - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2), IS_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22704,18 +23152,18 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } ZVAL_DEREF(container); - zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2), IS_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22727,10 +23175,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - zval_ptr_dtor_nogc(free_op1.var); + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); + zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2), IS_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22747,25 +23195,25 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCO if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); } - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } ZVAL_DEREF(container); - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2), IS_VAR TSRMLS_CC); + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - zval_ptr_dtor_nogc(free_op2.var); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + zval_ptr_dtor_nogc(free_op2); + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; } else { if (IS_VAR == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - zval_ptr_dtor_nogc(free_op1.var); + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); + zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2), IS_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -22778,18 +23226,18 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_ zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } ZVAL_DEREF(container); - zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2), IS_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22803,8 +23251,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if ((IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { @@ -22814,15 +23262,37 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } - zval_ptr_dtor_nogc(free_op2.var); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22835,19 +23305,19 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAND zval *container; SAVE_OPLINE(); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_VAR, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22860,18 +23330,18 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN zval *container; SAVE_OPLINE(); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_VAR, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22885,8 +23355,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if ((IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { @@ -22895,15 +23365,37 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HAN zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } - zval_ptr_dtor_nogc(free_op2.var); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22919,8 +23411,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCO zval *property; SAVE_OPLINE(); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); @@ -22928,12 +23420,12 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_VAR_HANDLER(ZEND_OPCO if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_VAR, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } else { @@ -22948,18 +23440,18 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_ zval *container, *property; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_VAR, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -22972,15 +23464,15 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL zval *property_name; SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); + property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + zval_ptr_dtor_nogc(free_op2); + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; /* assign_obj has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -22994,7 +23486,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL zval *object_ptr; SAVE_OPLINE(); - object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); @@ -23002,27 +23494,27 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL ZVAL_DEREF(object_ptr); if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_free_op free_op2; - zval *property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else { zend_free_op free_op2, free_op_data1; zval rv; zval *value; - zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2); zval *variable_ptr; if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) && EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); FREE_OP(free_op_data1); } else { zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); variable_ptr = Z_INDIRECT(rv); @@ -23042,7 +23534,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL } } } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; /* assign_dim has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -23057,12 +23549,12 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_A zval *variable_ptr; SAVE_OPLINE(); - value = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + value = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2); + variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) { if (IS_VAR == IS_TMP_VAR) { - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } if (RETURN_VALUE_USED(opline)) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -23072,11 +23564,11 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_A if (RETURN_VALUE_USED(opline)) { ZVAL_COPY(EX_VAR(opline->result.var), value); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; } /* zend_assign_to_variable() always takes care of op2, never free it! */ - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -23090,7 +23582,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL zval *value_ptr; SAVE_OPLINE(); - value_ptr = _get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + value_ptr = _get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects"); @@ -23099,22 +23591,22 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL (value_ptr == &EG(uninitialized_zval) || (opline->extended_value == ZEND_RETURNS_FUNCTION && !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) { - if (!(free_op2.var != NULL)) { + if (!(free_op2 != NULL)) { PZVAL_LOCK(value_ptr); /* undo the effect of get_zval_ptr_ptr() */ } zend_error(E_STRICT, "Only variables should be assigned by reference"); if (UNEXPECTED(EG(exception) != NULL)) { - if (free_op2.var) {zval_ptr_dtor_nogc(free_op2.var);}; + if (free_op2) {zval_ptr_dtor_nogc(free_op2);}; HANDLE_EXCEPTION(); } return ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } else if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) { - if (!(free_op2.var != NULL)) { + if (!(free_op2 != NULL)) { PZVAL_LOCK(value_ptr); } } - variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects"); } @@ -23131,7 +23623,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL } if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) { - if (!(free_op2.var != NULL)) { + if (!(free_op2 != NULL)) { Z_DELREF_P(variable_ptr); } } @@ -23140,8 +23632,8 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL ZVAL_COPY(EX_VAR(opline->result.var), variable_ptr); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; - if (free_op2.var) {zval_ptr_dtor_nogc(free_op2.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; + if (free_op2) {zval_ptr_dtor_nogc(free_op2);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -23159,7 +23651,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE SAVE_OPLINE(); - function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { @@ -23169,19 +23661,19 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE zend_error_noreturn(E_ERROR, "Method name must be a string"); } - object = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + object = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { uint32_t nesting = 1; if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); - zval_ptr_dtor_nogc(free_op2.var); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); if (EG(exception) != NULL) { HANDLE_EXCEPTION(); @@ -23249,8 +23741,8 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE EX(call) = zend_vm_stack_push_call_frame(VM_FRAME_NESTED_FUNCTION, fbc, opline->extended_value, called_scope, obj, EX(call) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op2); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -23295,7 +23787,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND } else if (IS_VAR != IS_UNUSED) { zend_free_op free_op2; - function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_VAR != IS_CONST) { if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { if (UNEXPECTED(EG(exception) != NULL)) { @@ -23323,7 +23815,7 @@ static int ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND } } if (IS_VAR != IS_CONST) { - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } } else { if (UNEXPECTED(ce->constructor == NULL)) { @@ -23388,10 +23880,10 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG SAVE_OPLINE(); fast_equal_function(result, - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -23405,15 +23897,15 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD SAVE_OPLINE(); if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { - expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; } else { - expr_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + expr_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_TMP_VAR) { ZVAL_COPY_VALUE(&new_expr, expr_ptr); expr_ptr = &new_expr; @@ -23425,7 +23917,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD } else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_ISREF_P(expr_ptr)) { expr_ptr = Z_REFVAL_P(expr_ptr); if (Z_REFCOUNTED_P(expr_ptr)) Z_ADDREF_P(expr_ptr); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } else if (IS_VAR == IS_CV && Z_REFCOUNTED_P(expr_ptr)) { Z_ADDREF_P(expr_ptr); } @@ -23433,7 +23925,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD if (IS_VAR != IS_UNUSED) { zend_free_op free_op2; - zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); zend_string *str; zend_ulong hval; @@ -23476,7 +23968,7 @@ str_index: /* do nothing */ break; } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else { zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr); } @@ -23545,7 +24037,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE ZEND_VM_NEXT_OPCODE(); } - varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); ZVAL_UNDEF(&tmp); if (IS_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { @@ -23562,10 +24054,10 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE } else { ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_VAR != IS_CONST) { - zval_dtor(&tmp); + if (IS_VAR != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); HANDLE_EXCEPTION(); } if (UNEXPECTED(ce == NULL)) { @@ -23582,10 +24074,10 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_VAR != IS_CONST) { - zval_dtor(&tmp); + if (IS_VAR != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -23599,7 +24091,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE zend_ulong hval; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); } @@ -23607,7 +24099,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE ZVAL_DEREF(container); SEPARATE_ZVAL_NOREF(container); } - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_VAR != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht = Z_ARRVAL_P(container); @@ -23654,7 +24146,7 @@ num_index_dim: zend_error(E_WARNING, "Illegal offset type in unset"); break; } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else if (IS_VAR == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use object as array"); @@ -23663,14 +24155,14 @@ num_index_dim: //??? zval_copy_ctor(offset); //??? } Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_CONTINUE(); /* bailed out before */ } else { - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -23683,11 +24175,11 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); } - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); ZVAL_DEREF(container); if (IS_VAR == IS_UNUSED || Z_TYPE_P(container) == IS_OBJECT) { @@ -23697,8 +24189,8 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE zend_error(E_NOTICE, "Trying to unset property of non-object"); } } - zval_ptr_dtor_nogc(free_op2.var); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + zval_ptr_dtor_nogc(free_op2); + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -23725,8 +24217,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD ZEND_VM_NEXT_OPCODE(); } else { zend_free_op free_op1; - zval tmp, *varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zval tmp, *varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); + ZVAL_UNDEF(&tmp); if (IS_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { ZVAL_STR(&tmp, zval_get_string(varname)); varname = &tmp; @@ -23755,10 +24248,10 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_VAR != IS_CONST && varname == &tmp) { - zval_dtor(&tmp); + if (IS_VAR != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); if (opline->extended_value & ZEND_ISSET) { ZVAL_BOOL(EX_VAR(opline->result.var), @@ -23784,8 +24277,8 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_O zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_VAR != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht = Z_ARRVAL_P(container); @@ -23881,9 +24374,9 @@ num_index_prop: result = ((opline->extended_value & ZEND_ISSET) == 0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); ZVAL_BOOL(EX_VAR(opline->result.var), result); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -23897,8 +24390,8 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_ zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_VAR == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (EXPECTED(Z_OBJ_HT_P(container)->has_property)) { @@ -23914,9 +24407,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_VAR_HANDLER(ZEND_ result = ((opline->extended_value & ZEND_ISSET) == 0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); ZVAL_BOOL(EX_VAR(opline->result.var), result); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -23929,7 +24422,7 @@ static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL zend_bool result; SAVE_OPLINE(); - expr = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + expr = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); if (Z_TYPE_P(expr) == IS_OBJECT) { zend_class_entry *ce; @@ -23941,7 +24434,7 @@ static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC); if (UNEXPECTED(ce == NULL)) { ZVAL_FALSE(EX_VAR(opline->result.var)); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -23955,7 +24448,7 @@ static int ZEND_FASTCALL ZEND_INSTANCEOF_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDL result = 0; } ZVAL_BOOL(EX_VAR(opline->result.var), result); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -23989,7 +24482,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); ZVAL_COPY_VALUE(&generator->value, value); if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1); @@ -23998,7 +24491,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR zval_opt_copy_ctor(&generator->value); } } else { - zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); @@ -24016,10 +24509,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR } ZVAL_COPY(&generator->value, value_ptr); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; } } else { - zval *value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zval *value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); /* Consts, temporary variables and references need copying */ if (IS_VAR == IS_CONST) { @@ -24028,7 +24521,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR ZVAL_COPY_VALUE(&generator->value, value); } else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_ISREF_P(value)) { ZVAL_DUP(&generator->value, Z_REFVAL_P(value)); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } else { ZVAL_COPY_VALUE(&generator->value, value); if (IS_VAR == IS_CV) { @@ -24044,7 +24537,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR /* Set the new yielded key */ if (IS_VAR != IS_UNUSED) { zend_free_op free_op2; - zval *key = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *key = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); /* Consts, temporary variables and references need copying */ if (IS_VAR == IS_CONST) { @@ -24053,7 +24546,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR ZVAL_COPY_VALUE(&generator->key, key); } else if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && Z_ISREF_P(key)) { ZVAL_DUP(&generator->key, Z_REFVAL_P(key)); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else { ZVAL_COPY_VALUE(&generator->key, key); if (IS_VAR == IS_CV) { @@ -24099,10 +24592,10 @@ static int ZEND_FASTCALL ZEND_POW_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); pow_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); - zval_ptr_dtor_nogc(free_op2.var); + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); + zval_ptr_dtor_nogc(free_op1); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -24116,7 +24609,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (* { USE_OPLINE zend_free_op free_op1, free_op_data1; - zval *object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zval *object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); zval *property = NULL; zval *value; zval *zptr; @@ -24171,7 +24664,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (* zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -24198,7 +24691,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (* FREE_OP(free_op_data1); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; /* assign_obj has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -24213,7 +24706,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_UNUSED(int (* zval *value, *container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } @@ -24221,7 +24714,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_UNUSED(int (* ZVAL_DEREF(container); } if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) { + if (IS_VAR == IS_VAR && !(free_op1 != NULL)) { Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */ } return zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -24254,7 +24747,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_UNUSED(int (* } FREE_OP(free_op_data1); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); ZEND_VM_NEXT_OPCODE(); @@ -24269,7 +24762,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_UNUSED(int (*bina SAVE_OPLINE(); value = NULL; - var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); @@ -24290,7 +24783,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_UNUSED(int (*bina } } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -24448,7 +24941,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_UNUSED(int type, HashTable *target_symbol_table; SAVE_OPLINE(); - varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_CONST) { name = Z_STR_P(varname); @@ -24471,7 +24964,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_UNUSED(int type, if (IS_VAR != IS_CONST) { zend_string_release(name); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -24481,7 +24974,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_UNUSED(int type, ce = Z_CE_P(EX_VAR(opline->op2.var)); } retval = zend_std_get_static_property(ce, name, 0, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(varname)) : NULL) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } else { target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC); retval = zend_hash_find(target_symbol_table, name); @@ -24529,7 +25022,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_UNUSED(int type, zval_update_constant(retval, 1 TSRMLS_CC); } } else if ((opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_GLOBAL_LOCK) { - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } } @@ -24593,7 +25086,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_H zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); @@ -24601,10 +25094,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_H ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -24616,7 +25109,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_ zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); @@ -24624,10 +25117,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_ ZVAL_DEREF(container); zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -24644,25 +25137,25 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_UNUSED_HANDLER(ZEND_O if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); } - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; } else { if (IS_UNUSED == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -24675,7 +25168,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA zval *object_ptr; SAVE_OPLINE(); - object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); @@ -24723,7 +25216,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HA } } } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; /* assign_dim has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -24863,15 +25356,15 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OP SAVE_OPLINE(); if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { - expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; } else { - expr_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + expr_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_TMP_VAR) { ZVAL_COPY_VALUE(&new_expr, expr_ptr); expr_ptr = &new_expr; @@ -24883,7 +25376,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OP } else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_ISREF_P(expr_ptr)) { expr_ptr = Z_REFVAL_P(expr_ptr); if (Z_REFCOUNTED_P(expr_ptr)) Z_ADDREF_P(expr_ptr); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } else if (IS_VAR == IS_CV && Z_REFCOUNTED_P(expr_ptr)) { Z_ADDREF_P(expr_ptr); } @@ -25003,7 +25496,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAN ZEND_VM_NEXT_OPCODE(); } - varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); ZVAL_UNDEF(&tmp); if (IS_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { @@ -25020,10 +25513,10 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAN } else { ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_VAR != IS_CONST) { - zval_dtor(&tmp); + if (IS_VAR != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); HANDLE_EXCEPTION(); } if (UNEXPECTED(ce == NULL)) { @@ -25040,10 +25533,10 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAN zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_VAR != IS_CONST) { - zval_dtor(&tmp); + if (IS_VAR != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -25070,8 +25563,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OP ZEND_VM_NEXT_OPCODE(); } else { zend_free_op free_op1; - zval tmp, *varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zval tmp, *varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); + ZVAL_UNDEF(&tmp); if (IS_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { ZVAL_STR(&tmp, zval_get_string(varname)); varname = &tmp; @@ -25100,10 +25594,10 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OP value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_VAR != IS_CONST && varname == &tmp) { - zval_dtor(&tmp); + if (IS_VAR != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); if (opline->extended_value & ZEND_ISSET) { ZVAL_BOOL(EX_VAR(opline->result.var), @@ -25166,7 +25660,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); ZVAL_COPY_VALUE(&generator->value, value); if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1); @@ -25175,7 +25669,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER zval_opt_copy_ctor(&generator->value); } } else { - zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); @@ -25193,10 +25687,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER } ZVAL_COPY(&generator->value, value_ptr); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; } } else { - zval *value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zval *value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); /* Consts, temporary variables and references need copying */ if (IS_VAR == IS_CONST) { @@ -25205,7 +25699,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER ZVAL_COPY_VALUE(&generator->value, value); } else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_ISREF_P(value)) { ZVAL_DUP(&generator->value, Z_REFVAL_P(value)); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } else { ZVAL_COPY_VALUE(&generator->value, value); if (IS_VAR == IS_CV) { @@ -25281,9 +25775,9 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); fast_add_function(EX_VAR(opline->result.var), - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -25296,9 +25790,9 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); fast_sub_function(EX_VAR(opline->result.var), - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -25311,9 +25805,9 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); fast_mul_function(EX_VAR(opline->result.var), - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -25326,9 +25820,9 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); fast_div_function(EX_VAR(opline->result.var), - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -25341,9 +25835,9 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); fast_mod_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -25356,9 +25850,9 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); shift_left_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -25371,9 +25865,9 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); shift_right_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -25386,9 +25880,9 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); concat_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -25401,9 +25895,9 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); fast_is_identical_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -25417,9 +25911,9 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_ SAVE_OPLINE(); fast_is_not_identical_function(result, - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -25433,9 +25927,9 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ SAVE_OPLINE(); fast_equal_function(result, - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -25449,9 +25943,9 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); fast_not_equal_function(result, - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -25465,9 +25959,9 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE SAVE_OPLINE(); fast_is_smaller_function(result, - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -25481,9 +25975,9 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_VAR_CV_HANDLER(ZEND_OPCO SAVE_OPLINE(); fast_is_smaller_or_equal_function(result, - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -25496,9 +25990,9 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG SAVE_OPLINE(); bitwise_or_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -25511,9 +26005,9 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); bitwise_and_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -25526,9 +26020,9 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); bitwise_xor_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -25541,9 +26035,9 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ SAVE_OPLINE(); boolean_xor_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -25553,7 +26047,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina { USE_OPLINE zend_free_op free_op1, free_op_data1; - zval *object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zval *object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); zval *property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); zval *value; zval *zptr; @@ -25608,7 +26102,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -25635,7 +26129,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina FREE_OP(free_op_data1); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; /* assign_obj has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -25650,7 +26144,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CV(int (*bina zval *value, *container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } @@ -25658,7 +26152,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CV(int (*bina ZVAL_DEREF(container); } if (IS_VAR == IS_UNUSED || UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { - if (IS_VAR == IS_VAR && !(free_op1.var != NULL)) { + if (IS_VAR == IS_VAR && !(free_op1 != NULL)) { Z_ADDREF_P(container); /* undo the effect of get_obj_zval_ptr_ptr() */ } return zend_binary_assign_op_obj_helper_SPEC_VAR_CV(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); @@ -25691,7 +26185,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_VAR_CV(int (*bina } FREE_OP(free_op_data1); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); ZEND_VM_NEXT_OPCODE(); @@ -25706,7 +26200,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CV(int (*binary_o SAVE_OPLINE(); value = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use assign-op operators with overloaded objects nor string offsets"); @@ -25727,7 +26221,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_VAR_CV(int (*binary_o } } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -25885,7 +26379,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t in zval *zptr; SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); retval = EX_VAR(opline->result.var); @@ -25903,7 +26397,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t in if (RETURN_VALUE_USED(opline)) { ZVAL_NULL(retval); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -25931,7 +26425,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t in zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -25950,7 +26444,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_VAR_CV(incdec_t in } } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -25975,7 +26469,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t i zval *zptr; SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); retval = EX_VAR(opline->result.var); @@ -25991,7 +26485,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t i zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); ZVAL_NULL(retval); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -26017,7 +26511,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t i zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -26034,7 +26528,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_VAR_CV(incdec_t i } } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -26056,10 +26550,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -26071,7 +26565,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); @@ -26079,10 +26573,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -26094,7 +26588,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); @@ -26102,10 +26596,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND ZVAL_DEREF(container); zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -26117,10 +26611,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -26137,25 +26631,25 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCOD if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); } - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; } else { if (IS_CV == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } - container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -26168,7 +26662,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_H zval *container; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); @@ -26176,10 +26670,10 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_H ZVAL_DEREF(container); zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -26193,7 +26687,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); if ((IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || @@ -26204,14 +26698,36 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -26226,17 +26742,17 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -26250,17 +26766,17 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -26274,7 +26790,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); if ((IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || @@ -26284,14 +26800,36 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HAND zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -26308,7 +26846,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCOD SAVE_OPLINE(); property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_CONST || IS_VAR == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); @@ -26316,12 +26854,12 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_VAR_CV_HANDLER(ZEND_OPCOD if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } else { @@ -26336,18 +26874,18 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_H zval *container, *property; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_VAR, property, IS_CV, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); - if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_VAR == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -26360,7 +26898,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE zval *property_name; SAVE_OPLINE(); - object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + object = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); if (IS_VAR == IS_VAR && UNEXPECTED(object == NULL)) { @@ -26368,7 +26906,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE } zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, IS_VAR, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; /* assign_obj has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -26382,7 +26920,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE zval *object_ptr; SAVE_OPLINE(); - object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + object_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(object_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); @@ -26430,7 +26968,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE } } } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; /* assign_dim has two opcodes! */ CHECK_EXCEPTION(); ZEND_VM_INC_OPCODE(); @@ -26446,7 +26984,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); value = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) { if (IS_CV == IS_TMP_VAR) { @@ -26460,7 +26998,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_AR if (RETURN_VALUE_USED(opline)) { ZVAL_COPY(EX_VAR(opline->result.var), value); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; } /* zend_assign_to_variable() always takes care of op2, never free it! */ @@ -26501,7 +27039,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE } } - variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects"); } @@ -26527,7 +27065,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLE ZVAL_COPY(EX_VAR(opline->result.var), variable_ptr); } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -26555,7 +27093,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_ zend_error_noreturn(E_ERROR, "Method name must be a string"); } - object = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + object = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); if (IS_VAR != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { uint32_t nesting = 1; @@ -26567,7 +27105,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_ zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); if (EG(exception) != NULL) { HANDLE_EXCEPTION(); @@ -26635,7 +27173,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_ EX(call) = zend_vm_stack_push_call_frame(VM_FRAME_NESTED_FUNCTION, fbc, opline->extended_value, called_scope, obj, EX(call) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -26773,7 +27311,7 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); fast_equal_function(result, - _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); CHECK_EXCEPTION(); @@ -26789,15 +27327,15 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE SAVE_OPLINE(); if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && (opline->extended_value & ZEND_ARRAY_ELEMENT_REF)) { - expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + expr_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(expr_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets"); } ZVAL_MAKE_REF(expr_ptr); Z_ADDREF_P(expr_ptr); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; } else { - expr_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + expr_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_TMP_VAR) { ZVAL_COPY_VALUE(&new_expr, expr_ptr); expr_ptr = &new_expr; @@ -26809,7 +27347,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE } else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_ISREF_P(expr_ptr)) { expr_ptr = Z_REFVAL_P(expr_ptr); if (Z_REFCOUNTED_P(expr_ptr)) Z_ADDREF_P(expr_ptr); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } else if (IS_VAR == IS_CV && Z_REFCOUNTED_P(expr_ptr)) { Z_ADDREF_P(expr_ptr); } @@ -26908,7 +27446,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER zend_ulong hval; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); } @@ -26979,7 +27517,7 @@ num_index_dim: } else { } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -26992,7 +27530,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); } @@ -27007,7 +27545,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER } } - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -27022,7 +27560,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_VAR_CV_HANDLER(ZEND_OP zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); if (IS_VAR != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { @@ -27093,7 +27631,7 @@ num_index_prop: result = 0; if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) { - if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { + if (IS_CV == IS_CV || IS_CV == IS_VAR) { ZVAL_DEREF(offset); } if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */ @@ -27120,7 +27658,7 @@ num_index_prop: } ZVAL_BOOL(EX_VAR(opline->result.var), result); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -27134,7 +27672,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_CV_HANDLER(ZEND_O zval *offset; SAVE_OPLINE(); - container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + container = _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); if (IS_VAR == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { @@ -27152,7 +27690,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_VAR_CV_HANDLER(ZEND_O } ZVAL_BOOL(EX_VAR(opline->result.var), result); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -27186,7 +27724,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG zend_error(E_NOTICE, "Only variable references should be yielded by reference"); - value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); ZVAL_COPY_VALUE(&generator->value, value); if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1); @@ -27195,7 +27733,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG zval_opt_copy_ctor(&generator->value); } } else { - zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zval *value_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1); if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot yield string offsets by reference"); @@ -27213,10 +27751,10 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG } ZVAL_COPY(&generator->value, value_ptr); - if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}; + if (free_op1) {zval_ptr_dtor_nogc(free_op1);}; } } else { - zval *value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC); + zval *value = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1); /* Consts, temporary variables and references need copying */ if (IS_VAR == IS_CONST) { @@ -27225,7 +27763,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG ZVAL_COPY_VALUE(&generator->value, value); } else if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && Z_ISREF_P(value)) { ZVAL_DUP(&generator->value, Z_REFVAL_P(value)); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); } else { ZVAL_COPY_VALUE(&generator->value, value); if (IS_VAR == IS_CV) { @@ -27296,9 +27834,9 @@ static int ZEND_FASTCALL ZEND_POW_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); pow_function(EX_VAR(opline->result.var), - _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC), + _get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op1.var); + zval_ptr_dtor_nogc(free_op1); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -27319,7 +27857,7 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARG zend_object_clone_obj_t clone_call; SAVE_OPLINE(); - obj = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + obj = _get_obj_zval_ptr_unused(execute_data); if (IS_UNUSED == IS_CONST || (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT))) { @@ -27359,7 +27897,7 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARG if (EXPECTED(EG(exception) == NULL)) { ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj TSRMLS_CC)); if (!RETURN_VALUE_USED(opline) || UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor(EX_VAR(opline->result.var)); + OBJ_RELEASE(Z_OBJ_P(EX_VAR(opline->result.var))); } } @@ -27393,7 +27931,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int { USE_OPLINE zend_free_op free_op_data1; - zval *object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + zval *object = _get_obj_zval_ptr_unused(execute_data); zval *property = opline->op2.zv; zval *value; zval *zptr; @@ -27448,7 +27986,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -27489,7 +28027,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CONST(int zval *value, *container; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } @@ -27724,7 +28262,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(incde zval *zptr; SAVE_OPLINE(); - object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + object = _get_obj_zval_ptr_unused(execute_data); property = opline->op2.zv; retval = EX_VAR(opline->result.var); @@ -27770,7 +28308,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CONST(incde zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -27814,7 +28352,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CONST(incd zval *zptr; SAVE_OPLINE(); - object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + object = _get_obj_zval_ptr_unused(execute_data); property = opline->op2.zv; retval = EX_VAR(opline->result.var); @@ -27856,7 +28394,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CONST(incd zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -27897,7 +28435,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE zval *offset; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); offset = opline->op2.zv; if ((IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || @@ -27908,11 +28446,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } @@ -27930,14 +28490,14 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE SAVE_OPLINE(); property = opline->op2.zv; - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -27954,14 +28514,14 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCOD SAVE_OPLINE(); property = opline->op2.zv; - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); - if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -27978,7 +28538,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCOD zval *offset; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); offset = opline->op2.zv; if ((IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || @@ -27988,11 +28548,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCOD zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } @@ -28012,7 +28594,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST_HANDLER(ZEND SAVE_OPLINE(); property = opline->op2.zv; - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); @@ -28020,9 +28602,9 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CONST_HANDLER(ZEND if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -28040,15 +28622,15 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CONST_HANDLER(ZEND_OP zval *container, *property; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); property = opline->op2.zv; if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); - if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -28064,7 +28646,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_ zval *property_name; SAVE_OPLINE(); - object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + object = _get_obj_zval_ptr_unused(execute_data); property_name = opline->op2.zv; if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { @@ -28139,7 +28721,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_O zend_error_noreturn(E_ERROR, "Method name must be a string"); } - object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + object = _get_obj_zval_ptr_unused(execute_data); if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { uint32_t nesting = 1; @@ -28361,7 +28943,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_H zend_ulong hval; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); } @@ -28445,7 +29027,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_H zval *offset; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); } @@ -28475,7 +29057,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNUSED_CONST_HANDLER(Z zval *offset; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); offset = opline->op2.zv; if (IS_UNUSED != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { @@ -28546,7 +29128,7 @@ num_index_prop: result = 0; if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) { - if (IS_UNUSED == IS_CV || IS_UNUSED == IS_VAR) { + if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { ZVAL_DEREF(offset); } if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */ @@ -28587,7 +29169,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CONST_HANDLER( zval *offset; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); offset = opline->op2.zv; if (IS_UNUSED == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { @@ -28750,8 +29332,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (* { USE_OPLINE zend_free_op free_op2, free_op_data1; - zval *object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); - zval *property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *object = _get_obj_zval_ptr_unused(execute_data); + zval *property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); zval *value; zval *zptr; @@ -28767,7 +29349,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (* if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to assign property of non-object"); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); FREE_OP(free_op_data1); if (RETURN_VALUE_USED(opline)) { @@ -28805,7 +29387,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (* zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -28829,7 +29411,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (* } } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); FREE_OP(free_op_data1); } @@ -28847,7 +29429,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_TMP(int (* zval *value, *container; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } @@ -28860,7 +29442,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_TMP(int (* } return zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } else { - zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); zend_fetch_dimension_address_RW(&rv, container, dim, IS_TMP_VAR TSRMLS_CC); value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); @@ -28887,7 +29469,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_TMP(int (* } } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); FREE_OP(free_op_data1); CHECK_EXCEPTION(); @@ -28903,7 +29485,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_TMP(int (*bina zval *value; SAVE_OPLINE(); - value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); var_ptr = NULL; if (IS_UNUSED == IS_VAR && UNEXPECTED(var_ptr == NULL)) { @@ -28925,7 +29507,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_TMP(int (*bina } } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -29084,8 +29666,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_TMP(incdec_ zval *zptr; SAVE_OPLINE(); - object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); - property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + object = _get_obj_zval_ptr_unused(execute_data); + property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); retval = EX_VAR(opline->result.var); if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { @@ -29098,7 +29680,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_TMP(incdec_ if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); if (RETURN_VALUE_USED(opline)) { ZVAL_NULL(retval); } @@ -29130,7 +29712,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_TMP(incdec_ zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -29149,7 +29731,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_TMP(incdec_ } } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -29175,8 +29757,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_TMP(incdec zval *zptr; SAVE_OPLINE(); - object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); - property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + object = _get_obj_zval_ptr_unused(execute_data); + property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); retval = EX_VAR(opline->result.var); if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { @@ -29189,7 +29771,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_TMP(incdec if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); ZVAL_NULL(retval); CHECK_EXCEPTION(); @@ -29217,7 +29799,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_TMP(incdec zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -29234,7 +29816,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_TMP(incdec } } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -29259,8 +29841,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_H zval *offset; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); - offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); + offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if ((IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { @@ -29270,14 +29852,36 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_H zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_TMP_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -29291,16 +29895,16 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_H zval *container; SAVE_OPLINE(); - property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -29316,15 +29920,15 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_ zval *container; SAVE_OPLINE(); - property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); + container = _get_obj_zval_ptr_unused(execute_data); if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -29341,8 +29945,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_ zval *offset; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); - offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); + offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if ((IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { @@ -29351,14 +29955,36 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_ zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_TMP_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -29375,8 +30001,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP_HANDLER(ZEND_O zval *property; SAVE_OPLINE(); - property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); + container = _get_obj_zval_ptr_unused(execute_data); if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); @@ -29384,9 +30010,9 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_TMP_HANDLER(ZEND_O if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -29404,15 +30030,15 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCO zval *container, *property; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); - property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); + property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -29428,14 +30054,14 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HA zval *property_name; SAVE_OPLINE(); - object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); - property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + object = _get_obj_zval_ptr_unused(execute_data); + property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, IS_UNUSED, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); /* assign_obj has two opcodes! */ CHECK_EXCEPTION(); @@ -29453,7 +30079,7 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDL int use_copy = 0; SAVE_OPLINE(); - var = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + var = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if (IS_UNUSED == IS_UNUSED) { /* Initialize for erealloc in add_string_to_string */ @@ -29473,7 +30099,7 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDL add_string_to_string(str, str, var); if (use_copy) { - zval_dtor(var); + zend_string_release(Z_STR_P(var)); } /* original comment, possibly problematic: * FREE_OP is missing intentionally here - we're always working on the same temporary variable @@ -29481,7 +30107,7 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDL * which aren't affected by FREE_OP(Ts, )'s anyway, unless they're * string offsets or overloaded objects */ - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -29499,7 +30125,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP_HANDLER(ZEND_OPC SAVE_OPLINE(); - function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if (IS_TMP_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { @@ -29509,18 +30135,18 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP_HANDLER(ZEND_OPC zend_error_noreturn(E_ERROR, "Method name must be a string"); } - object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + object = _get_obj_zval_ptr_unused(execute_data); if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { uint32_t nesting = 1; if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); if (EG(exception) != NULL) { HANDLE_EXCEPTION(); @@ -29588,7 +30214,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP_HANDLER(ZEND_OPC EX(call) = zend_vm_stack_push_call_frame(VM_FRAME_NESTED_FUNCTION, fbc, opline->extended_value, called_scope, obj, EX(call) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -29634,7 +30260,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HAN zend_ulong hval; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); } @@ -29642,7 +30268,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HAN ZVAL_DEREF(container); SEPARATE_ZVAL_NOREF(container); } - offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if (IS_UNUSED != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht = Z_ARRVAL_P(container); @@ -29689,7 +30315,7 @@ num_index_dim: zend_error(E_WARNING, "Illegal offset type in unset"); break; } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else if (IS_UNUSED == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use object as array"); @@ -29698,12 +30324,12 @@ num_index_dim: //??? zval_copy_ctor(offset); //??? } Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_CONTINUE(); /* bailed out before */ } else { - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } CHECK_EXCEPTION(); @@ -29718,11 +30344,11 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HAN zval *offset; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); } - offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); ZVAL_DEREF(container); if (IS_UNUSED == IS_UNUSED || Z_TYPE_P(container) == IS_OBJECT) { @@ -29732,7 +30358,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HAN zend_error(E_NOTICE, "Trying to unset property of non-object"); } } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -29748,8 +30374,8 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNUSED_TMP_HANDLER(ZEN zval *offset; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); - offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); + offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if (IS_UNUSED != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht = Z_ARRVAL_P(container); @@ -29819,7 +30445,7 @@ num_index_prop: result = 0; if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) { - if (IS_UNUSED == IS_CV || IS_UNUSED == IS_VAR) { + if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { ZVAL_DEREF(offset); } if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */ @@ -29845,7 +30471,7 @@ num_index_prop: result = ((opline->extended_value & ZEND_ISSET) == 0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); ZVAL_BOOL(EX_VAR(opline->result.var), result); CHECK_EXCEPTION(); @@ -29861,8 +30487,8 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMP_HANDLER(ZE zval *offset; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); - offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); + offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if (IS_UNUSED == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (EXPECTED(Z_OBJ_HT_P(container)->has_property)) { @@ -29878,7 +30504,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_TMP_HANDLER(ZE result = ((opline->extended_value & ZEND_ISSET) == 0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); ZVAL_BOOL(EX_VAR(opline->result.var), result); CHECK_EXCEPTION(); @@ -29968,7 +30594,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER /* Set the new yielded key */ if (IS_TMP_VAR != IS_UNUSED) { zend_free_op free_op2; - zval *key = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *key = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); /* Consts, temporary variables and references need copying */ if (IS_TMP_VAR == IS_CONST) { @@ -30025,8 +30651,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (* { USE_OPLINE zend_free_op free_op2, free_op_data1; - zval *object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); - zval *property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *object = _get_obj_zval_ptr_unused(execute_data); + zval *property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); zval *value; zval *zptr; @@ -30042,7 +30668,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (* if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to assign property of non-object"); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); FREE_OP(free_op_data1); if (RETURN_VALUE_USED(opline)) { @@ -30080,7 +30706,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (* zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -30104,7 +30730,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (* } } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); FREE_OP(free_op_data1); } @@ -30122,7 +30748,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_VAR(int (* zval *value, *container; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } @@ -30135,7 +30761,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_VAR(int (* } return zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } else { - zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2); zend_fetch_dimension_address_RW(&rv, container, dim, IS_VAR TSRMLS_CC); value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); @@ -30162,7 +30788,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_VAR(int (* } } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); FREE_OP(free_op_data1); CHECK_EXCEPTION(); @@ -30178,7 +30804,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_VAR(int (*bina zval *value; SAVE_OPLINE(); - value = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + value = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2); var_ptr = NULL; if (IS_UNUSED == IS_VAR && UNEXPECTED(var_ptr == NULL)) { @@ -30200,7 +30826,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_UNUSED_VAR(int (*bina } } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -30359,8 +30985,8 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_VAR(incdec_ zval *zptr; SAVE_OPLINE(); - object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + object = _get_obj_zval_ptr_unused(execute_data); + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); retval = EX_VAR(opline->result.var); if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { @@ -30373,7 +30999,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_VAR(incdec_ if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); if (RETURN_VALUE_USED(opline)) { ZVAL_NULL(retval); } @@ -30405,7 +31031,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_VAR(incdec_ zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -30424,7 +31050,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_VAR(incdec_ } } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -30450,8 +31076,8 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_VAR(incdec zval *zptr; SAVE_OPLINE(); - object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + object = _get_obj_zval_ptr_unused(execute_data); + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); retval = EX_VAR(opline->result.var); if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { @@ -30464,7 +31090,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_VAR(incdec if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); ZVAL_NULL(retval); CHECK_EXCEPTION(); @@ -30492,7 +31118,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_VAR(incdec zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -30509,7 +31135,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_VAR(incdec } } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -30534,8 +31160,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_H zval *offset; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if ((IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { @@ -30545,14 +31171,36 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_H zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -30566,16 +31214,16 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_H zval *container; SAVE_OPLINE(); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_VAR, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -30591,15 +31239,15 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_ zval *container; SAVE_OPLINE(); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + container = _get_obj_zval_ptr_unused(execute_data); if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_VAR, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -30616,8 +31264,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_ zval *offset; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if ((IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { @@ -30626,14 +31274,36 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_ zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -30650,8 +31320,8 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_VAR_HANDLER(ZEND_O zval *property; SAVE_OPLINE(); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); + container = _get_obj_zval_ptr_unused(execute_data); if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); @@ -30659,9 +31329,9 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_VAR_HANDLER(ZEND_O if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_VAR, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -30679,15 +31349,15 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCO zval *container, *property; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_VAR, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -30703,14 +31373,14 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HA zval *property_name; SAVE_OPLINE(); - object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); - property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + object = _get_obj_zval_ptr_unused(execute_data); + property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, IS_UNUSED, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); /* assign_obj has two opcodes! */ CHECK_EXCEPTION(); @@ -30728,7 +31398,7 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDL int use_copy = 0; SAVE_OPLINE(); - var = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + var = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_UNUSED == IS_UNUSED) { /* Initialize for erealloc in add_string_to_string */ @@ -30748,7 +31418,7 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDL add_string_to_string(str, str, var); if (use_copy) { - zval_dtor(var); + zend_string_release(Z_STR_P(var)); } /* original comment, possibly problematic: * FREE_OP is missing intentionally here - we're always working on the same temporary variable @@ -30756,7 +31426,7 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDL * which aren't affected by FREE_OP(Ts, )'s anyway, unless they're * string offsets or overloaded objects */ - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -30774,7 +31444,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_VAR_HANDLER(ZEND_OPC SAVE_OPLINE(); - function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { @@ -30784,18 +31454,18 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_VAR_HANDLER(ZEND_OPC zend_error_noreturn(E_ERROR, "Method name must be a string"); } - object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + object = _get_obj_zval_ptr_unused(execute_data); if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { uint32_t nesting = 1; if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); if (EG(exception) != NULL) { HANDLE_EXCEPTION(); @@ -30863,7 +31533,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_VAR_HANDLER(ZEND_OPC EX(call) = zend_vm_stack_push_call_frame(VM_FRAME_NESTED_FUNCTION, fbc, opline->extended_value, called_scope, obj, EX(call) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -30909,7 +31579,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HAN zend_ulong hval; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); } @@ -30917,7 +31587,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HAN ZVAL_DEREF(container); SEPARATE_ZVAL_NOREF(container); } - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_UNUSED != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht = Z_ARRVAL_P(container); @@ -30964,7 +31634,7 @@ num_index_dim: zend_error(E_WARNING, "Illegal offset type in unset"); break; } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else if (IS_UNUSED == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use object as array"); @@ -30973,12 +31643,12 @@ num_index_dim: //??? zval_copy_ctor(offset); //??? } Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_CONTINUE(); /* bailed out before */ } else { - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } CHECK_EXCEPTION(); @@ -30993,11 +31663,11 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HAN zval *offset; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); } - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); ZVAL_DEREF(container); if (IS_UNUSED == IS_UNUSED || Z_TYPE_P(container) == IS_OBJECT) { @@ -31007,7 +31677,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HAN zend_error(E_NOTICE, "Trying to unset property of non-object"); } } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -31023,8 +31693,8 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNUSED_VAR_HANDLER(ZEN zval *offset; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_UNUSED != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht = Z_ARRVAL_P(container); @@ -31094,7 +31764,7 @@ num_index_prop: result = 0; if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) { - if (IS_UNUSED == IS_CV || IS_UNUSED == IS_VAR) { + if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { ZVAL_DEREF(offset); } if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */ @@ -31120,7 +31790,7 @@ num_index_prop: result = ((opline->extended_value & ZEND_ISSET) == 0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); ZVAL_BOOL(EX_VAR(opline->result.var), result); CHECK_EXCEPTION(); @@ -31136,8 +31806,8 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_VAR_HANDLER(ZE zval *offset; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_UNUSED == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (EXPECTED(Z_OBJ_HT_P(container)->has_property)) { @@ -31153,7 +31823,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_VAR_HANDLER(ZE result = ((opline->extended_value & ZEND_ISSET) == 0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); ZVAL_BOOL(EX_VAR(opline->result.var), result); CHECK_EXCEPTION(); @@ -31243,7 +31913,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER /* Set the new yielded key */ if (IS_VAR != IS_UNUSED) { zend_free_op free_op2; - zval *key = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *key = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); /* Consts, temporary variables and references need copying */ if (IS_VAR == IS_CONST) { @@ -31252,7 +31922,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER ZVAL_COPY_VALUE(&generator->key, key); } else if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && Z_ISREF_P(key)) { ZVAL_DUP(&generator->key, Z_REFVAL_P(key)); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else { ZVAL_COPY_VALUE(&generator->key, key); if (IS_VAR == IS_CV) { @@ -31300,7 +31970,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int { USE_OPLINE zend_free_op free_op_data1; - zval *object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + zval *object = _get_obj_zval_ptr_unused(execute_data); zval *property = NULL; zval *value; zval *zptr; @@ -31355,7 +32025,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -31396,7 +32066,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_UNUSED(int zval *value, *container; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } @@ -31792,7 +32462,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b { USE_OPLINE zend_free_op free_op_data1; - zval *object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + zval *object = _get_obj_zval_ptr_unused(execute_data); zval *property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); zval *value; zval *zptr; @@ -31847,7 +32517,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -31888,7 +32558,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_UNUSED_CV(int (*b zval *value, *container; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } @@ -32123,7 +32793,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CV(incdec_t zval *zptr; SAVE_OPLINE(); - object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + object = _get_obj_zval_ptr_unused(execute_data); property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); retval = EX_VAR(opline->result.var); @@ -32169,7 +32839,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_UNUSED_CV(incdec_t zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -32213,7 +32883,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CV(incdec_ zval *zptr; SAVE_OPLINE(); - object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + object = _get_obj_zval_ptr_unused(execute_data); property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); retval = EX_VAR(opline->result.var); @@ -32255,7 +32925,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_UNUSED_CV(incdec_ zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -32296,7 +32966,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HA zval *offset; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); if ((IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || @@ -32307,11 +32977,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HA zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } @@ -32329,14 +33021,14 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HA SAVE_OPLINE(); property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -32353,14 +33045,14 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_H SAVE_OPLINE(); property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); - if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -32377,7 +33069,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_H zval *offset; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); if ((IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || @@ -32387,11 +33079,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_H zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } @@ -32411,7 +33125,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV_HANDLER(ZEND_OP SAVE_OPLINE(); property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); if (IS_UNUSED == IS_CONST || IS_UNUSED == IS_TMP_VAR) { zend_error_noreturn(E_ERROR, "Cannot use temporary expression in write context"); @@ -32419,9 +33133,9 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_UNUSED_CV_HANDLER(ZEND_OP if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -32439,15 +33153,15 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_UNUSED_CV_HANDLER(ZEND_OPCOD zval *container, *property; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); property = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_UNUSED, property, IS_CV, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); - if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_UNUSED == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -32463,7 +33177,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAN zval *property_name; SAVE_OPLINE(); - object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + object = _get_obj_zval_ptr_unused(execute_data); property_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); if (IS_UNUSED == IS_VAR && UNEXPECTED(object == NULL)) { @@ -32508,7 +33222,7 @@ static int ZEND_FASTCALL ZEND_ADD_VAR_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLE add_string_to_string(str, str, var); if (use_copy) { - zval_dtor(var); + zend_string_release(Z_STR_P(var)); } /* original comment, possibly problematic: * FREE_OP is missing intentionally here - we're always working on the same temporary variable @@ -32543,7 +33257,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCO zend_error_noreturn(E_ERROR, "Method name must be a string"); } - object = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + object = _get_obj_zval_ptr_unused(execute_data); if (IS_UNUSED != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { uint32_t nesting = 1; @@ -32667,7 +33381,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAND zend_ulong hval; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); } @@ -32751,7 +33465,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAND zval *offset; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); if (IS_UNUSED == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); } @@ -32781,7 +33495,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_UNUSED_CV_HANDLER(ZEND zval *offset; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); if (IS_UNUSED != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { @@ -32852,7 +33566,7 @@ num_index_prop: result = 0; if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) { - if (IS_UNUSED == IS_CV || IS_UNUSED == IS_VAR) { + if (IS_CV == IS_CV || IS_CV == IS_VAR) { ZVAL_DEREF(offset); } if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */ @@ -32893,7 +33607,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_UNUSED_CV_HANDLER(ZEN zval *offset; SAVE_OPLINE(); - container = _get_obj_zval_ptr_unused(execute_data TSRMLS_CC); + container = _get_obj_zval_ptr_unused(execute_data); offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC); if (IS_UNUSED == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { @@ -33573,11 +34287,8 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL zval *varptr, *arg; SAVE_OPLINE(); - if (opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) { /* Had function_ptr at compile_time */ - if (!(opline->extended_value & ZEND_ARG_SEND_BY_REF)) { - return ZEND_SEND_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); - } - } else { + + if (!(opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND)) { if (!ARG_SHOULD_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) { return ZEND_SEND_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } @@ -33592,20 +34303,18 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL if (IS_CV == IS_CV) { Z_ADDREF_P(varptr); } - arg = ZEND_CALL_ARG(EX(call), opline->op2.num); - EX(call)->num_args = opline->op2.num; - ZVAL_COPY_VALUE(arg, varptr); } else { if ((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ? !(opline->extended_value & ZEND_ARG_SEND_SILENT) : !ARG_MAY_BE_SENT_BY_REF(EX(call)->func, opline->op2.num)) { zend_error(E_STRICT, "Only variables should be passed by reference"); } - arg = ZEND_CALL_ARG(EX(call), opline->op2.num); - EX(call)->num_args = opline->op2.num; - ZVAL_COPY(arg, varptr); - } + + arg = ZEND_CALL_ARG(EX(call), opline->op2.num); + EX(call)->num_args = opline->op2.num; + ZVAL_COPY_VALUE(arg, varptr); + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -33635,12 +34344,11 @@ static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS ZVAL_COPY_VALUE(arg, varptr); } else if (IS_CV == IS_VAR && UNEXPECTED(Z_TYPE_P(EX_VAR(opline->op1.var)) != IS_INDIRECT)) { - ZVAL_COPY_VALUE(arg, varptr); - ZVAL_MAKE_REF(arg); + ZVAL_NEW_REF(arg, varptr); } else { - ZVAL_MAKE_REF(varptr); - Z_ADDREF_P(varptr); - ZVAL_REF(arg, Z_REF_P(varptr)); + ZVAL_NEW_REF(arg, varptr); + Z_ADDREF_P(arg); + ZVAL_REF(varptr, Z_REF_P(arg)); } ZEND_VM_NEXT_OPCODE(); @@ -33811,7 +34519,7 @@ static int ZEND_FASTCALL ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) if (EXPECTED(EG(exception) == NULL)) { ZVAL_OBJ(EX_VAR(opline->result.var), clone_call(obj TSRMLS_CC)); if (!RETURN_VALUE_USED(opline) || UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor(EX_VAR(opline->result.var)); + OBJ_RELEASE(Z_OBJ_P(EX_VAR(opline->result.var))); } } @@ -33999,7 +34707,7 @@ static int ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL } } if (Z_TYPE(tmp_inc_filename) != IS_UNDEF) { - zval_ptr_dtor(&tmp_inc_filename); + zend_string_release(Z_STR(tmp_inc_filename)); } if (UNEXPECTED(EG(exception) != NULL)) { @@ -34767,7 +35475,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -35089,7 +35797,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CONST(incdec_t zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -35175,7 +35883,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CONST(incdec_t zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -35385,7 +36093,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -35408,7 +36116,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA ZVAL_DEREF(container); zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -35449,7 +36157,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPC } ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -35482,7 +36190,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE ZVAL_DEREF(container); zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, opline->op2.zv, IS_CONST TSRMLS_CC); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -35510,11 +36218,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } @@ -35537,9 +36267,9 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -35561,9 +36291,9 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -35590,11 +36320,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HA zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CONST == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } @@ -35622,9 +36374,9 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CONST_HANDLER(ZEND_OPC if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -35648,9 +36400,9 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CONST_HANDLER(ZEND_OPCODE if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CONST, ((IS_CONST == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -36095,8 +36847,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL } else { ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_CV != IS_CONST) { - zval_dtor(&tmp); + if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } HANDLE_EXCEPTION(); @@ -36115,8 +36867,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_CV != IS_CONST) { - zval_dtor(&tmp); + if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } CHECK_EXCEPTION(); @@ -36260,6 +37012,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCO zval tmp, *varname = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); + ZVAL_UNDEF(&tmp); if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { ZVAL_STR(&tmp, zval_get_string(varname)); varname = &tmp; @@ -36288,8 +37041,8 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCO value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_CV != IS_CONST && varname == &tmp) { - zval_dtor(&tmp); + if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } if (opline->extended_value & ZEND_ISSET) { @@ -36387,7 +37140,7 @@ num_index_prop: result = 0; if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) { - if (IS_CV == IS_CV || IS_CV == IS_VAR) { + if (IS_CONST == IS_CV || IS_CONST == IS_VAR) { ZVAL_DEREF(offset); } if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */ @@ -36648,23 +37401,39 @@ static int ZEND_FASTCALL ZEND_BIND_GLOBAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN zval *varname; zval *value; zval *variable_ptr; - Bucket *p; uint32_t idx; SAVE_OPLINE(); varname = opline->op2.zv; - idx = (uint32_t)(uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(varname)); - /* index 0 can't be cached (NULL is a mark of uninitialized cache slot) */ - p = EG(symbol_table).ht.arData + idx; - if (EXPECTED(idx > 0) && - EXPECTED(idx < EG(symbol_table).ht.nNumUsed) && - EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && - (EXPECTED(p->key == Z_STR_P(varname)) || - (EXPECTED(p->h == Z_STR_P(varname)->h) && - EXPECTED(p->key != NULL) && - EXPECTED(p->key->len == Z_STRLEN_P(varname)) && - EXPECTED(memcmp(p->key->val, Z_STRVAL_P(varname), Z_STRLEN_P(varname)) == 0)))) { - value = &EG(symbol_table).ht.arData[idx].val; + + /* We store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ + idx = (uint32_t)(uintptr_t)CACHED_PTR(Z_CACHE_SLOT_P(varname)) - 1; + if (EXPECTED(idx < EG(symbol_table).ht.nNumUsed)) { + Bucket *p = EG(symbol_table).ht.arData + idx; + + if (EXPECTED(Z_TYPE(p->val) != IS_UNDEF) && + (EXPECTED(p->key == Z_STR_P(varname)) || + (EXPECTED(p->h == Z_STR_P(varname)->h) && + EXPECTED(p->key != NULL) && + EXPECTED(p->key->len == Z_STRLEN_P(varname)) && + EXPECTED(memcmp(p->key->val, Z_STRVAL_P(varname), Z_STRLEN_P(varname)) == 0)))) { + + value = &EG(symbol_table).ht.arData[idx].val; + goto check_indirect; + } + } + + value = zend_hash_find(&EG(symbol_table).ht, Z_STR_P(varname)); + if (UNEXPECTED(value == NULL)) { + value = zend_hash_add_new(&EG(symbol_table).ht, Z_STR_P(varname), &EG(uninitialized_zval)); + idx = ((char*)value - (char*)EG(symbol_table).ht.arData) / sizeof(Bucket); + /* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ + CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)(idx + 1)); + } else { + idx = ((char*)value - (char*)EG(symbol_table).ht.arData) / sizeof(Bucket); + /* Store "hash slot index" + 1 (NULL is a mark of uninitialized cache slot) */ + CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)(idx + 1)); +check_indirect: /* GLOBAL variable may be an INDIRECT pointer to CV */ if (UNEXPECTED(Z_TYPE_P(value) == IS_INDIRECT)) { value = Z_INDIRECT_P(value); @@ -36672,23 +37441,6 @@ static int ZEND_FASTCALL ZEND_BIND_GLOBAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAN ZVAL_NULL(value); } } - } else { - value = zend_hash_find(&EG(symbol_table).ht, Z_STR_P(varname)); - if (UNEXPECTED(value == NULL)) { - value = zend_hash_add_new(&EG(symbol_table).ht, Z_STR_P(varname), &EG(uninitialized_zval)); - idx = ((char*)value - (char*)EG(symbol_table).ht.arData) / sizeof(Bucket); - CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)idx); - } else { - idx = ((char*)value - (char*)EG(symbol_table).ht.arData) / sizeof(Bucket); - CACHE_PTR(Z_CACHE_SLOT_P(varname), (void*)(uintptr_t)idx); - /* GLOBAL variable may be an INDIRECT pointer to CV */ - if (UNEXPECTED(Z_TYPE_P(value) == IS_INDIRECT)) { - value = Z_INDIRECT_P(value); - if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) { - ZVAL_NULL(value); - } - } - } } variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); @@ -36706,9 +37458,9 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); fast_add_function(EX_VAR(opline->result.var), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -36721,9 +37473,9 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); fast_sub_function(EX_VAR(opline->result.var), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -36736,9 +37488,9 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); fast_mul_function(EX_VAR(opline->result.var), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -36751,9 +37503,9 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); fast_div_function(EX_VAR(opline->result.var), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -36766,9 +37518,9 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); fast_mod_function(EX_VAR(opline->result.var), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -36781,9 +37533,9 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); shift_left_function(EX_VAR(opline->result.var), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -36796,9 +37548,9 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); shift_right_function(EX_VAR(opline->result.var), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -36811,9 +37563,9 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); concat_function(EX_VAR(opline->result.var), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -36826,9 +37578,9 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); fast_is_identical_function(EX_VAR(opline->result.var), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -36842,9 +37594,9 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_ SAVE_OPLINE(); fast_is_not_identical_function(result, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -36858,9 +37610,9 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ SAVE_OPLINE(); fast_equal_function(result, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -36874,9 +37626,9 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); fast_not_equal_function(result, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -36890,9 +37642,9 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE SAVE_OPLINE(); fast_is_smaller_function(result, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -36906,9 +37658,9 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_TMP_HANDLER(ZEND_OPCO SAVE_OPLINE(); fast_is_smaller_or_equal_function(result, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -36921,9 +37673,9 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG SAVE_OPLINE(); bitwise_or_function(EX_VAR(opline->result.var), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -36936,9 +37688,9 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); bitwise_and_function(EX_VAR(opline->result.var), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -36951,9 +37703,9 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); bitwise_xor_function(EX_VAR(opline->result.var), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -36966,9 +37718,9 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ SAVE_OPLINE(); boolean_xor_function(EX_VAR(opline->result.var), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -36978,7 +37730,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina USE_OPLINE zend_free_op free_op2, free_op_data1; zval *object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); - zval *property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); zval *value; zval *zptr; @@ -36994,7 +37746,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to assign property of non-object"); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); FREE_OP(free_op_data1); if (RETURN_VALUE_USED(opline)) { @@ -37032,7 +37784,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -37056,7 +37808,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina } } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); FREE_OP(free_op_data1); } @@ -37087,7 +37839,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_TMP(int (*bina } return zend_binary_assign_op_obj_helper_SPEC_CV_TMP(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } else { - zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); zend_fetch_dimension_address_RW(&rv, container, dim, IS_TMP_VAR TSRMLS_CC); value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); @@ -37114,7 +37866,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_TMP(int (*bina } } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); FREE_OP(free_op_data1); CHECK_EXCEPTION(); @@ -37130,7 +37882,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_TMP(int (*binary_o zval *value; SAVE_OPLINE(); - value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); var_ptr = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) { @@ -37152,7 +37904,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_TMP(int (*binary_o } } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -37312,7 +38064,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_TMP(incdec_t in SAVE_OPLINE(); object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); - property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); retval = EX_VAR(opline->result.var); if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { @@ -37325,7 +38077,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_TMP(incdec_t in if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); if (RETURN_VALUE_USED(opline)) { ZVAL_NULL(retval); } @@ -37357,7 +38109,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_TMP(incdec_t in zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -37376,7 +38128,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_TMP(incdec_t in } } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -37403,7 +38155,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_TMP(incdec_t i SAVE_OPLINE(); object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); - property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); retval = EX_VAR(opline->result.var); if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { @@ -37416,7 +38168,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_TMP(incdec_t i if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); ZVAL_NULL(retval); CHECK_EXCEPTION(); @@ -37444,7 +38196,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_TMP(incdec_t i zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -37461,7 +38213,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_TMP(incdec_t i } } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -37485,8 +38237,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2), IS_TMP_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -37505,9 +38257,9 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } ZVAL_DEREF(container); - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2), IS_TMP_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -37528,9 +38280,9 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } ZVAL_DEREF(container); - zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2), IS_TMP_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -37546,8 +38298,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); - zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2), IS_TMP_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -37570,19 +38322,19 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCOD zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } ZVAL_DEREF(container); - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2), IS_TMP_VAR TSRMLS_CC); + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else { if (IS_TMP_VAR == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2), IS_TMP_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); } CHECK_EXCEPTION(); @@ -37602,9 +38354,9 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_H zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } ZVAL_DEREF(container); - zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_TMP_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2), IS_TMP_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -37622,7 +38374,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); container = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); - offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if ((IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { @@ -37632,14 +38384,36 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_TMP_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -37653,16 +38427,16 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDL zval *container; SAVE_OPLINE(); - property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -37678,15 +38452,15 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND zval *container; SAVE_OPLINE(); - property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -37704,7 +38478,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); container = _get_zval_ptr_cv_deref_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); - offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if ((IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { @@ -37713,14 +38487,36 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HAND zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_TMP_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -37737,7 +38533,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCOD zval *property; SAVE_OPLINE(); - property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) { @@ -37746,9 +38542,9 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_TMP_HANDLER(ZEND_OPCOD if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -37767,14 +38563,14 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_H SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); - property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + property = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_TMP_VAR, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -37791,13 +38587,13 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE SAVE_OPLINE(); object = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); /* assign_obj has two opcodes! */ CHECK_EXCEPTION(); @@ -37820,27 +38616,27 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLE ZVAL_DEREF(object_ptr); if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_free_op free_op2; - zval *property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *property_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_TMP_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else { zend_free_op free_op2, free_op_data1; zval rv; zval *value; - zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *dim = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); zval *variable_ptr; if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) && EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); FREE_OP(free_op_data1); } else { zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_TMP_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); variable_ptr = Z_INDIRECT(rv); @@ -37875,12 +38671,12 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR zval *variable_ptr; SAVE_OPLINE(); - value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + value = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) { if (IS_TMP_VAR == IS_TMP_VAR) { - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } if (RETURN_VALUE_USED(opline)) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -37911,7 +38707,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_ SAVE_OPLINE(); - function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + function_name = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if (IS_TMP_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { @@ -37927,12 +38723,12 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_ uint32_t nesting = 1; if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); if (EG(exception) != NULL) { HANDLE_EXCEPTION(); @@ -38000,7 +38796,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_ EX(call) = zend_vm_stack_push_call_frame(VM_FRAME_NESTED_FUNCTION, fbc, opline->extended_value, called_scope, obj, EX(call) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -38015,9 +38811,9 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); fast_equal_function(result, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -38059,7 +38855,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE if (IS_TMP_VAR != IS_UNUSED) { zend_free_op free_op2; - zval *offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); zend_string *str; zend_ulong hval; @@ -38102,7 +38898,7 @@ str_index: /* do nothing */ break; } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else { zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr); } @@ -38158,7 +38954,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER ZVAL_DEREF(container); SEPARATE_ZVAL_NOREF(container); } - offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if (IS_CV != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht = Z_ARRVAL_P(container); @@ -38205,7 +39001,7 @@ num_index_dim: zend_error(E_WARNING, "Illegal offset type in unset"); break; } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else if (IS_CV == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use object as array"); @@ -38214,12 +39010,12 @@ num_index_dim: //??? zval_copy_ctor(offset); //??? } Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_CONTINUE(); /* bailed out before */ } else { - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } CHECK_EXCEPTION(); @@ -38238,7 +39034,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); } - offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); ZVAL_DEREF(container); if (IS_CV == IS_UNUSED || Z_TYPE_P(container) == IS_OBJECT) { @@ -38248,7 +39044,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER zend_error(E_NOTICE, "Trying to unset property of non-object"); } } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -38265,7 +39061,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_TMP_HANDLER(ZEND_OP SAVE_OPLINE(); container = _get_zval_ptr_cv_deref_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); - offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if (IS_CV != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht = Z_ARRVAL_P(container); @@ -38335,7 +39131,7 @@ num_index_prop: result = 0; if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) { - if (IS_CV == IS_CV || IS_CV == IS_VAR) { + if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) { ZVAL_DEREF(offset); } if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */ @@ -38361,7 +39157,7 @@ num_index_prop: result = ((opline->extended_value & ZEND_ISSET) == 0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); ZVAL_BOOL(EX_VAR(opline->result.var), result); CHECK_EXCEPTION(); @@ -38378,7 +39174,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMP_HANDLER(ZEND_O SAVE_OPLINE(); container = _get_zval_ptr_cv_deref_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); - offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); if (IS_CV == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (EXPECTED(Z_OBJ_HT_P(container)->has_property)) { @@ -38394,7 +39190,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_TMP_HANDLER(ZEND_O result = ((opline->extended_value & ZEND_ISSET) == 0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); ZVAL_BOOL(EX_VAR(opline->result.var), result); CHECK_EXCEPTION(); @@ -38484,7 +39280,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG /* Set the new yielded key */ if (IS_TMP_VAR != IS_UNUSED) { zend_free_op free_op2; - zval *key = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *key = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2); /* Consts, temporary variables and references need copying */ if (IS_TMP_VAR == IS_CONST) { @@ -38540,9 +39336,9 @@ static int ZEND_FASTCALL ZEND_POW_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); pow_function(EX_VAR(opline->result.var), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -38560,9 +39356,9 @@ static int ZEND_FASTCALL ZEND_ADD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); fast_add_function(EX_VAR(opline->result.var), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -38575,9 +39371,9 @@ static int ZEND_FASTCALL ZEND_SUB_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); fast_sub_function(EX_VAR(opline->result.var), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -38590,9 +39386,9 @@ static int ZEND_FASTCALL ZEND_MUL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); fast_mul_function(EX_VAR(opline->result.var), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -38605,9 +39401,9 @@ static int ZEND_FASTCALL ZEND_DIV_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); fast_div_function(EX_VAR(opline->result.var), _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -38620,9 +39416,9 @@ static int ZEND_FASTCALL ZEND_MOD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); fast_mod_function(EX_VAR(opline->result.var), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -38635,9 +39431,9 @@ static int ZEND_FASTCALL ZEND_SL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); shift_left_function(EX_VAR(opline->result.var), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -38650,9 +39446,9 @@ static int ZEND_FASTCALL ZEND_SR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); shift_right_function(EX_VAR(opline->result.var), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -38665,9 +39461,9 @@ static int ZEND_FASTCALL ZEND_CONCAT_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); concat_function(EX_VAR(opline->result.var), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -38680,9 +39476,9 @@ static int ZEND_FASTCALL ZEND_IS_IDENTICAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); fast_is_identical_function(EX_VAR(opline->result.var), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -38696,9 +39492,9 @@ static int ZEND_FASTCALL ZEND_IS_NOT_IDENTICAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_ SAVE_OPLINE(); fast_is_not_identical_function(result, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -38712,9 +39508,9 @@ static int ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ SAVE_OPLINE(); fast_equal_function(result, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -38728,9 +39524,9 @@ static int ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); fast_not_equal_function(result, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -38744,9 +39540,9 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE SAVE_OPLINE(); fast_is_smaller_function(result, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -38760,9 +39556,9 @@ static int ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_VAR_HANDLER(ZEND_OPCO SAVE_OPLINE(); fast_is_smaller_or_equal_function(result, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -38775,9 +39571,9 @@ static int ZEND_FASTCALL ZEND_BW_OR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG SAVE_OPLINE(); bitwise_or_function(EX_VAR(opline->result.var), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -38790,9 +39586,9 @@ static int ZEND_FASTCALL ZEND_BW_AND_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); bitwise_and_function(EX_VAR(opline->result.var), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -38805,9 +39601,9 @@ static int ZEND_FASTCALL ZEND_BW_XOR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR SAVE_OPLINE(); bitwise_xor_function(EX_VAR(opline->result.var), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -38820,9 +39616,9 @@ static int ZEND_FASTCALL ZEND_BOOL_XOR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ SAVE_OPLINE(); boolean_xor_function(EX_VAR(opline->result.var), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -38832,7 +39628,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina USE_OPLINE zend_free_op free_op2, free_op_data1; zval *object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); - zval *property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); zval *value; zval *zptr; @@ -38848,7 +39644,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to assign property of non-object"); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); FREE_OP(free_op_data1); if (RETURN_VALUE_USED(opline)) { @@ -38886,7 +39682,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -38910,7 +39706,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina } } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); FREE_OP(free_op_data1); } @@ -38941,7 +39737,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_VAR(int (*bina } return zend_binary_assign_op_obj_helper_SPEC_CV_VAR(binary_op, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } else { - zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2); zend_fetch_dimension_address_RW(&rv, container, dim, IS_VAR TSRMLS_CC); value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); @@ -38968,7 +39764,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_dim_helper_SPEC_CV_VAR(int (*bina } } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); FREE_OP(free_op_data1); CHECK_EXCEPTION(); @@ -38984,7 +39780,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_VAR(int (*binary_o zval *value; SAVE_OPLINE(); - value = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + value = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2); var_ptr = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) { @@ -39006,7 +39802,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_helper_SPEC_CV_VAR(int (*binary_o } } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -39166,7 +39962,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_VAR(incdec_t in SAVE_OPLINE(); object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); retval = EX_VAR(opline->result.var); if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { @@ -39179,7 +39975,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_VAR(incdec_t in if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); if (RETURN_VALUE_USED(opline)) { ZVAL_NULL(retval); } @@ -39211,7 +40007,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_VAR(incdec_t in zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -39230,7 +40026,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_VAR(incdec_t in } } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -39257,7 +40053,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_VAR(incdec_t i SAVE_OPLINE(); object = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); retval = EX_VAR(opline->result.var); if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { @@ -39270,7 +40066,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_VAR(incdec_t i if (IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) { zend_error(E_WARNING, "Attempt to increment/decrement property of non-object"); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); ZVAL_NULL(retval); CHECK_EXCEPTION(); @@ -39298,7 +40094,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_VAR(incdec_t i zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -39315,7 +40111,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_VAR(incdec_t i } } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -39487,8 +40283,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_R_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2), IS_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -39507,9 +40303,9 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } ZVAL_DEREF(container); - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2), IS_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -39530,9 +40326,9 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } ZVAL_DEREF(container); - zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2), IS_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -39548,8 +40344,8 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_IS_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); - zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zend_fetch_dimension_address_read_IS(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2), IS_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -39572,19 +40368,19 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCOD zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } ZVAL_DEREF(container); - zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2), IS_VAR TSRMLS_CC); + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else { if (IS_VAR == IS_UNUSED) { zend_error_noreturn(E_ERROR, "Cannot use [] for reading"); } container = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); - zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zend_fetch_dimension_address_read_R(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2), IS_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); } CHECK_EXCEPTION(); @@ -39604,9 +40400,9 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_H zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } ZVAL_DEREF(container); - zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC), IS_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2), IS_VAR TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -39624,7 +40420,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL SAVE_OPLINE(); container = _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if ((IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { @@ -39634,14 +40430,36 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -39655,16 +40473,16 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDL zval *container; SAVE_OPLINE(); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_VAR, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -39680,15 +40498,15 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND zval *container; SAVE_OPLINE(); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); container = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_VAR, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -39706,7 +40524,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND SAVE_OPLINE(); container = _get_zval_ptr_cv_deref_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if ((IS_CV != IS_UNUSED && UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) || UNEXPECTED(Z_OBJ_HT_P(container)->read_property == NULL)) { @@ -39715,14 +40533,36 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HAND zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_VAR == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -39739,7 +40579,7 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCOD zval *property; SAVE_OPLINE(); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); container = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_CONST || IS_CV == IS_TMP_VAR) { @@ -39748,9 +40588,9 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_VAR_HANDLER(ZEND_OPCOD if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_VAR, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -39769,14 +40609,14 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_H SAVE_OPLINE(); container = _get_zval_ptr_cv_BP_VAR_UNSET(execute_data, opline->op1.var TSRMLS_CC); - property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + property = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_VAR, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); + zval_ptr_dtor_nogc(free_op2); + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -39793,13 +40633,13 @@ static int ZEND_FASTCALL ZEND_ASSIGN_OBJ_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE SAVE_OPLINE(); object = _get_zval_ptr_cv_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); - property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_CV == IS_VAR && UNEXPECTED(object == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an array"); } zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_OBJ, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); /* assign_obj has two opcodes! */ CHECK_EXCEPTION(); @@ -39822,27 +40662,27 @@ static int ZEND_FASTCALL ZEND_ASSIGN_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE ZVAL_DEREF(object_ptr); if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) { zend_free_op free_op2; - zval *property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *property_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); zend_assign_to_object(RETURN_VALUE_USED(opline)?EX_VAR(opline->result.var):NULL, object_ptr, IS_CV, property_name, (opline+1)->op1_type, &(opline+1)->op1, execute_data, ZEND_ASSIGN_DIM, ((IS_VAR == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else { zend_free_op free_op2, free_op_data1; zval rv; zval *value; - zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *dim = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2); zval *variable_ptr; if (UNEXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) && EXPECTED(Z_STRLEN_P(object_ptr) != 0)) { zend_long offset = zend_fetch_string_offset(object_ptr, dim, BP_VAR_W TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); zend_assign_to_string_offset(object_ptr, offset, value, (RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : NULL) TSRMLS_CC); FREE_OP(free_op_data1); } else { zend_fetch_dimension_address_W(&rv, object_ptr, dim, IS_VAR TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); value = get_zval_ptr_deref((opline+1)->op1_type, &(opline+1)->op1, execute_data, &free_op_data1, BP_VAR_R); ZEND_ASSERT(Z_TYPE(rv) == IS_INDIRECT); variable_ptr = Z_INDIRECT(rv); @@ -39877,12 +40717,12 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR zval *variable_ptr; SAVE_OPLINE(); - value = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + value = _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2); variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC); if (IS_CV == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) { if (IS_VAR == IS_TMP_VAR) { - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } if (RETURN_VALUE_USED(opline)) { ZVAL_NULL(EX_VAR(opline->result.var)); @@ -39896,7 +40736,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR } /* zend_assign_to_variable() always takes care of op2, never free it! */ - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -39910,7 +40750,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE zval *value_ptr; SAVE_OPLINE(); - value_ptr = _get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + value_ptr = _get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_VAR == IS_VAR && UNEXPECTED(value_ptr == NULL)) { zend_error_noreturn(E_ERROR, "Cannot create references to/from string offsets nor overloaded objects"); @@ -39919,17 +40759,17 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE (value_ptr == &EG(uninitialized_zval) || (opline->extended_value == ZEND_RETURNS_FUNCTION && !(Z_VAR_FLAGS_P(value_ptr) & IS_VAR_RET_REF)))) { - if (!(free_op2.var != NULL)) { + if (!(free_op2 != NULL)) { PZVAL_LOCK(value_ptr); /* undo the effect of get_zval_ptr_ptr() */ } zend_error(E_STRICT, "Only variables should be assigned by reference"); if (UNEXPECTED(EG(exception) != NULL)) { - if (free_op2.var) {zval_ptr_dtor_nogc(free_op2.var);}; + if (free_op2) {zval_ptr_dtor_nogc(free_op2);}; HANDLE_EXCEPTION(); } return ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); } else if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) { - if (!(free_op2.var != NULL)) { + if (!(free_op2 != NULL)) { PZVAL_LOCK(value_ptr); } } @@ -39951,7 +40791,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE } if (IS_VAR == IS_VAR && opline->extended_value == ZEND_RETURNS_NEW) { - if (!(free_op2.var != NULL)) { + if (!(free_op2 != NULL)) { Z_DELREF_P(variable_ptr); } } @@ -39960,7 +40800,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_REF_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLE ZVAL_COPY(EX_VAR(opline->result.var), variable_ptr); } - if (free_op2.var) {zval_ptr_dtor_nogc(free_op2.var);}; + if (free_op2) {zval_ptr_dtor_nogc(free_op2);}; CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -39978,7 +40818,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_ SAVE_OPLINE(); - function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_VAR != IS_CONST && UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) { @@ -39994,12 +40834,12 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_ uint32_t nesting = 1; if (UNEXPECTED(EG(exception) != NULL)) { - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); HANDLE_EXCEPTION(); } zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on %s", Z_STRVAL_P(function_name), zend_get_type_by_const(Z_TYPE_P(object))); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); if (EG(exception) != NULL) { HANDLE_EXCEPTION(); @@ -40067,7 +40907,7 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_ EX(call) = zend_vm_stack_push_call_frame(VM_FRAME_NESTED_FUNCTION, fbc, opline->extended_value, called_scope, obj, EX(call) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -40082,9 +40922,9 @@ static int ZEND_FASTCALL ZEND_CASE_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS SAVE_OPLINE(); fast_equal_function(result, _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -40126,7 +40966,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_VAR_HANDLER(ZEND_OPCODE if (IS_VAR != IS_UNUSED) { zend_free_op free_op2; - zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); zend_string *str; zend_ulong hval; @@ -40169,7 +41009,7 @@ str_index: /* do nothing */ break; } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else { zend_hash_next_index_insert(Z_ARRVAL_P(EX_VAR(opline->result.var)), expr_ptr); } @@ -40255,8 +41095,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER } else { ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_CV != IS_CONST) { - zval_dtor(&tmp); + if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } HANDLE_EXCEPTION(); @@ -40275,8 +41115,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_CV != IS_CONST) { - zval_dtor(&tmp); + if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } CHECK_EXCEPTION(); @@ -40300,7 +41140,7 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER ZVAL_DEREF(container); SEPARATE_ZVAL_NOREF(container); } - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_CV != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht = Z_ARRVAL_P(container); @@ -40347,7 +41187,7 @@ num_index_dim: zend_error(E_WARNING, "Illegal offset type in unset"); break; } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else if (IS_CV == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (UNEXPECTED(Z_OBJ_HT_P(container)->unset_dimension == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use object as array"); @@ -40356,12 +41196,12 @@ num_index_dim: //??? zval_copy_ctor(offset); //??? } Z_OBJ_HT_P(container)->unset_dimension(container, offset TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else if (UNEXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); ZEND_VM_CONTINUE(); /* bailed out before */ } else { - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } CHECK_EXCEPTION(); @@ -40380,7 +41220,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot unset string offsets"); } - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); ZVAL_DEREF(container); if (IS_CV == IS_UNUSED || Z_TYPE_P(container) == IS_OBJECT) { @@ -40390,7 +41230,7 @@ static int ZEND_FASTCALL ZEND_UNSET_OBJ_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER zend_error(E_NOTICE, "Trying to unset property of non-object"); } } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); @@ -40420,6 +41260,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE zval tmp, *varname = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); + ZVAL_UNDEF(&tmp); if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { ZVAL_STR(&tmp, zval_get_string(varname)); varname = &tmp; @@ -40448,8 +41289,8 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_CV != IS_CONST && varname == &tmp) { - zval_dtor(&tmp); + if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } if (opline->extended_value & ZEND_ISSET) { @@ -40477,7 +41318,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_VAR_HANDLER(ZEND_OP SAVE_OPLINE(); container = _get_zval_ptr_cv_deref_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_CV != IS_UNUSED && EXPECTED(Z_TYPE_P(container) == IS_ARRAY)) { HashTable *ht = Z_ARRVAL_P(container); @@ -40547,7 +41388,7 @@ num_index_prop: result = 0; if (UNEXPECTED(Z_TYPE_P(offset) != IS_LONG)) { - if (IS_CV == IS_CV || IS_CV == IS_VAR) { + if (IS_VAR == IS_CV || IS_VAR == IS_VAR) { ZVAL_DEREF(offset); } if (Z_TYPE_P(offset) < IS_STRING /* simple scalar types */ @@ -40573,7 +41414,7 @@ num_index_prop: result = ((opline->extended_value & ZEND_ISSET) == 0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); ZVAL_BOOL(EX_VAR(opline->result.var), result); CHECK_EXCEPTION(); @@ -40590,7 +41431,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_VAR_HANDLER(ZEND_O SAVE_OPLINE(); container = _get_zval_ptr_cv_deref_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); - offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); if (IS_CV == IS_UNUSED || EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) { if (EXPECTED(Z_OBJ_HT_P(container)->has_property)) { @@ -40606,7 +41447,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_PROP_OBJ_SPEC_CV_VAR_HANDLER(ZEND_O result = ((opline->extended_value & ZEND_ISSET) == 0); } - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); ZVAL_BOOL(EX_VAR(opline->result.var), result); CHECK_EXCEPTION(); @@ -40735,7 +41576,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG /* Set the new yielded key */ if (IS_VAR != IS_UNUSED) { zend_free_op free_op2; - zval *key = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC); + zval *key = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2); /* Consts, temporary variables and references need copying */ if (IS_VAR == IS_CONST) { @@ -40744,7 +41585,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG ZVAL_COPY_VALUE(&generator->key, key); } else if ((IS_VAR == IS_VAR || IS_VAR == IS_CV) && Z_ISREF_P(key)) { ZVAL_DUP(&generator->key, Z_REFVAL_P(key)); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); } else { ZVAL_COPY_VALUE(&generator->key, key); if (IS_VAR == IS_CV) { @@ -40791,9 +41632,9 @@ static int ZEND_FASTCALL ZEND_POW_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) SAVE_OPLINE(); pow_function(EX_VAR(opline->result.var), _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC), - _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC) TSRMLS_CC); + _get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2) TSRMLS_CC); - zval_ptr_dtor_nogc(free_op2.var); + zval_ptr_dtor_nogc(free_op2); CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -40862,7 +41703,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*b zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -41291,7 +42132,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HA ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -41314,7 +42155,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_H ZVAL_DEREF(container); zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -41340,7 +42181,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_UNUSED_HANDLER(ZEND_OP } ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, NULL, IS_UNUSED TSRMLS_CC); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -41586,8 +42427,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAND } else { ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC); if (UNEXPECTED(EG(exception) != NULL)) { - if (IS_CV != IS_CONST) { - zval_dtor(&tmp); + if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } HANDLE_EXCEPTION(); @@ -41606,8 +42447,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAND zend_hash_del_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_CV != IS_CONST) { - zval_dtor(&tmp); + if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } CHECK_EXCEPTION(); @@ -41638,6 +42479,7 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPC zval tmp, *varname = _get_zval_ptr_cv_BP_VAR_IS(execute_data, opline->op1.var TSRMLS_CC); + ZVAL_UNDEF(&tmp); if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) { ZVAL_STR(&tmp, zval_get_string(varname)); varname = &tmp; @@ -41666,8 +42508,8 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPC value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname)); } - if (IS_CV != IS_CONST && varname == &tmp) { - zval_dtor(&tmp); + if (IS_CV != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) { + zend_string_release(Z_STR(tmp)); } if (opline->extended_value & ZEND_ISSET) { @@ -42154,7 +42996,7 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -42476,7 +43318,7 @@ static int ZEND_FASTCALL zend_pre_incdec_property_helper_SPEC_CV_CV(incdec_t inc zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -42562,7 +43404,7 @@ static int ZEND_FASTCALL zend_post_incdec_property_helper_SPEC_CV_CV(incdec_t in zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC); if (Z_REFCOUNT_P(z) == 0) { - zval_dtor(z); + zend_objects_store_del(Z_OBJ_P(z) TSRMLS_CC); } ZVAL_COPY_VALUE(z, value); } @@ -42624,7 +43466,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -42647,7 +43489,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL ZVAL_DEREF(container); zend_fetch_dimension_address_RW(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -42688,7 +43530,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE } ZVAL_DEREF(container); zend_fetch_dimension_address_W(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -42721,7 +43563,7 @@ static int ZEND_FASTCALL ZEND_FETCH_DIM_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HA ZVAL_DEREF(container); zend_fetch_dimension_address_UNSET(EX_VAR(opline->result.var), container, _get_zval_ptr_cv_deref_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC), IS_CV TSRMLS_CC); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -42749,11 +43591,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_R_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } @@ -42776,9 +43640,9 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_W_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLE zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -42800,9 +43664,9 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_RW_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -42829,11 +43693,33 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_IS_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDL zval *retval; /* here we are sure we are dealing with an object */ - retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + do { + if (IS_CV == IS_CONST && + EXPECTED(Z_OBJCE_P(container) == CACHED_PTR(Z_CACHE_SLOT_P(offset)))) { + zend_property_info *prop_info = CACHED_PTR(Z_CACHE_SLOT_P(offset) + 1); + zend_object *zobj = Z_OBJ_P(container); + + if (EXPECTED(prop_info)) { + retval = OBJ_PROP(zobj, prop_info->offset); + if (EXPECTED(Z_TYPE_P(retval) != IS_UNDEF)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } else if (EXPECTED(zobj->properties != NULL)) { + retval = zend_hash_find(zobj->properties, Z_STR_P(offset)); + if (EXPECTED(retval)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + break; + } + } + } - if (retval != EX_VAR(opline->result.var)) { - ZVAL_COPY(EX_VAR(opline->result.var), retval); - } + retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC); + + if (retval != EX_VAR(opline->result.var)) { + ZVAL_COPY(EX_VAR(opline->result.var), retval); + } + } while (0); } @@ -42861,9 +43747,9 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_FUNC_ARG_SPEC_CV_CV_HANDLER(ZEND_OPCODE if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } @@ -42887,9 +43773,9 @@ static int ZEND_FASTCALL ZEND_FETCH_OBJ_UNSET_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HA if (IS_CV == IS_VAR && UNEXPECTED(container == NULL)) { zend_error_noreturn(E_ERROR, "Cannot use string offset as an object"); } - zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); + zend_fetch_property_address(EX_VAR(opline->result.var), container, IS_CV, property, IS_CV, ((IS_CV == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC); - if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1.var)) { + if (IS_CV == IS_VAR && READY_TO_DESTROY(free_op1)) { EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var)); } diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php index 69c25085aa..5836adaefb 100644 --- a/Zend/zend_vm_gen.php +++ b/Zend/zend_vm_gen.php @@ -100,18 +100,18 @@ $op2_type = array( ); $op1_free = array( - "ANY" => "(free_op1.var != NULL)", + "ANY" => "(free_op1 != NULL)", "TMP" => "1", - "VAR" => "(free_op1.var != NULL)", + "VAR" => "(free_op1 != NULL)", "CONST" => "0", "UNUSED" => "0", "CV" => "0", ); $op2_free = array( - "ANY" => "(free_op2.var != NULL)", + "ANY" => "(free_op2 != NULL)", "TMP" => "1", - "VAR" => "(free_op2.var != NULL)", + "VAR" => "(free_op2 != NULL)", "CONST" => "0", "UNUSED" => "0", "CV" => "0", @@ -119,8 +119,8 @@ $op2_free = array( $op1_get_zval_ptr = array( "ANY" => "get_zval_ptr(opline->op1_type, &opline->op1, execute_data, &free_op1, \\1)", - "TMP" => "_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC)", - "VAR" => "_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC)", + "TMP" => "_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1)", + "VAR" => "_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1)", "CONST" => "opline->op1.zv", "UNUSED" => "NULL", "CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op1.var TSRMLS_CC)", @@ -128,8 +128,8 @@ $op1_get_zval_ptr = array( $op2_get_zval_ptr = array( "ANY" => "get_zval_ptr(opline->op2_type, &opline->op2, execute_data, &free_op2, \\1)", - "TMP" => "_get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC)", - "VAR" => "_get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC)", + "TMP" => "_get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2)", + "VAR" => "_get_zval_ptr_var(opline->op2.var, execute_data, &free_op2)", "CONST" => "opline->op2.zv", "UNUSED" => "NULL", "CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op2.var TSRMLS_CC)", @@ -138,7 +138,7 @@ $op2_get_zval_ptr = array( $op1_get_zval_ptr_ptr = array( "ANY" => "get_zval_ptr_ptr(opline->op1_type, &opline->op1, execute_data, &free_op1, \\1)", "TMP" => "NULL", - "VAR" => "_get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC)", + "VAR" => "_get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1)", "CONST" => "NULL", "UNUSED" => "NULL", "CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op1.var TSRMLS_CC)", @@ -147,7 +147,7 @@ $op1_get_zval_ptr_ptr = array( $op2_get_zval_ptr_ptr = array( "ANY" => "get_zval_ptr_ptr(opline->op2_type, &opline->op2, execute_data, &free_op2, \\1)", "TMP" => "NULL", - "VAR" => "_get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC)", + "VAR" => "_get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2)", "CONST" => "NULL", "UNUSED" => "NULL", "CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op2.var TSRMLS_CC)", @@ -155,8 +155,8 @@ $op2_get_zval_ptr_ptr = array( $op1_get_zval_ptr_deref = array( "ANY" => "get_zval_ptr_deref(opline->op1_type, &opline->op1, execute_data, &free_op1, \\1)", - "TMP" => "_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC)", - "VAR" => "_get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC)", + "TMP" => "_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1)", + "VAR" => "_get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1)", "CONST" => "opline->op1.zv", "UNUSED" => "NULL", "CV" => "_get_zval_ptr_cv_deref_\\1(execute_data, opline->op1.var TSRMLS_CC)", @@ -164,8 +164,8 @@ $op1_get_zval_ptr_deref = array( $op2_get_zval_ptr_deref = array( "ANY" => "get_zval_ptr_deref(opline->op2_type, &opline->op2, execute_data, &free_op2, \\1)", - "TMP" => "_get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC)", - "VAR" => "_get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC)", + "TMP" => "_get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2)", + "VAR" => "_get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2)", "CONST" => "opline->op2.zv", "UNUSED" => "NULL", "CV" => "_get_zval_ptr_cv_deref_\\1(execute_data, opline->op2.var TSRMLS_CC)", @@ -174,7 +174,7 @@ $op2_get_zval_ptr_deref = array( $op1_get_zval_ptr_ptr_undef = array( "ANY" => "get_zval_ptr_ptr_undef(opline->op1_type, &opline->op1, execute_data, &free_op1, \\1)", "TMP" => "NULL", - "VAR" => "_get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC)", + "VAR" => "_get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1)", "CONST" => "NULL", "UNUSED" => "NULL", "CV" => "_get_zval_ptr_cv_undef_\\1(execute_data, opline->op1.var TSRMLS_CC)", @@ -183,7 +183,7 @@ $op1_get_zval_ptr_ptr_undef = array( $op2_get_zval_ptr_ptr_undef = array( "ANY" => "get_zval_ptr_ptr_undef(opline->op2_type, &opline->op2, execute_data, &free_op2, \\1)", "TMP" => "NULL", - "VAR" => "_get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC)", + "VAR" => "_get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2)", "CONST" => "NULL", "UNUSED" => "NULL", "CV" => "_get_zval_ptr_cv_undef_\\1(execute_data, opline->op2.var TSRMLS_CC)", @@ -191,62 +191,62 @@ $op2_get_zval_ptr_ptr_undef = array( $op1_get_obj_zval_ptr = array( "ANY" => "get_obj_zval_ptr(opline->op1_type, &opline->op1, execute_data, &free_op1, \\1)", - "TMP" => "_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC)", - "VAR" => "_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC)", + "TMP" => "_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1)", + "VAR" => "_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1)", "CONST" => "opline->op1.zv", - "UNUSED" => "_get_obj_zval_ptr_unused(TSRMLS_C)", + "UNUSED" => "_get_obj_zval_ptr_unused(execute_data)", "CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op1.var TSRMLS_CC)", ); $op2_get_obj_zval_ptr = array( "ANY" => "get_obj_zval_ptr(opline->op2_type, &opline->op2, execute_data, &free_op2, \\1)", - "TMP" => "_get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC)", - "VAR" => "_get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC)", + "TMP" => "_get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2)", + "VAR" => "_get_zval_ptr_var(opline->op2.var, execute_data, &free_op2)", "CONST" => "opline->op2.zv", - "UNUSED" => "_get_obj_zval_ptr_unused(TSRMLS_C)", + "UNUSED" => "_get_obj_zval_ptr_unused(execute_data)", "CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op2.var TSRMLS_CC)", ); $op1_get_obj_zval_ptr_deref = array( "ANY" => "get_obj_zval_ptr(opline->op1_type, &opline->op1, execute_data, &free_op1, \\1)", - "TMP" => "_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC)", - "VAR" => "_get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1 TSRMLS_CC)", + "TMP" => "_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1)", + "VAR" => "_get_zval_ptr_var_deref(opline->op1.var, execute_data, &free_op1)", "CONST" => "opline->op1.zv", - "UNUSED" => "_get_obj_zval_ptr_unused(execute_data TSRMLS_CC)", + "UNUSED" => "_get_obj_zval_ptr_unused(execute_data)", "CV" => "_get_zval_ptr_cv_deref_\\1(execute_data, opline->op1.var TSRMLS_CC)", ); $op2_get_obj_zval_ptr_deref = array( "ANY" => "get_obj_zval_ptr(opline->op2_type, &opline->op2, execute_data, &free_op2, \\1)", - "TMP" => "_get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC)", - "VAR" => "_get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2 TSRMLS_CC)", + "TMP" => "_get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2)", + "VAR" => "_get_zval_ptr_var_deref(opline->op2.var, execute_data, &free_op2)", "CONST" => "opline->op2.zv", - "UNUSED" => "_get_obj_zval_ptr_unused(execute_data TSRMLS_CC)", + "UNUSED" => "_get_obj_zval_ptr_unused(execute_data)", "CV" => "_get_zval_ptr_cv_deref_\\1(execute_data, opline->op2.var TSRMLS_CC)", ); $op1_get_obj_zval_ptr_ptr = array( "ANY" => "get_obj_zval_ptr_ptr(opline->op1_type, &opline->op1, execute_data, &free_op1, \\1)", "TMP" => "NULL", - "VAR" => "_get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC)", + "VAR" => "_get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1)", "CONST" => "NULL", - "UNUSED" => "_get_obj_zval_ptr_unused(execute_data TSRMLS_CC)", + "UNUSED" => "_get_obj_zval_ptr_unused(execute_data)", "CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op1.var TSRMLS_CC)", ); $op2_get_obj_zval_ptr_ptr = array( "ANY" => "get_obj_zval_ptr_ptr(opline->op2_type, &opline->op2, execute_data, &free_op2, \\1)", "TMP" => "NULL", - "VAR" => "_get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC)", + "VAR" => "_get_zval_ptr_ptr_var(opline->op2.var, execute_data, &free_op2)", "CONST" => "NULL", - "UNUSED" => "_get_obj_zval_ptr_unused(execute_data TSRMLS_CC)", + "UNUSED" => "_get_obj_zval_ptr_unused(execute_data)", "CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op2.var TSRMLS_CC)", ); $op1_free_op = array( "ANY" => "FREE_OP(free_op1)", - "TMP" => "zval_ptr_dtor_nogc(free_op1.var)", - "VAR" => "zval_ptr_dtor_nogc(free_op1.var)", + "TMP" => "zval_ptr_dtor_nogc(free_op1)", + "VAR" => "zval_ptr_dtor_nogc(free_op1)", "CONST" => "", "UNUSED" => "", "CV" => "", @@ -254,44 +254,44 @@ $op1_free_op = array( $op2_free_op = array( "ANY" => "FREE_OP(free_op2)", - "TMP" => "zval_ptr_dtor_nogc(free_op2.var)", - "VAR" => "zval_ptr_dtor_nogc(free_op2.var)", + "TMP" => "zval_ptr_dtor_nogc(free_op2)", + "VAR" => "zval_ptr_dtor_nogc(free_op2)", "CONST" => "", "UNUSED" => "", "CV" => "", ); $op1_free_op_if_var = array( - "ANY" => "if (opline->op1_type == IS_VAR) {zval_ptr_dtor_nogc(free_op1.var);}", + "ANY" => "if (opline->op1_type == IS_VAR) {zval_ptr_dtor_nogc(free_op1);}", "TMP" => "", - "VAR" => "zval_ptr_dtor_nogc(free_op1.var)", + "VAR" => "zval_ptr_dtor_nogc(free_op1)", "CONST" => "", "UNUSED" => "", "CV" => "", ); $op2_free_op_if_var = array( - "ANY" => "if (opline->op1_type == IS_VAR) {zval_ptr_dtor_nogc(free_op1.var);}", + "ANY" => "if (opline->op2_type == IS_VAR) {zval_ptr_dtor_nogc(free_op2);}", "TMP" => "", - "VAR" => "zval_ptr_dtor_nogc(free_op2.var)", + "VAR" => "zval_ptr_dtor_nogc(free_op2)", "CONST" => "", "UNUSED" => "", "CV" => "", ); $op1_free_op_var_ptr = array( - "ANY" => "if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}", + "ANY" => "if (free_op1) {zval_ptr_dtor_nogc(free_op1);}", "TMP" => "", - "VAR" => "if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);}", + "VAR" => "if (free_op1) {zval_ptr_dtor_nogc(free_op1);}", "CONST" => "", "UNUSED" => "", "CV" => "", ); $op2_free_op_var_ptr = array( - "ANY" => "if (free_op2.var) {zval_ptr_dtor_nogc(free_op2.var);}", + "ANY" => "if (free_op2) {zval_ptr_dtor_nogc(free_op2);}", "TMP" => "", - "VAR" => "if (free_op2.var) {zval_ptr_dtor_nogc(free_op2.var);}", + "VAR" => "if (free_op2) {zval_ptr_dtor_nogc(free_op2);}", "CONST" => "", "UNUSED" => "", "CV" => "", @@ -1217,7 +1217,9 @@ function gen_vm($def, $skel) { out($f, $GLOBALS['header_text']); fputs($f, "#ifndef ZEND_VM_OPCODES_H\n#define ZEND_VM_OPCODES_H\n\n"); + fputs($f, "BEGIN_EXTERN_C()\n\n"); fputs($f, "ZEND_API const char *zend_get_opcode_name(zend_uchar opcode);\n\n"); + fputs($f, "END_EXTERN_C()\n\n"); foreach ($opcodes as $code => $dsc) { $code = str_pad((string)$code,$code_len," ",STR_PAD_LEFT); diff --git a/Zend/zend_vm_opcodes.h b/Zend/zend_vm_opcodes.h index c06fd84ff4..9d969877e0 100644 --- a/Zend/zend_vm_opcodes.h +++ b/Zend/zend_vm_opcodes.h @@ -21,8 +21,12 @@ #ifndef ZEND_VM_OPCODES_H #define ZEND_VM_OPCODES_H +BEGIN_EXTERN_C() + ZEND_API const char *zend_get_opcode_name(zend_uchar opcode); +END_EXTERN_C() + #define ZEND_NOP 0 #define ZEND_ADD 1 #define ZEND_SUB 2 |