diff options
Diffstat (limited to 'Zend/zend_API.c')
-rw-r--r-- | Zend/zend_API.c | 190 |
1 files changed, 69 insertions, 121 deletions
diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 516753fdf7..357368f88d 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -45,67 +45,6 @@ static zend_module_entry **module_post_deactivate_handlers; static zend_class_entry **class_cleanup_handlers; -/* this function doesn't check for too many parameters */ -ZEND_API int zend_get_parameters(int ht, int param_count, ...) /* {{{ */ -{ - int arg_count; - va_list ptr; - zval **param, *param_ptr; - - param_ptr = ZEND_CALL_ARG(EG(current_execute_data), 1); - arg_count = ZEND_CALL_NUM_ARGS(EG(current_execute_data)); - - if (param_count>arg_count) { - return FAILURE; - } - - va_start(ptr, param_count); - - while (param_count-->0) { - param = va_arg(ptr, zval **); - if (!Z_ISREF_P(param_ptr) && Z_REFCOUNT_P(param_ptr) > 1) { - zval new_tmp; - - ZVAL_DUP(&new_tmp, param_ptr); - Z_DELREF_P(param_ptr); - ZVAL_COPY_VALUE(param_ptr, &new_tmp); - } - *param = param_ptr; - param_ptr++; - } - va_end(ptr); - - return SUCCESS; -} -/* }}} */ - -/* Zend-optimized Extended functions */ -/* this function doesn't check for too many parameters */ -ZEND_API int zend_get_parameters_ex(int param_count, ...) /* {{{ */ -{ - int arg_count; - va_list ptr; - zval **param, *param_ptr; - - param_ptr = ZEND_CALL_ARG(EG(current_execute_data), 1); - arg_count = ZEND_CALL_NUM_ARGS(EG(current_execute_data)); - - if (param_count>arg_count) { - return FAILURE; - } - - va_start(ptr, param_count); - while (param_count-->0) { - param = va_arg(ptr, zval **); - *param = param_ptr; - param_ptr++; - } - va_end(ptr); - - return SUCCESS; -} -/* }}} */ - ZEND_API int _zend_get_parameters_array_ex(int param_count, zval *argument_array) /* {{{ */ { zval *param_ptr; @@ -141,9 +80,7 @@ ZEND_API int zend_copy_parameters_array(int param_count, zval *argument_array) / } while (param_count-->0) { - if (Z_REFCOUNTED_P(param_ptr)) { - Z_ADDREF_P(param_ptr); - } + Z_TRY_ADDREF_P(param_ptr); zend_hash_next_index_insert_new(Z_ARRVAL_P(argument_array), param_ptr); param_ptr++; } @@ -1084,15 +1021,6 @@ ZEND_API int zend_parse_method_parameters_ex(int flags, int num_args, zval *this } /* }}} */ -/* Argument parsing API -- andrei */ -ZEND_API int _array_init(zval *arg, uint32_t size ZEND_FILE_LINE_DC) /* {{{ */ -{ - ZVAL_NEW_ARR(arg); - _zend_hash_init(Z_ARRVAL_P(arg), size, ZVAL_PTR_DTOR, 0 ZEND_FILE_LINE_RELAY_CC); - return SUCCESS; -} -/* }}} */ - /* This function should be called after the constructor has been called * because it may call __set from the uninitialized object otherwise. */ ZEND_API void zend_merge_properties(zval *obj, HashTable *properties) /* {{{ */ @@ -1136,19 +1064,21 @@ ZEND_API int zend_update_class_constants(zend_class_entry *class_type) /* {{{ */ #endif for (i = 0; i < class_type->default_static_members_count; i++) { p = &class_type->default_static_members_table[i]; - if (Z_ISREF_P(p) && - class_type->parent && - i < class_type->parent->default_static_members_count && - p == &class_type->parent->default_static_members_table[i] && - Z_TYPE(CE_STATIC_MEMBERS(class_type->parent)[i]) != IS_UNDEF - ) { - zval *q = &CE_STATIC_MEMBERS(class_type->parent)[i]; - - ZVAL_NEW_REF(q, q); - ZVAL_COPY_VALUE(&CE_STATIC_MEMBERS(class_type)[i], q); - Z_ADDREF_P(q); + if (Z_ISREF_P(p)) { + if (class_type->parent && + i < class_type->parent->default_static_members_count && + p == &class_type->parent->default_static_members_table[i] && + Z_TYPE(CE_STATIC_MEMBERS(class_type->parent)[i]) != IS_UNDEF + ) { + zval *q = &CE_STATIC_MEMBERS(class_type->parent)[i]; + + ZVAL_NEW_REF(q, q); + ZVAL_COPY(&CE_STATIC_MEMBERS(class_type)[i], q); + } else { + ZVAL_COPY_OR_DUP(&CE_STATIC_MEMBERS(class_type)[i], Z_REFVAL_P(p)); + } } else { - ZVAL_DUP(&CE_STATIC_MEMBERS(class_type)[i], p); + ZVAL_COPY_OR_DUP(&CE_STATIC_MEMBERS(class_type)[i], p); } } } else { @@ -1159,7 +1089,7 @@ ZEND_API int zend_update_class_constants(zend_class_entry *class_type) /* {{{ */ ZEND_HASH_FOREACH_PTR(&class_type->constants_table, c) { val = &c->value; - if (Z_CONSTANT_P(val)) { + if (Z_TYPE_P(val) == IS_CONSTANT_AST) { if (UNEXPECTED(zval_update_constant_ex(val, c->ce) != SUCCESS)) { return FAILURE; } @@ -1176,7 +1106,7 @@ ZEND_API int zend_update_class_constants(zend_class_entry *class_type) /* {{{ */ val = (zval*)((char*)class_type->default_properties_table + prop_info->offset - OBJ_PROP_TO_OFFSET(0)); } ZVAL_DEREF(val); - if (Z_CONSTANT_P(val)) { + if (Z_TYPE_P(val) == IS_CONSTANT_AST) { if (UNEXPECTED(zval_update_constant_ex(val, ce) != SUCCESS)) { return FAILURE; } @@ -1200,15 +1130,19 @@ ZEND_API void object_properties_init(zend_object *object, zend_class_entry *clas zval *dst = object->properties_table; zval *end = src + class_type->default_properties_count; - do { -#if ZTS - ZVAL_DUP(dst, src); -#else - ZVAL_COPY(dst, src); -#endif - src++; - dst++; - } while (src != end); + if (UNEXPECTED(class_type->type == ZEND_INTERNAL_CLASS)) { + do { + ZVAL_COPY_OR_DUP(dst, src); + src++; + dst++; + } while (src != end); + } else { + do { + ZVAL_COPY(dst, src); + src++; + dst++; + } while (src != end); + } object->properties = NULL; } } @@ -1690,9 +1624,7 @@ ZEND_API int array_set_zval_key(HashTable *ht, zval *key, zval *value) /* {{{ */ } if (result) { - if (Z_REFCOUNTED_P(result)) { - Z_ADDREF_P(result); - } + Z_TRY_ADDREF_P(result); return SUCCESS; } else { return FAILURE; @@ -2186,7 +2118,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio while (ptr->fname) { fname_len = strlen(ptr->fname); internal_function->handler = ptr->handler; - internal_function->function_name = zend_new_interned_string(zend_string_init(ptr->fname, fname_len, 1)); + internal_function->function_name = zend_string_init_interned(ptr->fname, fname_len, 1); internal_function->scope = scope; internal_function->prototype = NULL; if (ptr->flags) { @@ -2269,8 +2201,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio return FAILURE; } } - lowercase_name = zend_string_alloc(fname_len, 1); - zend_str_tolower_copy(ZSTR_VAL(lowercase_name), ptr->fname, fname_len); + lowercase_name = zend_string_tolower_ex(internal_function->function_name, 1); lowercase_name = zend_new_interned_string(lowercase_name); reg_function = malloc(sizeof(zend_internal_function)); memcpy(reg_function, &function, sizeof(zend_internal_function)); @@ -2316,7 +2247,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio class_name++; allow_null = 1; } - str = zend_new_interned_string(zend_string_init(class_name, strlen(class_name), 1)); + str = zend_string_init_interned(class_name, strlen(class_name), 1); new_arg_info[i].type = ZEND_TYPE_ENCODE_CLASS(str, allow_null); } } @@ -2578,7 +2509,7 @@ void module_destructor(zend_module_entry *module) /* {{{ */ } module->module_started=0; - if (module->functions) { + if (module->type == MODULE_TEMPORARY && module->functions) { zend_unregister_functions(module->functions, -1, NULL); } @@ -2704,7 +2635,7 @@ ZEND_API int zend_next_free_module(void) /* {{{ */ static zend_class_entry *do_register_internal_class(zend_class_entry *orig_class_entry, uint32_t ce_flags) /* {{{ */ { zend_class_entry *class_entry = malloc(sizeof(zend_class_entry)); - zend_string *lowercase_name = zend_string_alloc(ZSTR_LEN(orig_class_entry->name), 1); + zend_string *lowercase_name; *class_entry = *orig_class_entry; class_entry->type = ZEND_INTERNAL_CLASS; @@ -2716,7 +2647,7 @@ static zend_class_entry *do_register_internal_class(zend_class_entry *orig_class zend_register_functions(class_entry, class_entry->info.internal.builtin_functions, &class_entry->function_table, MODULE_PERSISTENT); } - zend_str_tolower_copy(ZSTR_VAL(lowercase_name), ZSTR_VAL(orig_class_entry->name), ZSTR_LEN(class_entry->name)); + lowercase_name = zend_string_tolower_ex(orig_class_entry->name, 1); lowercase_name = zend_new_interned_string(lowercase_name); zend_hash_update_ptr(CG(class_table), lowercase_name, class_entry); zend_string_release(lowercase_name); @@ -2771,15 +2702,15 @@ ZEND_API zend_class_entry *zend_register_internal_interface(zend_class_entry *or } /* }}} */ -ZEND_API int zend_register_class_alias_ex(const char *name, size_t name_len, zend_class_entry *ce) /* {{{ */ +ZEND_API int zend_register_class_alias_ex(const char *name, size_t name_len, zend_class_entry *ce, int persistent) /* {{{ */ { zend_string *lcname; if (name[0] == '\\') { - lcname = zend_string_alloc(name_len-1, 1); + lcname = zend_string_alloc(name_len-1, persistent); zend_str_tolower_copy(ZSTR_VAL(lcname), name+1, name_len-1); } else { - lcname = zend_string_alloc(name_len, 1); + lcname = zend_string_alloc(name_len, persistent); zend_str_tolower_copy(ZSTR_VAL(lcname), name, name_len); } @@ -2810,9 +2741,7 @@ ZEND_API int zend_set_hash_symbol(zval *symbol, const char *name, int name_lengt while (num_symbol_tables-- > 0) { symbol_table = va_arg(symbol_table_list, HashTable *); zend_hash_str_update(symbol_table, name, name_length, symbol); - if (Z_REFCOUNTED_P(symbol)) { - Z_ADDREF_P(symbol); - } + Z_TRY_ADDREF_P(symbol); } va_end(symbol_table_list); return SUCCESS; @@ -3308,7 +3237,7 @@ try_again: callable = Z_REFVAL_P(callable); goto try_again; default: - return zval_get_string(callable); + return zval_get_string_func(callable); } } /* }}} */ @@ -3571,9 +3500,7 @@ ZEND_API int zend_fcall_info_args_ex(zend_fcall_info *fci, zend_function *func, ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(args), arg) { if (func && !Z_ISREF_P(arg) && ARG_SHOULD_BE_SENT_BY_REF(func, n)) { ZVAL_NEW_REF(params, arg); - if (Z_REFCOUNTED_P(arg)) { - Z_ADDREF_P(arg); - } + Z_TRY_ADDREF_P(arg); } else { ZVAL_COPY(params, arg); } @@ -3688,22 +3615,36 @@ ZEND_API const char *zend_get_module_version(const char *module_name) /* {{{ */ } /* }}} */ +static inline zend_string *zval_make_interned_string(zval *zv) /* {{{ */ +{ + ZEND_ASSERT(Z_TYPE_P(zv) == IS_STRING); + Z_STR_P(zv) = zend_new_interned_string(Z_STR_P(zv)); + if (ZSTR_IS_INTERNED(Z_STR_P(zv))) { + Z_TYPE_FLAGS_P(zv) &= ~ (IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE); + } + return Z_STR_P(zv); +} + ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment) /* {{{ */ { zend_property_info *property_info, *property_info_ptr; if (ce->type == ZEND_INTERNAL_CLASS) { property_info = pemalloc(sizeof(zend_property_info), 1); - if ((access_type & ZEND_ACC_STATIC) || Z_CONSTANT_P(property)) { + if ((access_type & ZEND_ACC_STATIC) || Z_TYPE_P(property) == IS_CONSTANT_AST) { ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; } } else { property_info = zend_arena_alloc(&CG(arena), sizeof(zend_property_info)); - if (Z_CONSTANT_P(property)) { + if (Z_TYPE_P(property) == IS_CONSTANT_AST) { ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; } } + if (Z_TYPE_P(property) == IS_STRING && !ZSTR_IS_INTERNED(Z_STR_P(property))) { + zval_make_interned_string(property); + } + if (!(access_type & ZEND_ACC_PPP_MASK)) { access_type |= ZEND_ACC_PUBLIC; } @@ -3846,6 +3787,10 @@ ZEND_API int zend_declare_class_constant_ex(zend_class_entry *ce, zend_string *n "A class constant must not be called 'class'; it is reserved for class name fetching"); } + if (Z_TYPE_P(value) == IS_STRING && !ZSTR_IS_INTERNED(Z_STR_P(value))) { + zval_make_interned_string(value); + } + if (ce->type == ZEND_INTERNAL_CLASS) { c = pemalloc(sizeof(zend_class_constant), 1); } else { @@ -3855,7 +3800,7 @@ ZEND_API int zend_declare_class_constant_ex(zend_class_entry *ce, zend_string *n Z_ACCESS_FLAGS(c->value) = access_type; c->doc_comment = doc_comment; c->ce = ce; - if (Z_CONSTANT_P(value)) { + if (Z_TYPE_P(value) == IS_CONSTANT_AST) { ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED; } @@ -3872,9 +3817,12 @@ ZEND_API int zend_declare_class_constant(zend_class_entry *ce, const char *name, { int ret; - zend_string *key = zend_string_init(name, name_length, ce->type & ZEND_INTERNAL_CLASS); + zend_string *key; + if (ce->type == ZEND_INTERNAL_CLASS) { - key = zend_new_interned_string(key); + key = zend_string_init_interned(name, name_length, 1); + } else { + key = zend_string_init(name, name_length, 0); } ret = zend_declare_class_constant_ex(ce, key, value, ZEND_ACC_PUBLIC, NULL); zend_string_release(key); |