summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXinchen Hui <laruence@gmail.com>2014-03-26 23:25:26 +0800
committerXinchen Hui <laruence@gmail.com>2014-03-26 23:25:26 +0800
commit903b6b59bfefb5dd5be1efaec0d53d3fc4d9d06e (patch)
tree15756a8d9ac274e7e38226750ae47a984a64f478
parentc9bca5039be162bd056909ce9c21f6fd96e5204a (diff)
parent887189ca31eeac5f1f7dbcaf54405de0dc432f2d (diff)
downloadphp-git-903b6b59bfefb5dd5be1efaec0d53d3fc4d9d06e.tar.gz
Merge branch 'refactoring2' of github.com:zendtech/php into refactoring2
-rw-r--r--Zend/zend.c7
-rw-r--r--Zend/zend_API.c67
-rw-r--r--Zend/zend_API.h9
-rw-r--r--Zend/zend_builtin_functions.c22
-rw-r--r--Zend/zend_execute.c166
-rw-r--r--Zend/zend_execute_API.c168
-rw-r--r--Zend/zend_gc.c2
-rw-r--r--Zend/zend_hash.c144
-rw-r--r--Zend/zend_hash.h68
-rw-r--r--Zend/zend_object_handlers.c184
-rw-r--r--Zend/zend_objects.c43
-rw-r--r--Zend/zend_variables.c12
-rw-r--r--Zend/zend_vm_def.h136
-rw-r--r--Zend/zend_vm_execute.h1068
-rw-r--r--ext/reflection/php_reflection.c39
-rw-r--r--ext/spl/spl_array.c102
-rw-r--r--ext/standard/array.c75
-rw-r--r--ext/standard/basic_functions.c9
-rw-r--r--ext/standard/http.c6
-rw-r--r--ext/standard/http_fopen_wrapper.c2
-rw-r--r--ext/standard/var.c114
-rw-r--r--ext/standard/var_unserializer.c78
-rw-r--r--ext/standard/var_unserializer.re18
-rw-r--r--main/main.c15
-rw-r--r--main/php_variables.c19
25 files changed, 1399 insertions, 1174 deletions
diff --git a/Zend/zend.c b/Zend/zend.c
index a494c97dc9..8b58d4b8b0 100644
--- a/Zend/zend.c
+++ b/Zend/zend.c
@@ -144,6 +144,13 @@ static void print_hash(zend_write_func_t write_func, HashTable *ht, int indent,
indent += PRINT_ZVAL_INDENT;
zend_hash_internal_pointer_reset_ex(ht, &iterator);
while ((tmp = zend_hash_get_current_data_ex(ht, &iterator)) != NULL) {
+ if (Z_TYPE_P(tmp) == IS_INDIRECT) {
+ tmp = Z_INDIRECT_P(tmp);
+ if (Z_TYPE_P(tmp) == IS_UNDEF) {
+ zend_hash_move_forward_ex(ht, &iterator);
+ continue;
+ }
+ }
for (i = 0; i < indent; i++) {
ZEND_PUTS_EX(" ");
}
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index e9d30811db..c0bb644ee2 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -1230,6 +1230,70 @@ ZEND_API void object_properties_init(zend_object *object, zend_class_entry *clas
}
/* }}} */
+ZEND_API void object_properties_init_ex(zend_object *object, HashTable *properties) /* {{{ */
+{
+ object->properties = properties;
+ if (object->ce->default_properties_count) {
+ HashPosition pos;
+ zval *prop, tmp;
+ zend_string *key;
+ ulong num_key;
+ zend_property_info *property_info;
+
+ for (zend_hash_internal_pointer_reset_ex(properties, &pos);
+ (prop = zend_hash_get_current_data_ex(properties, &pos)) != NULL &&
+ zend_hash_get_current_key_ex(properties, &key, &num_key, 0, &pos) == HASH_KEY_IS_STRING;
+ zend_hash_move_forward_ex(properties, &pos)) {
+
+ ZVAL_STR(&tmp, key);
+ property_info = zend_get_property_info(object->ce, &tmp, 1 TSRMLS_CC);
+ if (property_info &&
+ (property_info->flags & ZEND_ACC_STATIC) == 0 &&
+ property_info->offset >= 0) {
+ ZVAL_COPY_VALUE(&object->properties_table[property_info->offset], prop);
+ ZVAL_INDIRECT(prop, &object->properties_table[property_info->offset]);
+ }
+ }
+ }
+}
+/* }}} */
+
+ZEND_API void object_properties_load(zend_object *object, HashTable *properties) /* {{{ */
+{
+ HashPosition pos;
+ zval *prop, tmp;
+ zend_string *key;
+ ulong num_key;
+ zend_property_info *property_info;
+
+ for (zend_hash_internal_pointer_reset_ex(properties, &pos);
+ (prop = zend_hash_get_current_data_ex(properties, &pos)) != NULL &&
+ zend_hash_get_current_key_ex(properties, &key, &num_key, 0, &pos) == HASH_KEY_IS_STRING;
+ zend_hash_move_forward_ex(properties, &pos)) {
+
+ ZVAL_STR(&tmp, key);
+ property_info = zend_get_property_info(object->ce, &tmp, 1 TSRMLS_CC);
+ if (property_info &&
+ (property_info->flags & ZEND_ACC_STATIC) == 0 &&
+ property_info->offset >= 0) {
+ zval_ptr_dtor(&object->properties_table[property_info->offset]);
+ ZVAL_COPY_VALUE(&object->properties_table[property_info->offset], prop);
+ zval_add_ref(&object->properties_table[property_info->offset]);
+ if (object->properties) {
+ ZVAL_INDIRECT(&tmp, &object->properties_table[property_info->offset]);
+ prop = zend_hash_update(object->properties, key, &tmp);
+ }
+ } else {
+ if (!object->properties) {
+ rebuild_object_properties(object);
+ }
+ prop = zend_hash_update(object->properties, key, prop);
+ zval_add_ref(prop);
+ }
+ }
+}
+/* }}} */
+
/* This function requires 'properties' to contain all props declared in the
* class and all props being public. If only a subset is given or the class
* has protected members then you need to merge the properties separately by
@@ -1248,8 +1312,7 @@ ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *class_type
if (class_type->create_object == NULL) {
ZVAL_OBJ(arg, zend_objects_new(class_type TSRMLS_CC));
if (properties) {
- Z_OBJ_P(arg)->properties = properties;
-//??? Z_OBJ_P(arg)->properties_table = NULL;
+ object_properties_init_ex(Z_OBJ_P(arg), properties);
} else {
object_properties_init(Z_OBJ_P(arg), class_type);
}
diff --git a/Zend/zend_API.h b/Zend/zend_API.h
index 9afcde846d..05973d63dc 100644
--- a/Zend/zend_API.h
+++ b/Zend/zend_API.h
@@ -366,6 +366,8 @@ ZEND_API int _object_init(zval *arg ZEND_FILE_LINE_DC TSRMLS_DC);
ZEND_API int _object_init_ex(zval *arg, zend_class_entry *ce ZEND_FILE_LINE_DC TSRMLS_DC);
ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *ce, HashTable *properties ZEND_FILE_LINE_DC TSRMLS_DC);
ZEND_API void object_properties_init(zend_object *object, zend_class_entry *class_type);
+ZEND_API void object_properties_init_ex(zend_object *object, HashTable *properties);
+ZEND_API void object_properties_load(zend_object *object, HashTable *properties);
ZEND_API void zend_merge_properties(zval *obj, HashTable *properties, int destroy_ht TSRMLS_DC);
@@ -515,13 +517,12 @@ ZEND_API int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci
ZEND_API int zend_set_hash_symbol(zval *symbol, const char *name, int name_length, zend_bool is_ref, int num_symbol_tables, ...);
-ZEND_API void zend_delete_variable(zend_execute_data *ex, HashTable *ht, zend_string *name TSRMLS_DC);
-
ZEND_API int zend_delete_global_variable(zend_string *name TSRMLS_DC);
-ZEND_API void zend_reset_all_cv(zend_array *symbol_table TSRMLS_DC);
-
ZEND_API void zend_rebuild_symbol_table(TSRMLS_D);
+ZEND_API void zend_attach_symbol_table(TSRMLS_D);
+ZEND_API void zend_detach_symbol_table(TSRMLS_D);
+ZEND_API int zend_set_local_var(const char *name, int len, zval *value, int force TSRMLS_DC);
ZEND_API zend_string *zend_find_alias_name(zend_class_entry *ce, zend_string *name);
ZEND_API zend_string *zend_resolve_method_name(zend_class_entry *ce, zend_function *f);
diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c
index 5691fd0b69..06c4774873 100644
--- a/Zend/zend_builtin_functions.c
+++ b/Zend/zend_builtin_functions.c
@@ -593,9 +593,18 @@ ZEND_FUNCTION(each)
zend_error(E_WARNING,"Variable passed to each() is not an array or object");
return;
}
- entry = zend_hash_get_current_data(target_hash);
- if (!entry) {
- RETURN_FALSE;
+ while (1) {
+ entry = zend_hash_get_current_data(target_hash);
+ if (!entry) {
+ RETURN_FALSE;
+ } else if (Z_TYPE_P(entry) == IS_INDIRECT) {
+ entry = Z_INDIRECT_P(entry);
+ if (Z_TYPE_P(entry) == IS_UNDEF) {
+ zend_hash_move_forward(target_hash);
+ continue;
+ }
+ }
+ break;
}
array_init(return_value);
@@ -999,6 +1008,13 @@ ZEND_FUNCTION(get_object_vars)
zend_hash_internal_pointer_reset_ex(properties, &pos);
while ((value = zend_hash_get_current_data_ex(properties, &pos)) != NULL) {
+ if (Z_TYPE_P(value) == IS_INDIRECT) {
+ value = Z_INDIRECT_P(value);
+ if (Z_TYPE_P(value) == IS_UNDEF) {
+ zend_hash_move_forward_ex(properties, &pos);
+ continue;
+ }
+ }
if (zend_hash_get_current_key_ex(properties, &key, &num_index, 0, &pos) == HASH_KEY_IS_STRING) {
if (zend_check_property_access(zobj, key TSRMLS_CC) == SUCCESS) {
zend_unmangle_property_name_ex(key->val, key->len, &class_name, &prop_name, (int*) &prop_len);
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index bc498fee0a..51f58cf2cd 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -206,52 +206,31 @@ static zend_always_inline zval *_get_zval_ptr_var_deref(zend_uint var, const zen
static zend_never_inline zval *_get_zval_cv_lookup(zval *ptr, zend_uint var, int type TSRMLS_DC)
{
- zend_string *cv = CV_DEF_OF(var);
- zval *ret = NULL;
-
- if (EG(active_symbol_table)) {
- ret = zend_hash_find(&EG(active_symbol_table)->ht, cv);
- if (ret) {
- ZVAL_INDIRECT(ptr, ret);
- return ret;
- }
- }
+ zend_string *cv;
switch (type) {
case BP_VAR_R:
case BP_VAR_UNSET:
+ cv = CV_DEF_OF(var);
zend_error(E_NOTICE, "Undefined variable: %s", cv->val);
/* break missing intentionally */
case BP_VAR_IS:
- return &EG(uninitialized_zval);
+ ptr = &EG(uninitialized_zval);
+ break;
case BP_VAR_RW:
+ cv = CV_DEF_OF(var);
zend_error(E_NOTICE, "Undefined variable: %s", cv->val);
/* break missing intentionally */
case BP_VAR_W:
- if (EG(active_symbol_table)) {
- ret = zend_hash_update(&EG(active_symbol_table)->ht, cv, ret);
- ZVAL_INDIRECT(ptr, ret);
- } else {
- ZVAL_NULL(ptr);
- ret = ptr;
- }
+ ZVAL_NULL(ptr);
break;
}
- return ret;
+ return ptr;
}
static zend_never_inline zval *_get_zval_cv_lookup_BP_VAR_R(zval *ptr, zend_uint var TSRMLS_DC)
{
zend_string *cv = CV_DEF_OF(var);
- zval *ret = NULL;
-
- if (EG(active_symbol_table)) {
- ret = zend_hash_find(&EG(active_symbol_table)->ht, cv);
- if (ret) {
- ZVAL_INDIRECT(ptr, ret);
- return ret;
- }
- }
zend_error(E_NOTICE, "Undefined variable: %s", cv->val);
return &EG(uninitialized_zval);
@@ -260,15 +239,6 @@ static zend_never_inline zval *_get_zval_cv_lookup_BP_VAR_R(zval *ptr, zend_uint
static zend_never_inline zval *_get_zval_cv_lookup_BP_VAR_UNSET(zval *ptr, zend_uint var TSRMLS_DC)
{
zend_string *cv = CV_DEF_OF(var);
- zval *ret;
-
- if (EG(active_symbol_table)) {
- ret = zend_hash_find(&EG(active_symbol_table)->ht, cv);
- if (ret) {
- ZVAL_INDIRECT(ptr, ret);
- return ret;
- }
- }
zend_error(E_NOTICE, "Undefined variable: %s", cv->val);
return &EG(uninitialized_zval);
@@ -276,60 +246,22 @@ static zend_never_inline zval *_get_zval_cv_lookup_BP_VAR_UNSET(zval *ptr, zend_
static zend_never_inline zval *_get_zval_cv_lookup_BP_VAR_IS(zval *ptr, zend_uint var TSRMLS_DC)
{
- zend_string *cv = CV_DEF_OF(var);
- zval *ret;
-
- if (EG(active_symbol_table)) {
- ret = zend_hash_find(&EG(active_symbol_table)->ht, cv);
- if (ret) {
- ZVAL_INDIRECT(ptr, ret);
- return ret;
- }
- }
-
return &EG(uninitialized_zval);
}
static zend_never_inline zval *_get_zval_cv_lookup_BP_VAR_RW(zval *ptr, zend_uint var TSRMLS_DC)
{
zend_string *cv = CV_DEF_OF(var);
- zval *ret;
- if (EG(active_symbol_table)) {
- ret = zend_hash_find(&EG(active_symbol_table)->ht, cv);
- if (ret) {
- ZVAL_INDIRECT(ptr, ret);
- return ret;
- }
- ret = zend_hash_update(&EG(active_symbol_table)->ht, cv, &EG(uninitialized_zval));
- ZVAL_INDIRECT(ptr, ret);
- zend_error(E_NOTICE, "Undefined variable: %s", cv->val);
- return ret;
- } else {
- ZVAL_NULL(ptr);
- zend_error(E_NOTICE, "Undefined variable: %s", cv->val);
- return ptr;
- }
+ ZVAL_NULL(ptr);
+ zend_error(E_NOTICE, "Undefined variable: %s", cv->val);
+ return ptr;
}
static zend_never_inline zval *_get_zval_cv_lookup_BP_VAR_W(zval *ptr, zend_uint var TSRMLS_DC)
{
- zend_string *cv = CV_DEF_OF(var);
- zval *ret;
-
- if (EG(active_symbol_table)) {
- ret = zend_hash_find(&EG(active_symbol_table)->ht, cv);
- if (ret) {
- ZVAL_INDIRECT(ptr, ret);
- return ret;
- }
- ret = zend_hash_update(&EG(active_symbol_table)->ht, cv, &EG(uninitialized_zval));
- ZVAL_INDIRECT(ptr, ret);
- return ret;
- } else {
- ZVAL_NULL(ptr);
- return ptr;
- }
+ ZVAL_NULL(ptr);
+ return ptr;
}
static zend_always_inline zval *_get_zval_ptr_cv(zend_uint var, int type TSRMLS_DC)
@@ -338,8 +270,6 @@ static zend_always_inline zval *_get_zval_ptr_cv(zend_uint var, int type TSRMLS_
if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
return _get_zval_cv_lookup(ret, var, type TSRMLS_CC);
- } else if (UNEXPECTED(Z_TYPE_P(ret) == IS_INDIRECT)) {
- ret = Z_INDIRECT_P(ret);
}
return ret;
}
@@ -350,8 +280,6 @@ static zend_always_inline zval *_get_zval_ptr_cv_deref(zend_uint var, int type T
if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
return _get_zval_cv_lookup(ret, var, type TSRMLS_CC);
- } else if (UNEXPECTED(Z_TYPE_P(ret) == IS_INDIRECT)) {
- ret = Z_INDIRECT_P(ret);
}
if (UNEXPECTED(Z_TYPE_P(ret) == IS_REFERENCE)) {
ret = Z_REFVAL_P(ret);
@@ -365,8 +293,6 @@ static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_R(const zend_execute_dat
if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
return _get_zval_cv_lookup_BP_VAR_R(ret, var TSRMLS_CC);
- } else if (UNEXPECTED(Z_TYPE_P(ret) == IS_INDIRECT)) {
- ret = Z_INDIRECT_P(ret);
}
return ret;
}
@@ -377,8 +303,6 @@ static zend_always_inline zval *_get_zval_ptr_cv_deref_BP_VAR_R(const zend_execu
if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
return _get_zval_cv_lookup_BP_VAR_R(ret, var TSRMLS_CC);
- } else if (UNEXPECTED(Z_TYPE_P(ret) == IS_INDIRECT)) {
- ret = Z_INDIRECT_P(ret);
}
if (UNEXPECTED(Z_TYPE_P(ret) == IS_REFERENCE)) {
ret = Z_REFVAL_P(ret);
@@ -392,8 +316,6 @@ static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_UNSET(const zend_execute
if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
return _get_zval_cv_lookup_BP_VAR_UNSET(ret, var TSRMLS_CC);
- } else if (UNEXPECTED(Z_TYPE_P(ret) == IS_INDIRECT)) {
- ret = Z_INDIRECT_P(ret);
}
return ret;
}
@@ -404,8 +326,6 @@ static zend_always_inline zval *_get_zval_ptr_cv_deref_BP_VAR_UNSET(const zend_e
if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
return _get_zval_cv_lookup_BP_VAR_UNSET(ret, var TSRMLS_CC);
- } else if (UNEXPECTED(Z_TYPE_P(ret) == IS_INDIRECT)) {
- ret = Z_INDIRECT_P(ret);
}
if (UNEXPECTED(Z_TYPE_P(ret) == IS_REFERENCE)) {
ret = Z_REFVAL_P(ret);
@@ -419,8 +339,6 @@ static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_IS(const zend_execute_da
if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
return _get_zval_cv_lookup_BP_VAR_IS(ret, var TSRMLS_CC);
- } else if (UNEXPECTED(Z_TYPE_P(ret) == IS_INDIRECT)) {
- ret = Z_INDIRECT_P(ret);
}
return ret;
}
@@ -431,8 +349,6 @@ static zend_always_inline zval *_get_zval_ptr_cv_deref_BP_VAR_IS(const zend_exec
if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
return _get_zval_cv_lookup_BP_VAR_IS(ret, var TSRMLS_CC);
- } else if (UNEXPECTED(Z_TYPE_P(ret) == IS_INDIRECT)) {
- ret = Z_INDIRECT_P(ret);
}
if (UNEXPECTED(Z_TYPE_P(ret) == IS_REFERENCE)) {
ret = Z_REFVAL_P(ret);
@@ -446,8 +362,6 @@ static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_RW(const zend_execute_da
if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
return _get_zval_cv_lookup_BP_VAR_RW(ret, var TSRMLS_CC);
- } else if (UNEXPECTED(Z_TYPE_P(ret) == IS_INDIRECT)) {
- ret = Z_INDIRECT_P(ret);
}
return ret;
}
@@ -458,8 +372,6 @@ static zend_always_inline zval *_get_zval_ptr_cv_deref_BP_VAR_RW(const zend_exec
if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
return _get_zval_cv_lookup_BP_VAR_RW(ret, var TSRMLS_CC);
- } else if (UNEXPECTED(Z_TYPE_P(ret) == IS_INDIRECT)) {
- ret = Z_INDIRECT_P(ret);
}
if (UNEXPECTED(Z_TYPE_P(ret) == IS_REFERENCE)) {
ret = Z_REFVAL_P(ret);
@@ -473,8 +385,6 @@ static zend_always_inline zval *_get_zval_ptr_cv_BP_VAR_W(const zend_execute_dat
if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
return _get_zval_cv_lookup_BP_VAR_W(ret, var TSRMLS_CC);
- } else if (UNEXPECTED(Z_TYPE_P(ret) == IS_INDIRECT)) {
- ret = Z_INDIRECT_P(ret);
}
return ret;
}
@@ -485,8 +395,6 @@ static zend_always_inline zval *_get_zval_ptr_cv_deref_BP_VAR_W(const zend_execu
if (UNEXPECTED(Z_TYPE_P(ret) == IS_UNDEF)) {
return _get_zval_cv_lookup_BP_VAR_W(ret, var TSRMLS_CC);
- } else if (UNEXPECTED(Z_TYPE_P(ret) == IS_INDIRECT)) {
- ret = Z_INDIRECT_P(ret);
}
if (UNEXPECTED(Z_TYPE_P(ret) == IS_REFERENCE)) {
ret = Z_REFVAL_P(ret);
@@ -774,10 +682,6 @@ static inline void zend_assign_to_object(zval *retval, zval *object_ptr, zval *p
}
Z_ADDREF_P(object);
zend_error(E_WARNING, "Creating default object from empty value");
-//???
- if (Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
if (Z_REFCOUNT_P(object) == 1) {
/* object was removed by error handler, nothing to assign to */
zval_ptr_dtor(object);
@@ -790,10 +694,6 @@ static inline void zend_assign_to_object(zval *retval, zval *object_ptr, zval *p
Z_DELREF_P(object);
} else {
zend_error(E_WARNING, "Creating default object from empty value");
-//???
- if (Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
}
zval_dtor(object);
object_init(object);
@@ -1098,7 +998,29 @@ static inline zval *zend_fetch_dimension_address_inner(HashTable *ht, const zval
}
fetch_string_dim:
retval = zend_hash_find(ht, offset_key);
- if (retval == NULL) {
+// ??? support for $GLOBALS[...]
+ if (retval) {
+ if (Z_TYPE_P(retval) == IS_INDIRECT) {
+ retval = Z_INDIRECT_P(retval);
+ if (Z_TYPE_P(retval) == IS_UNDEF) {
+ switch (type) {
+ case BP_VAR_R:
+ zend_error(E_NOTICE, "Undefined index: %s", offset_key->val);
+ /* break missing intentionally */
+ case BP_VAR_UNSET:
+ case BP_VAR_IS:
+ retval = &EG(uninitialized_zval);
+ break;
+ case BP_VAR_RW:
+ zend_error(E_NOTICE,"Undefined index: %s", offset_key->val);
+ /* break missing intentionally */
+ case BP_VAR_W:
+ ZVAL_NULL(retval);
+ break;
+ }
+ }
+ }
+ } else {
switch (type) {
case BP_VAR_R:
zend_error(E_NOTICE, "Undefined index: %s", offset_key->val);
@@ -1247,10 +1169,6 @@ convert_to_array:
convert_to_long(&tmp);
dim = &tmp;
}
-//??? container may became IS_INDIRECT because of symtable initialization in zend_error
- if (Z_TYPE_P(container) == IS_INDIRECT) {
- container = Z_INDIRECT_P(container);
- }
ZVAL_STR_OFFSET(result, container, Z_LVAL_P(dim));
if (!IS_INTERNED(Z_STR_P(container))) STR_ADDREF(Z_STR_P(container));
return;
@@ -1719,16 +1637,12 @@ static zend_always_inline zend_execute_data *i_create_execute_data_from_op_array
op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*));
}
+ if (EG(active_symbol_table)) {
+ zend_attach_symbol_table(TSRMLS_C);
+ }
+
if (op_array->this_var != -1 && Z_TYPE(EG(This)) != IS_UNDEF) {
- if (!EG(active_symbol_table)) {
- ZVAL_COPY(EX_VAR_NUM(op_array->this_var), &EG(This));
- } else {
- ZVAL_COPY(EX_VAR_NUM(op_array->this_var), &EG(This));
- zval *zv = zend_hash_str_add(&EG(active_symbol_table)->ht, "this", sizeof("this")-1, EX_VAR(op_array->this_var));
- if (zv) {
- ZVAL_INDIRECT(EX_VAR_NUM(op_array->this_var), zv);
- }
- }
+ ZVAL_COPY(EX_VAR_NUM(op_array->this_var), &EG(This));
}
EX(opline) = UNEXPECTED((op_array->fn_flags & ZEND_ACC_INTERACTIVE) != 0) && EG(start_op) ? EG(start_op) : op_array->opcodes;
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index a90dade139..0980517935 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -202,6 +202,9 @@ void init_executor(TSRMLS_D) /* {{{ */
static int zval_call_destructor(zval *zv TSRMLS_DC) /* {{{ */
{
+ if (Z_TYPE_P(zv) == IS_INDIRECT) {
+ zv = Z_INDIRECT_P(zv);
+ }
if (Z_TYPE_P(zv) == IS_OBJECT && Z_REFCOUNT_P(zv) == 1) {
return ZEND_HASH_APPLY_REMOVE;
} else {
@@ -210,8 +213,22 @@ static int zval_call_destructor(zval *zv TSRMLS_DC) /* {{{ */
}
/* }}} */
+static int zend_unclean_zval_ptr_dtor(zval *zv) /* {{{ */
+{
+ TSRMLS_FETCH();
+
+ if (Z_TYPE_P(zv) == IS_INDIRECT) {
+ zv = Z_INDIRECT_P(zv);
+ }
+ i_zval_ptr_dtor(zv ZEND_FILE_LINE_CC TSRMLS_CC);
+}
+/* }}} */
+
void shutdown_destructors(TSRMLS_D) /* {{{ */
{
+ if (CG(unclean_shutdown)) {
+ EG(symbol_table).ht.pDestructor = zend_unclean_zval_ptr_dtor;
+ }
zend_try {
int symbols;
do {
@@ -246,6 +263,10 @@ void shutdown_executor(TSRMLS_D) /* {{{ */
}
*/
zend_llist_apply(&zend_extensions, (llist_apply_func_t) zend_extension_deactivator TSRMLS_CC);
+
+ if (CG(unclean_shutdown)) {
+ EG(symbol_table).ht.pDestructor = zend_unclean_zval_ptr_dtor;
+ }
zend_hash_graceful_reverse_destroy(&EG(symbol_table).ht);
} zend_end_try();
@@ -1638,65 +1659,9 @@ void zend_verify_abstract_class(zend_class_entry *ce TSRMLS_DC) /* {{{ */
}
/* }}} */
-ZEND_API void zend_reset_all_cv(zend_array *symbol_table TSRMLS_DC) /* {{{ */
-{
- zend_execute_data *ex;
- int i;
-
- for (ex = EG(current_execute_data); ex; ex = ex->prev_execute_data) {
- if (ex->op_array && ex->symbol_table == symbol_table) {
- for (i = 0; i < ex->op_array->last_var; i++) {
- ZVAL_UNDEF(EX_VAR_NUM_2(ex, i));
- }
- }
- }
-}
-/* }}} */
-
-ZEND_API void zend_delete_variable(zend_execute_data *ex, HashTable *ht, zend_string *name TSRMLS_DC) /* {{{ */
-{
- if (zend_hash_del(ht, name) == SUCCESS) {
- while (ex && &ex->symbol_table->ht == ht) {
- int i;
-
- if (ex->op_array) {
- for (i = 0; i < ex->op_array->last_var; i++) {
- if (ex->op_array->vars[i]->h == name->h &&
- ex->op_array->vars[i]->len == name->len &&
- !memcmp(ex->op_array->vars[i]->val, name->val, name->len)) {
- ZVAL_UNDEF(EX_VAR_NUM_2(ex, i));
- break;
- }
- }
- }
- ex = ex->prev_execute_data;
- }
- }
-}
-/* }}} */
-
ZEND_API int zend_delete_global_variable(zend_string *name TSRMLS_DC) /* {{{ */
{
- zend_execute_data *ex;
-
- if (zend_hash_del(&EG(symbol_table).ht, name) == SUCCESS) {
- for (ex = EG(current_execute_data); ex; ex = ex->prev_execute_data) {
- if (ex->op_array && ex->symbol_table == &EG(symbol_table)) {
- int i;
- for (i = 0; i < ex->op_array->last_var; i++) {
- if (ex->op_array->vars[i]->h == name->h &&
- ex->op_array->vars[i]->len == name->len &&
- !memcmp(ex->op_array->vars[i]->val, name->val, name->len)
- ) {
- ZVAL_UNDEF(EX_VAR_NUM_2(ex, i));
- break;
- }
- }
- }
- }
- return SUCCESS;
- }
- return FAILURE;
+ return zend_hash_del_ind(&EG(symbol_table).ht, name);
}
/* }}} */
@@ -1736,18 +1701,97 @@ ZEND_API void zend_rebuild_symbol_table(TSRMLS_D) /* {{{ */
ZVAL_COPY_VALUE(EX_VAR_NUM_2(ex, ex->op_array->this_var), &EG(This));
}
for (i = 0; i < ex->op_array->last_var; i++) {
- if (Z_TYPE_P(EX_VAR_NUM_2(ex, i)) != IS_UNDEF) {
- zval *zv = zend_hash_update(&EG(active_symbol_table)->ht,
- ex->op_array->vars[i],
- EX_VAR_NUM_2(ex, i));
- ZVAL_INDIRECT(EX_VAR_NUM_2(ex, i), zv);
+ zval zv;
+
+ ZVAL_INDIRECT(&zv, EX_VAR_NUM_2(ex, i));
+ zend_hash_update(&EG(active_symbol_table)->ht,
+ ex->op_array->vars[i], &zv);
+ }
+ }
+ }
+}
+/* }}} */
+
+ZEND_API void zend_attach_symbol_table(TSRMLS_D) /* {{{ */
+{
+ int i;
+ zend_execute_data *execute_data = EG(current_execute_data);
+ zend_op_array *op_array = execute_data->op_array;
+ HashTable *ht = &EG(active_symbol_table)->ht;
+
+ /* copy real values from symbol table into CV slots and create
+ INDIRECT references to CV in symbol table */
+ for (i = 0; i < op_array->last_var; i++) {
+ zval *zv = zend_hash_find(ht, op_array->vars[i]);
+
+ if (zv) {
+ if (Z_TYPE_P(zv) == IS_INDIRECT) {
+ zval *val = Z_INDIRECT_P(zv);
+ if (Z_TYPE_P(val) == IS_UNDEF) {
+ ZVAL_UNDEF(EX_VAR_NUM(i));
+ } else {
+ ZVAL_COPY_VALUE(EX_VAR_NUM(i), val);
}
+ } else {
+ ZVAL_COPY_VALUE(EX_VAR_NUM(i), zv);
}
+ } else {
+ ZVAL_UNDEF(EX_VAR_NUM(i));
+ zv = zend_hash_update(ht, op_array->vars[i], EX_VAR_NUM(i));
}
+ ZVAL_INDIRECT(zv, EX_VAR_NUM(i));
}
}
/* }}} */
+ZEND_API void zend_detach_symbol_table(TSRMLS_D) /* {{{ */
+{
+ int i;
+ zend_execute_data *execute_data = EG(current_execute_data);
+ zend_op_array *op_array = execute_data->op_array;
+ HashTable *ht = &EG(active_symbol_table)->ht;
+
+ /* copy real values from CV slots into symbol table */
+ for (i = 0; i < op_array->last_var; i++) {
+ zend_hash_update(ht, op_array->vars[i], EX_VAR_NUM(i));
+ ZVAL_UNDEF(EX_VAR_NUM(i));
+ }
+}
+/* }}} */
+
+ZEND_API int zend_set_local_var(const char *name, int len, zval *value, int force TSRMLS_DC) /* {{{ */
+{
+ if (!EG(active_symbol_table)) {
+ int i;
+ zend_execute_data *execute_data = EG(current_execute_data);
+ zend_op_array *op_array = execute_data->op_array;
+ zend_ulong h = zend_hash_func(name, len);
+
+ if (op_array) {
+ for (i = 0; i < op_array->last_var; i++) {
+ if (op_array->vars[i]->h == h &&
+ op_array->vars[i]->len == len &&
+ memcmp(op_array->vars[i]->val, name, len) == 0) {
+ ZVAL_COPY_VALUE(EX_VAR_NUM(i), value);
+ return SUCCESS;
+ }
+ }
+ }
+ if (force) {
+ zend_rebuild_symbol_table(TSRMLS_C);
+ if (EG(active_symbol_table)) {
+ zend_hash_str_update(&EG(active_symbol_table)->ht, name, len, value);
+ }
+ } else {
+ return FAILURE;
+ }
+ } else {
+ return zend_hash_str_update_ind(&EG(active_symbol_table)->ht, name, len, value);
+ }
+ return SUCCESS;
+}
+/* }}} */
+
/*
* Local variables:
* tab-width: 4
diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c
index 54fd532fc7..dca99c0911 100644
--- a/Zend/zend_gc.c
+++ b/Zend/zend_gc.c
@@ -557,7 +557,7 @@ tail_call:
p = ht->arData + idx;
if (!Z_REFCOUNTED(p->val)) {
/* count non-refcounted for compatibilty ??? */
- if (Z_TYPE(p->val) != IS_UNDEF) {
+ if (Z_TYPE(p->val) != IS_UNDEF && Z_TYPE(p->val) != IS_INDIRECT) {
count++;
}
continue;
diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c
index be2b0c742b..3cfc62e7a1 100644
--- a/Zend/zend_hash.c
+++ b/Zend/zend_hash.c
@@ -267,17 +267,23 @@ ZEND_API zval *_zend_hash_add_or_update(HashTable *ht, zend_string *key, zval *p
p = zend_hash_find_bucket(ht, key);
if (p) {
+ zval *data;
+
if (flag & HASH_ADD) {
return NULL;
}
ZEND_ASSERT(&p->val != pData);
+ data = &p->val;
+ if ((flag & HASH_UPDATE_INDIRECT) && Z_TYPE_P(data) == IS_INDIRECT) {
+ data = Z_INDIRECT_P(data);
+ }
HANDLE_BLOCK_INTERRUPTIONS();
if (ht->pDestructor) {
- ht->pDestructor(&p->val);
+ ht->pDestructor(data);
}
- ZVAL_COPY_VALUE(&p->val, pData);
+ ZVAL_COPY_VALUE(data, pData);
HANDLE_UNBLOCK_INTERRUPTIONS();
- return &p->val;
+ return data;
}
ZEND_HASH_IF_FULL_DO_RESIZE(ht); /* If the Hash table is full, resize it */
@@ -588,6 +594,58 @@ ZEND_API int zend_hash_del(HashTable *ht, zend_string *key)
return FAILURE;
}
+ZEND_API int zend_hash_del_ind(HashTable *ht, zend_string *key)
+{
+ ulong h;
+ uint nIndex;
+ uint idx;
+ Bucket *p;
+ Bucket *prev = NULL;
+#ifdef ZEND_SIGNALS
+ TSRMLS_FETCH();
+#endif
+
+ IS_CONSISTENT(ht);
+
+ if (ht->flags & HASH_FLAG_PACKED) {
+ return FAILURE;
+ }
+
+ h = STR_HASH_VAL(key);
+ nIndex = h & ht->nTableMask;
+
+ idx = ht->arHash[nIndex];
+ while (idx != INVALID_IDX) {
+ p = ht->arData + idx;
+ if ((p->key == key) ||
+ (p->h == h &&
+ p->key &&
+ p->key->len == key->len &&
+ memcmp(p->key->val, key->val, key->len) == 0)) {
+ if (Z_TYPE(p->val) == IS_INDIRECT) {
+ zval *data = Z_INDIRECT(p->val);
+
+ if (Z_TYPE_P(data) == IS_UNDEF) {
+ return FAILURE;
+ } else {
+ if (ht->pDestructor) {
+ ht->pDestructor(data);
+ }
+ ZVAL_UNDEF(data);
+ }
+ } else {
+ HANDLE_BLOCK_INTERRUPTIONS();
+ _zend_hash_del_el_ex(ht, idx, p, prev);
+ HANDLE_UNBLOCK_INTERRUPTIONS();
+ }
+ return SUCCESS;
+ }
+ prev = p;
+ idx = p->val.u.next;
+ }
+ return FAILURE;
+}
+
ZEND_API int zend_hash_str_del(HashTable *ht, const char *str, int len)
{
ulong h;
@@ -611,6 +669,53 @@ ZEND_API int zend_hash_str_del(HashTable *ht, const char *str, int len)
&& p->key
&& (p->key->len == len)
&& !memcmp(p->key->val, str, len)) {
+ if (Z_TYPE(p->val) == IS_INDIRECT) {
+ zval *data = Z_INDIRECT(p->val);
+
+ if (Z_TYPE_P(data) == IS_UNDEF) {
+ return FAILURE;
+ } else {
+ if (ht->pDestructor) {
+ ht->pDestructor(data);
+ }
+ ZVAL_UNDEF(data);
+ }
+ } else {
+ HANDLE_BLOCK_INTERRUPTIONS();
+ _zend_hash_del_el_ex(ht, idx, p, prev);
+ HANDLE_UNBLOCK_INTERRUPTIONS();
+ }
+ return SUCCESS;
+ }
+ prev = p;
+ idx = p->val.u.next;
+ }
+ return FAILURE;
+}
+
+ZEND_API int zend_hash_str_del_ind(HashTable *ht, const char *str, int len)
+{
+ ulong h;
+ uint nIndex;
+ uint idx;
+ Bucket *p;
+ Bucket *prev = NULL;
+#ifdef ZEND_SIGNALS
+ TSRMLS_FETCH();
+#endif
+
+ IS_CONSISTENT(ht);
+
+ h = zend_inline_hash_func(str, len);
+ nIndex = h & ht->nTableMask;
+
+ idx = ht->arHash[nIndex];
+ while (idx != INVALID_IDX) {
+ p = ht->arData + idx;
+ if ((p->h == h)
+ && p->key
+ && (p->key->len == len)
+ && !memcmp(p->key->val, str, len)) {
HANDLE_BLOCK_INTERRUPTIONS();
_zend_hash_del_el_ex(ht, idx, p, prev);
HANDLE_UNBLOCK_INTERRUPTIONS();
@@ -914,7 +1019,7 @@ ZEND_API void zend_hash_copy(HashTable *target, HashTable *source, copy_ctor_fun
{
uint idx;
Bucket *p;
- zval *new_entry;
+ zval *new_entry, *data;
zend_bool setTargetPointer;
IS_CONSISTENT(source);
@@ -928,10 +1033,18 @@ ZEND_API void zend_hash_copy(HashTable *target, HashTable *source, copy_ctor_fun
if (setTargetPointer && source->nInternalPointer == idx) {
target->nInternalPointer = INVALID_IDX;
}
+//???
+ data = &p->val;
+ if (Z_TYPE_P(data) == IS_INDIRECT) {
+ data = Z_INDIRECT_P(data);
+ if (Z_TYPE_P(data) == IS_UNDEF) {
+ continue;
+ }
+ }
if (p->key) {
- new_entry = zend_hash_update(target, p->key, &p->val);
+ new_entry = zend_hash_update(target, p->key, data);
} else {
- new_entry = zend_hash_index_update(target, p->h, &p->val);
+ new_entry = zend_hash_index_update(target, p->h, data);
}
if (pCopyConstructor) {
pCopyConstructor(new_entry);
@@ -1551,7 +1664,7 @@ ZEND_API int zend_hash_compare(HashTable *ht1, HashTable *ht2, compare_func_t co
uint idx1, idx2;
Bucket *p1, *p2 = NULL;
int result;
- zval *pData2;
+ zval *pData1, *pData2;
IS_CONSISTENT(ht1);
IS_CONSISTENT(ht2);
@@ -1620,7 +1733,22 @@ ZEND_API int zend_hash_compare(HashTable *ht1, HashTable *ht2, compare_func_t co
}
}
}
- result = compar(&p1->val, pData2 TSRMLS_CC);
+ pData1 = &p1->val;
+ if (Z_TYPE_P(pData1) == IS_INDIRECT) {
+ pData1 = Z_INDIRECT_P(pData1);
+ }
+ if (Z_TYPE_P(pData2) == IS_INDIRECT) {
+ pData2 = Z_INDIRECT_P(pData2);
+ }
+ if (Z_TYPE_P(pData1) == IS_UNDEF) {
+ if (Z_TYPE_P(pData2) != IS_UNDEF) {
+ return -1;
+ }
+ } else if (Z_TYPE_P(pData2) == IS_UNDEF) {
+ return 1;
+ } else {
+ result = compar(pData1, pData2 TSRMLS_CC);
+ }
if (result != 0) {
HASH_UNPROTECT_RECURSION(ht1);
HASH_UNPROTECT_RECURSION(ht2);
diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h
index 2718356497..b9918304cd 100644
--- a/Zend/zend_hash.h
+++ b/Zend/zend_hash.h
@@ -30,9 +30,10 @@
#define HASH_KEY_NON_EXISTENT 3
#define HASH_KEY_NON_EXISTANT HASH_KEY_NON_EXISTENT /* Keeping old define (with typo) for backward compatibility */
-#define HASH_UPDATE (1<<0)
-#define HASH_ADD (1<<1)
-#define HASH_NEXT_INSERT (1<<2)
+#define HASH_UPDATE (1<<0)
+#define HASH_ADD (1<<1)
+#define HASH_NEXT_INSERT (1<<2)
+#define HASH_UPDATE_INDIRECT (1<<3)
#define HASH_UPDATE_KEY_IF_NONE 0
#define HASH_UPDATE_KEY_IF_BEFORE 1
@@ -74,12 +75,16 @@ ZEND_API void zend_hash_to_packed(HashTable *ht);
ZEND_API zval *_zend_hash_add_or_update(HashTable *ht, zend_string *key, zval *pData, int flag ZEND_FILE_LINE_DC);
#define zend_hash_update(ht, key, pData) \
_zend_hash_add_or_update(ht, key, pData, HASH_UPDATE ZEND_FILE_LINE_CC)
+#define zend_hash_update_ind(ht, key, pData) \
+ _zend_hash_add_or_update(ht, key, pData, HASH_UPDATE | HASH_UPDATE_INDIRECT ZEND_FILE_LINE_CC)
#define zend_hash_add(ht, key, pData) \
_zend_hash_add_or_update(ht, key, pData, HASH_ADD ZEND_FILE_LINE_CC)
ZEND_API zval *_zend_hash_str_add_or_update(HashTable *ht, const char *key, int len, zval *pData, int flag ZEND_FILE_LINE_DC);
#define zend_hash_str_update(ht, key, len, pData) \
_zend_hash_str_add_or_update(ht, key, len, pData, HASH_UPDATE ZEND_FILE_LINE_CC)
+#define zend_hash_str_update_ind(ht, key, len, pData) \
+ _zend_hash_str_add_or_update(ht, key, len, pData, HASH_UPDATE | HASH_UPDATE_INDIRECT ZEND_FILE_LINE_CC)
#define zend_hash_str_add(ht, key, len, pData) \
_zend_hash_str_add_or_update(ht, key, len, pData, HASH_ADD ZEND_FILE_LINE_CC)
@@ -117,7 +122,9 @@ ZEND_API void zend_hash_reverse_apply(HashTable *ht, apply_func_t apply_func TSR
/* Deletes */
ZEND_API int zend_hash_del(HashTable *ht, zend_string *key);
+ZEND_API int zend_hash_del_ind(HashTable *ht, zend_string *key);
ZEND_API int zend_hash_str_del(HashTable *ht, const char *key, int len);
+ZEND_API int zend_hash_str_del_ind(HashTable *ht, const char *key, int len);
ZEND_API int zend_hash_index_del(HashTable *ht, ulong h);
/* Data retreival */
@@ -244,6 +251,25 @@ END_EXTERN_C()
ZEND_HANDLE_NUMERIC_EX(key, length, idx, return func); \
} while (0)
+
+static inline zval *zend_hash_find_ind(const HashTable *ht, zend_string *key)
+{
+ zval *zv;
+
+ zv = zend_hash_find(ht, key);
+ return (zv && Z_TYPE_P(zv) == IS_INDIRECT) ? Z_INDIRECT_P(zv) : zv;
+}
+
+
+static inline zval *zend_hash_str_find_ind(const HashTable *ht, const char *str, int len)
+{
+ zval *zv;
+
+ zv = zend_hash_str_find(ht, str, len);
+ return (zv && Z_TYPE_P(zv) == IS_INDIRECT) ? Z_INDIRECT_P(zv) : zv;
+}
+
+
static inline zval *zend_symtable_update(HashTable *ht, zend_string *key, zval *pData)
{
ZEND_HANDLE_NUMERIC(key->val, key->len+1, zend_hash_index_update(ht, idx, pData));
@@ -251,6 +277,13 @@ static inline zval *zend_symtable_update(HashTable *ht, zend_string *key, zval *
}
+static inline zval *zend_symtable_update_ind(HashTable *ht, zend_string *key, zval *pData)
+{
+ ZEND_HANDLE_NUMERIC(key->val, key->len+1, zend_hash_index_update(ht, idx, pData));
+ return zend_hash_update_ind(ht, key, pData);
+}
+
+
static inline int zend_symtable_del(HashTable *ht, zend_string *key)
{
ZEND_HANDLE_NUMERIC(key->val, key->len+1, zend_hash_index_del(ht, idx));
@@ -258,6 +291,13 @@ static inline int zend_symtable_del(HashTable *ht, zend_string *key)
}
+static inline int zend_symtable_del_ind(HashTable *ht, zend_string *key)
+{
+ ZEND_HANDLE_NUMERIC(key->val, key->len+1, zend_hash_index_del(ht, idx));
+ return zend_hash_del_ind(ht, key);
+}
+
+
static inline zval *zend_symtable_find(const HashTable *ht, zend_string *key)
{
ZEND_HANDLE_NUMERIC(key->val, key->len+1, zend_hash_index_find(ht, idx));
@@ -265,12 +305,20 @@ static inline zval *zend_symtable_find(const HashTable *ht, zend_string *key)
}
+static inline zval *zend_symtable_find_ind(const HashTable *ht, zend_string *key)
+{
+ ZEND_HANDLE_NUMERIC(key->val, key->len+1, zend_hash_index_find(ht, idx));
+ return zend_hash_find_ind(ht, key);
+}
+
+
static inline int zend_symtable_exists(HashTable *ht, zend_string *key)
{
ZEND_HANDLE_NUMERIC(key->val, key->len+1, zend_hash_index_exists(ht, idx));
return zend_hash_exists(ht, key);
}
+
static inline zval *zend_symtable_str_update(HashTable *ht, const char *str, int len, zval *pData)
{
ZEND_HANDLE_NUMERIC(str, len+1, zend_hash_index_update(ht, idx, pData));
@@ -278,6 +326,13 @@ static inline zval *zend_symtable_str_update(HashTable *ht, const char *str, int
}
+static inline zval *zend_symtable_str_update_ind(HashTable *ht, const char *str, int len, zval *pData)
+{
+ ZEND_HANDLE_NUMERIC(str, len+1, zend_hash_index_update(ht, idx, pData));
+ return zend_hash_str_update_ind(ht, str, len, pData);
+}
+
+
static inline int zend_symtable_str_del(HashTable *ht, const char *str, int len)
{
ZEND_HANDLE_NUMERIC(str, len+1, zend_hash_index_del(ht, idx));
@@ -285,6 +340,13 @@ static inline int zend_symtable_str_del(HashTable *ht, const char *str, int len)
}
+static inline int zend_symtable_str_del_ind(HashTable *ht, const char *str, int len)
+{
+ ZEND_HANDLE_NUMERIC(str, len+1, zend_hash_index_del(ht, idx));
+ return zend_hash_str_del_ind(ht, str, len);
+}
+
+
static inline zval *zend_symtable_str_find(HashTable *ht, const char *str, int len)
{
ZEND_HANDLE_NUMERIC(str, len+1, zend_hash_index_find(ht, idx));
diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c
index 24a3a9ebd8..3d821993af 100644
--- a/Zend/zend_object_handlers.c
+++ b/Zend/zend_object_handlers.c
@@ -85,10 +85,10 @@ ZEND_API void rebuild_object_properties(zend_object *zobj) /* {{{ */
(prop_info->flags & ZEND_ACC_STATIC) == 0 &&
prop_info->offset >= 0 &&
Z_TYPE(zobj->properties_table[prop_info->offset]) != IS_UNDEF) {
- zval *zv = zend_hash_add(zobj->properties, prop_info->name, &zobj->properties_table[prop_info->offset]);
- if (EXPECTED(zv != NULL)) {
- ZVAL_INDIRECT(&zobj->properties_table[prop_info->offset], zv);
- }
+ zval zv;
+
+ ZVAL_INDIRECT(&zv, &zobj->properties_table[prop_info->offset]);
+ zend_hash_add(zobj->properties, prop_info->name, &zv);
}
}
while (ce->parent && ce->parent->default_properties_count) {
@@ -101,10 +101,10 @@ ZEND_API void rebuild_object_properties(zend_object *zobj) /* {{{ */
(prop_info->flags & ZEND_ACC_PRIVATE) != 0 &&
prop_info->offset >= 0 &&
Z_TYPE(zobj->properties_table[prop_info->offset]) != IS_UNDEF) {
- zval *zv = zend_hash_add(zobj->properties, prop_info->name, &zobj->properties_table[prop_info->offset]);
- if (EXPECTED(zv != NULL)) {
- ZVAL_INDIRECT(&zobj->properties_table[prop_info->offset], zv);
- }
+ zval zv;
+
+ ZVAL_INDIRECT(&zv, &zobj->properties_table[prop_info->offset]);
+ zend_hash_add(zobj->properties, prop_info->name, &zv);
}
}
}
@@ -133,15 +133,9 @@ ZEND_API HashTable *zend_std_get_gc(zval *object, zval **table, int *n TSRMLS_DC
} else {
zend_object *zobj = Z_OBJ_P(object);
- if (zobj->properties) {
- *table = NULL;
- *n = 0;
- return zobj->properties;
- } else {
- *table = zobj->properties_table;
- *n = zobj->ce->default_properties_count;
- return NULL;
- }
+ *table = zobj->properties_table;
+ *n = zobj->ce->default_properties_count;
+ return zobj->properties;
}
}
/* }}} */
@@ -454,20 +448,18 @@ zval *zend_std_read_property(zval *object, zval *member, int type, const zend_li
if (EXPECTED(property_info != NULL)) {
if (EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0) &&
- property_info->offset >= 0 &&
- Z_TYPE(zobj->properties_table[property_info->offset]) != IS_UNDEF) {
+ property_info->offset >= 0) {
retval = &zobj->properties_table[property_info->offset];
- if (Z_TYPE_P(retval) == IS_INDIRECT) {
- retval = Z_INDIRECT_P(retval);
+ if (Z_TYPE_P(retval) != IS_UNDEF) {
+ goto exit;
}
- goto exit;
- }
- if (UNEXPECTED(zobj->properties != NULL)) {
+ } else if (UNEXPECTED(zobj->properties != NULL)) {
retval = zend_hash_find(zobj->properties, property_info->name);
if (retval) goto exit;
}
}
+ /* magic get */
if (zobj->ce->__get) {
long *guard = zend_get_property_guard(zobj, property_info, member);
if (!((*guard) & IN_GET)) {
@@ -534,6 +526,7 @@ zval *zend_std_read_property(zval *object, zval *member, int type, const zend_li
}
retval = &EG(uninitialized_zval);
}
+
exit:
if (UNEXPECTED(Z_TYPE(tmp_member) != IS_UNDEF)) {
if (Z_REFCOUNTED_P(retval)) Z_ADDREF_P(retval);
@@ -565,15 +558,12 @@ ZEND_API void zend_std_write_property(zval *object, zval *member, zval *value, c
if (EXPECTED(property_info != NULL)) {
if (EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0) &&
- property_info->offset >= 0 &&
- Z_TYPE(zobj->properties_table[property_info->offset]) != IS_UNDEF) {
+ property_info->offset >= 0) {
variable_ptr = &zobj->properties_table[property_info->offset];
- if (Z_TYPE_P(variable_ptr) == IS_INDIRECT) {
- variable_ptr = Z_INDIRECT_P(variable_ptr);
+ if (Z_TYPE_P(variable_ptr) != IS_UNDEF) {
+ goto found;
}
- goto found;
- }
- if (EXPECTED(zobj->properties != NULL)) {
+ } else if (EXPECTED(zobj->properties != NULL)) {
if ((variable_ptr = zend_hash_find(zobj->properties, property_info->name)) != NULL) {
found:
/* if we already have this value there, we don't actually need to do anything */
@@ -607,11 +597,12 @@ found:
zval_ptr_dtor(&garbage);
}
}
- return;
+ goto exit;
}
}
}
+ /* magic set */
if (zobj->ce->__set) {
long *guard = zend_get_property_guard(zobj, property_info, member);
@@ -653,12 +644,7 @@ write_std_property:
if (EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0) &&
property_info->offset >= 0) {
- if (zobj->properties) {
- zval *zv = zend_hash_update(zobj->properties, property_info->name, value);
- ZVAL_INDIRECT(&zobj->properties_table[property_info->offset], zv);
- } else {
- ZVAL_COPY_VALUE(&zobj->properties_table[property_info->offset], value);
- }
+ ZVAL_COPY_VALUE(&zobj->properties_table[property_info->offset], value);
} else {
if (!zobj->properties) {
rebuild_object_properties(zobj);
@@ -667,6 +653,7 @@ write_std_property:
}
}
+exit:
if (UNEXPECTED(Z_TYPE(tmp_member) != IS_UNDEF)) {
zval_ptr_dtor(&tmp_member);
}
@@ -785,15 +772,12 @@ static zval *zend_std_get_property_ptr_ptr(zval *object, zval *member, int type,
if (EXPECTED(property_info != NULL)) {
if (EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0) &&
- property_info->offset >= 0 &&
- Z_TYPE(zobj->properties_table[property_info->offset]) != IS_UNDEF) {
+ property_info->offset >= 0) {
retval = &zobj->properties_table[property_info->offset];
- if (Z_TYPE_P(retval) == IS_INDIRECT) {
- retval = Z_INDIRECT_P(retval);
+ if (Z_TYPE_P(retval) != IS_UNDEF) {
+ goto exit;
}
- goto exit;
- }
- if (UNEXPECTED(zobj->properties != NULL)) {
+ } else if (UNEXPECTED(zobj->properties != NULL)) {
retval = zend_hash_find(zobj->properties, property_info->name);
if (retval) goto exit;
}
@@ -810,13 +794,8 @@ static zval *zend_std_get_property_ptr_ptr(zval *object, zval *member, int type,
ZVAL_NULL(&tmp);
if (EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0) &&
property_info->offset >= 0) {
- if (zobj->properties) {
- retval = zend_hash_update(zobj->properties, property_info->name, &tmp);
- ZVAL_INDIRECT(&zobj->properties_table[property_info->offset], retval);
- } else {
- retval = &zobj->properties_table[property_info->offset];
- ZVAL_NULL(retval);
- }
+ retval = &zobj->properties_table[property_info->offset];
+ ZVAL_NULL(retval);
} else {
if (!zobj->properties) {
rebuild_object_properties(zobj);
@@ -854,36 +833,39 @@ static void zend_std_unset_property(zval *object, zval *member, const zend_liter
property_info = zend_get_property_info_quick(zobj->ce, member, (zobj->ce->__unset != NULL), key TSRMLS_CC);
- if (EXPECTED(property_info != NULL) &&
- EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0) &&
- property_info->offset >= 0) {
- zval_ptr_dtor(&zobj->properties_table[property_info->offset]);
- ZVAL_UNDEF(&zobj->properties_table[property_info->offset]);
- if (!zobj->properties) goto exit;
+ if (EXPECTED(property_info != NULL)) {
+ if (EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0) &&
+ property_info->offset >= 0) {
+ if (Z_TYPE(zobj->properties_table[property_info->offset]) != IS_UNDEF) {
+ zval_ptr_dtor(&zobj->properties_table[property_info->offset]);
+ ZVAL_UNDEF(&zobj->properties_table[property_info->offset]);
+ goto exit;
+ }
+ } else if (zobj->properties &&
+ UNEXPECTED(zend_hash_del(zobj->properties, property_info->name) != FAILURE)) {
+ goto exit;
+ }
}
- if (UNEXPECTED(!property_info) ||
- !zobj->properties ||
- UNEXPECTED(zend_hash_del(zobj->properties, property_info->name) == FAILURE)) {
- if (zobj->ce->__unset) {
- long *guard = zend_get_property_guard(zobj, property_info, member);
- if (!((*guard) & IN_UNSET)) {
- /* have unseter - try with it! */
- Z_ADDREF_P(object);
- if (Z_ISREF_P(object)) {
- SEPARATE_ZVAL(object);
- }
- (*guard) |= IN_UNSET; /* prevent circular unsetting */
- zend_std_call_unsetter(object, member TSRMLS_CC);
- (*guard) &= ~IN_UNSET;
- zval_ptr_dtor(object);
- } else {
- if (Z_STRVAL_P(member)[0] == '\0') {
- if (Z_STRLEN_P(member) == 0) {
- zend_error(E_ERROR, "Cannot access empty property");
- } else {
- zend_error(E_ERROR, "Cannot access property started with '\\0'");
- }
+ /* magic unset */
+ if (zobj->ce->__unset) {
+ long *guard = zend_get_property_guard(zobj, property_info, member);
+ if (!((*guard) & IN_UNSET)) {
+ /* have unseter - try with it! */
+ Z_ADDREF_P(object);
+ if (Z_ISREF_P(object)) {
+ SEPARATE_ZVAL(object);
+ }
+ (*guard) |= IN_UNSET; /* prevent circular unsetting */
+ zend_std_call_unsetter(object, member TSRMLS_CC);
+ (*guard) &= ~IN_UNSET;
+ zval_ptr_dtor(object);
+ } else {
+ if (Z_STRVAL_P(member)[0] == '\0') {
+ if (Z_STRLEN_P(member) == 0) {
+ zend_error(E_ERROR, "Cannot access empty property");
+ } else {
+ zend_error(E_ERROR, "Cannot access property started with '\\0'");
}
}
}
@@ -1382,12 +1364,6 @@ static int zend_std_compare_objects(zval *o1, zval *o2 TSRMLS_DC) /* {{{ */
zval *p1 = &zobj1->properties_table[i];
zval *p2 = &zobj2->properties_table[i];
- if (Z_TYPE_P(p1) == IS_INDIRECT) {
- p1 = Z_INDIRECT_P(p1);
- }
- if (Z_TYPE_P(p2) == IS_INDIRECT) {
- p1 = Z_INDIRECT_P(p2);
- }
if (compare_function(&result, p1, p2 TSRMLS_CC)==FAILURE) {
Z_OBJ_UNPROTECT_RECURSION(o1);
Z_OBJ_UNPROTECT_RECURSION(o2);
@@ -1448,30 +1424,26 @@ static int zend_std_has_property(zval *object, zval *member, int has_set_exists,
if (EXPECTED(property_info != NULL)) {
if (EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0) &&
- property_info->offset >= 0 &&
- Z_TYPE(zobj->properties_table[property_info->offset]) != IS_UNDEF) {
+ property_info->offset >= 0) {
value = &zobj->properties_table[property_info->offset];
- if (Z_TYPE_P(value) == IS_INDIRECT) {
- value = Z_INDIRECT_P(value);
+ if (Z_TYPE_P(value) != IS_UNDEF) {
+ goto found;
}
- goto found;
- }
- if (UNEXPECTED(zobj->properties != NULL)) {
- if ((value = zend_hash_find(zobj->properties, property_info->name)) != NULL) {
+ } else if (UNEXPECTED(zobj->properties != NULL) &&
+ (value = zend_hash_find(zobj->properties, property_info->name)) != NULL) {
found:
- switch (has_set_exists) {
- case 0:
- result = (Z_TYPE_P(value) != IS_NULL);
- break;
- default:
- result = zend_is_true(value TSRMLS_CC);
- break;
- case 2:
- result = 1;
- break;
- }
- goto exit;
+ switch (has_set_exists) {
+ case 0:
+ result = (Z_TYPE_P(value) != IS_NULL);
+ break;
+ default:
+ result = zend_is_true(value TSRMLS_CC);
+ break;
+ case 2:
+ result = 1;
+ break;
}
+ goto exit;
}
}
diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c
index 50785b86ec..ec353b7a2c 100644
--- a/Zend/zend_objects.c
+++ b/Zend/zend_objects.c
@@ -142,32 +142,39 @@ ZEND_API void zend_objects_clone_members(zend_object *new_object, zend_object *o
{
int i;
- if (!old_object->properties) {
+ if (old_object->ce->default_properties_count) {
for (i = 0; i < old_object->ce->default_properties_count; i++) {
zval_ptr_dtor(&new_object->properties_table[i]);
ZVAL_COPY(&new_object->properties_table[i], &old_object->properties_table[i]);
}
- } else {
+ }
+ if (old_object->properties) {
+ HashPosition pos;
+ zval *prop, new_prop;
+ ulong num_key;
+ zend_string *key;
+
if (!new_object->properties) {
ALLOC_HASHTABLE(new_object->properties);
zend_hash_init(new_object->properties, 0, NULL, ZVAL_PTR_DTOR, 0);
}
- zend_hash_copy(new_object->properties, old_object->properties, zval_add_ref_unref);
- if (old_object->properties_table) {
- HashPosition pos;
- zval *prop;
- zend_property_info *prop_info;
-
- for (zend_hash_internal_pointer_reset_ex(&old_object->ce->properties_info, &pos);
- (prop_info = zend_hash_get_current_data_ptr_ex(&old_object->ce->properties_info, &pos)) != NULL;
- zend_hash_move_forward_ex(&old_object->ce->properties_info, &pos)) {
- if ((prop_info->flags & ZEND_ACC_STATIC) == 0) {
- if ((prop = zend_hash_find(new_object->properties, prop_info->name)) != NULL) {
- ZVAL_INDIRECT(&new_object->properties_table[prop_info->offset], prop);
- } else {
- ZVAL_UNDEF(&new_object->properties_table[prop_info->offset]);
- }
- }
+
+ for (zend_hash_internal_pointer_reset_ex(old_object->properties, &pos);
+ (prop = zend_hash_get_current_data_ex(old_object->properties, &pos)) != NULL;
+ zend_hash_move_forward_ex(old_object->properties, &pos)) {
+ if (Z_TYPE_P(prop) == IS_INDIRECT) {
+ ZVAL_INDIRECT(&new_prop, new_object->properties_table + (Z_INDIRECT_P(prop) - old_object->properties_table));
+ } else {
+ ZVAL_COPY_VALUE(&new_prop, prop);
+ zval_add_ref_unref(&new_prop);
+ }
+ switch (zend_hash_get_current_key_ex(old_object->properties, &key, &num_key, 0, &pos)) {
+ case HASH_KEY_IS_STRING:
+ zend_hash_update(new_object->properties, key, &new_prop);
+ break;
+ case HASH_KEY_IS_LONG:
+ zend_hash_index_update(new_object->properties, num_key, &new_prop);
+ break;
}
}
}
diff --git a/Zend/zend_variables.c b/Zend/zend_variables.c
index f7375edc5e..4a7fb4f74a 100644
--- a/Zend/zend_variables.c
+++ b/Zend/zend_variables.c
@@ -336,6 +336,18 @@ ZEND_API int zval_copy_static_var(zval *p TSRMLS_DC, int num_args, va_list args,
zend_error(E_NOTICE,"Undefined variable: %s", key->key->val);
}
} else {
+ if (Z_TYPE_P(p) == IS_INDIRECT) {
+ p = Z_INDIRECT_P(p);
+ if (Z_TYPE_P(p) == IS_UNDEF) {
+ if (!is_ref) {
+ zend_error(E_NOTICE,"Undefined variable: %s", key->key->val);
+ p = &tmp;
+ ZVAL_NULL(&tmp);
+ } else {
+ ZVAL_NULL(p);
+ }
+ }
+ }
if (is_ref) {
SEPARATE_ZVAL_TO_MAKE_IS_REF(p);
Z_ADDREF_P(p);
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 37bd9107b7..e97646be2e 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -340,17 +340,8 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMP|VAR
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
-//???: object may become INDIRECT
- if (OP1_TYPE == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
-
if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
make_real_object(object TSRMLS_CC);
-//???
- if (Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
}
if (UNEXPECTED(Z_ISREF_P(object))) {
object = Z_REFVAL_P(object);
@@ -1048,10 +1039,6 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, UNUSED|CONST|
FREE_OP1();
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (OP1_TYPE == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
/*
if (!target_symbol_table) {
CHECK_EXCEPTION();
@@ -1076,6 +1063,29 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, UNUSED|CONST|
break;
EMPTY_SWITCH_DEFAULT_CASE()
}
+//??? GLOBAL or $$name variable may be an INDIRECT pointer to CV
+ } else if (/*(opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_STATIC &&*/
+ Z_TYPE_P(retval) == IS_INDIRECT) {
+ retval = Z_INDIRECT_P(retval);
+ if (Z_TYPE_P(retval) == IS_UNDEF) {
+ switch (type) {
+ case BP_VAR_R:
+ case BP_VAR_UNSET:
+ zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
+ /* break missing intentionally */
+ case BP_VAR_IS:
+ retval = EX_VAR(opline->result.var);
+ ZVAL_NULL(retval);
+ break;
+ case BP_VAR_RW:
+ zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
+ /* break missing intentionally */
+ case BP_VAR_W:
+ ZVAL_NULL(retval);
+ break;
+ EMPTY_SWITCH_DEFAULT_CASE()
+ }
+ }
}
switch (opline->extended_value & ZEND_FETCH_TYPE_MASK) {
case ZEND_FETCH_GLOBAL:
@@ -1860,9 +1870,15 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
zend_bool nested = EX(nested);
zend_op_array *op_array = EX(op_array);
+ if ((nested && EX(prev_execute_data)->opline->opcode == ZEND_INCLUDE_OR_EVAL) ||
+ EG(active_symbol_table) == &EG(symbol_table)) {
+ zend_detach_symbol_table(TSRMLS_C);
+ }
+
EG(current_execute_data) = EX(prev_execute_data);
EG(opline_ptr) = NULL;
- if (!EG(active_symbol_table)) {
+
+ if (EG(active_symbol_table) != &EG(symbol_table)) {
i_free_compiled_variables(execute_data TSRMLS_CC);
}
@@ -1882,6 +1898,8 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
LOAD_OPLINE();
if (UNEXPECTED(opline->opcode == ZEND_INCLUDE_OR_EVAL)) {
+ zend_attach_symbol_table(TSRMLS_C);
+
EX(function_state).function = (zend_function *) EX(op_array);
EX(function_state).arguments = NULL;
@@ -3027,11 +3045,6 @@ ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV)
zval_ptr_dtor(EX_VAR_NUM(opline->op2.var));
}
ZVAL_OBJ(EX_VAR_NUM(opline->op2.var), EG(exception));
- if (EG(active_symbol_table)) {
- zend_string *cv = CV_DEF_OF(opline->op2.var);
- zval *zv = zend_hash_update(&EG(active_symbol_table)->ht, cv, EX_VAR_NUM(opline->op2.var));
- ZVAL_INDIRECT(EX_VAR_NUM(opline->op2.var), zv);
- }
if (UNEXPECTED(EG(exception) != exception)) {
EG(exception)->gc.refcount++;
HANDLE_EXCEPTION();
@@ -3222,7 +3235,7 @@ ZEND_VM_HANDLER(165, ZEND_SEND_UNPACK, ANY, ANY)
args = GET_OP1_ZVAL_PTR(BP_VAR_R);
arg_num = opline->op2.num + EX(call)->num_additional_args + 1;
-again:
+ZEND_VM_C_LABEL(send_again):
switch (Z_TYPE_P(args)) {
case IS_ARRAY: {
HashTable *ht = Z_ARRVAL_P(args);
@@ -3350,7 +3363,7 @@ ZEND_VM_C_LABEL(unpack_iter_dtor):
}
case IS_REFERENCE:
args = Z_REFVAL_P(args);
- goto again;
+ ZEND_VM_C_GOTO(send_again);
break;
default:
zend_error(E_WARNING, "Only arrays and Traversables can be unpacked");
@@ -3419,10 +3432,6 @@ ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST)
ZVAL_COPY_VALUE(&tmp, opline->op2.zv);
zval_update_constant(&tmp, 0 TSRMLS_CC);
-//???: var_ptr may become INDIRECT
- if (Z_TYPE_P(var_ptr) == IS_INDIRECT) {
- var_ptr = Z_INDIRECT_P(var_ptr);
- }
ZVAL_COPY_VALUE(var_ptr, &tmp);
} else {
ZVAL_COPY_VALUE(var_ptr, opline->op2.zv);
@@ -3467,10 +3476,6 @@ ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, ANY, ANY)
for (; arg_num <= arg_count; ++arg_num) {
zval *param = zend_vm_stack_get_arg(arg_num TSRMLS_CC);
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, param, opline->extended_value TSRMLS_CC);
-//??? "params" may became IS_INDIRECT because of symtable initialization in zend_error
- if (Z_TYPE_P(params) == IS_INDIRECT) {
- params = Z_INDIRECT_P(params);
- }
zend_hash_next_index_insert(Z_ARRVAL_P(params), param);
if (Z_REFCOUNTED_P(param)) {
Z_ADDREF_P(param);
@@ -3805,7 +3810,7 @@ ZEND_VM_HANDLER(72, ZEND_ADD_ARRAY_ELEMENT, CONST|TMP|VAR|CV, CONST|TMP|VAR|UNUS
zval *offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
ulong hval;
-again:
+ZEND_VM_C_LABEL(add_again):
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -3827,7 +3832,7 @@ ZEND_VM_C_LABEL(num_index):
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ ZEND_VM_C_GOTO(add_again);
break;
default:
zend_error(E_WARNING, "Illegal offset type");
@@ -3877,7 +3882,7 @@ ZEND_VM_HANDLER(21, ZEND_CAST, CONST|TMP|VAR|CV, ANY)
}
}
-again:
+ZEND_VM_C_LABEL(cast_again):
switch (opline->extended_value) {
case IS_NULL:
convert_to_null(result);
@@ -3917,7 +3922,7 @@ again:
break;
case IS_REFERENCE:
result = Z_REFVAL_P(result);
- goto again;
+ ZEND_VM_C_GOTO(cast_again);
break;
}
FREE_OP1_IF_VAR();
@@ -4061,15 +4066,8 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
if (OP1_TYPE == IS_CV &&
OP2_TYPE == IS_UNUSED &&
(opline->extended_value & ZEND_QUICK_SET)) {
- if (EG(active_symbol_table)) {
- zend_string *cv = CV_DEF_OF(opline->op1.var);
-
- zend_delete_variable(EX(prev_execute_data), &EG(active_symbol_table)->ht, cv TSRMLS_CC);
- ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
- } else if (Z_TYPE_P(EX_VAR_NUM(opline->op1.var)) != IS_UNDEF) {
- zval_ptr_dtor(EX_VAR_NUM(opline->op1.var));
- ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
- }
+ zval_ptr_dtor(EX_VAR_NUM(opline->op1.var));
+ ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -4112,11 +4110,7 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
zend_std_unset_static_property(ce, Z_STR_P(varname), ((OP1_TYPE == IS_CONST) ? opline->op1.literal : NULL) TSRMLS_CC);
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (OP1_TYPE == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
- zend_delete_variable(execute_data, target_symbol_table, Z_STR_P(varname) TSRMLS_CC);
+ zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
}
if (OP1_TYPE != IS_CONST && varname == &tmp) {
@@ -4145,12 +4139,11 @@ ZEND_VM_HANDLER(75, ZEND_UNSET_DIM, VAR|UNUSED|CV, CONST|TMP|VAR|CV)
offset = GET_OP2_ZVAL_PTR(BP_VAR_R);
if (OP1_TYPE != IS_VAR || container) {
-//???deref
-container_again:
+ZEND_VM_C_LABEL(container_again):
switch (Z_TYPE_P(container)) {
case IS_ARRAY: {
HashTable *ht = Z_ARRVAL_P(container);
-offset_again:
+ZEND_VM_C_LABEL(offset_again):
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -4189,7 +4182,7 @@ ZEND_VM_C_LABEL(num_index_dim):
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto offset_again;
+ ZEND_VM_C_GOTO(offset_again);
break;
default:
zend_error(E_WARNING, "Illegal offset type in unset");
@@ -4221,7 +4214,7 @@ ZEND_VM_C_LABEL(num_index_dim):
ZEND_VM_CONTINUE(); /* bailed out before */
case IS_REFERENCE:
container = Z_REFVAL_P(container);
- goto container_again;
+ ZEND_VM_C_GOTO(container_again);
break;
default:
FREE_OP2();
@@ -4492,16 +4485,28 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
fe_ht = Z_OBJPROP_P(array);
zend_hash_set_pointer(fe_ht, (HashPointer*)EX_VAR((opline+1)->op1.var));
- do {
+ while (1) {
if ((value = zend_hash_get_current_data(fe_ht)) == NULL) {
/* reached end of iteration */
ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num);
}
+
+ if (Z_TYPE_P(value) == IS_INDIRECT) {
+ value = Z_INDIRECT_P(value);
+ if (Z_TYPE_P(value) == IS_UNDEF) {
+ zend_hash_move_forward(fe_ht);
+ continue;
+ }
+ }
+
key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &int_key, 0, NULL);
zend_hash_move_forward(fe_ht);
- } while (key_type != HASH_KEY_IS_LONG &&
- zend_check_property_access(zobj, str_key TSRMLS_CC) != SUCCESS);
+ if (key_type == HASH_KEY_IS_LONG ||
+ zend_check_property_access(zobj, str_key TSRMLS_CC) == SUCCESS) {
+ break;
+ }
+ }
if (key) {
if (key_type == HASH_KEY_IS_LONG) {
@@ -4599,18 +4604,9 @@ ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
(opline->extended_value & ZEND_QUICK_SET)) {
if (Z_TYPE_P(EX_VAR_NUM(opline->op1.var)) != IS_UNDEF) {
value = EX_VAR_NUM(opline->op1.var);
- if (Z_TYPE_P(value) == IS_INDIRECT) {
- value = Z_INDIRECT_P(value);
- }
if (Z_TYPE_P(value) == IS_REFERENCE) {
value = Z_REFVAL_P(value);
}
- } else if (EG(active_symbol_table)) {
- zend_string *cv = CV_DEF_OF(opline->op1.var);
-
- if ((value = zend_hash_find(&EG(active_symbol_table)->ht, cv)) == NULL) {
- isset = 0;
- }
} else {
isset = 0;
}
@@ -4648,10 +4644,6 @@ ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMP|VAR|CV, UNUSED|CONST|VAR)
}
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (OP1_TYPE == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
if ((value = zend_hash_find(target_symbol_table, Z_STR_P(varname))) == NULL) {
isset = 0;
}
@@ -4704,7 +4696,7 @@ ZEND_VM_HELPER_EX(zend_isset_isempty_dim_prop_obj_handler, VAR|UNUSED|CV, CONST|
ht = Z_ARRVAL_P(container);
-again:
+ZEND_VM_C_LABEL(isset_again):
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -4722,18 +4714,18 @@ ZEND_VM_C_LABEL(num_index_prop):
if (OP2_TYPE != IS_CONST) {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, ZEND_VM_C_GOTO(num_index_prop));
}
- if ((value = zend_hash_find(ht, Z_STR_P(offset))) != NULL) {
+ if ((value = zend_hash_find_ind(ht, Z_STR_P(offset))) != NULL) {
isset = 1;
}
break;
case IS_NULL:
- if ((value = zend_hash_find(ht, STR_EMPTY_ALLOC())) != NULL) {
+ if ((value = zend_hash_find_ind(ht, STR_EMPTY_ALLOC())) != NULL) {
isset = 1;
}
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ ZEND_VM_C_GOTO(isset_again);
break;
default:
zend_error(E_WARNING, "Illegal offset type in isset or empty");
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index c61ad64045..2ebff4738d 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -386,9 +386,15 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
zend_bool nested = EX(nested);
zend_op_array *op_array = EX(op_array);
+ if ((nested && EX(prev_execute_data)->opline->opcode == ZEND_INCLUDE_OR_EVAL) ||
+ EG(active_symbol_table) == &EG(symbol_table)) {
+ zend_detach_symbol_table(TSRMLS_C);
+ }
+
EG(current_execute_data) = EX(prev_execute_data);
EG(opline_ptr) = NULL;
- if (!EG(active_symbol_table)) {
+
+ if (EG(active_symbol_table) != &EG(symbol_table)) {
i_free_compiled_variables(execute_data TSRMLS_CC);
}
@@ -408,6 +414,8 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
LOAD_OPLINE();
if (UNEXPECTED(opline->opcode == ZEND_INCLUDE_OR_EVAL)) {
+ zend_attach_symbol_table(TSRMLS_C);
+
EX(function_state).function = (zend_function *) EX(op_array);
EX(function_state).arguments = NULL;
@@ -702,7 +710,7 @@ static int ZEND_FASTCALL ZEND_SEND_UNPACK_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS
args = get_zval_ptr(opline->op1_type, &opline->op1, execute_data, &free_op1, BP_VAR_R);
arg_num = opline->op2.num + EX(call)->num_additional_args + 1;
-again:
+send_again:
switch (Z_TYPE_P(args)) {
case IS_ARRAY: {
HashTable *ht = Z_ARRVAL_P(args);
@@ -830,7 +838,7 @@ unpack_iter_dtor:
}
case IS_REFERENCE:
args = Z_REFVAL_P(args);
- goto again;
+ goto send_again;
break;
default:
zend_error(E_WARNING, "Only arrays and Traversables can be unpacked");
@@ -902,10 +910,6 @@ static int ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR
for (; arg_num <= arg_count; ++arg_num) {
zval *param = zend_vm_stack_get_arg(arg_num TSRMLS_CC);
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, param, opline->extended_value TSRMLS_CC);
-//??? "params" may became IS_INDIRECT because of symtable initialization in zend_error
- if (Z_TYPE_P(params) == IS_INDIRECT) {
- params = Z_INDIRECT_P(params);
- }
zend_hash_next_index_insert(Z_ARRVAL_P(params), param);
if (Z_REFCOUNTED_P(param)) {
Z_ADDREF_P(param);
@@ -1616,10 +1620,6 @@ static int ZEND_FASTCALL ZEND_RECV_INIT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_
ZVAL_COPY_VALUE(&tmp, opline->op2.zv);
zval_update_constant(&tmp, 0 TSRMLS_CC);
-//???: var_ptr may become INDIRECT
- if (Z_TYPE_P(var_ptr) == IS_INDIRECT) {
- var_ptr = Z_INDIRECT_P(var_ptr);
- }
ZVAL_COPY_VALUE(var_ptr, &tmp);
} else {
ZVAL_COPY_VALUE(var_ptr, opline->op2.zv);
@@ -2814,7 +2814,7 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
}
}
-again:
+cast_again:
switch (opline->extended_value) {
case IS_NULL:
convert_to_null(result);
@@ -2854,7 +2854,7 @@ again:
break;
case IS_REFERENCE:
result = Z_REFVAL_P(result);
- goto again;
+ goto cast_again;
break;
}
@@ -3603,10 +3603,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_CONST(int type
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_CONST == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
/*
if (!target_symbol_table) {
CHECK_EXCEPTION();
@@ -3631,6 +3627,29 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_CONST(int type
break;
EMPTY_SWITCH_DEFAULT_CASE()
}
+//??? GLOBAL or $$name variable may be an INDIRECT pointer to CV
+ } else if (/*(opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_STATIC &&*/
+ Z_TYPE_P(retval) == IS_INDIRECT) {
+ retval = Z_INDIRECT_P(retval);
+ if (Z_TYPE_P(retval) == IS_UNDEF) {
+ switch (type) {
+ case BP_VAR_R:
+ case BP_VAR_UNSET:
+ zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
+ /* break missing intentionally */
+ case BP_VAR_IS:
+ retval = EX_VAR(opline->result.var);
+ ZVAL_NULL(retval);
+ break;
+ case BP_VAR_RW:
+ zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
+ /* break missing intentionally */
+ case BP_VAR_W:
+ ZVAL_NULL(retval);
+ break;
+ EMPTY_SWITCH_DEFAULT_CASE()
+ }
+ }
}
switch (opline->extended_value & ZEND_FETCH_TYPE_MASK) {
case ZEND_FETCH_GLOBAL:
@@ -4013,7 +4032,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CONST_HANDLER(ZEND_O
zval *offset = opline->op2.zv;
ulong hval;
-again:
+add_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -4035,7 +4054,7 @@ num_index:
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto add_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type");
@@ -4079,15 +4098,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HA
if (IS_CONST == IS_CV &&
IS_CONST == IS_UNUSED &&
(opline->extended_value & ZEND_QUICK_SET)) {
- if (EG(active_symbol_table)) {
- zend_string *cv = CV_DEF_OF(opline->op1.var);
-
- zend_delete_variable(EX(prev_execute_data), &EG(active_symbol_table)->ht, cv TSRMLS_CC);
- ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
- } else if (Z_TYPE_P(EX_VAR_NUM(opline->op1.var)) != IS_UNDEF) {
- zval_ptr_dtor(EX_VAR_NUM(opline->op1.var));
- ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
- }
+ zval_ptr_dtor(EX_VAR_NUM(opline->op1.var));
+ ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -4130,11 +4142,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HA
zend_std_unset_static_property(ce, Z_STR_P(varname), ((IS_CONST == IS_CONST) ? opline->op1.literal : NULL) TSRMLS_CC);
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_CONST == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
- zend_delete_variable(execute_data, target_symbol_table, Z_STR_P(varname) TSRMLS_CC);
+ zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
}
if (IS_CONST != IS_CONST && varname == &tmp) {
@@ -4159,18 +4167,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_CONST_HANDLER(ZEND_O
(opline->extended_value & ZEND_QUICK_SET)) {
if (Z_TYPE_P(EX_VAR_NUM(opline->op1.var)) != IS_UNDEF) {
value = EX_VAR_NUM(opline->op1.var);
- if (Z_TYPE_P(value) == IS_INDIRECT) {
- value = Z_INDIRECT_P(value);
- }
if (Z_TYPE_P(value) == IS_REFERENCE) {
value = Z_REFVAL_P(value);
}
- } else if (EG(active_symbol_table)) {
- zend_string *cv = CV_DEF_OF(opline->op1.var);
-
- if ((value = zend_hash_find(&EG(active_symbol_table)->ht, cv)) == NULL) {
- isset = 0;
- }
} else {
isset = 0;
}
@@ -4208,10 +4207,6 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_CONST_HANDLER(ZEND_O
}
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_CONST == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
if ((value = zend_hash_find(target_symbol_table, Z_STR_P(varname))) == NULL) {
isset = 0;
}
@@ -4868,7 +4863,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_TMP_HANDLER(ZEND_OPC
zval *offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
ulong hval;
-again:
+add_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -4890,7 +4885,7 @@ num_index:
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto add_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type");
@@ -5381,10 +5376,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_VAR(int type,
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_CONST == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
/*
if (!target_symbol_table) {
CHECK_EXCEPTION();
@@ -5409,6 +5400,29 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_VAR(int type,
break;
EMPTY_SWITCH_DEFAULT_CASE()
}
+//??? GLOBAL or $$name variable may be an INDIRECT pointer to CV
+ } else if (/*(opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_STATIC &&*/
+ Z_TYPE_P(retval) == IS_INDIRECT) {
+ retval = Z_INDIRECT_P(retval);
+ if (Z_TYPE_P(retval) == IS_UNDEF) {
+ switch (type) {
+ case BP_VAR_R:
+ case BP_VAR_UNSET:
+ zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
+ /* break missing intentionally */
+ case BP_VAR_IS:
+ retval = EX_VAR(opline->result.var);
+ ZVAL_NULL(retval);
+ break;
+ case BP_VAR_RW:
+ zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
+ /* break missing intentionally */
+ case BP_VAR_W:
+ ZVAL_NULL(retval);
+ break;
+ EMPTY_SWITCH_DEFAULT_CASE()
+ }
+ }
}
switch (opline->extended_value & ZEND_FETCH_TYPE_MASK) {
case ZEND_FETCH_GLOBAL:
@@ -5677,7 +5691,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_VAR_HANDLER(ZEND_OPC
zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
ulong hval;
-again:
+add_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -5699,7 +5713,7 @@ num_index:
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto add_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type");
@@ -5743,15 +5757,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HAND
if (IS_CONST == IS_CV &&
IS_VAR == IS_UNUSED &&
(opline->extended_value & ZEND_QUICK_SET)) {
- if (EG(active_symbol_table)) {
- zend_string *cv = CV_DEF_OF(opline->op1.var);
-
- zend_delete_variable(EX(prev_execute_data), &EG(active_symbol_table)->ht, cv TSRMLS_CC);
- ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
- } else if (Z_TYPE_P(EX_VAR_NUM(opline->op1.var)) != IS_UNDEF) {
- zval_ptr_dtor(EX_VAR_NUM(opline->op1.var));
- ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
- }
+ zval_ptr_dtor(EX_VAR_NUM(opline->op1.var));
+ ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -5794,11 +5801,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_VAR_HANDLER(ZEND_OPCODE_HAND
zend_std_unset_static_property(ce, Z_STR_P(varname), ((IS_CONST == IS_CONST) ? opline->op1.literal : NULL) TSRMLS_CC);
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_CONST == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
- zend_delete_variable(execute_data, target_symbol_table, Z_STR_P(varname) TSRMLS_CC);
+ zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
}
if (IS_CONST != IS_CONST && varname == &tmp) {
@@ -5823,18 +5826,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_VAR_HANDLER(ZEND_OPC
(opline->extended_value & ZEND_QUICK_SET)) {
if (Z_TYPE_P(EX_VAR_NUM(opline->op1.var)) != IS_UNDEF) {
value = EX_VAR_NUM(opline->op1.var);
- if (Z_TYPE_P(value) == IS_INDIRECT) {
- value = Z_INDIRECT_P(value);
- }
if (Z_TYPE_P(value) == IS_REFERENCE) {
value = Z_REFVAL_P(value);
}
- } else if (EG(active_symbol_table)) {
- zend_string *cv = CV_DEF_OF(opline->op1.var);
-
- if ((value = zend_hash_find(&EG(active_symbol_table)->ht, cv)) == NULL) {
- isset = 0;
- }
} else {
isset = 0;
}
@@ -5872,10 +5866,6 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_VAR_HANDLER(ZEND_OPC
}
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_CONST == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
if ((value = zend_hash_find(target_symbol_table, Z_STR_P(varname))) == NULL) {
isset = 0;
}
@@ -6088,10 +6078,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_UNUSED(int typ
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_CONST == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
/*
if (!target_symbol_table) {
CHECK_EXCEPTION();
@@ -6116,6 +6102,29 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CONST_UNUSED(int typ
break;
EMPTY_SWITCH_DEFAULT_CASE()
}
+//??? GLOBAL or $$name variable may be an INDIRECT pointer to CV
+ } else if (/*(opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_STATIC &&*/
+ Z_TYPE_P(retval) == IS_INDIRECT) {
+ retval = Z_INDIRECT_P(retval);
+ if (Z_TYPE_P(retval) == IS_UNDEF) {
+ switch (type) {
+ case BP_VAR_R:
+ case BP_VAR_UNSET:
+ zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
+ /* break missing intentionally */
+ case BP_VAR_IS:
+ retval = EX_VAR(opline->result.var);
+ ZVAL_NULL(retval);
+ break;
+ case BP_VAR_RW:
+ zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
+ /* break missing intentionally */
+ case BP_VAR_W:
+ ZVAL_NULL(retval);
+ break;
+ EMPTY_SWITCH_DEFAULT_CASE()
+ }
+ }
}
switch (opline->extended_value & ZEND_FETCH_TYPE_MASK) {
case ZEND_FETCH_GLOBAL:
@@ -6352,7 +6361,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_UNUSED_HANDLER(ZEND_
zval *offset = NULL;
ulong hval;
-again:
+add_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -6374,7 +6383,7 @@ num_index:
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto add_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type");
@@ -6418,15 +6427,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_H
if (IS_CONST == IS_CV &&
IS_UNUSED == IS_UNUSED &&
(opline->extended_value & ZEND_QUICK_SET)) {
- if (EG(active_symbol_table)) {
- zend_string *cv = CV_DEF_OF(opline->op1.var);
-
- zend_delete_variable(EX(prev_execute_data), &EG(active_symbol_table)->ht, cv TSRMLS_CC);
- ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
- } else if (Z_TYPE_P(EX_VAR_NUM(opline->op1.var)) != IS_UNDEF) {
- zval_ptr_dtor(EX_VAR_NUM(opline->op1.var));
- ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
- }
+ zval_ptr_dtor(EX_VAR_NUM(opline->op1.var));
+ ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -6469,11 +6471,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_H
zend_std_unset_static_property(ce, Z_STR_P(varname), ((IS_CONST == IS_CONST) ? opline->op1.literal : NULL) TSRMLS_CC);
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_CONST == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
- zend_delete_variable(execute_data, target_symbol_table, Z_STR_P(varname) TSRMLS_CC);
+ zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
}
if (IS_CONST != IS_CONST && varname == &tmp) {
@@ -6498,18 +6496,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED_HANDLER(ZEND_
(opline->extended_value & ZEND_QUICK_SET)) {
if (Z_TYPE_P(EX_VAR_NUM(opline->op1.var)) != IS_UNDEF) {
value = EX_VAR_NUM(opline->op1.var);
- if (Z_TYPE_P(value) == IS_INDIRECT) {
- value = Z_INDIRECT_P(value);
- }
if (Z_TYPE_P(value) == IS_REFERENCE) {
value = Z_REFVAL_P(value);
}
- } else if (EG(active_symbol_table)) {
- zend_string *cv = CV_DEF_OF(opline->op1.var);
-
- if ((value = zend_hash_find(&EG(active_symbol_table)->ht, cv)) == NULL) {
- isset = 0;
- }
} else {
isset = 0;
}
@@ -6547,10 +6536,6 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CONST_UNUSED_HANDLER(ZEND_
}
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_CONST == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
if ((value = zend_hash_find(target_symbol_table, Z_STR_P(varname))) == NULL) {
isset = 0;
}
@@ -7186,11 +7171,6 @@ static int ZEND_FASTCALL ZEND_CATCH_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_A
zval_ptr_dtor(EX_VAR_NUM(opline->op2.var));
}
ZVAL_OBJ(EX_VAR_NUM(opline->op2.var), EG(exception));
- if (EG(active_symbol_table)) {
- zend_string *cv = CV_DEF_OF(opline->op2.var);
- zval *zv = zend_hash_update(&EG(active_symbol_table)->ht, cv, EX_VAR_NUM(opline->op2.var));
- ZVAL_INDIRECT(EX_VAR_NUM(opline->op2.var), zv);
- }
if (UNEXPECTED(EG(exception) != exception)) {
EG(exception)->gc.refcount++;
HANDLE_EXCEPTION();
@@ -7250,7 +7230,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CONST_CV_HANDLER(ZEND_OPCO
zval *offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
ulong hval;
-again:
+add_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -7272,7 +7252,7 @@ num_index:
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto add_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type");
@@ -7906,7 +7886,7 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
}
}
-again:
+cast_again:
switch (opline->extended_value) {
case IS_NULL:
convert_to_null(result);
@@ -7946,7 +7926,7 @@ again:
break;
case IS_REFERENCE:
result = Z_REFVAL_P(result);
- goto again;
+ goto cast_again;
break;
}
@@ -8745,10 +8725,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_CONST(int type,
zval_dtor(free_op1.var);
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_TMP_VAR == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
/*
if (!target_symbol_table) {
CHECK_EXCEPTION();
@@ -8773,6 +8749,29 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_CONST(int type,
break;
EMPTY_SWITCH_DEFAULT_CASE()
}
+//??? GLOBAL or $$name variable may be an INDIRECT pointer to CV
+ } else if (/*(opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_STATIC &&*/
+ Z_TYPE_P(retval) == IS_INDIRECT) {
+ retval = Z_INDIRECT_P(retval);
+ if (Z_TYPE_P(retval) == IS_UNDEF) {
+ switch (type) {
+ case BP_VAR_R:
+ case BP_VAR_UNSET:
+ zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
+ /* break missing intentionally */
+ case BP_VAR_IS:
+ retval = EX_VAR(opline->result.var);
+ ZVAL_NULL(retval);
+ break;
+ case BP_VAR_RW:
+ zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
+ /* break missing intentionally */
+ case BP_VAR_W:
+ ZVAL_NULL(retval);
+ break;
+ EMPTY_SWITCH_DEFAULT_CASE()
+ }
+ }
}
switch (opline->extended_value & ZEND_FETCH_TYPE_MASK) {
case ZEND_FETCH_GLOBAL:
@@ -9063,7 +9062,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CONST_HANDLER(ZEND_OPC
zval *offset = opline->op2.zv;
ulong hval;
-again:
+add_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -9085,7 +9084,7 @@ num_index:
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto add_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type");
@@ -9129,15 +9128,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HAND
if (IS_TMP_VAR == IS_CV &&
IS_CONST == IS_UNUSED &&
(opline->extended_value & ZEND_QUICK_SET)) {
- if (EG(active_symbol_table)) {
- zend_string *cv = CV_DEF_OF(opline->op1.var);
-
- zend_delete_variable(EX(prev_execute_data), &EG(active_symbol_table)->ht, cv TSRMLS_CC);
- ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
- } else if (Z_TYPE_P(EX_VAR_NUM(opline->op1.var)) != IS_UNDEF) {
- zval_ptr_dtor(EX_VAR_NUM(opline->op1.var));
- ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
- }
+ zval_ptr_dtor(EX_VAR_NUM(opline->op1.var));
+ ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -9180,11 +9172,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPCODE_HAND
zend_std_unset_static_property(ce, Z_STR_P(varname), ((IS_TMP_VAR == IS_CONST) ? opline->op1.literal : NULL) TSRMLS_CC);
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_TMP_VAR == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
- zend_delete_variable(execute_data, target_symbol_table, Z_STR_P(varname) TSRMLS_CC);
+ zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
}
if (IS_TMP_VAR != IS_CONST && varname == &tmp) {
@@ -9209,18 +9197,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPC
(opline->extended_value & ZEND_QUICK_SET)) {
if (Z_TYPE_P(EX_VAR_NUM(opline->op1.var)) != IS_UNDEF) {
value = EX_VAR_NUM(opline->op1.var);
- if (Z_TYPE_P(value) == IS_INDIRECT) {
- value = Z_INDIRECT_P(value);
- }
if (Z_TYPE_P(value) == IS_REFERENCE) {
value = Z_REFVAL_P(value);
}
- } else if (EG(active_symbol_table)) {
- zend_string *cv = CV_DEF_OF(opline->op1.var);
-
- if ((value = zend_hash_find(&EG(active_symbol_table)->ht, cv)) == NULL) {
- isset = 0;
- }
} else {
isset = 0;
}
@@ -9258,10 +9237,6 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_CONST_HANDLER(ZEND_OPC
}
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_TMP_VAR == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
if ((value = zend_hash_find(target_symbol_table, Z_STR_P(varname))) == NULL) {
isset = 0;
}
@@ -9895,7 +9870,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_TMP_HANDLER(ZEND_OPCOD
zval *offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
ulong hval;
-again:
+add_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -9917,7 +9892,7 @@ num_index:
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto add_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type");
@@ -10408,10 +10383,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_VAR(int type, ZE
zval_dtor(free_op1.var);
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_TMP_VAR == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
/*
if (!target_symbol_table) {
CHECK_EXCEPTION();
@@ -10436,6 +10407,29 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_VAR(int type, ZE
break;
EMPTY_SWITCH_DEFAULT_CASE()
}
+//??? GLOBAL or $$name variable may be an INDIRECT pointer to CV
+ } else if (/*(opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_STATIC &&*/
+ Z_TYPE_P(retval) == IS_INDIRECT) {
+ retval = Z_INDIRECT_P(retval);
+ if (Z_TYPE_P(retval) == IS_UNDEF) {
+ switch (type) {
+ case BP_VAR_R:
+ case BP_VAR_UNSET:
+ zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
+ /* break missing intentionally */
+ case BP_VAR_IS:
+ retval = EX_VAR(opline->result.var);
+ ZVAL_NULL(retval);
+ break;
+ case BP_VAR_RW:
+ zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
+ /* break missing intentionally */
+ case BP_VAR_W:
+ ZVAL_NULL(retval);
+ break;
+ EMPTY_SWITCH_DEFAULT_CASE()
+ }
+ }
}
switch (opline->extended_value & ZEND_FETCH_TYPE_MASK) {
case ZEND_FETCH_GLOBAL:
@@ -10714,7 +10708,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_VAR_HANDLER(ZEND_OPCOD
zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
ulong hval;
-again:
+add_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -10736,7 +10730,7 @@ num_index:
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto add_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type");
@@ -10780,15 +10774,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLE
if (IS_TMP_VAR == IS_CV &&
IS_VAR == IS_UNUSED &&
(opline->extended_value & ZEND_QUICK_SET)) {
- if (EG(active_symbol_table)) {
- zend_string *cv = CV_DEF_OF(opline->op1.var);
-
- zend_delete_variable(EX(prev_execute_data), &EG(active_symbol_table)->ht, cv TSRMLS_CC);
- ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
- } else if (Z_TYPE_P(EX_VAR_NUM(opline->op1.var)) != IS_UNDEF) {
- zval_ptr_dtor(EX_VAR_NUM(opline->op1.var));
- ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
- }
+ zval_ptr_dtor(EX_VAR_NUM(opline->op1.var));
+ ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -10831,11 +10818,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE_HANDLE
zend_std_unset_static_property(ce, Z_STR_P(varname), ((IS_TMP_VAR == IS_CONST) ? opline->op1.literal : NULL) TSRMLS_CC);
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_TMP_VAR == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
- zend_delete_variable(execute_data, target_symbol_table, Z_STR_P(varname) TSRMLS_CC);
+ zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
}
if (IS_TMP_VAR != IS_CONST && varname == &tmp) {
@@ -10860,18 +10843,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCOD
(opline->extended_value & ZEND_QUICK_SET)) {
if (Z_TYPE_P(EX_VAR_NUM(opline->op1.var)) != IS_UNDEF) {
value = EX_VAR_NUM(opline->op1.var);
- if (Z_TYPE_P(value) == IS_INDIRECT) {
- value = Z_INDIRECT_P(value);
- }
if (Z_TYPE_P(value) == IS_REFERENCE) {
value = Z_REFVAL_P(value);
}
- } else if (EG(active_symbol_table)) {
- zend_string *cv = CV_DEF_OF(opline->op1.var);
-
- if ((value = zend_hash_find(&EG(active_symbol_table)->ht, cv)) == NULL) {
- isset = 0;
- }
} else {
isset = 0;
}
@@ -10909,10 +10883,6 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_VAR_HANDLER(ZEND_OPCOD
}
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_TMP_VAR == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
if ((value = zend_hash_find(target_symbol_table, Z_STR_P(varname))) == NULL) {
isset = 0;
}
@@ -11125,10 +11095,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_UNUSED(int type,
zval_dtor(free_op1.var);
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_TMP_VAR == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
/*
if (!target_symbol_table) {
CHECK_EXCEPTION();
@@ -11153,6 +11119,29 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP_UNUSED(int type,
break;
EMPTY_SWITCH_DEFAULT_CASE()
}
+//??? GLOBAL or $$name variable may be an INDIRECT pointer to CV
+ } else if (/*(opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_STATIC &&*/
+ Z_TYPE_P(retval) == IS_INDIRECT) {
+ retval = Z_INDIRECT_P(retval);
+ if (Z_TYPE_P(retval) == IS_UNDEF) {
+ switch (type) {
+ case BP_VAR_R:
+ case BP_VAR_UNSET:
+ zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
+ /* break missing intentionally */
+ case BP_VAR_IS:
+ retval = EX_VAR(opline->result.var);
+ ZVAL_NULL(retval);
+ break;
+ case BP_VAR_RW:
+ zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
+ /* break missing intentionally */
+ case BP_VAR_W:
+ ZVAL_NULL(retval);
+ break;
+ EMPTY_SWITCH_DEFAULT_CASE()
+ }
+ }
}
switch (opline->extended_value & ZEND_FETCH_TYPE_MASK) {
case ZEND_FETCH_GLOBAL:
@@ -11278,7 +11267,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_UNUSED_HANDLER(ZEND_OP
zval *offset = NULL;
ulong hval;
-again:
+add_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -11300,7 +11289,7 @@ num_index:
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto add_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type");
@@ -11344,15 +11333,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HAN
if (IS_TMP_VAR == IS_CV &&
IS_UNUSED == IS_UNUSED &&
(opline->extended_value & ZEND_QUICK_SET)) {
- if (EG(active_symbol_table)) {
- zend_string *cv = CV_DEF_OF(opline->op1.var);
-
- zend_delete_variable(EX(prev_execute_data), &EG(active_symbol_table)->ht, cv TSRMLS_CC);
- ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
- } else if (Z_TYPE_P(EX_VAR_NUM(opline->op1.var)) != IS_UNDEF) {
- zval_ptr_dtor(EX_VAR_NUM(opline->op1.var));
- ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
- }
+ zval_ptr_dtor(EX_VAR_NUM(opline->op1.var));
+ ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -11395,11 +11377,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_TMP_UNUSED_HANDLER(ZEND_OPCODE_HAN
zend_std_unset_static_property(ce, Z_STR_P(varname), ((IS_TMP_VAR == IS_CONST) ? opline->op1.literal : NULL) TSRMLS_CC);
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_TMP_VAR == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
- zend_delete_variable(execute_data, target_symbol_table, Z_STR_P(varname) TSRMLS_CC);
+ zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
}
if (IS_TMP_VAR != IS_CONST && varname == &tmp) {
@@ -11424,18 +11402,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_UNUSED_HANDLER(ZEND_OP
(opline->extended_value & ZEND_QUICK_SET)) {
if (Z_TYPE_P(EX_VAR_NUM(opline->op1.var)) != IS_UNDEF) {
value = EX_VAR_NUM(opline->op1.var);
- if (Z_TYPE_P(value) == IS_INDIRECT) {
- value = Z_INDIRECT_P(value);
- }
if (Z_TYPE_P(value) == IS_REFERENCE) {
value = Z_REFVAL_P(value);
}
- } else if (EG(active_symbol_table)) {
- zend_string *cv = CV_DEF_OF(opline->op1.var);
-
- if ((value = zend_hash_find(&EG(active_symbol_table)->ht, cv)) == NULL) {
- isset = 0;
- }
} else {
isset = 0;
}
@@ -11473,10 +11442,6 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_TMP_UNUSED_HANDLER(ZEND_OP
}
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_TMP_VAR == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
if ((value = zend_hash_find(target_symbol_table, Z_STR_P(varname))) == NULL) {
isset = 0;
}
@@ -12107,7 +12072,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_TMP_CV_HANDLER(ZEND_OPCODE
zval *offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
ulong hval;
-again:
+add_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -12129,7 +12094,7 @@ num_index:
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto add_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type");
@@ -13076,7 +13041,7 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
}
}
-again:
+cast_again:
switch (opline->extended_value) {
case IS_NULL:
convert_to_null(result);
@@ -13116,7 +13081,7 @@ again:
break;
case IS_REFERENCE:
result = Z_REFVAL_P(result);
- goto again;
+ goto cast_again;
break;
}
zval_ptr_dtor_nogc(free_op1.var);
@@ -13464,16 +13429,28 @@ static int ZEND_FASTCALL ZEND_FE_FETCH_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
fe_ht = Z_OBJPROP_P(array);
zend_hash_set_pointer(fe_ht, (HashPointer*)EX_VAR((opline+1)->op1.var));
- do {
+ while (1) {
if ((value = zend_hash_get_current_data(fe_ht)) == NULL) {
/* reached end of iteration */
ZEND_VM_JMP(EX(op_array)->opcodes+opline->op2.opline_num);
}
+
+ if (Z_TYPE_P(value) == IS_INDIRECT) {
+ value = Z_INDIRECT_P(value);
+ if (Z_TYPE_P(value) == IS_UNDEF) {
+ zend_hash_move_forward(fe_ht);
+ continue;
+ }
+ }
+
key_type = zend_hash_get_current_key_ex(fe_ht, &str_key, &int_key, 0, NULL);
zend_hash_move_forward(fe_ht);
- } while (key_type != HASH_KEY_IS_LONG &&
- zend_check_property_access(zobj, str_key TSRMLS_CC) != SUCCESS);
+ if (key_type == HASH_KEY_IS_LONG ||
+ zend_check_property_access(zobj, str_key TSRMLS_CC) == SUCCESS) {
+ break;
+ }
+ }
if (key) {
if (key_type == HASH_KEY_IS_LONG) {
@@ -13988,17 +13965,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CONST(int (*b
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
-//???: object may become INDIRECT
- if (IS_VAR == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
-
if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
make_real_object(object TSRMLS_CC);
-//???
- if (Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
}
if (UNEXPECTED(Z_ISREF_P(object))) {
object = Z_REFVAL_P(object);
@@ -14475,10 +14443,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_CONST(int type,
zval_ptr_dtor_nogc(free_op1.var);
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_VAR == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
/*
if (!target_symbol_table) {
CHECK_EXCEPTION();
@@ -14503,6 +14467,29 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_CONST(int type,
break;
EMPTY_SWITCH_DEFAULT_CASE()
}
+//??? GLOBAL or $$name variable may be an INDIRECT pointer to CV
+ } else if (/*(opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_STATIC &&*/
+ Z_TYPE_P(retval) == IS_INDIRECT) {
+ retval = Z_INDIRECT_P(retval);
+ if (Z_TYPE_P(retval) == IS_UNDEF) {
+ switch (type) {
+ case BP_VAR_R:
+ case BP_VAR_UNSET:
+ zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
+ /* break missing intentionally */
+ case BP_VAR_IS:
+ retval = EX_VAR(opline->result.var);
+ ZVAL_NULL(retval);
+ break;
+ case BP_VAR_RW:
+ zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
+ /* break missing intentionally */
+ case BP_VAR_W:
+ ZVAL_NULL(retval);
+ break;
+ EMPTY_SWITCH_DEFAULT_CASE()
+ }
+ }
}
switch (opline->extended_value & ZEND_FETCH_TYPE_MASK) {
case ZEND_FETCH_GLOBAL:
@@ -15527,7 +15514,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CONST_HANDLER(ZEND_OPC
zval *offset = opline->op2.zv;
ulong hval;
-again:
+add_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -15549,7 +15536,7 @@ num_index:
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto add_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type");
@@ -15593,15 +15580,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND
if (IS_VAR == IS_CV &&
IS_CONST == IS_UNUSED &&
(opline->extended_value & ZEND_QUICK_SET)) {
- if (EG(active_symbol_table)) {
- zend_string *cv = CV_DEF_OF(opline->op1.var);
-
- zend_delete_variable(EX(prev_execute_data), &EG(active_symbol_table)->ht, cv TSRMLS_CC);
- ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
- } else if (Z_TYPE_P(EX_VAR_NUM(opline->op1.var)) != IS_UNDEF) {
- zval_ptr_dtor(EX_VAR_NUM(opline->op1.var));
- ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
- }
+ zval_ptr_dtor(EX_VAR_NUM(opline->op1.var));
+ ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -15644,11 +15624,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND
zend_std_unset_static_property(ce, Z_STR_P(varname), ((IS_VAR == IS_CONST) ? opline->op1.literal : NULL) TSRMLS_CC);
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_VAR == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
- zend_delete_variable(execute_data, target_symbol_table, Z_STR_P(varname) TSRMLS_CC);
+ zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
}
if (IS_VAR != IS_CONST && varname == &tmp) {
@@ -15677,7 +15653,6 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HAND
offset = opline->op2.zv;
if (IS_VAR != IS_VAR || container) {
-//???deref
container_again:
switch (Z_TYPE_P(container)) {
case IS_ARRAY: {
@@ -15821,18 +15796,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPC
(opline->extended_value & ZEND_QUICK_SET)) {
if (Z_TYPE_P(EX_VAR_NUM(opline->op1.var)) != IS_UNDEF) {
value = EX_VAR_NUM(opline->op1.var);
- if (Z_TYPE_P(value) == IS_INDIRECT) {
- value = Z_INDIRECT_P(value);
- }
if (Z_TYPE_P(value) == IS_REFERENCE) {
value = Z_REFVAL_P(value);
}
- } else if (EG(active_symbol_table)) {
- zend_string *cv = CV_DEF_OF(opline->op1.var);
-
- if ((value = zend_hash_find(&EG(active_symbol_table)->ht, cv)) == NULL) {
- isset = 0;
- }
} else {
isset = 0;
}
@@ -15870,10 +15836,6 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_CONST_HANDLER(ZEND_OPC
}
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_VAR == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
if ((value = zend_hash_find(target_symbol_table, Z_STR_P(varname))) == NULL) {
isset = 0;
}
@@ -15926,7 +15888,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CONST(
ht = Z_ARRVAL_P(container);
-again:
+isset_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -15944,18 +15906,18 @@ num_index_prop:
if (IS_CONST != IS_CONST) {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
}
- if ((value = zend_hash_find(ht, Z_STR_P(offset))) != NULL) {
+ if ((value = zend_hash_find_ind(ht, Z_STR_P(offset))) != NULL) {
isset = 1;
}
break;
case IS_NULL:
- if ((value = zend_hash_find(ht, STR_EMPTY_ALLOC())) != NULL) {
+ if ((value = zend_hash_find_ind(ht, STR_EMPTY_ALLOC())) != NULL) {
isset = 1;
}
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto isset_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type in isset or empty");
@@ -16483,17 +16445,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_TMP(int (*bin
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
-//???: object may become INDIRECT
- if (IS_VAR == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
-
if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
make_real_object(object TSRMLS_CC);
-//???
- if (Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
}
if (UNEXPECTED(Z_ISREF_P(object))) {
object = Z_REFVAL_P(object);
@@ -17773,7 +17726,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMP_HANDLER(ZEND_OPCOD
zval *offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
ulong hval;
-again:
+add_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -17795,7 +17748,7 @@ num_index:
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto add_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type");
@@ -17844,7 +17797,6 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE_HANDLE
offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_VAR != IS_VAR || container) {
-//???deref
container_again:
switch (Z_TYPE_P(container)) {
case IS_ARRAY: {
@@ -17999,7 +17951,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_TMP(in
ht = Z_ARRVAL_P(container);
-again:
+isset_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -18017,18 +17969,18 @@ num_index_prop:
if (IS_TMP_VAR != IS_CONST) {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
}
- if ((value = zend_hash_find(ht, Z_STR_P(offset))) != NULL) {
+ if ((value = zend_hash_find_ind(ht, Z_STR_P(offset))) != NULL) {
isset = 1;
}
break;
case IS_NULL:
- if ((value = zend_hash_find(ht, STR_EMPTY_ALLOC())) != NULL) {
+ if ((value = zend_hash_find_ind(ht, STR_EMPTY_ALLOC())) != NULL) {
isset = 1;
}
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto isset_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type in isset or empty");
@@ -18556,17 +18508,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_VAR(int (*bin
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
-//???: object may become INDIRECT
- if (IS_VAR == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
-
if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
make_real_object(object TSRMLS_CC);
-//???
- if (Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
}
if (UNEXPECTED(Z_ISREF_P(object))) {
object = Z_REFVAL_P(object);
@@ -19044,10 +18987,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_VAR(int type, ZE
zval_ptr_dtor_nogc(free_op1.var);
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_VAR == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
/*
if (!target_symbol_table) {
CHECK_EXCEPTION();
@@ -19072,6 +19011,29 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_VAR(int type, ZE
break;
EMPTY_SWITCH_DEFAULT_CASE()
}
+//??? GLOBAL or $$name variable may be an INDIRECT pointer to CV
+ } else if (/*(opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_STATIC &&*/
+ Z_TYPE_P(retval) == IS_INDIRECT) {
+ retval = Z_INDIRECT_P(retval);
+ if (Z_TYPE_P(retval) == IS_UNDEF) {
+ switch (type) {
+ case BP_VAR_R:
+ case BP_VAR_UNSET:
+ zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
+ /* break missing intentionally */
+ case BP_VAR_IS:
+ retval = EX_VAR(opline->result.var);
+ ZVAL_NULL(retval);
+ break;
+ case BP_VAR_RW:
+ zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
+ /* break missing intentionally */
+ case BP_VAR_W:
+ ZVAL_NULL(retval);
+ break;
+ EMPTY_SWITCH_DEFAULT_CASE()
+ }
+ }
}
switch (opline->extended_value & ZEND_FETCH_TYPE_MASK) {
case ZEND_FETCH_GLOBAL:
@@ -20066,7 +20028,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD
zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
ulong hval;
-again:
+add_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -20088,7 +20050,7 @@ num_index:
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto add_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type");
@@ -20132,15 +20094,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE
if (IS_VAR == IS_CV &&
IS_VAR == IS_UNUSED &&
(opline->extended_value & ZEND_QUICK_SET)) {
- if (EG(active_symbol_table)) {
- zend_string *cv = CV_DEF_OF(opline->op1.var);
-
- zend_delete_variable(EX(prev_execute_data), &EG(active_symbol_table)->ht, cv TSRMLS_CC);
- ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
- } else if (Z_TYPE_P(EX_VAR_NUM(opline->op1.var)) != IS_UNDEF) {
- zval_ptr_dtor(EX_VAR_NUM(opline->op1.var));
- ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
- }
+ zval_ptr_dtor(EX_VAR_NUM(opline->op1.var));
+ ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -20183,11 +20138,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE
zend_std_unset_static_property(ce, Z_STR_P(varname), ((IS_VAR == IS_CONST) ? opline->op1.literal : NULL) TSRMLS_CC);
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_VAR == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
- zend_delete_variable(execute_data, target_symbol_table, Z_STR_P(varname) TSRMLS_CC);
+ zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
}
if (IS_VAR != IS_CONST && varname == &tmp) {
@@ -20216,7 +20167,6 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE_HANDLE
offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_VAR != IS_VAR || container) {
-//???deref
container_again:
switch (Z_TYPE_P(container)) {
case IS_ARRAY: {
@@ -20360,18 +20310,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD
(opline->extended_value & ZEND_QUICK_SET)) {
if (Z_TYPE_P(EX_VAR_NUM(opline->op1.var)) != IS_UNDEF) {
value = EX_VAR_NUM(opline->op1.var);
- if (Z_TYPE_P(value) == IS_INDIRECT) {
- value = Z_INDIRECT_P(value);
- }
if (Z_TYPE_P(value) == IS_REFERENCE) {
value = Z_REFVAL_P(value);
}
- } else if (EG(active_symbol_table)) {
- zend_string *cv = CV_DEF_OF(opline->op1.var);
-
- if ((value = zend_hash_find(&EG(active_symbol_table)->ht, cv)) == NULL) {
- isset = 0;
- }
} else {
isset = 0;
}
@@ -20409,10 +20350,6 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_VAR_HANDLER(ZEND_OPCOD
}
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_VAR == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
if ((value = zend_hash_find(target_symbol_table, Z_STR_P(varname))) == NULL) {
isset = 0;
}
@@ -20465,7 +20402,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_VAR(in
ht = Z_ARRVAL_P(container);
-again:
+isset_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -20483,18 +20420,18 @@ num_index_prop:
if (IS_VAR != IS_CONST) {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
}
- if ((value = zend_hash_find(ht, Z_STR_P(offset))) != NULL) {
+ if ((value = zend_hash_find_ind(ht, Z_STR_P(offset))) != NULL) {
isset = 1;
}
break;
case IS_NULL:
- if ((value = zend_hash_find(ht, STR_EMPTY_ALLOC())) != NULL) {
+ if ((value = zend_hash_find_ind(ht, STR_EMPTY_ALLOC())) != NULL) {
isset = 1;
}
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto isset_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type in isset or empty");
@@ -20747,17 +20684,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_UNUSED(int (*
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
-//???: object may become INDIRECT
- if (IS_VAR == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
-
if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
make_real_object(object TSRMLS_CC);
-//???
- if (Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
}
if (UNEXPECTED(Z_ISREF_P(object))) {
object = Z_REFVAL_P(object);
@@ -21040,10 +20968,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_UNUSED(int type,
zval_ptr_dtor_nogc(free_op1.var);
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_VAR == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
/*
if (!target_symbol_table) {
CHECK_EXCEPTION();
@@ -21068,6 +20992,29 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR_UNUSED(int type,
break;
EMPTY_SWITCH_DEFAULT_CASE()
}
+//??? GLOBAL or $$name variable may be an INDIRECT pointer to CV
+ } else if (/*(opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_STATIC &&*/
+ Z_TYPE_P(retval) == IS_INDIRECT) {
+ retval = Z_INDIRECT_P(retval);
+ if (Z_TYPE_P(retval) == IS_UNDEF) {
+ switch (type) {
+ case BP_VAR_R:
+ case BP_VAR_UNSET:
+ zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
+ /* break missing intentionally */
+ case BP_VAR_IS:
+ retval = EX_VAR(opline->result.var);
+ ZVAL_NULL(retval);
+ break;
+ case BP_VAR_RW:
+ zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
+ /* break missing intentionally */
+ case BP_VAR_W:
+ ZVAL_NULL(retval);
+ break;
+ EMPTY_SWITCH_DEFAULT_CASE()
+ }
+ }
}
switch (opline->extended_value & ZEND_FETCH_TYPE_MASK) {
case ZEND_FETCH_GLOBAL:
@@ -21491,7 +21438,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_UNUSED_HANDLER(ZEND_OP
zval *offset = NULL;
ulong hval;
-again:
+add_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -21513,7 +21460,7 @@ num_index:
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto add_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type");
@@ -21557,15 +21504,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAN
if (IS_VAR == IS_CV &&
IS_UNUSED == IS_UNUSED &&
(opline->extended_value & ZEND_QUICK_SET)) {
- if (EG(active_symbol_table)) {
- zend_string *cv = CV_DEF_OF(opline->op1.var);
-
- zend_delete_variable(EX(prev_execute_data), &EG(active_symbol_table)->ht, cv TSRMLS_CC);
- ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
- } else if (Z_TYPE_P(EX_VAR_NUM(opline->op1.var)) != IS_UNDEF) {
- zval_ptr_dtor(EX_VAR_NUM(opline->op1.var));
- ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
- }
+ zval_ptr_dtor(EX_VAR_NUM(opline->op1.var));
+ ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -21608,11 +21548,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HAN
zend_std_unset_static_property(ce, Z_STR_P(varname), ((IS_VAR == IS_CONST) ? opline->op1.literal : NULL) TSRMLS_CC);
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_VAR == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
- zend_delete_variable(execute_data, target_symbol_table, Z_STR_P(varname) TSRMLS_CC);
+ zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
}
if (IS_VAR != IS_CONST && varname == &tmp) {
@@ -21637,18 +21573,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OP
(opline->extended_value & ZEND_QUICK_SET)) {
if (Z_TYPE_P(EX_VAR_NUM(opline->op1.var)) != IS_UNDEF) {
value = EX_VAR_NUM(opline->op1.var);
- if (Z_TYPE_P(value) == IS_INDIRECT) {
- value = Z_INDIRECT_P(value);
- }
if (Z_TYPE_P(value) == IS_REFERENCE) {
value = Z_REFVAL_P(value);
}
- } else if (EG(active_symbol_table)) {
- zend_string *cv = CV_DEF_OF(opline->op1.var);
-
- if ((value = zend_hash_find(&EG(active_symbol_table)->ht, cv)) == NULL) {
- isset = 0;
- }
} else {
isset = 0;
}
@@ -21686,10 +21613,6 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_VAR_UNUSED_HANDLER(ZEND_OP
}
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_VAR == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
if ((value = zend_hash_find(target_symbol_table, Z_STR_P(varname))) == NULL) {
isset = 0;
}
@@ -22167,17 +22090,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_VAR_CV(int (*bina
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
-//???: object may become INDIRECT
- if (IS_VAR == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
-
if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
make_real_object(object TSRMLS_CC);
-//???
- if (Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
}
if (UNEXPECTED(Z_ISREF_P(object))) {
object = Z_REFVAL_P(object);
@@ -23511,7 +23425,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE
zval *offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
ulong hval;
-again:
+add_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -23533,7 +23447,7 @@ num_index:
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto add_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type");
@@ -23582,7 +23496,6 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER
offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_VAR != IS_VAR || container) {
-//???deref
container_again:
switch (Z_TYPE_P(container)) {
case IS_ARRAY: {
@@ -23737,7 +23650,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_VAR_CV(int
ht = Z_ARRVAL_P(container);
-again:
+isset_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -23755,18 +23668,18 @@ num_index_prop:
if (IS_CV != IS_CONST) {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
}
- if ((value = zend_hash_find(ht, Z_STR_P(offset))) != NULL) {
+ if ((value = zend_hash_find_ind(ht, Z_STR_P(offset))) != NULL) {
isset = 1;
}
break;
case IS_NULL:
- if ((value = zend_hash_find(ht, STR_EMPTY_ALLOC())) != NULL) {
+ if ((value = zend_hash_find_ind(ht, STR_EMPTY_ALLOC())) != NULL) {
isset = 1;
}
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto isset_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type in isset or empty");
@@ -24099,17 +24012,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CONST(int
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
-//???: object may become INDIRECT
- if (IS_UNUSED == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
-
if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
make_real_object(object TSRMLS_CC);
-//???
- if (Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
}
if (UNEXPECTED(Z_ISREF_P(object))) {
object = Z_REFVAL_P(object);
@@ -25070,7 +24974,6 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_H
offset = opline->op2.zv;
if (IS_UNUSED != IS_VAR || container) {
-//???deref
container_again:
switch (Z_TYPE_P(container)) {
case IS_ARRAY: {
@@ -25223,7 +25126,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CON
ht = Z_ARRVAL_P(container);
-again:
+isset_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -25241,18 +25144,18 @@ num_index_prop:
if (IS_CONST != IS_CONST) {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
}
- if ((value = zend_hash_find(ht, Z_STR_P(offset))) != NULL) {
+ if ((value = zend_hash_find_ind(ht, Z_STR_P(offset))) != NULL) {
isset = 1;
}
break;
case IS_NULL:
- if ((value = zend_hash_find(ht, STR_EMPTY_ALLOC())) != NULL) {
+ if ((value = zend_hash_find_ind(ht, STR_EMPTY_ALLOC())) != NULL) {
isset = 1;
}
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto isset_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type in isset or empty");
@@ -25500,17 +25403,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_TMP(int (*
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
-//???: object may become INDIRECT
- if (IS_UNUSED == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
-
if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
make_real_object(object TSRMLS_CC);
-//???
- if (Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
}
if (UNEXPECTED(Z_ISREF_P(object))) {
object = Z_REFVAL_P(object);
@@ -26388,7 +26282,6 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_TMP_HANDLER(ZEND_OPCODE_HAN
offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_UNUSED != IS_VAR || container) {
-//???deref
container_again:
switch (Z_TYPE_P(container)) {
case IS_ARRAY: {
@@ -26541,7 +26434,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_TMP
ht = Z_ARRVAL_P(container);
-again:
+isset_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -26559,18 +26452,18 @@ num_index_prop:
if (IS_TMP_VAR != IS_CONST) {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
}
- if ((value = zend_hash_find(ht, Z_STR_P(offset))) != NULL) {
+ if ((value = zend_hash_find_ind(ht, Z_STR_P(offset))) != NULL) {
isset = 1;
}
break;
case IS_NULL:
- if ((value = zend_hash_find(ht, STR_EMPTY_ALLOC())) != NULL) {
+ if ((value = zend_hash_find_ind(ht, STR_EMPTY_ALLOC())) != NULL) {
isset = 1;
}
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto isset_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type in isset or empty");
@@ -26818,17 +26711,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_VAR(int (*
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
-//???: object may become INDIRECT
- if (IS_UNUSED == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
-
if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
make_real_object(object TSRMLS_CC);
-//???
- if (Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
}
if (UNEXPECTED(Z_ISREF_P(object))) {
object = Z_REFVAL_P(object);
@@ -27706,7 +27590,6 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_VAR_HANDLER(ZEND_OPCODE_HAN
offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_UNUSED != IS_VAR || container) {
-//???deref
container_again:
switch (Z_TYPE_P(container)) {
case IS_ARRAY: {
@@ -27859,7 +27742,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_VAR
ht = Z_ARRVAL_P(container);
-again:
+isset_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -27877,18 +27760,18 @@ num_index_prop:
if (IS_VAR != IS_CONST) {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
}
- if ((value = zend_hash_find(ht, Z_STR_P(offset))) != NULL) {
+ if ((value = zend_hash_find_ind(ht, Z_STR_P(offset))) != NULL) {
isset = 1;
}
break;
case IS_NULL:
- if ((value = zend_hash_find(ht, STR_EMPTY_ALLOC())) != NULL) {
+ if ((value = zend_hash_find_ind(ht, STR_EMPTY_ALLOC())) != NULL) {
isset = 1;
}
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto isset_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type in isset or empty");
@@ -28137,17 +28020,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_UNUSED(int
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
-//???: object may become INDIRECT
- if (IS_UNUSED == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
-
if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
make_real_object(object TSRMLS_CC);
-//???
- if (Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
}
if (UNEXPECTED(Z_ISREF_P(object))) {
object = Z_REFVAL_P(object);
@@ -28552,17 +28426,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_UNUSED_CV(int (*b
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
-//???: object may become INDIRECT
- if (IS_UNUSED == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
-
if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
make_real_object(object TSRMLS_CC);
-//???
- if (Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
}
if (UNEXPECTED(Z_ISREF_P(object))) {
object = Z_REFVAL_P(object);
@@ -29437,7 +29302,6 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HAND
offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_UNUSED != IS_VAR || container) {
-//???deref
container_again:
switch (Z_TYPE_P(container)) {
case IS_ARRAY: {
@@ -29590,7 +29454,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_UNUSED_CV(
ht = Z_ARRVAL_P(container);
-again:
+isset_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -29608,18 +29472,18 @@ num_index_prop:
if (IS_CV != IS_CONST) {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
}
- if ((value = zend_hash_find(ht, Z_STR_P(offset))) != NULL) {
+ if ((value = zend_hash_find_ind(ht, Z_STR_P(offset))) != NULL) {
isset = 1;
}
break;
case IS_NULL:
- if ((value = zend_hash_find(ht, STR_EMPTY_ALLOC())) != NULL) {
+ if ((value = zend_hash_find_ind(ht, STR_EMPTY_ALLOC())) != NULL) {
isset = 1;
}
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto isset_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type in isset or empty");
@@ -30597,7 +30461,7 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
}
}
-again:
+cast_again:
switch (opline->extended_value) {
case IS_NULL:
convert_to_null(result);
@@ -30637,7 +30501,7 @@ again:
break;
case IS_REFERENCE:
result = Z_REFVAL_P(result);
- goto again;
+ goto cast_again;
break;
}
@@ -31377,17 +31241,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CONST(int (*bi
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
-//???: object may become INDIRECT
- if (IS_CV == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
-
if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
make_real_object(object TSRMLS_CC);
-//???
- if (Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
}
if (UNEXPECTED(Z_ISREF_P(object))) {
object = Z_REFVAL_P(object);
@@ -31863,10 +31718,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_CONST(int type, Z
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_CV == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
/*
if (!target_symbol_table) {
CHECK_EXCEPTION();
@@ -31891,6 +31742,29 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_CONST(int type, Z
break;
EMPTY_SWITCH_DEFAULT_CASE()
}
+//??? GLOBAL or $$name variable may be an INDIRECT pointer to CV
+ } else if (/*(opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_STATIC &&*/
+ Z_TYPE_P(retval) == IS_INDIRECT) {
+ retval = Z_INDIRECT_P(retval);
+ if (Z_TYPE_P(retval) == IS_UNDEF) {
+ switch (type) {
+ case BP_VAR_R:
+ case BP_VAR_UNSET:
+ zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
+ /* break missing intentionally */
+ case BP_VAR_IS:
+ retval = EX_VAR(opline->result.var);
+ ZVAL_NULL(retval);
+ break;
+ case BP_VAR_RW:
+ zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
+ /* break missing intentionally */
+ case BP_VAR_W:
+ ZVAL_NULL(retval);
+ break;
+ EMPTY_SWITCH_DEFAULT_CASE()
+ }
+ }
}
switch (opline->extended_value & ZEND_FETCH_TYPE_MASK) {
case ZEND_FETCH_GLOBAL:
@@ -32704,7 +32578,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CONST_HANDLER(ZEND_OPCO
zval *offset = opline->op2.zv;
ulong hval;
-again:
+add_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -32726,7 +32600,7 @@ num_index:
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto add_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type");
@@ -32770,15 +32644,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL
if (IS_CV == IS_CV &&
IS_CONST == IS_UNUSED &&
(opline->extended_value & ZEND_QUICK_SET)) {
- if (EG(active_symbol_table)) {
- zend_string *cv = CV_DEF_OF(opline->op1.var);
-
- zend_delete_variable(EX(prev_execute_data), &EG(active_symbol_table)->ht, cv TSRMLS_CC);
- ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
- } else if (Z_TYPE_P(EX_VAR_NUM(opline->op1.var)) != IS_UNDEF) {
- zval_ptr_dtor(EX_VAR_NUM(opline->op1.var));
- ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
- }
+ zval_ptr_dtor(EX_VAR_NUM(opline->op1.var));
+ ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -32821,11 +32688,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL
zend_std_unset_static_property(ce, Z_STR_P(varname), ((IS_CV == IS_CONST) ? opline->op1.literal : NULL) TSRMLS_CC);
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_CV == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
- zend_delete_variable(execute_data, target_symbol_table, Z_STR_P(varname) TSRMLS_CC);
+ zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
}
if (IS_CV != IS_CONST && varname == &tmp) {
@@ -32854,7 +32717,6 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDL
offset = opline->op2.zv;
if (IS_CV != IS_VAR || container) {
-//???deref
container_again:
switch (Z_TYPE_P(container)) {
case IS_ARRAY: {
@@ -32996,18 +32858,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCO
(opline->extended_value & ZEND_QUICK_SET)) {
if (Z_TYPE_P(EX_VAR_NUM(opline->op1.var)) != IS_UNDEF) {
value = EX_VAR_NUM(opline->op1.var);
- if (Z_TYPE_P(value) == IS_INDIRECT) {
- value = Z_INDIRECT_P(value);
- }
if (Z_TYPE_P(value) == IS_REFERENCE) {
value = Z_REFVAL_P(value);
}
- } else if (EG(active_symbol_table)) {
- zend_string *cv = CV_DEF_OF(opline->op1.var);
-
- if ((value = zend_hash_find(&EG(active_symbol_table)->ht, cv)) == NULL) {
- isset = 0;
- }
} else {
isset = 0;
}
@@ -33045,10 +32898,6 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_CONST_HANDLER(ZEND_OPCO
}
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_CV == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
if ((value = zend_hash_find(target_symbol_table, Z_STR_P(varname))) == NULL) {
isset = 0;
}
@@ -33101,7 +32950,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CONST(i
ht = Z_ARRVAL_P(container);
-again:
+isset_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -33119,18 +32968,18 @@ num_index_prop:
if (IS_CONST != IS_CONST) {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
}
- if ((value = zend_hash_find(ht, Z_STR_P(offset))) != NULL) {
+ if ((value = zend_hash_find_ind(ht, Z_STR_P(offset))) != NULL) {
isset = 1;
}
break;
case IS_NULL:
- if ((value = zend_hash_find(ht, STR_EMPTY_ALLOC())) != NULL) {
+ if ((value = zend_hash_find_ind(ht, STR_EMPTY_ALLOC())) != NULL) {
isset = 1;
}
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto isset_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type in isset or empty");
@@ -33654,17 +33503,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_TMP(int (*bina
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
-//???: object may become INDIRECT
- if (IS_CV == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
-
if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
make_real_object(object TSRMLS_CC);
-//???
- if (Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
}
if (UNEXPECTED(Z_ISREF_P(object))) {
object = Z_REFVAL_P(object);
@@ -34825,7 +34665,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_TMP_HANDLER(ZEND_OPCODE
zval *offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
ulong hval;
-again:
+add_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -34847,7 +34687,7 @@ num_index:
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto add_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type");
@@ -34896,7 +34736,6 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER
offset = _get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_CV != IS_VAR || container) {
-//???deref
container_again:
switch (Z_TYPE_P(container)) {
case IS_ARRAY: {
@@ -35049,7 +34888,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_TMP(int
ht = Z_ARRVAL_P(container);
-again:
+isset_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -35067,18 +34906,18 @@ num_index_prop:
if (IS_TMP_VAR != IS_CONST) {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
}
- if ((value = zend_hash_find(ht, Z_STR_P(offset))) != NULL) {
+ if ((value = zend_hash_find_ind(ht, Z_STR_P(offset))) != NULL) {
isset = 1;
}
break;
case IS_NULL:
- if ((value = zend_hash_find(ht, STR_EMPTY_ALLOC())) != NULL) {
+ if ((value = zend_hash_find_ind(ht, STR_EMPTY_ALLOC())) != NULL) {
isset = 1;
}
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto isset_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type in isset or empty");
@@ -35602,17 +35441,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_VAR(int (*bina
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
-//???: object may become INDIRECT
- if (IS_CV == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
-
if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
make_real_object(object TSRMLS_CC);
-//???
- if (Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
}
if (UNEXPECTED(Z_ISREF_P(object))) {
object = Z_REFVAL_P(object);
@@ -36089,10 +35919,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_VAR(int type, ZEN
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_CV == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
/*
if (!target_symbol_table) {
CHECK_EXCEPTION();
@@ -36117,6 +35943,29 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_VAR(int type, ZEN
break;
EMPTY_SWITCH_DEFAULT_CASE()
}
+//??? GLOBAL or $$name variable may be an INDIRECT pointer to CV
+ } else if (/*(opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_STATIC &&*/
+ Z_TYPE_P(retval) == IS_INDIRECT) {
+ retval = Z_INDIRECT_P(retval);
+ if (Z_TYPE_P(retval) == IS_UNDEF) {
+ switch (type) {
+ case BP_VAR_R:
+ case BP_VAR_UNSET:
+ zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
+ /* break missing intentionally */
+ case BP_VAR_IS:
+ retval = EX_VAR(opline->result.var);
+ ZVAL_NULL(retval);
+ break;
+ case BP_VAR_RW:
+ zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
+ /* break missing intentionally */
+ case BP_VAR_W:
+ ZVAL_NULL(retval);
+ break;
+ EMPTY_SWITCH_DEFAULT_CASE()
+ }
+ }
}
switch (opline->extended_value & ZEND_FETCH_TYPE_MASK) {
case ZEND_FETCH_GLOBAL:
@@ -36992,7 +36841,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_VAR_HANDLER(ZEND_OPCODE
zval *offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
ulong hval;
-again:
+add_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -37014,7 +36863,7 @@ num_index:
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto add_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type");
@@ -37058,15 +36907,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER
if (IS_CV == IS_CV &&
IS_VAR == IS_UNUSED &&
(opline->extended_value & ZEND_QUICK_SET)) {
- if (EG(active_symbol_table)) {
- zend_string *cv = CV_DEF_OF(opline->op1.var);
-
- zend_delete_variable(EX(prev_execute_data), &EG(active_symbol_table)->ht, cv TSRMLS_CC);
- ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
- } else if (Z_TYPE_P(EX_VAR_NUM(opline->op1.var)) != IS_UNDEF) {
- zval_ptr_dtor(EX_VAR_NUM(opline->op1.var));
- ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
- }
+ zval_ptr_dtor(EX_VAR_NUM(opline->op1.var));
+ ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -37109,11 +36951,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER
zend_std_unset_static_property(ce, Z_STR_P(varname), ((IS_CV == IS_CONST) ? opline->op1.literal : NULL) TSRMLS_CC);
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_CV == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
- zend_delete_variable(execute_data, target_symbol_table, Z_STR_P(varname) TSRMLS_CC);
+ zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
}
if (IS_CV != IS_CONST && varname == &tmp) {
@@ -37142,7 +36980,6 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_HANDLER
offset = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2 TSRMLS_CC);
if (IS_CV != IS_VAR || container) {
-//???deref
container_again:
switch (Z_TYPE_P(container)) {
case IS_ARRAY: {
@@ -37284,18 +37121,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE
(opline->extended_value & ZEND_QUICK_SET)) {
if (Z_TYPE_P(EX_VAR_NUM(opline->op1.var)) != IS_UNDEF) {
value = EX_VAR_NUM(opline->op1.var);
- if (Z_TYPE_P(value) == IS_INDIRECT) {
- value = Z_INDIRECT_P(value);
- }
if (Z_TYPE_P(value) == IS_REFERENCE) {
value = Z_REFVAL_P(value);
}
- } else if (EG(active_symbol_table)) {
- zend_string *cv = CV_DEF_OF(opline->op1.var);
-
- if ((value = zend_hash_find(&EG(active_symbol_table)->ht, cv)) == NULL) {
- isset = 0;
- }
} else {
isset = 0;
}
@@ -37333,10 +37161,6 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_VAR_HANDLER(ZEND_OPCODE
}
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_CV == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
if ((value = zend_hash_find(target_symbol_table, Z_STR_P(varname))) == NULL) {
isset = 0;
}
@@ -37389,7 +37213,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_VAR(int
ht = Z_ARRVAL_P(container);
-again:
+isset_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -37407,18 +37231,18 @@ num_index_prop:
if (IS_VAR != IS_CONST) {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
}
- if ((value = zend_hash_find(ht, Z_STR_P(offset))) != NULL) {
+ if ((value = zend_hash_find_ind(ht, Z_STR_P(offset))) != NULL) {
isset = 1;
}
break;
case IS_NULL:
- if ((value = zend_hash_find(ht, STR_EMPTY_ALLOC())) != NULL) {
+ if ((value = zend_hash_find_ind(ht, STR_EMPTY_ALLOC())) != NULL) {
isset = 1;
}
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto isset_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type in isset or empty");
@@ -37667,17 +37491,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_UNUSED(int (*b
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
-//???: object may become INDIRECT
- if (IS_CV == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
-
if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
make_real_object(object TSRMLS_CC);
-//???
- if (Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
}
if (UNEXPECTED(Z_ISREF_P(object))) {
object = Z_REFVAL_P(object);
@@ -37959,10 +37774,6 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_UNUSED(int type,
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_CV == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
/*
if (!target_symbol_table) {
CHECK_EXCEPTION();
@@ -37987,6 +37798,29 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_CV_UNUSED(int type,
break;
EMPTY_SWITCH_DEFAULT_CASE()
}
+//??? GLOBAL or $$name variable may be an INDIRECT pointer to CV
+ } else if (/*(opline->extended_value & ZEND_FETCH_TYPE_MASK) != ZEND_FETCH_STATIC &&*/
+ Z_TYPE_P(retval) == IS_INDIRECT) {
+ retval = Z_INDIRECT_P(retval);
+ if (Z_TYPE_P(retval) == IS_UNDEF) {
+ switch (type) {
+ case BP_VAR_R:
+ case BP_VAR_UNSET:
+ zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
+ /* break missing intentionally */
+ case BP_VAR_IS:
+ retval = EX_VAR(opline->result.var);
+ ZVAL_NULL(retval);
+ break;
+ case BP_VAR_RW:
+ zend_error(E_NOTICE,"Undefined variable: %s", Z_STRVAL_P(varname));
+ /* break missing intentionally */
+ case BP_VAR_W:
+ ZVAL_NULL(retval);
+ break;
+ EMPTY_SWITCH_DEFAULT_CASE()
+ }
+ }
}
switch (opline->extended_value & ZEND_FETCH_TYPE_MASK) {
case ZEND_FETCH_GLOBAL:
@@ -38297,7 +38131,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_UNUSED_HANDLER(ZEND_OPC
zval *offset = NULL;
ulong hval;
-again:
+add_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -38319,7 +38153,7 @@ num_index:
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto add_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type");
@@ -38363,15 +38197,8 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAND
if (IS_CV == IS_CV &&
IS_UNUSED == IS_UNUSED &&
(opline->extended_value & ZEND_QUICK_SET)) {
- if (EG(active_symbol_table)) {
- zend_string *cv = CV_DEF_OF(opline->op1.var);
-
- zend_delete_variable(EX(prev_execute_data), &EG(active_symbol_table)->ht, cv TSRMLS_CC);
- ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
- } else if (Z_TYPE_P(EX_VAR_NUM(opline->op1.var)) != IS_UNDEF) {
- zval_ptr_dtor(EX_VAR_NUM(opline->op1.var));
- ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
- }
+ zval_ptr_dtor(EX_VAR_NUM(opline->op1.var));
+ ZVAL_UNDEF(EX_VAR_NUM(opline->op1.var));
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
@@ -38414,11 +38241,7 @@ static int ZEND_FASTCALL ZEND_UNSET_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPCODE_HAND
zend_std_unset_static_property(ce, Z_STR_P(varname), ((IS_CV == IS_CONST) ? opline->op1.literal : NULL) TSRMLS_CC);
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_CV == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
- zend_delete_variable(execute_data, target_symbol_table, Z_STR_P(varname) TSRMLS_CC);
+ zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
}
if (IS_CV != IS_CONST && varname == &tmp) {
@@ -38443,18 +38266,9 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPC
(opline->extended_value & ZEND_QUICK_SET)) {
if (Z_TYPE_P(EX_VAR_NUM(opline->op1.var)) != IS_UNDEF) {
value = EX_VAR_NUM(opline->op1.var);
- if (Z_TYPE_P(value) == IS_INDIRECT) {
- value = Z_INDIRECT_P(value);
- }
if (Z_TYPE_P(value) == IS_REFERENCE) {
value = Z_REFVAL_P(value);
}
- } else if (EG(active_symbol_table)) {
- zend_string *cv = CV_DEF_OF(opline->op1.var);
-
- if ((value = zend_hash_find(&EG(active_symbol_table)->ht, cv)) == NULL) {
- isset = 0;
- }
} else {
isset = 0;
}
@@ -38492,10 +38306,6 @@ static int ZEND_FASTCALL ZEND_ISSET_ISEMPTY_VAR_SPEC_CV_UNUSED_HANDLER(ZEND_OPC
}
} else {
target_symbol_table = zend_get_target_symbol_table(opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
-//???: STRING may become INDIRECT
- if (IS_CV == IS_CV && Z_TYPE_P(varname) == IS_INDIRECT) {
- varname = Z_INDIRECT_P(varname);
- }
if ((value = zend_hash_find(target_symbol_table, Z_STR_P(varname))) == NULL) {
isset = 0;
}
@@ -38953,17 +38763,8 @@ static int ZEND_FASTCALL zend_binary_assign_op_obj_helper_SPEC_CV_CV(int (*binar
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
}
-//???: object may become INDIRECT
- if (IS_CV == IS_CV && Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
-
if (UNEXPECTED(Z_TYPE_P(object) != IS_OBJECT)) {
make_real_object(object TSRMLS_CC);
-//???
- if (Z_TYPE_P(object) == IS_INDIRECT) {
- object = Z_INDIRECT_P(object);
- }
}
if (UNEXPECTED(Z_ISREF_P(object))) {
object = Z_REFVAL_P(object);
@@ -40177,7 +39978,7 @@ static int ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_CV_CV_HANDLER(ZEND_OPCODE_
zval *offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
ulong hval;
-again:
+add_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -40199,7 +40000,7 @@ num_index:
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto add_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type");
@@ -40248,7 +40049,6 @@ static int ZEND_FASTCALL ZEND_UNSET_DIM_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_
offset = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var TSRMLS_CC);
if (IS_CV != IS_VAR || container) {
-//???deref
container_again:
switch (Z_TYPE_P(container)) {
case IS_ARRAY: {
@@ -40401,7 +40201,7 @@ static int ZEND_FASTCALL zend_isset_isempty_dim_prop_obj_handler_SPEC_CV_CV(int
ht = Z_ARRVAL_P(container);
-again:
+isset_again:
switch (Z_TYPE_P(offset)) {
case IS_DOUBLE:
hval = zend_dval_to_lval(Z_DVAL_P(offset));
@@ -40419,18 +40219,18 @@ num_index_prop:
if (IS_CV != IS_CONST) {
ZEND_HANDLE_NUMERIC_EX(Z_STRVAL_P(offset), Z_STRLEN_P(offset)+1, hval, goto num_index_prop);
}
- if ((value = zend_hash_find(ht, Z_STR_P(offset))) != NULL) {
+ if ((value = zend_hash_find_ind(ht, Z_STR_P(offset))) != NULL) {
isset = 1;
}
break;
case IS_NULL:
- if ((value = zend_hash_find(ht, STR_EMPTY_ALLOC())) != NULL) {
+ if ((value = zend_hash_find_ind(ht, STR_EMPTY_ALLOC())) != NULL) {
isset = 1;
}
break;
case IS_REFERENCE:
offset = Z_REFVAL_P(offset);
- goto again;
+ goto isset_again;
break;
default:
zend_error(E_WARNING, "Illegal offset type in isset or empty");
diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c
index 148dae4378..53101b4623 100644
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@ -223,14 +223,23 @@ static inline reflection_object *reflection_object_from_obj(zend_object *obj) /*
static zend_object_handlers reflection_object_handlers;
+static zval *_default_load_entry(zval *object, char *name, int name_len TSRMLS_DC) /* {{{ */
+{
+ zval *value;
+
+ if ((value = zend_hash_str_find_ind(Z_OBJPROP_P(object), name, name_len)) == NULL) {
+ return NULL;
+ }
+ return value;
+}
+
static void _default_get_entry(zval *object, char *name, int name_len, zval *return_value TSRMLS_DC) /* {{{ */
{
zval *value;
- if ((value = zend_hash_str_find(Z_OBJPROP_P(object), name, name_len)) == NULL) {
+ if ((value = _default_load_entry(object, name, name_len TSRMLS_CC)) == NULL) {
RETURN_FALSE;
}
-
ZVAL_DUP(return_value, value);
}
/* }}} */
@@ -3102,7 +3111,7 @@ ZEND_METHOD(reflection_function, inNamespace)
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- if ((name = zend_hash_str_find(Z_OBJPROP_P(getThis()), "name", sizeof("name")-1)) == NULL) {
+ if ((name = _default_load_entry(getThis(), "name", sizeof("name")-1) TSRMLS_CC) == NULL) {
RETURN_FALSE;
}
if (Z_TYPE_P(name) == IS_STRING
@@ -3125,7 +3134,7 @@ ZEND_METHOD(reflection_function, getNamespaceName)
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- if ((name = zend_hash_str_find(Z_OBJPROP_P(getThis()), "name", sizeof("name")-1)) == NULL) {
+ if ((name = _default_load_entry(getThis(), "name", sizeof("name")-1) TSRMLS_CC) == NULL) {
RETURN_FALSE;
}
if (Z_TYPE_P(name) == IS_STRING
@@ -3148,7 +3157,7 @@ ZEND_METHOD(reflection_function, getShortName)
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- if ((name = zend_hash_str_find(Z_OBJPROP_P(getThis()), "name", sizeof("name")-1)) == NULL) {
+ if ((name = _default_load_entry(getThis(), "name", sizeof("name")-1) TSRMLS_CC) == NULL) {
RETURN_FALSE;
}
if (Z_TYPE_P(name) == IS_STRING
@@ -4654,7 +4663,7 @@ ZEND_METHOD(reflection_class, inNamespace)
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- if ((name = zend_hash_str_find(Z_OBJPROP_P(getThis()), "name", sizeof("name")-1)) == NULL) {
+ if ((name = _default_load_entry(getThis(), "name", sizeof("name")-1) TSRMLS_CC) == NULL) {
RETURN_FALSE;
}
if (Z_TYPE_P(name) == IS_STRING
@@ -4677,7 +4686,7 @@ ZEND_METHOD(reflection_class, getNamespaceName)
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- if ((name = zend_hash_str_find(Z_OBJPROP_P(getThis()), "name", sizeof("name")-1)) == NULL) {
+ if ((name = _default_load_entry(getThis(), "name", sizeof("name")-1) TSRMLS_CC) == NULL) {
RETURN_FALSE;
}
if (Z_TYPE_P(name) == IS_STRING
@@ -4700,7 +4709,7 @@ ZEND_METHOD(reflection_class, getShortName)
if (zend_parse_parameters_none() == FAILURE) {
return;
}
- if ((name = zend_hash_str_find(Z_OBJPROP_P(getThis()), "name", sizeof("name")-1)) == NULL) {
+ if ((name = _default_load_entry(getThis(), "name", sizeof("name")-1) TSRMLS_CC) == NULL) {
RETURN_FALSE;
}
if (Z_TYPE_P(name) == IS_STRING
@@ -4937,17 +4946,16 @@ ZEND_METHOD(reflection_property, getValue)
{
reflection_object *intern;
property_reference *ref;
- zval *object, name;
+ zval *object, *name;
zval *member_p = NULL;
METHOD_NOTSTATIC(reflection_property_ptr);
GET_REFLECTION_OBJECT_PTR(ref);
if (!(ref->prop.flags & (ZEND_ACC_PUBLIC | ZEND_ACC_IMPLICIT_PUBLIC)) && intern->ignore_visibility == 0) {
- _default_get_entry(getThis(), "name", sizeof("name")-1, &name TSRMLS_CC);
+ name = _default_load_entry(getThis(), "name", sizeof("name")-1 TSRMLS_CC);
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
- "Cannot access non-public member %s::%s", intern->ce->name->val, Z_STRVAL(name));
- zval_dtor(&name);
+ "Cannot access non-public member %s::%s", intern->ce->name->val, Z_STRVAL_P(name));
return;
}
@@ -4984,7 +4992,7 @@ ZEND_METHOD(reflection_property, setValue)
reflection_object *intern;
property_reference *ref;
zval *variable_ptr;
- zval *object, name;
+ zval *object, *name;
zval *value;
zval *tmp;
@@ -4992,10 +5000,9 @@ ZEND_METHOD(reflection_property, setValue)
GET_REFLECTION_OBJECT_PTR(ref);
if (!(ref->prop.flags & ZEND_ACC_PUBLIC) && intern->ignore_visibility == 0) {
- _default_get_entry(getThis(), "name", sizeof("name")-1, &name TSRMLS_CC);
+ name = _default_load_entry(getThis(), "name", sizeof("name")-1 TSRMLS_CC);
zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC,
- "Cannot access non-public member %s::%s", intern->ce->name->val, Z_STRVAL(name));
- zval_dtor(&name);
+ "Cannot access non-public member %s::%s", intern->ce->name->val, Z_STRVAL_P(name));
return;
}
diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c
index c6634ecf8a..47f5fa2402 100644
--- a/ext/spl/spl_array.c
+++ b/ext/spl/spl_array.c
@@ -324,7 +324,27 @@ static zval *spl_array_get_dimension_ptr(int check_inherited, zval *object, zval
case IS_STRING:
offset_key = Z_STR_P(offset);
fetch_dim_string:
- if ((retval = (zend_symtable_find(ht, offset_key))) == NULL) {
+ retval = zend_symtable_find(ht, offset_key);
+ if (retval) {
+ if (Z_TYPE_P(retval) == IS_INDIRECT) {
+ retval = Z_INDIRECT_P(retval);
+ if (Z_TYPE_P(retval) == IS_UNDEF) {
+ switch (type) {
+ case BP_VAR_R:
+ zend_error(E_NOTICE, "Undefined index: %s", offset_key->val);
+ case BP_VAR_UNSET:
+ case BP_VAR_IS:
+ retval = &EG(uninitialized_zval);
+ break;
+ case BP_VAR_RW:
+ zend_error(E_NOTICE,"Undefined index: %s", offset_key->val);
+ case BP_VAR_W: {
+ ZVAL_NULL(retval);
+ }
+ }
+ }
+ }
+ } else {
switch (type) {
case BP_VAR_R:
zend_error(E_NOTICE, "Undefined index: %s", offset_key->val);
@@ -430,6 +450,7 @@ static void spl_array_write_dimension_ex(int check_inherited, zval *object, zval
if (check_inherited && intern->fptr_offset_set) {
zval tmp;
+
if (!offset) {
ZVAL_NULL(&tmp);
offset = &tmp;
@@ -464,7 +485,7 @@ static void spl_array_write_dimension_ex(int check_inherited, zval *object, zval
zend_error(E_WARNING, "Modification of ArrayObject during sorting is prohibited");
return;
}
- zend_symtable_update(ht, Z_STR_P(offset), value);
+ zend_symtable_update_ind(ht, Z_STR_P(offset), value);
return;
case IS_DOUBLE:
case IS_RESOURCE:
@@ -526,36 +547,29 @@ static void spl_array_unset_dimension_ex(int check_inherited, zval *object, zval
zend_error(E_NOTICE,"Undefined index: %s", Z_STRVAL_P(offset));
}
} else {
- if (zend_symtable_del(ht, Z_STR_P(offset)) == FAILURE) {
- zend_error(E_NOTICE,"Undefined index: %s", Z_STRVAL_P(offset));
- } else {
- spl_array_object *obj = intern;
-
- while (1) {
- if ((obj->ar_flags & SPL_ARRAY_IS_SELF) != 0) {
- break;
- } else if (Z_TYPE(obj->array) == IS_OBJECT) {
- if ((obj->ar_flags & SPL_ARRAY_USE_OTHER) == 0) {
- obj = Z_SPLARRAY_P(&obj->array);
- break;
- } else {
- obj = Z_SPLARRAY_P(&obj->array);
- }
+//??? see below
+#if 0
+ if (zend_symtable_del_ind(ht, Z_STR_P(offset)) == FAILURE) {
+#else
+ zval *data = zend_symtable_find(ht, Z_STR_P(offset));
+
+ if (data) {
+ if (Z_TYPE_P(data) == IS_INDIRECT) {
+ data = Z_INDIRECT_P(data);
+ if (Z_TYPE_P(data) == IS_UNDEF) {
+ zend_error(E_NOTICE,"Undefined index: %s", Z_STRVAL_P(offset));
} else {
- obj = NULL;
- break;
- }
- }
- if (obj) {
- zend_property_info *property_info = zend_get_property_info(obj->std.ce, offset, 1 TSRMLS_CC);
-
- if (property_info &&
- (property_info->flags & ZEND_ACC_STATIC) == 0 &&
- property_info->offset >= 0) {
- zval_ptr_dtor(&obj->std.properties_table[property_info->offset]);
- ZVAL_UNDEF(&obj->std.properties_table[property_info->offset]);
+ zval_ptr_dtor(data);
+ ZVAL_UNDEF(data);
}
+//??? fix for ext/spl/tests/bug45614.phpt (may be fix is wrong)
+ spl_array_rewind(intern TSRMLS_CC);
+ } else if (zend_symtable_del(ht, Z_STR_P(offset)) == FAILURE) {
+ zend_error(E_NOTICE,"Undefined index: %s", Z_STRVAL_P(offset));
}
+ } else {
+#endif
+ zend_error(E_NOTICE,"Undefined index: %s", Z_STRVAL_P(offset));
}
}
break;
@@ -610,7 +624,7 @@ static int spl_array_has_dimension_ex(int check_inherited, zval *object, zval *o
case IS_STRING:
{
HashTable *ht = spl_array_get_hash_table(intern, 0 TSRMLS_CC);
- if ((tmp = zend_symtable_find(ht, Z_STR_P(offset))) != NULL) {
+ if ((tmp = zend_symtable_find_ind(ht, Z_STR_P(offset))) != NULL) {
switch (check_empty) {
case 0:
return Z_TYPE_P(tmp) != IS_NULL;
@@ -919,11 +933,16 @@ static int spl_array_skip_protected(spl_array_object *intern, HashTable *aht TSR
{
zend_string *string_key;
ulong num_key;
+ zval *data;
if (Z_TYPE(intern->array) == IS_OBJECT) {
do {
if (zend_hash_get_current_key_ex(aht, &string_key, &num_key, 0, &intern->pos) == HASH_KEY_IS_STRING) {
- if (!string_key->len || string_key->val[0]) {
+ data = zend_hash_get_current_data_ex(aht, &intern->pos);
+ if (data && Z_TYPE_P(data) == IS_INDIRECT &&
+ Z_TYPE_P(data = Z_INDIRECT_P(data)) == IS_UNDEF) {
+ /* skip */
+ } else if (!string_key->len || string_key->val[0]) {
return SUCCESS;
}
} else {
@@ -1002,7 +1021,11 @@ static zval *spl_array_it_get_current_data(zend_object_iterator *iter TSRMLS_DC)
if (object->ar_flags & SPL_ARRAY_OVERLOADED_CURRENT) {
return zend_user_it_get_current_data(iter TSRMLS_CC);
} else {
- return zend_hash_get_current_data_ex(aht, &object->pos);
+ zval *data = zend_hash_get_current_data_ex(aht, &object->pos);
+ if (Z_TYPE_P(data) == IS_INDIRECT) {
+ data = Z_INDIRECT_P(data);
+ }
+ return data;
}
}
/* }}} */
@@ -1096,14 +1119,14 @@ static void spl_array_set_array(zval *object, spl_array_object *intern, zval *ar
ar_flags = other->ar_flags & ~SPL_ARRAY_INT_MASK;
}
ar_flags |= SPL_ARRAY_USE_OTHER;
- intern->array = *array;
+ ZVAL_COPY_VALUE(&intern->array, array);
} else {
if (Z_TYPE_P(array) != IS_OBJECT && Z_TYPE_P(array) != IS_ARRAY) {
zend_throw_exception(spl_ce_InvalidArgumentException, "Passed variable is not an array or object, using empty array instead", 0 TSRMLS_CC);
return;
}
zval_ptr_dtor(&intern->array);
- intern->array = *array;
+ ZVAL_COPY_VALUE(&intern->array, array);
}
if (Z_TYPE_P(array) == IS_OBJECT && Z_OBJ_P(object) == Z_OBJ_P(array)) {
intern->ar_flags |= SPL_ARRAY_IS_SELF;
@@ -1507,6 +1530,12 @@ SPL_METHOD(Array, current)
if ((entry = zend_hash_get_current_data_ex(aht, &intern->pos)) == NULL) {
return;
}
+ if (Z_TYPE_P(entry) == IS_INDIRECT) {
+ entry = Z_INDIRECT_P(entry);
+ if (Z_TYPE_P(entry) == IS_UNDEF) {
+ return;
+ }
+ }
RETVAL_ZVAL(entry, 1, 0);
}
/* }}} */
@@ -1765,10 +1794,7 @@ SPL_METHOD(Array, unserialize)
}
/* copy members */
- if (!intern->std.properties) {
- rebuild_object_properties(&intern->std);
- }
- zend_hash_copy(intern->std.properties, Z_ARRVAL(members), (copy_ctor_func_t) zval_add_ref);
+ object_properties_load(&intern->std, Z_ARRVAL(members));
zval_ptr_dtor(&members);
/* done reading $serialized */
diff --git a/ext/standard/array.c b/ext/standard/array.c
index 84c5f87a43..e2a2f02332 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -370,6 +370,12 @@ static int php_array_data_compare(const void *a, const void *b TSRMLS_DC) /* {{{
first = &f->val;
second = &s->val;
+ if (Z_TYPE_P(first) == IS_INDIRECT) {
+ first = Z_INDIRECT_P(first);
+ }
+ if (Z_TYPE_P(second) == IS_INDIRECT) {
+ second = Z_INDIRECT_P(second);
+ }
if (ARRAYG(compare_func)(&result, first, second TSRMLS_CC) == FAILURE) {
return 0;
}
@@ -1056,6 +1062,13 @@ static int php_array_walk(HashTable *target_hash, zval *userdata, int recursive
/* Iterate through hash */
zend_hash_internal_pointer_reset(target_hash);
while (!EG(exception) && (zv = zend_hash_get_current_data(target_hash)) != NULL) {
+ if (Z_TYPE_P(zv) == IS_INDIRECT) {
+ zv = Z_INDIRECT_P(zv);
+ if (Z_TYPE_P(zv) == IS_UNDEF) {
+ zend_hash_move_forward(target_hash);
+ continue;
+ }
+ }
ZVAL_COPY(&args[0], zv);
if (recursive &&
(Z_TYPE(args[0]) == IS_ARRAY ||
@@ -1332,6 +1345,14 @@ PHP_FUNCTION(extract)
while ((entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(var_array), &pos)) != NULL) {
zval final_name;
+ if (Z_TYPE_P(entry) == IS_INDIRECT) {
+ entry = Z_INDIRECT_P(entry);
+ if (Z_TYPE_P(entry) == IS_UNDEF) {
+ zend_hash_move_forward_ex(Z_ARRVAL_P(var_array), &pos);
+ continue;
+ }
+ }
+
ZVAL_NULL(&final_name);
key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(var_array), &var_name, &num_key, 0, &pos);
@@ -1410,6 +1431,9 @@ PHP_FUNCTION(extract)
Z_ADDREF_P(entry);
if ((orig_var = zend_hash_find(&EG(active_symbol_table)->ht, Z_STR(final_name))) != NULL) {
+ if (Z_TYPE_P(orig_var) == IS_INDIRECT) {
+ orig_var = Z_INDIRECT_P(orig_var);
+ }
zval_ptr_dtor(orig_var);
ZVAL_COPY_VALUE(orig_var, entry);
} else {
@@ -1417,7 +1441,7 @@ PHP_FUNCTION(extract)
}
} else {
ZVAL_DUP(&data, entry);
- ZEND_SET_SYMBOL_WITH_LENGTH(&EG(active_symbol_table)->ht, Z_STRVAL(final_name), Z_STRLEN(final_name), &data, 1, 0);
+ zend_set_local_var(Z_STRVAL(final_name), Z_STRLEN(final_name), &data, 1 TSRMLS_CC);
}
count++;
}
@@ -1442,12 +1466,11 @@ static void php_compact_var(HashTable *eg_active_symbol_table, zval *return_valu
entry = Z_REFVAL_P(entry);
}
if (Z_TYPE_P(entry) == IS_STRING) {
- if ((value_ptr = zend_hash_find(eg_active_symbol_table, Z_STR_P(entry))) != NULL) {
+ if ((value_ptr = zend_hash_find_ind(eg_active_symbol_table, Z_STR_P(entry))) != NULL) {
ZVAL_DUP(&data, value_ptr);
zend_hash_update(Z_ARRVAL_P(return_value), Z_STR_P(entry), &data);
}
- }
- else if (Z_TYPE_P(entry) == IS_ARRAY) {
+ } else if (Z_TYPE_P(entry) == IS_ARRAY) {
HashPosition pos;
if ((Z_ARRVAL_P(entry)->nApplyCount > 1)) {
@@ -1459,6 +1482,13 @@ static void php_compact_var(HashTable *eg_active_symbol_table, zval *return_valu
zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(entry), &pos);
while ((value_ptr = zend_hash_get_current_data_ex(Z_ARRVAL_P(entry), &pos)) != NULL) {
+ if (Z_TYPE_P(value_ptr) == IS_INDIRECT) {
+ value_ptr = Z_INDIRECT_P(value_ptr);
+ if (Z_TYPE_P(value_ptr) == IS_UNDEF) {
+ zend_hash_move_forward_ex(Z_ARRVAL_P(entry), &pos);
+ continue;
+ }
+ }
php_compact_var(eg_active_symbol_table, return_value, value_ptr TSRMLS_CC);
zend_hash_move_forward_ex(Z_ARRVAL_P(entry), &pos);
}
@@ -1963,7 +1993,19 @@ static void _phpi_pop(INTERNAL_FUNCTION_PARAMETERS, int off_the_end)
} else {
zend_hash_internal_pointer_reset(Z_ARRVAL_P(stack));
}
- val = zend_hash_get_current_data(Z_ARRVAL_P(stack));
+ while (1) {
+ val = zend_hash_get_current_data(Z_ARRVAL_P(stack));
+ if (!val) {
+ return;
+ } else if (Z_TYPE_P(val) == IS_INDIRECT) {
+ val = Z_INDIRECT_P(val);
+ if (Z_TYPE_P(val) == IS_UNDEF) {
+ zend_hash_move_forward(Z_ARRVAL_P(stack));
+ continue;
+ }
+ }
+ break;
+ }
RETVAL_ZVAL_FAST(val);
/* Delete the first or last value */
@@ -2045,9 +2087,6 @@ PHP_FUNCTION(array_unshift)
* hashtable and replace it with new one */
new_hash = php_splice(Z_ARRVAL_P(stack), 0, 0, &args[0], argc, NULL);
old_hash = *Z_ARRVAL_P(stack);
- if (Z_ARRVAL_P(stack) == &EG(symbol_table).ht) {
- zend_reset_all_cv(&EG(symbol_table) TSRMLS_CC);
- }
*Z_ARRVAL_P(stack) = *new_hash;
FREE_HASHTABLE(new_hash);
zend_hash_destroy(&old_hash);
@@ -2128,9 +2167,6 @@ PHP_FUNCTION(array_splice)
/* Replace input array's hashtable with the new one */
old_hash = *Z_ARRVAL_P(array);
- if (Z_ARRVAL_P(array) == &EG(symbol_table).ht) {
- zend_reset_all_cv(&EG(symbol_table) TSRMLS_CC);
- }
*Z_ARRVAL_P(array) = *new_hash;
FREE_HASHTABLE(new_hash);
zend_hash_destroy(&old_hash);
@@ -2789,9 +2825,6 @@ PHP_FUNCTION(array_pad)
/* Copy the result hash into return value */
old_hash = *Z_ARRVAL_P(return_value);
- if (Z_ARRVAL_P(return_value) == &EG(symbol_table).ht) {
- zend_reset_all_cv(&EG(symbol_table) TSRMLS_CC);
- }
*Z_ARRVAL_P(return_value) = *new_hash;
FREE_HASHTABLE(new_hash);
zend_hash_destroy(&old_hash);
@@ -2911,6 +2944,7 @@ PHP_FUNCTION(array_unique)
for (i = 0, idx = 0; idx < Z_ARRVAL_P(array)->nNumUsed; idx++) {
p = Z_ARRVAL_P(array)->arData + idx;
if (Z_TYPE(p->val) == IS_UNDEF) continue;
+ if (Z_TYPE(p->val) == IS_INDIRECT && Z_TYPE_P(Z_INDIRECT(p->val)) == IS_UNDEF) continue;
arTmp[i].b = *p;
arTmp[i].i = i;
i++;
@@ -2954,6 +2988,12 @@ static int zval_compare(zval *a, zval *b TSRMLS_DC) /* {{{ */
first = a;
second = b;
+ if (Z_TYPE_P(first) == IS_INDIRECT) {
+ first = Z_INDIRECT_P(first);
+ }
+ if (Z_TYPE_P(second) == IS_INDIRECT) {
+ second = Z_INDIRECT_P(second);
+ }
if (string_compare_function(&result, first, second TSRMLS_CC) == FAILURE) {
return 0;
}
@@ -2985,6 +3025,13 @@ static int zval_user_compare(zval *a, zval *b TSRMLS_DC) /* {{{ */
zval args[2];
zval retval;
+ if (Z_TYPE_P(a) == IS_INDIRECT) {
+ a = Z_INDIRECT_P(a);
+ }
+ if (Z_TYPE_P(b) == IS_INDIRECT) {
+ b = Z_INDIRECT_P(b);
+ }
+
ZVAL_COPY_VALUE(&args[0], a);
ZVAL_COPY_VALUE(&args[1], b);
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c
index d666c025bb..2018c90b92 100644
--- a/ext/standard/basic_functions.c
+++ b/ext/standard/basic_functions.c
@@ -4265,13 +4265,16 @@ PHP_FUNCTION(getopt)
* in order to be on the safe side, even though it is also available
* from the symbol table. */
if (Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) != IS_UNDEF &&
- ((args = zend_hash_str_find(HASH_OF(&PG(http_globals)[TRACK_VARS_SERVER]), "argv", sizeof("argv")-1)) != NULL ||
- (args = zend_hash_str_find(&EG(symbol_table).ht, "argv", sizeof("argv")-1)) != NULL) && Z_TYPE_P(args) == IS_ARRAY
+ ((args = zend_hash_str_find_ind(HASH_OF(&PG(http_globals)[TRACK_VARS_SERVER]), "argv", sizeof("argv")-1)) != NULL ||
+ (args = zend_hash_str_find_ind(&EG(symbol_table).ht, "argv", sizeof("argv")-1)) != NULL)
) {
int pos = 0;
zval *entry;
- argc = zend_hash_num_elements(Z_ARRVAL_P(args));
+ if (Z_TYPE_P(args) != IS_ARRAY) {
+ RETURN_FALSE;
+ }
+ argc = zend_hash_num_elements(Z_ARRVAL_P(args));
/* Attempt to allocate enough memory to hold all of the arguments
* and a trailing NULL */
diff --git a/ext/standard/http.c b/ext/standard/http.c
index 62437f82d6..fc5727d7ce 100644
--- a/ext/standard/http.c
+++ b/ext/standard/http.c
@@ -82,6 +82,12 @@ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr,
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error traversing form data array");
return FAILURE;
}
+ if (Z_TYPE_P(zdata) == IS_INDIRECT) {
+ zdata = Z_INDIRECT_P(zdata);
+ if (Z_TYPE_P(zdata) == IS_UNDEF) {
+ continue;
+ }
+ }
if (Z_TYPE_P(zdata) == IS_ARRAY || Z_TYPE_P(zdata) == IS_OBJECT) {
if (key_type == HASH_KEY_IS_STRING) {
zend_string *ekey;
diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c
index 29e5db0ebf..0fdba30559 100644
--- a/ext/standard/http_fopen_wrapper.c
+++ b/ext/standard/http_fopen_wrapper.c
@@ -659,7 +659,7 @@ finish:
if (header_init) {
zval ztmp;
array_init(&ztmp);
- ZEND_SET_SYMBOL(&EG(active_symbol_table)->ht, "http_response_header", &ztmp);
+ zend_set_local_var("http_response_header", sizeof("http_response_header")-1, &ztmp, 0 TSRMLS_CC);
}
response_header = zend_hash_str_find(&EG(active_symbol_table)->ht, "http_response_header", sizeof("http_response_header")-1);
diff --git a/ext/standard/var.c b/ext/standard/var.c
index 8c2694bef7..9ea1119cea 100644
--- a/ext/standard/var.c
+++ b/ext/standard/var.c
@@ -35,12 +35,37 @@
#define COMMON (is_ref ? "&" : "")
/* }}} */
+static uint zend_obj_num_elements(HashTable *ht)
+{
+ Bucket *p;
+ uint idx;
+ uint num;
+
+ num = ht->nNumOfElements;
+ for (idx = 0; idx < ht->nNumUsed; idx++) {
+ p = ht->arData + idx;
+ if (Z_TYPE(p->val) == IS_UNDEF) continue;
+ if (Z_TYPE(p->val) == IS_INDIRECT) {
+ if (Z_TYPE_P(Z_INDIRECT(p->val)) == IS_UNDEF) {
+ num--;
+ }
+ }
+ }
+ return num;
+}
+
static int php_array_element_dump(zval *zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
{
int level;
level = va_arg(args, int);
+ if (Z_TYPE_P(zv) == IS_INDIRECT) {
+ zv = Z_INDIRECT_P(zv);
+ if (Z_TYPE_P(zv) == IS_UNDEF) {
+ return 0;
+ }
+ }
if (hash_key->key == NULL) { /* numeric key */
php_printf("%*c[%ld]=>\n", level + 1, ' ', hash_key->h);
} else { /* string key */
@@ -60,6 +85,12 @@ static int php_object_property_dump(zval *zv TSRMLS_DC, int num_args, va_list ar
level = va_arg(args, int);
+ if (Z_TYPE_P(zv) == IS_INDIRECT) {
+ zv = Z_INDIRECT_P(zv);
+ if (Z_TYPE_P(zv) == IS_UNDEF) {
+ return 0;
+ }
+ }
if (hash_key->key == NULL) { /* numeric key */
php_printf("%*c[%ld]=>\n", level + 1, ' ', hash_key->h);
} else { /* string key */
@@ -136,10 +167,10 @@ again:
if (Z_OBJ_HANDLER_P(struc, get_class_name)) {
class_name = Z_OBJ_HANDLER_P(struc, get_class_name)(struc, 0 TSRMLS_CC);
- php_printf("%sobject(%s)#%d (%d) {\n", COMMON, class_name->val, Z_OBJ_HANDLE_P(struc), myht ? zend_hash_num_elements(myht) : 0);
+ php_printf("%sobject(%s)#%d (%d) {\n", COMMON, class_name->val, Z_OBJ_HANDLE_P(struc), myht ? zend_obj_num_elements(myht) : 0);
STR_RELEASE(class_name);
} else {
- php_printf("%sobject(unknown class)#%d (%d) {\n", COMMON, Z_OBJ_HANDLE_P(struc), myht ? zend_hash_num_elements(myht) : 0);
+ php_printf("%sobject(unknown class)#%d (%d) {\n", COMMON, Z_OBJ_HANDLE_P(struc), myht ? zend_obj_num_elements(myht) : 0);
}
php_element_dump_func = php_object_property_dump;
head_done:
@@ -162,7 +193,7 @@ again:
break;
}
case IS_REFERENCE:
- //??? hide references with refcount==1 (for compatibility)
+//??? hide references with refcount==1 (for compatibility)
if (Z_REFCOUNT_P(struc) > 1) {
is_ref = 1;
}
@@ -200,6 +231,12 @@ static int zval_array_element_dump(zval *zv TSRMLS_DC, int num_args, va_list arg
level = va_arg(args, int);
+ if (Z_TYPE_P(zv) == IS_INDIRECT) {
+ zv = Z_INDIRECT_P(zv);
+ if (Z_TYPE_P(zv) == IS_UNDEF) {
+ return 0;
+ }
+ }
if (hash_key->key == NULL) { /* numeric key */
php_printf("%*c[%ld]=>\n", level + 1, ' ', hash_key->h);
} else { /* string key */
@@ -225,6 +262,12 @@ static int zval_object_property_dump(zval *zv TSRMLS_DC, int num_args, va_list a
level = va_arg(args, int);
+ if (Z_TYPE_P(zv) == IS_INDIRECT) {
+ zv = Z_INDIRECT_P(zv);
+ if (Z_TYPE_P(zv) == IS_UNDEF) {
+ return 0;
+ }
+ }
if (hash_key->key == NULL) { /* numeric key */
php_printf("%*c[%ld]=>\n", level + 1, ' ', hash_key->h);
} else { /* string key */
@@ -259,14 +302,7 @@ PHPAPI void php_debug_zval_dump(zval *struc, int level TSRMLS_DC) /* {{{ */
php_printf("%*c", level - 1, ' ');
}
- if (Z_TYPE_P(struc) == IS_REFERENCE) {
-//??? hide references with refcount==1 (for compatibility)
- if (Z_REFCOUNT_P(struc) > 1) {
- is_ref = 1;
- }
- struc = Z_REFVAL_P(struc);
- }
-
+again:
switch (Z_TYPE_P(struc)) {
case IS_BOOL:
php_printf("%sbool(%s)\n", COMMON, Z_LVAL_P(struc)?"true":"false");
@@ -301,7 +337,7 @@ PHPAPI void php_debug_zval_dump(zval *struc, int level TSRMLS_DC) /* {{{ */
return;
}
class_name = Z_OBJ_HANDLER_P(struc, get_class_name)(struc, 0 TSRMLS_CC);
- php_printf("%sobject(%s)#%d (%d) refcount(%u){\n", COMMON, class_name->val, Z_OBJ_HANDLE_P(struc), myht ? zend_hash_num_elements(myht) : 0, Z_REFCOUNT_P(struc));
+ php_printf("%sobject(%s)#%d (%d) refcount(%u){\n", COMMON, class_name->val, Z_OBJ_HANDLE_P(struc), myht ? zend_obj_num_elements(myht) : 0, Z_REFCOUNT_P(struc));
STR_RELEASE(class_name);
zval_element_dump_func = zval_object_property_dump;
head_done:
@@ -322,6 +358,13 @@ head_done:
php_printf("%sresource(%ld) of type (%s) refcount(%u)\n", COMMON, Z_RES_P(struc)->handle, type_name ? type_name : "Unknown", Z_REFCOUNT_P(struc));
break;
}
+ case IS_REFERENCE:
+//??? hide references with refcount==1 (for compatibility)
+ if (Z_REFCOUNT_P(struc) > 1) {
+ is_ref = 1;
+ }
+ struc = Z_REFVAL_P(struc);
+ goto again;
default:
php_printf("%sUNKNOWN:0\n", COMMON);
break;
@@ -364,6 +407,12 @@ static int php_array_element_export(zval *zv TSRMLS_DC, int num_args, va_list ar
level = va_arg(args, int);
buf = va_arg(args, smart_str *);
+ if (Z_TYPE_P(zv) == IS_INDIRECT) {
+ zv = Z_INDIRECT_P(zv);
+ if (Z_TYPE_P(zv) == IS_UNDEF) {
+ return 0;
+ }
+ }
if (hash_key->key == NULL) { /* numeric key */
buffer_append_spaces(buf, level+1);
smart_str_append_long(buf, (long) hash_key->h);
@@ -400,6 +449,13 @@ static int php_object_element_export(zval *zv TSRMLS_DC, int num_args, va_list a
level = va_arg(args, int);
buf = va_arg(args, smart_str *);
+ if (Z_TYPE_P(zv) == IS_INDIRECT) {
+ zv = Z_INDIRECT_P(zv);
+ if (Z_TYPE_P(zv) == IS_UNDEF) {
+ return 0;
+ }
+ }
+
buffer_append_spaces(buf, level + 2);
if (hash_key->key != NULL) {
const char *class_name; /* ignored, but must be passed to unmangle */
@@ -683,6 +739,12 @@ static void php_var_serialize_class(smart_str *buf, zval *struc, zval *retval_pt
}
propers = Z_OBJPROP_P(struc);
if ((d = zend_hash_find(propers, Z_STR_P(name))) != NULL) {
+ if (Z_TYPE_P(d) == IS_INDIRECT) {
+ d = Z_INDIRECT_P(d);
+ if (Z_TYPE_P(d) == IS_UNDEF) {
+ continue;
+ }
+ }
php_var_serialize_string(buf, Z_STRVAL_P(name), Z_STRLEN_P(name));
php_var_serialize_intern(buf, d, var_hash TSRMLS_CC);
} else {
@@ -694,6 +756,13 @@ static void php_var_serialize_class(smart_str *buf, zval *struc, zval *retval_pt
do {
priv_name = zend_mangle_property_name(ce->name->val, ce->name->len, Z_STRVAL_P(name), Z_STRLEN_P(name), ce->type & ZEND_INTERNAL_CLASS);
if ((d = zend_hash_find(propers, priv_name)) != NULL) {
+ if (Z_TYPE_P(d) == IS_INDIRECT) {
+ d = Z_INDIRECT_P(d);
+ if (Z_TYPE_P(d) == IS_UNDEF) {
+ STR_FREE(prot_name);
+ break;
+ }
+ }
php_var_serialize_string(buf, priv_name->val, priv_name->len);
STR_FREE(priv_name);
php_var_serialize_intern(buf, d, var_hash TSRMLS_CC);
@@ -702,6 +771,13 @@ static void php_var_serialize_class(smart_str *buf, zval *struc, zval *retval_pt
STR_FREE(priv_name);
prot_name = zend_mangle_property_name("*", 1, Z_STRVAL_P(name), Z_STRLEN_P(name), ce->type & ZEND_INTERNAL_CLASS);
if ((d = zend_hash_find(propers, prot_name)) != NULL) {
+ if (Z_TYPE_P(d) == IS_INDIRECT) {
+ d = Z_INDIRECT_P(d);
+ if (Z_TYPE_P(d) == IS_UNDEF) {
+ STR_FREE(prot_name);
+ break;
+ }
+ }
php_var_serialize_string(buf, prot_name->val, prot_name->len);
STR_FREE(prot_name);
php_var_serialize_intern(buf, d, var_hash TSRMLS_CC);
@@ -873,10 +949,17 @@ again:
zend_hash_internal_pointer_reset_ex(myht, &pos);
for (;; zend_hash_move_forward_ex(myht, &pos)) {
- i = zend_hash_get_current_key_ex(myht, &key, &index, 0, &pos);
- if (i == HASH_KEY_NON_EXISTENT) {
+ data = zend_hash_get_current_data_ex(myht, &pos);
+ if (!data) {
break;
+ } else if (Z_TYPE_P(data) == IS_INDIRECT) {
+ data = Z_INDIRECT_P(data);
+ if (Z_TYPE_P(data) == IS_UNDEF) {
+ continue;
+ }
}
+
+ i = zend_hash_get_current_key_ex(myht, &key, &index, 0, &pos);
if (incomplete_class && strcmp(key->val, MAGIC_MEMBER) == 0) {
continue;
}
@@ -892,8 +975,7 @@ again:
/* we should still add element even if it's not OK,
* since we already wrote the length of the array before */
- if ((data = zend_hash_get_current_data_ex(myht, &pos)) == NULL
- || (Z_TYPE_P(data) == IS_ARRAY && Z_TYPE_P(struc) == IS_ARRAY && Z_ARR_P(data) == Z_ARR_P(struc))
+ if ((Z_TYPE_P(data) == IS_ARRAY && Z_TYPE_P(struc) == IS_ARRAY && Z_ARR_P(data) == Z_ARR_P(struc))
|| (Z_TYPE_P(data) == IS_ARRAY && Z_ARRVAL_P(data)->nApplyCount > 1)
) {
smart_str_appendl(buf, "N;", 2);
diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c
index 8e69338b02..13f645b58e 100644
--- a/ext/standard/var_unserializer.c
+++ b/ext/standard/var_unserializer.c
@@ -79,7 +79,7 @@ PHPAPI void var_push_dtor(php_unserialize_data_t *var_hashx, zval *rval)
(*var_hashx)->last_dtor = var_hash;
}
- Z_ADDREF_P(rval);
+ if (Z_REFCOUNTED_P(rval)) Z_ADDREF_P(rval);
var_hash->data[var_hash->used_slots++] = rval;
}
@@ -306,7 +306,21 @@ static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long
} else {
/* object properties should include no integers */
convert_to_string(&key);
- data = zend_hash_update(ht, Z_STR(key), &d);
+//???
+#if 1
+ data = zend_hash_update_ind(ht, Z_STR(key), &d);
+#else
+ if ((data = zend_hash_find(ht, Z_STR(key))) != NULL) {
+ if (Z_TYPE_P(data) == IS_INDIRECT) {
+ data = Z_INDIRECT_P(data);
+ }
+ zval_ptr_dtor(data);
+//??? var_push_dtor(var_hash, data);
+ ZVAL_UNDEF(data);
+ } else {
+ data = zend_hash_update(ht, Z_STR(key), &d);
+ }
+#endif
}
zval_dtor(&key);
@@ -428,7 +442,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
start = cursor;
-#line 432 "ext/standard/var_unserializer.c"
+#line 446 "ext/standard/var_unserializer.c"
{
YYCTYPE yych;
static const unsigned char yybm[] = {
@@ -488,9 +502,9 @@ yy2:
yych = *(YYMARKER = ++YYCURSOR);
if (yych == ':') goto yy95;
yy3:
-#line 778 "ext/standard/var_unserializer.re"
+#line 792 "ext/standard/var_unserializer.re"
{ return 0; }
-#line 494 "ext/standard/var_unserializer.c"
+#line 508 "ext/standard/var_unserializer.c"
yy4:
yych = *(YYMARKER = ++YYCURSOR);
if (yych == ':') goto yy89;
@@ -533,13 +547,13 @@ yy13:
goto yy3;
yy14:
++YYCURSOR;
-#line 772 "ext/standard/var_unserializer.re"
+#line 786 "ext/standard/var_unserializer.re"
{
/* this is the case where we have less data than planned */
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unexpected end of serialized data");
return 0; /* not sure if it should be 0 or 1 here? */
}
-#line 543 "ext/standard/var_unserializer.c"
+#line 557 "ext/standard/var_unserializer.c"
yy16:
yych = *++YYCURSOR;
goto yy3;
@@ -569,7 +583,7 @@ yy20:
yych = *++YYCURSOR;
if (yych != '"') goto yy18;
++YYCURSOR;
-#line 633 "ext/standard/var_unserializer.re"
+#line 647 "ext/standard/var_unserializer.re"
{
size_t len, len2, len3, maxlen;
long elements;
@@ -708,7 +722,7 @@ yy20:
return object_common2(UNSERIALIZE_PASSTHRU, elements);
}
-#line 712 "ext/standard/var_unserializer.c"
+#line 726 "ext/standard/var_unserializer.c"
yy25:
yych = *++YYCURSOR;
if (yych <= ',') {
@@ -733,7 +747,7 @@ yy27:
yych = *++YYCURSOR;
if (yych != '"') goto yy18;
++YYCURSOR;
-#line 625 "ext/standard/var_unserializer.re"
+#line 639 "ext/standard/var_unserializer.re"
{
//??? INIT_PZVAL(rval);
@@ -741,7 +755,7 @@ yy27:
return object_common2(UNSERIALIZE_PASSTHRU,
object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR));
}
-#line 745 "ext/standard/var_unserializer.c"
+#line 759 "ext/standard/var_unserializer.c"
yy32:
yych = *++YYCURSOR;
if (yych == '+') goto yy33;
@@ -762,7 +776,7 @@ yy34:
yych = *++YYCURSOR;
if (yych != '{') goto yy18;
++YYCURSOR;
-#line 604 "ext/standard/var_unserializer.re"
+#line 618 "ext/standard/var_unserializer.re"
{
long elements = parse_iv(start + 2);
/* use iv() not uiv() in order to check data range */
@@ -783,7 +797,7 @@ yy34:
return finish_nested_data(UNSERIALIZE_PASSTHRU);
}
-#line 787 "ext/standard/var_unserializer.c"
+#line 801 "ext/standard/var_unserializer.c"
yy39:
yych = *++YYCURSOR;
if (yych == '+') goto yy40;
@@ -804,7 +818,7 @@ yy41:
yych = *++YYCURSOR;
if (yych != '"') goto yy18;
++YYCURSOR;
-#line 574 "ext/standard/var_unserializer.re"
+#line 588 "ext/standard/var_unserializer.re"
{
size_t len, maxlen;
//??? TODO: use zend_string* instead of char*
@@ -834,7 +848,7 @@ yy41:
efree(str);
return 1;
}
-#line 838 "ext/standard/var_unserializer.c"
+#line 852 "ext/standard/var_unserializer.c"
yy46:
yych = *++YYCURSOR;
if (yych == '+') goto yy47;
@@ -855,7 +869,7 @@ yy48:
yych = *++YYCURSOR;
if (yych != '"') goto yy18;
++YYCURSOR;
-#line 547 "ext/standard/var_unserializer.re"
+#line 561 "ext/standard/var_unserializer.re"
{
size_t len, maxlen;
char *str;
@@ -882,7 +896,7 @@ yy48:
ZVAL_STRINGL(rval, str, len);
return 1;
}
-#line 886 "ext/standard/var_unserializer.c"
+#line 900 "ext/standard/var_unserializer.c"
yy53:
yych = *++YYCURSOR;
if (yych <= '/') {
@@ -970,7 +984,7 @@ yy61:
}
yy63:
++YYCURSOR;
-#line 538 "ext/standard/var_unserializer.re"
+#line 552 "ext/standard/var_unserializer.re"
{
#if SIZEOF_LONG == 4
use_double:
@@ -979,7 +993,7 @@ use_double:
ZVAL_DOUBLE(rval, zend_strtod((const char *)start + 2, NULL));
return 1;
}
-#line 983 "ext/standard/var_unserializer.c"
+#line 997 "ext/standard/var_unserializer.c"
yy65:
yych = *++YYCURSOR;
if (yych <= ',') {
@@ -1038,7 +1052,7 @@ yy73:
yych = *++YYCURSOR;
if (yych != ';') goto yy18;
++YYCURSOR;
-#line 522 "ext/standard/var_unserializer.re"
+#line 536 "ext/standard/var_unserializer.re"
{
*p = YYCURSOR;
@@ -1054,7 +1068,7 @@ yy73:
return 1;
}
-#line 1058 "ext/standard/var_unserializer.c"
+#line 1072 "ext/standard/var_unserializer.c"
yy76:
yych = *++YYCURSOR;
if (yych == 'N') goto yy73;
@@ -1081,7 +1095,7 @@ yy79:
if (yych <= '9') goto yy79;
if (yych != ';') goto yy18;
++YYCURSOR;
-#line 496 "ext/standard/var_unserializer.re"
+#line 510 "ext/standard/var_unserializer.re"
{
#if SIZEOF_LONG == 4
int digits = YYCURSOR - start - 3;
@@ -1107,7 +1121,7 @@ yy79:
ZVAL_LONG(rval, parse_iv(start + 2));
return 1;
}
-#line 1111 "ext/standard/var_unserializer.c"
+#line 1125 "ext/standard/var_unserializer.c"
yy83:
yych = *++YYCURSOR;
if (yych <= '/') goto yy18;
@@ -1115,22 +1129,22 @@ yy83:
yych = *++YYCURSOR;
if (yych != ';') goto yy18;
++YYCURSOR;
-#line 490 "ext/standard/var_unserializer.re"
+#line 504 "ext/standard/var_unserializer.re"
{
*p = YYCURSOR;
ZVAL_BOOL(rval, parse_iv(start + 2));
return 1;
}
-#line 1125 "ext/standard/var_unserializer.c"
+#line 1139 "ext/standard/var_unserializer.c"
yy87:
++YYCURSOR;
-#line 484 "ext/standard/var_unserializer.re"
+#line 498 "ext/standard/var_unserializer.re"
{
*p = YYCURSOR;
ZVAL_NULL(rval);
return 1;
}
-#line 1134 "ext/standard/var_unserializer.c"
+#line 1148 "ext/standard/var_unserializer.c"
yy89:
yych = *++YYCURSOR;
if (yych <= ',') {
@@ -1153,7 +1167,7 @@ yy91:
if (yych <= '9') goto yy91;
if (yych != ';') goto yy18;
++YYCURSOR;
-#line 461 "ext/standard/var_unserializer.re"
+#line 475 "ext/standard/var_unserializer.re"
{
long id;
@@ -1176,7 +1190,7 @@ yy91:
return 1;
}
-#line 1180 "ext/standard/var_unserializer.c"
+#line 1194 "ext/standard/var_unserializer.c"
yy95:
yych = *++YYCURSOR;
if (yych <= ',') {
@@ -1199,7 +1213,7 @@ yy97:
if (yych <= '9') goto yy97;
if (yych != ';') goto yy18;
++YYCURSOR;
-#line 436 "ext/standard/var_unserializer.re"
+#line 450 "ext/standard/var_unserializer.re"
{
long id;
@@ -1224,9 +1238,9 @@ yy97:
return 1;
}
-#line 1228 "ext/standard/var_unserializer.c"
+#line 1242 "ext/standard/var_unserializer.c"
}
-#line 780 "ext/standard/var_unserializer.re"
+#line 794 "ext/standard/var_unserializer.re"
return 0;
diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re
index ae195ae88b..cda2dcd452 100644
--- a/ext/standard/var_unserializer.re
+++ b/ext/standard/var_unserializer.re
@@ -77,7 +77,7 @@ PHPAPI void var_push_dtor(php_unserialize_data_t *var_hashx, zval *rval)
(*var_hashx)->last_dtor = var_hash;
}
- Z_ADDREF_P(rval);
+ if (Z_REFCOUNTED_P(rval)) Z_ADDREF_P(rval);
var_hash->data[var_hash->used_slots++] = rval;
}
@@ -310,7 +310,21 @@ static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long
} else {
/* object properties should include no integers */
convert_to_string(&key);
- data = zend_hash_update(ht, Z_STR(key), &d);
+//???
+#if 1
+ data = zend_hash_update_ind(ht, Z_STR(key), &d);
+#else
+ if ((data = zend_hash_find(ht, Z_STR(key))) != NULL) {
+ if (Z_TYPE_P(data) == IS_INDIRECT) {
+ data = Z_INDIRECT_P(data);
+ }
+ zval_ptr_dtor(data);
+//??? var_push_dtor(var_hash, data);
+ ZVAL_UNDEF(data);
+ } else {
+ data = zend_hash_update(ht, Z_STR(key), &d);
+ }
+#endif
}
zval_dtor(&key);
diff --git a/main/main.c b/main/main.c
index 0f8a029b51..931a5246c6 100644
--- a/main/main.c
+++ b/main/main.c
@@ -857,13 +857,10 @@ PHPAPI void php_verror(const char *docref, const char *params, int type, const c
if (PG(track_errors) && module_initialized &&
(Z_TYPE(EG(user_error_handler)) == IS_UNDEF || !(EG(user_error_handler_error_reporting) & type))) {
- if (!EG(active_symbol_table)) {
- zend_rebuild_symbol_table(TSRMLS_C);
- }
- if (EG(active_symbol_table)) {
- zval tmp;
- ZVAL_STRINGL(&tmp, buffer, buffer_len);
- zend_hash_str_update(&EG(active_symbol_table)->ht, "php_errormsg", sizeof("php_errormsg")-1, &tmp);
+ zval tmp;
+ ZVAL_STRINGL(&tmp, buffer, buffer_len);
+ if (zend_set_local_var("php_errormsg", sizeof("php_errormsg")-1, &tmp, 0 TSRMLS_CC) == FAILURE) {
+ zval_ptr_dtor(&tmp);
}
}
if (replace_buffer) {
@@ -1195,7 +1192,9 @@ static void php_error_cb(int type, const char *error_filename, const uint error_
if (EG(active_symbol_table)) {
zval tmp;
ZVAL_STRINGL(&tmp, buffer, buffer_len);
- zend_hash_str_update(&EG(active_symbol_table)->ht, "php_errormsg", sizeof("php_errormsg")-1, &tmp);
+ if (zend_set_local_var("php_errormsg", sizeof("php_errormsg")-1, &tmp, 0 TSRMLS_CC) == FAILURE) {
+ zval_ptr_dtor(&tmp);
+ }
}
}
diff --git a/main/php_variables.c b/main/php_variables.c
index 47b2c522bd..20bee7e8d9 100644
--- a/main/php_variables.c
+++ b/main/php_variables.c
@@ -181,10 +181,19 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
return;
}
} else {
- if ((gpc_element_p = zend_symtable_str_find(symtable1, index, index_len)) == NULL
- || Z_TYPE_P(gpc_element_p) != IS_ARRAY) {
- array_init(&gpc_element);
- gpc_element_p = zend_symtable_str_update(symtable1, index, index_len, &gpc_element);
+ gpc_element_p = zend_symtable_str_find(symtable1, index, index_len);
+ if (!gpc_element_p) {
+ zval tmp;
+ array_init(&tmp);
+ gpc_element_p = zend_symtable_str_update_ind(symtable1, index, index_len, &tmp);
+ } else {
+ if (Z_TYPE_P(gpc_element_p) == IS_INDIRECT) {
+ gpc_element_p = Z_INDIRECT_P(gpc_element_p);
+ }
+ if (Z_TYPE_P(gpc_element_p) != IS_ARRAY) {
+ zval_ptr_dtor(gpc_element_p);
+ array_init(gpc_element_p);
+ }
}
}
symtable1 = Z_ARRVAL_P(gpc_element_p);
@@ -219,7 +228,7 @@ plain_var:
zend_symtable_str_exists(symtable1, index, index_len)) {
zval_ptr_dtor(&gpc_element);
} else {
- gpc_element_p = zend_symtable_str_update(symtable1, index, index_len, &gpc_element);
+ gpc_element_p = zend_symtable_str_update_ind(symtable1, index, index_len, &gpc_element);
}
}
}