php - 当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
被某物读取吗?或者跳转会完全忽略它吗?
解决方案
操作码由 Zend 执行器执行。如果你想知道它是如何工作的,你需要阅读它的源文件。
您将在此处找到一般介绍:
推荐阅读
- graph - 约束 core.logic 查询的结果?
- libreoffice - 卡在 LibreOffice 文档末尾的一个部分
- java - .text 不打印任何内容,但 .append 可以
- java - 如何将集合中的所有整数加 1
(爪哇)? - reactjs - 结合 React 最终形式数组和最终形式计算
- java - 如何使用 selenium java 将表的内容写入 csv 文件?
- node.js - 一旦会话过期,Node.js 会抓取刷新令牌 FIREBASE
- jquery - $(document).ready() 更新视图组件后未触发
- api - 如何分配唯一的二维码并对其进行身份验证
- algorithm - 如果数据不适合物理 RAM 内存,最快排序?