前言
运行指令字节码(ByteCode)是JavaScriptCore引擎中很核心的部分,各家JavaScript引擎的优化也主要集中于此。JSByteCode的解释执行是一套很复杂的系统,特别是加入了OSR和多级JIT技术之后,整个解释执行变的越来越高效,并且让整个ByteCode的执行在低延时之间和高吞吐之间有个很好的平衡:由低延时的LLInt来解释执行ByteCode,当遇到多次重复调用或者是递归,循环等条件会通过OSR切换成JIT进行解释执行(根据具体触发条件会进入不同的JIT进行动态解释)来加快速度。
// CLoopRegister来模拟真正的CPU寄存器,它定义了如下策略:
// 1、如何将小于intptr_t的整形打包进假寄存器;
// 2、隐藏了大端和小端的区别
1 | struct UnlinkedInstruction |
1 | struct ProtoCallFrame { |
1 | JSValue execute(ProgramExecutable*, CallFrame*, JSObject* thisObj); |
1 | // 解释器执行要素:可执行程序、执行栈、全局对象 |
ProgramExecutable
ProgramExecutable
可以理解为当前所执行脚本的大总管,从其名字上可以看出来是代表一个可执行程序
先初始化全局属性
处理的结果都会记录在 callFrame 里。主要是通过 JSGlobalObject 这个对象的 addFunction 和 addVar 方法记录 Parser 出那些在全局空间的那些 let,const 和 class 的全局属性,或者 var,let 和 const 的全局变量
1 | // 初始化全局属性 |
1 | JSObject* ScriptExecutable::prepareForExecutionImpl( |