mirror of
https://github.com/php/php-src.git
synced 2024-11-23 18:04:36 +08:00
Fixed "delayed" compilation
This commit is contained in:
parent
37ace4ad89
commit
e375ba877a
16
Zend/tests/globals_005.phpt
Normal file
16
Zend/tests/globals_005.phpt
Normal file
@ -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
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user