0
<?php
echo "A";
try {
    echo "B";
    throw new Exception("B");
    try {
        echo "C";
    } catch(Exception $e) {
        echo "inner";
    }
    echo "D";
} catch(Exception $e) {
    echo "outer";
}
echo "E";
?>

Called with php -dvld.active=1 -dvld.execute=0 -dvld.dump_paths=1 multiple_catch.php 2> multiple_catch.php.byte results in

number of ops:  16
compiled vars:  !0 = $e
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
    3     0  E >   ECHO                                                     'A'
    7     1        ECHO                                                     'B'
    8     2        NEW                                              $1      'Exception'
          3        SEND_VAL_EX                                              'B'
          4        DO_FCALL                                      0          
          5      > THROW                                         0          $1
   12     6*       ECHO                                                     'C'
          7*       JMP                                                      ->10
   14     8  E > > CATCH                                       last         'Exception'
   15     9    >   ECHO                                                     'inner'
   18    10        ECHO                                                     'D'
         11      > JMP                                                      ->14
   20    12  E > > CATCH                                       last         'Exception'
   21    13    >   ECHO                                                     'outer'
   24    14    >   ECHO                                                     'E'
   27    15      > RETURN                                                   1

However, just naively reading the op column it looks as if an exception thrown by op 5 would lead to the print out of 'inner'. However, when taking the original source into account, this is obviously wrong as running the source confirms:

$> php multiple_catch.php
ABouterE

How does the PHP engine know the try block it is in based on the byte code?

Sim
  • 4,199
  • 4
  • 39
  • 77
  • Remember you are looking at (for want of a better word) compiled code. All possibilities are compiled, but not all path are possible. Some compilers would actually flag that the inner try could never actually be reached – RiggsFolly Jun 25 '20 at 09:28
  • @RiggsFolly This bytecode was generated using the vulcan logic dumper and it seems to be semi correct in that regard as it realized that OP 6 and 7 are not reachable,i.e., the stars. However, I cross checked whether this dead-branch issue might hide information by wrapping the `throw` in a random number decided `if`. It did not change the output in a way that would indicate new information. – Sim Jun 25 '20 at 09:44

0 Answers0