summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend-parser.y8
-rw-r--r--Zend/zend_compile.c18
-rw-r--r--Zend/zend_compile.h14
-rw-r--r--Zend/zend_execute.c10
-rw-r--r--Zend/zend_opcode.c2
5 files changed, 43 insertions, 9 deletions
diff --git a/Zend/zend-parser.y b/Zend/zend-parser.y
index f5c51ff408..0a20ef3435 100644
--- a/Zend/zend-parser.y
+++ b/Zend/zend-parser.y
@@ -521,7 +521,7 @@ compound_variable:
dim_list:
dim_list ']' '[' dim_offset { fetch_array_dim(&$$, &$1, &$4 CLS_CC); }
- | compound_variable { do_begin_variable_parse(CLS_C); } '[' dim_offset { fetch_array_begin(&$$, &$1, &$4 CLS_CC); }
+ | compound_variable { do_fetch_globals(&$1); do_begin_variable_parse(CLS_C); } '[' dim_offset { fetch_array_begin(&$$, &$1, &$4 CLS_CC); }
;
@@ -604,10 +604,10 @@ encaps_list:
encaps_var:
- VARIABLE { do_begin_variable_parse(CLS_C); fetch_simple_variable(&$$, &$1, 1 CLS_CC); }
- | VARIABLE '[' encaps_var_offset ']' { do_begin_variable_parse(CLS_C); fetch_array_begin(&$$, &$1, &$3 CLS_CC); }
+ VARIABLE { do_fetch_globals(&$1); do_begin_variable_parse(CLS_C); fetch_simple_variable(&$$, &$1, 1 CLS_CC); }
+ | VARIABLE '[' encaps_var_offset ']' { do_fetch_globals(&$1); do_begin_variable_parse(CLS_C); fetch_array_begin(&$$, &$1, &$3 CLS_CC); }
| VARIABLE ZEND_OBJECT_OPERATOR STRING { do_begin_variable_parse(CLS_C); fetch_simple_variable(&$2, &$1, 1 CLS_CC); do_fetch_property(&$$, &$2, &$3 CLS_CC); }
- | DOLLAR_OPEN_CURLY_BRACES expr '}' { do_begin_variable_parse(CLS_C); fetch_simple_variable(&$$, &$2, 1 CLS_CC); }
+ | DOLLAR_OPEN_CURLY_BRACES expr '}' { do_begin_variable_parse(CLS_C); fetch_simple_variable(&$$, &$2, 1 CLS_CC); }
| DOLLAR_OPEN_CURLY_BRACES STRING '[' expr ']' '}' { do_begin_variable_parse(CLS_C); fetch_array_begin(&$$, &$2, &$4 CLS_CC); }
| T_CURLY_OPEN cvar '}' { $$ = $2; }
;
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 48b7d9aea1..9f4dc4e079 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -154,6 +154,24 @@ void do_binary_assign_op(int op, znode *result, znode *op1, znode *op2 CLS_DC)
}
+
+void do_fetch_globals(znode *varname)
+{
+ if (!CG(active_op_array)->initialized_globals
+ && varname->op_type == IS_CONST
+ && varname->u.constant.type == IS_STRING
+ && varname->u.constant.value.str.len == (sizeof("GLOBALS")-1)
+ && !memcmp(varname->u.constant.value.str.val, "GLOBALS", sizeof("GLOBALS")-1)) {
+ zend_op *opline = get_next_op(CG(active_op_array) CLS_CC);
+
+ opline->opcode = ZEND_INIT_GLOBALS;
+ SET_UNUSED(opline->op1);
+ SET_UNUSED(opline->op2);
+ CG(active_op_array)->initialized_globals = 1;
+ }
+}
+
+
void fetch_simple_variable(znode *result, znode *varname, int bp CLS_DC)
{
int next_op_number = get_next_op_number(CG(active_op_array));
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index 0eace15565..a6d7d834ef 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -91,6 +91,7 @@ struct _zend_op_array {
zend_brk_cont_element *brk_cont_array;
int last_brk_cont;
int current_brk_cont;
+ unsigned char initialized_globals;
/* static variables support */
HashTable *static_variables;
@@ -195,6 +196,7 @@ void do_assign_ref(znode *result, znode *lvar, znode *rvar CLS_DC);
void fetch_simple_variable(znode *result, znode *varname, int bp CLS_DC);
void do_indirect_references(znode *result, znode *num_references, znode *variable CLS_DC);
void do_fetch_global_or_static_variable(znode *varname, znode *static_assignment, int fetch_type CLS_DC);
+void do_fetch_globals(znode *varname);
void fetch_array_begin(znode *result, znode *varname, znode *first_dim CLS_DC);
void fetch_array_dim(znode *result, znode *parent, znode *dim CLS_DC);
@@ -450,11 +452,13 @@ int zendlex(znode *zendlval CLS_DC);
#define ZEND_FETCH_DIM_TMP_VAR 89
#define ZEND_FETCH_CONSTANT 90
-
-#define ZEND_EXT_STMT 91
-#define ZEND_EXT_FCALL_BEGIN 92
-#define ZEND_EXT_FCALL_END 93
-#define ZEND_EXT_NOP 94
+
+#define ZEND_INIT_GLOBALS 91
+
+#define ZEND_EXT_STMT 92
+#define ZEND_EXT_FCALL_BEGIN 93
+#define ZEND_EXT_FCALL_END 94
+#define ZEND_EXT_NOP 95
/* end of block */
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 8d6bbbbd91..5683e93a8b 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -1874,6 +1874,16 @@ send_by_ref:
zend_llist_apply_with_argument(&zend_extensions, (void (*)(void *, void *)) zend_extension_fcall_end_handler, op_array);
}
break;
+ case ZEND_INIT_GLOBALS: {
+ zval *globals = (zval *) emalloc(sizeof(zval));
+
+ globals->refcount=1;
+ globals->is_ref=1;
+ globals->type = IS_ARRAY;
+ globals->value.ht = &EG(symbol_table);
+ zend_hash_add(EG(active_symbol_table), "GLOBALS", sizeof("GLOBALS"), &globals, sizeof(zval *), NULL);
+ }
+ break;
case ZEND_EXT_NOP:
case ZEND_NOP:
break;
diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c
index 83f5bdf908..551f7366a0 100644
--- a/Zend/zend_opcode.c
+++ b/Zend/zend_opcode.c
@@ -90,6 +90,8 @@ void init_op_array(zend_op_array *op_array, int initial_ops_size)
op_array->static_variables = NULL;
+ op_array->initialized_globals = 0;
+
zend_llist_apply_with_argument(&zend_extensions, (void (*)(void *, void *)) zend_extension_op_array_ctor_handler, op_array);
}