diff options
author | Dmitry Stogov <dmitry@zend.com> | 2016-04-28 04:13:34 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2016-04-28 04:13:34 +0300 |
commit | 6499162ff0d8aa6e862d3e3cdd2288b87636b8a1 (patch) | |
tree | b1de28564ceb5249bd207a6291fff0ab3dac877f /Zend/zend_execute_API.c | |
parent | 8339222106ac38090e9790f1abbbe2c70c1840fd (diff) | |
download | php-git-6499162ff0d8aa6e862d3e3cdd2288b87636b8a1.tar.gz |
- get rid of EG(scope). zend_get_executed_scope() should be used instead.
- ichanged zval_update_constant_ex(). Use IS_TYPE_IMMUTABLE flag on shared constants and AST, instead of "inline_change" parameter.
Diffstat (limited to 'Zend/zend_execute_API.c')
-rw-r--r-- | Zend/zend_execute_API.c | 73 |
1 files changed, 38 insertions, 35 deletions
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 63d20e1fe2..023b341f21 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -177,7 +177,7 @@ void init_executor(void) /* {{{ */ EG(exception) = NULL; EG(prev_exception) = NULL; - EG(scope) = NULL; + EG(fake_scope) = NULL; EG(ht_iterators_count) = sizeof(EG(ht_iterators_slots)) / sizeof(HashTableIterator); EG(ht_iterators_used) = 0; @@ -523,6 +523,21 @@ ZEND_API uint zend_get_executed_lineno(void) /* {{{ */ } /* }}} */ +ZEND_API zend_class_entry *zend_get_executed_scope(void) /* {{{ */ +{ + zend_execute_data *ex = EG(current_execute_data); + + while (1) { + if (!ex) { + return NULL; + } else if (ex->func && (ZEND_USER_CODE(ex->func->type) || ex->func->common.scope)) { + return ex->func->common.scope; + } + ex = ex->prev_execute_data; + } +} +/* }}} */ + ZEND_API zend_bool zend_is_executing(void) /* {{{ */ { return EG(current_execute_data) != 0; @@ -546,21 +561,18 @@ 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) /* {{{ */ +ZEND_API int zval_update_constant_ex(zval *p, zend_class_entry *scope) /* {{{ */ { zval *const_value; char *colon; + zend_bool inline_change; - if (IS_CONSTANT_VISITED(p)) { - zend_throw_error(NULL, "Cannot declare self-referencing constant '%s'", Z_STRVAL_P(p)); - return FAILURE; - } else if (Z_TYPE_P(p) == IS_CONSTANT) { - + 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)); + return FAILURE; + } + inline_change = (Z_TYPE_FLAGS_P(p) & IS_TYPE_IMMUTABLE) == 0; SEPARATE_ZVAL_NOREF(p); MARK_CONSTANT_VISITED(p); if (Z_CONST_FLAGS_P(p) & IS_CONSTANT_CLASS) { @@ -568,8 +580,8 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas if (inline_change) { zend_string_release(Z_STR_P(p)); } - if (EG(scope) && EG(scope)->name) { - ZVAL_STR_COPY(p, EG(scope)->name); + if (scope && scope->name) { + ZVAL_STR_COPY(p, scope->name); } else { ZVAL_EMPTY_STRING(p); } @@ -635,7 +647,7 @@ 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)) { - if (UNEXPECTED(zval_update_constant_ex(p, 1, NULL) != SUCCESS)) { + if (UNEXPECTED(zval_update_constant_ex(p, scope) != SUCCESS)) { RESET_CONSTANT_VISITED(p); return FAILURE; } @@ -645,6 +657,7 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas } else if (Z_TYPE_P(p) == IS_CONSTANT_AST) { zval tmp; + inline_change = (Z_TYPE_FLAGS_P(p) & IS_TYPE_IMMUTABLE) == 0; if (UNEXPECTED(zend_ast_evaluate(&tmp, Z_ASTVAL_P(p), scope) != SUCCESS)) { return FAILURE; } @@ -657,9 +670,9 @@ ZEND_API int zval_update_constant_ex(zval *p, zend_bool inline_change, zend_clas } /* }}} */ -ZEND_API int zval_update_constant(zval *pp, zend_bool inline_change) /* {{{ */ +ZEND_API int zval_update_constant(zval *pp) /* {{{ */ { - return zval_update_constant_ex(pp, inline_change, NULL); + return zval_update_constant_ex(pp, EG(current_execute_data) ? zend_get_executed_scope() : CG(active_class_entry)); } /* }}} */ @@ -682,11 +695,9 @@ int _call_user_function_ex(zval *object, zval *function_name, zval *retval_ptr, int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) /* {{{ */ { uint32_t i; - zend_class_entry *calling_scope = NULL; zend_execute_data *call, dummy_execute_data; zend_fcall_info_cache fci_cache_local; zend_function *func; - zend_class_entry *orig_scope; ZVAL_UNDEF(fci->retval); @@ -706,8 +717,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) / break; } - orig_scope = EG(scope); - /* Initialize execute_data */ if (!EG(current_execute_data)) { /* This only happens when we're called outside any execute()'s @@ -763,7 +772,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) / } func = fci_cache->function_handler; - calling_scope = fci_cache->calling_scope; fci->object = (func->common.fn_flags & ZEND_ACC_STATIC) ? NULL : fci_cache->object; @@ -837,8 +845,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) / ZVAL_COPY_VALUE(param, arg); } - EG(scope) = calling_scope; - if (UNEXPECTED(func->op_array.fn_flags & ZEND_ACC_CLOSURE)) { ZEND_ASSERT(GC_TYPE((zend_object*)func->op_array.prototype) == IS_OBJECT); GC_REFCOUNT((zend_object*)func->op_array.prototype)++; @@ -847,7 +853,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) / if (func->type == ZEND_USER_FUNCTION) { int call_via_handler = (func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) != 0; - EG(scope) = func->common.scope; call->symbol_table = NULL; if (EXPECTED((func->op_array.fn_flags & ZEND_ACC_GENERATOR) == 0)) { zend_init_execute_data(call, &func->op_array, fci->retval); @@ -862,9 +867,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) / } else if (func->type == ZEND_INTERNAL_FUNCTION) { int call_via_handler = (func->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) != 0; ZVAL_NULL(fci->retval); - if (func->common.scope) { - EG(scope) = func->common.scope; - } call->prev_execute_data = EG(current_execute_data); call->return_value = NULL; /* this is not a constructor call */ EG(current_execute_data) = call; @@ -918,7 +920,6 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) / } } - EG(scope) = orig_scope; zend_vm_stack_free_call_frame(call); if (EG(current_execute_data) == &dummy_execute_data) { @@ -1379,25 +1380,27 @@ void zend_unset_timeout(void) /* {{{ */ zend_class_entry *zend_fetch_class(zend_string *class_name, int fetch_type) /* {{{ */ { - zend_class_entry *ce; + zend_class_entry *ce, *scope; int fetch_sub_type = fetch_type & ZEND_FETCH_CLASS_MASK; check_fetch_type: switch (fetch_sub_type) { case ZEND_FETCH_CLASS_SELF: - if (UNEXPECTED(!EG(scope))) { + scope = zend_get_executed_scope(); + if (UNEXPECTED(!scope)) { zend_throw_or_error(fetch_type, NULL, "Cannot access self:: when no class scope is active"); } - return EG(scope); + return scope; case ZEND_FETCH_CLASS_PARENT: - if (UNEXPECTED(!EG(scope))) { + scope = zend_get_executed_scope(); + if (UNEXPECTED(!scope)) { zend_throw_or_error(fetch_type, NULL, "Cannot access parent:: when no class scope is active"); return NULL; } - if (UNEXPECTED(!EG(scope)->parent)) { + if (UNEXPECTED(!scope->parent)) { zend_throw_or_error(fetch_type, NULL, "Cannot access parent:: when current class scope has no parent"); } - return EG(scope)->parent; + return scope->parent; case ZEND_FETCH_CLASS_STATIC: ce = zend_get_called_scope(EG(current_execute_data)); if (UNEXPECTED(!ce)) { |