Hi!

While investigating an issue with Xdebug and fast_call/fast_ret, I 
noticed that the opcodes "associated" with the "finally" statement, are 
rolled up in the previous line.

The code:

  1 <?php
  2 function extractFile()
  3 {
  4     try {
  5         echo "try\n";
  6     } catch (Catch1 $e) {
  7         echo "catch1\n";
  8     } catch (Catch2 $e) {
  9         echo "catch2\n";
 10     } finally {
 11         echo "finally\n";
 12     }
 13     echo "end\n";
 14 }
 15 
 16 extractFile();
 17 ?>


Produces:

line     #* E I O op                           fetch          ext  return  
operands
-------------------------------------------------------------------------------------
   5     0  E >   ECHO                                                     
'try%0A'
         1      > JMP                                                      ->7
   6     2  E > > CATCH                                                    
'Catch1', !0, ->5
   7     3    >   ECHO                                                     
'catch1%0A'
         4      > JMP                                                      ->7
   8     5  E > > CATCH                                                    
'Catch2', !0
   9     6    >   ECHO                                                     
'catch2%0A'
         7    > > FAST_CALL                                                ->9
         8*       JMP                                                      ->11
  11     9    >   ECHO                                                     
'finally%0A'
        10      > FAST_RET                                                 
  13    11    >   ECHO                                                     
'end%0A'
  14    12      > RETURN                                                   null


The FAST_CALL/JMP instructions should really be linked to line 10. Not 
doing so produces confusing results while doing code coverage, where it now
shows that the "echo catch2\n" on line 9 is executed. This is of course not
the case, but the linking of FAST_CALL and JMP to line 9 makes it look like
this. Is it possible to change this so thta the FAST_CALL and JMP are linked
to line 10 instead?

And secondly, I am struggeling with where FAST_CALL and FAST_RET can jump to.
Right now, I have: 

https://github.com/derickr/vld/commit/9cf01bba0a1aeef6a261c6c85b238552215a9f0b#diff-286f7620179e1ee0a20e81523d91ff24R1036

+#if PHP_VERSION_ID >= 50500
+       } else if (opcode.opcode == ZEND_FAST_CALL) {
+#if PHP_VERSION_ID >= 70000
+               *jmp1 = VLD_ZNODE_JMP_LINE(opcode.op1, position, base_address);
+#else
+               *jmp1 = ((long) VLD_ZNODE_ELEM(opcode.op1, jmp_addr) - (long) 
base_address) / sizeof(zend_op);
+#endif
+               if (opcode.extended_value) {
+                       *jmp2 = VLD_ZNODE_ELEM(opcode.op2, opline_num);
+               }
+               return 1;
+       } else if (opcode.opcode == ZEND_FAST_RET) {
+               *jmp1 = position + 1;
+               if (opcode.extended_value) {
+                       *jmp2 = VLD_ZNODE_ELEM(opcode.op2, opline_num);
+               }
+               return 1;
+#endif

Which seems to work, although I am unsure about the "+ 1" for FAST_RET.

I also never see anything for opcode.extended_value, and hence the *jmp is
unset. This also returns dumping opcodes with this bit of code (code slightly
lifted from dbg):

https://github.com/derickr/vld/commit/9cf01bba0a1aeef6a261c6c85b238552215a9f0b#diff-286f7620179e1ee0a20e81523d91ff24R684

+#if PHP_VERSION_ID >= 50600
+       switch (op.opcode) {
+               case ZEND_FAST_RET:
+                       if (op.extended_value == ZEND_FAST_RET_TO_FINALLY) {
+                               fetch_type = "to_finally";
+                       } else if (op.extended_value == ZEND_FAST_RET_TO_CATCH) 
{
+                               fetch_type = "to_catch";
+                       }
+                       break;
+               case ZEND_FAST_CALL:
+                       if (op.extended_value == ZEND_FAST_CALL_FROM_FINALLY)
{
+                               fetch_type = "from_finally";
+                       }
+                       break;
+       }
+#endif
+

Any hints?

cheers,
Derick
-- 
http://derickrethans.nl | http://xdebug.org
Like Xdebug? Consider a donation: http://xdebug.org/donate.php
twitter: @derickr and @xdebug
Posted with an email client that doesn't mangle email: alpine

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to