]> granicus.if.org Git - php/commitdiff
Introduced new BIND_GLOBAL instraction instead of FETCH_W+ASSIGN_REF pair that caused...
authorDmitry Stogov <dmitry@zend.com>
Fri, 6 Jun 2014 11:04:30 +0000 (15:04 +0400)
committerDmitry Stogov <dmitry@zend.com>
Fri, 6 Jun 2014 11:04:30 +0000 (15:04 +0400)
Zend/zend_compile.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
Zend/zend_vm_opcodes.c
Zend/zend_vm_opcodes.h

index c84937b645f613ec2f9db840736b368119fe78f1..de45b5a683f36b7471307ed1d5b083eee6930ebe 100644 (file)
@@ -6257,21 +6257,33 @@ void zend_do_fetch_global_variable(znode *varname, const znode *static_assignmen
        }
 
        opline = get_next_op(CG(active_op_array) TSRMLS_CC);
-       opline->opcode = ZEND_FETCH_W;          /* the default mode must be Write, since fetch_simple_variable() is used to define function arguments */
-       opline->result_type = IS_VAR;
-       opline->result.var = get_temporary_variable(CG(active_op_array));
-       SET_NODE(opline->op1, varname);
-       SET_UNUSED(opline->op2);
-       opline->extended_value = fetch_type;
-       GET_NODE(&result, opline->result);
 
-       if (varname->op_type == IS_CONST) {
+       if (varname->op_type == IS_CONST &&
+          !zend_is_auto_global(Z_STR(varname->u.constant) TSRMLS_CC) &&
+           !(Z_STRLEN(varname->u.constant) == (sizeof("this")-1) &&
+             !memcmp(Z_STRVAL(varname->u.constant), "this", sizeof("this") - 1))) {
+               opline->opcode = ZEND_BIND_GLOBAL;
+               SET_NODE(opline->op2, varname);
+               opline->op1_type = IS_CV;
                zval_copy_ctor(&varname->u.constant);
-       }
-       fetch_simple_variable(&lval, varname, 0 TSRMLS_CC); /* Relies on the fact that the default fetch is BP_VAR_W */
+               opline->op1.var = lookup_cv(CG(active_op_array), Z_STR(varname->u.constant) TSRMLS_CC);
+       } else {
+               opline->opcode = ZEND_FETCH_W;          /* the default mode must be Write, since fetch_simple_variable() is used to define function arguments */
+               opline->result_type = IS_VAR;
+               opline->result.var = get_temporary_variable(CG(active_op_array));
+               SET_NODE(opline->op1, varname);
+               SET_UNUSED(opline->op2);
+               opline->extended_value = fetch_type;
+               GET_NODE(&result, opline->result);
 
-       zend_do_assign_ref(NULL, &lval, &result TSRMLS_CC);
-       CG(active_op_array)->opcodes[CG(active_op_array)->last-1].result_type |= EXT_TYPE_UNUSED;
+               if (varname->op_type == IS_CONST) {
+                       zval_copy_ctor(&varname->u.constant);
+               }
+               fetch_simple_variable(&lval, varname, 0 TSRMLS_CC); /* Relies on the fact that the default fetch is BP_VAR_W */
+
+               zend_do_assign_ref(NULL, &lval, &result TSRMLS_CC);
+               CG(active_op_array)->opcodes[CG(active_op_array)->last-1].result_type |= EXT_TYPE_UNUSED;
+       }
 }
 /* }}} */
 
index 8aa60ce3cd4e95e54c0d97c298ed406201f3d005..9542419b398fbd03d91ac9af5103133ec308733b 100644 (file)
@@ -5624,4 +5624,34 @@ ZEND_VM_HANDLER(167, ZEND_ASSIGN_POW, VAR|UNUSED|CV, CONST|TMP|VAR|UNUSED|CV)
        ZEND_VM_DISPATCH_TO_HELPER_EX(zend_binary_assign_op_helper, binary_op,pow_function);
 }
 
+ZEND_VM_HANDLER(168, ZEND_BIND_GLOBAL, CV, CONST)
+{
+       USE_OPLINE
+       zend_free_op free_op1, free_op2;
+       zval *varname;
+       zval *value;
+       zval *variable_ptr;
+       zend_string *name;
+
+       SAVE_OPLINE();
+       varname = GET_OP2_ZVAL_PTR(BP_VAR_R);
+       name = Z_STR_P(varname);
+       value = zend_hash_find(&EG(symbol_table).ht, name);
+       if (value == NULL) {
+               value = zend_hash_add_new(&EG(symbol_table).ht, name, &EG(uninitialized_zval));
+               /* GLOBAL variable may be an INDIRECT pointer to CV */
+       } else if (Z_TYPE_P(value) == IS_INDIRECT) {
+               value = Z_INDIRECT_P(value);
+               if (Z_TYPE_P(value) == IS_UNDEF) {
+                       ZVAL_NULL(value);
+               }
+       }
+
+       variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
+       zend_assign_to_variable_reference(variable_ptr, value TSRMLS_CC);
+
+       CHECK_EXCEPTION();
+       ZEND_VM_NEXT_OPCODE();
+}
+
 ZEND_VM_EXPORT_HELPER(zend_do_fcall, zend_do_fcall_common_helper)
index 1babe8587ceda1977a5b698a4883d2f56fafdf7f..b1198b2c6af7284f7c45c54c5eb65aa55283bdb4 100644 (file)
@@ -33168,6 +33168,36 @@ static int ZEND_FASTCALL  ZEND_ASSIGN_POW_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HAND
        return zend_binary_assign_op_helper_SPEC_CV_CONST(pow_function, ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
 }
 
+static int ZEND_FASTCALL  ZEND_BIND_GLOBAL_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
+{
+       USE_OPLINE
+
+       zval *varname;
+       zval *value;
+       zval *variable_ptr;
+       zend_string *name;
+
+       SAVE_OPLINE();
+       varname = opline->op2.zv;
+       name = Z_STR_P(varname);
+       value = zend_hash_find(&EG(symbol_table).ht, name);
+       if (value == NULL) {
+               value = zend_hash_add_new(&EG(symbol_table).ht, name, &EG(uninitialized_zval));
+               /* GLOBAL variable may be an INDIRECT pointer to CV */
+       } else if (Z_TYPE_P(value) == IS_INDIRECT) {
+               value = Z_INDIRECT_P(value);
+               if (Z_TYPE_P(value) == IS_UNDEF) {
+                       ZVAL_NULL(value);
+               }
+       }
+
+       variable_ptr = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->op1.var TSRMLS_CC);
+       zend_assign_to_variable_reference(variable_ptr, value TSRMLS_CC);
+
+       CHECK_EXCEPTION();
+       ZEND_VM_NEXT_OPCODE();
+}
+
 static int ZEND_FASTCALL  ZEND_ADD_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
 {
        USE_OPLINE
@@ -44468,6 +44498,31 @@ void zend_init_opcodes_handlers(void)
        ZEND_ASSIGN_POW_SPEC_CV_VAR_HANDLER,
        ZEND_ASSIGN_POW_SPEC_CV_UNUSED_HANDLER,
        ZEND_ASSIGN_POW_SPEC_CV_CV_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_BIND_GLOBAL_SPEC_CV_CONST_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
+       ZEND_NULL_HANDLER,
        ZEND_NULL_HANDLER
   };
   zend_opcode_handlers = (opcode_handler_t*)labels;
index 23edabc47ff5b35492179a62b764963f08868108..df127039c6b0556a5ede6b067a040e50368730dd 100644 (file)
@@ -21,7 +21,7 @@
 #include <stdio.h>
 #include <zend.h>
 
-const char *zend_vm_opcodes_map[168] = {
+const char *zend_vm_opcodes_map[169] = {
        "ZEND_NOP",
        "ZEND_ADD",
        "ZEND_SUB",
@@ -190,6 +190,7 @@ const char *zend_vm_opcodes_map[168] = {
        "ZEND_SEND_UNPACK",
        "ZEND_POW",
        "ZEND_ASSIGN_POW",
+       "ZEND_BIND_GLOBAL",
 };
 
 ZEND_API const char* zend_get_opcode_name(zend_uchar opcode) {
index f9c30ca126043b7f215eb590cd6c71589b93dbf8..df499f946b74db25bb1b69849d426a08285a7e36 100644 (file)
@@ -173,5 +173,6 @@ ZEND_API const char *zend_get_opcode_name(zend_uchar opcode);
 #define ZEND_SEND_UNPACK                     165
 #define ZEND_POW                             166
 #define ZEND_ASSIGN_POW                      167
+#define ZEND_BIND_GLOBAL                     168
 
 #endif