diff options
Diffstat (limited to 'Zend/zend_compile.c')
-rw-r--r-- | Zend/zend_compile.c | 52 |
1 files changed, 22 insertions, 30 deletions
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 2b2dc9b249..deff0dbe57 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1091,27 +1091,19 @@ static zend_never_inline ZEND_COLD ZEND_NORETURN void do_bind_function_error(zen } } -ZEND_API zend_result do_bind_function(zval *lcname) /* {{{ */ +ZEND_API zend_result do_bind_function(zend_function *func, zval *lcname) /* {{{ */ { - zend_function *function; - zval *rtd_key, *zv; - - rtd_key = lcname + 1; - zv = zend_hash_find_ex(EG(function_table), Z_STR_P(rtd_key), 1); - if (UNEXPECTED(!zv)) { - do_bind_function_error(Z_STR_P(lcname), NULL, 0); + zend_function *added_func = zend_hash_add_ptr(EG(function_table), Z_STR_P(lcname), func); + if (UNEXPECTED(!added_func)) { + do_bind_function_error(Z_STR_P(lcname), &func->op_array, 0); return FAILURE; } - function = (zend_function*)Z_PTR_P(zv); - if (UNEXPECTED(function->common.fn_flags & ZEND_ACC_PRELOADED) - && !(CG(compiler_options) & ZEND_COMPILE_PRELOAD)) { - zv = zend_hash_add(EG(function_table), Z_STR_P(lcname), zv); - } else { - zv = zend_hash_set_bucket_key(EG(function_table), (Bucket*)zv, Z_STR_P(lcname)); + + if (func->op_array.refcount) { + ++*func->op_array.refcount; } - if (UNEXPECTED(!zv)) { - do_bind_function_error(Z_STR_P(lcname), &function->op_array, 0); - return FAILURE; + if (func->common.function_name) { + zend_string_addref(func->common.function_name); } return SUCCESS; } @@ -6954,9 +6946,18 @@ zend_string *zend_begin_method_decl(zend_op_array *op_array, zend_string *name, } /* }}} */ +static uint32_t zend_add_dynamic_func_def(zend_op_array *def) { + zend_op_array *op_array = CG(active_op_array); + uint32_t def_offset = op_array->num_dynamic_func_defs++; + op_array->dynamic_func_defs = erealloc( + op_array->dynamic_func_defs, op_array->num_dynamic_func_defs * sizeof(zend_op_array *)); + op_array->dynamic_func_defs[def_offset] = def; + return def_offset; +} + static void zend_begin_func_decl(znode *result, zend_op_array *op_array, zend_ast_decl *decl, bool toplevel) /* {{{ */ { - zend_string *unqualified_name, *name, *lcname, *key; + zend_string *unqualified_name, *name, *lcname; zend_op *opline; unqualified_name = decl->name; @@ -6992,25 +6993,16 @@ static void zend_begin_func_decl(znode *result, zend_op_array *op_array, zend_as return; } - /* Generate RTD keys until we find one that isn't in use yet. */ - key = NULL; - do { - zend_tmp_string_release(key); - key = zend_build_runtime_definition_key(lcname, decl->start_lineno); - } while (!zend_hash_add_ptr(CG(function_table), key, op_array)); - + uint32_t func_ref = zend_add_dynamic_func_def(op_array); if (op_array->fn_flags & ZEND_ACC_CLOSURE) { opline = zend_emit_op_tmp(result, ZEND_DECLARE_LAMBDA_FUNCTION, NULL, NULL); - opline->extended_value = zend_alloc_cache_slot(); - opline->op1_type = IS_CONST; - LITERAL_STR(opline->op1, key); + opline->op2.num = func_ref; } else { opline = get_next_op(); opline->opcode = ZEND_DECLARE_FUNCTION; opline->op1_type = IS_CONST; LITERAL_STR(opline->op1, zend_string_copy(lcname)); - /* RTD key is placed after lcname literal in op1 */ - zend_add_literal_string(&key); + opline->op2.num = func_ref; } zend_string_release_ex(lcname, 0); } |