mirror of
https://github.com/php/php-src.git
synced 2024-11-23 18:04:36 +08:00
Refactored IS_INDIRECT usage for CV and object properties to support HashTable resizing
This commit is contained in:
parent
e82f112468
commit
887189ca31
@ -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(" ");
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
144
Zend/zend_hash.c
144
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;
|
||||
@ -604,6 +662,53 @@ ZEND_API int zend_hash_str_del(HashTable *ht, const char *str, int len)
|
||||
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)) {
|
||||
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;
|
||||
@ -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);
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
//??? 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));
|
||||
|
||||
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);
|
||||
}
|
||||
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 */
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
15
main/main.c
15
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user