}
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;
+ }
}
/* }}} */
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)
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
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;
#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",
"ZEND_SEND_UNPACK",
"ZEND_POW",
"ZEND_ASSIGN_POW",
+ "ZEND_BIND_GLOBAL",
};
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