]> granicus.if.org Git - php/commitdiff
- get rid of EG(scope). zend_get_executed_scope() should be used instead.
authorDmitry Stogov <dmitry@zend.com>
Thu, 28 Apr 2016 01:13:34 +0000 (04:13 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 28 Apr 2016 01:13:34 +0000 (04:13 +0300)
- ichanged zval_update_constant_ex(). Use IS_TYPE_IMMUTABLE flag on shared constants and AST, instead of "inline_change" parameter.

36 files changed:
Zend/tests/constant_expressions_self_referencing_array.phpt
Zend/zend_API.c
Zend/zend_ast.c
Zend/zend_builtin_functions.c
Zend/zend_constants.c
Zend/zend_execute.c
Zend/zend_execute.h
Zend/zend_execute_API.c
Zend/zend_generators.c
Zend/zend_globals.h
Zend/zend_ini_parser.y
Zend/zend_object_handlers.c
Zend/zend_objects.c
Zend/zend_types.h
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
ext/intl/transliterator/transliterator_class.c
ext/mysqli/mysqli.c
ext/opcache/zend_accelerator_util_funcs.c
ext/opcache/zend_persist.c
ext/pdo/pdo_dbh.c
ext/pdo/pdo_stmt.c
ext/pgsql/pgsql.c
ext/reflection/php_reflection.c
ext/soap/php_encoding.c
ext/spl/spl_engine.h
ext/standard/array.c
ext/standard/assert.c
ext/standard/basic_functions.c
ext/wddx/wddx.c
main/streams/userspace.c
sapi/phpdbg/phpdbg_frame.c
sapi/phpdbg/phpdbg_list.c
sapi/phpdbg/phpdbg_print.c
sapi/phpdbg/phpdbg_prompt.c
sapi/phpdbg/phpdbg_watch.c

index 63f2b20ef590d098f3f32cef72a47b650afbdf30..c584b5d5034b23c8ecbea731d80bd68d1d9ea2b6 100644 (file)
@@ -9,7 +9,7 @@ class A {
 var_dump(A::FOO);
 ?>
 --EXPECTF--
-Fatal error: Uncaught Error: Cannot declare self-referencing constant 'self::FOO' in %s:%d
+Fatal error: Uncaught Error: Cannot declare self-referencing constant 'self::BAR' in %s:%d
 Stack trace:
 #0 {main}
   thrown in %s on line %d
index fdb9628dbf1608419cca0140c8f064ffe4b6f032..9963ef322aedb5d8981a3ac0525741893007e53d 100644 (file)
@@ -1063,11 +1063,11 @@ ZEND_API int _array_init(zval *arg, uint32_t size ZEND_FILE_LINE_DC) /* {{{ */
 ZEND_API void zend_merge_properties(zval *obj, HashTable *properties) /* {{{ */
 {
        const zend_object_handlers *obj_ht = Z_OBJ_HT_P(obj);
-       zend_class_entry *old_scope = EG(scope);
+       zend_class_entry *old_scope = EG(fake_scope);
        zend_string *key;
        zval *value;
 
-       EG(scope) = Z_OBJCE_P(obj);
+       EG(fake_scope) = Z_OBJCE_P(obj);
        ZEND_HASH_FOREACH_STR_KEY_VAL(properties, key, value) {
                if (key) {
                        zval member;
@@ -1076,7 +1076,7 @@ ZEND_API void zend_merge_properties(zval *obj, HashTable *properties) /* {{{ */
                        obj_ht->write_property(obj, &member, value, NULL);
                }
        } ZEND_HASH_FOREACH_END();
-       EG(scope) = old_scope;
+       EG(fake_scope) = old_scope;
 }
 /* }}} */
 
@@ -1119,18 +1119,15 @@ ZEND_API int zend_update_class_constants(zend_class_entry *class_type) /* {{{ */
                                }
                        }
                } else {
-                       zend_class_entry **scope = EG(current_execute_data) ? &EG(scope) : &CG(active_class_entry);
-                       zend_class_entry *old_scope = *scope;
                        zend_class_entry *ce;
                        zend_class_constant *c;
                        zval *val;
                        zend_property_info *prop_info;
 
-                       *scope = class_type;
                        ZEND_HASH_FOREACH_PTR(&class_type->constants_table, c) {
                                val = &c->value;
                                if (Z_CONSTANT_P(val)) {
-                                       if (UNEXPECTED(zval_update_constant_ex(val, 1, class_type) != SUCCESS)) {
+                                       if (UNEXPECTED(zval_update_constant_ex(val, class_type) != SUCCESS)) {
                                                return FAILURE;
                                        }
                                }
@@ -1147,8 +1144,7 @@ ZEND_API int zend_update_class_constants(zend_class_entry *class_type) /* {{{ */
                                                }
                                                ZVAL_DEREF(val);
                                                if (Z_CONSTANT_P(val)) {
-                                                       *scope = ce;
-                                                       if (UNEXPECTED(zval_update_constant_ex(val, 1, NULL) != SUCCESS)) {
+                                                       if (UNEXPECTED(zval_update_constant_ex(val, ce) != SUCCESS)) {
                                                                return FAILURE;
                                                        }
                                                }
@@ -1156,8 +1152,6 @@ ZEND_API int zend_update_class_constants(zend_class_entry *class_type) /* {{{ */
                                } ZEND_HASH_FOREACH_END();
                                ce = ce->parent;
                        }
-
-                       *scope = old_scope;
                }
        }
        return SUCCESS;
@@ -1221,15 +1215,15 @@ ZEND_API void object_properties_load(zend_object *object, HashTable *properties)
                                size_t prop_name_len;
                                if (zend_unmangle_property_name_ex(key, &class_name, &prop_name, &prop_name_len) == SUCCESS) {
                                        zend_string *pname = zend_string_init(prop_name, prop_name_len, 0);
-                                       zend_class_entry *prev_scope = EG(scope);
+                                       zend_class_entry *prev_scope = EG(fake_scope);
                                        if (class_name && class_name[0] != '*') {
                                                zend_string *cname = zend_string_init(class_name, strlen(class_name), 0);
-                                               EG(scope) = zend_lookup_class(cname);
+                                               EG(fake_scope) = zend_lookup_class(cname);
                                                zend_string_release(cname);
                                        }
                                        property_info = zend_get_property_info(object->ce, pname, 1);
                                        zend_string_release(pname);
-                                       EG(scope) = prev_scope;
+                                       EG(fake_scope) = prev_scope;
                                } else {
                                        property_info = ZEND_WRONG_PROPERTY_INFO;
                                }
@@ -2819,7 +2813,7 @@ ZEND_API int zend_disable_class(char *class_name, size_t class_name_length) /* {
 }
 /* }}} */
 
-static int zend_is_callable_check_class(zend_string *name, zend_fcall_info_cache *fcc, int *strict_class, char **error) /* {{{ */
+static int zend_is_callable_check_class(zend_string *name, zend_class_entry *scope, zend_fcall_info_cache *fcc, int *strict_class, char **error) /* {{{ */
 {
        int ret = 0;
        zend_class_entry *ce;
@@ -2832,24 +2826,24 @@ static int zend_is_callable_check_class(zend_string *name, zend_fcall_info_cache
 
        *strict_class = 0;
        if (zend_string_equals_literal(lcname, "self")) {
-               if (!EG(scope)) {
+               if (!scope) {
                        if (error) *error = estrdup("cannot access self:: when no class scope is active");
                } else {
                        fcc->called_scope = zend_get_called_scope(EG(current_execute_data));
-                       fcc->calling_scope = EG(scope);
+                       fcc->calling_scope = scope;
                        if (!fcc->object) {
                                fcc->object = zend_get_this_object(EG(current_execute_data));
                        }
                        ret = 1;
                }
        } else if (zend_string_equals_literal(lcname, "parent")) {
-               if (!EG(scope)) {
+               if (!scope) {
                        if (error) *error = estrdup("cannot access parent:: when no class scope is active");
-               } else if (!EG(scope)->parent) {
+               } else if (!scope->parent) {
                        if (error) *error = estrdup("cannot access parent:: when current class scope has no parent");
                } else {
                        fcc->called_scope = zend_get_called_scope(EG(current_execute_data));
-                       fcc->calling_scope = EG(scope)->parent;
+                       fcc->calling_scope = scope->parent;
                        if (!fcc->object) {
                                fcc->object = zend_get_this_object(EG(current_execute_data));
                        }
@@ -2911,9 +2905,9 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
        zend_string *lmname;
        const char *colon;
        size_t clen, mlen;
-       zend_class_entry *last_scope;
        HashTable *ftable;
        int call_via_handler = 0;
+       zend_class_entry *scope;
        ALLOCA_FLAG(use_heap)
 
        if (error) {
@@ -2974,19 +2968,18 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
 
                /* This is a compound name.
                 * Try to fetch class and then find static method. */
-               last_scope = EG(scope);
                if (ce_org) {
-                       EG(scope) = ce_org;
+                       scope = ce_org;
+               } else {
+                       scope = zend_get_executed_scope();
                }
 
                cname = zend_string_init(Z_STRVAL_P(callable), clen, 0);
-               if (!zend_is_callable_check_class(cname, fcc, &strict_class, error)) {
+               if (!zend_is_callable_check_class(cname, scope, fcc, &strict_class, error)) {
                        zend_string_release(cname);
-                       EG(scope) = last_scope;
                        return 0;
                }
                zend_string_release(cname);
-               EG(scope) = last_scope;
 
                ftable = &fcc->calling_scope->function_table;
                if (ce_org && !instanceof_function(ce_org, fcc->calling_scope)) {
@@ -3020,14 +3013,17 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
        } else if ((fcc->function_handler = zend_hash_find_ptr(ftable, lmname)) != NULL) {
                retval = 1;
                if ((fcc->function_handler->op_array.fn_flags & ZEND_ACC_CHANGED) &&
-                   !strict_class && EG(scope) &&
-                   instanceof_function(fcc->function_handler->common.scope, EG(scope))) {
-                       zend_function *priv_fbc;
-
-                       if ((priv_fbc = zend_hash_find_ptr(&EG(scope)->function_table, lmname)) != NULL
-                               && priv_fbc->common.fn_flags & ZEND_ACC_PRIVATE
-                               && priv_fbc->common.scope == EG(scope)) {
-                               fcc->function_handler = priv_fbc;
+                   !strict_class) {
+                       scope = zend_get_executed_scope();
+                       if (scope &&
+                           instanceof_function(fcc->function_handler->common.scope, scope)) {
+                               zend_function *priv_fbc;
+
+                               if ((priv_fbc = zend_hash_find_ptr(&scope->function_table, lmname)) != NULL
+                                       && priv_fbc->common.fn_flags & ZEND_ACC_PRIVATE
+                                       && priv_fbc->common.scope == scope) {
+                                       fcc->function_handler = priv_fbc;
+                               }
                        }
                }
                if ((check_flags & IS_CALLABLE_CHECK_NO_ACCESS) == 0 &&
@@ -3035,13 +3031,15 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
                     ((fcc->object && fcc->calling_scope->__call) ||
                      (!fcc->object && fcc->calling_scope->__callstatic)))) {
                        if (fcc->function_handler->op_array.fn_flags & ZEND_ACC_PRIVATE) {
-                               if (!zend_check_private(fcc->function_handler, fcc->object ? fcc->object->ce : EG(scope), lmname)) {
+                               scope = zend_get_executed_scope();
+                               if (!zend_check_private(fcc->function_handler, fcc->object ? fcc->object->ce : scope, lmname)) {
                                        retval = 0;
                                        fcc->function_handler = NULL;
                                        goto get_function_via_handler;
                                }
                        } else if (fcc->function_handler->common.fn_flags & ZEND_ACC_PROTECTED) {
-                               if (!zend_check_protected(fcc->function_handler->common.scope, EG(scope))) {
+                               scope = zend_get_executed_scope();
+                               if (!zend_check_protected(fcc->function_handler->common.scope, scope)) {
                                        retval = 0;
                                        fcc->function_handler = NULL;
                                        goto get_function_via_handler;
@@ -3132,7 +3130,8 @@ get_function_via_handler:
                        }
                        if (retval && (check_flags & IS_CALLABLE_CHECK_NO_ACCESS) == 0) {
                                if (fcc->function_handler->op_array.fn_flags & ZEND_ACC_PRIVATE) {
-                                       if (!zend_check_private(fcc->function_handler, fcc->object ? fcc->object->ce : EG(scope), lmname)) {
+                                       scope = zend_get_executed_scope();
+                                       if (!zend_check_private(fcc->function_handler, fcc->object ? fcc->object->ce : scope, lmname)) {
                                                if (error) {
                                                        if (*error) {
                                                                efree(*error);
@@ -3142,7 +3141,8 @@ get_function_via_handler:
                                                retval = 0;
                                        }
                                } else if ((fcc->function_handler->common.fn_flags & ZEND_ACC_PROTECTED)) {
-                                       if (!zend_check_protected(fcc->function_handler->common.scope, EG(scope))) {
+                                       scope = zend_get_executed_scope();
+                                       if (!zend_check_protected(fcc->function_handler->common.scope, scope)) {
                                                if (error) {
                                                        if (*error) {
                                                                efree(*error);
@@ -3279,7 +3279,7 @@ again:
                                                        return 1;
                                                }
 
-                                               if (!zend_is_callable_check_class(Z_STR_P(obj), fcc, &strict_class, error)) {
+                                               if (!zend_is_callable_check_class(Z_STR_P(obj), zend_get_executed_scope(), fcc, &strict_class, error)) {
                                                        return 0;
                                                }
 
@@ -3838,9 +3838,9 @@ ZEND_API int zend_declare_class_constant_string(zend_class_entry *ce, const char
 ZEND_API void zend_update_property_ex(zend_class_entry *scope, zval *object, zend_string *name, zval *value) /* {{{ */
 {
        zval property;
-       zend_class_entry *old_scope = EG(scope);
+       zend_class_entry *old_scope = EG(fake_scope);
 
-       EG(scope) = scope;
+       EG(fake_scope) = scope;
 
        if (!Z_OBJ_HT_P(object)->write_property) {
                zend_error_noreturn(E_CORE_ERROR, "Property %s of class %s cannot be updated", name, ZSTR_VAL(Z_OBJCE_P(object)->name));
@@ -3848,16 +3848,16 @@ ZEND_API void zend_update_property_ex(zend_class_entry *scope, zval *object, zen
        ZVAL_STR(&property, name);
        Z_OBJ_HT_P(object)->write_property(object, &property, value, NULL);
 
-       EG(scope) = old_scope;
+       EG(fake_scope) = old_scope;
 }
 /* }}} */
 
 ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zval *value) /* {{{ */
 {
        zval property;
-       zend_class_entry *old_scope = EG(scope);
+       zend_class_entry *old_scope = EG(fake_scope);
 
-       EG(scope) = scope;
+       EG(fake_scope) = scope;
 
        if (!Z_OBJ_HT_P(object)->write_property) {
                zend_error_noreturn(E_CORE_ERROR, "Property %s of class %s cannot be updated", name, ZSTR_VAL(Z_OBJCE_P(object)->name));
@@ -3866,7 +3866,7 @@ ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, const
        Z_OBJ_HT_P(object)->write_property(object, &property, value, NULL);
        zval_ptr_dtor(&property);
 
-       EG(scope) = old_scope;
+       EG(fake_scope) = old_scope;
 }
 /* }}} */
 
@@ -3938,12 +3938,12 @@ ZEND_API void zend_update_property_stringl(zend_class_entry *scope, zval *object
 ZEND_API int zend_update_static_property(zend_class_entry *scope, const char *name, size_t name_length, zval *value) /* {{{ */
 {
        zval *property;
-       zend_class_entry *old_scope = EG(scope);
+       zend_class_entry *old_scope = EG(fake_scope);
        zend_string *key = zend_string_init(name, name_length, 0);
 
-       EG(scope) = scope;
+       EG(fake_scope) = scope;
        property = zend_std_get_static_property(scope, key, 0);
-       EG(scope) = old_scope;
+       EG(fake_scope) = old_scope;
        zend_string_free(key);
        if (!property) {
                return FAILURE;
@@ -4033,9 +4033,9 @@ ZEND_API int zend_update_static_property_stringl(zend_class_entry *scope, const
 ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, const char *name, size_t name_length, zend_bool silent, zval *rv) /* {{{ */
 {
        zval property, *value;
-       zend_class_entry *old_scope = EG(scope);
+       zend_class_entry *old_scope = EG(fake_scope);
 
-       EG(scope) = scope;
+       EG(fake_scope) = scope;
 
        if (!Z_OBJ_HT_P(object)->read_property) {
                zend_error_noreturn(E_CORE_ERROR, "Property %s of class %s cannot be read", name, ZSTR_VAL(Z_OBJCE_P(object)->name));
@@ -4045,7 +4045,7 @@ ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, const c
        value = Z_OBJ_HT_P(object)->read_property(object, &property, silent?BP_VAR_IS:BP_VAR_R, NULL, rv);
        zval_ptr_dtor(&property);
 
-       EG(scope) = old_scope;
+       EG(fake_scope) = old_scope;
        return value;
 }
 /* }}} */
@@ -4053,12 +4053,12 @@ ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, const c
 ZEND_API zval *zend_read_static_property(zend_class_entry *scope, const char *name, size_t name_length, zend_bool silent) /* {{{ */
 {
        zval *property;
-       zend_class_entry *old_scope = EG(scope);
+       zend_class_entry *old_scope = EG(fake_scope);
        zend_string *key = zend_string_init(name, name_length, 0);
 
-       EG(scope) = scope;
+       EG(fake_scope) = scope;
        property = zend_std_get_static_property(scope, key, silent);
-       EG(scope) = old_scope;
+       EG(fake_scope) = old_scope;
        zend_string_free(key);
 
        return property;
index 37728870920906c10b09b371b487eb2527bac6ed..eee4a44e867e30e866748a91780e65030c633077 100644 (file)
@@ -256,23 +256,23 @@ ZEND_API int zend_ast_evaluate(zval *result, zend_ast *ast, zend_class_entry *sc
                case ZEND_AST_ZVAL:
                {
                        zval *zv = zend_ast_get_zval(ast);
-                       if (scope) {
-                               /* class constants may be updated in-place */
-                               if (Z_OPT_CONSTANT_P(zv)) {
-                                       if (UNEXPECTED(zval_update_constant_ex(zv, 1, scope) != SUCCESS)) {
+
+                       if (Z_OPT_CONSTANT_P(zv)) {
+                               if (!(Z_TYPE_FLAGS_P(zv) & IS_TYPE_IMMUTABLE)) {
+                                       if (UNEXPECTED(zval_update_constant_ex(zv, scope) != SUCCESS)) {
                                                ret = FAILURE;
                                                break;
                                        }
-                               }
-                               ZVAL_DUP(result, zv);
-                       } else {
-                               ZVAL_DUP(result, zv);
-                               if (Z_OPT_CONSTANT_P(result)) {
-                                       if (UNEXPECTED(zval_update_constant_ex(result, 1, scope) != SUCCESS)) {
+                                       ZVAL_COPY(result, zv);
+                               } else {
+                                       ZVAL_COPY_VALUE(result, zv);
+                                       if (UNEXPECTED(zval_update_constant_ex(result, scope) != SUCCESS)) {
                                                ret = FAILURE;
                                                break;
                                        }
                                }
+                       } else {
+                               ZVAL_COPY(result, zv);
                        }
                        break;
                }
index 0cbafc7818ad34cade14f964be3898aa13624155..449276611769df7a0a1b00a804f4e2a9d58a3f42 100644 (file)
@@ -982,7 +982,7 @@ ZEND_FUNCTION(defined)
        ZEND_PARSE_PARAMETERS_END();
 #endif
 
-       if (zend_get_constant_ex(name, NULL, ZEND_FETCH_CLASS_SILENT)) {
+       if (zend_get_constant_ex(name, zend_get_executed_scope(), ZEND_FETCH_CLASS_SILENT)) {
                RETURN_TRUE;
        } else {
                RETURN_FALSE;
@@ -1001,8 +1001,10 @@ ZEND_FUNCTION(get_class)
        }
 
        if (!obj) {
-               if (EG(scope)) {
-                       RETURN_STR_COPY(EG(scope)->name);
+               zend_class_entry *scope = zend_get_executed_scope();
+
+               if (scope) {
+                       RETURN_STR_COPY(scope->name);
                } else {
                        zend_error(E_WARNING, "get_class() called without object from outside a class");
                        RETURN_FALSE;
@@ -1026,8 +1028,11 @@ ZEND_FUNCTION(get_called_class)
        called_scope = zend_get_called_scope(execute_data);
        if (called_scope) {
                RETURN_STR_COPY(called_scope->name);
-       } else if (!EG(scope))  {
-               zend_error(E_WARNING, "get_called_class() called from outside a class");
+       } else {
+               zend_class_entry *scope = zend_get_executed_scope();
+               if (!scope)  {
+                       zend_error(E_WARNING, "get_called_class() called from outside a class");
+               }
        }
        RETURN_FALSE;
 }
@@ -1045,7 +1050,7 @@ ZEND_FUNCTION(get_parent_class)
        }
 
        if (!ZEND_NUM_ARGS()) {
-               ce = EG(scope);
+               ce = zend_get_executed_scope();
                if (ce && ce->parent) {
                        RETURN_STR_COPY(ce->parent->name);
                } else {
@@ -1142,7 +1147,7 @@ ZEND_FUNCTION(is_a)
 /* }}} */
 
 /* {{{ add_class_vars */
-static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value)
+static void add_class_vars(zend_class_entry *scope, zend_class_entry *ce, int statics, zval *return_value)
 {
        zend_property_info *prop_info;
        zval *prop, prop_copy;
@@ -1150,12 +1155,12 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value
 
        ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->properties_info, key, prop_info) {
                if (((prop_info->flags & ZEND_ACC_SHADOW) &&
-                    prop_info->ce != EG(scope)) ||
+                    prop_info->ce != scope) ||
                    ((prop_info->flags & ZEND_ACC_PROTECTED) &&
-                    !zend_check_protected(prop_info->ce, EG(scope))) ||
+                    !zend_check_protected(prop_info->ce, scope)) ||
                    ((prop_info->flags & ZEND_ACC_PRIVATE) &&
-                     ce != EG(scope) &&
-                         prop_info->ce != EG(scope))) {
+                     ce != scope &&
+                         prop_info->ce != scope)) {
                        continue;
                }
                prop = NULL;
@@ -1180,7 +1185,7 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value
                /* this is necessary to make it able to work with default array
                 * properties, returned to user */
                if (Z_OPT_CONSTANT_P(prop)) {
-                       if (UNEXPECTED(zval_update_constant_ex(prop, 0, NULL) != SUCCESS)) {
+                       if (UNEXPECTED(zval_update_constant_ex(prop, NULL) != SUCCESS)) {
                                return;
                        }
                }
@@ -1195,7 +1200,7 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value
 ZEND_FUNCTION(get_class_vars)
 {
        zend_string *class_name;
-       zend_class_entry *ce;
+       zend_class_entry *ce, *scope;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &class_name) == FAILURE) {
                return;
@@ -1211,8 +1216,9 @@ ZEND_FUNCTION(get_class_vars)
                                return;
                        }
                }
-               add_class_vars(ce, 0, return_value);
-               add_class_vars(ce, 1, return_value);
+               scope = zend_get_executed_scope();
+               add_class_vars(scope, ce, 0, return_value);
+               add_class_vars(scope, ce, 1, return_value);
        }
 }
 /* }}} */
@@ -1310,6 +1316,7 @@ ZEND_FUNCTION(get_class_methods)
        zval *klass;
        zval method_name;
        zend_class_entry *ce = NULL;
+       zend_class_entry *scope;
        zend_function *mptr;
        zend_string *key;
 
@@ -1328,15 +1335,16 @@ ZEND_FUNCTION(get_class_methods)
        }
 
        array_init(return_value);
+       scope = zend_get_executed_scope();
 
        ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->function_table, key, mptr) {
 
                if ((mptr->common.fn_flags & ZEND_ACC_PUBLIC)
-                || (EG(scope) &&
+                || (scope &&
                     (((mptr->common.fn_flags & ZEND_ACC_PROTECTED) &&
-                      zend_check_protected(mptr->common.scope, EG(scope)))
+                      zend_check_protected(mptr->common.scope, scope))
                   || ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) &&
-                      EG(scope) == mptr->common.scope)))) {
+                      scope == mptr->common.scope)))) {
                        size_t len = ZSTR_LEN(mptr->common.function_name);
 
                        /* Do not display old-style inherited constructors */
index 0249d3562667c145f65f4ac1eaf0f2e9580f4351..22162d8976bbc06dcf365e05b89c7965edc56f0e 100644 (file)
@@ -334,13 +334,6 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope,
                class_name = zend_string_init(name, class_name_len, 0);
                lcname = do_alloca(class_name_len + 1, use_heap);
                zend_str_tolower_copy(lcname, name, class_name_len);
-               if (!scope) {
-                       if (EG(current_execute_data)) {
-                               scope = EG(scope);
-                       } else {
-                               scope = CG(active_class_entry);
-                       }
-               }
 
                if (class_name_len == sizeof("self")-1 &&
                    !memcmp(lcname, "self", sizeof("self")-1)) {
@@ -391,13 +384,26 @@ ZEND_API zval *zend_get_constant_ex(zend_string *cname, zend_class_entry *scope,
                                ret_constant = &c->value;
                        }
                }
-               zend_string_release(class_name);
-               zend_string_free(constant_name);
                if (ret_constant && Z_CONSTANT_P(ret_constant)) {
-                       if (UNEXPECTED(zval_update_constant_ex(ret_constant, 1, ce) != SUCCESS)) {
+                       if (Z_TYPE_P(ret_constant) == IS_CONSTANT_AST) {
+                               if (IS_CONSTANT_VISITED(ret_constant)) {
+                                       zend_throw_error(NULL, "Cannot declare self-referencing constant '%s::%s'", ZSTR_VAL(class_name), ZSTR_VAL(constant_name));
+                                       zend_string_release(class_name);
+                                       zend_string_free(constant_name);
+                                       return NULL;
+                               }
+                               MARK_CONSTANT_VISITED(ret_constant);
+                       }
+                       if (UNEXPECTED(zval_update_constant_ex(ret_constant, ce) != SUCCESS)) {
+                               RESET_CONSTANT_VISITED(ret_constant);
+                               zend_string_release(class_name);
+                               zend_string_free(constant_name);
                                return NULL;
                        }
+                       RESET_CONSTANT_VISITED(ret_constant);
                }
+               zend_string_release(class_name);
+               zend_string_free(constant_name);
                return ret_constant;
        }
 
index 68fc5e7f5dc07f0490d2998e2325a340cb25cacb..95aea65ac8f685e8a13fab766330b62c4b2c6ae9 100644 (file)
@@ -645,19 +645,19 @@ static ZEND_COLD void zend_verify_arg_error(const zend_function *zf, uint32_t ar
        }
 }
 
-static int is_null_constant(zval *default_value)
+static int is_null_constant(zend_class_entry *scope, zval *default_value)
 {
        if (Z_CONSTANT_P(default_value)) {
                zval constant;
 
-               ZVAL_COPY_VALUE(&constant, default_value);
-               if (UNEXPECTED(zval_update_constant_ex(&constant, 0, NULL) != SUCCESS)) {
+               ZVAL_COPY(&constant, default_value);
+               if (UNEXPECTED(zval_update_constant_ex(&constant, scope) != SUCCESS)) {
                        return 0;
                }
                if (Z_TYPE(constant) == IS_NULL) {
                        return 1;
                }
-               zval_dtor(&constant);
+               zval_ptr_dtor(&constant);
        }
        return 0;
 }
@@ -822,7 +822,7 @@ static zend_always_inline int zend_verify_arg_type(zend_function *zf, uint32_t a
                                        return 0;
                                }
                        }
-               } else if (Z_TYPE_P(arg) != IS_NULL || !(cur_arg_info->allow_null || (default_value && is_null_constant(default_value)))) {
+               } else if (Z_TYPE_P(arg) != IS_NULL || !(cur_arg_info->allow_null || (default_value && is_null_constant(zf->common.scope, default_value)))) {
                        if (cur_arg_info->class_name) {
                                if (EXPECTED(*cache_slot)) {
                                        ce = (zend_class_entry*)*cache_slot;
@@ -2979,7 +2979,6 @@ static zend_never_inline int zend_do_fcall_overloaded(zend_function *fbc, zend_e
        }
 
        object = Z_OBJ(call->This);
-       EG(scope) = fbc->common.scope;
 
        ZVAL_NULL(ret);
 
index 05f0e9a95666ab9cae4857246e78e726df491d40..011a4f126ae95c690285463eaa5c8a3cc249921c 100644 (file)
@@ -122,8 +122,8 @@ static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval
        return variable_ptr;
 }
 
-ZEND_API int zval_update_constant(zval *pp, zend_bool inline_change);
-ZEND_API int zval_update_constant_ex(zval *pp, zend_bool inline_change, zend_class_entry *scope);
+ZEND_API int zval_update_constant(zval *pp);
+ZEND_API int zval_update_constant_ex(zval *pp, zend_class_entry *scope);
 
 /* dedicated Zend executor functions - do not use! */
 struct _zend_vm_stack {
@@ -284,6 +284,7 @@ ZEND_API const char *get_active_function_name(void);
 ZEND_API const char *zend_get_executed_filename(void);
 ZEND_API zend_string *zend_get_executed_filename_ex(void);
 ZEND_API uint zend_get_executed_lineno(void);
+ZEND_API zend_class_entry *zend_get_executed_scope(void);
 ZEND_API zend_bool zend_is_executing(void);
 
 ZEND_API void zend_set_timeout(zend_long seconds, int reset_signals);
index 63d20e1fe24fa822c1fdf8471876969fd73a5f19..023b341f21107205b1ed3e489b6d204a8bebb3ea 100644 (file)
@@ -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)) {
index 33f187c96fca68e87892754e409564fb3365f117..5524a165fa0d90e5659a2a78e4618f2ca2a88fd9 100644 (file)
@@ -321,7 +321,7 @@ static zend_object *zend_generator_create(zend_class_entry *class_type) /* {{{ *
 }
 /* }}} */
 
-/* Requires globals EG(scope), EG(This) and EG(current_execute_data). */
+/* Requires globals EG(current_execute_data). */
 ZEND_API void zend_generator_create_zval(zend_execute_data *call, zend_op_array *op_array, zval *return_value) /* {{{ */
 {
        zend_generator *generator;
@@ -761,13 +761,11 @@ try_again:
        {
                /* Backup executor globals */
                zend_execute_data *original_execute_data = EG(current_execute_data);
-               zend_class_entry *original_scope = EG(scope);
                zend_vm_stack original_stack = EG(vm_stack);
                original_stack->top = EG(vm_stack_top);
 
                /* Set executor globals */
                EG(current_execute_data) = generator->execute_data;
-               EG(scope) = generator->execute_data->func->common.scope;
                EG(vm_stack_top) = generator->stack->top;
                EG(vm_stack_end) = generator->stack->end;
                EG(vm_stack) = generator->stack;
@@ -797,7 +795,6 @@ try_again:
 
                /* Restore executor globals */
                EG(current_execute_data) = original_execute_data;
-               EG(scope) = original_scope;
                EG(vm_stack_top) = original_stack->top;
                EG(vm_stack_end) = original_stack->end;
                EG(vm_stack) = original_stack;
index 6c1280117a7f5f90c43612b0a107292a3acacd8c..14f47554d137aa5d7302c28b79a30e5c7dc02aa9 100644 (file)
@@ -161,7 +161,7 @@ struct _zend_executor_globals {
        zend_vm_stack  vm_stack;
 
        struct _zend_execute_data *current_execute_data;
-       zend_class_entry *scope;
+       zend_class_entry *fake_scope; /* used to avoid checks accessing properties */
 
        zend_long precision;
 
index ae04d2b70c23559e248f0fc4cbfe022af6aac989..315455bf8872dbf77ddb364f8ca2877a9db7b539 100644 (file)
@@ -134,7 +134,7 @@ static void zend_ini_get_constant(zval *result, zval *name)
                if (Z_TYPE_P(c) != IS_STRING) {
                        ZVAL_COPY_VALUE(&tmp, c);
                        if (Z_OPT_CONSTANT(tmp)) {
-                               zval_update_constant_ex(&tmp, 1, NULL);
+                               zval_update_constant_ex(&tmp, NULL);
                        }
                        zval_opt_copy_ctor(&tmp);
                        convert_to_string(&tmp);
index d0c5106342d0b4c590e6dfa66bae24bf221e539a..ca6ec6ac7eef547861d4745e066cf47a26aa94fd 100644 (file)
@@ -271,12 +271,24 @@ static void zend_std_call_issetter(zval *object, zval *member, zval *retval) /*
 
 static zend_always_inline int zend_verify_property_access(zend_property_info *property_info, zend_class_entry *ce) /* {{{ */
 {
+       zend_class_entry *scope;
+
        if (property_info->flags & ZEND_ACC_PUBLIC) {
                return 1;
        } else if (property_info->flags & ZEND_ACC_PRIVATE) {
-               return (ce == EG(scope) || property_info->ce == EG(scope));
+               if (EG(fake_scope)) {
+                       scope = EG(fake_scope);
+               } else {
+                       scope = zend_get_executed_scope();
+               }
+               return (ce == scope || property_info->ce == scope);
        } else if (property_info->flags & ZEND_ACC_PROTECTED) {
-               return zend_check_protected(property_info->ce, EG(scope));
+               if (EG(fake_scope)) {
+                       scope = EG(fake_scope);
+               } else {
+                       scope = zend_get_executed_scope();
+               }
+               return zend_check_protected(property_info->ce, scope);
        }
        return 0;
 }
@@ -301,6 +313,7 @@ static zend_always_inline uint32_t zend_get_property_offset(zend_class_entry *ce
        zval *zv;
        zend_property_info *property_info = NULL;
        uint32_t flags;
+       zend_class_entry *scope;
 
        if (cache_slot && EXPECTED(ce == CACHED_PTR_EX(cache_slot))) {
                return (uint32_t)(intptr_t)CACHED_PTR_EX(cache_slot + 1);
@@ -347,10 +360,16 @@ static zend_always_inline uint32_t zend_get_property_offset(zend_class_entry *ce
                }
        }
 
-       if (EG(scope) != ce
-               && EG(scope)
-               && is_derived_class(ce, EG(scope))
-               && (zv = zend_hash_find(&EG(scope)->properties_info, member)) != NULL
+       if (EG(fake_scope)) {
+               scope = EG(fake_scope);
+       } else {
+               scope = zend_get_executed_scope();
+       }
+
+       if (scope != ce
+               && scope
+               && is_derived_class(ce, scope)
+               && (zv = zend_hash_find(&scope->properties_info, member)) != NULL
                && ((zend_property_info*)Z_PTR_P(zv))->flags & ZEND_ACC_PRIVATE) {
                property_info = (zend_property_info*)Z_PTR_P(zv);
                if (UNEXPECTED((property_info->flags & ZEND_ACC_STATIC) != 0)) {
@@ -383,6 +402,7 @@ ZEND_API zend_property_info *zend_get_property_info(zend_class_entry *ce, zend_s
        zval *zv;
        zend_property_info *property_info = NULL;
        uint32_t flags;
+       zend_class_entry *scope;
 
        if (UNEXPECTED(ZSTR_VAL(member)[0] == '\0')) {
                if (!silent) {
@@ -424,10 +444,16 @@ ZEND_API zend_property_info *zend_get_property_info(zend_class_entry *ce, zend_s
                }
        }
 
-       if (EG(scope) != ce
-               && EG(scope)
-               && is_derived_class(ce, EG(scope))
-               && (zv = zend_hash_find(&EG(scope)->properties_info, member)) != NULL
+       if (EG(fake_scope)) {
+               scope = EG(fake_scope);
+       } else {
+               scope = zend_get_executed_scope();
+       }
+
+       if (scope != ce
+               && scope
+               && is_derived_class(ce, scope)
+               && (zv = zend_hash_find(&scope->properties_info, member)) != NULL
                && ((zend_property_info*)Z_PTR_P(zv))->flags & ZEND_ACC_PRIVATE) {
                property_info = (zend_property_info*)Z_PTR_P(zv);
        } else if (UNEXPECTED(property_info == NULL)) {
@@ -1022,6 +1048,7 @@ static void zend_std_unset_dimension(zval *object, zval *offset) /* {{{ */
 static inline zend_function *zend_check_private_int(zend_function *fbc, zend_class_entry *ce, zend_string *function_name) /* {{{ */
 {
     zval *func;
+    zend_class_entry *scope;
 
        if (!ce) {
                return 0;
@@ -1033,7 +1060,8 @@ static inline zend_function *zend_check_private_int(zend_function *fbc, zend_cla
         * 2.  One of our parent classes are the same as the scope, and it contains
         *     a private function with the same name that has the same scope.
         */
-       if (fbc->common.scope == ce && EG(scope) == ce) {
+       scope = zend_get_executed_scope();
+       if (fbc->common.scope == ce && scope == ce) {
                /* rule #1 checks out ok, allow the function call */
                return fbc;
        }
@@ -1042,11 +1070,11 @@ static inline zend_function *zend_check_private_int(zend_function *fbc, zend_cla
        /* Check rule #2 */
        ce = ce->parent;
        while (ce) {
-               if (ce == EG(scope)) {
+               if (ce == scope) {
                        if ((func = zend_hash_find(&ce->function_table, function_name))) {
                                fbc = Z_FUNC_P(func);
                                if (fbc->common.fn_flags & ZEND_ACC_PRIVATE
-                                       && fbc->common.scope == EG(scope)) {
+                                       && fbc->common.scope == scope) {
                                        return fbc;
                                }
                        }
@@ -1149,6 +1177,7 @@ static union _zend_function *zend_std_get_method(zend_object **obj_ptr, zend_str
        zval *func;
        zend_function *fbc;
        zend_string *lc_method_name;
+       zend_class_entry *scope = NULL;
        ALLOCA_FLAG(use_heap);
 
        if (EXPECTED(key != NULL)) {
@@ -1187,7 +1216,8 @@ static union _zend_function *zend_std_get_method(zend_object **obj_ptr, zend_str
                        if (zobj->ce->__call) {
                                fbc = zend_get_user_call_function(zobj->ce, method_name);
                        } else {
-                               zend_throw_error(NULL, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), ZSTR_VAL(method_name), EG(scope) ? ZSTR_VAL(EG(scope)->name) : "");
+                               scope = zend_get_executed_scope();
+                               zend_throw_error(NULL, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), ZSTR_VAL(method_name), scope ? ZSTR_VAL(scope->name) : "");
                                fbc = NULL;
                        }
                }
@@ -1195,26 +1225,29 @@ static union _zend_function *zend_std_get_method(zend_object **obj_ptr, zend_str
                /* Ensure that we haven't overridden a private function and end up calling
                 * the overriding public function...
                 */
-               if (EG(scope) &&
-                   is_derived_class(fbc->common.scope, EG(scope)) &&
-                   fbc->op_array.fn_flags & ZEND_ACC_CHANGED) {
-                       if ((func = zend_hash_find(&EG(scope)->function_table, lc_method_name)) != NULL) {
-                               zend_function *priv_fbc = Z_FUNC_P(func);
-                               if (priv_fbc->common.fn_flags & ZEND_ACC_PRIVATE
-                                       && priv_fbc->common.scope == EG(scope)) {
-                                       fbc = priv_fbc;
+               if (fbc->op_array.fn_flags & (ZEND_ACC_CHANGED|ZEND_ACC_PROTECTED)) {
+                       scope = zend_get_executed_scope();
+               }
+               if (fbc->op_array.fn_flags & ZEND_ACC_CHANGED) {
+                       if (scope && is_derived_class(fbc->common.scope, scope)) {
+                               if ((func = zend_hash_find(&scope->function_table, lc_method_name)) != NULL) {
+                                       zend_function *priv_fbc = Z_FUNC_P(func);
+                                       if (priv_fbc->common.fn_flags & ZEND_ACC_PRIVATE
+                                               && priv_fbc->common.scope == scope) {
+                                               fbc = priv_fbc;
+                                       }
                                }
                        }
                }
-               if ((fbc->common.fn_flags & ZEND_ACC_PROTECTED)) {
+               if (fbc->common.fn_flags & ZEND_ACC_PROTECTED) {
                        /* Ensure that if we're calling a protected function, we're allowed to do so.
                         * If we're not and __call() handler exists, invoke it, otherwise error out.
                         */
-                       if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(fbc), EG(scope)))) {
+                       if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(fbc), scope))) {
                                if (zobj->ce->__call) {
                                        fbc = zend_get_user_call_function(zobj->ce, method_name);
                                } else {
-                                       zend_throw_error(NULL, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), ZSTR_VAL(method_name), EG(scope) ? ZSTR_VAL(EG(scope)->name) : "");
+                                       zend_throw_error(NULL, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), ZSTR_VAL(method_name), scope ? ZSTR_VAL(scope->name) : "");
                                        fbc = NULL;
                                }
                        }
@@ -1240,6 +1273,7 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_st
        char *lc_class_name;
        zend_string *lc_function_name;
        zend_object *object;
+       zend_class_entry *scope;
 
        if (EXPECTED(key != NULL)) {
                lc_function_name = Z_STR_P(key);
@@ -1300,25 +1334,27 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_st
 
                /* Ensure that if we're calling a private function, we're allowed to do so.
                 */
-               updated_fbc = zend_check_private_int(fbc, EG(scope), lc_function_name);
+               scope = zend_get_executed_scope();
+               updated_fbc = zend_check_private_int(fbc, scope, lc_function_name);
                if (EXPECTED(updated_fbc != NULL)) {
                        fbc = updated_fbc;
                } else {
                        if (ce->__callstatic) {
                                fbc = zend_get_user_callstatic_function(ce, function_name);
                        } else {
-                               zend_throw_error(NULL, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), ZSTR_VAL(function_name), EG(scope) ? ZSTR_VAL(EG(scope)->name) : "");
+                               zend_throw_error(NULL, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), ZSTR_VAL(function_name), scope ? ZSTR_VAL(scope->name) : "");
                                fbc = NULL;
                        }
                }
        } else if ((fbc->common.fn_flags & ZEND_ACC_PROTECTED)) {
                /* Ensure that if we're calling a protected function, we're allowed to do so.
                 */
-               if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(fbc), EG(scope)))) {
+               scope = zend_get_executed_scope();
+               if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(fbc), scope))) {
                        if (ce->__callstatic) {
                                fbc = zend_get_user_callstatic_function(ce, function_name);
                        } else {
-                               zend_throw_error(NULL, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), ZSTR_VAL(function_name), EG(scope) ? ZSTR_VAL(EG(scope)->name) : "");
+                               zend_throw_error(NULL, "Call to %s method %s::%s() from context '%s'", zend_visibility_string(fbc->common.fn_flags), ZEND_FN_SCOPE_NAME(fbc), ZSTR_VAL(function_name), scope ? ZSTR_VAL(scope->name) : "");
                                fbc = NULL;
                        }
                }
@@ -1382,6 +1418,7 @@ ZEND_API ZEND_COLD zend_bool zend_std_unset_static_property(zend_class_entry *ce
 ZEND_API union _zend_function *zend_std_get_constructor(zend_object *zobj) /* {{{ */
 {
        zend_function *constructor = zobj->ce->constructor;
+       zend_class_entry *scope;
 
        if (constructor) {
                if (constructor->op_array.fn_flags & ZEND_ACC_PUBLIC) {
@@ -1389,9 +1426,14 @@ ZEND_API union _zend_function *zend_std_get_constructor(zend_object *zobj) /* {{
                } else if (constructor->op_array.fn_flags & ZEND_ACC_PRIVATE) {
                        /* Ensure that if we're calling a private function, we're allowed to do so.
                         */
-                       if (UNEXPECTED(constructor->common.scope != EG(scope))) {
-                               if (EG(scope)) {
-                                       zend_throw_error(NULL, "Call to private %s::%s() from context '%s'", ZSTR_VAL(constructor->common.scope->name), ZSTR_VAL(constructor->common.function_name), ZSTR_VAL(EG(scope)->name));
+                       if (EG(fake_scope)) {
+                               scope = EG(fake_scope);
+                       } else {
+                               scope = zend_get_executed_scope();
+                       }
+                       if (UNEXPECTED(constructor->common.scope != scope)) {
+                               if (scope) {
+                                       zend_throw_error(NULL, "Call to private %s::%s() from context '%s'", ZSTR_VAL(constructor->common.scope->name), ZSTR_VAL(constructor->common.function_name), ZSTR_VAL(scope->name));
                                        constructor = NULL;
                                } else {
                                        zend_throw_error(NULL, "Call to private %s::%s() from invalid context", ZSTR_VAL(constructor->common.scope->name), ZSTR_VAL(constructor->common.function_name));
@@ -1403,9 +1445,14 @@ ZEND_API union _zend_function *zend_std_get_constructor(zend_object *zobj) /* {{
                         * Constructors only have prototype if they are defined by an interface but
                         * it is the compilers responsibility to take care of the prototype.
                         */
-                       if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(constructor), EG(scope)))) {
-                               if (EG(scope)) {
-                                       zend_throw_error(NULL, "Call to protected %s::%s() from context '%s'", ZSTR_VAL(constructor->common.scope->name), ZSTR_VAL(constructor->common.function_name), ZSTR_VAL(EG(scope)->name));
+                       if (EG(fake_scope)) {
+                               scope = EG(fake_scope);
+                       } else {
+                               scope = zend_get_executed_scope();
+                       }
+                       if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(constructor), scope))) {
+                               if (scope) {
+                                       zend_throw_error(NULL, "Call to protected %s::%s() from context '%s'", ZSTR_VAL(constructor->common.scope->name), ZSTR_VAL(constructor->common.function_name), ZSTR_VAL(scope->name));
                                        constructor = NULL;
                                } else {
                                        zend_throw_error(NULL, "Call to protected %s::%s() from invalid context", ZSTR_VAL(constructor->common.scope->name), ZSTR_VAL(constructor->common.function_name));
index 0f052335db4bace09ecc85a01ffa0c150df91506..53d215d27e7c4bd0ff43c1cc5cb573bdead37797 100644 (file)
@@ -96,39 +96,39 @@ ZEND_API void zend_objects_destroy_object(zend_object *object)
                        if (destructor->op_array.fn_flags & ZEND_ACC_PRIVATE) {
                                /* Ensure that if we're calling a private function, we're allowed to do so.
                                 */
-                               if (object->ce != EG(scope)) {
-                                       zend_class_entry *ce = object->ce;
+                               if (EG(current_execute_data)) {
+                                       zend_class_entry *scope = zend_get_executed_scope();
 
-                                       if (EG(current_execute_data)) {
+                                       if (object->ce != scope) {
                                                zend_throw_error(NULL,
                                                        "Call to private %s::__destruct() from context '%s'",
-                                                       ZSTR_VAL(ce->name),
-                                                       EG(scope) ? ZSTR_VAL(EG(scope)->name) : "");
-                                       } else {
-                                               zend_error(E_WARNING,
-                                                       "Call to private %s::__destruct() from context '%s' during shutdown ignored",
-                                                       ZSTR_VAL(ce->name),
-                                                       EG(scope) ? ZSTR_VAL(EG(scope)->name) : "");
+                                                       ZSTR_VAL(object->ce->name),
+                                                       scope ? ZSTR_VAL(scope->name) : "");
+                                               return;
                                        }
+                               } else {
+                                       zend_error(E_WARNING,
+                                               "Call to private %s::__destruct() from context '' during shutdown ignored",
+                                               ZSTR_VAL(object->ce->name));
                                        return;
                                }
                        } else {
                                /* Ensure that if we're calling a protected function, we're allowed to do so.
                                 */
-                               if (!zend_check_protected(zend_get_function_root_class(destructor), EG(scope))) {
-                                       zend_class_entry *ce = object->ce;
+                               if (EG(current_execute_data)) {
+                                       zend_class_entry *scope = zend_get_executed_scope();
 
-                                       if (EG(current_execute_data)) {
+                                       if (!zend_check_protected(zend_get_function_root_class(destructor), scope)) {
                                                zend_throw_error(NULL,
                                                        "Call to protected %s::__destruct() from context '%s'",
-                                                       ZSTR_VAL(ce->name),
-                                                       EG(scope) ? ZSTR_VAL(EG(scope)->name) : "");
-                                       } else {
-                                               zend_error(E_WARNING,
-                                                       "Call to protected %s::__destruct() from context '%s' during shutdown ignored",
-                                                       ZSTR_VAL(ce->name),
-                                                       EG(scope) ? ZSTR_VAL(EG(scope)->name) : "");
+                                                       ZSTR_VAL(object->ce->name),
+                                                       scope ? ZSTR_VAL(scope->name) : "");
+                                               return;
                                        }
+                               } else {
+                                       zend_error(E_WARNING,
+                                               "Call to protected %s::__destruct() from context '' during shutdown ignored",
+                                               ZSTR_VAL(object->ce->name));
                                        return;
                                }
                        }
index b775bd7e533083d101d4ab1342d900a311b24bc6..45c2ebdf70a69b4d67e1a7219bd973b9837220a8 100644 (file)
@@ -410,9 +410,14 @@ static zend_always_inline zend_uchar zval_get_type(const zval* pz) {
 
 /* zval.u1.v.const_flags */
 #define IS_CONSTANT_UNQUALIFIED                0x010
+#define IS_CONSTANT_VISITED_MARK       0x020
 #define IS_CONSTANT_CLASS           0x080  /* __CLASS__ in trait */
 #define IS_CONSTANT_IN_NAMESPACE       0x100  /* used only in opline->extended_value */
 
+#define IS_CONSTANT_VISITED(p)         (Z_CONST_FLAGS_P(p) & IS_CONSTANT_VISITED_MARK)
+#define MARK_CONSTANT_VISITED(p)       Z_CONST_FLAGS_P(p) |= IS_CONSTANT_VISITED_MARK
+#define RESET_CONSTANT_VISITED(p)      Z_CONST_FLAGS_P(p) &= ~IS_CONSTANT_VISITED_MARK
+
 /* string flags (zval.value->gc.u.flags) */
 #define IS_STR_PERSISTENT                      (1<<0) /* allocated using malloc   */
 #define IS_STR_INTERNED                                (1<<1) /* interned string          */
index e1a87bbc9e58223977a1d0ad37cdf71f4892c794..2b29e62887c4b452917d97fc5dc081a8a7831afe 100644 (file)
@@ -2537,8 +2537,6 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
                        execute_data = EX(prev_execute_data);
                }
 
-               EG(scope) = EX(func)->op_array.scope;
-
                if (UNEXPECTED(EG(exception) != NULL)) {
                        const zend_op *old_opline = EX(opline);
                        zend_throw_exception_internal(NULL);
@@ -3591,7 +3589,6 @@ ZEND_VM_HANDLER(130, ZEND_DO_UCALL, ANY, ANY, SPEC(RETVAL))
        SAVE_OPLINE();
        EX(call) = call->prev_execute_data;
 
-       EG(scope) = NULL;
        ret = NULL;
        call->symbol_table = NULL;
        if (RETURN_VALUE_USED(opline)) {
@@ -3616,7 +3613,6 @@ ZEND_VM_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL))
        EX(call) = call->prev_execute_data;
 
        if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
-               EG(scope) = NULL;
                if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
                        if (EXPECTED(RETURN_VALUE_USED(opline))) {
                                ret = EX_VAR(opline->result.var);
@@ -3639,7 +3635,6 @@ ZEND_VM_HANDLER(131, ZEND_DO_FCALL_BY_NAME, ANY, ANY, SPEC(RETVAL))
 
                        ZEND_VM_ENTER();
                }
-               EG(scope) = EX(func)->op_array.scope;
        } else {
                zval retval;
                ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
@@ -3727,7 +3722,6 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL))
        LOAD_OPLINE();
 
        if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
-               EG(scope) = fbc->common.scope;
                if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
                        if (EXPECTED(RETURN_VALUE_USED(opline))) {
                                ret = EX_VAR(opline->result.var);
@@ -3757,14 +3751,8 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL))
                        }
                }
        } else if (EXPECTED(fbc->type < ZEND_USER_FUNCTION)) {
-               int should_change_scope = 0;
                zval retval;
 
-               if (fbc->common.scope) {
-                       should_change_scope = 1;
-                       EG(scope) = fbc->common.scope;
-               }
-
                call->prev_execute_data = execute_data;
                EG(current_execute_data) = call;
 
@@ -3773,11 +3761,7 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL))
                        if (RETURN_VALUE_USED(opline)) {
                                ZVAL_UNDEF(EX_VAR(opline->result.var));
                        }
-                       if (UNEXPECTED(should_change_scope)) {
-                               ZEND_VM_C_GOTO(fcall_end_change_scope);
-                       } else {
-                               ZEND_VM_C_GOTO(fcall_end);
-                       }
+                       ZEND_VM_C_GOTO(fcall_end);
                }
 
                ret = RETURN_VALUE_USED(opline) ? EX_VAR(opline->result.var) : &retval;
@@ -3806,11 +3790,6 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL))
                        zval_ptr_dtor(ret);
                }
 
-               if (UNEXPECTED(should_change_scope)) {
-                       ZEND_VM_C_GOTO(fcall_end_change_scope);
-               } else {
-                       ZEND_VM_C_GOTO(fcall_end);
-               }
        } else { /* ZEND_OVERLOADED_FUNCTION */
                zval retval;
 
@@ -3827,7 +3806,7 @@ ZEND_VM_HANDLER(60, ZEND_DO_FCALL, ANY, ANY, SPEC(RETVAL))
                }
        }
 
-ZEND_VM_C_LABEL(fcall_end_change_scope):
+ZEND_VM_C_LABEL(fcall_end):
        if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS)) {
                object = Z_OBJ(call->This);
 #if 0
@@ -3842,9 +3821,7 @@ ZEND_VM_C_LABEL(fcall_end_change_scope):
                }
                OBJ_RELEASE(object);
        }
-       EG(scope) = EX(func)->op_array.scope;
 
-ZEND_VM_C_LABEL(fcall_end):
        zend_vm_stack_free_call_frame(call);
        if (UNEXPECTED(EG(exception) != NULL)) {
                zend_throw_exception_internal(NULL);
@@ -4688,17 +4665,13 @@ ZEND_VM_HANDLER(64, ZEND_RECV_INIT, NUM, CONST)
        arg_num = opline->op1.num;
        param = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var);
        if (arg_num > EX_NUM_ARGS()) {
-               ZVAL_COPY_VALUE(param, EX_CONSTANT(opline->op2));
+               ZVAL_COPY(param, EX_CONSTANT(opline->op2));
                if (Z_OPT_CONSTANT_P(param)) {
                        SAVE_OPLINE();
-                       if (UNEXPECTED(zval_update_constant_ex(param, 0, NULL) != SUCCESS)) {
+                       if (UNEXPECTED(zval_update_constant_ex(param, EX(func)->op_array.scope) != SUCCESS)) {
                                ZVAL_UNDEF(param);
                                HANDLE_EXCEPTION();
                        }
-               } else {
-                       if (UNEXPECTED(Z_OPT_REFCOUNTED_P(param))) {
-                               Z_ADDREF_P(param);
-                       }
                }
        }
 
@@ -4923,7 +4896,7 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY)
        USE_OPLINE
        zend_free_op free_op1;
        zval *obj;
-       zend_class_entry *ce;
+       zend_class_entry *ce, *scope;
        zend_function *clone;
        zend_object_clone_obj_t clone_call;
 
@@ -4969,16 +4942,18 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMPVAR|UNUSED|THIS|CV, ANY)
                if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
                        /* Ensure that if we're calling a private function, we're allowed to do so.
                         */
-                       if (UNEXPECTED(ce != EG(scope))) {
-                               zend_throw_error(NULL, "Call to private %s::__clone() from context '%s'", ZSTR_VAL(ce->name), EG(scope) ? ZSTR_VAL(EG(scope)->name) : "");
+                       scope = EX(func)->op_array.scope;
+                       if (UNEXPECTED(ce != scope)) {
+                               zend_throw_error(NULL, "Call to private %s::__clone() from context '%s'", ZSTR_VAL(ce->name), scope ? ZSTR_VAL(scope->name) : "");
                                FREE_OP1();
                                HANDLE_EXCEPTION();
                        }
                } else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) {
                        /* Ensure that if we're calling a protected function, we're allowed to do so.
                         */
-                       if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), EG(scope)))) {
-                               zend_throw_error(NULL, "Call to protected %s::__clone() from context '%s'", ZSTR_VAL(ce->name), EG(scope) ? ZSTR_VAL(EG(scope)->name) : "");
+                       scope = EX(func)->op_array.scope;
+                       if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) {
+                               zend_throw_error(NULL, "Call to protected %s::__clone() from context '%s'", ZSTR_VAL(ce->name), scope ? ZSTR_VAL(scope->name) : "");
                                FREE_OP1();
                                HANDLE_EXCEPTION();
                        }
@@ -5040,7 +5015,7 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, UNUSED, CONST, CONST_FETCH)
 
 ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CONST)
 {
-       zend_class_entry *ce;
+       zend_class_entry *ce, *scope;
        zend_class_constant *c;
        zval *value;
        USE_OPLINE
@@ -5083,15 +5058,14 @@ ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CO
                }
 
                if (EXPECTED((c = zend_hash_find_ptr(&ce->constants_table, Z_STR_P(EX_CONSTANT(opline->op2)))) != NULL)) {
-                       if (!zend_verify_const_access(c, EG(scope))) {
+                       scope = EX(func)->op_array.scope;
+                       if (!zend_verify_const_access(c, scope)) {
                                zend_throw_error(NULL, "Cannot access %s const %s::%s", zend_visibility_string(Z_ACCESS_FLAGS(c->value)), ZSTR_VAL(ce->name), Z_STRVAL_P(EX_CONSTANT(opline->op2)));
                                HANDLE_EXCEPTION();
                        }
                        value = &c->value;
                        if (Z_CONSTANT_P(value)) {
-                               EG(scope) = ce;
-                               zval_update_constant_ex(value, 1, NULL);
-                               EG(scope) = EX(func)->op_array.scope;
+                               zval_update_constant_ex(value, ce);
                                if (UNEXPECTED(EG(exception) != NULL)) {
                                        HANDLE_EXCEPTION();
                                }
@@ -5372,7 +5346,7 @@ ZEND_VM_HANDLER(73, ZEND_INCLUDE_OR_EVAL, CONST|TMPVAR|CV, ANY, EVAL)
                        return_value = EX_VAR(opline->result.var);
                }
 
-               new_op_array->scope = EG(scope);
+               new_op_array->scope = EX(func)->op_array.scope;
 
                call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_CODE,
                        (zend_function*)new_op_array, 0,
@@ -7201,7 +7175,7 @@ ZEND_VM_HANDLER(143, ZEND_DECLARE_CONST, CONST, CONST)
 
        ZVAL_COPY_VALUE(&c.value, val);
        if (Z_OPT_CONSTANT(c.value)) {
-               if (UNEXPECTED(zval_update_constant_ex(&c.value, 0, NULL) != SUCCESS)) {
+               if (UNEXPECTED(zval_update_constant_ex(&c.value, EX(func)->op_array.scope) != SUCCESS)) {
                        FREE_OP1();
                        FREE_OP2();
                        HANDLE_EXCEPTION();
@@ -7248,7 +7222,7 @@ ZEND_VM_HANDLER(153, ZEND_DECLARE_LAMBDA_FUNCTION, CONST, UNUSED)
                object = NULL;
        }
        zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc),
-               EG(scope), called_scope, object);
+               EX(func)->op_array.scope, called_scope, object);
 
        ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
@@ -7781,13 +7755,14 @@ ZEND_VM_HANDLER(151, ZEND_ASSERT_CHECK, ANY, JMP_ADDR)
 ZEND_VM_HANDLER(157, ZEND_FETCH_CLASS_NAME, ANY, ANY, CLASS_FETCH)
 {
        uint32_t fetch_type;
-       zend_class_entry *called_scope;
+       zend_class_entry *called_scope, *scope;
        USE_OPLINE
 
        SAVE_OPLINE();
        fetch_type = opline->extended_value;
 
-       if (UNEXPECTED(EG(scope) == NULL)) {
+       scope = EX(func)->op_array.scope;
+       if (UNEXPECTED(scope == NULL)) {
                zend_throw_error(NULL, "Cannot use \"%s\" when no class scope is active",
                        fetch_type == ZEND_FETCH_CLASS_SELF ? "self" :
                        fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static");
@@ -7796,15 +7771,15 @@ ZEND_VM_HANDLER(157, ZEND_FETCH_CLASS_NAME, ANY, ANY, CLASS_FETCH)
 
        switch (fetch_type) {
                case ZEND_FETCH_CLASS_SELF:
-                       ZVAL_STR_COPY(EX_VAR(opline->result.var), EG(scope)->name);
+                       ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->name);
                        break;
                case ZEND_FETCH_CLASS_PARENT:
-                       if (UNEXPECTED(EG(scope)->parent == NULL)) {
+                       if (UNEXPECTED(scope->parent == NULL)) {
                                zend_throw_error(NULL,
                                        "Cannot use \"parent\" when current class scope has no parent");
                                HANDLE_EXCEPTION();
                        }
-                       ZVAL_STR_COPY(EX_VAR(opline->result.var), EG(scope)->parent->name);
+                       ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->parent->name);
                        break;
                case ZEND_FETCH_CLASS_STATIC:
                        if (Z_TYPE(EX(This)) == IS_OBJECT) {
@@ -7931,7 +7906,6 @@ ZEND_VM_C_LABEL(call_trampoline_end):
                zend_object *object = Z_OBJ(call->This);
                OBJ_RELEASE(object);
        }
-       EG(scope) = EX(func)->op_array.scope;
        zend_vm_stack_free_call_frame(call);
 
        if (UNEXPECTED(EG(exception) != NULL)) {
@@ -8004,7 +7978,7 @@ ZEND_VM_HANDLER(183, ZEND_BIND_STATIC, CV, CONST, REF)
 
        if (opline->extended_value) {
                if (Z_CONSTANT_P(value)) {
-                       if (UNEXPECTED(zval_update_constant_ex(value, 1, NULL) != SUCCESS)) {
+                       if (UNEXPECTED(zval_update_constant_ex(value, EX(func)->op_array.scope) != SUCCESS)) {
                                ZVAL_NULL(variable_ptr);
                                HANDLE_EXCEPTION();
                        }
index bbf9213ab0e6087353f8ccc9b8a4a4e340656ef9..cd7965bc563236cc61cbe83638bd2d1e6f585a3b 100644 (file)
@@ -526,8 +526,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_
                        execute_data = EX(prev_execute_data);
                }
 
-               EG(scope) = EX(func)->op_array.scope;
-
                if (UNEXPECTED(EG(exception) != NULL)) {
                        const zend_op *old_opline = EX(opline);
                        zend_throw_exception_internal(NULL);
@@ -701,7 +699,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_RETVAL_UNUSED_HA
        SAVE_OPLINE();
        EX(call) = call->prev_execute_data;
 
-       EG(scope) = NULL;
        ret = NULL;
        call->symbol_table = NULL;
        if (0) {
@@ -725,7 +722,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_UCALL_SPEC_RETVAL_USED_HAND
        SAVE_OPLINE();
        EX(call) = call->prev_execute_data;
 
-       EG(scope) = NULL;
        ret = NULL;
        call->symbol_table = NULL;
        if (1) {
@@ -750,7 +746,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_U
        EX(call) = call->prev_execute_data;
 
        if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
-               EG(scope) = NULL;
                if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
                        if (EXPECTED(0)) {
                                ret = EX_VAR(opline->result.var);
@@ -773,7 +768,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_U
 
                        ZEND_VM_ENTER();
                }
-               EG(scope) = EX(func)->op_array.scope;
        } else {
                zval retval;
                ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
@@ -843,7 +837,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_U
        EX(call) = call->prev_execute_data;
 
        if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
-               EG(scope) = NULL;
                if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
                        if (EXPECTED(1)) {
                                ret = EX_VAR(opline->result.var);
@@ -866,7 +859,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_BY_NAME_SPEC_RETVAL_U
 
                        ZEND_VM_ENTER();
                }
-               EG(scope) = EX(func)->op_array.scope;
        } else {
                zval retval;
                ZEND_ASSERT(fbc->type == ZEND_INTERNAL_FUNCTION);
@@ -954,7 +946,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HA
        LOAD_OPLINE();
 
        if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
-               EG(scope) = fbc->common.scope;
                if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
                        if (EXPECTED(0)) {
                                ret = EX_VAR(opline->result.var);
@@ -984,14 +975,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HA
                        }
                }
        } else if (EXPECTED(fbc->type < ZEND_USER_FUNCTION)) {
-               int should_change_scope = 0;
                zval retval;
 
-               if (fbc->common.scope) {
-                       should_change_scope = 1;
-                       EG(scope) = fbc->common.scope;
-               }
-
                call->prev_execute_data = execute_data;
                EG(current_execute_data) = call;
 
@@ -1000,11 +985,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HA
                        if (0) {
                                ZVAL_UNDEF(EX_VAR(opline->result.var));
                        }
-                       if (UNEXPECTED(should_change_scope)) {
-                               goto fcall_end_change_scope;
-                       } else {
-                               goto fcall_end;
-                       }
+                       goto fcall_end;
                }
 
                ret = 0 ? EX_VAR(opline->result.var) : &retval;
@@ -1033,11 +1014,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HA
                        zval_ptr_dtor(ret);
                }
 
-               if (UNEXPECTED(should_change_scope)) {
-                       goto fcall_end_change_scope;
-               } else {
-                       goto fcall_end;
-               }
        } else { /* ZEND_OVERLOADED_FUNCTION */
                zval retval;
 
@@ -1054,7 +1030,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_UNUSED_HA
                }
        }
 
-fcall_end_change_scope:
+fcall_end:
        if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS)) {
                object = Z_OBJ(call->This);
 #if 0
@@ -1069,9 +1045,7 @@ fcall_end_change_scope:
                }
                OBJ_RELEASE(object);
        }
-       EG(scope) = EX(func)->op_array.scope;
 
-fcall_end:
        zend_vm_stack_free_call_frame(call);
        if (UNEXPECTED(EG(exception) != NULL)) {
                zend_throw_exception_internal(NULL);
@@ -1114,7 +1088,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_USED_HAND
        LOAD_OPLINE();
 
        if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
-               EG(scope) = fbc->common.scope;
                if (UNEXPECTED((fbc->common.fn_flags & ZEND_ACC_GENERATOR) != 0)) {
                        if (EXPECTED(1)) {
                                ret = EX_VAR(opline->result.var);
@@ -1144,14 +1117,8 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_USED_HAND
                        }
                }
        } else if (EXPECTED(fbc->type < ZEND_USER_FUNCTION)) {
-               int should_change_scope = 0;
                zval retval;
 
-               if (fbc->common.scope) {
-                       should_change_scope = 1;
-                       EG(scope) = fbc->common.scope;
-               }
-
                call->prev_execute_data = execute_data;
                EG(current_execute_data) = call;
 
@@ -1160,11 +1127,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_USED_HAND
                        if (1) {
                                ZVAL_UNDEF(EX_VAR(opline->result.var));
                        }
-                       if (UNEXPECTED(should_change_scope)) {
-                               goto fcall_end_change_scope;
-                       } else {
-                               goto fcall_end;
-                       }
+                       goto fcall_end;
                }
 
                ret = 1 ? EX_VAR(opline->result.var) : &retval;
@@ -1193,11 +1156,6 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_USED_HAND
                        zval_ptr_dtor(ret);
                }
 
-               if (UNEXPECTED(should_change_scope)) {
-                       goto fcall_end_change_scope;
-               } else {
-                       goto fcall_end;
-               }
        } else { /* ZEND_OVERLOADED_FUNCTION */
                zval retval;
 
@@ -1214,7 +1172,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DO_FCALL_SPEC_RETVAL_USED_HAND
                }
        }
 
-fcall_end_change_scope:
+fcall_end:
        if (UNEXPECTED(ZEND_CALL_INFO(call) & ZEND_CALL_RELEASE_THIS)) {
                object = Z_OBJ(call->This);
 #if 0
@@ -1229,9 +1187,7 @@ fcall_end_change_scope:
                }
                OBJ_RELEASE(object);
        }
-       EG(scope) = EX(func)->op_array.scope;
 
-fcall_end:
        zend_vm_stack_free_call_frame(call);
        if (UNEXPECTED(EG(exception) != NULL)) {
                zend_throw_exception_internal(NULL);
@@ -1931,13 +1887,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ASSERT_CHECK_SPEC_HANDLER(ZEND
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_NAME_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        uint32_t fetch_type;
-       zend_class_entry *called_scope;
+       zend_class_entry *called_scope, *scope;
        USE_OPLINE
 
        SAVE_OPLINE();
        fetch_type = opline->extended_value;
 
-       if (UNEXPECTED(EG(scope) == NULL)) {
+       scope = EX(func)->op_array.scope;
+       if (UNEXPECTED(scope == NULL)) {
                zend_throw_error(NULL, "Cannot use \"%s\" when no class scope is active",
                        fetch_type == ZEND_FETCH_CLASS_SELF ? "self" :
                        fetch_type == ZEND_FETCH_CLASS_PARENT ? "parent" : "static");
@@ -1946,15 +1903,15 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_NAME_SPEC_HANDLER(
 
        switch (fetch_type) {
                case ZEND_FETCH_CLASS_SELF:
-                       ZVAL_STR_COPY(EX_VAR(opline->result.var), EG(scope)->name);
+                       ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->name);
                        break;
                case ZEND_FETCH_CLASS_PARENT:
-                       if (UNEXPECTED(EG(scope)->parent == NULL)) {
+                       if (UNEXPECTED(scope->parent == NULL)) {
                                zend_throw_error(NULL,
                                        "Cannot use \"parent\" when current class scope has no parent");
                                HANDLE_EXCEPTION();
                        }
-                       ZVAL_STR_COPY(EX_VAR(opline->result.var), EG(scope)->parent->name);
+                       ZVAL_STR_COPY(EX_VAR(opline->result.var), scope->parent->name);
                        break;
                case ZEND_FETCH_CLASS_STATIC:
                        if (Z_TYPE(EX(This)) == IS_OBJECT) {
@@ -2081,7 +2038,6 @@ call_trampoline_end:
                zend_object *object = Z_OBJ(call->This);
                OBJ_RELEASE(object);
        }
-       EG(scope) = EX(func)->op_array.scope;
        zend_vm_stack_free_call_frame(call);
 
        if (UNEXPECTED(EG(exception) != NULL)) {
@@ -2289,17 +2245,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_RECV_INIT_SPEC_CONST_HANDLER(Z
        arg_num = opline->op1.num;
        param = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var);
        if (arg_num > EX_NUM_ARGS()) {
-               ZVAL_COPY_VALUE(param, EX_CONSTANT(opline->op2));
+               ZVAL_COPY(param, EX_CONSTANT(opline->op2));
                if (Z_OPT_CONSTANT_P(param)) {
                        SAVE_OPLINE();
-                       if (UNEXPECTED(zval_update_constant_ex(param, 0, NULL) != SUCCESS)) {
+                       if (UNEXPECTED(zval_update_constant_ex(param, EX(func)->op_array.scope) != SUCCESS)) {
                                ZVAL_UNDEF(param);
                                HANDLE_EXCEPTION();
                        }
-               } else {
-                       if (UNEXPECTED(Z_OPT_REFCOUNTED_P(param))) {
-                               Z_ADDREF_P(param);
-                       }
                }
        }
 
@@ -3229,7 +3181,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_
        USE_OPLINE
 
        zval *obj;
-       zend_class_entry *ce;
+       zend_class_entry *ce, *scope;
        zend_function *clone;
        zend_object_clone_obj_t clone_call;
 
@@ -3275,16 +3227,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CONST_HANDLER(ZEND_
                if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
                        /* Ensure that if we're calling a private function, we're allowed to do so.
                         */
-                       if (UNEXPECTED(ce != EG(scope))) {
-                               zend_throw_error(NULL, "Call to private %s::__clone() from context '%s'", ZSTR_VAL(ce->name), EG(scope) ? ZSTR_VAL(EG(scope)->name) : "");
+                       scope = EX(func)->op_array.scope;
+                       if (UNEXPECTED(ce != scope)) {
+                               zend_throw_error(NULL, "Call to private %s::__clone() from context '%s'", ZSTR_VAL(ce->name), scope ? ZSTR_VAL(scope->name) : "");
 
                                HANDLE_EXCEPTION();
                        }
                } else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) {
                        /* Ensure that if we're calling a protected function, we're allowed to do so.
                         */
-                       if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), EG(scope)))) {
-                               zend_throw_error(NULL, "Call to protected %s::__clone() from context '%s'", ZSTR_VAL(ce->name), EG(scope) ? ZSTR_VAL(EG(scope)->name) : "");
+                       scope = EX(func)->op_array.scope;
+                       if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) {
+                               zend_throw_error(NULL, "Call to protected %s::__clone() from context '%s'", ZSTR_VAL(ce->name), scope ? ZSTR_VAL(scope->name) : "");
 
                                HANDLE_EXCEPTION();
                        }
@@ -3424,7 +3378,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HAN
                        return_value = EX_VAR(opline->result.var);
                }
 
-               new_op_array->scope = EG(scope);
+               new_op_array->scope = EX(func)->op_array.scope;
 
                call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_CODE,
                        (zend_function*)new_op_array, 0,
@@ -5593,7 +5547,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_CONST_HANDLER(
 
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
-       zend_class_entry *ce;
+       zend_class_entry *ce, *scope;
        zend_class_constant *c;
        zval *value;
        USE_OPLINE
@@ -5636,15 +5590,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS
                }
 
                if (EXPECTED((c = zend_hash_find_ptr(&ce->constants_table, Z_STR_P(EX_CONSTANT(opline->op2)))) != NULL)) {
-                       if (!zend_verify_const_access(c, EG(scope))) {
+                       scope = EX(func)->op_array.scope;
+                       if (!zend_verify_const_access(c, scope)) {
                                zend_throw_error(NULL, "Cannot access %s const %s::%s", zend_visibility_string(Z_ACCESS_FLAGS(c->value)), ZSTR_VAL(ce->name), Z_STRVAL_P(EX_CONSTANT(opline->op2)));
                                HANDLE_EXCEPTION();
                        }
                        value = &c->value;
                        if (Z_CONSTANT_P(value)) {
-                               EG(scope) = ce;
-                               zval_update_constant_ex(value, 1, NULL);
-                               EG(scope) = EX(func)->op_array.scope;
+                               zval_update_constant_ex(value, ce);
                                if (UNEXPECTED(EG(exception) != NULL)) {
                                        HANDLE_EXCEPTION();
                                }
@@ -6139,7 +6092,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_CONST_SPEC_CONST_CONST
 
        ZVAL_COPY_VALUE(&c.value, val);
        if (Z_OPT_CONSTANT(c.value)) {
-               if (UNEXPECTED(zval_update_constant_ex(&c.value, 0, NULL) != SUCCESS)) {
+               if (UNEXPECTED(zval_update_constant_ex(&c.value, EX(func)->op_array.scope) != SUCCESS)) {
 
 
                        HANDLE_EXCEPTION();
@@ -7832,7 +7785,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_C
                object = NULL;
        }
        zend_create_closure(EX_VAR(opline->result.var), Z_FUNC_P(zfunc),
-               EG(scope), called_scope, object);
+               EX(func)->op_array.scope, called_scope, object);
 
        ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
 }
@@ -18943,7 +18896,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
 
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
-       zend_class_entry *ce;
+       zend_class_entry *ce, *scope;
        zend_class_constant *c;
        zval *value;
        USE_OPLINE
@@ -18986,15 +18939,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_
                }
 
                if (EXPECTED((c = zend_hash_find_ptr(&ce->constants_table, Z_STR_P(EX_CONSTANT(opline->op2)))) != NULL)) {
-                       if (!zend_verify_const_access(c, EG(scope))) {
+                       scope = EX(func)->op_array.scope;
+                       if (!zend_verify_const_access(c, scope)) {
                                zend_throw_error(NULL, "Cannot access %s const %s::%s", zend_visibility_string(Z_ACCESS_FLAGS(c->value)), ZSTR_VAL(ce->name), Z_STRVAL_P(EX_CONSTANT(opline->op2)));
                                HANDLE_EXCEPTION();
                        }
                        value = &c->value;
                        if (Z_CONSTANT_P(value)) {
-                               EG(scope) = ce;
-                               zval_update_constant_ex(value, 1, NULL);
-                               EG(scope) = EX(func)->op_array.scope;
+                               zval_update_constant_ex(value, ce);
                                if (UNEXPECTED(EG(exception) != NULL)) {
                                        HANDLE_EXCEPTION();
                                }
@@ -26394,7 +26346,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND
        USE_OPLINE
 
        zval *obj;
-       zend_class_entry *ce;
+       zend_class_entry *ce, *scope;
        zend_function *clone;
        zend_object_clone_obj_t clone_call;
 
@@ -26440,16 +26392,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_UNUSED_HANDLER(ZEND
                if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
                        /* Ensure that if we're calling a private function, we're allowed to do so.
                         */
-                       if (UNEXPECTED(ce != EG(scope))) {
-                               zend_throw_error(NULL, "Call to private %s::__clone() from context '%s'", ZSTR_VAL(ce->name), EG(scope) ? ZSTR_VAL(EG(scope)->name) : "");
+                       scope = EX(func)->op_array.scope;
+                       if (UNEXPECTED(ce != scope)) {
+                               zend_throw_error(NULL, "Call to private %s::__clone() from context '%s'", ZSTR_VAL(ce->name), scope ? ZSTR_VAL(scope->name) : "");
 
                                HANDLE_EXCEPTION();
                        }
                } else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) {
                        /* Ensure that if we're calling a protected function, we're allowed to do so.
                         */
-                       if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), EG(scope)))) {
-                               zend_throw_error(NULL, "Call to protected %s::__clone() from context '%s'", ZSTR_VAL(ce->name), EG(scope) ? ZSTR_VAL(EG(scope)->name) : "");
+                       scope = EX(func)->op_array.scope;
+                       if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) {
+                               zend_throw_error(NULL, "Call to protected %s::__clone() from context '%s'", ZSTR_VAL(ce->name), scope ? ZSTR_VAL(scope->name) : "");
 
                                HANDLE_EXCEPTION();
                        }
@@ -28351,7 +28305,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CON
 
 static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
-       zend_class_entry *ce;
+       zend_class_entry *ce, *scope;
        zend_class_constant *c;
        zval *value;
        USE_OPLINE
@@ -28394,15 +28348,14 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS
                }
 
                if (EXPECTED((c = zend_hash_find_ptr(&ce->constants_table, Z_STR_P(EX_CONSTANT(opline->op2)))) != NULL)) {
-                       if (!zend_verify_const_access(c, EG(scope))) {
+                       scope = EX(func)->op_array.scope;
+                       if (!zend_verify_const_access(c, scope)) {
                                zend_throw_error(NULL, "Cannot access %s const %s::%s", zend_visibility_string(Z_ACCESS_FLAGS(c->value)), ZSTR_VAL(ce->name), Z_STRVAL_P(EX_CONSTANT(opline->op2)));
                                HANDLE_EXCEPTION();
                        }
                        value = &c->value;
                        if (Z_CONSTANT_P(value)) {
-                               EG(scope) = ce;
-                               zval_update_constant_ex(value, 1, NULL);
-                               EG(scope) = EX(func)->op_array.scope;
+                               zval_update_constant_ex(value, ce);
                                if (UNEXPECTED(EG(exception) != NULL)) {
                                        HANDLE_EXCEPTION();
                                }
@@ -35301,7 +35254,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPC
        USE_OPLINE
 
        zval *obj;
-       zend_class_entry *ce;
+       zend_class_entry *ce, *scope;
        zend_function *clone;
        zend_object_clone_obj_t clone_call;
 
@@ -35347,16 +35300,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_CV_HANDLER(ZEND_OPC
                if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
                        /* Ensure that if we're calling a private function, we're allowed to do so.
                         */
-                       if (UNEXPECTED(ce != EG(scope))) {
-                               zend_throw_error(NULL, "Call to private %s::__clone() from context '%s'", ZSTR_VAL(ce->name), EG(scope) ? ZSTR_VAL(EG(scope)->name) : "");
+                       scope = EX(func)->op_array.scope;
+                       if (UNEXPECTED(ce != scope)) {
+                               zend_throw_error(NULL, "Call to private %s::__clone() from context '%s'", ZSTR_VAL(ce->name), scope ? ZSTR_VAL(scope->name) : "");
 
                                HANDLE_EXCEPTION();
                        }
                } else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) {
                        /* Ensure that if we're calling a protected function, we're allowed to do so.
                         */
-                       if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), EG(scope)))) {
-                               zend_throw_error(NULL, "Call to protected %s::__clone() from context '%s'", ZSTR_VAL(ce->name), EG(scope) ? ZSTR_VAL(EG(scope)->name) : "");
+                       scope = EX(func)->op_array.scope;
+                       if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) {
+                               zend_throw_error(NULL, "Call to protected %s::__clone() from context '%s'", ZSTR_VAL(ce->name), scope ? ZSTR_VAL(scope->name) : "");
 
                                HANDLE_EXCEPTION();
                        }
@@ -35496,7 +35451,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_CV_HANDLE
                        return_value = EX_VAR(opline->result.var);
                }
 
-               new_op_array->scope = EG(scope);
+               new_op_array->scope = EX(func)->op_array.scope;
 
                call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_CODE,
                        (zend_function*)new_op_array, 0,
@@ -40176,7 +40131,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_STATIC_SPEC_CV_CONST_HAND
 
        if (opline->extended_value) {
                if (Z_CONSTANT_P(value)) {
-                       if (UNEXPECTED(zval_update_constant_ex(value, 1, NULL) != SUCCESS)) {
+                       if (UNEXPECTED(zval_update_constant_ex(value, EX(func)->op_array.scope) != SUCCESS)) {
                                ZVAL_NULL(variable_ptr);
                                HANDLE_EXCEPTION();
                        }
@@ -50147,7 +50102,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_TMPVAR_HANDLER(ZEND
        USE_OPLINE
        zend_free_op free_op1;
        zval *obj;
-       zend_class_entry *ce;
+       zend_class_entry *ce, *scope;
        zend_function *clone;
        zend_object_clone_obj_t clone_call;
 
@@ -50193,16 +50148,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CLONE_SPEC_TMPVAR_HANDLER(ZEND
                if (clone->op_array.fn_flags & ZEND_ACC_PRIVATE) {
                        /* Ensure that if we're calling a private function, we're allowed to do so.
                         */
-                       if (UNEXPECTED(ce != EG(scope))) {
-                               zend_throw_error(NULL, "Call to private %s::__clone() from context '%s'", ZSTR_VAL(ce->name), EG(scope) ? ZSTR_VAL(EG(scope)->name) : "");
+                       scope = EX(func)->op_array.scope;
+                       if (UNEXPECTED(ce != scope)) {
+                               zend_throw_error(NULL, "Call to private %s::__clone() from context '%s'", ZSTR_VAL(ce->name), scope ? ZSTR_VAL(scope->name) : "");
                                zval_ptr_dtor_nogc(free_op1);
                                HANDLE_EXCEPTION();
                        }
                } else if ((clone->common.fn_flags & ZEND_ACC_PROTECTED)) {
                        /* Ensure that if we're calling a protected function, we're allowed to do so.
                         */
-                       if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), EG(scope)))) {
-                               zend_throw_error(NULL, "Call to protected %s::__clone() from context '%s'", ZSTR_VAL(ce->name), EG(scope) ? ZSTR_VAL(EG(scope)->name) : "");
+                       scope = EX(func)->op_array.scope;
+                       if (UNEXPECTED(!zend_check_protected(zend_get_function_root_class(clone), scope))) {
+                               zend_throw_error(NULL, "Call to protected %s::__clone() from context '%s'", ZSTR_VAL(ce->name), scope ? ZSTR_VAL(scope->name) : "");
                                zval_ptr_dtor_nogc(free_op1);
                                HANDLE_EXCEPTION();
                        }
@@ -50243,7 +50200,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INCLUDE_OR_EVAL_SPEC_TMPVAR_HA
                        return_value = EX_VAR(opline->result.var);
                }
 
-               new_op_array->scope = EG(scope);
+               new_op_array->scope = EX(func)->op_array.scope;
 
                call = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_CODE,
                        (zend_function*)new_op_array, 0,
index ce8c7e6291f95a5b85bcd6745b4f8deebcace087..5c80b25af868a7414097de6682381469a4c7be1d 100644 (file)
@@ -269,9 +269,15 @@ static zval *Transliterator_read_property( zval *object, zval *member, int type,
 static void Transliterator_write_property( zval *object, zval *member, zval *value,
        void **cache_slot )
 {
+       zend_class_entry *scope;
        TRANSLITERATOR_PROPERTY_HANDLER_PROLOG;
 
-       if( ( EG( scope ) != Transliterator_ce_ptr ) &&
+       if (EG(fake_scope)) {
+               scope = EG(fake_scope);
+       } else {
+               scope = zend_get_executed_scope();
+       }
+       if( ( scope != Transliterator_ce_ptr ) &&
                ( zend_binary_strcmp( "id", sizeof( "id" ) - 1,
                Z_STRVAL_P( member ), Z_STRLEN_P( member ) ) == 0 ) )
        {
index e339e85d34dd3f57b370c82e57bc353a663f5749..a907eed42fd3bed940a04c73a3131c72dfa7162f 100644 (file)
@@ -1307,7 +1307,7 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags
 
                        fcc.initialized = 1;
                        fcc.function_handler = ce->constructor;
-                       fcc.calling_scope = EG(scope);
+                       fcc.calling_scope = zend_get_executed_scope();
                        fcc.called_scope = Z_OBJCE_P(return_value);
                        fcc.object = Z_OBJ_P(return_value);
 
index 58794c79df7df35540133138cbb480cb3ec77a64..61c9c15d2b10f39b4fd53e2b9c76f2232947a1d5 100644 (file)
@@ -40,8 +40,6 @@
 typedef int (*id_function_t)(void *, void *);
 typedef void (*unique_copy_ctor_func_t)(void *pElement);
 
-static zend_ast *zend_ast_clone(zend_ast *ast);
-
 static void zend_accel_destroy_zend_function(zval *zv)
 {
        zend_function *function = Z_PTR_P(zv);
@@ -169,61 +167,6 @@ static inline void zend_clone_zval(zval *src)
                        src = Z_REFVAL_P(src);
                }
        }
-       if (Z_TYPE_P(src) == IS_CONSTANT_AST) {
-               if (Z_REFCOUNT_P(src) > 1 && (ptr = accel_xlat_get(Z_AST_P(src))) != NULL) {
-                       Z_AST_P(src) = ptr;
-               } else {
-                       zend_ast_ref *old = Z_AST_P(src);
-
-                       ZVAL_NEW_AST(src, old->ast);
-                       Z_AST_P(src)->gc = old->gc;
-                       if (Z_REFCOUNT_P(src) > 1) {
-                               accel_xlat_set(old, Z_AST_P(src));
-                       }
-                       Z_ASTVAL_P(src) = zend_ast_clone(Z_ASTVAL_P(src));
-               }
-       }
-}
-
-static zend_ast *zend_ast_clone(zend_ast *ast)
-{
-       uint32_t i;
-
-       if (ast->kind == ZEND_AST_ZVAL) {
-               zend_ast_zval *copy = emalloc(sizeof(zend_ast_zval));
-               copy->kind = ZEND_AST_ZVAL;
-               copy->attr = ast->attr;
-               ZVAL_COPY_VALUE(&copy->val, zend_ast_get_zval(ast));
-               return (zend_ast *) copy;
-       } else if (zend_ast_is_list(ast)) {
-               zend_ast_list *list = zend_ast_get_list(ast);
-               zend_ast_list *copy = emalloc(
-                       sizeof(zend_ast_list) - sizeof(zend_ast *) + sizeof(zend_ast *) * list->children);
-               copy->kind = list->kind;
-               copy->attr = list->attr;
-               copy->children = list->children;
-               for (i = 0; i < list->children; i++) {
-                       if (list->child[i]) {
-                               copy->child[i] = zend_ast_clone(list->child[i]);
-                       } else {
-                               copy->child[i] = NULL;
-                       }
-               }
-               return (zend_ast *) copy;
-       } else {
-               uint32_t children = zend_ast_get_num_children(ast);
-               zend_ast *copy = emalloc(sizeof(zend_ast) - sizeof(zend_ast *) + sizeof(zend_ast *) * children);
-               copy->kind = ast->kind;
-               copy->attr = ast->attr;
-               for (i = 0; i < children; i++) {
-                       if (ast->child[i]) {
-                               copy->child[i] = zend_ast_clone(ast->child[i]);
-                       } else {
-                               copy->child[i] = NULL;
-                       }
-               }
-               return copy;
-       }
 }
 
 static void zend_hash_clone_constants(HashTable *ht, HashTable *source)
index aa3b8e82f3903f3d61a4d3689e32274bb6408b10..25a504575d2640ed192a2bd3d5ad6ddba6cf5d4d 100644 (file)
@@ -65,7 +65,6 @@
 typedef void (*zend_persist_func_t)(zval*);
 
 static void zend_persist_zval(zval *z);
-static void zend_persist_zval_const(zval *z);
 
 static const uint32_t uninitialized_bucket[-HT_MIN_MASK] =
        {HT_INVALID_IDX, HT_INVALID_IDX};
@@ -204,7 +203,7 @@ static void zend_hash_persist_immutable(HashTable *ht)
                        }
 
                        /* persist the data itself */
-                       zend_persist_zval_const(&p->val);
+                       zend_persist_zval(&p->val);
 
                        nIndex = p->h | ht->nTableMask;
                        Z_NEXT(p->val) = HT_HASH(ht, nIndex);
@@ -229,7 +228,7 @@ static void zend_hash_persist_immutable(HashTable *ht)
                }
 
                /* persist the data itself */
-               zend_persist_zval_const(&p->val);
+               zend_persist_zval(&p->val);
        }
 }
 
@@ -278,63 +277,10 @@ static void zend_persist_zval(zval *z)
                        zend_accel_store_interned_string(Z_STR_P(z));
                        Z_GC_FLAGS_P(z) |= flags;
                        Z_TYPE_FLAGS_P(z) &= ~(IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE);
-                       break;
-               case IS_ARRAY:
-                       new_ptr = zend_shared_alloc_get_xlat_entry(Z_ARR_P(z));
-                       if (new_ptr) {
-                               Z_ARR_P(z) = new_ptr;
-                               Z_TYPE_FLAGS_P(z) = IS_TYPE_IMMUTABLE;
-                       } else {
-                               if (Z_IMMUTABLE_P(z)) {
-                                       Z_ARR_P(z) = zend_accel_memdup(Z_ARR_P(z), sizeof(zend_array));
-                                       zend_hash_persist_immutable(Z_ARRVAL_P(z));
-                               } else {
-                                       GC_REMOVE_FROM_BUFFER(Z_ARR_P(z));
-                                       zend_accel_store(Z_ARR_P(z), sizeof(zend_array));
-                                       zend_hash_persist(Z_ARRVAL_P(z), zend_persist_zval);
-                                       /* make immutable array */
-                                       Z_TYPE_FLAGS_P(z) = IS_TYPE_IMMUTABLE;
-                                       GC_REFCOUNT(Z_COUNTED_P(z)) = 2;
-                                       GC_FLAGS(Z_COUNTED_P(z)) |= IS_ARRAY_IMMUTABLE;
-                                       Z_ARRVAL_P(z)->u.flags |= HASH_FLAG_STATIC_KEYS;
-                                       Z_ARRVAL_P(z)->u.flags &= ~HASH_FLAG_APPLY_PROTECTION;
-                               }
-                       }
-                       break;
-               case IS_REFERENCE:
-                       new_ptr = zend_shared_alloc_get_xlat_entry(Z_REF_P(z));
-                       if (new_ptr) {
-                               Z_REF_P(z) = new_ptr;
-                       } else {
-                               zend_accel_store(Z_REF_P(z), sizeof(zend_reference));
-                               zend_persist_zval(Z_REFVAL_P(z));
-                       }
-                       break;
-               case IS_CONSTANT_AST:
-                       new_ptr = zend_shared_alloc_get_xlat_entry(Z_AST_P(z));
-                       if (new_ptr) {
-                               Z_AST_P(z) = new_ptr;
-                       } else {
-                               zend_accel_store(Z_AST_P(z), sizeof(zend_ast_ref));
-                               Z_ASTVAL_P(z) = zend_persist_ast(Z_ASTVAL_P(z));
+                       if (Z_TYPE_P(z) == IS_CONSTANT) {
+                               Z_TYPE_FLAGS_P(z) |= IS_TYPE_IMMUTABLE;
                        }
                        break;
-       }
-}
-
-static void zend_persist_zval_static(zval *z)
-{
-       zend_uchar flags;
-       void *new_ptr;
-
-       switch (Z_TYPE_P(z)) {
-               case IS_STRING:
-               case IS_CONSTANT:
-                       flags = Z_GC_FLAGS_P(z) & ~ (IS_STR_PERSISTENT | IS_STR_INTERNED | IS_STR_PERMANENT);
-                       zend_accel_store_interned_string(Z_STR_P(z));
-                       Z_GC_FLAGS_P(z) |= flags;
-                       Z_TYPE_FLAGS_P(z) &= ~(IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE);
-                       break;
                case IS_ARRAY:
                        new_ptr = zend_shared_alloc_get_xlat_entry(Z_ARR_P(z));
                        if (new_ptr) {
@@ -381,62 +327,6 @@ static void zend_persist_zval_static(zval *z)
        }
 }
 
-static void zend_persist_zval_const(zval *z)
-{
-       zend_uchar flags;
-       void *new_ptr;
-
-       switch (Z_TYPE_P(z)) {
-               case IS_STRING:
-               case IS_CONSTANT:
-                       flags = Z_GC_FLAGS_P(z) & ~ (IS_STR_PERSISTENT | IS_STR_INTERNED | IS_STR_PERMANENT);
-                       zend_accel_memdup_interned_string(Z_STR_P(z));
-                       Z_GC_FLAGS_P(z) |= flags;
-                       Z_TYPE_FLAGS_P(z) &= ~(IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE);
-                       break;
-               case IS_ARRAY:
-                       new_ptr = zend_shared_alloc_get_xlat_entry(Z_ARR_P(z));
-                       if (new_ptr) {
-                               Z_ARR_P(z) = new_ptr;
-                               Z_TYPE_FLAGS_P(z) = IS_TYPE_IMMUTABLE;
-                       } else {
-                               if (Z_IMMUTABLE_P(z)) {
-                                       Z_ARR_P(z) = zend_accel_memdup(Z_ARR_P(z), sizeof(zend_array));
-                                       zend_hash_persist_immutable(Z_ARRVAL_P(z));
-                               } else {
-                                       GC_REMOVE_FROM_BUFFER(Z_ARR_P(z));
-                                       zend_accel_store(Z_ARR_P(z), sizeof(zend_array));
-                                       zend_hash_persist(Z_ARRVAL_P(z), zend_persist_zval);
-                                       /* make immutable array */
-                                       Z_TYPE_FLAGS_P(z) = IS_TYPE_IMMUTABLE;
-                                       GC_REFCOUNT(Z_COUNTED_P(z)) = 2;
-                                       GC_FLAGS(Z_COUNTED_P(z)) |= IS_ARRAY_IMMUTABLE;
-                                       Z_ARRVAL_P(z)->u.flags |= HASH_FLAG_STATIC_KEYS;
-                                       Z_ARRVAL_P(z)->u.flags &= ~HASH_FLAG_APPLY_PROTECTION;
-                               }
-                       }
-                       break;
-               case IS_REFERENCE:
-                       new_ptr = zend_shared_alloc_get_xlat_entry(Z_REF_P(z));
-                       if (new_ptr) {
-                               Z_REF_P(z) = new_ptr;
-                       } else {
-                               zend_accel_store(Z_REF_P(z), sizeof(zend_reference));
-                               zend_persist_zval(Z_REFVAL_P(z));
-                       }
-                       break;
-               case IS_CONSTANT_AST:
-                       new_ptr = zend_shared_alloc_get_xlat_entry(Z_AST_P(z));
-                       if (new_ptr) {
-                               Z_AST_P(z) = new_ptr;
-                       } else {
-                               zend_accel_store(Z_AST_P(z), sizeof(zend_ast_ref));
-                               Z_ASTVAL_P(z) = zend_persist_ast(Z_ASTVAL_P(z));
-                       }
-                       break;
-       }
-}
-
 static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_script* main_persistent_script)
 {
        int already_stored = 0;
@@ -472,7 +362,7 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
                if (stored) {
                        op_array->static_variables = stored;
                } else {
-                       zend_hash_persist(op_array->static_variables, zend_persist_zval_static);
+                       zend_hash_persist(op_array->static_variables, zend_persist_zval);
                        zend_accel_store(op_array->static_variables, sizeof(HashTable));
                        /* make immutable array */
                        GC_REFCOUNT(op_array->static_variables) = 2;
index 68c9d67a6af5d2889c5356b946ddc1f7181aabd0..624281c18b97f12f4b97036be286cf51dbcb452b 100644 (file)
@@ -447,7 +447,7 @@ static void pdo_stmt_construct(zend_execute_data *execute_data, pdo_stmt_t *stmt
 
                fcc.initialized = 1;
                fcc.function_handler = dbstmt_ce->constructor;
-               fcc.calling_scope = EG(scope);
+               fcc.calling_scope = zend_get_executed_scope();
                fcc.called_scope = Z_OBJCE_P(object);
                fcc.object = Z_OBJ_P(object);
 
index 91546c02c503cf1159a918a9ff556b0165690b25..c2f3c133990f702542cc91108551d6de8f54ec7c 100644 (file)
@@ -750,7 +750,7 @@ static int do_fetch_class_prepare(pdo_stmt_t *stmt) /* {{{ */
 
                fcc->initialized = 1;
                fcc->function_handler = ce->constructor;
-               fcc->calling_scope = EG(scope);
+               fcc->calling_scope = zend_get_executed_scope();
                fcc->called_scope = ce;
                return 1;
        } else if (!Z_ISUNDEF(stmt->fetch.cls.ctor_args)) {
index 82a750340916e2de45dc443bfd110d8b70fc4511..408802cfbf367ba5c700ebb6c9ef1aaaf73ae8b9 100644 (file)
@@ -2848,7 +2848,7 @@ static void php_pgsql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, zend_long result_
 
                        fcc.initialized = 1;
                        fcc.function_handler = ce->constructor;
-                       fcc.calling_scope = EG(scope);
+                       fcc.calling_scope = zend_get_executed_scope();
                        fcc.called_scope = Z_OBJCE_P(return_value);
                        fcc.object = Z_OBJ_P(return_value);
 
index fe89db9dee2493b7de2411fcbb03362298767fab..b4bd65182a2e7dd14d1b596c2047cfdaabeafaf3 100644 (file)
@@ -456,7 +456,7 @@ static void _class_string(string *str, zend_class_entry *ce, zval *obj, char *in
                zend_class_constant *c;
 
                ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->constants_table, key, c) {
-                       zval_update_constant_ex(&c->value, 1, NULL);
+                       zval_update_constant_ex(&c->value, NULL);
                        _class_const_string(str, ZSTR_VAL(key), c, indent);
                } ZEND_HASH_FOREACH_END();
        }
@@ -706,14 +706,10 @@ static void _parameter_string(string *str, zend_function *fptr, struct _zend_arg
                zend_op *precv = _get_recv_op((zend_op_array*)fptr, offset);
                if (precv && precv->opcode == ZEND_RECV_INIT && precv->op2_type != IS_UNUSED) {
                        zval zv;
-                       zend_class_entry *old_scope;
 
                        string_write(str, " = ", sizeof(" = ")-1);
                        ZVAL_DUP(&zv, RT_CONSTANT(&fptr->op_array, precv->op2));
-                       old_scope = EG(scope);
-                       EG(scope) = fptr->common.scope;
-                       zval_update_constant_ex(&zv, 1, NULL);
-                       EG(scope) = old_scope;
+                       zval_update_constant_ex(&zv, fptr->common.scope);
                        if (Z_TYPE(zv) == IS_TRUE) {
                                string_write(str, "true", sizeof("true")-1);
                        } else if (Z_TYPE(zv) == IS_FALSE) {
@@ -1931,7 +1927,7 @@ ZEND_METHOD(reflection_function, getStaticVariables)
                        fptr->op_array.static_variables = zend_array_dup(fptr->op_array.static_variables);
                }
                ZEND_HASH_FOREACH_VAL(fptr->op_array.static_variables, val) {
-                       if (UNEXPECTED(zval_update_constant_ex(val, 1, fptr->common.scope) != SUCCESS)) {
+                       if (UNEXPECTED(zval_update_constant_ex(val, fptr->common.scope) != SUCCESS)) {
                                return;
                        }
                } ZEND_HASH_FOREACH_END();
@@ -1969,7 +1965,7 @@ ZEND_METHOD(reflection_function, invoke)
 
        fcc.initialized = 1;
        fcc.function_handler = fptr;
-       fcc.calling_scope = EG(scope);
+       fcc.calling_scope = zend_get_executed_scope();
        fcc.called_scope = NULL;
        fcc.object = NULL;
 
@@ -2027,7 +2023,7 @@ ZEND_METHOD(reflection_function, invokeArgs)
 
        fcc.initialized = 1;
        fcc.function_handler = fptr;
-       fcc.calling_scope = EG(scope);
+       fcc.calling_scope = zend_get_executed_scope();
        fcc.called_scope = NULL;
        fcc.object = NULL;
 
@@ -2890,11 +2886,7 @@ ZEND_METHOD(reflection_parameter, getDefaultValue)
 
        ZVAL_COPY_VALUE(return_value, RT_CONSTANT(&param->fptr->op_array, precv->op2));
        if (Z_CONSTANT_P(return_value)) {
-               zend_class_entry *old_scope = EG(scope);
-
-               EG(scope) = param->fptr->common.scope;
-               zval_update_constant_ex(return_value, 0, NULL);
-               EG(scope) = old_scope;
+               zval_update_constant_ex(return_value, param->fptr->common.scope);
        } else {
                zval_copy_ctor(return_value);
        }
@@ -3965,7 +3957,7 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value
                /* this is necessary to make it able to work with default array
                * properties, returned to user */
                if (Z_CONSTANT(prop_copy)) {
-                       if (UNEXPECTED(zval_update_constant_ex(&prop_copy, 1, NULL) != SUCCESS)) {
+                       if (UNEXPECTED(zval_update_constant_ex(&prop_copy, NULL) != SUCCESS)) {
                                return;
                        }
                }
@@ -4621,7 +4613,7 @@ ZEND_METHOD(reflection_class, getConstants)
        GET_REFLECTION_OBJECT_PTR(ce);
        array_init(return_value);
        ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->constants_table, key, c) {
-               if (UNEXPECTED(zval_update_constant_ex(&c->value, 1, ce) != SUCCESS)) {
+               if (UNEXPECTED(zval_update_constant_ex(&c->value, ce) != SUCCESS)) {
                        zend_array_destroy(Z_ARRVAL_P(return_value));
                        return;
                }
@@ -4669,7 +4661,7 @@ ZEND_METHOD(reflection_class, getConstant)
 
        GET_REFLECTION_OBJECT_PTR(ce);
        ZEND_HASH_FOREACH_PTR(&ce->constants_table, c) {
-               if (UNEXPECTED(zval_update_constant_ex(&c->value, 1, ce) != SUCCESS)) {
+               if (UNEXPECTED(zval_update_constant_ex(&c->value, ce) != SUCCESS)) {
                        return;
                }
        } ZEND_HASH_FOREACH_END();
@@ -4856,10 +4848,10 @@ ZEND_METHOD(reflection_class, newInstance)
                return;
        }
 
-       old_scope = EG(scope);
-       EG(scope) = ce;
+       old_scope = EG(fake_scope);
+       EG(fake_scope) = ce;
        constructor = Z_OBJ_HT_P(return_value)->get_constructor(Z_OBJ_P(return_value));
-       EG(scope) = old_scope;
+       EG(fake_scope) = old_scope;
 
        /* Run the constructor if there is one */
        if (constructor) {
@@ -4893,7 +4885,7 @@ ZEND_METHOD(reflection_class, newInstance)
 
                fcc.initialized = 1;
                fcc.function_handler = constructor;
-               fcc.calling_scope = EG(scope);
+               fcc.calling_scope = zend_get_executed_scope();;
                fcc.called_scope = Z_OBJCE_P(return_value);
                fcc.object = Z_OBJ_P(return_value);
 
@@ -4959,10 +4951,10 @@ ZEND_METHOD(reflection_class, newInstanceArgs)
                return;
        }
 
-       old_scope = EG(scope);
-       EG(scope) = ce;
+       old_scope = EG(fake_scope);
+       EG(fake_scope) = ce;
        constructor = Z_OBJ_HT_P(return_value)->get_constructor(Z_OBJ_P(return_value));
-       EG(scope) = old_scope;
+       EG(fake_scope) = old_scope;
 
        /* Run the constructor if there is one */
        if (constructor) {
@@ -4995,7 +4987,7 @@ ZEND_METHOD(reflection_class, newInstanceArgs)
 
                fcc.initialized = 1;
                fcc.function_handler = constructor;
-               fcc.calling_scope = EG(scope);
+               fcc.calling_scope = zend_get_executed_scope();
                fcc.called_scope = Z_OBJCE_P(return_value);
                fcc.object = Z_OBJ_P(return_value);
 
index fc389f2365ef4e5c55009c720732f32bd61e5f66..803a5cd596481c408aaacf118d079e24b345c0fb 100644 (file)
@@ -1164,13 +1164,8 @@ static xmlNodePtr to_xml_null(encodeTypePtr type, zval *data, int style, xmlNode
 
 static void set_zval_property(zval* object, char* name, zval* val)
 {
-       zend_class_entry *old_scope;
-
-       old_scope = EG(scope);
-       EG(scope) = Z_OBJCE_P(object);
-       add_property_zval(object, name, val);
+       zend_update_property(Z_OBJCE_P(object), object, name, strlen(name), val);
        if (Z_REFCOUNTED_P(val)) Z_DELREF_P(val);
-       EG(scope) = old_scope;
 }
 
 static zval* get_zval_property(zval* object, char* name, zval *rv)
@@ -1181,15 +1176,15 @@ static zval* get_zval_property(zval* object, char* name, zval *rv)
                zend_class_entry *old_scope;
 
                ZVAL_STRING(&member, name);
-               old_scope = EG(scope);
-               EG(scope) = Z_OBJCE_P(object);
+               old_scope = EG(fake_scope);
+               EG(fake_scope) = Z_OBJCE_P(object);
                data = Z_OBJ_HT_P(object)->read_property(object, &member, BP_VAR_IS, NULL, rv);
                if (data == &EG(uninitialized_zval)) {
                        /* Hack for bug #32455 */
                        zend_property_info *property_info;
 
                        property_info = zend_get_property_info(Z_OBJCE_P(object), Z_STR(member), 1);
-                       EG(scope) = old_scope;
+                       EG(fake_scope) = old_scope;
                        if (property_info != ZEND_WRONG_PROPERTY_INFO && property_info &&
                            zend_hash_exists(Z_OBJPROP_P(object), property_info->name)) {
                                zval_ptr_dtor(&member);
@@ -1199,7 +1194,7 @@ static zval* get_zval_property(zval* object, char* name, zval *rv)
                        return NULL;
                }
                zval_ptr_dtor(&member);
-               EG(scope) = old_scope;
+               EG(fake_scope) = old_scope;
                return data;
        } else if (Z_TYPE_P(object) == IS_ARRAY) {
                zval *data_ptr;
@@ -1218,10 +1213,10 @@ static void unset_zval_property(zval* object, char* name)
                zend_class_entry *old_scope;
 
                ZVAL_STRING(&member, name);
-               old_scope = EG(scope);
-               EG(scope) = Z_OBJCE_P(object);
+               old_scope = EG(fake_scope);
+               EG(fake_scope) = Z_OBJCE_P(object);
                Z_OBJ_HT_P(object)->unset_property(object, &member, NULL);
-               EG(scope) = old_scope;
+               EG(fake_scope) = old_scope;
                zval_ptr_dtor(&member);
        } else if (Z_TYPE_P(object) == IS_ARRAY) {
                zend_hash_str_del(Z_ARRVAL_P(object), name, strlen(name));
index e73e0f08a07ca64a5e159ec8ba098a5d475d2478..b683c16d942fe09b529da0095b77912921728b28 100644 (file)
@@ -71,7 +71,7 @@ static inline void spl_instantiate_arg_n(zend_class_entry *pce, zval *retval, in
 
        fcc.initialized = 1;
        fcc.function_handler = func;
-       fcc.calling_scope = EG(scope);
+       fcc.calling_scope = zend_get_executed_scope();
        fcc.called_scope = pce;
        fcc.object = Z_OBJ_P(retval);
 
index 61ed3c0bd9496105d6fc44e2f2d8c9f2d79629de..d1281c255721cf46de2aa7ecabb1e0ee7792eb8c 100644 (file)
@@ -1843,8 +1843,11 @@ PHP_FUNCTION(extract)
                                if (var_exists && ZSTR_LEN(var_name) == sizeof("GLOBALS")-1 && !strcmp(ZSTR_VAL(var_name), "GLOBALS")) {
                                        break;
                                }
-                               if (var_exists && ZSTR_LEN(var_name) == sizeof("this")-1  && !strcmp(ZSTR_VAL(var_name), "this") && EG(scope) && ZSTR_LEN(EG(scope)->name) != 0) {
-                                       break;
+                               if (var_exists && ZSTR_LEN(var_name) == sizeof("this")-1  && !strcmp(ZSTR_VAL(var_name), "this")) {
+                                       zend_class_entry *scope = zend_get_executed_scope();
+                                       if (scope && ZSTR_LEN(scope->name) != 0) {
+                                               break;
+                                       }
                                }
                                ZVAL_STR_COPY(&final_name, var_name);
                                break;
index 109ba3ba22fb584dee9db4151a292ba833f276f8..2cb6285f4e30e2a66908abc801c27db8cd281ff1 100644 (file)
@@ -164,7 +164,6 @@ PHP_FUNCTION(assert)
        if (Z_TYPE_P(assertion) == IS_STRING) {
                zval retval;
                int old_error_reporting = 0; /* shut up gcc! */
-               zend_class_entry *orig_scope = EG(scope);
 
                myeval = Z_STRVAL_P(assertion);
 
@@ -194,8 +193,6 @@ PHP_FUNCTION(assert)
                        EG(error_reporting) = old_error_reporting;
                }
 
-               EG(scope) = orig_scope;
-
                convert_to_boolean(&retval);
                val = Z_TYPE(retval) == IS_TRUE;
        } else {
index 6323d18b5f18ea10998a5f8bc06a878fa052ed04..0481e41a6e33ea2e6e135ec0f6acce3161d8028f 100644 (file)
@@ -3834,16 +3834,18 @@ PHP_FUNCTION(constant)
 {
        zend_string *const_name;
        zval *c;
+       zend_class_entry *scope;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS(), "S", &const_name) == FAILURE) {
                return;
        }
 
-       c = zend_get_constant_ex(const_name, NULL, ZEND_FETCH_CLASS_SILENT);
+       scope = zend_get_executed_scope();
+       c = zend_get_constant_ex(const_name, scope, ZEND_FETCH_CLASS_SILENT);
        if (c) {
                ZVAL_COPY_VALUE(return_value, c);
                if (Z_CONSTANT_P(return_value)) {
-                       if (UNEXPECTED(zval_update_constant_ex(return_value, 1, NULL) != SUCCESS)) {
+                       if (UNEXPECTED(zval_update_constant_ex(return_value, scope) != SUCCESS)) {
                                return;
                        }
                }
index 330cb49f08518656c17c7e4049b420a8c97aba58..e848afdeb71226046b08dec9c0da616043ec7ef6 100644 (file)
@@ -954,12 +954,8 @@ static void php_wddx_pop_element(void *user_data, const XML_Char *name)
                                                /* Clean up class name var entry */
                                                zval_ptr_dtor(&ent1->data);
                                        } else if (Z_TYPE(ent2->data) == IS_OBJECT) {
-                                               zend_class_entry *old_scope = EG(scope);
-
-                                               EG(scope) = Z_OBJCE(ent2->data);
-                                               add_property_zval(&ent2->data, ent1->varname, &ent1->data);
+                                               zend_update_property(Z_OBJCE(ent2->data), &ent2->data, ent1->varname, strlen(ent1->varname), &ent1->data);
                                                if Z_REFCOUNTED(ent1->data) Z_DELREF(ent1->data);
-                                               EG(scope) = old_scope;
                                        } else {
                                                zend_symtable_str_update(target_hash, ent1->varname, strlen(ent1->varname), &ent1->data);
                                        }
index 5ad7dc2e649d6fb68a70729ce9230c7609a17b1b..eb8b32eed9e887f520bf5f4518472353c947ed38 100644 (file)
@@ -308,7 +308,7 @@ static void user_stream_create_object(struct php_user_stream_wrapper *uwrap, php
 
                fcc.initialized = 1;
                fcc.function_handler = uwrap->ce->constructor;
-               fcc.calling_scope = EG(scope);
+               fcc.calling_scope = zend_get_executed_scope();
                fcc.called_scope = Z_OBJCE_P(object);
                fcc.object = Z_OBJ_P(object);
 
index d6256a84af90a12d85e9fa109fdc743f60ac6790..f64d18b4bbff0b7f93b97704a54a78db2f7fd74d 100644 (file)
@@ -36,8 +36,6 @@ void phpdbg_restore_frame(void) /* {{{ */
 
        /* move things back */
        EG(current_execute_data) = PHPDBG_FRAME(execute_data);
-
-       EG(scope) = PHPDBG_EX(func)->op_array.scope;
 } /* }}} */
 
 void phpdbg_switch_frame(int frame) /* {{{ */
@@ -78,8 +76,6 @@ void phpdbg_switch_frame(int frame) /* {{{ */
                /* backup things and jump back */
                PHPDBG_FRAME(execute_data) = EG(current_execute_data);
                EG(current_execute_data) = execute_data;
-
-               EG(scope) = PHPDBG_EX(func)->op_array.scope;
        }
 
        phpdbg_notice("frame", "id=\"%d\"", "Switched to frame #%d", frame);
index e9cf1bc0b8618586aea452887b68df43220b9b64..2e97ad4b73606d3a8eb047ab8903ae7fde15d71f 100644 (file)
@@ -200,11 +200,12 @@ void phpdbg_list_function_byname(const char *str, size_t len) /* {{{ */
 
        /* search active scope if begins with period */
        if (func_name[0] == '.') {
-               if (EG(scope)) {
+               zend_class_entry *scope = zend_get_executed_scope();
+               if (scope) {
                        func_name++;
                        func_name_len--;
 
-                       func_table = &EG(scope)->function_table;
+                       func_table = &scope->function_table;
                } else {
                        phpdbg_error("inactive", "type=\"noclasses\"", "No active class");
                        return;
index 3725bf608375a9d739b916c43a6fc6b77b03e1f4..034354a9e76740b649a0eb8a3658878c96d38097 100644 (file)
@@ -217,11 +217,13 @@ PHPDBG_PRINT(func) /* {{{ */
        zend_string *lcname;
        /* search active scope if begins with period */
        if (func_name[0] == '.') {
-               if (EG(scope)) {
+               zend_class_entry *scope = zend_get_executed_scope();
+
+               if (scope) {
                        func_name++;
                        func_name_len--;
 
-                       func_table = &EG(scope)->function_table;
+                       func_table = &scope->function_table;
                } else {
                        phpdbg_error("inactive", "type=\"noclasses\"", "No active class");
                        return SUCCESS;
index a9fd351ffdc773a0cc49a354ecfba07f279cd676..787517dd9dcfa7188de8f3af24e76abbe2df53fd 100644 (file)
@@ -797,7 +797,6 @@ PHPDBG_COMMAND(ev) /* {{{ */
        zval retval;
 
        zend_execute_data *original_execute_data = EG(current_execute_data);
-       zend_class_entry *original_scope = EG(scope);
        zend_vm_stack original_stack = EG(vm_stack);
        zend_object *ex = NULL;
 
@@ -845,7 +844,6 @@ PHPDBG_COMMAND(ev) /* {{{ */
                        OBJ_RELEASE(ex);
                }
                EG(current_execute_data) = original_execute_data;
-               EG(scope) = original_scope;
                EG(vm_stack_top) = original_stack->top;
                EG(vm_stack_end) = original_stack->end;
                EG(vm_stack) = original_stack;
index 2c324aa5dcad17bfe0208cf79833cde093798301..0224ff4fd1e18d4066325bc2da69839484b5a3df 100644 (file)
@@ -680,7 +680,9 @@ static int phpdbg_watchpoint_parse_step(char *name, size_t namelen, char *key, s
 }
 
 static int phpdbg_watchpoint_parse_symtables(char *input, size_t len, int (*callback)(phpdbg_watchpoint_t *)) {
-       if (EG(scope) && len >= 5 && !memcmp("$this", input, 5)) {
+       zend_class_entry *scope = zend_get_executed_scope();
+
+       if (scope && len >= 5 && !memcmp("$this", input, 5)) {
                zend_hash_str_add(EG(current_execute_data)->symbol_table, ZEND_STRL("this"), &EG(current_execute_data)->This);
        }