summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/Makefile.am2
-rw-r--r--Zend/Zend.dsp4
-rw-r--r--Zend/ZendTS.dsp4
-rw-r--r--Zend/tests/list_destructuring_to_special_variables.phpt49
-rw-r--r--Zend/zend_compile.c31
-rw-r--r--Zend/zend_dynamic_array.c72
-rw-r--r--Zend/zend_dynamic_array.h47
-rw-r--r--Zend/zend_execute.c49
-rw-r--r--Zend/zend_static_allocator.c84
-rw-r--r--Zend/zend_static_allocator.h55
-rw-r--r--Zend/zend_vm_def.h87
-rw-r--r--Zend/zend_vm_execute.h1138
-rw-r--r--Zend/zend_vm_gen.php24
-rw-r--r--configure.in2
-rw-r--r--ext/opcache/Optimizer/block_pass.c2
-rw-r--r--ext/standard/basic_functions.h4
-rw-r--r--ext/standard/php_var.h109
-rw-r--r--ext/standard/var.c92
-rw-r--r--win32/build/config.w322
-rw-r--r--win32/build/projectgen.js1
20 files changed, 716 insertions, 1142 deletions
diff --git a/Zend/Makefile.am b/Zend/Makefile.am
index 65c4113497..2a76db36b1 100644
--- a/Zend/Makefile.am
+++ b/Zend/Makefile.am
@@ -8,7 +8,7 @@ noinst_LTLIBRARIES=libZend.la
libZend_la_SOURCES=\
zend_language_parser.y zend_language_scanner.l \
zend_ini_parser.y zend_ini_scanner.l \
- zend_alloc.c zend_compile.c zend_constants.c zend_dynamic_array.c \
+ zend_alloc.c zend_compile.c zend_constants.c \
zend_execute.c zend_execute_API.c zend_highlight.c zend_llist.c \
zend_vm_opcodes.c zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \
zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
diff --git a/Zend/Zend.dsp b/Zend/Zend.dsp
index c1b3f2a9f7..717580c5a3 100644
--- a/Zend/Zend.dsp
+++ b/Zend/Zend.dsp
@@ -143,10 +143,6 @@ SOURCE=.\zend_default_classes.c
# End Source File
# Begin Source File
-SOURCE=.\zend_dynamic_array.c
-# End Source File
-# Begin Source File
-
SOURCE=.\zend_execute.c
# End Source File
# Begin Source File
diff --git a/Zend/ZendTS.dsp b/Zend/ZendTS.dsp
index 4c6ef92465..d452221d3a 100644
--- a/Zend/ZendTS.dsp
+++ b/Zend/ZendTS.dsp
@@ -168,10 +168,6 @@ SOURCE=.\zend_default_classes.c
# End Source File
# Begin Source File
-SOURCE=.\zend_dynamic_array.c
-# End Source File
-# Begin Source File
-
SOURCE=.\zend_exceptions.c
# End Source File
# Begin Source File
diff --git a/Zend/tests/list_destructuring_to_special_variables.phpt b/Zend/tests/list_destructuring_to_special_variables.phpt
new file mode 100644
index 0000000000..4418c967c2
--- /dev/null
+++ b/Zend/tests/list_destructuring_to_special_variables.phpt
@@ -0,0 +1,49 @@
+--TEST--
+list() can be used to destructure to string offsets, __set and ArrayAccess::offsetSet
+--FILE--
+<?php
+
+class Obj {
+ public $values = [];
+ public function __set($name, $value) {
+ $this->values[$name] = $value;
+ }
+}
+
+class Arr implements ArrayAccess {
+ public $values = [];
+ public function offsetSet($name, $value) {
+ $this->values[$name] = $value;
+ }
+ public function offsetGet($name) {}
+ public function offsetExists($name) {}
+ public function offsetUnset($name) {}
+}
+
+$str = 'ab';
+list($str[0], $str[1]) = ['x', 'y'];
+var_dump($str);
+
+$obj = new Obj;
+list($obj->foo, $obj->bar) = ['foo', 'bar'];
+var_dump($obj->values);
+
+$arr = new Arr;
+list($arr['foo'], $arr['bar']) = ['foo', 'bar'];
+var_dump($arr->values);
+
+?>
+--EXPECT--
+string(2) "xy"
+array(2) {
+ ["foo"]=>
+ string(3) "foo"
+ ["bar"]=>
+ string(3) "bar"
+}
+array(2) {
+ ["foo"]=>
+ string(3) "foo"
+ ["bar"]=>
+ string(3) "bar"
+}
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index b88f329eaf..439ae83547 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -2067,6 +2067,17 @@ static void zend_separate_if_call_and_write(znode *node, zend_ast *ast, uint32_t
/* }}} */
void zend_delayed_compile_var(znode *result, zend_ast *ast, uint32_t type TSRMLS_DC);
+void zend_compile_assign(znode *result, zend_ast *ast TSRMLS_DC);
+
+static inline void zend_emit_assign_znode(zend_ast *var_ast, znode *value_node TSRMLS_DC) /* {{{ */
+{
+ znode dummy_node;
+ zend_ast *assign_ast = zend_ast_create(ZEND_AST_ASSIGN, var_ast,
+ zend_ast_create_znode(value_node));
+ zend_compile_assign(&dummy_node, assign_ast TSRMLS_CC);
+ zend_do_free(&dummy_node TSRMLS_CC);
+}
+/* }}} */
static zend_op *zend_delayed_compile_dim(znode *result, zend_ast *ast, uint32_t type TSRMLS_DC) /* {{{ */
{
@@ -2227,7 +2238,7 @@ static void zend_compile_list_assign(znode *result, zend_ast *ast, znode *expr_n
for (i = 0; i < list->children; ++i) {
zend_ast *var_ast = list->child[i];
- znode fetch_result, dim_node, var_node, assign_result;
+ znode fetch_result, dim_node;
zend_op *opline;
if (var_ast == NULL) {
@@ -2246,13 +2257,9 @@ static void zend_compile_list_assign(znode *result, zend_ast *ast, znode *expr_n
opline->extended_value |= ZEND_FETCH_ADD_LOCK;
if (var_ast->kind != ZEND_AST_LIST) {
- if (is_this_fetch(var_ast)) {
- zend_error_noreturn(E_COMPILE_ERROR, "Cannot re-assign $this");
- }
- zend_compile_var(&var_node, var_ast, BP_VAR_W TSRMLS_CC);
- zend_emit_op(&assign_result, ZEND_ASSIGN, &var_node, &fetch_result TSRMLS_CC);
- zend_do_free(&assign_result TSRMLS_CC);
+ zend_emit_assign_znode(var_ast, &fetch_result TSRMLS_CC);
} else {
+ znode assign_result;
zend_compile_list_assign(&assign_result, var_ast, &fetch_result TSRMLS_CC);
zend_do_free(&assign_result TSRMLS_CC);
}
@@ -2357,16 +2364,6 @@ void zend_compile_assign(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
}
/* }}} */
-static inline void zend_emit_assign_znode(zend_ast *var_ast, znode *value_node TSRMLS_DC) /* {{{ */
-{
- znode dummy_node;
- zend_ast *assign_ast = zend_ast_create(ZEND_AST_ASSIGN, var_ast,
- zend_ast_create_znode(value_node));
- zend_compile_assign(&dummy_node, assign_ast TSRMLS_CC);
- zend_do_free(&dummy_node TSRMLS_CC);
-}
-/* }}} */
-
void zend_compile_assign_ref(znode *result, zend_ast *ast TSRMLS_DC) /* {{{ */
{
zend_ast *target_ast = ast->child[0];
diff --git a/Zend/zend_dynamic_array.c b/Zend/zend_dynamic_array.c
deleted file mode 100644
index db81b00a73..0000000000
--- a/Zend/zend_dynamic_array.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- +----------------------------------------------------------------------+
- | Zend Engine |
- +----------------------------------------------------------------------+
- | Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) |
- +----------------------------------------------------------------------+
- | This source file is subject to version 2.00 of the Zend license, |
- | that is bundled with this package in the file LICENSE, and is |
- | available through the world-wide-web at the following url: |
- | http://www.zend.com/license/2_00.txt. |
- | If you did not receive a copy of the Zend license and are unable to |
- | obtain it through the world-wide-web, please send a note to |
- | license@zend.com so we can mail you a copy immediately. |
- +----------------------------------------------------------------------+
- | Authors: Andi Gutmans <andi@zend.com> |
- | Zeev Suraski <zeev@zend.com> |
- +----------------------------------------------------------------------+
-*/
-
-/* $Id$ */
-
-#include "zend.h"
-
-typedef struct _dynamic_array {
- char *array;
- unsigned int element_size;
- unsigned int current;
- unsigned int allocated;
-} dynamic_array;
-
-ZEND_API int zend_dynamic_array_init(dynamic_array *da, unsigned int element_size, unsigned int size)
-{
- da->element_size = element_size;
- da->allocated = size;
- da->current = 0;
- da->array = (char *) emalloc(size*element_size);
- if (da->array == NULL) {
- return 1;
- }
- return 0;
-}
-
-ZEND_API void *zend_dynamic_array_push(dynamic_array *da)
-{
- if (da->current == da->allocated) {
- da->allocated *= 2;
- da->array = (char *) erealloc(da->array, da->allocated*da->element_size);
- }
- return (void *)(da->array+(da->current++)*da->element_size);
-}
-
-ZEND_API void *zend_dynamic_array_pop(dynamic_array *da)
-{
- return (void *)(da->array+(--(da->current))*da->element_size);
-
-}
-
-ZEND_API void *zend_dynamic_array_get_element(dynamic_array *da, unsigned int index)
-{
- if (index >= da->current) {
- return NULL;
- }
- return (void *)(da->array+index*da->element_size);
-}
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * indent-tabs-mode: t
- * End:
- */
diff --git a/Zend/zend_dynamic_array.h b/Zend/zend_dynamic_array.h
deleted file mode 100644
index e69eb18768..0000000000
--- a/Zend/zend_dynamic_array.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- +----------------------------------------------------------------------+
- | Zend Engine |
- +----------------------------------------------------------------------+
- | Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) |
- +----------------------------------------------------------------------+
- | This source file is subject to version 2.00 of the Zend license, |
- | that is bundled with this package in the file LICENSE, and is |
- | available through the world-wide-web at the following url: |
- | http://www.zend.com/license/2_00.txt. |
- | If you did not receive a copy of the Zend license and are unable to |
- | obtain it through the world-wide-web, please send a note to |
- | license@zend.com so we can mail you a copy immediately. |
- +----------------------------------------------------------------------+
- | Authors: Andi Gutmans <andi@zend.com> |
- | Zeev Suraski <zeev@zend.com> |
- +----------------------------------------------------------------------+
-*/
-
-/* $Id$ */
-
-#ifndef ZEND_DYNAMIC_ARRAY_H
-#define ZEND_DYNAMIC_ARRAY_H
-
-typedef struct _dynamic_array {
- char *array;
- unsigned int element_size;
- unsigned int last_used;
- unsigned int allocated;
-} dynamic_array;
-
-BEGIN_EXTERN_C()
-ZEND_API int zend_dynamic_array_init(dynamic_array *da, unsigned int element_size, unsigned int size);
-ZEND_API void *zend_dynamic_array_push(dynamic_array *da);
-ZEND_API void *zend_dynamic_array_pop(dynamic_array *da);
-ZEND_API void *zend_dynamic_array_get_element(dynamic_array *da, unsigned int index);
-END_EXTERN_C()
-
-#endif /* ZEND_DYNAMIC_ARRAY_H */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * indent-tabs-mode: t
- * End:
- */
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 700b986d61..031ba54d69 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -667,17 +667,17 @@ static inline void zend_assign_to_object(zval *retval, zval *object_ptr, zval *p
zval *object = object_ptr;
ZVAL_DEREF(object);
- if (Z_TYPE_P(object) != IS_OBJECT) {
- if (object == &EG(error_zval)) {
+ if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
+ if (UNEXPECTED(object == &EG(error_zval))) {
if (retval) {
ZVAL_NULL(retval);
}
FREE_OP(free_value);
return;
}
- if (Z_TYPE_P(object) == IS_NULL ||
+ if (EXPECTED(Z_TYPE_P(object) == IS_NULL ||
Z_TYPE_P(object) == IS_FALSE ||
- (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0)) {
+ (Z_TYPE_P(object) == IS_STRING && Z_STRLEN_P(object) == 0))) {
zend_object *obj;
zval_ptr_dtor(object);
@@ -1021,7 +1021,7 @@ static zend_always_inline zval *zend_fetch_dimension_address(zval *result, zval
fetch_from_array:
if (dim == NULL) {
retval = zend_hash_next_index_insert(Z_ARRVAL_P(container), &EG(uninitialized_zval));
- if (retval == NULL) {
+ if (UNEXPECTED(retval == NULL)) {
zend_error(E_WARNING, "Cannot add element to the array as the next element is already occupied");
retval = &EG(error_zval);
}
@@ -1030,11 +1030,8 @@ fetch_from_array:
}
if (is_ref) {
ZVAL_MAKE_REF(retval);
- Z_ADDREF_P(retval);
- ZVAL_REF(result, Z_REF_P(retval));
- } else {
- ZVAL_INDIRECT(result, retval);
}
+ ZVAL_INDIRECT(result, retval);
} else if (EXPECTED(Z_TYPE_P(container) == IS_STRING)) {
zend_long offset;
@@ -1100,7 +1097,7 @@ convert_to_array:
ZVAL_NULL(result);
zend_error(E_NOTICE, "Indirect modification of overloaded element of %s has no effect", ce->name->val);
- } else if (retval && Z_TYPE_P(retval) != IS_UNDEF) {
+ } else if (EXPECTED(retval && Z_TYPE_P(retval) != IS_UNDEF)) {
if (!Z_ISREF_P(retval)) {
if (Z_REFCOUNTED_P(retval) &&
Z_REFCOUNT_P(retval) > 1) {
@@ -1121,18 +1118,15 @@ convert_to_array:
if (result != retval) {
if (is_ref) {
ZVAL_MAKE_REF(retval);
- Z_ADDREF_P(retval);
- ZVAL_REF(result, Z_REF_P(retval));
- } else {
- ZVAL_INDIRECT(result, retval);
}
+ ZVAL_INDIRECT(result, retval);
}
} else {
ZVAL_INDIRECT(result, &EG(error_zval));
}
}
} else if (EXPECTED(Z_TYPE_P(container) == IS_NULL)) {
- if (container == &EG(error_zval)) {
+ if (UNEXPECTED(container == &EG(error_zval))) {
ZVAL_INDIRECT(result, &EG(error_zval));
} else if (type != BP_VAR_UNSET) {
goto convert_to_array;
@@ -1276,15 +1270,15 @@ static void zend_fetch_property_address(zval *result, zval *container_ptr, zval
zval *container = container_ptr;
ZVAL_DEREF(container);
- if (Z_TYPE_P(container) != IS_OBJECT) {
- if (container == &EG(error_zval)) {
+ if (UNEXPECTED(Z_TYPE_P(container) != IS_OBJECT)) {
+ if (UNEXPECTED(container == &EG(error_zval))) {
ZVAL_INDIRECT(result, &EG(error_zval));
return;
}
/* this should modify object only if it's empty */
if (type != BP_VAR_UNSET &&
- ((Z_TYPE_P(container) == IS_NULL ||
+ EXPECTED((Z_TYPE_P(container) == IS_NULL ||
Z_TYPE_P(container) == IS_FALSE ||
(Z_TYPE_P(container) == IS_STRING && Z_STRLEN_P(container)==0)))) {
zval_ptr_dtor_nogc(container);
@@ -1296,7 +1290,7 @@ static void zend_fetch_property_address(zval *result, zval *container_ptr, zval
}
}
- if (Z_OBJ_HT_P(container)->get_property_ptr_ptr) {
+ 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) {
if (Z_OBJ_HT_P(container)->read_property &&
@@ -1304,11 +1298,8 @@ static void zend_fetch_property_address(zval *result, zval *container_ptr, zval
if (ptr != result) {
if (is_ref && ptr != &EG(uninitialized_zval)) {
ZVAL_MAKE_REF(ptr);
- Z_ADDREF_P(ptr);
- ZVAL_REF(result, Z_REF_P(ptr));
- } else {
- ZVAL_INDIRECT(result, ptr);
}
+ ZVAL_INDIRECT(result, ptr);
}
} else {
zend_error_noreturn(E_ERROR, "Cannot access undefined property for object with overloaded property access");
@@ -1316,22 +1307,16 @@ static void zend_fetch_property_address(zval *result, zval *container_ptr, zval
} else {
if (is_ref) {
ZVAL_MAKE_REF(ptr);
- Z_ADDREF_P(ptr);
- ZVAL_REF(result, Z_REF_P(ptr));
- } else {
- ZVAL_INDIRECT(result, ptr);
}
+ ZVAL_INDIRECT(result, ptr);
}
- } else if (Z_OBJ_HT_P(container)->read_property) {
+ } else if (EXPECTED(Z_OBJ_HT_P(container)->read_property)) {
zval *ptr = Z_OBJ_HT_P(container)->read_property(container, prop_ptr, type, cache_slot, result TSRMLS_CC);
if (ptr != result) {
if (is_ref && ptr != &EG(uninitialized_zval)) {
ZVAL_MAKE_REF(ptr);
- Z_ADDREF_P(ptr);
- ZVAL_REF(result, Z_REF_P(ptr));
- } else {
- ZVAL_INDIRECT(result, ptr);
}
+ ZVAL_INDIRECT(result, ptr);
}
} else {
zend_error(E_WARNING, "This object doesn't support property references");
diff --git a/Zend/zend_static_allocator.c b/Zend/zend_static_allocator.c
deleted file mode 100644
index 049d29f6a2..0000000000
--- a/Zend/zend_static_allocator.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- +----------------------------------------------------------------------+
- | Zend Engine |
- +----------------------------------------------------------------------+
- | Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) |
- +----------------------------------------------------------------------+
- | This source file is subject to version 2.00 of the Zend license, |
- | that is bundled with this package in the file LICENSE, and is |
- | available through the world-wide-web at the following url: |
- | http://www.zend.com/license/2_00.txt. |
- | If you did not receive a copy of the Zend license and are unable to |
- | obtain it through the world-wide-web, please send a note to |
- | license@zend.com so we can mail you a copy immediately. |
- +----------------------------------------------------------------------+
- | Authors: Andi Gutmans <andi@zend.com> |
- +----------------------------------------------------------------------+
-*/
-
-/* $Id$ */
-
-#include "zend_static_allocator.h"
-
-/* Not checking emalloc() and erealloc() return values as they are supposed to bailout */
-
-inline static void block_init(Block *block, uint32_t block_size)
-{
- block->pos = block->bp = (char *) emalloc(block_size);
- block->end = block->bp + block_size;
-}
-
-inline static char *block_allocate(Block *block, uint32_t size)
-{
- char *retval = block->pos;
- if ((block->pos += size) >= block->end) {
- return (char *)NULL;
- }
- return retval;
-}
-
-inline static void block_destroy(Block *block)
-{
- efree(block->bp);
-}
-
-void static_allocator_init(StaticAllocator *sa)
-{
- sa->Blocks = (Block *) emalloc(sizeof(Block));
- block_init(sa->Blocks, ALLOCATOR_BLOCK_SIZE);
- sa->num_blocks = 1;
- sa->current_block = 0;
-}
-
-char *static_allocator_allocate(StaticAllocator *sa, uint32_t size)
-{
- char *retval;
-
- retval = block_allocate(&sa->Blocks[sa->current_block], size);
- if (retval) {
- return retval;
- }
- sa->Blocks = (Block *) erealloc(sa->Blocks, ++sa->num_blocks);
- sa->current_block++;
- block_init(&sa->Blocks[sa->current_block], (size > ALLOCATOR_BLOCK_SIZE) ? size : ALLOCATOR_BLOCK_SIZE);
- retval = block_allocate(&sa->Blocks[sa->current_block], size);
- return retval;
-}
-
-void static_allocator_destroy(StaticAllocator *sa)
-{
- uint32_t i;
-
- for (i=0; i<sa->num_blocks; i++) {
- block_free(&sa->Blocks[i]);
- }
- efree(sa->Blocks);
-}
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * indent-tabs-mode: t
- * End:
- */
diff --git a/Zend/zend_static_allocator.h b/Zend/zend_static_allocator.h
deleted file mode 100644
index cd9b0ff583..0000000000
--- a/Zend/zend_static_allocator.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- +----------------------------------------------------------------------+
- | Zend Engine |
- +----------------------------------------------------------------------+
- | Copyright (c) 1998-2014 Zend Technologies Ltd. (http://www.zend.com) |
- +----------------------------------------------------------------------+
- | This source file is subject to version 2.00 of the Zend license, |
- | that is bundled with this package in the file LICENSE, and is |
- | available through the world-wide-web at the following url: |
- | http://www.zend.com/license/2_00.txt. |
- | If you did not receive a copy of the Zend license and are unable to |
- | obtain it through the world-wide-web, please send a note to |
- | license@zend.com so we can mail you a copy immediately. |
- +----------------------------------------------------------------------+
- | Authors: Andi Gutmans <andi@zend.com> |
- +----------------------------------------------------------------------+
-*/
-
-/* $Id$ */
-
-#ifndef ZEND_STATIC_ALLOCATOR_H
-#define ZEND_STATIC_ALLOCATOR_H
-
-#define ALLOCATOR_BLOCK_SIZE 400000
-
-/* Temporary */
-typedef unsigned int uint32_t;
-#define emalloc(s) malloc(s)
-#define efree(p) free(p)
-
-typedef struct _Block {
- char *bp;
- char *pos;
- char *end;
-} Block;
-
-typedef struct _StaticAllocator {
- Block *Blocks;
- uint32_t num_blocks;
- uint32_t current_block;
-} StaticAllocator;
-
-void static_allocator_init(StaticAllocator *sa);
-char *static_allocator_allocate(StaticAllocator *sa, uint32_t size);
-void static_allocator_destroy(StaticAllocator *sa);
-
-#endif /* ZEND_STATIC_ALLOCATOR_H */
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * indent-tabs-mode: t
- * End:
- */
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index cc16072c5b..b25ab4e8be 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -1683,7 +1683,7 @@ ZEND_VM_HANDLER(38, ZEND_ASSIGN, VAR|CV, CONST|TMP|VAR|CV)
variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
if (OP1_TYPE == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
- if (IS_OP2_TMP_FREE()) {
+ if (OP2_TYPE == IS_TMP_VAR) {
zval_dtor(value);
}
if (RETURN_VALUE_USED(opline)) {
@@ -2826,7 +2826,7 @@ ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY)
zval_copy_ctor_func(EX(return_value));
}
}
- } else if (Z_ISREF_P(retval_ptr)) {
+ } else if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) && Z_ISREF_P(retval_ptr)) {
ZVAL_COPY(EX(return_value), Z_REFVAL_P(retval_ptr));
FREE_OP1_IF_VAR();
} else {
@@ -2879,9 +2879,8 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY)
} else {
zend_error(E_NOTICE, "Only variable references should be returned by reference");
if (EX(return_value)) {
- zval tmp;
- ZVAL_DUP(&tmp, retval_ptr);
- ZVAL_NEW_REF(EX(return_value), &tmp);
+ ZVAL_NEW_REF(EX(return_value), retval_ptr);
+ if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr);
}
break;
}
@@ -3040,7 +3039,7 @@ ZEND_VM_HANDLER(117, ZEND_SEND_VAR, VAR|CV, ANY)
varptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
EX(call)->num_args = opline->op2.num;
- if (Z_ISREF_P(varptr)) {
+ if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) && Z_ISREF_P(varptr)) {
ZVAL_COPY(arg, Z_REFVAL_P(varptr));
FREE_OP1();
} else {
@@ -3145,7 +3144,7 @@ ZEND_VM_HANDLER(66, ZEND_SEND_VAR_EX, VAR|CV, ANY)
varptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
EX(call)->num_args = opline->op2.num;
- if (Z_ISREF_P(varptr)) {
+ if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) && Z_ISREF_P(varptr)) {
ZVAL_COPY(arg, Z_REFVAL_P(varptr));
FREE_OP1();
} else {
@@ -3911,7 +3910,7 @@ ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMP|VAR|UNUS
FREE_OP1_VAR_PTR();
} else {
expr_ptr = GET_OP1_ZVAL_PTR(BP_VAR_R);
- if (IS_OP1_TMP_FREE()) { /* temporary variable */
+ if (OP1_TYPE == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&new_expr, expr_ptr);
expr_ptr = &new_expr;
} else if (OP1_TYPE == IS_CONST) {
@@ -3919,9 +3918,9 @@ ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMP|VAR|UNUS
ZVAL_DUP(&new_expr, expr_ptr);
expr_ptr = &new_expr;
}
- } else if (Z_ISREF_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
- expr_ptr = &new_expr;
+ } else if ((OP1_TYPE == IS_CV || OP1_TYPE == 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);
FREE_OP1_IF_VAR();
} else if (OP1_TYPE == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
@@ -4085,7 +4084,7 @@ ZEND_VM_HANDLER(21, ZEND_CAST, CONST|TMP|VAR|CV, ANY)
}
} else {
ZVAL_COPY_VALUE(result, expr);
- if (!IS_OP1_TMP_FREE()) {
+ if (OP1_TYPE != IS_TMP_VAR) {
zval_opt_copy_ctor(result);
}
convert_to_array(result);
@@ -4105,7 +4104,7 @@ ZEND_VM_HANDLER(21, ZEND_CAST, CONST|TMP|VAR|CV, ANY)
}
} else {
ZVAL_COPY_VALUE(result, expr);
- if (!IS_OP1_TMP_FREE()) {
+ if (OP1_TYPE != IS_TMP_VAR) {
zval_opt_copy_ctor(result);
}
convert_to_object(result);
@@ -4251,29 +4250,37 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
zval tmp, *varname;
HashTable *target_symbol_table;
zend_free_op free_op1;
- zend_bool tmp_is_dup = 0;
SAVE_OPLINE();
if (OP1_TYPE == IS_CV &&
OP2_TYPE == IS_UNUSED &&
(opline->extended_value & ZEND_QUICK_SET)) {
- ZVAL_COPY_VALUE(&tmp, EX_VAR(opline->op1.var));
- ZVAL_UNDEF(EX_VAR(opline->op1.var));
- zval_ptr_dtor(&tmp);
+ zval *var = EX_VAR(opline->op1.var);
+
+ if (Z_REFCOUNTED_P(var)) {
+ zend_refcounted *garbage = Z_COUNTED_P(var);
+
+ if (!--GC_REFCOUNT(garbage)) {
+ ZVAL_UNDEF(var);
+ _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC);
+ } else {
+ GC_ZVAL_CHECK_POSSIBLE_ROOT(var);
+ ZVAL_UNDEF(var);
+ }
+ } else {
+ ZVAL_UNDEF(var);
+ }
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
varname = GET_OP1_ZVAL_PTR(BP_VAR_R);
+ ZVAL_UNDEF(&tmp);
if (OP1_TYPE != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_DUP(&tmp, varname);
convert_to_string(&tmp);
varname = &tmp;
- tmp_is_dup = 1;
- } else if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) {
- ZVAL_COPY(&tmp, varname);
- varname = &tmp;
}
if (OP2_TYPE != IS_UNUSED) {
@@ -4285,10 +4292,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 && tmp_is_dup) {
+ if (OP1_TYPE != IS_CONST) {
zval_dtor(&tmp);
- } else if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) {
- zval_ptr_dtor(&tmp);
}
FREE_OP1();
HANDLE_EXCEPTION();
@@ -4307,10 +4312,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 && tmp_is_dup) {
+ if (OP1_TYPE != IS_CONST) {
zval_dtor(&tmp);
- } else if (OP1_TYPE == IS_VAR || OP1_TYPE == IS_CV) {
- zval_ptr_dtor(&tmp);
}
FREE_OP1();
CHECK_EXCEPTION();
@@ -4351,12 +4354,9 @@ ZEND_VM_C_LABEL(num_index_dim):
zend_hash_index_del(ht, hval);
break;
case IS_STRING:
- if (OP2_TYPE == IS_CV || OP2_TYPE == IS_VAR) {
- if (Z_REFCOUNTED_P(offset)) Z_ADDREF_P(offset);
- }
if (OP2_TYPE != IS_CONST) {
if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) {
- ZEND_VM_C_GOTO(numeric_index_dim);
+ ZEND_VM_C_GOTO(num_index_dim);
}
}
if (ht == &EG(symbol_table).ht) {
@@ -4364,15 +4364,6 @@ ZEND_VM_C_LABEL(num_index_dim):
} else {
zend_hash_del(ht, Z_STR_P(offset));
}
- if (OP2_TYPE == IS_CV || OP2_TYPE == IS_VAR) {
- zval_ptr_dtor(offset);
- }
- break;
-ZEND_VM_C_LABEL(numeric_index_dim):
- zend_hash_index_del(ht, hval);
- if (OP2_TYPE == IS_CV || OP2_TYPE == IS_VAR) {
- zval_ptr_dtor(offset);
- }
break;
case IS_NULL:
zend_hash_del(ht, STR_EMPTY_ALLOC());
@@ -4487,7 +4478,7 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
} else {
array_ptr = array_ref = GET_OP1_ZVAL_PTR(BP_VAR_R);
ZVAL_DEREF(array_ptr);
- if (IS_OP1_TMP_FREE()) { /* IS_TMP_VAR */
+ if (OP1_TYPE == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&tmp, array_ptr);
array_ptr = &tmp;
if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
@@ -5695,7 +5686,7 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE
if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
- if (!IS_OP1_TMP_FREE()) {
+ if (OP1_TYPE != IS_TMP_VAR) {
zval_copy_ctor(&generator->value);
}
} else {
@@ -5726,14 +5717,14 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE
ZVAL_DUP(&generator->value, value);
} else if (OP1_TYPE == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if (Z_ISREF_P(value)) {
+ } else if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) && Z_ISREF_P(value)) {
ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
FREE_OP1_IF_VAR();
} else {
+ ZVAL_COPY_VALUE(&generator->value, value);
if (OP1_TYPE == IS_CV) {
- if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+ if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
- ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
@@ -5751,14 +5742,14 @@ ZEND_VM_HANDLER(160, ZEND_YIELD, CONST|TMP|VAR|CV|UNUSED, CONST|TMP|VAR|CV|UNUSE
ZVAL_DUP(&generator->key, key);
} else if (OP2_TYPE == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if (Z_ISREF_P(key)) {
+ } else if ((OP2_TYPE == IS_VAR || OP2_TYPE == IS_CV) && Z_ISREF_P(key)) {
ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
FREE_OP2_IF_VAR();
} else {
+ ZVAL_COPY_VALUE(&generator->key, key);
if (OP2_TYPE == IS_CV) {
- if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+ if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
}
- ZVAL_COPY_VALUE(&generator->key, key);
}
if (Z_TYPE(generator->key) == IS_LONG
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 84fc8f9b23..467dd4f168 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -2610,7 +2610,7 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
zval_copy_ctor_func(EX(return_value));
}
}
- } else if (Z_ISREF_P(retval_ptr)) {
+ } else if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && Z_ISREF_P(retval_ptr)) {
ZVAL_COPY(EX(return_value), Z_REFVAL_P(retval_ptr));
} else {
@@ -2663,9 +2663,8 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER(ZEND_OPCODE_HAND
} else {
zend_error(E_NOTICE, "Only variable references should be returned by reference");
if (EX(return_value)) {
- zval tmp;
- ZVAL_DUP(&tmp, retval_ptr);
- ZVAL_NEW_REF(EX(return_value), &tmp);
+ ZVAL_NEW_REF(EX(return_value), retval_ptr);
+ if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr);
}
break;
}
@@ -2893,7 +2892,7 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
}
} else {
ZVAL_COPY_VALUE(result, expr);
- if (!0) {
+ if (IS_CONST != IS_TMP_VAR) {
zval_opt_copy_ctor(result);
}
convert_to_array(result);
@@ -2913,7 +2912,7 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
}
} else {
ZVAL_COPY_VALUE(result, expr);
- if (!0) {
+ if (IS_CONST != IS_TMP_VAR) {
zval_opt_copy_ctor(result);
}
convert_to_object(result);
@@ -3092,7 +3091,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
} else {
array_ptr = array_ref = opline->op1.zv;
ZVAL_DEREF(array_ptr);
- if (0) { /* IS_TMP_VAR */
+ if (IS_CONST == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&tmp, array_ptr);
array_ptr = &tmp;
if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
@@ -4333,7 +4332,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(ZEND_O
} else {
expr_ptr = opline->op1.zv;
- if (0) { /* temporary variable */
+ if (IS_CONST == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&new_expr, expr_ptr);
expr_ptr = &new_expr;
} else if (IS_CONST == IS_CONST) {
@@ -4341,9 +4340,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(ZEND_O
ZVAL_DUP(&new_expr, expr_ptr);
expr_ptr = &new_expr;
}
- } else if (Z_ISREF_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
- expr_ptr = &new_expr;
+ } else if ((IS_CONST == IS_CV || IS_CONST == 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);
} else if (IS_CONST == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
@@ -4440,29 +4439,37 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HA
zval tmp, *varname;
HashTable *target_symbol_table;
- zend_bool tmp_is_dup = 0;
SAVE_OPLINE();
if (IS_CONST == IS_CV &&
IS_CONST == IS_UNUSED &&
(opline->extended_value & ZEND_QUICK_SET)) {
- ZVAL_COPY_VALUE(&tmp, EX_VAR(opline->op1.var));
- ZVAL_UNDEF(EX_VAR(opline->op1.var));
- zval_ptr_dtor(&tmp);
+ zval *var = EX_VAR(opline->op1.var);
+
+ if (Z_REFCOUNTED_P(var)) {
+ zend_refcounted *garbage = Z_COUNTED_P(var);
+
+ if (!--GC_REFCOUNT(garbage)) {
+ ZVAL_UNDEF(var);
+ _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC);
+ } else {
+ GC_ZVAL_CHECK_POSSIBLE_ROOT(var);
+ ZVAL_UNDEF(var);
+ }
+ } else {
+ ZVAL_UNDEF(var);
+ }
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
varname = opline->op1.zv;
+ ZVAL_UNDEF(&tmp);
if (IS_CONST != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_DUP(&tmp, varname);
convert_to_string(&tmp);
varname = &tmp;
- tmp_is_dup = 1;
- } else if (IS_CONST == IS_VAR || IS_CONST == IS_CV) {
- ZVAL_COPY(&tmp, varname);
- varname = &tmp;
}
if (IS_CONST != IS_UNUSED) {
@@ -4474,10 +4481,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 && tmp_is_dup) {
+ if (IS_CONST != IS_CONST) {
zval_dtor(&tmp);
- } else if (IS_CONST == IS_VAR || IS_CONST == IS_CV) {
- zval_ptr_dtor(&tmp);
}
HANDLE_EXCEPTION();
@@ -4496,10 +4501,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 && tmp_is_dup) {
+ if (IS_CONST != IS_CONST) {
zval_dtor(&tmp);
- } else if (IS_CONST == IS_VAR || IS_CONST == IS_CV) {
- zval_ptr_dtor(&tmp);
}
CHECK_EXCEPTION();
@@ -4798,7 +4801,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLE
if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
- if (!0) {
+ if (IS_CONST != IS_TMP_VAR) {
zval_copy_ctor(&generator->value);
}
} else {
@@ -4828,14 +4831,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLE
ZVAL_DUP(&generator->value, value);
} else if (IS_CONST == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if (Z_ISREF_P(value)) {
+ } else if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && Z_ISREF_P(value)) {
ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
} else {
+ ZVAL_COPY_VALUE(&generator->value, value);
if (IS_CONST == IS_CV) {
- if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+ if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
- ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
@@ -4853,14 +4856,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLE
ZVAL_DUP(&generator->key, key);
} else if (IS_CONST == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if (Z_ISREF_P(key)) {
+ } else if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && Z_ISREF_P(key)) {
ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
} else {
+ ZVAL_COPY_VALUE(&generator->key, key);
if (IS_CONST == IS_CV) {
- if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+ if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
}
- ZVAL_COPY_VALUE(&generator->key, key);
}
if (Z_TYPE(generator->key) == IS_LONG
@@ -5546,7 +5549,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_HANDLER(ZEND_OPC
} else {
expr_ptr = opline->op1.zv;
- if (0) { /* temporary variable */
+ if (IS_CONST == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&new_expr, expr_ptr);
expr_ptr = &new_expr;
} else if (IS_CONST == IS_CONST) {
@@ -5554,9 +5557,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_HANDLER(ZEND_OPC
ZVAL_DUP(&new_expr, expr_ptr);
expr_ptr = &new_expr;
}
- } else if (Z_ISREF_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
- expr_ptr = &new_expr;
+ } else if ((IS_CONST == IS_CV || IS_CONST == 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);
} else if (IS_CONST == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
@@ -5828,7 +5831,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_
if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
- if (!0) {
+ if (IS_CONST != IS_TMP_VAR) {
zval_copy_ctor(&generator->value);
}
} else {
@@ -5858,14 +5861,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_
ZVAL_DUP(&generator->value, value);
} else if (IS_CONST == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if (Z_ISREF_P(value)) {
+ } else if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && Z_ISREF_P(value)) {
ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
} else {
+ ZVAL_COPY_VALUE(&generator->value, value);
if (IS_CONST == IS_CV) {
- if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+ if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
- ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
@@ -5883,14 +5886,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_TMP_HANDLER(ZEND_OPCODE_HANDLER_
ZVAL_DUP(&generator->key, key);
} else if (IS_TMP_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if (Z_ISREF_P(key)) {
+ } else if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && Z_ISREF_P(key)) {
ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
} else {
+ ZVAL_COPY_VALUE(&generator->key, key);
if (IS_TMP_VAR == IS_CV) {
- if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+ if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
}
- ZVAL_COPY_VALUE(&generator->key, key);
}
if (Z_TYPE(generator->key) == IS_LONG
@@ -6727,7 +6730,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_VAR_HANDLER(ZEND_OPC
} else {
expr_ptr = opline->op1.zv;
- if (0) { /* temporary variable */
+ if (IS_CONST == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&new_expr, expr_ptr);
expr_ptr = &new_expr;
} else if (IS_CONST == IS_CONST) {
@@ -6735,9 +6738,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_VAR_HANDLER(ZEND_OPC
ZVAL_DUP(&new_expr, expr_ptr);
expr_ptr = &new_expr;
}
- } else if (Z_ISREF_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
- expr_ptr = &new_expr;
+ } else if ((IS_CONST == IS_CV || IS_CONST == 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);
} else if (IS_CONST == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
@@ -6834,29 +6837,37 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HAND
zval tmp, *varname;
HashTable *target_symbol_table;
- zend_bool tmp_is_dup = 0;
SAVE_OPLINE();
if (IS_CONST == IS_CV &&
IS_VAR == IS_UNUSED &&
(opline->extended_value & ZEND_QUICK_SET)) {
- ZVAL_COPY_VALUE(&tmp, EX_VAR(opline->op1.var));
- ZVAL_UNDEF(EX_VAR(opline->op1.var));
- zval_ptr_dtor(&tmp);
+ zval *var = EX_VAR(opline->op1.var);
+
+ if (Z_REFCOUNTED_P(var)) {
+ zend_refcounted *garbage = Z_COUNTED_P(var);
+
+ if (!--GC_REFCOUNT(garbage)) {
+ ZVAL_UNDEF(var);
+ _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC);
+ } else {
+ GC_ZVAL_CHECK_POSSIBLE_ROOT(var);
+ ZVAL_UNDEF(var);
+ }
+ } else {
+ ZVAL_UNDEF(var);
+ }
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
varname = opline->op1.zv;
+ ZVAL_UNDEF(&tmp);
if (IS_CONST != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_DUP(&tmp, varname);
convert_to_string(&tmp);
varname = &tmp;
- tmp_is_dup = 1;
- } else if (IS_CONST == IS_VAR || IS_CONST == IS_CV) {
- ZVAL_COPY(&tmp, varname);
- varname = &tmp;
}
if (IS_VAR != IS_UNUSED) {
@@ -6868,10 +6879,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 && tmp_is_dup) {
+ if (IS_CONST != IS_CONST) {
zval_dtor(&tmp);
- } else if (IS_CONST == IS_VAR || IS_CONST == IS_CV) {
- zval_ptr_dtor(&tmp);
}
HANDLE_EXCEPTION();
@@ -6890,10 +6899,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 && tmp_is_dup) {
+ if (IS_CONST != IS_CONST) {
zval_dtor(&tmp);
- } else if (IS_CONST == IS_VAR || IS_CONST == IS_CV) {
- zval_ptr_dtor(&tmp);
}
CHECK_EXCEPTION();
@@ -7161,7 +7168,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_
if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
- if (!0) {
+ if (IS_CONST != IS_TMP_VAR) {
zval_copy_ctor(&generator->value);
}
} else {
@@ -7191,14 +7198,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_
ZVAL_DUP(&generator->value, value);
} else if (IS_CONST == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if (Z_ISREF_P(value)) {
+ } else if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && Z_ISREF_P(value)) {
ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
} else {
+ ZVAL_COPY_VALUE(&generator->value, value);
if (IS_CONST == IS_CV) {
- if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+ if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
- ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
@@ -7216,14 +7223,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HANDLER_
ZVAL_DUP(&generator->key, key);
} else if (IS_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if (Z_ISREF_P(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);
} else {
+ ZVAL_COPY_VALUE(&generator->key, key);
if (IS_VAR == IS_CV) {
- if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+ if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
}
- ZVAL_COPY_VALUE(&generator->key, key);
}
if (Z_TYPE(generator->key) == IS_LONG
@@ -7592,7 +7599,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(ZEND_
} else {
expr_ptr = opline->op1.zv;
- if (0) { /* temporary variable */
+ if (IS_CONST == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&new_expr, expr_ptr);
expr_ptr = &new_expr;
} else if (IS_CONST == IS_CONST) {
@@ -7600,9 +7607,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(ZEND_
ZVAL_DUP(&new_expr, expr_ptr);
expr_ptr = &new_expr;
}
- } else if (Z_ISREF_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
- expr_ptr = &new_expr;
+ } else if ((IS_CONST == IS_CV || IS_CONST == 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);
} else if (IS_CONST == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
@@ -7699,29 +7706,37 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_H
zval tmp, *varname;
HashTable *target_symbol_table;
- zend_bool tmp_is_dup = 0;
SAVE_OPLINE();
if (IS_CONST == IS_CV &&
IS_UNUSED == IS_UNUSED &&
(opline->extended_value & ZEND_QUICK_SET)) {
- ZVAL_COPY_VALUE(&tmp, EX_VAR(opline->op1.var));
- ZVAL_UNDEF(EX_VAR(opline->op1.var));
- zval_ptr_dtor(&tmp);
+ zval *var = EX_VAR(opline->op1.var);
+
+ if (Z_REFCOUNTED_P(var)) {
+ zend_refcounted *garbage = Z_COUNTED_P(var);
+
+ if (!--GC_REFCOUNT(garbage)) {
+ ZVAL_UNDEF(var);
+ _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC);
+ } else {
+ GC_ZVAL_CHECK_POSSIBLE_ROOT(var);
+ ZVAL_UNDEF(var);
+ }
+ } else {
+ ZVAL_UNDEF(var);
+ }
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
varname = opline->op1.zv;
+ ZVAL_UNDEF(&tmp);
if (IS_CONST != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_DUP(&tmp, varname);
convert_to_string(&tmp);
varname = &tmp;
- tmp_is_dup = 1;
- } else if (IS_CONST == IS_VAR || IS_CONST == IS_CV) {
- ZVAL_COPY(&tmp, varname);
- varname = &tmp;
}
if (IS_UNUSED != IS_UNUSED) {
@@ -7733,10 +7748,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 && tmp_is_dup) {
+ if (IS_CONST != IS_CONST) {
zval_dtor(&tmp);
- } else if (IS_CONST == IS_VAR || IS_CONST == IS_CV) {
- zval_ptr_dtor(&tmp);
}
HANDLE_EXCEPTION();
@@ -7755,10 +7768,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 && tmp_is_dup) {
+ if (IS_CONST != IS_CONST) {
zval_dtor(&tmp);
- } else if (IS_CONST == IS_VAR || IS_CONST == IS_CV) {
- zval_ptr_dtor(&tmp);
}
CHECK_EXCEPTION();
@@ -7904,7 +7915,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDL
if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
- if (!0) {
+ if (IS_CONST != IS_TMP_VAR) {
zval_copy_ctor(&generator->value);
}
} else {
@@ -7934,14 +7945,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDL
ZVAL_DUP(&generator->value, value);
} else if (IS_CONST == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if (Z_ISREF_P(value)) {
+ } else if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && Z_ISREF_P(value)) {
ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
} else {
+ ZVAL_COPY_VALUE(&generator->value, value);
if (IS_CONST == IS_CV) {
- if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+ if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
- ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
@@ -7959,14 +7970,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDL
ZVAL_DUP(&generator->key, key);
} else if (IS_UNUSED == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if (Z_ISREF_P(key)) {
+ } else if ((IS_UNUSED == IS_VAR || IS_UNUSED == IS_CV) && Z_ISREF_P(key)) {
ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
} else {
+ ZVAL_COPY_VALUE(&generator->key, key);
if (IS_UNUSED == IS_CV) {
- if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+ if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
}
- ZVAL_COPY_VALUE(&generator->key, key);
}
if (Z_TYPE(generator->key) == IS_LONG
@@ -8686,7 +8697,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(ZEND_OPCO
} else {
expr_ptr = opline->op1.zv;
- if (0) { /* temporary variable */
+ if (IS_CONST == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&new_expr, expr_ptr);
expr_ptr = &new_expr;
} else if (IS_CONST == IS_CONST) {
@@ -8694,9 +8705,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(ZEND_OPCO
ZVAL_DUP(&new_expr, expr_ptr);
expr_ptr = &new_expr;
}
- } else if (Z_ISREF_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
- expr_ptr = &new_expr;
+ } else if ((IS_CONST == IS_CV || IS_CONST == 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);
} else if (IS_CONST == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
@@ -8966,7 +8977,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_A
if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
- if (!0) {
+ if (IS_CONST != IS_TMP_VAR) {
zval_copy_ctor(&generator->value);
}
} else {
@@ -8996,14 +9007,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_A
ZVAL_DUP(&generator->value, value);
} else if (IS_CONST == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if (Z_ISREF_P(value)) {
+ } else if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && Z_ISREF_P(value)) {
ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
} else {
+ ZVAL_COPY_VALUE(&generator->value, value);
if (IS_CONST == IS_CV) {
- if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+ if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
- ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
@@ -9021,14 +9032,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_A
ZVAL_DUP(&generator->key, key);
} else if (IS_CV == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if (Z_ISREF_P(key)) {
+ } else if ((IS_CV == IS_VAR || IS_CV == IS_CV) && Z_ISREF_P(key)) {
ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
} else {
+ ZVAL_COPY_VALUE(&generator->key, key);
if (IS_CV == IS_CV) {
- if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+ if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
}
- ZVAL_COPY_VALUE(&generator->key, key);
}
if (Z_TYPE(generator->key) == IS_LONG
@@ -9322,7 +9333,7 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zval_copy_ctor_func(EX(return_value));
}
}
- } else if (Z_ISREF_P(retval_ptr)) {
+ } else if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && Z_ISREF_P(retval_ptr)) {
ZVAL_COPY(EX(return_value), Z_REFVAL_P(retval_ptr));
} else {
@@ -9375,9 +9386,8 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLE
} else {
zend_error(E_NOTICE, "Only variable references should be returned by reference");
if (EX(return_value)) {
- zval tmp;
- ZVAL_DUP(&tmp, retval_ptr);
- ZVAL_NEW_REF(EX(return_value), &tmp);
+ ZVAL_NEW_REF(EX(return_value), retval_ptr);
+ if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr);
}
break;
}
@@ -9607,7 +9617,7 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
}
} else {
ZVAL_COPY_VALUE(result, expr);
- if (!1) {
+ if (IS_TMP_VAR != IS_TMP_VAR) {
zval_opt_copy_ctor(result);
}
convert_to_array(result);
@@ -9627,7 +9637,7 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
}
} else {
ZVAL_COPY_VALUE(result, expr);
- if (!1) {
+ if (IS_TMP_VAR != IS_TMP_VAR) {
zval_opt_copy_ctor(result);
}
convert_to_object(result);
@@ -9806,7 +9816,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
} else {
array_ptr = array_ref = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
ZVAL_DEREF(array_ptr);
- if (1) { /* IS_TMP_VAR */
+ if (IS_TMP_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&tmp, array_ptr);
array_ptr = &tmp;
if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
@@ -10921,7 +10931,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPC
} else {
expr_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (1) { /* temporary variable */
+ if (IS_TMP_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&new_expr, expr_ptr);
expr_ptr = &new_expr;
} else if (IS_TMP_VAR == IS_CONST) {
@@ -10929,9 +10939,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPC
ZVAL_DUP(&new_expr, expr_ptr);
expr_ptr = &new_expr;
}
- } else if (Z_ISREF_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
- expr_ptr = &new_expr;
+ } else if ((IS_TMP_VAR == IS_CV || IS_TMP_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);
} else if (IS_TMP_VAR == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
@@ -11028,29 +11038,37 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HAND
zval tmp, *varname;
HashTable *target_symbol_table;
zend_free_op free_op1;
- zend_bool tmp_is_dup = 0;
SAVE_OPLINE();
if (IS_TMP_VAR == IS_CV &&
IS_CONST == IS_UNUSED &&
(opline->extended_value & ZEND_QUICK_SET)) {
- ZVAL_COPY_VALUE(&tmp, EX_VAR(opline->op1.var));
- ZVAL_UNDEF(EX_VAR(opline->op1.var));
- zval_ptr_dtor(&tmp);
+ zval *var = EX_VAR(opline->op1.var);
+
+ if (Z_REFCOUNTED_P(var)) {
+ zend_refcounted *garbage = Z_COUNTED_P(var);
+
+ if (!--GC_REFCOUNT(garbage)) {
+ ZVAL_UNDEF(var);
+ _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC);
+ } else {
+ GC_ZVAL_CHECK_POSSIBLE_ROOT(var);
+ ZVAL_UNDEF(var);
+ }
+ } else {
+ ZVAL_UNDEF(var);
+ }
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ ZVAL_UNDEF(&tmp);
if (IS_TMP_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_DUP(&tmp, varname);
convert_to_string(&tmp);
varname = &tmp;
- tmp_is_dup = 1;
- } else if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
- ZVAL_COPY(&tmp, varname);
- varname = &tmp;
}
if (IS_CONST != IS_UNUSED) {
@@ -11062,10 +11080,8 @@ 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 && tmp_is_dup) {
+ if (IS_TMP_VAR != IS_CONST) {
zval_dtor(&tmp);
- } else if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
- zval_ptr_dtor(&tmp);
}
zval_dtor(free_op1.var);
HANDLE_EXCEPTION();
@@ -11084,10 +11100,8 @@ 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 && tmp_is_dup) {
+ if (IS_TMP_VAR != IS_CONST) {
zval_dtor(&tmp);
- } else if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
- zval_ptr_dtor(&tmp);
}
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -11353,7 +11367,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_
if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
- if (!1) {
+ if (IS_TMP_VAR != IS_TMP_VAR) {
zval_copy_ctor(&generator->value);
}
} else {
@@ -11383,14 +11397,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_
ZVAL_DUP(&generator->value, value);
} else if (IS_TMP_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if (Z_ISREF_P(value)) {
+ } else if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && Z_ISREF_P(value)) {
ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
} else {
+ ZVAL_COPY_VALUE(&generator->value, value);
if (IS_TMP_VAR == IS_CV) {
- if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+ if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
- ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
@@ -11408,14 +11422,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HANDLER_
ZVAL_DUP(&generator->key, key);
} else if (IS_CONST == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if (Z_ISREF_P(key)) {
+ } else if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && Z_ISREF_P(key)) {
ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
} else {
+ ZVAL_COPY_VALUE(&generator->key, key);
if (IS_CONST == IS_CV) {
- if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+ if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
}
- ZVAL_COPY_VALUE(&generator->key, key);
}
if (Z_TYPE(generator->key) == IS_LONG
@@ -12058,7 +12072,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_HANDLER(ZEND_OPCOD
} else {
expr_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (1) { /* temporary variable */
+ if (IS_TMP_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&new_expr, expr_ptr);
expr_ptr = &new_expr;
} else if (IS_TMP_VAR == IS_CONST) {
@@ -12066,9 +12080,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_HANDLER(ZEND_OPCOD
ZVAL_DUP(&new_expr, expr_ptr);
expr_ptr = &new_expr;
}
- } else if (Z_ISREF_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
- expr_ptr = &new_expr;
+ } else if ((IS_TMP_VAR == IS_CV || IS_TMP_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);
} else if (IS_TMP_VAR == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
@@ -12340,7 +12354,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
- if (!1) {
+ if (IS_TMP_VAR != IS_TMP_VAR) {
zval_copy_ctor(&generator->value);
}
} else {
@@ -12370,14 +12384,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
ZVAL_DUP(&generator->value, value);
} else if (IS_TMP_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if (Z_ISREF_P(value)) {
+ } else if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && Z_ISREF_P(value)) {
ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
} else {
+ ZVAL_COPY_VALUE(&generator->value, value);
if (IS_TMP_VAR == IS_CV) {
- if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+ if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
- ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
@@ -12395,14 +12409,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
ZVAL_DUP(&generator->key, key);
} else if (IS_TMP_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if (Z_ISREF_P(key)) {
+ } else if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && Z_ISREF_P(key)) {
ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
} else {
+ ZVAL_COPY_VALUE(&generator->key, key);
if (IS_TMP_VAR == IS_CV) {
- if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+ if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
}
- ZVAL_COPY_VALUE(&generator->key, key);
}
if (Z_TYPE(generator->key) == IS_LONG
@@ -13196,7 +13210,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_VAR_HANDLER(ZEND_OPCOD
} else {
expr_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (1) { /* temporary variable */
+ if (IS_TMP_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&new_expr, expr_ptr);
expr_ptr = &new_expr;
} else if (IS_TMP_VAR == IS_CONST) {
@@ -13204,9 +13218,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_VAR_HANDLER(ZEND_OPCOD
ZVAL_DUP(&new_expr, expr_ptr);
expr_ptr = &new_expr;
}
- } else if (Z_ISREF_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
- expr_ptr = &new_expr;
+ } else if ((IS_TMP_VAR == IS_CV || IS_TMP_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);
} else if (IS_TMP_VAR == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
@@ -13303,29 +13317,37 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLE
zval tmp, *varname;
HashTable *target_symbol_table;
zend_free_op free_op1;
- zend_bool tmp_is_dup = 0;
SAVE_OPLINE();
if (IS_TMP_VAR == IS_CV &&
IS_VAR == IS_UNUSED &&
(opline->extended_value & ZEND_QUICK_SET)) {
- ZVAL_COPY_VALUE(&tmp, EX_VAR(opline->op1.var));
- ZVAL_UNDEF(EX_VAR(opline->op1.var));
- zval_ptr_dtor(&tmp);
+ zval *var = EX_VAR(opline->op1.var);
+
+ if (Z_REFCOUNTED_P(var)) {
+ zend_refcounted *garbage = Z_COUNTED_P(var);
+
+ if (!--GC_REFCOUNT(garbage)) {
+ ZVAL_UNDEF(var);
+ _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC);
+ } else {
+ GC_ZVAL_CHECK_POSSIBLE_ROOT(var);
+ ZVAL_UNDEF(var);
+ }
+ } else {
+ ZVAL_UNDEF(var);
+ }
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ ZVAL_UNDEF(&tmp);
if (IS_TMP_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_DUP(&tmp, varname);
convert_to_string(&tmp);
varname = &tmp;
- tmp_is_dup = 1;
- } else if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
- ZVAL_COPY(&tmp, varname);
- varname = &tmp;
}
if (IS_VAR != IS_UNUSED) {
@@ -13337,10 +13359,8 @@ 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 && tmp_is_dup) {
+ if (IS_TMP_VAR != IS_CONST) {
zval_dtor(&tmp);
- } else if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
- zval_ptr_dtor(&tmp);
}
zval_dtor(free_op1.var);
HANDLE_EXCEPTION();
@@ -13359,10 +13379,8 @@ 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 && tmp_is_dup) {
+ if (IS_TMP_VAR != IS_CONST) {
zval_dtor(&tmp);
- } else if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
- zval_ptr_dtor(&tmp);
}
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -13630,7 +13648,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
- if (!1) {
+ if (IS_TMP_VAR != IS_TMP_VAR) {
zval_copy_ctor(&generator->value);
}
} else {
@@ -13660,14 +13678,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
ZVAL_DUP(&generator->value, value);
} else if (IS_TMP_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if (Z_ISREF_P(value)) {
+ } else if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && Z_ISREF_P(value)) {
ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
} else {
+ ZVAL_COPY_VALUE(&generator->value, value);
if (IS_TMP_VAR == IS_CV) {
- if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+ if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
- ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
@@ -13685,14 +13703,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
ZVAL_DUP(&generator->key, key);
} else if (IS_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if (Z_ISREF_P(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);
} else {
+ ZVAL_COPY_VALUE(&generator->key, key);
if (IS_VAR == IS_CV) {
- if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+ if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
}
- ZVAL_COPY_VALUE(&generator->key, key);
}
if (Z_TYPE(generator->key) == IS_LONG
@@ -13945,7 +13963,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OP
} else {
expr_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (1) { /* temporary variable */
+ if (IS_TMP_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&new_expr, expr_ptr);
expr_ptr = &new_expr;
} else if (IS_TMP_VAR == IS_CONST) {
@@ -13953,9 +13971,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OP
ZVAL_DUP(&new_expr, expr_ptr);
expr_ptr = &new_expr;
}
- } else if (Z_ISREF_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
- expr_ptr = &new_expr;
+ } else if ((IS_TMP_VAR == IS_CV || IS_TMP_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);
} else if (IS_TMP_VAR == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
@@ -14052,29 +14070,37 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HAN
zval tmp, *varname;
HashTable *target_symbol_table;
zend_free_op free_op1;
- zend_bool tmp_is_dup = 0;
SAVE_OPLINE();
if (IS_TMP_VAR == IS_CV &&
IS_UNUSED == IS_UNUSED &&
(opline->extended_value & ZEND_QUICK_SET)) {
- ZVAL_COPY_VALUE(&tmp, EX_VAR(opline->op1.var));
- ZVAL_UNDEF(EX_VAR(opline->op1.var));
- zval_ptr_dtor(&tmp);
+ zval *var = EX_VAR(opline->op1.var);
+
+ if (Z_REFCOUNTED_P(var)) {
+ zend_refcounted *garbage = Z_COUNTED_P(var);
+
+ if (!--GC_REFCOUNT(garbage)) {
+ ZVAL_UNDEF(var);
+ _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC);
+ } else {
+ GC_ZVAL_CHECK_POSSIBLE_ROOT(var);
+ ZVAL_UNDEF(var);
+ }
+ } else {
+ ZVAL_UNDEF(var);
+ }
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
varname = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ ZVAL_UNDEF(&tmp);
if (IS_TMP_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_DUP(&tmp, varname);
convert_to_string(&tmp);
varname = &tmp;
- tmp_is_dup = 1;
- } else if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
- ZVAL_COPY(&tmp, varname);
- varname = &tmp;
}
if (IS_UNUSED != IS_UNUSED) {
@@ -14086,10 +14112,8 @@ 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 && tmp_is_dup) {
+ if (IS_TMP_VAR != IS_CONST) {
zval_dtor(&tmp);
- } else if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
- zval_ptr_dtor(&tmp);
}
zval_dtor(free_op1.var);
HANDLE_EXCEPTION();
@@ -14108,10 +14132,8 @@ 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 && tmp_is_dup) {
+ if (IS_TMP_VAR != IS_CONST) {
zval_dtor(&tmp);
- } else if (IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) {
- zval_ptr_dtor(&tmp);
}
zval_dtor(free_op1.var);
CHECK_EXCEPTION();
@@ -14232,7 +14254,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER
if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
- if (!1) {
+ if (IS_TMP_VAR != IS_TMP_VAR) {
zval_copy_ctor(&generator->value);
}
} else {
@@ -14262,14 +14284,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER
ZVAL_DUP(&generator->value, value);
} else if (IS_TMP_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if (Z_ISREF_P(value)) {
+ } else if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && Z_ISREF_P(value)) {
ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
} else {
+ ZVAL_COPY_VALUE(&generator->value, value);
if (IS_TMP_VAR == IS_CV) {
- if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+ if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
- ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
@@ -14287,14 +14309,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HANDLER
ZVAL_DUP(&generator->key, key);
} else if (IS_UNUSED == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if (Z_ISREF_P(key)) {
+ } else if ((IS_UNUSED == IS_VAR || IS_UNUSED == IS_CV) && Z_ISREF_P(key)) {
ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
} else {
+ ZVAL_COPY_VALUE(&generator->key, key);
if (IS_UNUSED == IS_CV) {
- if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+ if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
}
- ZVAL_COPY_VALUE(&generator->key, key);
}
if (Z_TYPE(generator->key) == IS_LONG
@@ -14917,7 +14939,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE
} else {
expr_ptr = _get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (1) { /* temporary variable */
+ if (IS_TMP_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&new_expr, expr_ptr);
expr_ptr = &new_expr;
} else if (IS_TMP_VAR == IS_CONST) {
@@ -14925,9 +14947,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE
ZVAL_DUP(&new_expr, expr_ptr);
expr_ptr = &new_expr;
}
- } else if (Z_ISREF_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
- expr_ptr = &new_expr;
+ } else if ((IS_TMP_VAR == IS_CV || IS_TMP_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);
} else if (IS_TMP_VAR == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
@@ -15197,7 +15219,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
- if (!1) {
+ if (IS_TMP_VAR != IS_TMP_VAR) {
zval_copy_ctor(&generator->value);
}
} else {
@@ -15227,14 +15249,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
ZVAL_DUP(&generator->value, value);
} else if (IS_TMP_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if (Z_ISREF_P(value)) {
+ } else if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && Z_ISREF_P(value)) {
ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
} else {
+ ZVAL_COPY_VALUE(&generator->value, value);
if (IS_TMP_VAR == IS_CV) {
- if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+ if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
- ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
@@ -15252,14 +15274,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
ZVAL_DUP(&generator->key, key);
} else if (IS_CV == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if (Z_ISREF_P(key)) {
+ } else if ((IS_CV == IS_VAR || IS_CV == IS_CV) && Z_ISREF_P(key)) {
ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
} else {
+ ZVAL_COPY_VALUE(&generator->key, key);
if (IS_CV == IS_CV) {
- if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+ if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
}
- ZVAL_COPY_VALUE(&generator->key, key);
}
if (Z_TYPE(generator->key) == IS_LONG
@@ -15775,7 +15797,7 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zval_copy_ctor_func(EX(return_value));
}
}
- } else if (Z_ISREF_P(retval_ptr)) {
+ } 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);
} else {
@@ -15828,9 +15850,8 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE
} else {
zend_error(E_NOTICE, "Only variable references should be returned by reference");
if (EX(return_value)) {
- zval tmp;
- ZVAL_DUP(&tmp, retval_ptr);
- ZVAL_NEW_REF(EX(return_value), &tmp);
+ ZVAL_NEW_REF(EX(return_value), retval_ptr);
+ if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr);
}
break;
}
@@ -15883,7 +15904,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
EX(call)->num_args = opline->op2.num;
- if (Z_ISREF_P(varptr)) {
+ 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);
} else {
@@ -15988,7 +16009,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_EX_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_
varptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
EX(call)->num_args = opline->op2.num;
- if (Z_ISREF_P(varptr)) {
+ 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);
} else {
@@ -16235,7 +16256,7 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
}
} else {
ZVAL_COPY_VALUE(result, expr);
- if (!0) {
+ if (IS_VAR != IS_TMP_VAR) {
zval_opt_copy_ctor(result);
}
convert_to_array(result);
@@ -16255,7 +16276,7 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
}
} else {
ZVAL_COPY_VALUE(result, expr);
- if (!0) {
+ if (IS_VAR != IS_TMP_VAR) {
zval_opt_copy_ctor(result);
}
convert_to_object(result);
@@ -16435,7 +16456,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
} else {
array_ptr = array_ref = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
ZVAL_DEREF(array_ptr);
- if (0) { /* IS_TMP_VAR */
+ if (IS_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&tmp, array_ptr);
array_ptr = &tmp;
if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
@@ -18379,7 +18400,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER
variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
- if (0) {
+ if (IS_CONST == IS_TMP_VAR) {
zval_dtor(value);
}
if (RETURN_VALUE_USED(opline)) {
@@ -18715,7 +18736,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPC
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
} else {
expr_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (0) { /* temporary variable */
+ if (IS_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&new_expr, expr_ptr);
expr_ptr = &new_expr;
} else if (IS_VAR == IS_CONST) {
@@ -18723,9 +18744,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPC
ZVAL_DUP(&new_expr, expr_ptr);
expr_ptr = &new_expr;
}
- } else if (Z_ISREF_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
- expr_ptr = &new_expr;
+ } 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);
} else if (IS_VAR == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
@@ -18822,29 +18843,37 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND
zval tmp, *varname;
HashTable *target_symbol_table;
zend_free_op free_op1;
- zend_bool tmp_is_dup = 0;
SAVE_OPLINE();
if (IS_VAR == IS_CV &&
IS_CONST == IS_UNUSED &&
(opline->extended_value & ZEND_QUICK_SET)) {
- ZVAL_COPY_VALUE(&tmp, EX_VAR(opline->op1.var));
- ZVAL_UNDEF(EX_VAR(opline->op1.var));
- zval_ptr_dtor(&tmp);
+ zval *var = EX_VAR(opline->op1.var);
+
+ if (Z_REFCOUNTED_P(var)) {
+ zend_refcounted *garbage = Z_COUNTED_P(var);
+
+ if (!--GC_REFCOUNT(garbage)) {
+ ZVAL_UNDEF(var);
+ _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC);
+ } else {
+ GC_ZVAL_CHECK_POSSIBLE_ROOT(var);
+ ZVAL_UNDEF(var);
+ }
+ } else {
+ ZVAL_UNDEF(var);
+ }
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ ZVAL_UNDEF(&tmp);
if (IS_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_DUP(&tmp, varname);
convert_to_string(&tmp);
varname = &tmp;
- tmp_is_dup = 1;
- } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
- ZVAL_COPY(&tmp, varname);
- varname = &tmp;
}
if (IS_CONST != IS_UNUSED) {
@@ -18856,10 +18885,8 @@ 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 && tmp_is_dup) {
+ if (IS_VAR != IS_CONST) {
zval_dtor(&tmp);
- } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
- zval_ptr_dtor(&tmp);
}
zval_ptr_dtor_nogc(free_op1.var);
HANDLE_EXCEPTION();
@@ -18878,10 +18905,8 @@ 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 && tmp_is_dup) {
+ if (IS_VAR != IS_CONST) {
zval_dtor(&tmp);
- } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
- zval_ptr_dtor(&tmp);
}
zval_ptr_dtor_nogc(free_op1.var);
CHECK_EXCEPTION();
@@ -18922,12 +18947,9 @@ num_index_dim:
zend_hash_index_del(ht, hval);
break;
case IS_STRING:
- if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
- if (Z_REFCOUNTED_P(offset)) Z_ADDREF_P(offset);
- }
if (IS_CONST != IS_CONST) {
if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) {
- goto numeric_index_dim;
+ goto num_index_dim;
}
}
if (ht == &EG(symbol_table).ht) {
@@ -18935,15 +18957,6 @@ num_index_dim:
} else {
zend_hash_del(ht, Z_STR_P(offset));
}
- if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
- zval_ptr_dtor(offset);
- }
- break;
-numeric_index_dim:
- zend_hash_index_del(ht, hval);
- if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
- zval_ptr_dtor(offset);
- }
break;
case IS_NULL:
zend_hash_del(ht, STR_EMPTY_ALLOC());
@@ -19277,7 +19290,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_
if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
- if (!0) {
+ if (IS_VAR != IS_TMP_VAR) {
zval_copy_ctor(&generator->value);
}
} else {
@@ -19308,14 +19321,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_
ZVAL_DUP(&generator->value, value);
} else if (IS_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if (Z_ISREF_P(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);
} else {
+ ZVAL_COPY_VALUE(&generator->value, value);
if (IS_VAR == IS_CV) {
- if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+ if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
- ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
@@ -19333,14 +19346,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_
ZVAL_DUP(&generator->key, key);
} else if (IS_CONST == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if (Z_ISREF_P(key)) {
+ } else if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && Z_ISREF_P(key)) {
ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
} else {
+ ZVAL_COPY_VALUE(&generator->key, key);
if (IS_CONST == IS_CV) {
- if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+ if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
}
- ZVAL_COPY_VALUE(&generator->key, key);
}
if (Z_TYPE(generator->key) == IS_LONG
@@ -20607,7 +20620,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_A
variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
- if (1) {
+ if (IS_TMP_VAR == IS_TMP_VAR) {
zval_dtor(value);
}
if (RETURN_VALUE_USED(opline)) {
@@ -20849,7 +20862,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER(ZEND_OPCOD
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
} else {
expr_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (0) { /* temporary variable */
+ if (IS_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&new_expr, expr_ptr);
expr_ptr = &new_expr;
} else if (IS_VAR == IS_CONST) {
@@ -20857,9 +20870,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER(ZEND_OPCOD
ZVAL_DUP(&new_expr, expr_ptr);
expr_ptr = &new_expr;
}
- } else if (Z_ISREF_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
- expr_ptr = &new_expr;
+ } 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);
} else if (IS_VAR == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
@@ -20984,12 +20997,9 @@ num_index_dim:
zend_hash_index_del(ht, hval);
break;
case IS_STRING:
- if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
- if (Z_REFCOUNTED_P(offset)) Z_ADDREF_P(offset);
- }
if (IS_TMP_VAR != IS_CONST) {
if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) {
- goto numeric_index_dim;
+ goto num_index_dim;
}
}
if (ht == &EG(symbol_table).ht) {
@@ -20997,15 +21007,6 @@ num_index_dim:
} else {
zend_hash_del(ht, Z_STR_P(offset));
}
- if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
- zval_ptr_dtor(offset);
- }
- break;
-numeric_index_dim:
- zend_hash_index_del(ht, hval);
- if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
- zval_ptr_dtor(offset);
- }
break;
case IS_NULL:
zend_hash_del(ht, STR_EMPTY_ALLOC());
@@ -21261,7 +21262,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
- if (!0) {
+ if (IS_VAR != IS_TMP_VAR) {
zval_copy_ctor(&generator->value);
}
} else {
@@ -21292,14 +21293,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
ZVAL_DUP(&generator->value, value);
} else if (IS_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if (Z_ISREF_P(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);
} else {
+ ZVAL_COPY_VALUE(&generator->value, value);
if (IS_VAR == IS_CV) {
- if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+ if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
- ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
@@ -21317,14 +21318,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
ZVAL_DUP(&generator->key, key);
} else if (IS_TMP_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if (Z_ISREF_P(key)) {
+ } else if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && Z_ISREF_P(key)) {
ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
} else {
+ ZVAL_COPY_VALUE(&generator->key, key);
if (IS_TMP_VAR == IS_CV) {
- if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+ if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
}
- ZVAL_COPY_VALUE(&generator->key, key);
}
if (Z_TYPE(generator->key) == IS_LONG
@@ -22742,7 +22743,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_A
variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
- if (0) {
+ if (IS_VAR == IS_TMP_VAR) {
zval_dtor(value);
}
if (RETURN_VALUE_USED(opline)) {
@@ -23048,7 +23049,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
} else {
expr_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (0) { /* temporary variable */
+ if (IS_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&new_expr, expr_ptr);
expr_ptr = &new_expr;
} else if (IS_VAR == IS_CONST) {
@@ -23056,9 +23057,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD
ZVAL_DUP(&new_expr, expr_ptr);
expr_ptr = &new_expr;
}
- } else if (Z_ISREF_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
- expr_ptr = &new_expr;
+ } 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);
} else if (IS_VAR == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
@@ -23155,29 +23156,37 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE
zval tmp, *varname;
HashTable *target_symbol_table;
zend_free_op free_op1;
- zend_bool tmp_is_dup = 0;
SAVE_OPLINE();
if (IS_VAR == IS_CV &&
IS_VAR == IS_UNUSED &&
(opline->extended_value & ZEND_QUICK_SET)) {
- ZVAL_COPY_VALUE(&tmp, EX_VAR(opline->op1.var));
- ZVAL_UNDEF(EX_VAR(opline->op1.var));
- zval_ptr_dtor(&tmp);
+ zval *var = EX_VAR(opline->op1.var);
+
+ if (Z_REFCOUNTED_P(var)) {
+ zend_refcounted *garbage = Z_COUNTED_P(var);
+
+ if (!--GC_REFCOUNT(garbage)) {
+ ZVAL_UNDEF(var);
+ _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC);
+ } else {
+ GC_ZVAL_CHECK_POSSIBLE_ROOT(var);
+ ZVAL_UNDEF(var);
+ }
+ } else {
+ ZVAL_UNDEF(var);
+ }
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ ZVAL_UNDEF(&tmp);
if (IS_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_DUP(&tmp, varname);
convert_to_string(&tmp);
varname = &tmp;
- tmp_is_dup = 1;
- } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
- ZVAL_COPY(&tmp, varname);
- varname = &tmp;
}
if (IS_VAR != IS_UNUSED) {
@@ -23189,10 +23198,8 @@ 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 && tmp_is_dup) {
+ if (IS_VAR != IS_CONST) {
zval_dtor(&tmp);
- } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
- zval_ptr_dtor(&tmp);
}
zval_ptr_dtor_nogc(free_op1.var);
HANDLE_EXCEPTION();
@@ -23211,10 +23218,8 @@ 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 && tmp_is_dup) {
+ if (IS_VAR != IS_CONST) {
zval_dtor(&tmp);
- } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
- zval_ptr_dtor(&tmp);
}
zval_ptr_dtor_nogc(free_op1.var);
CHECK_EXCEPTION();
@@ -23255,12 +23260,9 @@ num_index_dim:
zend_hash_index_del(ht, hval);
break;
case IS_STRING:
- if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
- if (Z_REFCOUNTED_P(offset)) Z_ADDREF_P(offset);
- }
if (IS_VAR != IS_CONST) {
if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) {
- goto numeric_index_dim;
+ goto num_index_dim;
}
}
if (ht == &EG(symbol_table).ht) {
@@ -23268,15 +23270,6 @@ num_index_dim:
} else {
zend_hash_del(ht, Z_STR_P(offset));
}
- if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
- zval_ptr_dtor(offset);
- }
- break;
-numeric_index_dim:
- zend_hash_index_del(ht, hval);
- if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
- zval_ptr_dtor(offset);
- }
break;
case IS_NULL:
zend_hash_del(ht, STR_EMPTY_ALLOC());
@@ -23612,7 +23605,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
- if (!0) {
+ if (IS_VAR != IS_TMP_VAR) {
zval_copy_ctor(&generator->value);
}
} else {
@@ -23643,14 +23636,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
ZVAL_DUP(&generator->value, value);
} else if (IS_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if (Z_ISREF_P(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);
} else {
+ ZVAL_COPY_VALUE(&generator->value, value);
if (IS_VAR == IS_CV) {
- if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+ if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
- ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
@@ -23668,14 +23661,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
ZVAL_DUP(&generator->key, key);
} else if (IS_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if (Z_ISREF_P(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);
} else {
+ ZVAL_COPY_VALUE(&generator->key, key);
if (IS_VAR == IS_CV) {
- if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+ if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
}
- ZVAL_COPY_VALUE(&generator->key, key);
}
if (Z_TYPE(generator->key) == IS_LONG
@@ -24507,7 +24500,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OP
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
} else {
expr_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (0) { /* temporary variable */
+ if (IS_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&new_expr, expr_ptr);
expr_ptr = &new_expr;
} else if (IS_VAR == IS_CONST) {
@@ -24515,9 +24508,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OP
ZVAL_DUP(&new_expr, expr_ptr);
expr_ptr = &new_expr;
}
- } else if (Z_ISREF_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
- expr_ptr = &new_expr;
+ } 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);
} else if (IS_VAR == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
@@ -24614,29 +24607,37 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAN
zval tmp, *varname;
HashTable *target_symbol_table;
zend_free_op free_op1;
- zend_bool tmp_is_dup = 0;
SAVE_OPLINE();
if (IS_VAR == IS_CV &&
IS_UNUSED == IS_UNUSED &&
(opline->extended_value & ZEND_QUICK_SET)) {
- ZVAL_COPY_VALUE(&tmp, EX_VAR(opline->op1.var));
- ZVAL_UNDEF(EX_VAR(opline->op1.var));
- zval_ptr_dtor(&tmp);
+ zval *var = EX_VAR(opline->op1.var);
+
+ if (Z_REFCOUNTED_P(var)) {
+ zend_refcounted *garbage = Z_COUNTED_P(var);
+
+ if (!--GC_REFCOUNT(garbage)) {
+ ZVAL_UNDEF(var);
+ _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC);
+ } else {
+ GC_ZVAL_CHECK_POSSIBLE_ROOT(var);
+ ZVAL_UNDEF(var);
+ }
+ } else {
+ ZVAL_UNDEF(var);
+ }
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
varname = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
+ ZVAL_UNDEF(&tmp);
if (IS_VAR != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_DUP(&tmp, varname);
convert_to_string(&tmp);
varname = &tmp;
- tmp_is_dup = 1;
- } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
- ZVAL_COPY(&tmp, varname);
- varname = &tmp;
}
if (IS_UNUSED != IS_UNUSED) {
@@ -24648,10 +24649,8 @@ 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 && tmp_is_dup) {
+ if (IS_VAR != IS_CONST) {
zval_dtor(&tmp);
- } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
- zval_ptr_dtor(&tmp);
}
zval_ptr_dtor_nogc(free_op1.var);
HANDLE_EXCEPTION();
@@ -24670,10 +24669,8 @@ 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 && tmp_is_dup) {
+ if (IS_VAR != IS_CONST) {
zval_dtor(&tmp);
- } else if (IS_VAR == IS_VAR || IS_VAR == IS_CV) {
- zval_ptr_dtor(&tmp);
}
zval_ptr_dtor_nogc(free_op1.var);
CHECK_EXCEPTION();
@@ -24812,7 +24809,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER
if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
- if (!0) {
+ if (IS_VAR != IS_TMP_VAR) {
zval_copy_ctor(&generator->value);
}
} else {
@@ -24843,14 +24840,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER
ZVAL_DUP(&generator->value, value);
} else if (IS_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if (Z_ISREF_P(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);
} else {
+ ZVAL_COPY_VALUE(&generator->value, value);
if (IS_VAR == IS_CV) {
- if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+ if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
- ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
@@ -24868,14 +24865,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER
ZVAL_DUP(&generator->key, key);
} else if (IS_UNUSED == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if (Z_ISREF_P(key)) {
+ } else if ((IS_UNUSED == IS_VAR || IS_UNUSED == IS_CV) && Z_ISREF_P(key)) {
ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
} else {
+ ZVAL_COPY_VALUE(&generator->key, key);
if (IS_UNUSED == IS_CV) {
- if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+ if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
}
- ZVAL_COPY_VALUE(&generator->key, key);
}
if (Z_TYPE(generator->key) == IS_LONG
@@ -26122,7 +26119,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_AR
variable_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
if (IS_VAR == IS_VAR && UNEXPECTED(variable_ptr == &EG(error_zval))) {
- if (0) {
+ if (IS_CV == IS_TMP_VAR) {
zval_dtor(value);
}
if (RETURN_VALUE_USED(opline)) {
@@ -26424,7 +26421,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
} else {
expr_ptr = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1 TSRMLS_CC);
- if (0) { /* temporary variable */
+ if (IS_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&new_expr, expr_ptr);
expr_ptr = &new_expr;
} else if (IS_VAR == IS_CONST) {
@@ -26432,9 +26429,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE
ZVAL_DUP(&new_expr, expr_ptr);
expr_ptr = &new_expr;
}
- } else if (Z_ISREF_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
- expr_ptr = &new_expr;
+ } 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);
} else if (IS_VAR == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
@@ -26559,12 +26556,9 @@ num_index_dim:
zend_hash_index_del(ht, hval);
break;
case IS_STRING:
- if (IS_CV == IS_CV || IS_CV == IS_VAR) {
- if (Z_REFCOUNTED_P(offset)) Z_ADDREF_P(offset);
- }
if (IS_CV != IS_CONST) {
if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) {
- goto numeric_index_dim;
+ goto num_index_dim;
}
}
if (ht == &EG(symbol_table).ht) {
@@ -26572,15 +26566,6 @@ num_index_dim:
} else {
zend_hash_del(ht, Z_STR_P(offset));
}
- if (IS_CV == IS_CV || IS_CV == IS_VAR) {
- zval_ptr_dtor(offset);
- }
- break;
-numeric_index_dim:
- zend_hash_index_del(ht, hval);
- if (IS_CV == IS_CV || IS_CV == IS_VAR) {
- zval_ptr_dtor(offset);
- }
break;
case IS_NULL:
zend_hash_del(ht, STR_EMPTY_ALLOC());
@@ -26834,7 +26819,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
- if (!0) {
+ if (IS_VAR != IS_TMP_VAR) {
zval_copy_ctor(&generator->value);
}
} else {
@@ -26865,14 +26850,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
ZVAL_DUP(&generator->value, value);
} else if (IS_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if (Z_ISREF_P(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);
} else {
+ ZVAL_COPY_VALUE(&generator->value, value);
if (IS_VAR == IS_CV) {
- if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+ if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
- ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
@@ -26890,14 +26875,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
ZVAL_DUP(&generator->key, key);
} else if (IS_CV == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if (Z_ISREF_P(key)) {
+ } else if ((IS_CV == IS_VAR || IS_CV == IS_CV) && Z_ISREF_P(key)) {
ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
} else {
+ ZVAL_COPY_VALUE(&generator->key, key);
if (IS_CV == IS_CV) {
- if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+ if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
}
- ZVAL_COPY_VALUE(&generator->key, key);
}
if (Z_TYPE(generator->key) == IS_LONG
@@ -28024,12 +28009,9 @@ num_index_dim:
zend_hash_index_del(ht, hval);
break;
case IS_STRING:
- if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
- if (Z_REFCOUNTED_P(offset)) Z_ADDREF_P(offset);
- }
if (IS_CONST != IS_CONST) {
if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) {
- goto numeric_index_dim;
+ goto num_index_dim;
}
}
if (ht == &EG(symbol_table).ht) {
@@ -28037,15 +28019,6 @@ num_index_dim:
} else {
zend_hash_del(ht, Z_STR_P(offset));
}
- if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
- zval_ptr_dtor(offset);
- }
- break;
-numeric_index_dim:
- zend_hash_index_del(ht, hval);
- if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
- zval_ptr_dtor(offset);
- }
break;
case IS_NULL:
zend_hash_del(ht, STR_EMPTY_ALLOC());
@@ -28299,7 +28272,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDL
if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
- if (!0) {
+ if (IS_UNUSED != IS_TMP_VAR) {
zval_copy_ctor(&generator->value);
}
} else {
@@ -28329,14 +28302,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDL
ZVAL_DUP(&generator->value, value);
} else if (IS_UNUSED == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if (Z_ISREF_P(value)) {
+ } else if ((IS_UNUSED == IS_CV || IS_UNUSED == IS_VAR) && Z_ISREF_P(value)) {
ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
} else {
+ ZVAL_COPY_VALUE(&generator->value, value);
if (IS_UNUSED == IS_CV) {
- if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+ if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
- ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
@@ -28354,14 +28327,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDL
ZVAL_DUP(&generator->key, key);
} else if (IS_CONST == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if (Z_ISREF_P(key)) {
+ } else if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && Z_ISREF_P(key)) {
ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
} else {
+ ZVAL_COPY_VALUE(&generator->key, key);
if (IS_CONST == IS_CV) {
- if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+ if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
}
- ZVAL_COPY_VALUE(&generator->key, key);
}
if (Z_TYPE(generator->key) == IS_LONG
@@ -29309,12 +29282,9 @@ num_index_dim:
zend_hash_index_del(ht, hval);
break;
case IS_STRING:
- if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
- if (Z_REFCOUNTED_P(offset)) Z_ADDREF_P(offset);
- }
if (IS_TMP_VAR != IS_CONST) {
if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) {
- goto numeric_index_dim;
+ goto num_index_dim;
}
}
if (ht == &EG(symbol_table).ht) {
@@ -29322,15 +29292,6 @@ num_index_dim:
} else {
zend_hash_del(ht, Z_STR_P(offset));
}
- if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
- zval_ptr_dtor(offset);
- }
- break;
-numeric_index_dim:
- zend_hash_index_del(ht, hval);
- if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
- zval_ptr_dtor(offset);
- }
break;
case IS_NULL:
zend_hash_del(ht, STR_EMPTY_ALLOC());
@@ -29586,7 +29547,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER
if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
- if (!0) {
+ if (IS_UNUSED != IS_TMP_VAR) {
zval_copy_ctor(&generator->value);
}
} else {
@@ -29616,14 +29577,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER
ZVAL_DUP(&generator->value, value);
} else if (IS_UNUSED == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if (Z_ISREF_P(value)) {
+ } else if ((IS_UNUSED == IS_CV || IS_UNUSED == IS_VAR) && Z_ISREF_P(value)) {
ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
} else {
+ ZVAL_COPY_VALUE(&generator->value, value);
if (IS_UNUSED == IS_CV) {
- if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+ if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
- ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
@@ -29641,14 +29602,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HANDLER
ZVAL_DUP(&generator->key, key);
} else if (IS_TMP_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if (Z_ISREF_P(key)) {
+ } else if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && Z_ISREF_P(key)) {
ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
} else {
+ ZVAL_COPY_VALUE(&generator->key, key);
if (IS_TMP_VAR == IS_CV) {
- if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+ if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
}
- ZVAL_COPY_VALUE(&generator->key, key);
}
if (Z_TYPE(generator->key) == IS_LONG
@@ -30596,12 +30557,9 @@ num_index_dim:
zend_hash_index_del(ht, hval);
break;
case IS_STRING:
- if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
- if (Z_REFCOUNTED_P(offset)) Z_ADDREF_P(offset);
- }
if (IS_VAR != IS_CONST) {
if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) {
- goto numeric_index_dim;
+ goto num_index_dim;
}
}
if (ht == &EG(symbol_table).ht) {
@@ -30609,15 +30567,6 @@ num_index_dim:
} else {
zend_hash_del(ht, Z_STR_P(offset));
}
- if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
- zval_ptr_dtor(offset);
- }
- break;
-numeric_index_dim:
- zend_hash_index_del(ht, hval);
- if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
- zval_ptr_dtor(offset);
- }
break;
case IS_NULL:
zend_hash_del(ht, STR_EMPTY_ALLOC());
@@ -30873,7 +30822,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER
if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
- if (!0) {
+ if (IS_UNUSED != IS_TMP_VAR) {
zval_copy_ctor(&generator->value);
}
} else {
@@ -30903,14 +30852,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER
ZVAL_DUP(&generator->value, value);
} else if (IS_UNUSED == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if (Z_ISREF_P(value)) {
+ } else if ((IS_UNUSED == IS_CV || IS_UNUSED == IS_VAR) && Z_ISREF_P(value)) {
ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
} else {
+ ZVAL_COPY_VALUE(&generator->value, value);
if (IS_UNUSED == IS_CV) {
- if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+ if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
- ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
@@ -30928,14 +30877,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HANDLER
ZVAL_DUP(&generator->key, key);
} else if (IS_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if (Z_ISREF_P(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);
} else {
+ ZVAL_COPY_VALUE(&generator->key, key);
if (IS_VAR == IS_CV) {
- if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+ if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
}
- ZVAL_COPY_VALUE(&generator->key, key);
}
if (Z_TYPE(generator->key) == IS_LONG
@@ -31389,7 +31338,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HAND
if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
- if (!0) {
+ if (IS_UNUSED != IS_TMP_VAR) {
zval_copy_ctor(&generator->value);
}
} else {
@@ -31419,14 +31368,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HAND
ZVAL_DUP(&generator->value, value);
} else if (IS_UNUSED == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if (Z_ISREF_P(value)) {
+ } else if ((IS_UNUSED == IS_CV || IS_UNUSED == IS_VAR) && Z_ISREF_P(value)) {
ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
} else {
+ ZVAL_COPY_VALUE(&generator->value, value);
if (IS_UNUSED == IS_CV) {
- if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+ if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
- ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
@@ -31444,14 +31393,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_UNUSED_HANDLER(ZEND_OPCODE_HAND
ZVAL_DUP(&generator->key, key);
} else if (IS_UNUSED == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if (Z_ISREF_P(key)) {
+ } else if ((IS_UNUSED == IS_VAR || IS_UNUSED == IS_CV) && Z_ISREF_P(key)) {
ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
} else {
+ ZVAL_COPY_VALUE(&generator->key, key);
if (IS_UNUSED == IS_CV) {
- if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+ if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
}
- ZVAL_COPY_VALUE(&generator->key, key);
}
if (Z_TYPE(generator->key) == IS_LONG
@@ -32392,12 +32341,9 @@ num_index_dim:
zend_hash_index_del(ht, hval);
break;
case IS_STRING:
- if (IS_CV == IS_CV || IS_CV == IS_VAR) {
- if (Z_REFCOUNTED_P(offset)) Z_ADDREF_P(offset);
- }
if (IS_CV != IS_CONST) {
if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) {
- goto numeric_index_dim;
+ goto num_index_dim;
}
}
if (ht == &EG(symbol_table).ht) {
@@ -32405,15 +32351,6 @@ num_index_dim:
} else {
zend_hash_del(ht, Z_STR_P(offset));
}
- if (IS_CV == IS_CV || IS_CV == IS_VAR) {
- zval_ptr_dtor(offset);
- }
- break;
-numeric_index_dim:
- zend_hash_index_del(ht, hval);
- if (IS_CV == IS_CV || IS_CV == IS_VAR) {
- zval_ptr_dtor(offset);
- }
break;
case IS_NULL:
zend_hash_del(ht, STR_EMPTY_ALLOC());
@@ -32667,7 +32604,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_
if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
- if (!0) {
+ if (IS_UNUSED != IS_TMP_VAR) {
zval_copy_ctor(&generator->value);
}
} else {
@@ -32697,14 +32634,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_
ZVAL_DUP(&generator->value, value);
} else if (IS_UNUSED == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if (Z_ISREF_P(value)) {
+ } else if ((IS_UNUSED == IS_CV || IS_UNUSED == IS_VAR) && Z_ISREF_P(value)) {
ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
} else {
+ ZVAL_COPY_VALUE(&generator->value, value);
if (IS_UNUSED == IS_CV) {
- if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+ if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
- ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
@@ -32722,14 +32659,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_
ZVAL_DUP(&generator->key, key);
} else if (IS_CV == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if (Z_ISREF_P(key)) {
+ } else if ((IS_CV == IS_VAR || IS_CV == IS_CV) && Z_ISREF_P(key)) {
ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
} else {
+ ZVAL_COPY_VALUE(&generator->key, key);
if (IS_CV == IS_CV) {
- if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+ if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
}
- ZVAL_COPY_VALUE(&generator->key, key);
}
if (Z_TYPE(generator->key) == IS_LONG
@@ -33216,7 +33153,7 @@ static int ZEND_FASTCALL ZEND_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
zval_copy_ctor_func(EX(return_value));
}
}
- } else if (Z_ISREF_P(retval_ptr)) {
+ } else if ((IS_CV == IS_CV || IS_CV == IS_VAR) && Z_ISREF_P(retval_ptr)) {
ZVAL_COPY(EX(return_value), Z_REFVAL_P(retval_ptr));
} else {
@@ -33269,9 +33206,8 @@ static int ZEND_FASTCALL ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER
} else {
zend_error(E_NOTICE, "Only variable references should be returned by reference");
if (EX(return_value)) {
- zval tmp;
- ZVAL_DUP(&tmp, retval_ptr);
- ZVAL_NEW_REF(EX(return_value), &tmp);
+ ZVAL_NEW_REF(EX(return_value), retval_ptr);
+ if (Z_REFCOUNTED_P(retval_ptr)) Z_ADDREF_P(retval_ptr);
}
break;
}
@@ -33323,7 +33259,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
varptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
EX(call)->num_args = opline->op2.num;
- if (Z_ISREF_P(varptr)) {
+ if ((IS_CV == IS_CV || IS_CV == IS_VAR) && Z_ISREF_P(varptr)) {
ZVAL_COPY(arg, Z_REFVAL_P(varptr));
} else {
@@ -33427,7 +33363,7 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_EX_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_A
varptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
arg = ZEND_CALL_ARG(EX(call), opline->op2.num);
EX(call)->num_args = opline->op2.num;
- if (Z_ISREF_P(varptr)) {
+ if ((IS_CV == IS_CV || IS_CV == IS_VAR) && Z_ISREF_P(varptr)) {
ZVAL_COPY(arg, Z_REFVAL_P(varptr));
} else {
@@ -33660,7 +33596,7 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
}
} else {
ZVAL_COPY_VALUE(result, expr);
- if (!0) {
+ if (IS_CV != IS_TMP_VAR) {
zval_opt_copy_ctor(result);
}
convert_to_array(result);
@@ -33680,7 +33616,7 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
}
} else {
ZVAL_COPY_VALUE(result, expr);
- if (!0) {
+ if (IS_CV != IS_TMP_VAR) {
zval_opt_copy_ctor(result);
}
convert_to_object(result);
@@ -33859,7 +33795,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
} else {
array_ptr = array_ref = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
ZVAL_DEREF(array_ptr);
- if (0) { /* IS_TMP_VAR */
+ if (IS_CV == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&tmp, array_ptr);
array_ptr = &tmp;
if (Z_TYPE_P(array_ptr) == IS_OBJECT) {
@@ -35559,7 +35495,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_
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 (0) {
+ if (IS_CONST == IS_TMP_VAR) {
zval_dtor(value);
}
if (RETURN_VALUE_USED(opline)) {
@@ -35682,7 +35618,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCO
} else {
expr_ptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
- if (0) { /* temporary variable */
+ if (IS_CV == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&new_expr, expr_ptr);
expr_ptr = &new_expr;
} else if (IS_CV == IS_CONST) {
@@ -35690,9 +35626,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCO
ZVAL_DUP(&new_expr, expr_ptr);
expr_ptr = &new_expr;
}
- } else if (Z_ISREF_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
- expr_ptr = &new_expr;
+ } else if ((IS_CV == IS_CV || IS_CV == 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);
} else if (IS_CV == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
@@ -35789,29 +35725,37 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL
zval tmp, *varname;
HashTable *target_symbol_table;
- zend_bool tmp_is_dup = 0;
SAVE_OPLINE();
if (IS_CV == IS_CV &&
IS_CONST == IS_UNUSED &&
(opline->extended_value & ZEND_QUICK_SET)) {
- ZVAL_COPY_VALUE(&tmp, EX_VAR(opline->op1.var));
- ZVAL_UNDEF(EX_VAR(opline->op1.var));
- zval_ptr_dtor(&tmp);
+ zval *var = EX_VAR(opline->op1.var);
+
+ if (Z_REFCOUNTED_P(var)) {
+ zend_refcounted *garbage = Z_COUNTED_P(var);
+
+ if (!--GC_REFCOUNT(garbage)) {
+ ZVAL_UNDEF(var);
+ _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC);
+ } else {
+ GC_ZVAL_CHECK_POSSIBLE_ROOT(var);
+ ZVAL_UNDEF(var);
+ }
+ } else {
+ ZVAL_UNDEF(var);
+ }
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
varname = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ ZVAL_UNDEF(&tmp);
if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_DUP(&tmp, varname);
convert_to_string(&tmp);
varname = &tmp;
- tmp_is_dup = 1;
- } else if (IS_CV == IS_VAR || IS_CV == IS_CV) {
- ZVAL_COPY(&tmp, varname);
- varname = &tmp;
}
if (IS_CONST != IS_UNUSED) {
@@ -35823,10 +35767,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 && tmp_is_dup) {
+ if (IS_CV != IS_CONST) {
zval_dtor(&tmp);
- } else if (IS_CV == IS_VAR || IS_CV == IS_CV) {
- zval_ptr_dtor(&tmp);
}
HANDLE_EXCEPTION();
@@ -35845,10 +35787,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 && tmp_is_dup) {
+ if (IS_CV != IS_CONST) {
zval_dtor(&tmp);
- } else if (IS_CV == IS_VAR || IS_CV == IS_CV) {
- zval_ptr_dtor(&tmp);
}
CHECK_EXCEPTION();
@@ -35889,12 +35829,9 @@ num_index_dim:
zend_hash_index_del(ht, hval);
break;
case IS_STRING:
- if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
- if (Z_REFCOUNTED_P(offset)) Z_ADDREF_P(offset);
- }
if (IS_CONST != IS_CONST) {
if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) {
- goto numeric_index_dim;
+ goto num_index_dim;
}
}
if (ht == &EG(symbol_table).ht) {
@@ -35902,15 +35839,6 @@ num_index_dim:
} else {
zend_hash_del(ht, Z_STR_P(offset));
}
- if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
- zval_ptr_dtor(offset);
- }
- break;
-numeric_index_dim:
- zend_hash_index_del(ht, hval);
- if (IS_CONST == IS_CV || IS_CONST == IS_VAR) {
- zval_ptr_dtor(offset);
- }
break;
case IS_NULL:
zend_hash_del(ht, STR_EMPTY_ALLOC());
@@ -36244,7 +36172,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
- if (!0) {
+ if (IS_CV != IS_TMP_VAR) {
zval_copy_ctor(&generator->value);
}
} else {
@@ -36274,14 +36202,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
ZVAL_DUP(&generator->value, value);
} else if (IS_CV == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if (Z_ISREF_P(value)) {
+ } else if ((IS_CV == IS_CV || IS_CV == IS_VAR) && Z_ISREF_P(value)) {
ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
} else {
+ ZVAL_COPY_VALUE(&generator->value, value);
if (IS_CV == IS_CV) {
- if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+ if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
- ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
@@ -36299,14 +36227,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
ZVAL_DUP(&generator->key, key);
} else if (IS_CONST == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if (Z_ISREF_P(key)) {
+ } else if ((IS_CONST == IS_VAR || IS_CONST == IS_CV) && Z_ISREF_P(key)) {
ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
} else {
+ ZVAL_COPY_VALUE(&generator->key, key);
if (IS_CONST == IS_CV) {
- if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+ if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
}
- ZVAL_COPY_VALUE(&generator->key, key);
}
if (Z_TYPE(generator->key) == IS_LONG
@@ -37629,7 +37557,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_AR
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 (1) {
+ if (IS_TMP_VAR == IS_TMP_VAR) {
zval_dtor(value);
}
if (RETURN_VALUE_USED(opline)) {
@@ -37754,7 +37682,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE
} else {
expr_ptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
- if (0) { /* temporary variable */
+ if (IS_CV == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&new_expr, expr_ptr);
expr_ptr = &new_expr;
} else if (IS_CV == IS_CONST) {
@@ -37762,9 +37690,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE
ZVAL_DUP(&new_expr, expr_ptr);
expr_ptr = &new_expr;
}
- } else if (Z_ISREF_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
- expr_ptr = &new_expr;
+ } else if ((IS_CV == IS_CV || IS_CV == 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);
} else if (IS_CV == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
@@ -37889,12 +37817,9 @@ num_index_dim:
zend_hash_index_del(ht, hval);
break;
case IS_STRING:
- if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
- if (Z_REFCOUNTED_P(offset)) Z_ADDREF_P(offset);
- }
if (IS_TMP_VAR != IS_CONST) {
if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) {
- goto numeric_index_dim;
+ goto num_index_dim;
}
}
if (ht == &EG(symbol_table).ht) {
@@ -37902,15 +37827,6 @@ num_index_dim:
} else {
zend_hash_del(ht, Z_STR_P(offset));
}
- if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
- zval_ptr_dtor(offset);
- }
- break;
-numeric_index_dim:
- zend_hash_index_del(ht, hval);
- if (IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) {
- zval_ptr_dtor(offset);
- }
break;
case IS_NULL:
zend_hash_del(ht, STR_EMPTY_ALLOC());
@@ -38166,7 +38082,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
- if (!0) {
+ if (IS_CV != IS_TMP_VAR) {
zval_copy_ctor(&generator->value);
}
} else {
@@ -38196,14 +38112,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
ZVAL_DUP(&generator->value, value);
} else if (IS_CV == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if (Z_ISREF_P(value)) {
+ } else if ((IS_CV == IS_CV || IS_CV == IS_VAR) && Z_ISREF_P(value)) {
ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
} else {
+ ZVAL_COPY_VALUE(&generator->value, value);
if (IS_CV == IS_CV) {
- if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+ if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
- ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
@@ -38221,14 +38137,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
ZVAL_DUP(&generator->key, key);
} else if (IS_TMP_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if (Z_ISREF_P(key)) {
+ } else if ((IS_TMP_VAR == IS_VAR || IS_TMP_VAR == IS_CV) && Z_ISREF_P(key)) {
ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
} else {
+ ZVAL_COPY_VALUE(&generator->key, key);
if (IS_TMP_VAR == IS_CV) {
- if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+ if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
}
- ZVAL_COPY_VALUE(&generator->key, key);
}
if (Z_TYPE(generator->key) == IS_LONG
@@ -39645,7 +39561,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_AR
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 (0) {
+ if (IS_VAR == IS_TMP_VAR) {
zval_dtor(value);
}
if (RETURN_VALUE_USED(opline)) {
@@ -39833,7 +39749,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_VAR_HANDLER(ZEND_OPCODE
} else {
expr_ptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
- if (0) { /* temporary variable */
+ if (IS_CV == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&new_expr, expr_ptr);
expr_ptr = &new_expr;
} else if (IS_CV == IS_CONST) {
@@ -39841,9 +39757,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_VAR_HANDLER(ZEND_OPCODE
ZVAL_DUP(&new_expr, expr_ptr);
expr_ptr = &new_expr;
}
- } else if (Z_ISREF_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
- expr_ptr = &new_expr;
+ } else if ((IS_CV == IS_CV || IS_CV == 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);
} else if (IS_CV == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
@@ -39940,29 +39856,37 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER
zval tmp, *varname;
HashTable *target_symbol_table;
- zend_bool tmp_is_dup = 0;
SAVE_OPLINE();
if (IS_CV == IS_CV &&
IS_VAR == IS_UNUSED &&
(opline->extended_value & ZEND_QUICK_SET)) {
- ZVAL_COPY_VALUE(&tmp, EX_VAR(opline->op1.var));
- ZVAL_UNDEF(EX_VAR(opline->op1.var));
- zval_ptr_dtor(&tmp);
+ zval *var = EX_VAR(opline->op1.var);
+
+ if (Z_REFCOUNTED_P(var)) {
+ zend_refcounted *garbage = Z_COUNTED_P(var);
+
+ if (!--GC_REFCOUNT(garbage)) {
+ ZVAL_UNDEF(var);
+ _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC);
+ } else {
+ GC_ZVAL_CHECK_POSSIBLE_ROOT(var);
+ ZVAL_UNDEF(var);
+ }
+ } else {
+ ZVAL_UNDEF(var);
+ }
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
varname = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ ZVAL_UNDEF(&tmp);
if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_DUP(&tmp, varname);
convert_to_string(&tmp);
varname = &tmp;
- tmp_is_dup = 1;
- } else if (IS_CV == IS_VAR || IS_CV == IS_CV) {
- ZVAL_COPY(&tmp, varname);
- varname = &tmp;
}
if (IS_VAR != IS_UNUSED) {
@@ -39974,10 +39898,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 && tmp_is_dup) {
+ if (IS_CV != IS_CONST) {
zval_dtor(&tmp);
- } else if (IS_CV == IS_VAR || IS_CV == IS_CV) {
- zval_ptr_dtor(&tmp);
}
HANDLE_EXCEPTION();
@@ -39996,10 +39918,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 && tmp_is_dup) {
+ if (IS_CV != IS_CONST) {
zval_dtor(&tmp);
- } else if (IS_CV == IS_VAR || IS_CV == IS_CV) {
- zval_ptr_dtor(&tmp);
}
CHECK_EXCEPTION();
@@ -40040,12 +39960,9 @@ num_index_dim:
zend_hash_index_del(ht, hval);
break;
case IS_STRING:
- if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
- if (Z_REFCOUNTED_P(offset)) Z_ADDREF_P(offset);
- }
if (IS_VAR != IS_CONST) {
if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) {
- goto numeric_index_dim;
+ goto num_index_dim;
}
}
if (ht == &EG(symbol_table).ht) {
@@ -40053,15 +39970,6 @@ num_index_dim:
} else {
zend_hash_del(ht, Z_STR_P(offset));
}
- if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
- zval_ptr_dtor(offset);
- }
- break;
-numeric_index_dim:
- zend_hash_index_del(ht, hval);
- if (IS_VAR == IS_CV || IS_VAR == IS_VAR) {
- zval_ptr_dtor(offset);
- }
break;
case IS_NULL:
zend_hash_del(ht, STR_EMPTY_ALLOC());
@@ -40397,7 +40305,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
- if (!0) {
+ if (IS_CV != IS_TMP_VAR) {
zval_copy_ctor(&generator->value);
}
} else {
@@ -40427,14 +40335,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
ZVAL_DUP(&generator->value, value);
} else if (IS_CV == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if (Z_ISREF_P(value)) {
+ } else if ((IS_CV == IS_CV || IS_CV == IS_VAR) && Z_ISREF_P(value)) {
ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
} else {
+ ZVAL_COPY_VALUE(&generator->value, value);
if (IS_CV == IS_CV) {
- if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+ if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
- ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
@@ -40452,14 +40360,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
ZVAL_DUP(&generator->key, key);
} else if (IS_VAR == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if (Z_ISREF_P(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);
} else {
+ ZVAL_COPY_VALUE(&generator->key, key);
if (IS_VAR == IS_CV) {
- if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+ if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
}
- ZVAL_COPY_VALUE(&generator->key, key);
}
if (Z_TYPE(generator->key) == IS_LONG
@@ -41174,7 +41082,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPC
} else {
expr_ptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
- if (0) { /* temporary variable */
+ if (IS_CV == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&new_expr, expr_ptr);
expr_ptr = &new_expr;
} else if (IS_CV == IS_CONST) {
@@ -41182,9 +41090,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPC
ZVAL_DUP(&new_expr, expr_ptr);
expr_ptr = &new_expr;
}
- } else if (Z_ISREF_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
- expr_ptr = &new_expr;
+ } else if ((IS_CV == IS_CV || IS_CV == 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);
} else if (IS_CV == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
@@ -41281,29 +41189,37 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAND
zval tmp, *varname;
HashTable *target_symbol_table;
- zend_bool tmp_is_dup = 0;
SAVE_OPLINE();
if (IS_CV == IS_CV &&
IS_UNUSED == IS_UNUSED &&
(opline->extended_value & ZEND_QUICK_SET)) {
- ZVAL_COPY_VALUE(&tmp, EX_VAR(opline->op1.var));
- ZVAL_UNDEF(EX_VAR(opline->op1.var));
- zval_ptr_dtor(&tmp);
+ zval *var = EX_VAR(opline->op1.var);
+
+ if (Z_REFCOUNTED_P(var)) {
+ zend_refcounted *garbage = Z_COUNTED_P(var);
+
+ if (!--GC_REFCOUNT(garbage)) {
+ ZVAL_UNDEF(var);
+ _zval_dtor_func_for_ptr(garbage ZEND_FILE_LINE_CC);
+ } else {
+ GC_ZVAL_CHECK_POSSIBLE_ROOT(var);
+ ZVAL_UNDEF(var);
+ }
+ } else {
+ ZVAL_UNDEF(var);
+ }
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
varname = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
+ ZVAL_UNDEF(&tmp);
if (IS_CV != IS_CONST && Z_TYPE_P(varname) != IS_STRING) {
ZVAL_DUP(&tmp, varname);
convert_to_string(&tmp);
varname = &tmp;
- tmp_is_dup = 1;
- } else if (IS_CV == IS_VAR || IS_CV == IS_CV) {
- ZVAL_COPY(&tmp, varname);
- varname = &tmp;
}
if (IS_UNUSED != IS_UNUSED) {
@@ -41315,10 +41231,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 && tmp_is_dup) {
+ if (IS_CV != IS_CONST) {
zval_dtor(&tmp);
- } else if (IS_CV == IS_VAR || IS_CV == IS_CV) {
- zval_ptr_dtor(&tmp);
}
HANDLE_EXCEPTION();
@@ -41337,10 +41251,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 && tmp_is_dup) {
+ if (IS_CV != IS_CONST) {
zval_dtor(&tmp);
- } else if (IS_CV == IS_VAR || IS_CV == IS_CV) {
- zval_ptr_dtor(&tmp);
}
CHECK_EXCEPTION();
@@ -41461,7 +41373,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_
if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
- if (!0) {
+ if (IS_CV != IS_TMP_VAR) {
zval_copy_ctor(&generator->value);
}
} else {
@@ -41491,14 +41403,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_
ZVAL_DUP(&generator->value, value);
} else if (IS_CV == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if (Z_ISREF_P(value)) {
+ } else if ((IS_CV == IS_CV || IS_CV == IS_VAR) && Z_ISREF_P(value)) {
ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
} else {
+ ZVAL_COPY_VALUE(&generator->value, value);
if (IS_CV == IS_CV) {
- if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+ if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
- ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
@@ -41516,14 +41428,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_
ZVAL_DUP(&generator->key, key);
} else if (IS_UNUSED == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if (Z_ISREF_P(key)) {
+ } else if ((IS_UNUSED == IS_VAR || IS_UNUSED == IS_CV) && Z_ISREF_P(key)) {
ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
} else {
+ ZVAL_COPY_VALUE(&generator->key, key);
if (IS_UNUSED == IS_CV) {
- if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+ if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
}
- ZVAL_COPY_VALUE(&generator->key, key);
}
if (Z_TYPE(generator->key) == IS_LONG
@@ -42769,7 +42681,7 @@ static int ZEND_FASTCALL ZEND_ASSIGN_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARG
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 (0) {
+ if (IS_CV == IS_TMP_VAR) {
zval_dtor(value);
}
if (RETURN_VALUE_USED(opline)) {
@@ -42953,7 +42865,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_
} else {
expr_ptr = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var TSRMLS_CC);
- if (0) { /* temporary variable */
+ if (IS_CV == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&new_expr, expr_ptr);
expr_ptr = &new_expr;
} else if (IS_CV == IS_CONST) {
@@ -42961,9 +42873,9 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_
ZVAL_DUP(&new_expr, expr_ptr);
expr_ptr = &new_expr;
}
- } else if (Z_ISREF_P(expr_ptr)) {
- ZVAL_DUP(&new_expr, Z_REFVAL_P(expr_ptr));
- expr_ptr = &new_expr;
+ } else if ((IS_CV == IS_CV || IS_CV == 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);
} else if (IS_CV == IS_CV && Z_REFCOUNTED_P(expr_ptr)) {
Z_ADDREF_P(expr_ptr);
@@ -43088,12 +43000,9 @@ num_index_dim:
zend_hash_index_del(ht, hval);
break;
case IS_STRING:
- if (IS_CV == IS_CV || IS_CV == IS_VAR) {
- if (Z_REFCOUNTED_P(offset)) Z_ADDREF_P(offset);
- }
if (IS_CV != IS_CONST) {
if (ZEND_HANDLE_NUMERIC(Z_STR_P(offset), hval)) {
- goto numeric_index_dim;
+ goto num_index_dim;
}
}
if (ht == &EG(symbol_table).ht) {
@@ -43101,15 +43010,6 @@ num_index_dim:
} else {
zend_hash_del(ht, Z_STR_P(offset));
}
- if (IS_CV == IS_CV || IS_CV == IS_VAR) {
- zval_ptr_dtor(offset);
- }
- break;
-numeric_index_dim:
- zend_hash_index_del(ht, hval);
- if (IS_CV == IS_CV || IS_CV == IS_VAR) {
- zval_ptr_dtor(offset);
- }
break;
case IS_NULL:
zend_hash_del(ht, STR_EMPTY_ALLOC());
@@ -43363,7 +43263,7 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
if (Z_OPT_REFCOUNTED(generator->value)) Z_SET_REFCOUNT(generator->value, 1);
/* Temporary variables don't need ctor copying */
- if (!0) {
+ if (IS_CV != IS_TMP_VAR) {
zval_copy_ctor(&generator->value);
}
} else {
@@ -43393,14 +43293,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
ZVAL_DUP(&generator->value, value);
} else if (IS_CV == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->value, value);
- } else if (Z_ISREF_P(value)) {
+ } else if ((IS_CV == IS_CV || IS_CV == IS_VAR) && Z_ISREF_P(value)) {
ZVAL_DUP(&generator->value, Z_REFVAL_P(value));
} else {
+ ZVAL_COPY_VALUE(&generator->value, value);
if (IS_CV == IS_CV) {
- if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value);
+ if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
}
- ZVAL_COPY_VALUE(&generator->value, value);
}
}
} else {
@@ -43418,14 +43318,14 @@ static int ZEND_FASTCALL ZEND_YIELD_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
ZVAL_DUP(&generator->key, key);
} else if (IS_CV == IS_TMP_VAR) {
ZVAL_COPY_VALUE(&generator->key, key);
- } else if (Z_ISREF_P(key)) {
+ } else if ((IS_CV == IS_VAR || IS_CV == IS_CV) && Z_ISREF_P(key)) {
ZVAL_DUP(&generator->key, Z_REFVAL_P(key));
} else {
+ ZVAL_COPY_VALUE(&generator->key, key);
if (IS_CV == IS_CV) {
- if (Z_REFCOUNTED_P(key)) Z_ADDREF_P(key);
+ if (Z_OPT_REFCOUNTED_P(key)) Z_ADDREF_P(key);
}
- ZVAL_COPY_VALUE(&generator->key, key);
}
if (Z_TYPE(generator->key) == IS_LONG
diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php
index df4ac12d3a..ac7a96ce61 100644
--- a/Zend/zend_vm_gen.php
+++ b/Zend/zend_vm_gen.php
@@ -243,24 +243,6 @@ $op2_get_obj_zval_ptr_ptr = array(
"CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op2.var TSRMLS_CC)",
);
-$op1_is_tmp_free = array(
- "ANY" => "IS_TMP_FREE(free_op1)",
- "TMP" => "1",
- "VAR" => "0",
- "CONST" => "0",
- "UNUSED" => "0",
- "CV" => "0",
-);
-
-$op2_is_tmp_free = array(
- "ANY" => "IS_TMP_FREE(free_op2)",
- "TMP" => "1",
- "VAR" => "0",
- "CONST" => "0",
- "UNUSED" => "0",
- "CV" => "0",
-);
-
$op1_free_op = array(
"ANY" => "FREE_OP(free_op1)",
"TMP" => "zval_dtor(free_op1.var)",
@@ -366,7 +348,7 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) {
$op1_get_obj_zval_ptr, $op2_get_obj_zval_ptr,
$op1_get_obj_zval_ptr_deref, $op2_get_obj_zval_ptr_deref,
$op1_get_obj_zval_ptr_ptr, $op2_get_obj_zval_ptr_ptr,
- $op1_is_tmp_free, $op2_is_tmp_free, $op1_free, $op2_free,
+ $op1_free, $op2_free,
$op1_free_op, $op2_free_op, $op1_free_op_if_var, $op2_free_op_if_var,
$op1_free_op_var_ptr, $op2_free_op_var_ptr, $prefix;
@@ -391,8 +373,6 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) {
"/GET_OP2_OBJ_ZVAL_PTR_DEREF\(([^)]*)\)/",
"/GET_OP1_OBJ_ZVAL_PTR_PTR\(([^)]*)\)/",
"/GET_OP2_OBJ_ZVAL_PTR_PTR\(([^)]*)\)/",
- "/IS_OP1_TMP_FREE\(\)/",
- "/IS_OP2_TMP_FREE\(\)/",
"/FREE_OP1\(\)/",
"/FREE_OP2\(\)/",
"/FREE_OP1_IF_VAR\(\)/",
@@ -429,8 +409,6 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) {
$op2_get_obj_zval_ptr_deref[$op2],
$op1_get_obj_zval_ptr_ptr[$op1],
$op2_get_obj_zval_ptr_ptr[$op2],
- $op1_is_tmp_free[$op1],
- $op2_is_tmp_free[$op2],
$op1_free_op[$op1],
$op2_free_op[$op2],
$op1_free_op_if_var[$op1],
diff --git a/configure.in b/configure.in
index bcdd55a51c..697cc0225a 100644
--- a/configure.in
+++ b/configure.in
@@ -1483,7 +1483,7 @@ esac
PHP_ADD_SOURCES(Zend, \
zend_language_parser.c zend_language_scanner.c \
zend_ini_parser.c zend_ini_scanner.c \
- zend_alloc.c zend_compile.c zend_constants.c zend_dynamic_array.c zend_dtrace.c \
+ zend_alloc.c zend_compile.c zend_constants.c zend_dtrace.c \
zend_execute_API.c zend_highlight.c zend_llist.c \
zend_vm_opcodes.c zend_opcode.c zend_operators.c zend_ptr_stack.c zend_stack.c \
zend_variables.c zend.c zend_API.c zend_extensions.c zend_hash.c \
diff --git a/ext/opcache/Optimizer/block_pass.c b/ext/opcache/Optimizer/block_pass.c
index 1f873912b4..31f76b6ca2 100644
--- a/ext/opcache/Optimizer/block_pass.c
+++ b/ext/opcache/Optimizer/block_pass.c
@@ -1116,7 +1116,7 @@ static void zend_optimize_block(zend_code_block *block, zend_op_array *op_array,
opline->opcode == ZEND_ADD_CHAR ||
opline->opcode == ZEND_ADD_VAR ||
opline->opcode == ZEND_CONCAT) &&
- ZEND_OP1_TYPE(opline) == (IS_TMP_VAR|IS_VAR) &&
+ (ZEND_OP1_TYPE(opline) & (IS_TMP_VAR|IS_VAR)) &&
VAR_SOURCE(opline->op1) &&
VAR_SOURCE(opline->op1)->opcode == ZEND_CAST &&
VAR_SOURCE(opline->op1)->extended_value == IS_STRING) {
diff --git a/ext/standard/basic_functions.h b/ext/standard/basic_functions.h
index 9490754b23..a6d8496d75 100644
--- a/ext/standard/basic_functions.h
+++ b/ext/standard/basic_functions.h
@@ -204,11 +204,11 @@ typedef struct _php_basic_globals {
zend_class_entry *incomplete_class;
unsigned serialize_lock; /* whether to use the locally supplied var_hash instead (__sleep/__wakeup) */
struct {
- void *var_hash;
+ struct php_serialize_data *data;
unsigned level;
} serialize;
struct {
- void *var_hash;
+ struct php_unserialize_data *data;
unsigned level;
} unserialize;
diff --git a/ext/standard/php_var.h b/ext/standard/php_var.h
index 90979159ab..23225cdc42 100644
--- a/ext/standard/php_var.h
+++ b/ext/standard/php_var.h
@@ -38,7 +38,10 @@ PHPAPI void php_var_export_ex(zval *struc, int level, smart_str *buf TSRMLS_DC);
PHPAPI void php_debug_zval_dump(zval *struc, int level TSRMLS_DC);
-typedef HashTable* php_serialize_data_t;
+struct php_serialize_data {
+ HashTable ht;
+ uint32_t n;
+};
struct php_unserialize_data {
void *first;
@@ -47,71 +50,67 @@ struct php_unserialize_data {
void *last_dtor;
};
-typedef struct php_unserialize_data* php_unserialize_data_t;
+typedef struct php_serialize_data *php_serialize_data_t;
+typedef struct php_unserialize_data *php_unserialize_data_t;
-PHPAPI void php_var_serialize(smart_str *buf, zval *struc, php_serialize_data_t *var_hash TSRMLS_DC);
+PHPAPI void php_var_serialize(smart_str *buf, zval *struc, php_serialize_data_t *data TSRMLS_DC);
PHPAPI int php_var_unserialize(zval *rval, const unsigned char **p, const unsigned char *max, php_unserialize_data_t *var_hash TSRMLS_DC);
PHPAPI int php_var_unserialize_ref(zval *rval, const unsigned char **p, const unsigned char *max, php_unserialize_data_t *var_hash TSRMLS_DC);
PHPAPI int php_var_unserialize_intern(zval *rval, const unsigned char **p, const unsigned char *max, php_unserialize_data_t *var_hash TSRMLS_DC);
-#define PHP_VAR_SERIALIZE_INIT(var_hash_ptr) \
+#define PHP_VAR_SERIALIZE_INIT(d) \
do { \
/* fprintf(stderr, "SERIALIZE_INIT == lock: %u, level: %u\n", BG(serialize_lock), BG(serialize).level); */ \
if (BG(serialize_lock) || !BG(serialize).level) { \
- ALLOC_HASHTABLE(var_hash_ptr); \
- zend_hash_init((var_hash_ptr), 16, NULL, NULL, 0); \
+ (d) = (php_serialize_data_t) emalloc(sizeof(struct php_serialize_data)); \
+ zend_hash_init(&(d)->ht, 16, NULL, ZVAL_PTR_DTOR, 0); \
+ (d)->n = 0; \
if (!BG(serialize_lock)) { \
- BG(serialize).var_hash = (void *)(var_hash_ptr); \
+ BG(serialize).data = d; \
BG(serialize).level = 1; \
} \
} else { \
- (var_hash_ptr) = (php_serialize_data_t)BG(serialize).var_hash; \
+ (d) = BG(serialize).data; \
++BG(serialize).level; \
} \
} while(0)
-#define PHP_VAR_SERIALIZE_DESTROY(var_hash_ptr) \
+#define PHP_VAR_SERIALIZE_DESTROY(d) \
do { \
/* fprintf(stderr, "SERIALIZE_DESTROY == lock: %u, level: %u\n", BG(serialize_lock), BG(serialize).level); */ \
- if (BG(serialize_lock) || !BG(serialize).level) { \
- zend_hash_destroy((var_hash_ptr)); \
- FREE_HASHTABLE(var_hash_ptr); \
- } else { \
- if (!--BG(serialize).level) { \
- zend_hash_destroy((php_serialize_data_t)BG(serialize).var_hash); \
- FREE_HASHTABLE((php_serialize_data_t)BG(serialize).var_hash); \
- BG(serialize).var_hash = NULL; \
- } \
+ if (BG(serialize_lock) || BG(serialize).level == 1) { \
+ zend_hash_destroy(&(d)->ht); \
+ efree((d)); \
+ } \
+ if (!BG(serialize_lock) && !--BG(serialize).level) { \
+ BG(serialize).data = NULL; \
} \
} while (0)
-#define PHP_VAR_UNSERIALIZE_INIT(var_hash_ptr) \
+#define PHP_VAR_UNSERIALIZE_INIT(d) \
do { \
/* fprintf(stderr, "UNSERIALIZE_INIT == lock: %u, level: %u\n", BG(serialize_lock), BG(unserialize).level); */ \
if (BG(serialize_lock) || !BG(unserialize).level) { \
- (var_hash_ptr) = (php_unserialize_data_t)ecalloc(1, sizeof(struct php_unserialize_data)); \
+ (d) = (php_unserialize_data_t)ecalloc(1, sizeof(struct php_unserialize_data)); \
if (!BG(serialize_lock)) { \
- BG(unserialize).var_hash = (void *)(var_hash_ptr); \
+ BG(unserialize).data = (d); \
BG(unserialize).level = 1; \
} \
} else { \
- (var_hash_ptr) = (php_unserialize_data_t)BG(unserialize).var_hash; \
+ (d) = BG(unserialize).data; \
++BG(unserialize).level; \
} \
} while (0)
-#define PHP_VAR_UNSERIALIZE_DESTROY(var_hash_ptr) \
+#define PHP_VAR_UNSERIALIZE_DESTROY(d) \
do { \
/* fprintf(stderr, "UNSERIALIZE_DESTROY == lock: %u, level: %u\n", BG(serialize_lock), BG(unserialize).level); */ \
- if (BG(serialize_lock) || !BG(unserialize).level) { \
- var_destroy(&(var_hash_ptr)); \
- efree(var_hash_ptr); \
- } else { \
- if (!--BG(unserialize).level) { \
- var_destroy(&(var_hash_ptr)); \
- efree((var_hash_ptr)); \
- BG(unserialize).var_hash = NULL; \
- } \
+ if (BG(serialize_lock) || BG(unserialize).level == 1) { \
+ var_destroy(&(d)); \
+ efree((d)); \
+ } \
+ if (!BG(serialize_lock) && !--BG(unserialize).level) { \
+ BG(unserialize).data = NULL; \
} \
} while (0)
@@ -120,50 +119,4 @@ PHPAPI void var_push_dtor(php_unserialize_data_t *var_hash, zval *val);
PHPAPI void var_push_dtor_no_addref(php_unserialize_data_t *var_hashx, zval *rval);
PHPAPI void var_destroy(php_unserialize_data_t *var_hash);
-PHPAPI zend_class_entry *php_create_empty_class(char *class_name, int len);
-
-static inline int php_varname_check(char *name, int name_len, zend_bool silent TSRMLS_DC) /* {{{ */
-{
- if (name_len == sizeof("GLOBALS") - 1 && !memcmp(name, "GLOBALS", sizeof("GLOBALS") - 1)) {
- if (!silent) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempted GLOBALS variable overwrite");
- }
- return FAILURE;
- } else if (name[0] == '_' &&
- (
- (name_len == sizeof("_GET") - 1 && !memcmp(name, "_GET", sizeof("_GET") - 1)) ||
- (name_len == sizeof("_POST") - 1 && !memcmp(name, "_POST", sizeof("_POST") - 1)) ||
- (name_len == sizeof("_COOKIE") - 1 && !memcmp(name, "_COOKIE", sizeof("_COOKIE") - 1)) ||
- (name_len == sizeof("_ENV") - 1 && !memcmp(name, "_ENV", sizeof("_ENV") - 1)) ||
- (name_len == sizeof("_SERVER") - 1 && !memcmp(name, "_SERVER", sizeof("_SERVER") - 1)) ||
- (name_len == sizeof("_SESSION") - 1 && !memcmp(name, "_SESSION", sizeof("_SESSION") - 1)) ||
- (name_len == sizeof("_FILES") - 1 && !memcmp(name, "_FILES", sizeof("_FILES") - 1)) ||
- (name_len == sizeof("_REQUEST") -1 && !memcmp(name, "_REQUEST", sizeof("_REQUEST") - 1))
- )
- ) {
- if (!silent) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempted super-global (%s) variable overwrite", name);
- }
- return FAILURE;
- } else if (name[0] == 'H' &&
- (
- (name_len == sizeof("HTTP_POST_VARS") - 1 && !memcmp(name, "HTTP_POST_VARS", sizeof("HTTP_POST_VARS") - 1)) ||
- (name_len == sizeof("HTTP_GET_VARS") - 1 && !memcmp(name, "HTTP_GET_VARS", sizeof("HTTP_GET_VARS") - 1)) ||
- (name_len == sizeof("HTTP_COOKIE_VARS") - 1 && !memcmp(name, "HTTP_COOKIE_VARS", sizeof("HTTP_COOKIE_VARS") - 1)) ||
- (name_len == sizeof("HTTP_ENV_VARS") - 1 && !memcmp(name, "HTTP_ENV_VARS", sizeof("HTTP_ENV_VARS") - 1)) ||
- (name_len == sizeof("HTTP_SERVER_VARS") - 1 && !memcmp(name, "HTTP_SERVER_VARS", sizeof("HTTP_SERVER_VARS") - 1)) ||
- (name_len == sizeof("HTTP_SESSION_VARS") - 1 && !memcmp(name, "HTTP_SESSION_VARS", sizeof("HTTP_SESSION_VARS") - 1)) ||
- (name_len == sizeof("HTTP_RAW_POST_DATA") - 1 && !memcmp(name, "HTTP_RAW_POST_DATA", sizeof("HTTP_RAW_POST_DATA") - 1)) ||
- (name_len == sizeof("HTTP_POST_FILES") - 1 && !memcmp(name, "HTTP_POST_FILES", sizeof("HTTP_POST_FILES") - 1))
- )
- ) {
- if (!silent) {
- php_error_docref(NULL TSRMLS_CC, E_WARNING, "Attempted long input array (%s) overwrite", name);
- }
- return FAILURE;
- }
- return SUCCESS;
-}
-/* }}} */
-
#endif /* PHP_VAR_H */
diff --git a/ext/standard/var.c b/ext/standard/var.c
index f9d897a4ec..194715edf0 100644
--- a/ext/standard/var.c
+++ b/ext/standard/var.c
@@ -598,54 +598,45 @@ PHP_FUNCTION(var_export)
}
/* }}} */
-static void php_var_serialize_intern(smart_str *buf, zval *struc, HashTable *var_hash TSRMLS_DC);
+static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_data_t var_hash TSRMLS_DC);
-static inline int php_add_var_hash(HashTable *var_hash, zval *var_ptr, zval *var_old TSRMLS_DC) /* {{{ */
+static inline uint32_t php_add_var_hash(php_serialize_data_t data, zval *var TSRMLS_DC) /* {{{ */
{
- zval var_no, *zv;
- char id[32], *p;
- register int len;
- zval *var = var_ptr;
+ zval *zv;
+ zend_ulong key;
- if (Z_ISREF_P(var)) {
- var = Z_REFVAL_P(var);
- }
- if ((Z_TYPE_P(var) == IS_OBJECT) && Z_OBJ_HT_P(var)->get_class_entry) {
- p = zend_print_long_to_buf(id + sizeof(id) - 1,
- (zend_long) Z_OBJ_P(var));
- *(--p) = 'O';
- len = id + sizeof(id) - 1 - p;
- } else if (var_ptr != var) {
- p = zend_print_long_to_buf(id + sizeof(id) - 1,
- (zend_long) Z_REF_P(var_ptr));
- *(--p) = 'R';
- len = id + sizeof(id) - 1 - p;
- } else {
- p = zend_print_long_to_buf(id + sizeof(id) - 1, (zend_long) var);
- len = id + sizeof(id) - 1 - p;
+ data->n += 1;
+
+ if (Z_TYPE_P(var) != IS_OBJECT && Z_TYPE_P(var) != IS_REFERENCE) {
+ return 0;
}
- if ((zv = zend_hash_str_find(var_hash, p, len)) != NULL) {
- ZVAL_COPY_VALUE(var_old, zv);
- if (var == var_ptr) {
- /* we still need to bump up the counter, since non-refs will
- * be counted separately by unserializer */
- ZVAL_LONG(&var_no, -1);
- zend_hash_next_index_insert(var_hash, &var_no);
- }
-#if 0
- fprintf(stderr, "- had var (%d): %lu\n", Z_TYPE_P(var), **(zend_ulong**)var_old);
-#endif
- return FAILURE;
+ /* References to objects are treated as if the reference didn't exist */
+ if (Z_TYPE_P(var) == IS_REFERENCE && Z_TYPE_P(Z_REFVAL_P(var)) == IS_OBJECT) {
+ var = Z_REFVAL_P(var);
}
- /* +1 because otherwise hash will think we are trying to store NULL pointer */
- ZVAL_LONG(&var_no, zend_hash_num_elements(var_hash) + 1);
- zend_hash_str_add(var_hash, p, len, &var_no);
-#if 0
- fprintf(stderr, "+ add var (%d): %lu\n", Z_TYPE_P(var), Z_LVAL(var_no));
-#endif
- return SUCCESS;
+ /* Index for the variable is stored using the numeric value of the pointer to
+ * the zend_refcounted struct */
+ key = (zend_ulong) (zend_uintptr_t) Z_COUNTED_P(var);
+ zv = zend_hash_index_find(&data->ht, key);
+
+ if (zv) {
+ return Z_LVAL_P(zv);
+ } else {
+ zval zv_n;
+ ZVAL_LONG(&zv_n, data->n);
+ zend_hash_index_add_new(&data->ht, key, &zv_n);
+
+ /* Additionally to the index, we also store the variable, to ensure that it is
+ * not destroyed during serialization and its pointer reused. The variable is
+ * stored at the numeric value of the pointer + 1, which cannot be the location
+ * of another zend_refcounted structure. */
+ zend_hash_index_add_new(&data->ht, key + 1, var);
+ Z_ADDREF_P(var);
+
+ return 0;
+ }
}
/* }}} */
@@ -682,7 +673,7 @@ static inline zend_bool php_var_serialize_class_name(smart_str *buf, zval *struc
}
/* }}} */
-static void php_var_serialize_class(smart_str *buf, zval *struc, zval *retval_ptr, HashTable *var_hash TSRMLS_DC) /* {{{ */
+static void php_var_serialize_class(smart_str *buf, zval *struc, zval *retval_ptr, php_serialize_data_t var_hash TSRMLS_DC) /* {{{ */
{
uint32_t count;
zend_bool incomplete_class;
@@ -780,27 +771,24 @@ static void php_var_serialize_class(smart_str *buf, zval *struc, zval *retval_pt
}
/* }}} */
-static void php_var_serialize_intern(smart_str *buf, zval *struc, HashTable *var_hash TSRMLS_DC) /* {{{ */
+static void php_var_serialize_intern(smart_str *buf, zval *struc, php_serialize_data_t var_hash TSRMLS_DC) /* {{{ */
{
- zval var_already;
+ uint32_t var_already;
HashTable *myht;
if (EG(exception)) {
return;
}
- ZVAL_UNDEF(&var_already);
-
- if (var_hash &&
- php_add_var_hash(var_hash, struc, &var_already TSRMLS_CC) == FAILURE) {
+ if (var_hash && (var_already = php_add_var_hash(var_hash, struc TSRMLS_CC))) {
if (Z_ISREF_P(struc)) {
smart_str_appendl(buf, "R:", 2);
- smart_str_append_long(buf, Z_LVAL(var_already));
+ smart_str_append_long(buf, var_already);
smart_str_appendc(buf, ';');
return;
} else if (Z_TYPE_P(struc) == IS_OBJECT) {
smart_str_appendl(buf, "r:", 2);
- smart_str_append_long(buf, Z_LVAL(var_already));
+ smart_str_append_long(buf, var_already);
smart_str_appendc(buf, ';');
return;
}
@@ -971,9 +959,9 @@ again:
}
/* }}} */
-PHPAPI void php_var_serialize(smart_str *buf, zval *struc, php_serialize_data_t *var_hash TSRMLS_DC) /* {{{ */
+PHPAPI void php_var_serialize(smart_str *buf, zval *struc, php_serialize_data_t *data TSRMLS_DC) /* {{{ */
{
- php_var_serialize_intern(buf, struc, *var_hash TSRMLS_CC);
+ php_var_serialize_intern(buf, struc, *data TSRMLS_CC);
smart_str_0(buf);
}
/* }}} */
diff --git a/win32/build/config.w32 b/win32/build/config.w32
index a7b525075d..f0689c2792 100644
--- a/win32/build/config.w32
+++ b/win32/build/config.w32
@@ -354,7 +354,7 @@ STDOUT.WriteLine("PHP Core: " + get_define('PHPDLL') + " and " + get_define('PH
ADD_SOURCES("Zend", "zend_language_parser.c zend_language_scanner.c \
zend_ini_parser.c zend_ini_scanner.c zend_alloc.c zend_compile.c \
- zend_constants.c zend_dynamic_array.c zend_exceptions.c \
+ zend_constants.c zend_exceptions.c \
zend_execute_API.c zend_highlight.c \
zend_llist.c zend_vm_opcodes.c zend_opcode.c zend_operators.c zend_ptr_stack.c \
zend_stack.c zend_variables.c zend.c zend_API.c zend_extensions.c \
diff --git a/win32/build/projectgen.js b/win32/build/projectgen.js
index 8adb887786..0ed8cc404b 100644
--- a/win32/build/projectgen.js
+++ b/win32/build/projectgen.js
@@ -46,7 +46,6 @@ function write_src_file(fname, path, intpath, arr)
if (arr[i].match('alloca.c') ||
arr[i].match(/internal_functions_(nw|win32)\.c/) ||
arr[i].match(/flock\.(c|h)/) ||
- arr[i].match(/zend_static_allocator\.(c|h)/) ||
arr[i].match(/zend_(ini|language)_scanner_defs\.h/)) {
continue;
}