The solution I'm tempted to pursue for this is to back up yet another step and make autoglobals be CVs by extending the zend_compiled_variable struct to contain a flag indicating how the var should be fetched (the determination for which happens during fetch_simple_var during the compilation. This would then yield an opcode stack like the following:

Okay, here's a shockingly simple patch for allowing auto globals to be treated as CVs. The one question mark I've got in here is: Why the last check in fetch_simple_var_ex() for the ZEND_BEGIN_SILENCE opcode? This seems completely unnecessary from what I can tell and shouldn't bar a variable (global or not) from being treated as a CV...

Am I missing something really obvious?

-Sara
Index: Zend/zend_compile.h
===================================================================
RCS file: /repository/ZendEngine2/zend_compile.h,v
retrieving revision 1.352
diff -u -p -r1.352 zend_compile.h
--- Zend/zend_compile.h 10 Jan 2007 15:59:55 -0000      1.352
+++ Zend/zend_compile.h 15 Jan 2007 22:48:24 -0000
@@ -174,6 +174,7 @@ typedef struct _zend_compiled_variable {
        zstr name;
        int name_len;
        ulong hash_value;
+       zend_uint fetch_type;
 } zend_compiled_variable;
 
 struct _zend_op_array {
Index: Zend/zend_compile.c
===================================================================
RCS file: /repository/ZendEngine2/zend_compile.c,v
retrieving revision 1.735
diff -u -p -r1.735 zend_compile.c
--- Zend/zend_compile.c 10 Jan 2007 15:59:55 -0000      1.735
+++ Zend/zend_compile.c 15 Jan 2007 22:48:24 -0000
@@ -267,7 +267,7 @@ static zend_uint get_temporary_variable(
        return (op_array->T)++ * sizeof(temp_variable);
 }
 
-static int lookup_cv(zend_op_array *op_array, zend_uchar type, zstr name, int 
name_len)
+static int lookup_cv(zend_op_array *op_array, zend_uchar type, zstr name, int 
name_len TSRMLS_DC)
 {
        int i = 0;
        ulong hash_value = zend_u_inline_hash_func(type, name, name_len+1);
@@ -290,6 +290,7 @@ static int lookup_cv(zend_op_array *op_a
        op_array->vars[i].name = name; /* estrndup(name, name_len); */
        op_array->vars[i].name_len = name_len;
        op_array->vars[i].hash_value = hash_value;
+       op_array->vars[i].fetch_type = zend_u_is_auto_global(type, name, 
name_len TSRMLS_CC) ? ZEND_FETCH_GLOBAL : ZEND_FETCH_LOCAL;
        return i;
 }
 
@@ -380,13 +381,12 @@ void fetch_simple_variable_ex(znode *res
        if (varname->op_type == IS_CONST &&
            (Z_TYPE(varname->u.constant) == IS_STRING ||
             Z_TYPE(varname->u.constant) == IS_UNICODE) &&
-           !zend_u_is_auto_global(Z_TYPE(varname->u.constant), 
Z_UNIVAL(varname->u.constant), Z_UNILEN(varname->u.constant) TSRMLS_CC) &&
            !(Z_UNILEN(varname->u.constant) == (sizeof("this")-1) &&
              ZEND_U_EQUAL(Z_TYPE(varname->u.constant), 
Z_UNIVAL(varname->u.constant), Z_UNILEN(varname->u.constant), "this", 
sizeof("this")-1)) &&
            (CG(active_op_array)->last == 0 ||
             CG(active_op_array)->opcodes[CG(active_op_array)->last-1].opcode 
!= ZEND_BEGIN_SILENCE)) {
                result->op_type = IS_CV;
-               result->u.var = lookup_cv(CG(active_op_array), 
Z_TYPE(varname->u.constant), Z_UNIVAL(varname->u.constant), 
Z_UNILEN(varname->u.constant));
+               result->u.var = lookup_cv(CG(active_op_array), 
Z_TYPE(varname->u.constant), Z_UNIVAL(varname->u.constant), 
Z_UNILEN(varname->u.constant) TSRMLS_CC);
                result->u.EA.type = 0;
                return;
        }
Index: Zend/zend_execute.c
===================================================================
RCS file: /repository/ZendEngine2/zend_execute.c,v
retrieving revision 1.757
diff -u -p -r1.757 zend_execute.c
--- Zend/zend_execute.c 10 Jan 2007 15:59:55 -0000      1.757
+++ Zend/zend_execute.c 15 Jan 2007 22:48:24 -0000
@@ -226,8 +226,9 @@ static inline zval *_get_zval_ptr_cv(zno
        if (!*ptr) {
                zend_compiled_variable *cv = &CV_DEF_OF(node->u.var);
                zend_uchar utype = UG(unicode)?IS_UNICODE:IS_STRING;
+               HashTable *symbol_table = (cv->fetch_type == ZEND_FETCH_GLOBAL) 
? &EG(symbol_table) : EG(active_symbol_table);
 
-               if (zend_u_hash_quick_find(EG(active_symbol_table), utype, 
cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
+               if (zend_u_hash_quick_find(symbol_table, utype, cv->name, 
cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
                        switch (type) {
                                case BP_VAR_R:
                                case BP_VAR_UNSET:
@@ -296,8 +297,9 @@ static inline zval **_get_zval_ptr_ptr_c
        if (!*ptr) {
                zend_compiled_variable *cv = &CV_DEF_OF(node->u.var);
                zend_uchar utype = UG(unicode)?IS_UNICODE:IS_STRING;
+               HashTable *symbol_table = (cv->fetch_type == ZEND_FETCH_GLOBAL) 
? &EG(symbol_table) : EG(active_symbol_table);
 
-               if (zend_u_hash_quick_find(EG(active_symbol_table), utype, 
cv->name, cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
+               if (zend_u_hash_quick_find(symbol_table, utype, cv->name, 
cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
                        switch (type) {
                                case BP_VAR_R:
                                case BP_VAR_UNSET:

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to