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:[EMAIL PROTECTED] 
>> Sent: Sunday, March 04, 2007 8:26 AM
>> To: [EMAIL PROTECTED]; 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
>> .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

Reply via email to