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