summaryrefslogtreecommitdiff
path: root/Zend
diff options
context:
space:
mode:
authorZeev Suraski <zeev@php.net>1999-07-24 11:24:19 +0000
committerZeev Suraski <zeev@php.net>1999-07-24 11:24:19 +0000
commit1b6fae101a3903f57e9b990c15a890b24497b131 (patch)
treef17f19a256c330013872beb6cafca332b29ee434 /Zend
parentb0c60bd249bb684e211ce58253a35a8598ee7ffc (diff)
downloadphp-git-1b6fae101a3903f57e9b990c15a890b24497b131.tar.gz
Thoroughly fix the SWITCH problem. No RETURN handling yet.
Diffstat (limited to 'Zend')
-rw-r--r--Zend/zend-parser.y8
-rw-r--r--Zend/zend_compile.c15
-rw-r--r--Zend/zend_compile.h119
-rw-r--r--Zend/zend_execute.c18
4 files changed, 90 insertions, 70 deletions
diff --git a/Zend/zend-parser.y b/Zend/zend-parser.y
index 56263f4847..f0c853d2af 100644
--- a/Zend/zend-parser.y
+++ b/Zend/zend-parser.y
@@ -161,11 +161,11 @@ statement:
| T_FOR
'('
for_expr
- ';' { do_free(&$3, 0 CLS_CC); $4.u.opline_num = get_next_op_number(CG(active_op_array)); }
+ ';' { do_free(&$3 CLS_CC); $4.u.opline_num = get_next_op_number(CG(active_op_array)); }
for_expr
';' { do_for_cond(&$6, &$7 CLS_CC); }
for_expr
- ')' { do_free(&$9, 0 CLS_CC); do_for_before_statement(&$4, &$7 CLS_CC); }
+ ')' { do_free(&$9 CLS_CC); do_for_before_statement(&$4, &$7 CLS_CC); }
for_statement { do_for_end(&$7 CLS_CC); }
| T_SWITCH '(' expr ')' { do_switch_cond(&$3 CLS_CC); } switch_case_list { do_switch_end(&$6 CLS_CC); }
| T_BREAK ';' { do_brk_cont(ZEND_BRK, NULL CLS_CC); }
@@ -178,7 +178,7 @@ statement:
| T_STATIC static_var_list
| T_ECHO echo_expr_list ';'
| T_INLINE_HTML { do_echo(&$1 CLS_CC); }
- | expr ';' { do_free(&$1, 0 CLS_CC); }
+ | expr ';' { do_free(&$1 CLS_CC); }
| T_REQUIRE expr ';' { if ($2.op_type==IS_CONST && $2.u.constant.type==IS_STRING) { require_filename($2.u.constant.value.str.val CLS_CC); zval_dtor(&$2.u.constant); } else { do_include_or_eval(ZEND_INCLUDE, &$$, &$2 CLS_CC); } }
| T_UNSET '(' r_cvar ')' ';' { do_unset(&$3 CLS_CC); }
| T_FOREACH '(' expr T_AS { do_foreach_begin(&$1, &$3, &$2, &$4 CLS_CC); } w_cvar foreach_optional_arg ')' { do_foreach_cont(&$6, &$7, &$4 CLS_CC); } foreach_statement { do_foreach_end(&$1, &$2 CLS_CC); }
@@ -358,7 +358,7 @@ echo_expr_list:
for_expr:
/* empty */ { $$.op_type = IS_CONST; $$.u.constant.type = IS_BOOL; $$.u.constant.value.lval = 1; }
- | for_expr ',' { do_free(&$1, 0 CLS_CC); } expr { $$ = $4; }
+ | for_expr ',' { do_free(&$1 CLS_CC); } expr { $$ = $4; }
| expr { $$ = $1; }
;
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 277cebe3c6..67fed1297f 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -573,7 +573,7 @@ void do_add_variable(znode *result, znode *op1, znode *op2 CLS_DC)
}
-void do_free(znode *op1, int is_used CLS_DC)
+void do_free(znode *op1 CLS_DC)
{
if (op1->op_type==IS_TMP_VAR) {
zend_op *opline = get_next_op(CG(active_op_array) CLS_CC);
@@ -581,7 +581,7 @@ void do_free(znode *op1, int is_used CLS_DC)
opline->opcode = ZEND_FREE;
opline->op1 = *op1;
SET_UNUSED(opline->op2);
- } else if (!is_used && op1->op_type==IS_VAR) {
+ } else if (op1->op_type==IS_VAR) {
zend_op *opline = &CG(active_op_array)->opcodes[CG(active_op_array)->last-1];
if (opline->result.op_type == op1->op_type
@@ -1095,7 +1095,10 @@ void do_switch_end(znode *case_list CLS_DC)
CG(active_op_array)->current_brk_cont = CG(active_op_array)->brk_cont_array[CG(active_op_array)->current_brk_cont].parent;
/* emit free for the switch condition*/
- do_free(&switch_entry_ptr->cond, 1 CLS_CC);
+ opline = get_next_op(CG(active_op_array) CLS_CC);
+ opline->opcode = ZEND_SWITCH_FREE;
+ opline->op1 = switch_entry_ptr->cond;
+ SET_UNUSED(opline->op2);
if (switch_entry_ptr->cond.op_type == IS_CONST) {
zval_dtor(&switch_entry_ptr->cond.u.constant);
}
@@ -1370,7 +1373,7 @@ void do_end_new_object(znode *class_name, znode *new_token, znode *argument_list
zval_copy_ctor(&class_name->u.constant);
}
do_end_function_call(class_name, &ctor_result, argument_list, 1 CLS_CC);
- do_free(&ctor_result, 0 CLS_CC);
+ do_free(&ctor_result CLS_CC);
CG(active_op_array)->opcodes[new_token->u.opline_num].op2.u.opline_num = get_next_op_number(CG(active_op_array));
}
@@ -1767,7 +1770,7 @@ void do_foreach_cont(znode *value, znode *key, znode *as_token CLS_DC)
do_assign(&dummy, key, &result_key CLS_CC);
CG(active_op_array)->opcodes[CG(active_op_array)->last-1].result.u.EA.type |= EXT_TYPE_UNUSED;
}
- do_free(as_token, 0 CLS_CC);
+ do_free(as_token CLS_CC);
do_begin_loop(CLS_C);
INC_BPC(CG(active_op_array));
@@ -1786,7 +1789,7 @@ void do_foreach_end(znode *foreach_token, znode *open_brackets_token CLS_DC)
do_end_loop(foreach_token->u.opline_num CLS_CC);
- do_free(open_brackets_token, 0 CLS_CC);
+ do_free(open_brackets_token CLS_CC);
DEC_BPC(CG(active_op_array));
}
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index ff64d18d26..37f10d48f2 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -250,7 +250,7 @@ void do_post_incdec(znode *result, znode *op1, int op CLS_DC);
void do_begin_variable_parse(CLS_D);
void do_end_variable_parse(int type CLS_DC);
-void do_free(znode *op1, int is_used CLS_DC);
+void do_free(znode *op1 CLS_DC);
void do_init_string(znode *result CLS_DC);
void do_add_char(znode *result, znode *op1, znode *op2 CLS_DC);
@@ -418,8 +418,8 @@ int zendlex(znode *zendlval CLS_DC);
#define ZEND_ASSIGN 36
#define ZEND_ASSIGN_REF 37
-#define ZEND_ECHO 38
-#define ZEND_PRINT 39
+#define ZEND_ECHO 38
+#define ZEND_PRINT 39
#define ZEND_JMP 40
#define ZEND_JMPZ 41
@@ -428,74 +428,75 @@ int zendlex(znode *zendlval CLS_DC);
#define ZEND_JMPZ_EX 44
#define ZEND_JMPNZ_EX 45
#define ZEND_CASE 46
-#define ZEND_BRK 47
-#define ZEND_CONT 48
-#define ZEND_BOOL 49
-
-#define ZEND_INIT_STRING 50
-#define ZEND_ADD_CHAR 51
-#define ZEND_ADD_STRING 52
-#define ZEND_ADD_VAR 53
-
-#define ZEND_BEGIN_SILENCE 54
-#define ZEND_END_SILENCE 55
-
-#define ZEND_INIT_FCALL_BY_NAME 56
-#define ZEND_DO_FCALL 57
-#define ZEND_DO_FCALL_BY_NAME 58
-#define ZEND_RETURN 59
-
-#define ZEND_RECV 60
-#define ZEND_RECV_INIT 61
+#define ZEND_SWITCH_FREE 47
+#define ZEND_BRK 48
+#define ZEND_CONT 49
+#define ZEND_BOOL 50
+
+#define ZEND_INIT_STRING 51
+#define ZEND_ADD_CHAR 52
+#define ZEND_ADD_STRING 53
+#define ZEND_ADD_VAR 54
+
+#define ZEND_BEGIN_SILENCE 55
+#define ZEND_END_SILENCE 56
+
+#define ZEND_INIT_FCALL_BY_NAME 57
+#define ZEND_DO_FCALL 58
+#define ZEND_DO_FCALL_BY_NAME 59
+#define ZEND_RETURN 60
+
+#define ZEND_RECV 61
+#define ZEND_RECV_INIT 62
-#define ZEND_SEND_VAL 62
-#define ZEND_SEND_VAR 63
-#define ZEND_SEND_REF 64
+#define ZEND_SEND_VAL 63
+#define ZEND_SEND_VAR 64
+#define ZEND_SEND_REF 65
-#define ZEND_NEW 65
-#define ZEND_JMP_NO_CTOR 66
-#define ZEND_FREE 67
+#define ZEND_NEW 66
+#define ZEND_JMP_NO_CTOR 67
+#define ZEND_FREE 68
-#define ZEND_INIT_ARRAY 68
-#define ZEND_ADD_ARRAY_ELEMENT 69
+#define ZEND_INIT_ARRAY 69
+#define ZEND_ADD_ARRAY_ELEMENT 70
-#define ZEND_INCLUDE_OR_EVAL 70
+#define ZEND_INCLUDE_OR_EVAL 71
-#define ZEND_UNSET_VAR 71
-#define ZEND_UNSET_DIM_OBJ 72
-#define ZEND_ISSET_ISEMPTY 73
+#define ZEND_UNSET_VAR 72
+#define ZEND_UNSET_DIM_OBJ 73
+#define ZEND_ISSET_ISEMPTY 74
-#define ZEND_FE_RESET 74
-#define ZEND_FE_FETCH 75
+#define ZEND_FE_RESET 75
+#define ZEND_FE_FETCH 76
-#define ZEND_EXIT 76
+#define ZEND_EXIT 77
/* the following 12 opcodes are 4 groups of 3 opcodes each, and must
* remain in that order!
*/
-#define ZEND_FETCH_R 77
-#define ZEND_FETCH_DIM_R 78
-#define ZEND_FETCH_OBJ_R 79
-#define ZEND_FETCH_W 80
-#define ZEND_FETCH_DIM_W 81
-#define ZEND_FETCH_OBJ_W 82
-#define ZEND_FETCH_RW 83
-#define ZEND_FETCH_DIM_RW 84
-#define ZEND_FETCH_OBJ_RW 85
-#define ZEND_FETCH_IS 86
-#define ZEND_FETCH_DIM_IS 87
-#define ZEND_FETCH_OBJ_IS 88
-
-#define ZEND_FETCH_DIM_TMP_VAR 89
-#define ZEND_FETCH_CONSTANT 90
-
-#define ZEND_DECLARE_FUNCTION_OR_CLASS 91
-
-#define ZEND_EXT_STMT 92
-#define ZEND_EXT_FCALL_BEGIN 93
-#define ZEND_EXT_FCALL_END 94
-#define ZEND_EXT_NOP 95
+#define ZEND_FETCH_R 78
+#define ZEND_FETCH_DIM_R 79
+#define ZEND_FETCH_OBJ_R 80
+#define ZEND_FETCH_W 81
+#define ZEND_FETCH_DIM_W 82
+#define ZEND_FETCH_OBJ_W 83
+#define ZEND_FETCH_RW 84
+#define ZEND_FETCH_DIM_RW 85
+#define ZEND_FETCH_OBJ_RW 86
+#define ZEND_FETCH_IS 87
+#define ZEND_FETCH_DIM_IS 88
+#define ZEND_FETCH_OBJ_IS 89
+
+#define ZEND_FETCH_DIM_TMP_VAR 90
+#define ZEND_FETCH_CONSTANT 91
+
+#define ZEND_DECLARE_FUNCTION_OR_CLASS 92
+
+#define ZEND_EXT_STMT 93
+#define ZEND_EXT_FCALL_BEGIN 94
+#define ZEND_EXT_FCALL_END 95
+#define ZEND_EXT_NOP 96
/* end of block */
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index eacac2bb34..dc605f5fff 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -1609,13 +1609,29 @@ send_by_ref:
get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R),
get_zval_ptr(&opline->op2, Ts, &free_op2, BP_VAR_R));
- FREE_OP(&opline->op1, free_op1);
FREE_OP(&opline->op2, free_op2);
if (switch_expr_is_overloaded) {
+ /* We only free op1 if this is a string offset,
+ * Since if it is a TMP_VAR, it'll be reused by
+ * other CASE opcodes (whereas string offsets
+ * are allocated at each get_zval_ptr())
+ */
+ FREE_OP(&opline->op1, free_op1);
Ts[opline->op1.u.var].var = NULL;
}
}
break;
+ case ZEND_SWITCH_FREE:
+ switch (opline->op1.op_type) {
+ case IS_VAR:
+ get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R);
+ FREE_OP(&opline->op1, free_op1);
+ break;
+ case IS_TMP_VAR:
+ zendi_zval_dtor(Ts[opline->op1.u.var].tmp_var);
+ break;
+ }
+ break;
case ZEND_NEW: {
zval *tmp = get_zval_ptr(&opline->op1, Ts, &free_op1, BP_VAR_R);
zval class_name;