diff options
| -rw-r--r-- | Zend/zend-parser.y | 8 | ||||
| -rw-r--r-- | Zend/zend_compile.c | 18 | ||||
| -rw-r--r-- | Zend/zend_compile.h | 14 | ||||
| -rw-r--r-- | Zend/zend_execute.c | 10 | ||||
| -rw-r--r-- | Zend/zend_opcode.c | 2 |
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); } |
