On Thu, 31 Dec 2015, Nikita Popov wrote:

> On Thu, Dec 31, 2015 at 1:09 AM, Derick Rethans <der...@php.net> wrote:
> 
> > On Thu, 31 Dec 2015, Nikita Popov wrote:
> >
> > > For PHP 7 only: FAST_CALL always jumps to op1. op2 is not a jmp 
> > > addr, it's a try_catch_array offset. For FAST_RET there are no 
> > > jump addresses encoded in the opline. It will either jump back to 
> > > one past the invoking FAST_CALL (of which there may be multiple), 
> > > or (if finally is executed due to an uncaught exception) it will 
> > > jump back to the next applicable catch or finally or leave the 
> > > function.
> >
> > Hmm, that's more complicated than I thought. How would I fix that 
> > code? (PR welcome :D )
> 
> I don't know what you need this for, but maybe you can use the same 
> "good enough" approximation we use for our internal control flow 
> analysis, namely simply say that FAST_CALL either jumps to op1 or to 
> the next instruction, while FAST_RET is treated as a terminator 
> instruction (like RETURN). This does not accurately model control 
> flow, but it may be sufficient for your purposes.

I need to analyse every possible branch, and path through the code in 
order to do dead code analysis (for which I think your simplified 
option works), but also for path coverage, for which I don't think your 
algorithm works. Xinchen alluded on IRC:

15:21 <@laruence> Derick, it used for calling "finally block"
15:22 <@laruence> it has the entry opline of finally block  as opline->op1
15:22 <@laruence> and in the end of finally block ,there always be a 
                  ZEND_FAST_RET opline, which will return to proper address 
                  after finally block codes is executed

To me that indicates that the FAST_RET can jump back to any location 
where FAST_CALL was *called* from (+1)?

In any case, I think my current code does what you describe, except for 
FAST_RET, as that does not act like a RETURN - is there any reason why 
my approach wouldn't work?

Some more observations and questions:

FAST_CALL:
*jmp1 = XDEBUG_ZNODE_JMP_LINE(opcode.op1, position, base_address);

- But what do do for *jmp2 - if extended_value is set?

- I can't come up with PHP code that sets extended_value though. Can you?

FAST_RET:
*jmp1 = position + 1;

- But you indicate that that really should be *jmp1 = XDEBUG_JMP_EXIT?

- Or, it should jump back to something else?
- But how do I know to which possible opline(s) it is going to jump back to?
- Is there a list of these somewhere?
- I can't come up with PHP code that sets extended_value here either. 
  Can you?

cheers,
Derick

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

Reply via email to