Hi Sara,

I fixed one error in your patch, so now it passes all tests.

BTW I am against this patch.

1) It adds sloppily built functionality into the core and slowdowns EACH
dimension or property fetch both at run-time and compilation-time. I think
it is a big cost for $_GET/$_POST encoding-conversion, but it is only my
opinion.

2) It adds pointer to zend_auto_global into zend_compiled_variable. This
makes troubles for opcode caches - zend_compiled_variable(s) may lay in
shared memory, so they cannot point to process specific data. I think this
issue can be fixed using indirect pointer (index).

I would prefer rollback "auto-globals CV" patch and commit (or not) the
whole patch after conclusion.

Why did you reject auto-globals as overloaded arrays?

Thanks. Dmitry.

> -----Original Message-----
> From: Sara Golemon [mailto:[EMAIL PROTECTED] 
> Sent: Wednesday, January 24, 2007 10:58 PM
> To: internals@lists.php.net; Dmitry Stogov; Andi Gutmans; 
> Andrei Zmievski
> Subject: [PHP-DEV] Runtime-JIT, the whole enchilada
> 
> 
> Dmitry-
> 
>    You asked for it, you get it :)  Hopefully it'll be 
> self-explanatory, 
> the one part I hope you don't notice is that I put the 
> auto_global check 
> back into fetch_simple_variable_ex in order to force direct access to 
> autoglobals ($foo = $_GET;    foreach($_POST as ...)  etc...) as 
> non-auto-globals.  Ultimately this made catching the 
> difference between 
> a whole var access and a dim/obj access much more 
> straight-forward and 
> computationally cheap.  It comes at a slight cost for those 
> fetches, but 
> hopefully they're in the minority.
> 
> Bench numbers with this patch:
> simple             0.461
> simplecall         1.985
> simpleucall        2.900
> simpleudcall       3.488
> mandel             2.136
> mandel2            3.192
> ackermann(7)       3.490
> ary(50000)         0.154
> ary2(50000)        0.137
> ary3(2000)         1.076
> fibo(30)           9.766
> hash1(50000)       0.423
> hash2(500)         0.307
> heapsort(20000)    0.799
> matrix(20)         0.526
> nestedloop(12)     0.866
> sieve(30)          0.630
> strcat(200000)     0.303
> ------------------------
> Total             32.639
> 
> -Sara
> 
> 
Index: main/php_variables.c
===================================================================
RCS file: /repository/php-src/main/php_variables.c,v
retrieving revision 1.136
diff -u -p -d -r1.136 php_variables.c
--- main/php_variables.c        1 Jan 2007 09:29:35 -0000       1.136
+++ main/php_variables.c        26 Jan 2007 10:23:11 -0000
@@ -628,9 +628,9 @@ void _php_import_environment_variables(z
        }
 }
 
-zend_bool php_std_auto_global_callback(char *name, uint name_len TSRMLS_DC)
+zend_bool php_std_auto_global_callback(zend_auto_global *auto_global, int 
stage, zval *ag_val, int fetch_op, zval *member TSRMLS_DC)
 {
-       zend_printf("%s\n", name);
+       zend_printf("%s\n", auto_global->name);
        return 0; /* don't rearm */
 }
 
@@ -802,9 +802,13 @@ static void php_autoglobal_merge(HashTab
 }
 /* }}} */
 
-static zend_bool php_auto_globals_create_server(char *name, uint name_len 
TSRMLS_DC);
-static zend_bool php_auto_globals_create_env(char *name, uint name_len 
TSRMLS_DC);
-static zend_bool php_auto_globals_create_request(char *name, uint name_len 
TSRMLS_DC);
+static zend_auto_global *php_server_auto_global = NULL;
+static zend_auto_global *php_env_auto_global = NULL;
+static zend_auto_global *php_request_auto_global = NULL;
+
+static zend_bool php_auto_globals_create_server(zend_auto_global *auto_global, 
int stage, zval *ag_val, int fetch_op, zval *member TSRMLS_DC);
+static zend_bool php_auto_globals_create_env(zend_auto_global *auto_global, 
int stage, zval *ag_val, int fetch_op, zval *member TSRMLS_DC);
+static zend_bool php_auto_globals_create_request(zend_auto_global 
*auto_global, int stage, zval *ag_val, int fetch_op, zval *member TSRMLS_DC);
 
 /* {{{ php_hash_environment
  */
@@ -861,16 +865,14 @@ int php_hash_environment(TSRMLS_D)
                        case 'e':
                        case 'E':
                                if (!jit_initialization && !_gpc_flags[3]) {
-                                       zend_auto_global_disable_jit("_ENV", 
sizeof("_ENV")-1 TSRMLS_CC);
-                                       php_auto_globals_create_env("_ENV", 
sizeof("_ENV")-1 TSRMLS_CC);
+                                       php_env_auto_global->armed = 
php_auto_globals_create_env(php_env_auto_global, ZEND_RT, NULL, ZEND_FETCH_R, 
NULL TSRMLS_CC);
                                        _gpc_flags[3] = 1;
                                }
                                break;
                        case 's':
                        case 'S':
                                if (!jit_initialization && !_gpc_flags[4]) {
-                                       zend_auto_global_disable_jit("_SERVER", 
sizeof("_SERVER")-1 TSRMLS_CC);
-                                       php_register_server_variables(TSRMLS_C);
+                                       php_server_auto_global->armed = 
php_auto_globals_create_server(php_server_auto_global, ZEND_RT, NULL, 
ZEND_FETCH_R, NULL TSRMLS_CC);
                                        _gpc_flags[4] = 1;
                                }
                                break;
@@ -904,15 +906,14 @@ int php_hash_environment(TSRMLS_D)
 
        /* Create _REQUEST */
        if (!jit_initialization) {
-               zend_auto_global_disable_jit("_REQUEST", sizeof("_REQUEST")-1 
TSRMLS_CC);
-               php_auto_globals_create_request("_REQUEST", 
sizeof("_REQUEST")-1 TSRMLS_CC);
+               php_request_auto_global->armed = 
php_auto_globals_create_request(php_request_auto_global, ZEND_RT, NULL, 
ZEND_FETCH_R, NULL TSRMLS_CC);
        }
 
        return SUCCESS;
 }
 /* }}} */
 
-static zend_bool php_auto_globals_create_server(char *name, uint name_len 
TSRMLS_DC)
+static zend_bool php_auto_globals_create_server(zend_auto_global *auto_global, 
int stage, zval *ag_val, int fetch_op, zval *member TSRMLS_DC)
 {
        if (PG(variables_order) && (strchr(PG(variables_order),'S') || 
strchr(PG(variables_order),'s'))) {
                php_register_server_variables(TSRMLS_C);
@@ -944,13 +945,13 @@ static zend_bool php_auto_globals_create
                PG(http_globals)[TRACK_VARS_SERVER] = server_vars;
        }
 
-       zend_ascii_hash_update(&EG(symbol_table), name, name_len + 1, 
&PG(http_globals)[TRACK_VARS_SERVER], sizeof(zval *), NULL);
+       zend_ascii_hash_update(&EG(symbol_table), auto_global->name, 
auto_global->name_len + 1, &PG(http_globals)[TRACK_VARS_SERVER], sizeof(zval 
*), NULL);
        PG(http_globals)[TRACK_VARS_SERVER]->refcount++;
 
        return 0; /* don't rearm */
 }
 
-static zend_bool php_auto_globals_create_env(char *name, uint name_len 
TSRMLS_DC)
+static zend_bool php_auto_globals_create_env(zend_auto_global *auto_global, 
int stage, zval *ag_val, int fetch_op, zval *member TSRMLS_DC)
 {
        zval *env_vars = NULL;
        ALLOC_ZVAL(env_vars);
@@ -965,13 +966,13 @@ static zend_bool php_auto_globals_create
                
php_import_environment_variables(PG(http_globals)[TRACK_VARS_ENV] TSRMLS_CC);
        }
 
-       zend_ascii_hash_update(&EG(symbol_table), name, name_len + 1, 
&PG(http_globals)[TRACK_VARS_ENV], sizeof(zval *), NULL);
+       zend_ascii_hash_update(&EG(symbol_table), auto_global->name, 
auto_global->name_len + 1, &PG(http_globals)[TRACK_VARS_ENV], sizeof(zval *), 
NULL);
        PG(http_globals)[TRACK_VARS_ENV]->refcount++;
 
        return 0; /* don't rearm */
 }
 
-static zend_bool php_auto_globals_create_request(char *name, uint name_len 
TSRMLS_DC)
+static zend_bool php_auto_globals_create_request(zend_auto_global 
*auto_global, int stage, zval *ag_val, int fetch_op, zval *member TSRMLS_DC)
 {
        zval *form_variables;
        unsigned char _gpc_flags[3] = {0, 0, 0};
@@ -1007,7 +1008,7 @@ static zend_bool php_auto_globals_create
                }
        }
 
-       zend_ascii_hash_update(&EG(symbol_table), "_REQUEST", 
sizeof("_REQUEST"), &form_variables, sizeof(zval *), NULL);
+       zend_ascii_hash_update(&EG(symbol_table), auto_global->name, 
auto_global->name_len + 1, &form_variables, sizeof(zval *), NULL);
        return 0;
 }
 
@@ -1016,9 +1017,9 @@ void php_startup_auto_globals(TSRMLS_D)
        zend_register_auto_global("_GET", sizeof("_GET")-1, NULL TSRMLS_CC);
        zend_register_auto_global("_POST", sizeof("_POST")-1, NULL TSRMLS_CC);
        zend_register_auto_global("_COOKIE", sizeof("_COOKIE")-1, NULL 
TSRMLS_CC);
-       zend_register_auto_global("_SERVER", sizeof("_SERVER")-1, 
php_auto_globals_create_server TSRMLS_CC);
-       zend_register_auto_global("_ENV", sizeof("_ENV")-1, 
php_auto_globals_create_env TSRMLS_CC);
-       zend_register_auto_global("_REQUEST", sizeof("_REQUEST")-1, 
php_auto_globals_create_request TSRMLS_CC);
+       zend_register_auto_global_ex("_SERVER", sizeof("_SERVER")-1, 
php_auto_globals_create_server, &php_server_auto_global TSRMLS_CC);
+       zend_register_auto_global_ex("_ENV", sizeof("_ENV")-1, 
php_auto_globals_create_env, &php_env_auto_global TSRMLS_CC);
+       zend_register_auto_global_ex("_REQUEST", sizeof("_REQUEST")-1, 
php_auto_globals_create_request, &php_request_auto_global TSRMLS_CC);
        zend_register_auto_global("_FILES", sizeof("_FILES")-1, NULL TSRMLS_CC);
 }
 
Index: Zend/zend_compile.c
===================================================================
RCS file: /repository/ZendEngine2/zend_compile.c,v
retrieving revision 1.736
diff -u -p -d -r1.736 zend_compile.c
--- Zend/zend_compile.c 20 Jan 2007 20:36:55 -0000      1.736
+++ Zend/zend_compile.c 26 Jan 2007 10:23:12 -0000
@@ -290,7 +290,8 @@ 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;
+       op_array->vars[i].auto_global = NULL;
+       op_array->vars[i].fetch_type = zend_u_is_auto_global(type, name, 
name_len, &(op_array->vars[i].auto_global) TSRMLS_CC) ? ZEND_FETCH_AUTO_GLOBAL 
: ZEND_FETCH_LOCAL;
        return i;
 }
 
@@ -377,18 +378,22 @@ void fetch_simple_variable_ex(znode *res
        zend_op opline;
        zend_op *opline_ptr;
        zend_llist *fetch_list_ptr;
+       long fetch_type = ZEND_FETCH_LOCAL;
 
        if (varname->op_type == IS_CONST &&
            (Z_TYPE(varname->u.constant) == IS_STRING ||
             Z_TYPE(varname->u.constant) == IS_UNICODE) &&
            !(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) TSRMLS_CC);
-               result->u.EA.type = 0;
-               return;
+             ZEND_U_EQUAL(Z_TYPE(varname->u.constant), 
Z_UNIVAL(varname->u.constant), Z_UNILEN(varname->u.constant), "this", 
sizeof("this")-1))) {
+               if (zend_u_is_auto_global(Z_TYPE(varname->u.constant), 
Z_UNIVAL(varname->u.constant), Z_UNILEN(varname->u.constant), NULL TSRMLS_CC)) {
+                       fetch_type = ZEND_FETCH_AUTO_GLOBAL;
+               } else if (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) TSRMLS_CC);
+                       result->u.EA.type = 0;
+                       return;
+               }
        }
 
        if (bp) {
@@ -405,15 +410,7 @@ void fetch_simple_variable_ex(znode *res
        opline_ptr->op1 = *varname;
        *result = opline_ptr->result;
        SET_UNUSED(opline_ptr->op2);
-
-       opline_ptr->op2.u.EA.type = ZEND_FETCH_LOCAL;
-       if (varname->op_type == IS_CONST &&
-           (Z_TYPE(varname->u.constant) == IS_STRING ||
-            Z_TYPE(varname->u.constant) == IS_UNICODE)) {
-               if (zend_u_is_auto_global(Z_TYPE(varname->u.constant), 
Z_UNIVAL(varname->u.constant), Z_UNILEN(varname->u.constant) TSRMLS_CC)) {
-                       opline_ptr->op2.u.EA.type = ZEND_FETCH_GLOBAL;
-               }
-       }
+       opline_ptr->op2.u.EA.type = fetch_type;
 
        if (bp) {
                zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr);
@@ -492,6 +489,31 @@ void fetch_array_dim(znode *result, znod
        zend_op opline;
        zend_llist *fetch_list_ptr;
 
+       zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr);
+       if (fetch_list_ptr->count == 1) {
+               zend_llist_element *le = fetch_list_ptr->head;
+               zend_op *parentop = (zend_op*)le->data;
+
+               if (parentop && parentop->opcode == ZEND_FETCH_W &&
+                   (parentop->op2.u.EA.type == ZEND_FETCH_LOCAL ||
+                    parentop->op2.u.EA.type == ZEND_FETCH_AUTO_GLOBAL) &&
+                       parent->op_type == IS_VAR && parentop->result.op_type 
== IS_VAR && parent->u.var == parentop->result.u.var &&
+                       parentop->op1.op_type == IS_CONST &&
+                       (Z_TYPE(parentop->op1.u.constant) == IS_STRING || 
Z_TYPE(parentop->op1.u.constant) == IS_UNICODE) &&
+                       !(Z_UNILEN(parentop->op1.u.constant) == 
(sizeof("this")-1) &&  ZEND_U_EQUAL(Z_TYPE(parentop->op1.u.constant), 
Z_UNIVAL(parentop->op1.u.constant), Z_UNILEN(parentop->op1.u.constant), "this", 
sizeof("this")-1)) ) {
+                       /* Recompile CV and rewrite previous op to direct 
FETCH_DIM */
+                       zval tmp = parentop->op1.u.constant;
+                       parentop->opcode = ZEND_FETCH_DIM_W;
+                       parentop->op1.op_type = IS_CV;
+                       parentop->op1.u.var = lookup_cv(CG(active_op_array), 
Z_TYPE(tmp), Z_UNIVAL(tmp), Z_UNILEN(tmp) TSRMLS_CC);
+                       parentop->op1.u.EA.type = 0;
+                       parentop->op2 = *dim;
+                       parentop->extended_value = ZEND_FETCH_STANDARD;
+                       *result = parentop->result;
+                       return;
+               }
+       }
+
        init_op(&opline TSRMLS_CC);
        opline.opcode = ZEND_FETCH_DIM_W;       /* the backpatching routine 
assumes W */
        opline.result.op_type = IS_VAR;
@@ -502,7 +524,6 @@ void fetch_array_dim(znode *result, znod
        opline.extended_value = ZEND_FETCH_STANDARD;
        *result = opline.result;
 
-       zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr);
        zend_llist_add_element(fetch_list_ptr, &opline);
 }
 
@@ -3261,7 +3282,6 @@ void zend_do_fetch_property(znode *resul
        zend_op *opline_ptr=NULL;
 
        zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr);
-
        if (fetch_list_ptr->count == 1) {
                zend_llist_element *le;
 
@@ -3295,6 +3315,21 @@ void zend_do_fetch_property(znode *resul
                        }
                        *result = opline_ptr->result;
                        return;
+               } else if (opline_ptr && opline_ptr->opcode == ZEND_FETCH_W &&
+                   (opline_ptr->op2.u.EA.type == ZEND_FETCH_LOCAL ||
+                    opline_ptr->op2.u.EA.type == ZEND_FETCH_AUTO_GLOBAL) &&
+                       object->op_type == IS_VAR && opline_ptr->result.op_type 
== IS_VAR && object->u.var == opline_ptr->result.u.var &&
+                       opline_ptr->op1.op_type == IS_CONST &&
+                       (Z_TYPE(opline_ptr->op1.u.constant) == IS_STRING || 
Z_TYPE(opline_ptr->op1.u.constant) == IS_UNICODE) ) {
+                       /* Recompile CV and rewrite previous op to direct 
FETCH_OBJ */
+                       zval tmp = opline_ptr->op1.u.constant;
+                       opline_ptr->opcode = ZEND_FETCH_OBJ_W;
+                       opline_ptr->op1.op_type = IS_CV;
+                       opline_ptr->op1.u.var = lookup_cv(CG(active_op_array), 
Z_TYPE(tmp), Z_UNIVAL(tmp), Z_UNILEN(tmp) TSRMLS_CC);
+                       opline_ptr->op1.u.EA.type = 0;
+                       opline_ptr->op2 = *property;
+                       *result = opline_ptr->result;
+                       return;
                }
        }
 
@@ -4312,13 +4347,16 @@ void zend_auto_global_dtor(zend_auto_glo
 }
 
 
-zend_bool zend_u_is_auto_global(zend_uchar type, zstr name, uint name_len 
TSRMLS_DC)
+zend_bool zend_u_is_auto_global(zend_uchar type, zstr name, uint name_len, 
zend_auto_global **pauto TSRMLS_DC)
 {
        zend_auto_global *auto_global;
 
        if (zend_u_hash_find(CG(auto_globals), type, name, name_len+1, (void 
**) &auto_global)==SUCCESS) {
                if (auto_global->armed) {
-                       auto_global->armed = 
auto_global->auto_global_callback(auto_global->name, auto_global->name_len 
TSRMLS_CC);
+                       auto_global->armed = 
auto_global->auto_global_callback(auto_global, ZEND_CT, NULL, 0, NULL 
TSRMLS_CC);
+               }
+               if (pauto) {
+                       *pauto = auto_global;
                }
                return 1;
        }
@@ -4327,21 +4365,26 @@ zend_bool zend_u_is_auto_global(zend_uch
 
 zend_bool zend_is_auto_global(char *name, uint name_len TSRMLS_DC)
 {
-       return zend_u_is_auto_global(IS_STRING, ZSTR(name), name_len TSRMLS_CC);
+       return zend_u_is_auto_global(IS_STRING, ZSTR(name), name_len, NULL 
TSRMLS_CC);
 }
 
 
-int zend_register_auto_global(char *name, uint name_len, 
zend_auto_global_callback auto_global_callback TSRMLS_DC)
+int zend_register_auto_global_ex(char *name, uint name_len, 
zend_auto_global_callback auto_global_callback, zend_auto_global **pauto 
TSRMLS_DC)
 {
        zend_auto_global auto_global;
 
        auto_global.name = zend_strndup(name, name_len);
        auto_global.name_len = name_len;
        auto_global.auto_global_callback = auto_global_callback;
+       auto_global.armed = auto_global_callback ? 1 : 0;
 
-       return zend_hash_add(CG(auto_globals), name, name_len+1, &auto_global, 
sizeof(zend_auto_global), NULL);
+       return zend_hash_add(CG(auto_globals), name, name_len+1, &auto_global, 
sizeof(zend_auto_global), (void**)pauto);
 }
 
+int zend_register_auto_global(char *name, uint name_len, 
zend_auto_global_callback auto_global_callback TSRMLS_DC)
+{
+       return zend_register_auto_global_ex(name, name_len, 
auto_global_callback, NULL TSRMLS_CC);
+}
 
 int zendlex(znode *zendlval TSRMLS_DC)
 {
Index: Zend/zend_compile.h
===================================================================
RCS file: /repository/ZendEngine2/zend_compile.h,v
retrieving revision 1.353
diff -u -p -d -r1.353 zend_compile.h
--- Zend/zend_compile.h 20 Jan 2007 20:36:55 -0000      1.353
+++ Zend/zend_compile.h 26 Jan 2007 10:23:12 -0000
@@ -51,6 +51,7 @@
 
 typedef struct _zend_op_array zend_op_array;
 typedef struct _zend_op zend_op;
+typedef struct _zend_auto_global zend_auto_global;
 
 typedef struct _znode {
        int op_type;
@@ -175,6 +176,7 @@ typedef struct _zend_compiled_variable {
        int name_len;
        ulong hash_value;
        zend_uint fetch_type;
+       zend_auto_global *auto_global;
 } zend_compiled_variable;
 
 struct _zend_op_array {
@@ -575,18 +577,19 @@ ZEND_API char *zend_make_compiled_string
 ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool 
nullify_handlers TSRMLS_DC);
 int zend_get_class_fetch_type(zend_uchar type, zstr class_name, uint 
class_name_len);
 
-typedef zend_bool (*zend_auto_global_callback)(char *name, uint name_len 
TSRMLS_DC);
-typedef struct _zend_auto_global {
+typedef zend_bool (*zend_auto_global_callback)(zend_auto_global *auto_global, 
int stage, zval *ag_val, int fetch_op, zval *member TSRMLS_DC);
+struct _zend_auto_global {
        char *name;
        uint name_len;
        zend_auto_global_callback auto_global_callback;
        zend_bool armed;
-} zend_auto_global;
+};
 
 void zend_auto_global_dtor(zend_auto_global *auto_global);
+ZEND_API int zend_register_auto_global_ex(char *name, uint name_len, 
zend_auto_global_callback auto_global_callback, zend_auto_global **pauto 
TSRMLS_DC);
 ZEND_API int zend_register_auto_global(char *name, uint name_len, 
zend_auto_global_callback auto_global_callback TSRMLS_DC);
 ZEND_API zend_bool zend_is_auto_global(char *name, uint name_len TSRMLS_DC);
-ZEND_API zend_bool zend_u_is_auto_global(zend_uchar type, zstr name, uint 
name_len TSRMLS_DC);
+ZEND_API zend_bool zend_u_is_auto_global(zend_uchar type, zstr name, uint 
name_len, zend_auto_global **pauto TSRMLS_DC);
 ZEND_API int zend_auto_global_disable_jit(char *varname, zend_uint 
varname_length TSRMLS_DC);
 
 int zendlex(znode *zendlval TSRMLS_DC);
@@ -607,7 +610,8 @@ int zendlex(znode *zendlval TSRMLS_DC);
 #define ZEND_FETCH_LOCAL                       1
 #define ZEND_FETCH_STATIC                      2
 #define ZEND_FETCH_STATIC_MEMBER       3
-#define ZEND_FETCH_GLOBAL_LOCK 4
+#define ZEND_FETCH_GLOBAL_LOCK         4
+#define ZEND_FETCH_AUTO_GLOBAL         5
 
 
 /* class fetches */
Index: Zend/zend_execute.c
===================================================================
RCS file: /repository/ZendEngine2/zend_execute.c,v
retrieving revision 1.758
diff -u -p -d -r1.758 zend_execute.c
--- Zend/zend_execute.c 20 Jan 2007 20:36:55 -0000      1.758
+++ Zend/zend_execute.c 26 Jan 2007 10:23:13 -0000
@@ -226,7 +226,7 @@ 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);
+               HashTable *symbol_table = (cv->fetch_type == 
ZEND_FETCH_AUTO_GLOBAL) ? &EG(symbol_table) : EG(active_symbol_table);
 
                if (zend_u_hash_quick_find(symbol_table, utype, cv->name, 
cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
                        switch (type) {
@@ -297,7 +297,7 @@ 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);
+               HashTable *symbol_table = (cv->fetch_type == 
ZEND_FETCH_AUTO_GLOBAL) ? &EG(symbol_table) : EG(active_symbol_table);
 
                if (zend_u_hash_quick_find(symbol_table, utype, cv->name, 
cv->name_len+1, cv->hash_value, (void **)ptr)==FAILURE) {
                        switch (type) {
@@ -905,6 +905,17 @@ static inline HashTable *zend_get_target
                case ZEND_FETCH_GLOBAL_LOCK:
                        return &EG(symbol_table);
                        break;
+               case ZEND_FETCH_AUTO_GLOBAL:
+               {
+                       zend_auto_global *auto_global;
+
+                       if (SUCCESS == zend_u_hash_find(CG(auto_globals), 
Z_TYPE_P(variable), Z_UNIVAL_P(variable), Z_UNILEN_P(variable) + 1, (void **) 
&auto_global) &&
+                               auto_global->armed && 
auto_global->auto_global_callback) {
+                               auto_global->armed = 
auto_global->auto_global_callback(auto_global, ZEND_RT, NULL, ZEND_FETCH_R + (3 
* type), NULL TSRMLS_CC);
+                       }
+                       return &EG(symbol_table);
+                       break;
+               }
                case ZEND_FETCH_STATIC:
                        if (!EG(active_op_array)->static_variables) {
                                
ALLOC_HASHTABLE(EG(active_op_array)->static_variables);
@@ -1030,7 +1041,7 @@ fetch_string_dim:
        return retval;
 }
 
-static void zend_fetch_dimension_address(temp_variable *result, zval 
**container_ptr, zval *dim, int dim_is_tmp_var, int type TSRMLS_DC)
+static void zend_fetch_dimension_address(znode *container_node, temp_variable 
*result, zval **container_ptr, zval *dim, int dim_is_tmp_var, int type 
TSRMLS_DC)
 {
        zval *container;
 
@@ -1039,6 +1050,13 @@ static void zend_fetch_dimension_address
        }
 
        container = *container_ptr;
+       if (container_node->op_type == IS_CV) {
+               zend_auto_global *auto_global = 
CV_DEF_OF(container_node->u.var).auto_global;
+
+               if (auto_global && auto_global->armed && 
auto_global->auto_global_callback) {
+                       auto_global->armed = 
auto_global->auto_global_callback(auto_global, ZEND_RT, container, 
ZEND_FETCH_DIM_R + (3 * type), dim TSRMLS_CC);
+               }
+       }
 
        if (container == EG(error_zval_ptr)) {
                if (result) {
@@ -1232,11 +1250,19 @@ static void zend_fetch_dimension_address
        }
 }
 
-static void zend_fetch_property_address(temp_variable *result, zval 
**container_ptr, zval *prop_ptr, int type TSRMLS_DC)
+static void zend_fetch_property_address(znode *container_node, temp_variable 
*result, zval **container_ptr, zval *prop_ptr, int type TSRMLS_DC)
 {
        zval *container;
 
        container = *container_ptr;
+       if (container_node->op_type == IS_CV) {
+               zend_auto_global *auto_global = 
CV_DEF_OF(container_node->u.var).auto_global;
+
+               if (auto_global && auto_global->armed && 
auto_global->auto_global_callback) {
+                       auto_global->armed = 
auto_global->auto_global_callback(auto_global, ZEND_RT, container, 
ZEND_FETCH_OBJ_R + (3 * type), prop_ptr TSRMLS_CC);
+               }
+       }
+
        if (container == EG(error_zval_ptr)) {
                if (result) {
                        result->var.ptr_ptr = &EG(error_zval_ptr);
Index: Zend/zend_vm_def.h
===================================================================
RCS file: /repository/ZendEngine2/zend_vm_def.h,v
retrieving revision 1.155
diff -u -p -d -r1.155 zend_vm_def.h
--- Zend/zend_vm_def.h  11 Jan 2007 22:35:36 -0000      1.155
+++ Zend/zend_vm_def.h  26 Jan 2007 10:23:13 -0000
@@ -418,7 +418,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_
                                        zend_op *op_data = opline+1;
                                        zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
 
-                                       
zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), 
GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW), dim, IS_OP2_TMP_FREE(), BP_VAR_RW TSRMLS_CC);
+                                       
zend_fetch_dimension_address(&opline->op1, &EX_T(op_data->op2.u.var), 
GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW), dim, IS_OP2_TMP_FREE(), BP_VAR_RW TSRMLS_CC);
                                        value = get_zval_ptr(&op_data->op1, 
EX(Ts), &free_op_data1, BP_VAR_R);
                                        var_ptr = 
get_zval_ptr_ptr(&op_data->op2, EX(Ts), &free_op_data2, BP_VAR_RW);
                                        increment_opline = 1;
@@ -978,6 +978,7 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address
                }
                switch (opline->op2.u.EA.type) {
                        case ZEND_FETCH_GLOBAL:
+                       case ZEND_FETCH_AUTO_GLOBAL:
                                if (OP1_TYPE != IS_TMP_VAR) {
                                        FREE_OP1();
                                }
@@ -1066,7 +1067,7 @@ ZEND_VM_HANDLER(81, ZEND_FETCH_DIM_R, VA
            EX_T(opline->op1.u.var).var.ptr_ptr) {
                PZVAL_LOCK(*EX_T(opline->op1.u.var).var.ptr_ptr);
        }
-       
zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var),
 GET_OP1_ZVAL_PTR_PTR(BP_VAR_R), dim, IS_OP2_TMP_FREE(), BP_VAR_R TSRMLS_CC);
+       zend_fetch_dimension_address(&opline->op1, 
RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), 
GET_OP1_ZVAL_PTR_PTR(BP_VAR_R), dim, IS_OP2_TMP_FREE(), BP_VAR_R TSRMLS_CC);
        FREE_OP2();
        FREE_OP1_VAR_PTR();
        ZEND_VM_NEXT_OPCODE();
@@ -1078,7 +1079,7 @@ ZEND_VM_HANDLER(84, ZEND_FETCH_DIM_W, VA
        zend_free_op free_op1, free_op2;
        zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
 
-       
zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var),
 GET_OP1_ZVAL_PTR_PTR(BP_VAR_W), dim, IS_OP2_TMP_FREE(), BP_VAR_W TSRMLS_CC);
+       zend_fetch_dimension_address(&opline->op1, 
RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), 
GET_OP1_ZVAL_PTR_PTR(BP_VAR_W), dim, IS_OP2_TMP_FREE(), BP_VAR_W TSRMLS_CC);
        FREE_OP2();
        if (OP1_TYPE == IS_VAR && OP1_FREE &&
            READY_TO_DESTROY(free_op1.var) &&
@@ -1095,7 +1096,7 @@ ZEND_VM_HANDLER(87, ZEND_FETCH_DIM_RW, V
        zend_free_op free_op1, free_op2;
        zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
 
-       
zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var),
 GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW), dim, IS_OP2_TMP_FREE(), BP_VAR_RW TSRMLS_CC);
+       zend_fetch_dimension_address(&opline->op1, 
RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), 
GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW), dim, IS_OP2_TMP_FREE(), BP_VAR_RW TSRMLS_CC);
        FREE_OP2();
        if (OP1_TYPE == IS_VAR && OP1_FREE &&
            READY_TO_DESTROY(free_op1.var) &&
@@ -1112,7 +1113,7 @@ ZEND_VM_HANDLER(90, ZEND_FETCH_DIM_IS, V
        zend_free_op free_op1, free_op2;
        zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
 
-       
zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var),
 GET_OP1_ZVAL_PTR_PTR(BP_VAR_IS), dim, IS_OP2_TMP_FREE(), BP_VAR_IS TSRMLS_CC);
+       zend_fetch_dimension_address(&opline->op1, 
RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), 
GET_OP1_ZVAL_PTR_PTR(BP_VAR_IS), dim, IS_OP2_TMP_FREE(), BP_VAR_IS TSRMLS_CC);
        FREE_OP2();
        FREE_OP1_VAR_PTR();
        ZEND_VM_NEXT_OPCODE();
@@ -1129,7 +1130,7 @@ ZEND_VM_HANDLER(93, ZEND_FETCH_DIM_FUNC_
                zend_error_noreturn(E_ERROR, "Cannot use [] for reading");
        }
        dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
-       
zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var),
 GET_OP1_ZVAL_PTR_PTR(type), dim, IS_OP2_TMP_FREE(), type TSRMLS_CC);
+       zend_fetch_dimension_address(&opline->op1, 
RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), 
GET_OP1_ZVAL_PTR_PTR(type), dim, IS_OP2_TMP_FREE(), type TSRMLS_CC);
        FREE_OP2();
        if (OP1_TYPE == IS_VAR && type == BP_VAR_W && OP1_FREE &&
            READY_TO_DESTROY(free_op1.var) &&
@@ -1157,7 +1158,7 @@ ZEND_VM_HANDLER(96, ZEND_FETCH_DIM_UNSET
                        SEPARATE_ZVAL_IF_NOT_REF(container);
                }
        }
-       
zend_fetch_dimension_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var),
 container, dim, IS_OP2_TMP_FREE(), BP_VAR_UNSET TSRMLS_CC);
+       zend_fetch_dimension_address(&opline->op1, 
RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), 
container, dim, IS_OP2_TMP_FREE(), BP_VAR_UNSET TSRMLS_CC);
        FREE_OP2();
        if (OP1_TYPE == IS_VAR && OP1_FREE &&
            READY_TO_DESTROY(free_op1.var) &&
@@ -1218,6 +1219,14 @@ ZEND_VM_HELPER_EX(zend_fetch_property_ad
                        MAKE_REAL_ZVAL_PTR(offset);
                }
 
+               if (opline->op1.op_type == IS_CV) {
+                       zend_auto_global *auto_global = 
CV_DEF_OF(opline->op1.u.var).auto_global;
+
+                       if (auto_global && auto_global->armed && 
auto_global->auto_global_callback) {
+                               auto_global->armed = 
auto_global->auto_global_callback(auto_global, ZEND_RT, container, 
ZEND_FETCH_OBJ_R + (3 * type), offset TSRMLS_CC);
+                       }
+               }
+
                /* here we are sure we are dealing with an object */
                *retval = Z_OBJ_HT_P(container)->read_property(container, 
offset, type TSRMLS_CC);
 
@@ -1259,7 +1268,7 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VA
        if (IS_OP2_TMP_FREE()) {
                MAKE_REAL_ZVAL_PTR(property);
        }
-       
zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var),
 GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W), property, BP_VAR_W TSRMLS_CC);
+       zend_fetch_property_address(&opline->op1, 
RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), 
GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W), property, BP_VAR_W TSRMLS_CC);
        if (IS_OP2_TMP_FREE()) {
                zval_ptr_dtor(&property);
        } else {
@@ -1283,7 +1292,7 @@ ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, V
        if (IS_OP2_TMP_FREE()) {
                MAKE_REAL_ZVAL_PTR(property);
        }
-       
zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var),
 GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW), property, BP_VAR_RW TSRMLS_CC);
+       zend_fetch_property_address(&opline->op1, 
RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), 
GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_RW), property, BP_VAR_RW TSRMLS_CC);
        if (IS_OP2_TMP_FREE()) {
                zval_ptr_dtor(&property);
        } else {
@@ -1315,7 +1324,7 @@ ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_
                if (IS_OP2_TMP_FREE()) {
                        MAKE_REAL_ZVAL_PTR(property);
                }
-               
zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var),
 GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W), property, BP_VAR_W TSRMLS_CC);
+               zend_fetch_property_address(&opline->op1, 
RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), 
GET_OP1_OBJ_ZVAL_PTR_PTR(BP_VAR_W), property, BP_VAR_W TSRMLS_CC);
                if (IS_OP2_TMP_FREE()) {
                        zval_ptr_dtor(&property);
                } else {
@@ -1348,7 +1357,7 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET
        if (IS_OP2_TMP_FREE()) {
                MAKE_REAL_ZVAL_PTR(property);
        }
-       
zend_fetch_property_address(RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var),
 container, property, BP_VAR_R TSRMLS_CC);
+       zend_fetch_property_address(&opline->op1, 
RETURN_VALUE_UNUSED(&opline->result)?NULL:&EX_T(opline->result.u.var), 
container, property, BP_VAR_R TSRMLS_CC);
        if (IS_OP2_TMP_FREE()) {
                zval_ptr_dtor(&property);
        } else {
@@ -1428,7 +1437,7 @@ ZEND_VM_HANDLER(147, ZEND_ASSIGN_DIM, VA
                zval *value;
                zval *dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
 
-               zend_fetch_dimension_address(&EX_T(op_data->op2.u.var), 
object_ptr, dim, IS_OP2_TMP_FREE(), BP_VAR_W TSRMLS_CC);
+               zend_fetch_dimension_address(&opline->op1, 
&EX_T(op_data->op2.u.var), object_ptr, dim, IS_OP2_TMP_FREE(), BP_VAR_W 
TSRMLS_CC);
                FREE_OP2();
 
                value = get_zval_ptr(&op_data->op1, EX(Ts), &free_op_data1, 
BP_VAR_R);

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

Reply via email to