diff options
| author | Dmitry Stogov <dmitry@zend.com> | 2015-02-02 20:44:16 +0300 |
|---|---|---|
| committer | Dmitry Stogov <dmitry@zend.com> | 2015-02-02 20:44:16 +0300 |
| commit | e375ba877afc52a273e342fa927f69fb759fd0e5 (patch) | |
| tree | 311d28553a707609ae0b9ac24710aa02b432419b | |
| parent | 37ace4ad89d1d738b1a72057498e93e5d7ec1a2b (diff) | |
| download | php-git-e375ba877afc52a273e342fa927f69fb759fd0e5.tar.gz | |
Fixed "delayed" compilation
| -rw-r--r-- | Zend/tests/globals_005.phpt | 16 | ||||
| -rw-r--r-- | Zend/zend_compile.c | 58 |
2 files changed, 56 insertions, 18 deletions
diff --git a/Zend/tests/globals_005.phpt b/Zend/tests/globals_005.phpt new file mode 100644 index 0000000000..27e26610b2 --- /dev/null +++ b/Zend/tests/globals_005.phpt @@ -0,0 +1,16 @@ +--TEST-- +$GLOBALS resize +--FILE-- +<?php +function foo() { + for ($i = 0; $i < 100; $i++) { + $GLOBALS["A". $i] = 1; //trigger resize + } + return "ops"; +} + +$GLOBALS[foo()] = "ops"; +?> +DONE +--EXPECT-- +DONE diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 7476d475de..4720b4ff59 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -1789,8 +1789,16 @@ static inline zend_op *zend_delayed_emit_op(znode *result, zend_uchar opcode, zn zend_op tmp_opline; init_op(&tmp_opline); tmp_opline.opcode = opcode; - SET_NODE(tmp_opline.op1, op1); - SET_NODE(tmp_opline.op2, op2); + if (op1 == NULL) { + SET_UNUSED(tmp_opline.op1); + } else { + SET_NODE(tmp_opline.op1, op1); + } + if (op2 == NULL) { + SET_UNUSED(tmp_opline.op2); + } else { + SET_NODE(tmp_opline.op2, op2); + } if (result) { zend_make_var_result(result, &tmp_opline); } @@ -1984,7 +1992,7 @@ static int zend_try_compile_cv(znode *result, zend_ast *ast) /* {{{ */ } /* }}} */ -static zend_op *zend_compile_simple_var_no_cv(znode *result, zend_ast *ast, uint32_t type) /* {{{ */ +static zend_op *zend_compile_simple_var_no_cv(znode *result, zend_ast *ast, uint32_t type, int delayed) /* {{{ */ { zend_ast *name_ast = ast->child[0]; znode name_node; @@ -2003,7 +2011,11 @@ static zend_op *zend_compile_simple_var_no_cv(znode *result, zend_ast *ast, uint convert_to_string(&name_node.u.constant); } - opline = zend_emit_op(result, ZEND_FETCH_R, &name_node, NULL); + if (delayed) { + opline = zend_delayed_emit_op(result, ZEND_FETCH_R, &name_node, NULL); + } else { + opline = zend_emit_op(result, ZEND_FETCH_R, &name_node, NULL); + } opline->extended_value = ZEND_FETCH_LOCAL; if (name_node.op_type == IS_CONST) { @@ -2016,10 +2028,10 @@ static zend_op *zend_compile_simple_var_no_cv(znode *result, zend_ast *ast, uint } /* }}} */ -static void zend_compile_simple_var(znode *result, zend_ast *ast, uint32_t type) /* {{{ */ +static void zend_compile_simple_var(znode *result, zend_ast *ast, uint32_t type, int delayed) /* {{{ */ { if (zend_try_compile_cv(result, ast) == FAILURE) { - zend_op *opline = zend_compile_simple_var_no_cv(result, ast, type); + zend_op *opline = zend_compile_simple_var_no_cv(result, ast, type, delayed); zend_adjust_for_fetch_type(opline, type); } } @@ -2151,7 +2163,7 @@ void zend_compile_prop(znode *result, zend_ast *ast, uint32_t type) /* {{{ */ } /* }}} */ -zend_op *zend_compile_static_prop_common(znode *result, zend_ast *ast, uint32_t type) /* {{{ */ +zend_op *zend_compile_static_prop_common(znode *result, zend_ast *ast, uint32_t type, int delayed) /* {{{ */ { zend_ast *class_ast = ast->child[0]; zend_ast *prop_ast = ast->child[1]; @@ -2168,7 +2180,11 @@ zend_op *zend_compile_static_prop_common(znode *result, zend_ast *ast, uint32_t zend_compile_expr(&prop_node, prop_ast); - opline = zend_emit_op(result, ZEND_FETCH_R, &prop_node, NULL); + if (delayed) { + opline = zend_delayed_emit_op(result, ZEND_FETCH_R, &prop_node, NULL); + } else { + opline = zend_emit_op(result, ZEND_FETCH_R, &prop_node, NULL); + } if (opline->op1_type == IS_CONST) { zend_alloc_polymorphic_cache_slot(opline->op1.constant); } @@ -2185,9 +2201,9 @@ zend_op *zend_compile_static_prop_common(znode *result, zend_ast *ast, uint32_t } /* }}} */ -void zend_compile_static_prop(znode *result, zend_ast *ast, uint32_t type) /* {{{ */ +void zend_compile_static_prop(znode *result, zend_ast *ast, uint32_t type, int delayed) /* {{{ */ { - zend_op *opline = zend_compile_static_prop_common(result, ast, type); + zend_op *opline = zend_compile_static_prop_common(result, ast, type, delayed); zend_adjust_for_fetch_type(opline, type); } /* }}} */ @@ -2291,7 +2307,7 @@ void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */ if (zend_is_assign_to_self(var_ast, expr_ast)) { /* $a[0] = $a should evaluate the right $a first */ - zend_compile_simple_var_no_cv(&expr_node, expr_ast, BP_VAR_R); + zend_compile_simple_var_no_cv(&expr_node, expr_ast, BP_VAR_R, 0); } else { zend_compile_expr(&expr_node, expr_ast); } @@ -3088,7 +3104,7 @@ void zend_compile_unset(zend_ast *ast) /* {{{ */ opline = zend_emit_op(NULL, ZEND_UNSET_VAR, &var_node, NULL); opline->extended_value = ZEND_FETCH_LOCAL | ZEND_QUICK_SET; } else { - opline = zend_compile_simple_var_no_cv(NULL, var_ast, BP_VAR_UNSET); + opline = zend_compile_simple_var_no_cv(NULL, var_ast, BP_VAR_UNSET, 0); opline->opcode = ZEND_UNSET_VAR; } return; @@ -3101,7 +3117,7 @@ void zend_compile_unset(zend_ast *ast) /* {{{ */ opline->opcode = ZEND_UNSET_OBJ; return; case ZEND_AST_STATIC_PROP: - opline = zend_compile_static_prop_common(NULL, var_ast, BP_VAR_UNSET); + opline = zend_compile_static_prop_common(NULL, var_ast, BP_VAR_UNSET, 0); opline->opcode = ZEND_UNSET_VAR; return; EMPTY_SWITCH_DEFAULT_CASE() @@ -5613,7 +5629,7 @@ void zend_compile_isset_or_empty(znode *result, zend_ast *ast) /* {{{ */ opline = zend_emit_op(result, ZEND_ISSET_ISEMPTY_VAR, &var_node, NULL); opline->extended_value = ZEND_FETCH_LOCAL | ZEND_QUICK_SET; } else { - opline = zend_compile_simple_var_no_cv(result, var_ast, BP_VAR_IS); + opline = zend_compile_simple_var_no_cv(result, var_ast, BP_VAR_IS, 0); opline->opcode = ZEND_ISSET_ISEMPTY_VAR; } break; @@ -5626,7 +5642,7 @@ void zend_compile_isset_or_empty(znode *result, zend_ast *ast) /* {{{ */ opline->opcode = ZEND_ISSET_ISEMPTY_PROP_OBJ; break; case ZEND_AST_STATIC_PROP: - opline = zend_compile_static_prop_common(result, var_ast, BP_VAR_IS); + opline = zend_compile_static_prop_common(result, var_ast, BP_VAR_IS, 0); opline->opcode = ZEND_ISSET_ISEMPTY_VAR; break; EMPTY_SWITCH_DEFAULT_CASE() @@ -5650,7 +5666,7 @@ void zend_compile_silence(znode *result, zend_ast *ast) /* {{{ */ if (expr_ast->kind == ZEND_AST_VAR) { /* For @$var we need to force a FETCH instruction, otherwise the CV access will * happen outside the silenced section. */ - zend_compile_simple_var_no_cv(result, expr_ast, BP_VAR_R); + zend_compile_simple_var_no_cv(result, expr_ast, BP_VAR_R, 0 ); } else { zend_compile_expr(result, expr_ast); } @@ -6406,7 +6422,7 @@ void zend_compile_var(znode *result, zend_ast *ast, uint32_t type) /* {{{ */ { switch (ast->kind) { case ZEND_AST_VAR: - zend_compile_simple_var(result, ast, type); + zend_compile_simple_var(result, ast, type, 0); return; case ZEND_AST_DIM: zend_compile_dim(result, ast, type); @@ -6415,7 +6431,7 @@ void zend_compile_var(znode *result, zend_ast *ast, uint32_t type) /* {{{ */ zend_compile_prop(result, ast, type); return; case ZEND_AST_STATIC_PROP: - zend_compile_static_prop(result, ast, type); + zend_compile_static_prop(result, ast, type, 0); return; case ZEND_AST_CALL: zend_compile_call(result, ast, type); @@ -6447,6 +6463,9 @@ void zend_delayed_compile_var(znode *result, zend_ast *ast, uint32_t type) /* {{ { zend_op *opline; switch (ast->kind) { + case ZEND_AST_VAR: + zend_compile_simple_var(result, ast, type, 1); + return; case ZEND_AST_DIM: opline = zend_delayed_compile_dim(result, ast, type); zend_adjust_for_fetch_type(opline, type); @@ -6455,6 +6474,9 @@ void zend_delayed_compile_var(znode *result, zend_ast *ast, uint32_t type) /* {{ opline = zend_delayed_compile_prop(result, ast, type); zend_adjust_for_fetch_type(opline, type); return; + case ZEND_AST_STATIC_PROP: + zend_compile_static_prop(result, ast, type, 1); + return; default: zend_compile_var(result, ast, type); return; |
