version 1.1, 2012/02/21 23:47:52
|
version 1.1.1.3, 2013/07/22 01:32:16
|
Line 2
|
Line 2
|
+----------------------------------------------------------------------+ |
+----------------------------------------------------------------------+ |
| Zend Engine | |
| Zend Engine | |
+----------------------------------------------------------------------+ |
+----------------------------------------------------------------------+ |
| Copyright (c) 1998-2012 Zend Technologies Ltd. (http://www.zend.com) | | | Copyright (c) 1998-2013 Zend Technologies Ltd. (http://www.zend.com) | |
+----------------------------------------------------------------------+ |
+----------------------------------------------------------------------+ |
| This source file is subject to version 2.00 of the Zend license, | |
| This source file is subject to version 2.00 of the Zend license, | |
| that is bundled with this package in the file LICENSE, and is | |
| that is bundled with this package in the file LICENSE, and is | |
Line 32
|
Line 32
|
|
|
#define DEBUG_OBJECT_HANDLERS 0 |
#define DEBUG_OBJECT_HANDLERS 0 |
|
|
#define Z_OBJ_P(zval_p) zend_objects_get_address(zval_p TSRMLS_CC) | #define Z_OBJ_P(zval_p) \ |
| ((zend_object*)(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(zval_p)].bucket.obj.object)) |
|
|
|
#define Z_OBJ_PROTECT_RECURSION(zval_p) \ |
|
do { \ |
|
if (EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(zval_p)].apply_count++ >= 3) { \ |
|
zend_error(E_ERROR, "Nesting level too deep - recursive dependency?"); \ |
|
} \ |
|
} while (0) |
|
|
|
|
|
#define Z_OBJ_UNPROTECT_RECURSION(zval_p) \ |
|
EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(zval_p)].apply_count-- |
|
|
/* |
/* |
__X accessors explanation: |
__X accessors explanation: |
|
|
Line 51
|
Line 63
|
called, we cal __call handler. |
called, we cal __call handler. |
*/ |
*/ |
|
|
|
ZEND_API void rebuild_object_properties(zend_object *zobj) /* {{{ */ |
|
{ |
|
if (!zobj->properties) { |
|
HashPosition pos; |
|
zend_property_info *prop_info; |
|
zend_class_entry *ce = zobj->ce; |
|
|
|
ALLOC_HASHTABLE(zobj->properties); |
|
zend_hash_init(zobj->properties, 0, NULL, ZVAL_PTR_DTOR, 0); |
|
if (ce->default_properties_count) { |
|
for (zend_hash_internal_pointer_reset_ex(&ce->properties_info, &pos); |
|
zend_hash_get_current_data_ex(&ce->properties_info, (void**)&prop_info, &pos) == SUCCESS; |
|
zend_hash_move_forward_ex(&ce->properties_info, &pos)) { |
|
if (/*prop_info->ce == ce &&*/ |
|
(prop_info->flags & ZEND_ACC_STATIC) == 0 && |
|
prop_info->offset >= 0 && |
|
zobj->properties_table[prop_info->offset]) { |
|
zend_hash_quick_add(zobj->properties, prop_info->name, prop_info->name_length+1, prop_info->h, (void**)&zobj->properties_table[prop_info->offset], sizeof(zval*), (void**)&zobj->properties_table[prop_info->offset]); |
|
} |
|
} |
|
while (ce->parent && ce->parent->default_properties_count) { |
|
ce = ce->parent; |
|
for (zend_hash_internal_pointer_reset_ex(&ce->properties_info, &pos); |
|
zend_hash_get_current_data_ex(&ce->properties_info, (void**)&prop_info, &pos) == SUCCESS; |
|
zend_hash_move_forward_ex(&ce->properties_info, &pos)) { |
|
if (prop_info->ce == ce && |
|
(prop_info->flags & ZEND_ACC_STATIC) == 0 && |
|
(prop_info->flags & ZEND_ACC_PRIVATE) != 0 && |
|
prop_info->offset >= 0 && |
|
zobj->properties_table[prop_info->offset]) { |
|
zend_hash_quick_add(zobj->properties, prop_info->name, prop_info->name_length+1, prop_info->h, (void**)&zobj->properties_table[prop_info->offset], sizeof(zval*), (void**)&zobj->properties_table[prop_info->offset]); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
} |
|
/* }}} */ |
|
|
ZEND_API HashTable *zend_std_get_properties(zval *object TSRMLS_DC) /* {{{ */ |
ZEND_API HashTable *zend_std_get_properties(zval *object TSRMLS_DC) /* {{{ */ |
{ |
{ |
zend_object *zobj; |
zend_object *zobj; |
zobj = Z_OBJ_P(object); |
zobj = Z_OBJ_P(object); |
|
if (!zobj->properties) { |
|
rebuild_object_properties(zobj); |
|
} |
return zobj->properties; |
return zobj->properties; |
} |
} |
/* }}} */ |
/* }}} */ |
|
|
|
ZEND_API HashTable *zend_std_get_gc(zval *object, zval ***table, int *n TSRMLS_DC) /* {{{ */ |
|
{ |
|
if (Z_OBJ_HANDLER_P(object, get_properties) != zend_std_get_properties) { |
|
*table = NULL; |
|
*n = 0; |
|
return Z_OBJ_HANDLER_P(object, get_properties)(object TSRMLS_CC); |
|
} 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; |
|
} |
|
} |
|
} |
|
/* }}} */ |
|
|
ZEND_API HashTable *zend_std_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ |
ZEND_API HashTable *zend_std_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ |
{ |
{ |
*is_temp = 0; |
*is_temp = 0; |
Line 158 static zval *zend_std_call_issetter(zval *object, zval
|
Line 234 static zval *zend_std_call_issetter(zval *object, zval
|
} |
} |
/* }}} */ |
/* }}} */ |
|
|
static int zend_verify_property_access(zend_property_info *property_info, zend_class_entry *ce TSRMLS_DC) /* {{{ */ | static zend_always_inline int zend_verify_property_access(zend_property_info *property_info, zend_class_entry *ce TSRMLS_DC) /* {{{ */ |
{ |
{ |
switch (property_info->flags & ZEND_ACC_PPP_MASK) { |
switch (property_info->flags & ZEND_ACC_PPP_MASK) { |
case ZEND_ACC_PUBLIC: |
case ZEND_ACC_PUBLIC: |
Line 177 static int zend_verify_property_access(zend_property_i
|
Line 253 static int zend_verify_property_access(zend_property_i
|
} |
} |
/* }}} */ |
/* }}} */ |
|
|
static inline zend_bool is_derived_class(zend_class_entry *child_class, zend_class_entry *parent_class) /* {{{ */ | static zend_always_inline zend_bool is_derived_class(zend_class_entry *child_class, zend_class_entry *parent_class) /* {{{ */ |
{ |
{ |
child_class = child_class->parent; |
child_class = child_class->parent; |
while (child_class) { |
while (child_class) { |
Line 191 static inline zend_bool is_derived_class(zend_class_en
|
Line 267 static inline zend_bool is_derived_class(zend_class_en
|
} |
} |
/* }}} */ |
/* }}} */ |
|
|
ZEND_API struct _zend_property_info *zend_get_property_info(zend_class_entry *ce, zval *member, int silent TSRMLS_DC) /* {{{ */ | static zend_always_inline struct _zend_property_info *zend_get_property_info_quick(zend_class_entry *ce, zval *member, int silent, const zend_literal *key TSRMLS_DC) /* {{{ */ |
{ |
{ |
zend_property_info *property_info = NULL; | zend_property_info *property_info; |
zend_property_info *scope_property_info; |
zend_property_info *scope_property_info; |
zend_bool denied_access = 0; |
zend_bool denied_access = 0; |
ulong h; |
ulong h; |
|
|
if (Z_STRVAL_P(member)[0] == '\0') { | if (key && (property_info = CACHED_POLYMORPHIC_PTR(key->cache_slot, ce)) != NULL) { |
| return property_info; |
| } |
| |
| if (UNEXPECTED(Z_STRVAL_P(member)[0] == '\0')) { |
if (!silent) { |
if (!silent) { |
if (Z_STRLEN_P(member) == 0) { |
if (Z_STRLEN_P(member) == 0) { |
zend_error(E_ERROR, "Cannot access empty property"); | zend_error_noreturn(E_ERROR, "Cannot access empty property"); |
} else { |
} else { |
zend_error(E_ERROR, "Cannot access property started with '\\0'"); | zend_error_noreturn(E_ERROR, "Cannot access property started with '\\0'"); |
} |
} |
} |
} |
return NULL; |
return NULL; |
} |
} |
h = zend_get_hash_value(Z_STRVAL_P(member), Z_STRLEN_P(member) + 1); | property_info = NULL; |
| h = key ? key->hash_value : zend_get_hash_value(Z_STRVAL_P(member), Z_STRLEN_P(member) + 1); |
if (zend_hash_quick_find(&ce->properties_info, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, h, (void **) &property_info)==SUCCESS) { |
if (zend_hash_quick_find(&ce->properties_info, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, h, (void **) &property_info)==SUCCESS) { |
if(property_info->flags & ZEND_ACC_SHADOW) { | if (UNEXPECTED((property_info->flags & ZEND_ACC_SHADOW) != 0)) { |
/* if it's a shadow - go to access it's private */ |
/* if it's a shadow - go to access it's private */ |
property_info = NULL; |
property_info = NULL; |
} else { |
} else { |
if (zend_verify_property_access(property_info, ce TSRMLS_CC)) { | if (EXPECTED(zend_verify_property_access(property_info, ce TSRMLS_CC) != 0)) { |
if (property_info->flags & ZEND_ACC_CHANGED | if (EXPECTED((property_info->flags & ZEND_ACC_CHANGED) != 0) |
&& !(property_info->flags & ZEND_ACC_PRIVATE)) { | && EXPECTED(!(property_info->flags & ZEND_ACC_PRIVATE))) { |
/* We still need to make sure that we're not in a context |
/* We still need to make sure that we're not in a context |
* where the right property is a different 'statically linked' private |
* where the right property is a different 'statically linked' private |
* continue checking below... |
* continue checking below... |
*/ |
*/ |
} else { |
} else { |
if (!silent && (property_info->flags & ZEND_ACC_STATIC)) { | if (UNEXPECTED((property_info->flags & ZEND_ACC_STATIC) != 0) && !silent) { |
zend_error(E_STRICT, "Accessing static property %s::$%s as non static", ce->name, Z_STRVAL_P(member)); |
zend_error(E_STRICT, "Accessing static property %s::$%s as non static", ce->name, Z_STRVAL_P(member)); |
} |
} |
|
if (key) { |
|
CACHE_POLYMORPHIC_PTR(key->cache_slot, ce, property_info); |
|
} |
return property_info; |
return property_info; |
} |
} |
} else { |
} else { |
Line 234 ZEND_API struct _zend_property_info *zend_get_property
|
Line 318 ZEND_API struct _zend_property_info *zend_get_property
|
} |
} |
} |
} |
if (EG(scope) != ce |
if (EG(scope) != ce |
&& is_derived_class(ce, EG(scope)) |
|
&& EG(scope) |
&& EG(scope) |
|
&& is_derived_class(ce, EG(scope)) |
&& zend_hash_quick_find(&EG(scope)->properties_info, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, h, (void **) &scope_property_info)==SUCCESS |
&& zend_hash_quick_find(&EG(scope)->properties_info, Z_STRVAL_P(member), Z_STRLEN_P(member)+1, h, (void **) &scope_property_info)==SUCCESS |
&& scope_property_info->flags & ZEND_ACC_PRIVATE) { |
&& scope_property_info->flags & ZEND_ACC_PRIVATE) { |
|
if (key) { |
|
CACHE_POLYMORPHIC_PTR(key->cache_slot, ce, scope_property_info); |
|
} |
return scope_property_info; |
return scope_property_info; |
} else if (property_info) { |
} else if (property_info) { |
if (denied_access) { | if (UNEXPECTED(denied_access != 0)) { |
/* Information was available, but we were denied access. Error out. */ |
/* Information was available, but we were denied access. Error out. */ |
if (silent) { | if (!silent) { |
return NULL; | zend_error_noreturn(E_ERROR, "Cannot access %s property %s::$%s", zend_visibility_string(property_info->flags), ce->name, Z_STRVAL_P(member)); |
} |
} |
zend_error(E_ERROR, "Cannot access %s property %s::$%s", zend_visibility_string(property_info->flags), ce->name, Z_STRVAL_P(member)); | return NULL; |
} else { |
} else { |
/* fall through, return property_info... */ |
/* fall through, return property_info... */ |
|
if (key) { |
|
CACHE_POLYMORPHIC_PTR(key->cache_slot, ce, property_info); |
|
} |
} |
} |
} else { |
} else { |
EG(std_property_info).flags = ZEND_ACC_PUBLIC; |
EG(std_property_info).flags = ZEND_ACC_PUBLIC; |
Line 255 ZEND_API struct _zend_property_info *zend_get_property
|
Line 345 ZEND_API struct _zend_property_info *zend_get_property
|
EG(std_property_info).name_length = Z_STRLEN_P(member); |
EG(std_property_info).name_length = Z_STRLEN_P(member); |
EG(std_property_info).h = h; |
EG(std_property_info).h = h; |
EG(std_property_info).ce = ce; |
EG(std_property_info).ce = ce; |
|
EG(std_property_info).offset = -1; |
property_info = &EG(std_property_info); |
property_info = &EG(std_property_info); |
} |
} |
return property_info; |
return property_info; |
} |
} |
/* }}} */ |
/* }}} */ |
|
|
ZEND_API int zend_check_property_access(zend_object *zobj, char *prop_info_name, int prop_info_name_len TSRMLS_DC) /* {{{ */ | ZEND_API struct _zend_property_info *zend_get_property_info(zend_class_entry *ce, zval *member, int silent TSRMLS_DC) /* {{{ */ |
{ |
{ |
|
return zend_get_property_info_quick(ce, member, silent, NULL TSRMLS_CC); |
|
} |
|
/* }}} */ |
|
|
|
ZEND_API int zend_check_property_access(zend_object *zobj, const char *prop_info_name, int prop_info_name_len TSRMLS_DC) /* {{{ */ |
|
{ |
zend_property_info *property_info; |
zend_property_info *property_info; |
char *class_name, *prop_name; | const char *class_name, *prop_name; |
zval member; |
zval member; |
|
|
zend_unmangle_property_name(prop_info_name, prop_info_name_len, &class_name, &prop_name); |
zend_unmangle_property_name(prop_info_name, prop_info_name_len, &class_name, &prop_name); |
ZVAL_STRING(&member, prop_name, 0); |
ZVAL_STRING(&member, prop_name, 0); |
property_info = zend_get_property_info(zobj->ce, &member, 1 TSRMLS_CC); | property_info = zend_get_property_info_quick(zobj->ce, &member, 1, NULL TSRMLS_CC); |
if (!property_info) { |
if (!property_info) { |
return FAILURE; |
return FAILURE; |
} |
} |
Line 296 static int zend_get_property_guard(zend_object *zobj,
|
Line 393 static int zend_get_property_guard(zend_object *zobj,
|
info.name = Z_STRVAL_P(member); |
info.name = Z_STRVAL_P(member); |
info.name_length = Z_STRLEN_P(member); |
info.name_length = Z_STRLEN_P(member); |
info.h = zend_get_hash_value(Z_STRVAL_P(member), Z_STRLEN_P(member) + 1); |
info.h = zend_get_hash_value(Z_STRVAL_P(member), Z_STRLEN_P(member) + 1); |
|
} else if(property_info->name[0] == '\0'){ |
|
const char *class_name = NULL, *prop_name = NULL; |
|
zend_unmangle_property_name(property_info->name, property_info->name_length, &class_name, &prop_name); |
|
if(class_name) { |
|
/* use unmangled name for protected properties */ |
|
info.name = prop_name; |
|
info.name_length = strlen(prop_name); |
|
info.h = zend_get_hash_value(info.name, info.name_length+1); |
|
property_info = &info; |
|
} |
} |
} |
if (!zobj->guards) { |
if (!zobj->guards) { |
ALLOC_HASHTABLE(zobj->guards); |
ALLOC_HASHTABLE(zobj->guards); |
Line 311 static int zend_get_property_guard(zend_object *zobj,
|
Line 418 static int zend_get_property_guard(zend_object *zobj,
|
} |
} |
/* }}} */ |
/* }}} */ |
|
|
zval *zend_std_read_property(zval *object, zval *member, int type TSRMLS_DC) /* {{{ */ | zval *zend_std_read_property(zval *object, zval *member, int type, const zend_literal *key TSRMLS_DC) /* {{{ */ |
{ |
{ |
zend_object *zobj; |
zend_object *zobj; |
zval *tmp_member = NULL; |
zval *tmp_member = NULL; |
Line 323 zval *zend_std_read_property(zval *object, zval *membe
|
Line 430 zval *zend_std_read_property(zval *object, zval *membe
|
silent = (type == BP_VAR_IS); |
silent = (type == BP_VAR_IS); |
zobj = Z_OBJ_P(object); |
zobj = Z_OBJ_P(object); |
|
|
if (Z_TYPE_P(member) != IS_STRING) { | if (UNEXPECTED(Z_TYPE_P(member) != IS_STRING)) { |
ALLOC_ZVAL(tmp_member); | ALLOC_ZVAL(tmp_member); |
*tmp_member = *member; |
*tmp_member = *member; |
INIT_PZVAL(tmp_member); |
INIT_PZVAL(tmp_member); |
zval_copy_ctor(tmp_member); |
zval_copy_ctor(tmp_member); |
convert_to_string(tmp_member); |
convert_to_string(tmp_member); |
member = tmp_member; |
member = tmp_member; |
|
key = NULL; |
} |
} |
|
|
#if DEBUG_OBJECT_HANDLERS |
#if DEBUG_OBJECT_HANDLERS |
Line 337 zval *zend_std_read_property(zval *object, zval *membe
|
Line 445 zval *zend_std_read_property(zval *object, zval *membe
|
#endif |
#endif |
|
|
/* make zend_get_property_info silent if we have getter - we may want to use it */ |
/* make zend_get_property_info silent if we have getter - we may want to use it */ |
property_info = zend_get_property_info(zobj->ce, member, (zobj->ce->__get != NULL) TSRMLS_CC); | property_info = zend_get_property_info_quick(zobj->ce, member, silent || (zobj->ce->__get != NULL), key TSRMLS_CC); |
|
|
if (!property_info || zend_hash_quick_find(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, (void **) &retval) == FAILURE) { | if (UNEXPECTED(!property_info) || |
| ((EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0) && |
| property_info->offset >= 0) ? |
| (zobj->properties ? |
| ((retval = (zval**)zobj->properties_table[property_info->offset]) == NULL) : |
| (*(retval = &zobj->properties_table[property_info->offset]) == NULL)) : |
| (UNEXPECTED(!zobj->properties) || |
| UNEXPECTED(zend_hash_quick_find(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, (void **) &retval) == FAILURE)))) { |
zend_guard *guard = NULL; |
zend_guard *guard = NULL; |
|
|
if (zobj->ce->__get && |
if (zobj->ce->__get && |
Line 367 zval *zend_std_read_property(zval *object, zval *membe
|
Line 482 zval *zend_std_read_property(zval *object, zval *membe
|
Z_UNSET_ISREF_P(rv); |
Z_UNSET_ISREF_P(rv); |
Z_SET_REFCOUNT_P(rv, 0); |
Z_SET_REFCOUNT_P(rv, 0); |
} |
} |
if (Z_TYPE_P(rv) != IS_OBJECT) { | if (UNEXPECTED(Z_TYPE_P(rv) != IS_OBJECT)) { |
zend_error(E_NOTICE, "Indirect modification of overloaded property %s::$%s has no effect", zobj->ce->name, Z_STRVAL_P(member)); |
zend_error(E_NOTICE, "Indirect modification of overloaded property %s::$%s has no effect", zobj->ce->name, Z_STRVAL_P(member)); |
} |
} |
} |
} |
Line 395 zval *zend_std_read_property(zval *object, zval *membe
|
Line 510 zval *zend_std_read_property(zval *object, zval *membe
|
retval = &EG(uninitialized_zval_ptr); |
retval = &EG(uninitialized_zval_ptr); |
} |
} |
} |
} |
if (tmp_member) { | if (UNEXPECTED(tmp_member != NULL)) { |
Z_ADDREF_PP(retval); |
Z_ADDREF_PP(retval); |
zval_ptr_dtor(&tmp_member); |
zval_ptr_dtor(&tmp_member); |
Z_DELREF_PP(retval); |
Z_DELREF_PP(retval); |
Line 404 zval *zend_std_read_property(zval *object, zval *membe
|
Line 519 zval *zend_std_read_property(zval *object, zval *membe
|
} |
} |
/* }}} */ |
/* }}} */ |
|
|
static void zend_std_write_property(zval *object, zval *member, zval *value TSRMLS_DC) /* {{{ */ | ZEND_API void zend_std_write_property(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC) /* {{{ */ |
{ |
{ |
zend_object *zobj; |
zend_object *zobj; |
zval *tmp_member = NULL; |
zval *tmp_member = NULL; |
Line 413 static void zend_std_write_property(zval *object, zval
|
Line 528 static void zend_std_write_property(zval *object, zval
|
|
|
zobj = Z_OBJ_P(object); |
zobj = Z_OBJ_P(object); |
|
|
if (Z_TYPE_P(member) != IS_STRING) { | if (UNEXPECTED(Z_TYPE_P(member) != IS_STRING)) { |
ALLOC_ZVAL(tmp_member); |
ALLOC_ZVAL(tmp_member); |
*tmp_member = *member; |
*tmp_member = *member; |
INIT_PZVAL(tmp_member); |
INIT_PZVAL(tmp_member); |
zval_copy_ctor(tmp_member); |
zval_copy_ctor(tmp_member); |
convert_to_string(tmp_member); |
convert_to_string(tmp_member); |
member = tmp_member; |
member = tmp_member; |
|
key = NULL; |
} |
} |
|
|
property_info = zend_get_property_info(zobj->ce, member, (zobj->ce->__set != NULL) TSRMLS_CC); | property_info = zend_get_property_info_quick(zobj->ce, member, (zobj->ce->__set != NULL), key TSRMLS_CC); |
|
|
if (property_info && zend_hash_quick_find(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, (void **) &variable_ptr) == SUCCESS) { | if (EXPECTED(property_info != NULL) && |
| ((EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0) && |
| property_info->offset >= 0) ? |
| (zobj->properties ? |
| ((variable_ptr = (zval**)zobj->properties_table[property_info->offset]) != NULL) : |
| (*(variable_ptr = &zobj->properties_table[property_info->offset]) != NULL)) : |
| (EXPECTED(zobj->properties != NULL) && |
| EXPECTED(zend_hash_quick_find(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, (void **) &variable_ptr) == SUCCESS)))) { |
/* if we already have this value there, we don't actually need to do anything */ |
/* if we already have this value there, we don't actually need to do anything */ |
if (*variable_ptr != value) { | if (EXPECTED(*variable_ptr != value)) { |
/* if we are assigning reference, we shouldn't move it, but instead assign variable |
/* if we are assigning reference, we shouldn't move it, but instead assign variable |
to the same pointer */ |
to the same pointer */ |
if (PZVAL_IS_REF(*variable_ptr)) { |
if (PZVAL_IS_REF(*variable_ptr)) { |
Line 437 static void zend_std_write_property(zval *object, zval
|
Line 560 static void zend_std_write_property(zval *object, zval
|
(*variable_ptr)->value = value->value; |
(*variable_ptr)->value = value->value; |
if (Z_REFCOUNT_P(value) > 0) { |
if (Z_REFCOUNT_P(value) > 0) { |
zval_copy_ctor(*variable_ptr); |
zval_copy_ctor(*variable_ptr); |
|
} else { |
|
efree(value); |
} |
} |
zval_dtor(&garbage); |
zval_dtor(&garbage); |
} else { |
} else { |
Line 467 static void zend_std_write_property(zval *object, zval
|
Line 592 static void zend_std_write_property(zval *object, zval
|
} |
} |
guard->in_set = 0; |
guard->in_set = 0; |
zval_ptr_dtor(&object); |
zval_ptr_dtor(&object); |
} else if (property_info) { | } else if (EXPECTED(property_info != NULL)) { |
zval **foo; | |
| |
/* if we assign referenced variable, we should separate it */ |
/* if we assign referenced variable, we should separate it */ |
Z_ADDREF_P(value); |
Z_ADDREF_P(value); |
if (PZVAL_IS_REF(value)) { |
if (PZVAL_IS_REF(value)) { |
SEPARATE_ZVAL(&value); |
SEPARATE_ZVAL(&value); |
} |
} |
zend_hash_quick_update(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, &value, sizeof(zval *), (void **) &foo); | if (EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0) && |
| property_info->offset >= 0) { |
| if (!zobj->properties) { |
| zobj->properties_table[property_info->offset] = value; |
| } else if (zobj->properties_table[property_info->offset]) { |
| *(zval**)zobj->properties_table[property_info->offset] = value; |
| } else { |
| zend_hash_quick_update(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, &value, sizeof(zval *), (void**)&zobj->properties_table[property_info->offset]); |
| } |
| } else { |
| if (!zobj->properties) { |
| rebuild_object_properties(zobj); |
| } |
| zend_hash_quick_update(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, &value, sizeof(zval *), NULL); |
| } |
} else if (zobj->ce->__set && guard && guard->in_set == 1) { |
} else if (zobj->ce->__set && guard && guard->in_set == 1) { |
if (Z_STRVAL_P(member)[0] == '\0') { |
if (Z_STRVAL_P(member)[0] == '\0') { |
if (Z_STRLEN_P(member) == 0) { |
if (Z_STRLEN_P(member) == 0) { |
Line 487 static void zend_std_write_property(zval *object, zval
|
Line 624 static void zend_std_write_property(zval *object, zval
|
} |
} |
} |
} |
|
|
if (tmp_member) { | if (UNEXPECTED(tmp_member != NULL)) { |
zval_ptr_dtor(&tmp_member); |
zval_ptr_dtor(&tmp_member); |
} |
} |
} |
} |
Line 498 zval *zend_std_read_dimension(zval *object, zval *offs
|
Line 635 zval *zend_std_read_dimension(zval *object, zval *offs
|
zend_class_entry *ce = Z_OBJCE_P(object); |
zend_class_entry *ce = Z_OBJCE_P(object); |
zval *retval; |
zval *retval; |
|
|
if (instanceof_function_ex(ce, zend_ce_arrayaccess, 1 TSRMLS_CC)) { | if (EXPECTED(instanceof_function_ex(ce, zend_ce_arrayaccess, 1 TSRMLS_CC) != 0)) { |
if(offset == NULL) { |
if(offset == NULL) { |
/* [] construct */ |
/* [] construct */ |
ALLOC_INIT_ZVAL(offset); |
ALLOC_INIT_ZVAL(offset); |
Line 509 zval *zend_std_read_dimension(zval *object, zval *offs
|
Line 646 zval *zend_std_read_dimension(zval *object, zval *offs
|
|
|
zval_ptr_dtor(&offset); |
zval_ptr_dtor(&offset); |
|
|
if (!retval) { | if (UNEXPECTED(!retval)) { |
if (!EG(exception)) { | if (UNEXPECTED(!EG(exception))) { |
zend_error(E_ERROR, "Undefined offset for object of type %s used as array", ce->name); | zend_error_noreturn(E_ERROR, "Undefined offset for object of type %s used as array", ce->name); |
} |
} |
return 0; |
return 0; |
} |
} |
Line 521 zval *zend_std_read_dimension(zval *object, zval *offs
|
Line 658 zval *zend_std_read_dimension(zval *object, zval *offs
|
|
|
return retval; |
return retval; |
} else { |
} else { |
zend_error(E_ERROR, "Cannot use object of type %s as array", ce->name); | zend_error_noreturn(E_ERROR, "Cannot use object of type %s as array", ce->name); |
return 0; |
return 0; |
} |
} |
} |
} |
Line 531 static void zend_std_write_dimension(zval *object, zva
|
Line 668 static void zend_std_write_dimension(zval *object, zva
|
{ |
{ |
zend_class_entry *ce = Z_OBJCE_P(object); |
zend_class_entry *ce = Z_OBJCE_P(object); |
|
|
if (instanceof_function_ex(ce, zend_ce_arrayaccess, 1 TSRMLS_CC)) { | if (EXPECTED(instanceof_function_ex(ce, zend_ce_arrayaccess, 1 TSRMLS_CC) != 0)) { |
if (!offset) { |
if (!offset) { |
ALLOC_INIT_ZVAL(offset); |
ALLOC_INIT_ZVAL(offset); |
} else { |
} else { |
Line 540 static void zend_std_write_dimension(zval *object, zva
|
Line 677 static void zend_std_write_dimension(zval *object, zva
|
zend_call_method_with_2_params(&object, ce, NULL, "offsetset", NULL, offset, value); |
zend_call_method_with_2_params(&object, ce, NULL, "offsetset", NULL, offset, value); |
zval_ptr_dtor(&offset); |
zval_ptr_dtor(&offset); |
} else { |
} else { |
zend_error(E_ERROR, "Cannot use object of type %s as array", ce->name); | zend_error_noreturn(E_ERROR, "Cannot use object of type %s as array", ce->name); |
} |
} |
} |
} |
/* }}} */ |
/* }}} */ |
Line 551 static int zend_std_has_dimension(zval *object, zval *
|
Line 688 static int zend_std_has_dimension(zval *object, zval *
|
zval *retval; |
zval *retval; |
int result; |
int result; |
|
|
if (instanceof_function_ex(ce, zend_ce_arrayaccess, 1 TSRMLS_CC)) { | if (EXPECTED(instanceof_function_ex(ce, zend_ce_arrayaccess, 1 TSRMLS_CC) != 0)) { |
SEPARATE_ARG_IF_REF(offset); |
SEPARATE_ARG_IF_REF(offset); |
zend_call_method_with_1_params(&object, ce, NULL, "offsetexists", &retval, offset); |
zend_call_method_with_1_params(&object, ce, NULL, "offsetexists", &retval, offset); |
if (retval) { | if (EXPECTED(retval != NULL)) { |
result = i_zend_is_true(retval); |
result = i_zend_is_true(retval); |
zval_ptr_dtor(&retval); |
zval_ptr_dtor(&retval); |
if (check_empty && result && !EG(exception)) { | if (check_empty && result && EXPECTED(!EG(exception))) { |
zend_call_method_with_1_params(&object, ce, NULL, "offsetget", &retval, offset); |
zend_call_method_with_1_params(&object, ce, NULL, "offsetget", &retval, offset); |
if (retval) { |
if (retval) { |
result = i_zend_is_true(retval); |
result = i_zend_is_true(retval); |
Line 569 static int zend_std_has_dimension(zval *object, zval *
|
Line 706 static int zend_std_has_dimension(zval *object, zval *
|
} |
} |
zval_ptr_dtor(&offset); |
zval_ptr_dtor(&offset); |
} else { |
} else { |
zend_error(E_ERROR, "Cannot use object of type %s as array", ce->name); | zend_error_noreturn(E_ERROR, "Cannot use object of type %s as array", ce->name); |
return 0; |
return 0; |
} |
} |
return result; |
return result; |
} |
} |
/* }}} */ |
/* }}} */ |
|
|
static zval **zend_std_get_property_ptr_ptr(zval *object, zval *member TSRMLS_DC) /* {{{ */ | static zval **zend_std_get_property_ptr_ptr(zval *object, zval *member, const zend_literal *key TSRMLS_DC) /* {{{ */ |
{ |
{ |
zend_object *zobj; |
zend_object *zobj; |
zval tmp_member; |
zval tmp_member; |
Line 585 static zval **zend_std_get_property_ptr_ptr(zval *obje
|
Line 722 static zval **zend_std_get_property_ptr_ptr(zval *obje
|
|
|
zobj = Z_OBJ_P(object); |
zobj = Z_OBJ_P(object); |
|
|
if (Z_TYPE_P(member) != IS_STRING) { | if (UNEXPECTED(Z_TYPE_P(member) != IS_STRING)) { |
tmp_member = *member; |
tmp_member = *member; |
zval_copy_ctor(&tmp_member); |
zval_copy_ctor(&tmp_member); |
convert_to_string(&tmp_member); |
convert_to_string(&tmp_member); |
member = &tmp_member; |
member = &tmp_member; |
|
key = NULL; |
} |
} |
|
|
#if DEBUG_OBJECT_HANDLERS |
#if DEBUG_OBJECT_HANDLERS |
fprintf(stderr, "Ptr object #%d property: %s\n", Z_OBJ_HANDLE_P(object), Z_STRVAL_P(member)); |
fprintf(stderr, "Ptr object #%d property: %s\n", Z_OBJ_HANDLE_P(object), Z_STRVAL_P(member)); |
#endif |
#endif |
|
|
property_info = zend_get_property_info(zobj->ce, member, (zobj->ce->__get != NULL) TSRMLS_CC); | property_info = zend_get_property_info_quick(zobj->ce, member, (zobj->ce->__get != NULL), key TSRMLS_CC); |
|
|
if (!property_info || zend_hash_quick_find(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, (void **) &retval) == FAILURE) { | if (UNEXPECTED(!property_info) || |
| ((EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0) && |
| property_info->offset >= 0) ? |
| (zobj->properties ? |
| ((retval = (zval**)zobj->properties_table[property_info->offset]) == NULL) : |
| (*(retval = &zobj->properties_table[property_info->offset]) == NULL)) : |
| (UNEXPECTED(!zobj->properties) || |
| UNEXPECTED(zend_hash_quick_find(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, (void **) &retval) == FAILURE)))) { |
zval *new_zval; |
zval *new_zval; |
zend_guard *guard; |
zend_guard *guard; |
|
|
Line 610 static zval **zend_std_get_property_ptr_ptr(zval *obje
|
Line 755 static zval **zend_std_get_property_ptr_ptr(zval *obje
|
|
|
/* zend_error(E_NOTICE, "Undefined property: %s", Z_STRVAL_P(member)); */ |
/* zend_error(E_NOTICE, "Undefined property: %s", Z_STRVAL_P(member)); */ |
Z_ADDREF_P(new_zval); |
Z_ADDREF_P(new_zval); |
zend_hash_quick_update(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, &new_zval, sizeof(zval *), (void **) &retval); | if (EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0) && |
| property_info->offset >= 0) { |
| if (!zobj->properties) { |
| zobj->properties_table[property_info->offset] = new_zval; |
| retval = &zobj->properties_table[property_info->offset]; |
| } else if (zobj->properties_table[property_info->offset]) { |
| *(zval**)zobj->properties_table[property_info->offset] = new_zval; |
| retval = (zval**)zobj->properties_table[property_info->offset]; |
| } else { |
| zend_hash_quick_update(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, &new_zval, sizeof(zval *), (void**)&zobj->properties_table[property_info->offset]); |
| retval = (zval**)zobj->properties_table[property_info->offset]; |
| } |
| } else { |
| if (!zobj->properties) { |
| rebuild_object_properties(zobj); |
| } |
| zend_hash_quick_update(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, &new_zval, sizeof(zval *), (void **) &retval); |
| } |
} else { |
} else { |
/* we do have getter - fail and let it try again with usual get/set */ |
/* we do have getter - fail and let it try again with usual get/set */ |
retval = NULL; |
retval = NULL; |
} |
} |
} |
} |
if (member == &tmp_member) { | if (UNEXPECTED(member == &tmp_member)) { |
zval_dtor(member); |
zval_dtor(member); |
} |
} |
return retval; |
return retval; |
} |
} |
/* }}} */ |
/* }}} */ |
|
|
static void zend_std_unset_property(zval *object, zval *member TSRMLS_DC) /* {{{ */ | static void zend_std_unset_property(zval *object, zval *member, const zend_literal *key TSRMLS_DC) /* {{{ */ |
{ |
{ |
zend_object *zobj; |
zend_object *zobj; |
zval *tmp_member = NULL; |
zval *tmp_member = NULL; |
Line 631 static void zend_std_unset_property(zval *object, zval
|
Line 793 static void zend_std_unset_property(zval *object, zval
|
|
|
zobj = Z_OBJ_P(object); |
zobj = Z_OBJ_P(object); |
|
|
if (Z_TYPE_P(member) != IS_STRING) { | if (UNEXPECTED(Z_TYPE_P(member) != IS_STRING)) { |
ALLOC_ZVAL(tmp_member); |
ALLOC_ZVAL(tmp_member); |
*tmp_member = *member; |
*tmp_member = *member; |
INIT_PZVAL(tmp_member); |
INIT_PZVAL(tmp_member); |
zval_copy_ctor(tmp_member); |
zval_copy_ctor(tmp_member); |
convert_to_string(tmp_member); |
convert_to_string(tmp_member); |
member = tmp_member; |
member = tmp_member; |
|
key = NULL; |
} |
} |
|
|
property_info = zend_get_property_info(zobj->ce, member, (zobj->ce->__unset != NULL) TSRMLS_CC); | property_info = zend_get_property_info_quick(zobj->ce, member, (zobj->ce->__unset != NULL), key TSRMLS_CC); |
|
|
if (!property_info || zend_hash_quick_del(zobj->properties, property_info->name, property_info->name_length+1, property_info->h) == FAILURE) { | if (EXPECTED(property_info != NULL) && |
| EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0) && |
| !zobj->properties && |
| property_info->offset >= 0 && |
| EXPECTED(zobj->properties_table[property_info->offset] != NULL)) { |
| zval_ptr_dtor(&zobj->properties_table[property_info->offset]); |
| zobj->properties_table[property_info->offset] = NULL; |
| } else if (UNEXPECTED(!property_info) || |
| !zobj->properties || |
| UNEXPECTED(zend_hash_quick_del(zobj->properties, property_info->name, property_info->name_length+1, property_info->h) == FAILURE)) { |
zend_guard *guard = NULL; |
zend_guard *guard = NULL; |
|
|
if (zobj->ce->__unset && |
if (zobj->ce->__unset && |
Line 666 static void zend_std_unset_property(zval *object, zval
|
Line 838 static void zend_std_unset_property(zval *object, zval
|
} |
} |
} |
} |
} |
} |
|
} else if (EXPECTED(property_info != NULL) && |
|
EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0) && |
|
property_info->offset >= 0) { |
|
zobj->properties_table[property_info->offset] = NULL; |
} |
} |
|
|
if (tmp_member) { | if (UNEXPECTED(tmp_member != NULL)) { |
zval_ptr_dtor(&tmp_member); |
zval_ptr_dtor(&tmp_member); |
} |
} |
} |
} |
Line 683 static void zend_std_unset_dimension(zval *object, zva
|
Line 859 static void zend_std_unset_dimension(zval *object, zva
|
zend_call_method_with_1_params(&object, ce, NULL, "offsetunset", NULL, offset); |
zend_call_method_with_1_params(&object, ce, NULL, "offsetunset", NULL, offset); |
zval_ptr_dtor(&offset); |
zval_ptr_dtor(&offset); |
} else { |
} else { |
zend_error(E_ERROR, "Cannot use object of type %s as array", ce->name); | zend_error_noreturn(E_ERROR, "Cannot use object of type %s as array", ce->name); |
} |
} |
} |
} |
/* }}} */ |
/* }}} */ |
Line 699 ZEND_API void zend_std_call_user_call(INTERNAL_FUNCTIO
|
Line 875 ZEND_API void zend_std_call_user_call(INTERNAL_FUNCTIO
|
INIT_PZVAL(method_args_ptr); |
INIT_PZVAL(method_args_ptr); |
array_init_size(method_args_ptr, ZEND_NUM_ARGS()); |
array_init_size(method_args_ptr, ZEND_NUM_ARGS()); |
|
|
if (zend_copy_parameters_array(ZEND_NUM_ARGS(), method_args_ptr TSRMLS_CC) == FAILURE) { | if (UNEXPECTED(zend_copy_parameters_array(ZEND_NUM_ARGS(), method_args_ptr TSRMLS_CC) == FAILURE)) { |
zval_dtor(method_args_ptr); |
zval_dtor(method_args_ptr); |
zend_error(E_ERROR, "Cannot get arguments for __call"); | zend_error_noreturn(E_ERROR, "Cannot get arguments for __call"); |
RETURN_FALSE; |
RETURN_FALSE; |
} |
} |
|
|
Line 737 ZEND_API void zend_std_call_user_call(INTERNAL_FUNCTIO
|
Line 913 ZEND_API void zend_std_call_user_call(INTERNAL_FUNCTIO
|
* Returns the function address that should be called, or NULL |
* Returns the function address that should be called, or NULL |
* if no such function exists. |
* if no such function exists. |
*/ |
*/ |
static inline zend_function *zend_check_private_int(zend_function *fbc, zend_class_entry *ce, char *function_name_strval, int function_name_strlen TSRMLS_DC) /* {{{ */ | static inline zend_function *zend_check_private_int(zend_function *fbc, zend_class_entry *ce, char *function_name_strval, int function_name_strlen, ulong hash_value TSRMLS_DC) /* {{{ */ |
{ |
{ |
if (!ce) { |
if (!ce) { |
return 0; |
return 0; |
Line 759 static inline zend_function *zend_check_private_int(ze
|
Line 935 static inline zend_function *zend_check_private_int(ze
|
ce = ce->parent; |
ce = ce->parent; |
while (ce) { |
while (ce) { |
if (ce == EG(scope)) { |
if (ce == EG(scope)) { |
if (zend_hash_find(&ce->function_table, function_name_strval, function_name_strlen+1, (void **) &fbc)==SUCCESS | if (zend_hash_quick_find(&ce->function_table, function_name_strval, function_name_strlen+1, hash_value, (void **) &fbc)==SUCCESS |
&& fbc->op_array.fn_flags & ZEND_ACC_PRIVATE |
&& fbc->op_array.fn_flags & ZEND_ACC_PRIVATE |
&& fbc->common.scope == EG(scope)) { |
&& fbc->common.scope == EG(scope)) { |
return fbc; |
return fbc; |
Line 774 static inline zend_function *zend_check_private_int(ze
|
Line 950 static inline zend_function *zend_check_private_int(ze
|
|
|
ZEND_API int zend_check_private(zend_function *fbc, zend_class_entry *ce, char *function_name_strval, int function_name_strlen TSRMLS_DC) /* {{{ */ |
ZEND_API int zend_check_private(zend_function *fbc, zend_class_entry *ce, char *function_name_strval, int function_name_strlen TSRMLS_DC) /* {{{ */ |
{ |
{ |
return zend_check_private_int(fbc, ce, function_name_strval, function_name_strlen TSRMLS_CC) != NULL; | return zend_check_private_int(fbc, ce, function_name_strval, function_name_strlen, zend_hash_func(function_name_strval, function_name_strlen+1) TSRMLS_CC) != NULL; |
} |
} |
/* }}} */ |
/* }}} */ |
|
|
Line 807 ZEND_API int zend_check_protected(zend_class_entry *ce
|
Line 983 ZEND_API int zend_check_protected(zend_class_entry *ce
|
} |
} |
/* }}} */ |
/* }}} */ |
|
|
static inline zend_class_entry * zend_get_function_root_class(zend_function *fbc) /* {{{ */ |
|
{ |
|
return fbc->common.prototype ? fbc->common.prototype->common.scope : fbc->common.scope; |
|
} |
|
/* }}} */ |
|
|
|
static inline union _zend_function *zend_get_user_call_function(zend_class_entry *ce, const char *method_name, int method_len) /* {{{ */ |
static inline union _zend_function *zend_get_user_call_function(zend_class_entry *ce, const char *method_name, int method_len) /* {{{ */ |
{ |
{ |
zend_internal_function *call_user_call = emalloc(sizeof(zend_internal_function)); |
zend_internal_function *call_user_call = emalloc(sizeof(zend_internal_function)); |
call_user_call->type = ZEND_INTERNAL_FUNCTION; |
call_user_call->type = ZEND_INTERNAL_FUNCTION; |
call_user_call->module = ce->module; | call_user_call->module = (ce->type == ZEND_INTERNAL_CLASS) ? ce->info.internal.module : NULL; |
call_user_call->handler = zend_std_call_user_call; |
call_user_call->handler = zend_std_call_user_call; |
call_user_call->arg_info = NULL; |
call_user_call->arg_info = NULL; |
call_user_call->num_args = 0; |
call_user_call->num_args = 0; |
call_user_call->scope = ce; |
call_user_call->scope = ce; |
call_user_call->fn_flags = ZEND_ACC_CALL_VIA_HANDLER; |
call_user_call->fn_flags = ZEND_ACC_CALL_VIA_HANDLER; |
call_user_call->function_name = estrndup(method_name, method_len); |
call_user_call->function_name = estrndup(method_name, method_len); |
call_user_call->pass_rest_by_reference = 0; |
|
call_user_call->return_reference = ZEND_RETURN_VALUE; |
|
|
|
return (union _zend_function *)call_user_call; |
return (union _zend_function *)call_user_call; |
} |
} |
/* }}} */ |
/* }}} */ |
|
|
static union _zend_function *zend_std_get_method(zval **object_ptr, char *method_name, int method_len TSRMLS_DC) /* {{{ */ | static union _zend_function *zend_std_get_method(zval **object_ptr, char *method_name, int method_len, const zend_literal *key TSRMLS_DC) /* {{{ */ |
{ |
{ |
zend_object *zobj; |
|
zend_function *fbc; |
zend_function *fbc; |
char *lc_method_name; |
|
zval *object = *object_ptr; |
zval *object = *object_ptr; |
|
zend_object *zobj = Z_OBJ_P(object); |
|
ulong hash_value; |
|
char *lc_method_name; |
ALLOCA_FLAG(use_heap) |
ALLOCA_FLAG(use_heap) |
|
|
lc_method_name = do_alloca(method_len+1, use_heap); | if (EXPECTED(key != NULL)) { |
/* Create a zend_copy_str_tolower(dest, src, src_length); */ | lc_method_name = Z_STRVAL(key->constant); |
zend_str_tolower_copy(lc_method_name, method_name, method_len); | hash_value = key->hash_value; |
| } else { |
| lc_method_name = do_alloca(method_len+1, use_heap); |
| /* Create a zend_copy_str_tolower(dest, src, src_length); */ |
| zend_str_tolower_copy(lc_method_name, method_name, method_len); |
| hash_value = zend_hash_func(lc_method_name, method_len+1); |
| } |
|
|
zobj = Z_OBJ_P(object); | if (UNEXPECTED(zend_hash_quick_find(&zobj->ce->function_table, lc_method_name, method_len+1, hash_value, (void **)&fbc) == FAILURE)) { |
if (zend_hash_find(&zobj->ce->function_table, lc_method_name, method_len+1, (void **)&fbc) == FAILURE) { | if (UNEXPECTED(!key)) { |
free_alloca(lc_method_name, use_heap); | free_alloca(lc_method_name, use_heap); |
| } |
if (zobj->ce->__call) { |
if (zobj->ce->__call) { |
return zend_get_user_call_function(zobj->ce, method_name, method_len); |
return zend_get_user_call_function(zobj->ce, method_name, method_len); |
} else { |
} else { |
Line 860 static union _zend_function *zend_std_get_method(zval
|
Line 1036 static union _zend_function *zend_std_get_method(zval
|
/* Ensure that if we're calling a private function, we're allowed to do so. |
/* Ensure that if we're calling a private function, we're allowed to do so. |
* If we're not and __call() handler exists, invoke it, otherwise error out. |
* If we're not and __call() handler exists, invoke it, otherwise error out. |
*/ |
*/ |
updated_fbc = zend_check_private_int(fbc, Z_OBJ_HANDLER_P(object, get_class_entry)(object TSRMLS_CC), lc_method_name, method_len TSRMLS_CC); | updated_fbc = zend_check_private_int(fbc, Z_OBJ_HANDLER_P(object, get_class_entry)(object TSRMLS_CC), lc_method_name, method_len, hash_value TSRMLS_CC); |
if (updated_fbc) { | if (EXPECTED(updated_fbc != NULL)) { |
fbc = updated_fbc; |
fbc = updated_fbc; |
} else { |
} else { |
if (zobj->ce->__call) { |
if (zobj->ce->__call) { |
fbc = zend_get_user_call_function(zobj->ce, method_name, method_len); |
fbc = zend_get_user_call_function(zobj->ce, method_name, method_len); |
} else { |
} else { |
zend_error(E_ERROR, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), method_name, EG(scope) ? EG(scope)->name : ""); | zend_error_noreturn(E_ERROR, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), method_name, EG(scope) ? EG(scope)->name : ""); |
} |
} |
} |
} |
} else { |
} else { |
Line 879 static union _zend_function *zend_std_get_method(zval
|
Line 1055 static union _zend_function *zend_std_get_method(zval
|
fbc->op_array.fn_flags & ZEND_ACC_CHANGED) { |
fbc->op_array.fn_flags & ZEND_ACC_CHANGED) { |
zend_function *priv_fbc; |
zend_function *priv_fbc; |
|
|
if (zend_hash_find(&EG(scope)->function_table, lc_method_name, method_len+1, (void **) &priv_fbc)==SUCCESS | if (zend_hash_quick_find(&EG(scope)->function_table, lc_method_name, method_len+1, hash_value, (void **) &priv_fbc)==SUCCESS |
&& priv_fbc->common.fn_flags & ZEND_ACC_PRIVATE |
&& priv_fbc->common.fn_flags & ZEND_ACC_PRIVATE |
&& priv_fbc->common.scope == EG(scope)) { |
&& priv_fbc->common.scope == EG(scope)) { |
fbc = priv_fbc; |
fbc = priv_fbc; |
Line 889 static union _zend_function *zend_std_get_method(zval
|
Line 1065 static union _zend_function *zend_std_get_method(zval
|
/* Ensure that if we're calling a protected function, we're allowed to do so. |
/* Ensure that if we're calling a protected function, we're allowed to do so. |
* If we're not and __call() handler exists, invoke it, otherwise error out. |
* If we're not and __call() handler exists, invoke it, otherwise error out. |
*/ |
*/ |
if (!zend_check_protected(zend_get_function_root_class(fbc), EG(scope))) { | if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(fbc), EG(scope)))) { |
if (zobj->ce->__call) { |
if (zobj->ce->__call) { |
fbc = zend_get_user_call_function(zobj->ce, method_name, method_len); |
fbc = zend_get_user_call_function(zobj->ce, method_name, method_len); |
} else { |
} else { |
zend_error(E_ERROR, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), method_name, EG(scope) ? EG(scope)->name : ""); | zend_error_noreturn(E_ERROR, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), method_name, EG(scope) ? EG(scope)->name : ""); |
} |
} |
} |
} |
} |
} |
} |
} |
|
|
free_alloca(lc_method_name, use_heap); | if (UNEXPECTED(!key)) { |
| free_alloca(lc_method_name, use_heap); |
| } |
return fbc; |
return fbc; |
} |
} |
/* }}} */ |
/* }}} */ |
Line 915 ZEND_API void zend_std_callstatic_user_call(INTERNAL_F
|
Line 1093 ZEND_API void zend_std_callstatic_user_call(INTERNAL_F
|
INIT_PZVAL(method_args_ptr); |
INIT_PZVAL(method_args_ptr); |
array_init_size(method_args_ptr, ZEND_NUM_ARGS()); |
array_init_size(method_args_ptr, ZEND_NUM_ARGS()); |
|
|
if (zend_copy_parameters_array(ZEND_NUM_ARGS(), method_args_ptr TSRMLS_CC) == FAILURE) { | if (UNEXPECTED(zend_copy_parameters_array(ZEND_NUM_ARGS(), method_args_ptr TSRMLS_CC) == FAILURE)) { |
zval_dtor(method_args_ptr); |
zval_dtor(method_args_ptr); |
zend_error(E_ERROR, "Cannot get arguments for " ZEND_CALLSTATIC_FUNC_NAME); | zend_error_noreturn(E_ERROR, "Cannot get arguments for " ZEND_CALLSTATIC_FUNC_NAME); |
RETURN_FALSE; |
RETURN_FALSE; |
} |
} |
|
|
Line 952 static inline union _zend_function *zend_get_user_call
|
Line 1130 static inline union _zend_function *zend_get_user_call
|
{ |
{ |
zend_internal_function *callstatic_user_call = emalloc(sizeof(zend_internal_function)); |
zend_internal_function *callstatic_user_call = emalloc(sizeof(zend_internal_function)); |
callstatic_user_call->type = ZEND_INTERNAL_FUNCTION; |
callstatic_user_call->type = ZEND_INTERNAL_FUNCTION; |
callstatic_user_call->module = ce->module; | callstatic_user_call->module = (ce->type == ZEND_INTERNAL_CLASS) ? ce->info.internal.module : NULL; |
callstatic_user_call->handler = zend_std_callstatic_user_call; |
callstatic_user_call->handler = zend_std_callstatic_user_call; |
callstatic_user_call->arg_info = NULL; |
callstatic_user_call->arg_info = NULL; |
callstatic_user_call->num_args = 0; |
callstatic_user_call->num_args = 0; |
callstatic_user_call->scope = ce; |
callstatic_user_call->scope = ce; |
callstatic_user_call->fn_flags = ZEND_ACC_STATIC | ZEND_ACC_PUBLIC | ZEND_ACC_CALL_VIA_HANDLER; |
callstatic_user_call->fn_flags = ZEND_ACC_STATIC | ZEND_ACC_PUBLIC | ZEND_ACC_CALL_VIA_HANDLER; |
callstatic_user_call->function_name = estrndup(method_name, method_len); |
callstatic_user_call->function_name = estrndup(method_name, method_len); |
callstatic_user_call->pass_rest_by_reference = 0; |
|
callstatic_user_call->return_reference = ZEND_RETURN_VALUE; |
|
|
|
return (zend_function *)callstatic_user_call; |
return (zend_function *)callstatic_user_call; |
} |
} |
Line 968 static inline union _zend_function *zend_get_user_call
|
Line 1144 static inline union _zend_function *zend_get_user_call
|
|
|
/* This is not (yet?) in the API, but it belongs in the built-in objects callbacks */ |
/* This is not (yet?) in the API, but it belongs in the built-in objects callbacks */ |
|
|
ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, char *function_name_strval, int function_name_strlen TSRMLS_DC) /* {{{ */ | ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, const char *function_name_strval, int function_name_strlen, const zend_literal *key TSRMLS_DC) /* {{{ */ |
{ |
{ |
zend_function *fbc = NULL; |
zend_function *fbc = NULL; |
char *lc_class_name, *lc_function_name = NULL; |
char *lc_class_name, *lc_function_name = NULL; |
| ulong hash_value; |
lc_function_name = zend_str_tolower_dup(function_name_strval, function_name_strlen); | ALLOCA_FLAG(use_heap) |
|
|
|
if (EXPECTED(key != NULL)) { |
|
lc_function_name = Z_STRVAL(key->constant); |
|
hash_value = key->hash_value; |
|
} else { |
|
lc_function_name = do_alloca(function_name_strlen+1, use_heap); |
|
/* Create a zend_copy_str_tolower(dest, src, src_length); */ |
|
zend_str_tolower_copy(lc_function_name, function_name_strval, function_name_strlen); |
|
hash_value = zend_hash_func(lc_function_name, function_name_strlen+1); |
|
} |
|
|
if (function_name_strlen == ce->name_length && ce->constructor) { |
if (function_name_strlen == ce->name_length && ce->constructor) { |
lc_class_name = zend_str_tolower_dup(ce->name, ce->name_length); |
lc_class_name = zend_str_tolower_dup(ce->name, ce->name_length); |
/* Only change the method to the constructor if the constructor isn't called __construct |
/* Only change the method to the constructor if the constructor isn't called __construct |
Line 985 ZEND_API zend_function *zend_std_get_static_method(zen
|
Line 1171 ZEND_API zend_function *zend_std_get_static_method(zen
|
} |
} |
efree(lc_class_name); |
efree(lc_class_name); |
} |
} |
if (!fbc && zend_hash_find(&ce->function_table, lc_function_name, function_name_strlen+1, (void **) &fbc)==FAILURE) { | if (EXPECTED(!fbc) && |
efree(lc_function_name); | UNEXPECTED(zend_hash_quick_find(&ce->function_table, lc_function_name, function_name_strlen+1, hash_value, (void **) &fbc)==FAILURE)) { |
| if (UNEXPECTED(!key)) { |
| free_alloca(lc_function_name, use_heap); |
| } |
|
|
if (ce->__call && |
if (ce->__call && |
EG(This) && |
EG(This) && |
Line 999 ZEND_API zend_function *zend_std_get_static_method(zen
|
Line 1188 ZEND_API zend_function *zend_std_get_static_method(zen
|
return NULL; |
return NULL; |
} |
} |
} |
} |
efree(lc_function_name); |
|
|
|
#if MBO_0 |
#if MBO_0 |
/* right now this function is used for non static method lookup too */ |
/* right now this function is used for non static method lookup too */ |
/* Is the function static */ |
/* Is the function static */ |
if (!(fbc->common.fn_flags & ZEND_ACC_STATIC)) { | if (UNEXPECTED(!(fbc->common.fn_flags & ZEND_ACC_STATIC))) { |
zend_error(E_ERROR, "Cannot call non static method %s::%s() without object", ZEND_FN_SCOPE_NAME(fbc), fbc->common.function_name); | zend_error_noreturn(E_ERROR, "Cannot call non static method %s::%s() without object", ZEND_FN_SCOPE_NAME(fbc), fbc->common.function_name); |
} |
} |
#endif | #endif |
if (fbc->op_array.fn_flags & ZEND_ACC_PUBLIC) { |
if (fbc->op_array.fn_flags & ZEND_ACC_PUBLIC) { |
/* No further checks necessary, most common case */ |
/* No further checks necessary, most common case */ |
} else if (fbc->op_array.fn_flags & ZEND_ACC_PRIVATE) { |
} else if (fbc->op_array.fn_flags & ZEND_ACC_PRIVATE) { |
Line 1015 ZEND_API zend_function *zend_std_get_static_method(zen
|
Line 1203 ZEND_API zend_function *zend_std_get_static_method(zen
|
|
|
/* Ensure that if we're calling a private function, we're allowed to do so. |
/* Ensure that if we're calling a private function, we're allowed to do so. |
*/ |
*/ |
updated_fbc = zend_check_private_int(fbc, EG(scope), function_name_strval, function_name_strlen TSRMLS_CC); | updated_fbc = zend_check_private_int(fbc, EG(scope), lc_function_name, function_name_strlen, hash_value TSRMLS_CC); |
if (updated_fbc) { | if (EXPECTED(updated_fbc != NULL)) { |
fbc = updated_fbc; |
fbc = updated_fbc; |
} else { |
} else { |
if (ce->__callstatic) { |
if (ce->__callstatic) { |
return zend_get_user_callstatic_function(ce, function_name_strval, function_name_strlen); | fbc = zend_get_user_callstatic_function(ce, function_name_strval, function_name_strlen); |
| } else { |
| zend_error_noreturn(E_ERROR, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), function_name_strval, EG(scope) ? EG(scope)->name : ""); |
} |
} |
zend_error(E_ERROR, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), function_name_strval, EG(scope) ? EG(scope)->name : ""); |
|
} |
} |
} else if ((fbc->common.fn_flags & ZEND_ACC_PROTECTED)) { |
} else if ((fbc->common.fn_flags & ZEND_ACC_PROTECTED)) { |
/* Ensure that if we're calling a protected function, we're allowed to do so. |
/* Ensure that if we're calling a protected function, we're allowed to do so. |
*/ |
*/ |
if (!zend_check_protected(zend_get_function_root_class(fbc), EG(scope))) { | if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(fbc), EG(scope)))) { |
if (ce->__callstatic) { |
if (ce->__callstatic) { |
return zend_get_user_callstatic_function(ce, function_name_strval, function_name_strlen); | fbc = zend_get_user_callstatic_function(ce, function_name_strval, function_name_strlen); |
| } else { |
| zend_error_noreturn(E_ERROR, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), function_name_strval, EG(scope) ? EG(scope)->name : ""); |
} |
} |
zend_error(E_ERROR, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), function_name_strval, EG(scope) ? EG(scope)->name : ""); |
|
} |
} |
} |
} |
|
|
|
if (UNEXPECTED(!key)) { |
|
free_alloca(lc_function_name, use_heap); |
|
} |
|
|
return fbc; |
return fbc; |
} |
} |
/* }}} */ |
/* }}} */ |
|
|
ZEND_API zval **zend_std_get_static_property(zend_class_entry *ce, char *property_name, int property_name_len, zend_bool silent TSRMLS_DC) /* {{{ */ | ZEND_API zval **zend_std_get_static_property(zend_class_entry *ce, const char *property_name, int property_name_len, zend_bool silent, const zend_literal *key TSRMLS_DC) /* {{{ */ |
{ |
{ |
zval **retval = NULL; |
|
zend_class_entry *tmp_ce = ce; |
|
zend_property_info *property_info; |
zend_property_info *property_info; |
zend_property_info std_property_info; | ulong hash_value; |
|
|
if (zend_hash_find(&ce->properties_info, property_name, property_name_len+1, (void **) &property_info)==FAILURE) { | if (UNEXPECTED(!key) || |
std_property_info.flags = ZEND_ACC_PUBLIC; | (property_info = CACHED_POLYMORPHIC_PTR(key->cache_slot, ce)) == NULL) { |
std_property_info.name = property_name; | if (EXPECTED(key != NULL)) { |
std_property_info.name_length = property_name_len; | hash_value = key->hash_value; |
std_property_info.h = zend_get_hash_value(std_property_info.name, std_property_info.name_length+1); | } else { |
std_property_info.ce = ce; | hash_value = zend_hash_func(property_name, property_name_len+1); |
property_info = &std_property_info; | } |
} | |
|
|
|
if (UNEXPECTED(zend_hash_quick_find(&ce->properties_info, property_name, property_name_len+1, hash_value, (void **) &property_info)==FAILURE)) { |
|
if (!silent) { |
|
zend_error_noreturn(E_ERROR, "Access to undeclared static property: %s::$%s", ce->name, property_name); |
|
} |
|
return NULL; |
|
} |
|
|
#if DEBUG_OBJECT_HANDLERS |
#if DEBUG_OBJECT_HANDLERS |
zend_printf("Access type for %s::%s is %s\n", ce->name, property_name, zend_visibility_string(property_info->flags)); | zend_printf("Access type for %s::%s is %s\n", ce->name, property_name, zend_visibility_string(property_info->flags)); |
#endif |
#endif |
|
|
if (!zend_verify_property_access(property_info, ce TSRMLS_CC)) { | if (UNEXPECTED(!zend_verify_property_access(property_info, ce TSRMLS_CC))) { |
if (!silent) { | if (!silent) { |
zend_error(E_ERROR, "Cannot access %s property %s::$%s", zend_visibility_string(property_info->flags), ce->name, property_name); | zend_error_noreturn(E_ERROR, "Cannot access %s property %s::$%s", zend_visibility_string(property_info->flags), ce->name, property_name); |
| } |
| return NULL; |
} |
} |
return NULL; |
|
} |
|
|
|
zend_update_class_constants(tmp_ce TSRMLS_CC); | if (UNEXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0)) { |
| if (!silent) { |
| zend_error_noreturn(E_ERROR, "Access to undeclared static property: %s::$%s", ce->name, property_name); |
| } |
| return NULL; |
| } |
|
|
zend_hash_quick_find(CE_STATIC_MEMBERS(tmp_ce), property_info->name, property_info->name_length+1, property_info->h, (void **) &retval); | zend_update_class_constants(ce TSRMLS_CC); |
|
|
if (!retval) { | if (EXPECTED(key != NULL)) { |
if (silent) { | CACHE_POLYMORPHIC_PTR(key->cache_slot, ce, property_info); |
return NULL; | |
} else { | |
zend_error(E_ERROR, "Access to undeclared static property: %s::$%s", ce->name, property_name); | |
} |
} |
} |
} |
|
|
return retval; | if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL) || |
| UNEXPECTED(CE_STATIC_MEMBERS(ce)[property_info->offset] == NULL)) { |
| if (!silent) { |
| zend_error_noreturn(E_ERROR, "Access to undeclared static property: %s::$%s", ce->name, property_name); |
| } |
| return NULL; |
| } |
| |
| return &CE_STATIC_MEMBERS(ce)[property_info->offset]; |
} |
} |
/* }}} */ |
/* }}} */ |
|
|
ZEND_API zend_bool zend_std_unset_static_property(zend_class_entry *ce, char *property_name, int property_name_len TSRMLS_DC) /* {{{ */ | ZEND_API zend_bool zend_std_unset_static_property(zend_class_entry *ce, const char *property_name, int property_name_len, const zend_literal *key TSRMLS_DC) /* {{{ */ |
{ |
{ |
zend_error(E_ERROR, "Attempt to unset static property %s::$%s", ce->name, property_name); | zend_error_noreturn(E_ERROR, "Attempt to unset static property %s::$%s", ce->name, property_name); |
return 0; |
return 0; |
} |
} |
/* }}} */ |
/* }}} */ |
Line 1100 ZEND_API union _zend_function *zend_std_get_constructo
|
Line 1308 ZEND_API union _zend_function *zend_std_get_constructo
|
} else if (constructor->op_array.fn_flags & ZEND_ACC_PRIVATE) { |
} else if (constructor->op_array.fn_flags & ZEND_ACC_PRIVATE) { |
/* Ensure that if we're calling a private function, we're allowed to do so. |
/* Ensure that if we're calling a private function, we're allowed to do so. |
*/ |
*/ |
if (constructor->common.scope != EG(scope)) { | if (UNEXPECTED(constructor->common.scope != EG(scope))) { |
if (EG(scope)) { |
if (EG(scope)) { |
zend_error(E_ERROR, "Call to private %s::%s() from context '%s'", constructor->common.scope->name, constructor->common.function_name, EG(scope)->name); | zend_error_noreturn(E_ERROR, "Call to private %s::%s() from context '%s'", constructor->common.scope->name, constructor->common.function_name, EG(scope)->name); |
} else { |
} else { |
zend_error(E_ERROR, "Call to private %s::%s() from invalid context", constructor->common.scope->name, constructor->common.function_name); | zend_error_noreturn(E_ERROR, "Call to private %s::%s() from invalid context", constructor->common.scope->name, constructor->common.function_name); |
} |
} |
} |
} |
} else if ((constructor->common.fn_flags & ZEND_ACC_PROTECTED)) { |
} else if ((constructor->common.fn_flags & ZEND_ACC_PROTECTED)) { |
Line 1112 ZEND_API union _zend_function *zend_std_get_constructo
|
Line 1320 ZEND_API union _zend_function *zend_std_get_constructo
|
* Constructors only have prototype if they are defined by an interface but |
* Constructors only have prototype if they are defined by an interface but |
* it is the compilers responsibility to take care of the prototype. |
* it is the compilers responsibility to take care of the prototype. |
*/ |
*/ |
if (!zend_check_protected(zend_get_function_root_class(constructor), EG(scope))) { | if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(constructor), EG(scope)))) { |
if (EG(scope)) { |
if (EG(scope)) { |
zend_error(E_ERROR, "Call to protected %s::%s() from context '%s'", constructor->common.scope->name, constructor->common.function_name, EG(scope)->name); | zend_error_noreturn(E_ERROR, "Call to protected %s::%s() from context '%s'", constructor->common.scope->name, constructor->common.function_name, EG(scope)->name); |
} else { |
} else { |
zend_error(E_ERROR, "Call to protected %s::%s() from invalid context", constructor->common.scope->name, constructor->common.function_name); | zend_error_noreturn(E_ERROR, "Call to protected %s::%s() from invalid context", constructor->common.scope->name, constructor->common.function_name); |
} |
} |
} |
} |
} |
} |
Line 1138 static int zend_std_compare_objects(zval *o1, zval *o2
|
Line 1346 static int zend_std_compare_objects(zval *o1, zval *o2
|
if (zobj1->ce != zobj2->ce) { |
if (zobj1->ce != zobj2->ce) { |
return 1; /* different classes */ |
return 1; /* different classes */ |
} |
} |
return zend_compare_symbol_tables_i(zobj1->properties, zobj2->properties TSRMLS_CC); | if (!zobj1->properties && !zobj2->properties) { |
| int i; |
| |
| Z_OBJ_PROTECT_RECURSION(o1); |
| Z_OBJ_PROTECT_RECURSION(o2); |
| for (i = 0; i < zobj1->ce->default_properties_count; i++) { |
| if (zobj1->properties_table[i]) { |
| if (zobj2->properties_table[i]) { |
| zval result; |
| |
| if (compare_function(&result, zobj1->properties_table[i], zobj2->properties_table[i] TSRMLS_CC)==FAILURE) { |
| Z_OBJ_UNPROTECT_RECURSION(o1); |
| Z_OBJ_UNPROTECT_RECURSION(o2); |
| return 1; |
| } |
| if (Z_LVAL(result) != 0) { |
| Z_OBJ_UNPROTECT_RECURSION(o1); |
| Z_OBJ_UNPROTECT_RECURSION(o2); |
| return Z_LVAL(result); |
| } |
| } else { |
| Z_OBJ_UNPROTECT_RECURSION(o1); |
| Z_OBJ_UNPROTECT_RECURSION(o2); |
| return 1; |
| } |
| } else { |
| if (zobj2->properties_table[i]) { |
| Z_OBJ_UNPROTECT_RECURSION(o1); |
| Z_OBJ_UNPROTECT_RECURSION(o2); |
| return 1; |
| } else { |
| Z_OBJ_UNPROTECT_RECURSION(o1); |
| Z_OBJ_UNPROTECT_RECURSION(o2); |
| return 0; |
| } |
| } |
| } |
| Z_OBJ_UNPROTECT_RECURSION(o1); |
| Z_OBJ_UNPROTECT_RECURSION(o2); |
| return 0; |
| } else { |
| if (!zobj1->properties) { |
| rebuild_object_properties(zobj1); |
| } |
| if (!zobj2->properties) { |
| rebuild_object_properties(zobj2); |
| } |
| return zend_compare_symbol_tables_i(zobj1->properties, zobj2->properties TSRMLS_CC); |
| } |
} |
} |
/* }}} */ |
/* }}} */ |
|
|
static int zend_std_has_property(zval *object, zval *member, int has_set_exists TSRMLS_DC) /* {{{ */ | static int zend_std_has_property(zval *object, zval *member, int has_set_exists, const zend_literal *key TSRMLS_DC) /* {{{ */ |
{ |
{ |
zend_object *zobj; |
zend_object *zobj; |
int result; |
int result; |
zval **value; | zval **value = NULL; |
zval *tmp_member = NULL; |
zval *tmp_member = NULL; |
zend_property_info *property_info; |
zend_property_info *property_info; |
|
|
zobj = Z_OBJ_P(object); |
zobj = Z_OBJ_P(object); |
|
|
if (Z_TYPE_P(member) != IS_STRING) { | if (UNEXPECTED(Z_TYPE_P(member) != IS_STRING)) { |
ALLOC_ZVAL(tmp_member); |
ALLOC_ZVAL(tmp_member); |
*tmp_member = *member; |
*tmp_member = *member; |
INIT_PZVAL(tmp_member); |
INIT_PZVAL(tmp_member); |
zval_copy_ctor(tmp_member); |
zval_copy_ctor(tmp_member); |
convert_to_string(tmp_member); |
convert_to_string(tmp_member); |
member = tmp_member; |
member = tmp_member; |
|
key = NULL; |
} |
} |
|
|
#if DEBUG_OBJECT_HANDLERS |
#if DEBUG_OBJECT_HANDLERS |
fprintf(stderr, "Read object #%d property: %s\n", Z_OBJ_HANDLE_P(object), Z_STRVAL_P(member)); |
fprintf(stderr, "Read object #%d property: %s\n", Z_OBJ_HANDLE_P(object), Z_STRVAL_P(member)); |
#endif |
#endif |
|
|
property_info = zend_get_property_info(zobj->ce, member, 1 TSRMLS_CC); | property_info = zend_get_property_info_quick(zobj->ce, member, 1, key TSRMLS_CC); |
|
|
if (!property_info || zend_hash_quick_find(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, (void **) &value) == FAILURE) { | if (UNEXPECTED(!property_info) || |
| ((EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0) && |
| property_info->offset >= 0) ? |
| (zobj->properties ? |
| ((value = (zval**)zobj->properties_table[property_info->offset]) == NULL) : |
| (*(value = &zobj->properties_table[property_info->offset]) == NULL)) : |
| (UNEXPECTED(!zobj->properties) || |
| UNEXPECTED(zend_hash_quick_find(zobj->properties, property_info->name, property_info->name_length+1, property_info->h, (void **) &value) == FAILURE)))) { |
zend_guard *guard; |
zend_guard *guard; |
|
|
result = 0; |
result = 0; |
Line 1188 static int zend_std_has_property(zval *object, zval *m
|
Line 1452 static int zend_std_has_property(zval *object, zval *m
|
result = zend_is_true(rv); |
result = zend_is_true(rv); |
zval_ptr_dtor(&rv); |
zval_ptr_dtor(&rv); |
if (has_set_exists && result) { |
if (has_set_exists && result) { |
if (!EG(exception) && zobj->ce->__get && !guard->in_get) { | if (EXPECTED(!EG(exception)) && zobj->ce->__get && !guard->in_get) { |
guard->in_get = 1; |
guard->in_get = 1; |
rv = zend_std_call_getter(object, member TSRMLS_CC); |
rv = zend_std_call_getter(object, member TSRMLS_CC); |
guard->in_get = 0; |
guard->in_get = 0; |
Line 1221 static int zend_std_has_property(zval *object, zval *m
|
Line 1485 static int zend_std_has_property(zval *object, zval *m
|
} |
} |
} |
} |
|
|
if (tmp_member) { | if (UNEXPECTED(tmp_member != NULL)) { |
zval_ptr_dtor(&tmp_member); |
zval_ptr_dtor(&tmp_member); |
} |
} |
return result; |
return result; |
Line 1237 zend_class_entry *zend_std_object_get_class(const zval
|
Line 1501 zend_class_entry *zend_std_object_get_class(const zval
|
} |
} |
/* }}} */ |
/* }}} */ |
|
|
int zend_std_object_get_class_name(const zval *object, char **class_name, zend_uint *class_name_len, int parent TSRMLS_DC) /* {{{ */ | int zend_std_object_get_class_name(const zval *object, const char **class_name, zend_uint *class_name_len, int parent TSRMLS_DC) /* {{{ */ |
{ |
{ |
zend_object *zobj; |
zend_object *zobj; |
zend_class_entry *ce; |
zend_class_entry *ce; |
Line 1268 ZEND_API int zend_std_cast_object_tostring(zval *reado
|
Line 1532 ZEND_API int zend_std_cast_object_tostring(zval *reado
|
ce = Z_OBJCE_P(readobj); |
ce = Z_OBJCE_P(readobj); |
if (ce->__tostring && |
if (ce->__tostring && |
(zend_call_method_with_0_params(&readobj, ce, &ce->__tostring, "__tostring", &retval) || EG(exception))) { |
(zend_call_method_with_0_params(&readobj, ce, &ce->__tostring, "__tostring", &retval) || EG(exception))) { |
if (EG(exception)) { | if (UNEXPECTED(EG(exception) != NULL)) { |
if (retval) { |
if (retval) { |
zval_ptr_dtor(&retval); |
zval_ptr_dtor(&retval); |
} |
} |
zend_error(E_ERROR, "Method %s::__toString() must not throw an exception", ce->name); | EG(exception) = NULL; |
| zend_error_noreturn(E_ERROR, "Method %s::__toString() must not throw an exception", ce->name); |
return FAILURE; |
return FAILURE; |
} |
} |
if (Z_TYPE_P(retval) == IS_STRING) { | if (EXPECTED(Z_TYPE_P(retval) == IS_STRING)) { |
INIT_PZVAL(writeobj); |
INIT_PZVAL(writeobj); |
if (readobj == writeobj) { |
if (readobj == writeobj) { |
zval_dtor(readobj); |
zval_dtor(readobj); |
Line 1382 ZEND_API zend_object_handlers std_object_handlers = {
|
Line 1647 ZEND_API zend_object_handlers std_object_handlers = {
|
NULL, /* count_elements */ |
NULL, /* count_elements */ |
NULL, /* get_debug_info */ |
NULL, /* get_debug_info */ |
zend_std_get_closure, /* get_closure */ |
zend_std_get_closure, /* get_closure */ |
|
zend_std_get_gc, /* get_gc */ |
}; |
}; |
|
|
/* |
/* |