Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:27639 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 82724 invoked by uid 1010); 24 Jan 2007 19:58:23 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 82709 invoked from network); 24 Jan 2007 19:58:23 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 24 Jan 2007 19:58:23 -0000 Authentication-Results: pb1.pair.com header.from=pollita@php.net; sender-id=unknown; domainkeys=good Authentication-Results: pb1.pair.com smtp.mail=pollita@php.net; spf=permerror; sender-id=unknown Received-SPF: error (pb1.pair.com: domain php.net from 140.211.166.39 cause and error) DomainKey-Status: good X-DomainKeys: Ecelerity dk_validate implementing draft-delany-domainkeys-base-01 X-PHP-List-Original-Sender: pollita@php.net X-Host-Fingerprint: 140.211.166.39 osu1.php.net Linux 2.4/2.6 Received: from [140.211.166.39] ([140.211.166.39:38431] helo=osu1.php.net) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 6B/56-43654-F5AB7B54 for ; Wed, 24 Jan 2007 14:58:23 -0500 X-DomainKeys: Ecelerity dk_sign implementing draft-delany-domainkeys-base-01 DomainKey-Signature: q=dns; a=rsa-sha1; c=nofws; s=mx; d=php.net; h=From:Subject:To:Date; b=Z3kkvW5qOoZJMUn4cpKOC4DI/IgUSwZ5s0aMuwq/GRnq4nA7IDUgyi+vkuYygKU/ 9sDFKBsDf5n6j+n7nqEErKyx/KEX4JIqb/aUBr+wW3ryNfdqItJwfP7FKVsY1IqK Authentication-Results: osu1.php.net smtp.user=pollita; auth=pass (LOGIN) X-Host-Fingerprint: 216.145.49.15 unknown Received: from [216.145.49.15] ([216.145.49.15:60660] helo=[10.72.72.69]) by osu1.php.net (ecelerity 2.1.1.11-rc1 r(13363/13364M)) with ESMTPSA (cipher=AES256-SHA) id F4/14-27939-EBAB7B54 for ; Wed, 24 Jan 2007 11:59:58 -0800 Message-ID: <45B7BA56.40406@php.net> Date: Wed, 24 Jan 2007 11:58:14 -0800 User-Agent: Thunderbird 1.5.0.9 (Windows/20061207) MIME-Version: 1.0 To: internals@lists.php.net, Dmitry Stogov , Andi Gutmans , Andrei Zmievski Content-Type: multipart/mixed; boundary="------------000705050202070103060102" Subject: Runtime-JIT, the whole enchilada From: pollita@php.net (Sara Golemon) --------------000705050202070103060102 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit 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 --------------000705050202070103060102 Content-Type: text/plain; name="runtime-jit.diff.txt" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="runtime-jit.diff.txt" Index: Zend/zend_compile.c =================================================================== RCS file: /repository/ZendEngine2/zend_compile.c,v retrieving revision 1.736 diff -u -p -r1.736 zend_compile.c --- Zend/zend_compile.c 20 Jan 2007 20:36:55 -0000 1.736 +++ Zend/zend_compile.c 24 Jan 2007 19:50:52 -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_GLOBAL : ZEND_FETCH_LOCAL; return i; } @@ -383,6 +384,7 @@ void fetch_simple_variable_ex(znode *res 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)) && + !zend_u_is_auto_global(Z_TYPE(varname->u.constant), Z_UNIVAL(varname->u.constant), Z_UNILEN(varname->u.constant), NULL TSRMLS_CC) && (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; @@ -410,7 +412,7 @@ 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)) { - if (zend_u_is_auto_global(Z_TYPE(varname->u.constant), Z_UNIVAL(varname->u.constant), Z_UNILEN(varname->u.constant) TSRMLS_CC)) { + if (zend_u_is_auto_global(Z_TYPE(varname->u.constant), Z_UNIVAL(varname->u.constant), Z_UNILEN(varname->u.constant), NULL TSRMLS_CC)) { opline_ptr->op2.u.EA.type = ZEND_FETCH_GLOBAL; } } @@ -492,6 +494,29 @@ 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 && + 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 +527,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 +3285,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 +3318,19 @@ void zend_do_fetch_property(znode *resul } *result = opline_ptr->result; return; + } else if (opline_ptr && opline_ptr->opcode == ZEND_FETCH_W && + 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 +4348,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 +4366,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 -r1.353 zend_compile.h --- Zend/zend_compile.h 20 Jan 2007 20:36:55 -0000 1.353 +++ Zend/zend_compile.h 24 Jan 2007 19:50:52 -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); Index: Zend/zend_execute.c =================================================================== RCS file: /repository/ZendEngine2/zend_execute.c,v retrieving revision 1.758 diff -u -p -r1.758 zend_execute.c --- Zend/zend_execute.c 20 Jan 2007 20:36:55 -0000 1.758 +++ Zend/zend_execute.c 24 Jan 2007 19:50:52 -0000 @@ -903,8 +903,17 @@ static inline HashTable *zend_get_target break; case ZEND_FETCH_GLOBAL: case ZEND_FETCH_GLOBAL_LOCK: + { + zend_auto_global *auto_global; + + if ((Z_TYPE_P(variable) == IS_STRING || Z_TYPE_P(variable) == IS_UNICODE) && + 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 +1039,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 +1048,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 +1248,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 -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 24 Jan 2007 19:50:52 -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; @@ -1066,7 +1066,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 +1078,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 +1095,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 +1112,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 +1129,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 +1157,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 +1218,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 +1267,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 +1291,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 +1323,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 +1356,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 +1436,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); Index: main/php_variables.c =================================================================== RCS file: /repository/php-src/main/php_variables.c,v retrieving revision 1.136 diff -u -p -r1.136 php_variables.c --- main/php_variables.c 1 Jan 2007 09:29:35 -0000 1.136 +++ main/php_variables.c 24 Jan 2007 19:50:52 -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); } --------------000705050202070103060102--