我正在研究v8编译器的工作方式。我读了一篇文章,其中指出了对源代码进行标记,解析,构造AST,然后生成字节码(https://medium.com/dailyjs/understanding-v8s-bytecode-317d46c94775)
此字节码是中间表示吗?
答案 0 :(得分:2)
简短的回答:否。通常人们使用术语“字节码”和“中间表示”来表示两种不同的含义。
长答案:这取决于您的定义(但是对于大多数定义,“否”仍然是正确的答案)。
像V8这样的虚拟机中的“字节码”指的是用作解释器输入的表示形式。您链接到的文章提供了很好的描述。
“中间表示”或IR通常是指编译器内部使用的数据,作为其输入(通常是AST =抽象语法树,即源文本的解析版本)与其输入之间的中间步骤(因此称为名称)输出(通常是机器码或字节码,但可以是任何东西,例如在源到源编译器中)。
因此在传统设置中,您可以:
源-(解析器)-> AST-(编译器前端)->红外-(编译器后端)->机器代码
其中,IR通常会在编译器对其进行各种优化之前进行多次修改,然后才最终从中生成机器代码。也可能有几个不同的IR;例如,例如V8较早的优化编译器(“ Crankshaft”)有两个:高级IR“ Hydrogen”和低级IR“ Lithium”,而V8当前的优化编译器(“ Turbofan”)甚至具有三个:“ JavaScript级节点” ,“简化节点”和“机器级节点”。
现在,如果您希望以不同的方式在系统的白板图中绘制方框,则可以不用源于“解析器”和“编译器”,而可以将源代码和机器代码之间的所有内容视为一个大的“编译器”。 (第一步是解析源代码)。在这种情况下,AST将是中间表示形式。但是,如上所述,通常当人们使用IR时,它们的意思是“编译器IR”,而不是AST。
在像V8这样的虚拟机中,整个执行管道比上面描述的要复杂。它始于:
source-(parser)-> AST-(bytecode generator)->字节码
此字节码主要用作V8解释器的输入。 作为一种优化,当V8决定通过优化编译器运行函数时,它不会从源代码和解析器重新开始,而是优化编译器使用字节码作为其输入。以图表形式:
字节码-(解释器)->程序执行
字节码-(编译器前端)-> IR-(编译器后端)->机器代码-(CPU)->程序执行
现在这是您的观点所在的部分:由于V8中的字节码不仅用作解释器的输入,而且还作为优化编译器的输入,从这个意义上讲,这是一步在从源文本到机器代码的过程中,如果您想将其称为一种特殊形式的中间表示形式,那么从技术上讲您不会错。但是这将是一个不寻常的定义。当编译器理论教科书谈论“中间表示”时,它并不意味着“字节码”。