summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2015-02-02 20:44:16 +0300
committerDmitry Stogov <dmitry@zend.com>2015-02-02 20:44:16 +0300
commite375ba877afc52a273e342fa927f69fb759fd0e5 (patch)
tree311d28553a707609ae0b9ac24710aa02b432419b
parent37ace4ad89d1d738b1a72057498e93e5d7ec1a2b (diff)
downloadphp-git-e375ba877afc52a273e342fa927f69fb759fd0e5.tar.gz
Fixed "delayed" compilation
-rw-r--r--Zend/tests/globals_005.phpt16
-rw-r--r--Zend/zend_compile.c58
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;