首页 > 解决方案 > 当php OPCODE被zend解释时,真正执行的是什么?

问题描述

假设我运行以下代码:

function isLucky() : bool
{
    for ($i = 0; $i < 50; ++$i) {
        try {
            if (!rand(0, 9)) {
                return true;
            };
            throw new Exception();
        } catch (Exception $e) {
        }
    }
}

一些软件(Vulcan Logic Dumper)让我生成了操作码:

line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   5     0  E >   ASSIGN                                                   !0, 0
         1      > JMP                                                      ->15
   7     2    >   INIT_FCALL                                               'rand'
         3        SEND_VAL                                                 0
         4        SEND_VAL                                                 9
         5        DO_ICALL                                         $3      
         6        BOOL_XOR                                         ~4      $3
         7      > JMPZ                                                     ~4, ->9
   8     8    > > RETURN                                                   <true>
  10     9    >   NEW                                              $5      :20
        10        DO_FCALL                                      0          
        11      > THROW                                         0          $5
        12*       JMP                                                      ->14
  11    13  E > > CATCH                                       last         'Exception'
   5    14    >   PRE_INC                                                  !0
        15    >   IS_SMALLER_OR_EQUAL                              ~8      !0, 50
        16      > JMPNZ                                                    ~8, ->2
  14    17    >   VERIFY_RETURN_TYPE                                       
        18      > RETURN                                                   null

这很好,但是有没有办法让系统真正做到这一点?

这个 zend 框架是否重新解释了每个令牌?系统调用实际上在哪里?每个操作码指令的成本是否相同?

当我使用 objdump 检查 C++ 程序的生成输出时,程序是指令列表,并且跳转到内存地址。

来自使用 -O0 和 -c objdump-ed 编译的 c++ 文件的虚拟 c++ 函数:

0000000000000000 <_Z14dummy_functionb>:
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
   4:   89 f8                   mov    %edi,%eax
   6:   88 45 fc                mov    %al,-0x4(%rbp)
   9:   80 7d fc 00             cmpb   $0x0,-0x4(%rbp)
   d:   74 07                   je     16 <_Z14dummy_functionb+0x16>
   f:   b8 01 00 00 00          mov    $0x1,%eax
  14:   eb 05                   jmp    1b <_Z14dummy_functionb+0x1b>
  16:   b8 00 00 00 00          mov    $0x0,%eax
  1b:   5d                      pop    %rbp
  1c:   c3                      retq   

zend的操作码是这样的吗?

例如,假设一个简单的函数:

<?php

(function (){
    return true;
    throw new Exception();
});


line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   4     0  E > > RETURN                                                   <true>
   5     1*       NEW                                              $0      :4
         2*       DO_FCALL                                      0          
         3*       THROW                                         0          $0
   6     4*     > RETURN                                                   null

表达式会throw被某物读取吗?或者跳转会完全忽略它吗?

标签: phpinstructionsopcode

解决方案


操作码由 Zend 执行器执行。如果你想知道它是如何工作的,你需要阅读它的源文件

您将在此处找到一般介绍:

http://blog.jpauli.tech/2015-02-05-zend-vm-executor-html/


推荐阅读