diff options
author | Zeev Suraski <zeev@php.net> | 1999-07-24 11:24:19 +0000 |
---|---|---|
committer | Zeev Suraski <zeev@php.net> | 1999-07-24 11:24:19 +0000 |
commit | 1b6fae101a3903f57e9b990c15a890b24497b131 (patch) | |
tree | f17f19a256c330013872beb6cafca332b29ee434 /Zend | |
parent | b0c60bd249bb684e211ce58253a35a8598ee7ffc (diff) | |
download | php-git-1b6fae101a3903f57e9b990c15a890b24497b131.tar.gz |
Thoroughly fix the SWITCH problem. No RETURN handling yet.
Diffstat (limited to 'Zend')
-rw-r--r-- | Zend/zend-parser.y | 8 | ||||
-rw-r--r-- | Zend/zend_compile.c | 15 | ||||
-rw-r--r-- | Zend/zend_compile.h | 119 | ||||
-rw-r--r-- | Zend/zend_execute.c | 18 |
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; |