diff options
Diffstat (limited to 'Zend/zend_execute_API.c')
-rw-r--r-- | Zend/zend_execute_API.c | 140 |
1 files changed, 56 insertions, 84 deletions
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index a619b3ccf3..8e366ca75c 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -333,7 +333,7 @@ void shutdown_executor(void) /* {{{ */ if (c->flags & CONST_PERSISTENT) { break; } - zval_ptr_dtor(&c->value); + zval_ptr_dtor_nogc(&c->value); if (c->name) { zend_string_release(c->name); } @@ -542,90 +542,64 @@ ZEND_API void _zval_internal_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC) /* {{{ * } /* }}} */ -ZEND_API int zval_update_constant_ex(zval *p, zend_class_entry *scope) /* {{{ */ +ZEND_API int zend_use_undefined_constant(zend_string *name, zend_ast_attr attr, zval *result) /* {{{ */ { - zval *const_value; char *colon; - zend_bool inline_change; - if (Z_TYPE_P(p) == IS_CONSTANT) { - if (IS_CONSTANT_VISITED(p)) { - zend_throw_error(NULL, "Cannot declare self-referencing constant '%s'", Z_STRVAL_P(p)); + if (UNEXPECTED(EG(exception))) { + return FAILURE; + } else if ((colon = (char*)zend_memrchr(ZSTR_VAL(name), ':', ZSTR_LEN(name)))) { + zend_throw_error(NULL, "Undefined class constant '%s'", ZSTR_VAL(name)); + return FAILURE; + } else if ((attr & IS_CONSTANT_UNQUALIFIED) == 0) { + zend_throw_error(NULL, "Undefined constant '%s'", ZSTR_VAL(name)); + return FAILURE; + } else { + char *actual = ZSTR_VAL(name); + size_t actual_len = ZSTR_LEN(name); + char *slash = (char *) zend_memrchr(actual, '\\', actual_len); + + if (slash) { + actual = slash + 1; + actual_len -= (actual - ZSTR_VAL(name)); + } + + zend_error(E_WARNING, "Use of undefined constant %s - assumed '%s' (this will throw an Error in a future version of PHP)", actual, actual); + if (EG(exception)) { return FAILURE; + } else { + zend_string *result_str = zend_string_init(actual, actual_len, 0); + zval_ptr_dtor_nogc(result); + ZVAL_NEW_STR(result, result_str); } - inline_change = (Z_TYPE_FLAGS_P(p) & IS_TYPE_REFCOUNTED) != 0; - SEPARATE_ZVAL_NOREF(p); - MARK_CONSTANT_VISITED(p); - if (Z_CONST_FLAGS_P(p) & IS_CONSTANT_CLASS) { - ZEND_ASSERT(EG(current_execute_data)); - if (inline_change) { - zend_string_release(Z_STR_P(p)); - } - if (scope && scope->name) { - ZVAL_STR_COPY(p, scope->name); - } else { - ZVAL_EMPTY_STRING(p); - } - } else if (UNEXPECTED((const_value = zend_get_constant_ex(Z_STR_P(p), scope, Z_CONST_FLAGS_P(p))) == NULL)) { - if (UNEXPECTED(EG(exception))) { - RESET_CONSTANT_VISITED(p); - return FAILURE; - } else if ((colon = (char*)zend_memrchr(Z_STRVAL_P(p), ':', Z_STRLEN_P(p)))) { - zend_throw_error(NULL, "Undefined class constant '%s'", Z_STRVAL_P(p)); - RESET_CONSTANT_VISITED(p); - return FAILURE; - } else { - if ((Z_CONST_FLAGS_P(p) & IS_CONSTANT_UNQUALIFIED) == 0) { - zend_throw_error(NULL, "Undefined constant '%s'", Z_STRVAL_P(p)); - RESET_CONSTANT_VISITED(p); - return FAILURE; - } else { - zend_string *save = Z_STR_P(p); - char *actual = Z_STRVAL_P(p); - size_t actual_len = Z_STRLEN_P(p); - char *slash = (char *) zend_memrchr(actual, '\\', actual_len); - if (slash) { - actual = slash + 1; - actual_len -= (actual - Z_STRVAL_P(p)); - } + } + return SUCCESS; +} +/* }}} */ - zend_error(E_WARNING, "Use of undefined constant %s - assumed '%s' (this will throw an Error in a future version of PHP)", actual, actual); - if (EG(exception)) { - RESET_CONSTANT_VISITED(p); - return FAILURE; - } +ZEND_API int zval_update_constant_ex(zval *p, zend_class_entry *scope) /* {{{ */ +{ + if (Z_TYPE_P(p) == IS_CONSTANT_AST) { + zend_ast *ast = Z_ASTVAL_P(p); - if (!inline_change) { - ZVAL_STRINGL(p, actual, actual_len); - } else { - if (slash) { - ZVAL_STRINGL(p, actual, actual_len); - zend_string_release(save); - } else { - Z_TYPE_INFO_P(p) = Z_REFCOUNTED_P(p) ? - IS_STRING_EX : IS_INTERNED_STRING_EX; - } - } - } + if (ast->kind == ZEND_AST_CONSTANT) { + zend_string *name = zend_ast_get_constant_name(ast); + zval *zv = zend_get_constant_ex(name, scope, ast->attr); + + if (UNEXPECTED(zv == NULL)) { + return zend_use_undefined_constant(name, ast->attr, p); } + zval_ptr_dtor_nogc(p); + ZVAL_COPY_OR_DUP(p, zv); } else { - if (inline_change) { - zend_string_release(Z_STR_P(p)); - } - ZVAL_COPY_VALUE(p, const_value); - zval_opt_copy_ctor(p); - } - } else if (Z_TYPE_P(p) == IS_CONSTANT_AST) { - zval tmp; + zval tmp; - inline_change = (Z_TYPE_FLAGS_P(p) & IS_TYPE_REFCOUNTED) != 0; - if (UNEXPECTED(zend_ast_evaluate(&tmp, Z_ASTVAL_P(p), scope) != SUCCESS)) { - return FAILURE; - } - if (inline_change) { - zval_ptr_dtor(p); + if (UNEXPECTED(zend_ast_evaluate(&tmp, ast, scope) != SUCCESS)) { + return FAILURE; + } + zval_ptr_dtor_nogc(p); + ZVAL_COPY_VALUE(p, &tmp); } - ZVAL_COPY_VALUE(p, &tmp); } return SUCCESS; } @@ -801,7 +775,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) / uint32_t call_info; ZEND_ASSERT(GC_TYPE((zend_object*)func->op_array.prototype) == IS_OBJECT); - GC_REFCOUNT((zend_object*)func->op_array.prototype)++; + GC_ADDREF((zend_object*)func->op_array.prototype); call_info = ZEND_CALL_CLOSURE; if (func->common.fn_flags & ZEND_ACC_FAKE_CLOSURE) { call_info |= ZEND_CALL_FAKE_CLOSURE; @@ -932,9 +906,9 @@ ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *k } if (!EG(autoload_func)) { - zend_function *func = zend_hash_find_ptr(EG(function_table), ZSTR_KNOWN(ZEND_STR_MAGIC_AUTOLOAD)); - if (func) { - EG(autoload_func) = func; + zval *zv = zend_hash_find_ex(EG(function_table), ZSTR_KNOWN(ZEND_STR_MAGIC_AUTOLOAD), 1); + if (zv) { + EG(autoload_func) = (zend_function*)Z_PTR_P(zv); } else { if (!key) { zend_string_release(lc_name); @@ -1052,7 +1026,7 @@ ZEND_API int zend_eval_stringl(char *str, size_t str_len, zval *retval_ptr, char int retval; if (retval_ptr) { - ZVAL_NEW_STR(&pv, zend_string_alloc(str_len + sizeof("return ;")-1, 1)); + ZVAL_NEW_STR(&pv, zend_string_alloc(str_len + sizeof("return ;")-1, 0)); memcpy(Z_STRVAL(pv), "return ", sizeof("return ") - 1); memcpy(Z_STRVAL(pv) + sizeof("return ") - 1, str, str_len); Z_STRVAL(pv)[Z_STRLEN(pv) - 1] = ';'; @@ -1527,8 +1501,7 @@ ZEND_API zend_array *zend_rebuild_symbol_table(void) /* {{{ */ } zend_hash_extend(symbol_table, ex->func->op_array.last_var, 0); } else { - symbol_table = ex->symbol_table = emalloc(sizeof(zend_array)); - zend_hash_init(symbol_table, ex->func->op_array.last_var, NULL, ZVAL_PTR_DTOR, 0); + symbol_table = ex->symbol_table = zend_new_array(ex->func->op_array.last_var); if (!ex->func->op_array.last_var) { return symbol_table; } @@ -1563,7 +1536,7 @@ ZEND_API void zend_attach_symbol_table(zend_execute_data *execute_data) /* {{{ * zval *var = EX_VAR_NUM(0); do { - zval *zv = zend_hash_find(ht, *str); + zval *zv = zend_hash_find_ex(ht, *str, 1); if (zv) { if (Z_TYPE_P(zv) == IS_INDIRECT) { @@ -1629,8 +1602,7 @@ ZEND_API int zend_set_local_var(zend_string *name, zval *value, int force) /* {{ do { if (ZSTR_H(*str) == h && - ZSTR_LEN(*str) == ZSTR_LEN(name) && - memcmp(ZSTR_VAL(*str), ZSTR_VAL(name), ZSTR_LEN(name)) == 0) { + zend_string_equal_content(*str, name)) { zval *var = EX_VAR_NUM(str - op_array->vars); ZVAL_COPY_VALUE(var, value); return SUCCESS; |