Re: [ZEND-ENGINE-CVS] cvs: ZendEngine2 / zend_language_parser.y

From: Date: Tue, 06 Mar 2007 08:33:33 +0000
Subject: Re: [ZEND-ENGINE-CVS] cvs: ZendEngine2 / zend_language_parser.y
References: 1 2  Groups: php.doc php.zend-engine.cvs 
Request: Send a blank email to phpdoc+get-969375740@lists.php.net to get a copy of this message
Hello Andi, actually it seems to be handling function calls on the left wrong. That's why I provided a better imlementation. Well we agreed way back that we wanted to have something like this. Maybe the I have it wrong in mind and we haven't really agreed on the exact behavior. But what I remember is that we wanted ?: behave just like a shortcut. And that is what I did. No with the new patch it works pretty fine. Patch is attached. best regards marcus Tuesday, March 6, 2007, 3:54:13 AM, you wrote: > Did we agree on this? I don't remember we concluded this discussion. > In any case, are you sure there's not a double free bug here? (Using $1 > twice?). While I haven't validated this, it seems to be buggy just by > looking at it. > Andi >> -----Original Message----- >> From: Marcus Boerger [mailto:helly@php.net] >> Sent: Sunday, March 04, 2007 8:26 AM >> To: zend-engine-cvs@lists.php.net; phpdoc@lists.php.net >> Subject: [ZEND-ENGINE-CVS] cvs: ZendEngine2 / zend_language_parser.y >> >> helly Sun Mar 4 16:25:58 2007 UTC >> >> Modified files: >> /ZendEngine2 zend_language_parser.y >> Log: >> - Implement '?:' >> [DOC] "expr1 ?: expr1" is a shortcut for: "expr1 ? expr1 : expr2" as >> exists in gcc and discussed some time back. Note that >> this is not >> an implementation ifsetor($var, default). While >> ifsetor would not >> generate any message for non existing variables or >> array indices >> the ternary shortcut does. Also the ternary shortcut >> does a boolean >> evaluation rather then checking for isset(). That way >> ther ternary >> shortcut can work on any expression while ifsetor can >> only work on >> variables. Also to be silent one has do do: "@$expr1 >> ?: $expr2". >> >> >> http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_language_parser*ˆ¥�[[BΔ >> ÓG†m >> .y?r1=1.178&r2=1.179&diff_format=u >> Index: ZendEngine2/zend_language_parser.y >> diff -u ZendEngine2/zend_language_parser.y:1.178 >> ZendEngine2/zend_language_parser.y:1.179 >> --- ZendEngine2/zend_language_parser.y:1.178 Mon Jan 29 04:40:46 2007 >> +++ ZendEngine2/zend_language_parser.y Sun Mar 4 16:25:57 2007 >> @@ -18,7 +18,7 @@ >> >> +------------------------------------------------------------- >> ---------+ >> */ >> >> -/* $Id: zend_language_parser.y,v 1.178 2007/01/29 04:40:46 >> iliaa Exp $ */ >> +/* $Id: zend_language_parser.y,v 1.179 2007/03/04 16:25:57 >> helly Exp $ >> +*/ >> >> /* >> * LALR shift/reduce conflicts and how they are resolved: >> @@ -611,6 +611,9 @@ >> | expr '?' { zend_do_begin_qm_op(&$1, &$2 TSRMLS_CC); } >> expr ':' { zend_do_qm_true(&$4, &$2, &$5 TSRMLS_CC); } >> expr { zend_do_qm_false(&$$, &$7, &$2, &$5 >> TSRMLS_CC); } >> + | expr '?' { zend_do_begin_qm_op(&$1, &$2 TSRMLS_CC); } >> + ':' { zend_do_qm_true(&$1, &$2, &$4 TSRMLS_CC); } >> + expr { zend_do_qm_false(&$$, &$6, &$2, &$4 >> TSRMLS_CC); } >> | internal_functions_in_yacc { $$ = $1; } >> | T_INT_CAST expr { zend_do_cast(&$$, >> &$2, IS_LONG TSRMLS_CC); } >> | T_DOUBLE_CAST expr { zend_do_cast(&$$, >> &$2, IS_DOUBLE TSRMLS_CC); } >> >> -- >> Zend Engine CVS Mailing List (http://cvs.php.net/) To >> unsubscribe, visit: http://www.php.net/unsub.php >> >> Best regards, Marcus

Index: Zend/zend_compile.c =================================================================== RCS file: /repository/ZendEngine2/zend_compile.c,v retrieving revision 1.740 diff -u -p -d -r1.740 zend_compile.c --- Zend/zend_compile.c 16 Feb 2007 19:36:45 -0000 1.740 +++ Zend/zend_compile.c 6 Mar 2007 00:49:40 -0000 @@ -4206,6 +4206,43 @@ void zend_do_end_silence(znode *strudel_ } +void zend_do_jmp_set(znode *value, znode *jmp_token, znode *colon_token TSRMLS_DC) +{ + int op_number = get_next_op_number(CG(active_op_array)); + zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); + + opline->opcode = ZEND_JMP_SET; + opline->result.op_type = IS_TMP_VAR; + opline->result.u.var = get_temporary_variable(CG(active_op_array)); + opline->op1 = *value; + SET_UNUSED(opline->op2); + + *colon_token = opline->result; + + jmp_token->u.opline_num = op_number; + + INC_BPC(CG(active_op_array)); +} + + +void zend_do_jmp_set_else(znode *result, znode *false_value, znode *jmp_token, znode *colon_token TSRMLS_DC) +{ + zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); + + opline->opcode = ZEND_QM_ASSIGN; + opline->extended_value = 0; + opline->result = *colon_token; + opline->op1 = *false_value; + SET_UNUSED(opline->op2); + + *result = opline->result; + + CG(active_op_array)->opcodes[jmp_token->u.opline_num].op2.u.opline_num = get_next_op_number(CG(active_op_array)); + + DEC_BPC(CG(active_op_array)); +} + + void zend_do_begin_qm_op(znode *cond, znode *qm_token TSRMLS_DC) { int jmpz_op_number = get_next_op_number(CG(active_op_array)); Index: Zend/zend_compile.h =================================================================== RCS file: /repository/ZendEngine2/zend_compile.h,v retrieving revision 1.355 diff -u -p -d -r1.355 zend_compile.h --- Zend/zend_compile.h 16 Feb 2007 19:36:45 -0000 1.355 +++ Zend/zend_compile.h 6 Mar 2007 00:49:40 -0000 @@ -506,6 +506,9 @@ void zend_do_exit(znode *result, znode * void zend_do_begin_silence(znode *strudel_token TSRMLS_DC); void zend_do_end_silence(znode *strudel_token TSRMLS_DC); +void zend_do_jmp_set(znode *value, znode *jmp_token, znode *colon_token TSRMLS_DC); +void zend_do_jmp_set_else(znode *result, znode *false_value, znode *jmp_token, znode *colon_token TSRMLS_DC); + void zend_do_begin_qm_op(znode *cond, znode *qm_token TSRMLS_DC); void zend_do_qm_true(znode *true_value, znode *qm_token, znode *colon_token TSRMLS_DC); void zend_do_qm_false(znode *result, znode *false_value, znode *qm_token, znode *colon_token TSRMLS_DC); Index: Zend/zend_execute_API.c =================================================================== RCS file: /repository/ZendEngine2/zend_execute_API.c,v retrieving revision 1.397 diff -u -p -d -r1.397 zend_execute_API.c --- Zend/zend_execute_API.c 3 Mar 2007 13:46:19 -0000 1.397 +++ Zend/zend_execute_API.c 6 Mar 2007 00:49:40 -0000 @@ -1376,6 +1376,7 @@ void execute_new_code(TSRMLS_D) case ZEND_JMPNZ: case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: + case ZEND_JMP_SET: opline->op2.u.jmp_addr = &CG(active_op_array)->opcodes[opline->op2.u.opline_num]; break; } Index: Zend/zend_language_parser.y =================================================================== RCS file: /repository/ZendEngine2/zend_language_parser.y,v retrieving revision 1.179 diff -u -p -d -r1.179 zend_language_parser.y --- Zend/zend_language_parser.y 4 Mar 2007 16:25:57 -0000 1.179 +++ Zend/zend_language_parser.y 6 Mar 2007 00:49:40 -0000 @@ -611,9 +611,8 @@ expr_without_variable: | expr '?' { zend_do_begin_qm_op(&$1, &$2 TSRMLS_CC); } expr ':' { zend_do_qm_true(&$4, &$2, &$5 TSRMLS_CC); } expr { zend_do_qm_false(&$$, &$7, &$2, &$5 TSRMLS_CC); } - | expr '?' { zend_do_begin_qm_op(&$1, &$2 TSRMLS_CC); } - ':' { zend_do_qm_true(&$1, &$2, &$4 TSRMLS_CC); } - expr { zend_do_qm_false(&$$, &$6, &$2, &$4 TSRMLS_CC); } + | expr '?' ':' { zend_do_jmp_set(&$1, &$2, &$3 TSRMLS_CC); } + expr { zend_do_jmp_set_else(&$$, &$5, &$2, &$3 TSRMLS_CC); } | internal_functions_in_yacc { $$ = $1; } | T_INT_CAST expr { zend_do_cast(&$$, &$2, IS_LONG TSRMLS_CC); } | T_DOUBLE_CAST expr { zend_do_cast(&$$, &$2, IS_DOUBLE TSRMLS_CC); } Index: Zend/zend_opcode.c =================================================================== RCS file: /repository/ZendEngine2/zend_opcode.c,v retrieving revision 1.126 diff -u -p -d -r1.126 zend_opcode.c --- Zend/zend_opcode.c 15 Feb 2007 10:42:51 -0000 1.126 +++ Zend/zend_opcode.c 6 Mar 2007 00:49:41 -0000 @@ -427,6 +427,7 @@ int pass_two(zend_op_array *op_array TSR case ZEND_JMPNZ: case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: + case ZEND_JMP_SET: opline->op2.u.jmp_addr = &op_array->opcodes[opline->op2.u.opline_num]; break; } Index: Zend/zend_vm_def.h =================================================================== RCS file: /repository/ZendEngine2/zend_vm_def.h,v retrieving revision 1.160 diff -u -p -d -r1.160 zend_vm_def.h --- Zend/zend_vm_def.h 25 Feb 2007 16:12:18 -0000 1.160 +++ Zend/zend_vm_def.h 6 Mar 2007 00:49:41 -0000 @@ -3769,6 +3769,26 @@ ZEND_VM_HANDLER(58, ZEND_END_SILENCE, TM ZEND_VM_NEXT_OPCODE(); } +ZEND_VM_HANDLER(152, ZEND_JMP_SET, CONST|TMP|VAR|CV, ANY) +{ + zend_op *opline = EX(opline); + zend_free_op free_op1; + zval *value = GET_OP1_ZVAL_PTR(BP_VAR_R); + + if (i_zend_is_true(value)) { + EX_T(opline->result.u.var).tmp_var = *value; + zendi_zval_copy_ctor(EX_T(opline->result.u.var).tmp_var); + FREE_OP1(); +#if DEBUG_ZEND>=2 + printf("Conditional jmp to %d\n", opline->op2.u.opline_num); +#endif + ZEND_VM_JMP(opline->op2.u.jmp_addr); + } + + FREE_OP1(); + ZEND_VM_NEXT_OPCODE(); +} + ZEND_VM_HANDLER(22, ZEND_QM_ASSIGN, CONST|TMP|VAR|CV, ANY) { zend_op *opline = EX(opline); Index: Zend/zend_vm_execute.h =================================================================== RCS file: /repository/ZendEngine2/zend_vm_execute.h,v retrieving revision 1.163 diff -u -p -d -r1.163 zend_vm_execute.h --- Zend/zend_vm_execute.h 25 Feb 2007 16:12:18 -0000 1.163 +++ Zend/zend_vm_execute.h 6 Mar 2007 00:49:43 -0000 @@ -2350,6 +2350,25 @@ static int ZEND_EXIT_SPEC_CONST_HANDLER( ZEND_VM_NEXT_OPCODE(); } +static int ZEND_JMP_SET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + zend_op *opline = EX(opline); + + zval *value = &opline->op1.u.constant; + + if (i_zend_is_true(value)) { + EX_T(opline->result.u.var).tmp_var = *value; + zendi_zval_copy_ctor(EX_T(opline->result.u.var).tmp_var); + +#if DEBUG_ZEND>=2 + printf("Conditional jmp to %d\n", opline->op2.u.opline_num); +#endif + ZEND_VM_JMP(opline->op2.u.jmp_addr); + } + + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_QM_ASSIGN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); @@ -5024,6 +5043,26 @@ static int ZEND_END_SILENCE_SPEC_TMP_HAN ZEND_VM_NEXT_OPCODE(); } +static int ZEND_JMP_SET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + zend_op *opline = EX(opline); + zend_free_op free_op1; + zval *value = _get_zval_ptr_tmp(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + + if (i_zend_is_true(value)) { + EX_T(opline->result.u.var).tmp_var = *value; + zendi_zval_copy_ctor(EX_T(opline->result.u.var).tmp_var); + zval_dtor(free_op1.var); +#if DEBUG_ZEND>=2 + printf("Conditional jmp to %d\n", opline->op2.u.opline_num); +#endif + ZEND_VM_JMP(opline->op2.u.jmp_addr); + } + + zval_dtor(free_op1.var); + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_QM_ASSIGN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); @@ -8400,6 +8439,26 @@ static int ZEND_EXIT_SPEC_VAR_HANDLER(ZE ZEND_VM_NEXT_OPCODE(); } +static int ZEND_JMP_SET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + zend_op *opline = EX(opline); + zend_free_op free_op1; + zval *value = _get_zval_ptr_var(&opline->op1, EX(Ts), &free_op1 TSRMLS_CC); + + if (i_zend_is_true(value)) { + EX_T(opline->result.u.var).tmp_var = *value; + zendi_zval_copy_ctor(EX_T(opline->result.u.var).tmp_var); + if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; +#if DEBUG_ZEND>=2 + printf("Conditional jmp to %d\n", opline->op2.u.opline_num); +#endif + ZEND_VM_JMP(opline->op2.u.jmp_addr); + } + + if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_QM_ASSIGN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); @@ -20828,6 +20887,25 @@ static int ZEND_EXIT_SPEC_CV_HANDLER(ZEN ZEND_VM_NEXT_OPCODE(); } +static int ZEND_JMP_SET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) +{ + zend_op *opline = EX(opline); + + zval *value = _get_zval_ptr_cv(&opline->op1, EX(Ts), BP_VAR_R TSRMLS_CC); + + if (i_zend_is_true(value)) { + EX_T(opline->result.u.var).tmp_var = *value; + zendi_zval_copy_ctor(EX_T(opline->result.u.var).tmp_var); + +#if DEBUG_ZEND>=2 + printf("Conditional jmp to %d\n", opline->op2.u.opline_num); +#endif + ZEND_VM_JMP(opline->op2.u.jmp_addr); + } + + ZEND_VM_NEXT_OPCODE(); +} + static int ZEND_QM_ASSIGN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) { zend_op *opline = EX(opline); @@ -31339,6 +31417,31 @@ void zend_init_opcodes_handlers() ZEND_U_NORMALIZE_SPEC_CV_HANDLER, ZEND_U_NORMALIZE_SPEC_CV_HANDLER, ZEND_U_NORMALIZE_SPEC_CV_HANDLER, + ZEND_JMP_SET_SPEC_CONST_HANDLER, + ZEND_JMP_SET_SPEC_CONST_HANDLER, + ZEND_JMP_SET_SPEC_CONST_HANDLER, + ZEND_JMP_SET_SPEC_CONST_HANDLER, + ZEND_JMP_SET_SPEC_CONST_HANDLER, + ZEND_JMP_SET_SPEC_TMP_HANDLER, + ZEND_JMP_SET_SPEC_TMP_HANDLER, + ZEND_JMP_SET_SPEC_TMP_HANDLER, + ZEND_JMP_SET_SPEC_TMP_HANDLER, + ZEND_JMP_SET_SPEC_TMP_HANDLER, + ZEND_JMP_SET_SPEC_VAR_HANDLER, + ZEND_JMP_SET_SPEC_VAR_HANDLER, + ZEND_JMP_SET_SPEC_VAR_HANDLER, + ZEND_JMP_SET_SPEC_VAR_HANDLER, + ZEND_JMP_SET_SPEC_VAR_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_NULL_HANDLER, + ZEND_JMP_SET_SPEC_CV_HANDLER, + ZEND_JMP_SET_SPEC_CV_HANDLER, + ZEND_JMP_SET_SPEC_CV_HANDLER, + ZEND_JMP_SET_SPEC_CV_HANDLER, + ZEND_JMP_SET_SPEC_CV_HANDLER, ZEND_NULL_HANDLER }; zend_opcode_handlers = (opcode_handler_t*)labels; Index: Zend/zend_vm_opcodes.h =================================================================== RCS file: /repository/ZendEngine2/zend_vm_opcodes.h,v retrieving revision 1.68 diff -u -p -d -r1.68 zend_vm_opcodes.h --- Zend/zend_vm_opcodes.h 1 Jan 2007 09:29:21 -0000 1.68 +++ Zend/zend_vm_opcodes.h 6 Mar 2007 00:49:43 -0000 @@ -149,3 +149,4 @@ #define ZEND_HANDLE_EXCEPTION 149 #define ZEND_USER_OPCODE 150 #define ZEND_U_NORMALIZE 151 +#define ZEND_JMP_SET 152
« previous php.doc (#969375740) next »