diff options
| author | Xinchen Hui <laruence@php.net> | 2015-04-02 09:03:48 +0800 |
|---|---|---|
| committer | Xinchen Hui <laruence@php.net> | 2015-04-02 09:03:48 +0800 |
| commit | f8461d4aa31ff12a513a0e0e4d19b160889f279e (patch) | |
| tree | 60ceccb15d58243e98a6eff45e4a506ce04dacb8 /Zend/zend_execute_API.c | |
| parent | ed43b7a5487c7ea245ae5b7ecd4f0a4f349e1b3b (diff) | |
| parent | 53d20140fbe4a5fa4339a7429280b4a964f5791d (diff) | |
| download | php-git-f8461d4aa31ff12a513a0e0e4d19b160889f279e.tar.gz | |
Merge branch 'master' of https://git.php.net/repository/php-src
Diffstat (limited to 'Zend/zend_execute_API.c')
| -rw-r--r-- | Zend/zend_execute_API.c | 160 |
1 files changed, 80 insertions, 80 deletions
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index fc212dbbd7..f6090685d9 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -520,6 +520,7 @@ ZEND_API void _zval_internal_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC) /* {{{ * #define IS_VISITED_CONSTANT 0x80 #define IS_CONSTANT_VISITED(p) (Z_TYPE_P(p) & IS_VISITED_CONSTANT) #define MARK_CONSTANT_VISITED(p) Z_TYPE_INFO_P(p) |= IS_VISITED_CONSTANT +#define RESET_CONSTANT_VISITED(p) Z_TYPE_INFO_P(p) &= ~IS_VISITED_CONSTANT ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_class_entry *scope) /* {{{ */ { @@ -527,7 +528,8 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas char *colon; if (IS_CONSTANT_VISITED(p)) { - zend_error_noreturn(E_ERROR, "Cannot declare self-referencing constant '%s'", Z_STRVAL_P(p)); + zend_error(E_EXCEPTION | E_ERROR, "Cannot declare self-referencing constant '%s'", Z_STRVAL_P(p)); + return FAILURE; } else if (Z_TYPE_P(p) == IS_CONSTANT) { int refcount; @@ -544,22 +546,18 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas } else { ZVAL_EMPTY_STRING(p); } - } else if ((const_value = zend_get_constant_ex(Z_STR_P(p), scope, Z_CONST_FLAGS_P(p))) == NULL) { + } else if (UNEXPECTED((const_value = zend_get_constant_ex(Z_STR_P(p), scope, Z_CONST_FLAGS_P(p))) == NULL)) { char *actual = Z_STRVAL_P(p); - if ((colon = (char*)zend_memrchr(Z_STRVAL_P(p), ':', Z_STRLEN_P(p)))) { + if (UNEXPECTED(EG(exception))) { + RESET_CONSTANT_VISITED(p); + return FAILURE; + } else if ((colon = (char*)zend_memrchr(Z_STRVAL_P(p), ':', Z_STRLEN_P(p)))) { size_t len; - zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(p)); - len = Z_STRLEN_P(p) - ((colon - Z_STRVAL_P(p)) + 1); - if (inline_change) { - zend_string *tmp = zend_string_init(colon + 1, len, 0); - zend_string_release(Z_STR_P(p)); - Z_STR_P(p) = tmp; - } else { - Z_STR_P(p) = zend_string_init(colon + 1, len, 0); - } - Z_TYPE_FLAGS_P(p) = IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE; + zend_error(E_EXCEPTION | E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(p)); + RESET_CONSTANT_VISITED(p); + return FAILURE; } else { zend_string *save = Z_STR_P(p); char *slash; @@ -584,23 +582,25 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas } if ((Z_CONST_FLAGS_P(p) & IS_CONSTANT_UNQUALIFIED) == 0) { if (save->val[0] == '\\') { - zend_error_noreturn(E_ERROR, "Undefined constant '%s'", save->val + 1); + zend_error(E_EXCEPTION | E_ERROR, "Undefined constant '%s'", save->val + 1); } else { - zend_error_noreturn(E_ERROR, "Undefined constant '%s'", save->val); + zend_error(E_EXCEPTION | E_ERROR, "Undefined constant '%s'", save->val); } if (inline_change) { zend_string_release(save); } - save = NULL; - } - zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual); - if (!inline_change) { - ZVAL_STRINGL(p, actual, actual_len); + RESET_CONSTANT_VISITED(p); + return FAILURE; } else { - Z_TYPE_INFO_P(p) = Z_REFCOUNTED_P(p) ? - IS_STRING_EX : IS_INTERNED_STRING_EX; - if (save && save->val != actual) { - zend_string_release(save); + zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'", actual, actual); + if (!inline_change) { + ZVAL_STRINGL(p, actual, actual_len); + } else { + Z_TYPE_INFO_P(p) = Z_REFCOUNTED_P(p) ? + IS_STRING_EX : IS_INTERNED_STRING_EX; + if (save && save->val != actual) { + zend_string_release(save); + } } } } @@ -610,7 +610,10 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas } ZVAL_COPY_VALUE(p, const_value); if (Z_OPT_CONSTANT_P(p)) { - zval_update_constant_ex(p, 1, NULL); + if (UNEXPECTED(zval_update_constant_ex(p, 1, NULL) != SUCCESS)) { + RESET_CONSTANT_VISITED(p); + return FAILURE; + } } zval_opt_copy_ctor(p); } @@ -618,29 +621,16 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas if (Z_REFCOUNTED_P(p)) Z_SET_REFCOUNT_P(p, refcount); } else if (Z_TYPE_P(p) == IS_CONSTANT_AST) { zval tmp; - if (inline_change) { - SEPARATE_ZVAL_NOREF(p); + + if (UNEXPECTED(zend_ast_evaluate(&tmp, Z_ASTVAL_P(p), scope) != SUCCESS)) { + return FAILURE; } - zend_ast_evaluate(&tmp, Z_ASTVAL_P(p), scope); if (inline_change) { - zend_ast_destroy_and_free(Z_ASTVAL_P(p)); - efree_size(Z_AST_P(p), sizeof(zend_ast_ref)); + zval_ptr_dtor(p); } ZVAL_COPY_VALUE(p, &tmp); } - return 0; -} -/* }}} */ - -ZEND_API int zval_update_constant_inline_change(zval *pp, zend_class_entry *scope) /* {{{ */ -{ - return zval_update_constant_ex(pp, 1, scope); -} -/* }}} */ - -ZEND_API int zval_update_constant_no_inline_change(zval *pp, zend_class_entry *scope) /* {{{ */ -{ - return zval_update_constant_ex(pp, 0, scope); + return SUCCESS; } /* }}} */ @@ -1311,50 +1301,59 @@ void zend_unset_timeout(void) /* {{{ */ zend_class_entry *zend_fetch_class(zend_string *class_name, int fetch_type) /* {{{ */ { zend_class_entry *ce; - int use_autoload = (fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD) == 0; - int silent = (fetch_type & ZEND_FETCH_CLASS_SILENT) != 0; - - fetch_type &= ZEND_FETCH_CLASS_MASK; + int fetch_sub_type = fetch_type & ZEND_FETCH_CLASS_MASK; check_fetch_type: - switch (fetch_type) { + switch (fetch_sub_type) { case ZEND_FETCH_CLASS_SELF: - if (!EG(scope)) { - zend_error_noreturn(E_ERROR, "Cannot access self:: when no class scope is active"); + if (UNEXPECTED(!EG(scope))) { + int error_type = (fetch_type & ZEND_FETCH_CLASS_EXCEPTION) ? + (E_EXCEPTION | E_ERROR) : E_ERROR; + zend_error(error_type, "Cannot access self:: when no class scope is active"); } return EG(scope); case ZEND_FETCH_CLASS_PARENT: - if (!EG(scope)) { - zend_error_noreturn(E_ERROR, "Cannot access parent:: when no class scope is active"); + if (UNEXPECTED(!EG(scope))) { + int error_type = (fetch_type & ZEND_FETCH_CLASS_EXCEPTION) ? + (E_EXCEPTION | E_ERROR) : E_ERROR; + zend_error(error_type, "Cannot access parent:: when no class scope is active"); + return NULL; } - if (!EG(scope)->parent) { - zend_error_noreturn(E_ERROR, "Cannot access parent:: when current class scope has no parent"); + if (UNEXPECTED(!EG(scope)->parent)) { + int error_type = (fetch_type & ZEND_FETCH_CLASS_EXCEPTION) ? + (E_EXCEPTION | E_ERROR) : E_ERROR; + zend_error(error_type, "Cannot access parent:: when current class scope has no parent"); } return EG(scope)->parent; case ZEND_FETCH_CLASS_STATIC: - if (!EG(current_execute_data) || !EG(current_execute_data)->called_scope) { - zend_error_noreturn(E_ERROR, "Cannot access static:: when no class scope is active"); + if (UNEXPECTED(!EG(current_execute_data)) || UNEXPECTED(!EG(current_execute_data)->called_scope)) { + int error_type = (fetch_type & ZEND_FETCH_CLASS_EXCEPTION) ? + (E_EXCEPTION | E_ERROR) : E_ERROR; + zend_error(error_type, "Cannot access static:: when no class scope is active"); + return NULL; } return EG(current_execute_data)->called_scope; case ZEND_FETCH_CLASS_AUTO: { - fetch_type = zend_get_class_fetch_type(class_name); - if (fetch_type!=ZEND_FETCH_CLASS_DEFAULT) { + fetch_sub_type = zend_get_class_fetch_type(class_name); + if (UNEXPECTED(fetch_sub_type != ZEND_FETCH_CLASS_DEFAULT)) { goto check_fetch_type; } } break; } - if ((ce = zend_lookup_class_ex(class_name, NULL, use_autoload)) == NULL) { - if (use_autoload) { - if (!silent && !EG(exception)) { - if (fetch_type == ZEND_FETCH_CLASS_INTERFACE) { - zend_error_noreturn(E_ERROR, "Interface '%s' not found", class_name->val); - } else if (fetch_type == ZEND_FETCH_CLASS_TRAIT) { - zend_error_noreturn(E_ERROR, "Trait '%s' not found", class_name->val); - } else { - zend_error_noreturn(E_ERROR, "Class '%s' not found", class_name->val); - } + if (fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD) { + return zend_lookup_class_ex(class_name, NULL, 0); + } else if ((ce = zend_lookup_class_ex(class_name, NULL, 1)) == NULL) { + if (!(fetch_type & ZEND_FETCH_CLASS_SILENT) && !EG(exception)) { + int error_type = (fetch_type & ZEND_FETCH_CLASS_EXCEPTION) ? + (E_EXCEPTION | E_ERROR) : E_ERROR; + if (fetch_sub_type == ZEND_FETCH_CLASS_INTERFACE) { + zend_error(error_type, "Interface '%s' not found", class_name->val); + } else if (fetch_sub_type == ZEND_FETCH_CLASS_TRAIT) { + zend_error(error_type, "Trait '%s' not found", class_name->val); + } else { + zend_error(error_type, "Class '%s' not found", class_name->val); } } return NULL; @@ -1366,18 +1365,19 @@ check_fetch_type: zend_class_entry *zend_fetch_class_by_name(zend_string *class_name, const zval *key, int fetch_type) /* {{{ */ { zend_class_entry *ce; - int use_autoload = (fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD) == 0; - - if ((ce = zend_lookup_class_ex(class_name, key, use_autoload)) == NULL) { - if (use_autoload) { - if ((fetch_type & ZEND_FETCH_CLASS_SILENT) == 0 && !EG(exception)) { - if ((fetch_type & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_INTERFACE) { - zend_error_noreturn(E_ERROR, "Interface '%s' not found", class_name->val); - } else if ((fetch_type & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_TRAIT) { - zend_error_noreturn(E_ERROR, "Trait '%s' not found", class_name->val); - } else { - zend_error_noreturn(E_ERROR, "Class '%s' not found", class_name->val); - } + + if (fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD) { + return zend_lookup_class_ex(class_name, key, 0); + } else if ((ce = zend_lookup_class_ex(class_name, key, 1)) == NULL) { + if ((fetch_type & ZEND_FETCH_CLASS_SILENT) == 0 && !EG(exception)) { + int error_type = (fetch_type & ZEND_FETCH_CLASS_EXCEPTION) ? + (E_EXCEPTION | E_ERROR) : E_ERROR; + if ((fetch_type & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_INTERFACE) { + zend_error(error_type, "Interface '%s' not found", class_name->val); + } else if ((fetch_type & ZEND_FETCH_CLASS_MASK) == ZEND_FETCH_CLASS_TRAIT) { + zend_error(error_type, "Trait '%s' not found", class_name->val); + } else { + zend_error(error_type, "Class '%s' not found", class_name->val); } } return NULL; |
