深入V8引擎-AST(1)
没办法了,开坑吧,接下来的几篇会讲述JavaScript字符串源码在v8中转换成AST(抽象语法树)的过程。
JS代码在V8的解析只有简单的几步,其中第一步就是将源字符串转换为抽象语法树,非常类似于vue中将html转换为VNODE的过程。该过程涉及的类并不多,均位于/src/parsing文件夹中,包括parsing、parser、scanner、token等等,先简单介绍一下各类的作用。
- Parser => 核心类,掌管了整个转换过程,内部包含scanner、parse-info等私有属性,产出抽象语法树
- Parsing => 这只是命名空间,全称为v8::interval::parsing,提供ParseProgram、ParseFunction、ParseAny作为parse的入口方法
- ParseInfo => 编译信息的描述类,包含大量配置参数与编译后的容器
- Scanner => 负责逐字解析解析源字符串的类,提供比较上层的API,初始化的Initialize方法会初始化所有变量并步进一格
- Scanner-character-streams => 所有源字符串都需要根据类型转换为该类,这个类提供解析的实际操作,诸如Peek(返回当前解析位置项)、Advance(解析过程前进一步)等等
- Token => 包含所有抽象语法树类型的枚举,例如关键词(const、if)、符号((、{)等等
这些所有的类通过互相合作,最后产出一个类型为FunctionLiteral的结果,将其传入asm模块,生成底层代码。
类型的继承关系树如下。
其实发现这个过程还是挺痛苦的,因为从Compile一路看下来,发现直接就进了asm变成了汇编语言,可以说一切来的那么突然,我根本找不到突破点。当然,如果去掉一些无关的配置和CHECK,可以找到编译核心属性,比如说最后的AsmJs部分是这样调用的。
- MaybeHandle<SharedFunctionInfo> GenerateUnoptimizedCodeForToplevel(
- Isolate* isolate, ParseInfo* parse_info, AccountingAllocator* allocator,
- IsCompiledScope* is_compiled_scope) {
- // ...
- std::vector<FunctionLiteral*> functions_to_compile;
- functions_to_compile.push_back(parse_info->literal());
- while (!functions_to_compile.empty()) {
- FunctionLiteral* literal = functions_to_compile.back();
- functions_to_compile.pop_back();
- Handle<SharedFunctionInfo> shared_info =
- Compiler::GetSharedFunctionInfo(literal, script, isolate);
- if (shared_info->is_compiled()) continue;
- if (UseAsmWasm(literal, parse_info->is_asm_wasm_broken())) {
- std::unique_ptr<UnoptimizedCompilationJob> asm_job(
- AsmJs::NewCompilationJob(parse_info, literal, allocator));
- if (asm_job->ExecuteJob() == CompilationJob::SUCCEEDED &&
- FinalizeUnoptimizedCompilationJob(asm_job.get(), shared_info, isolate) == CompilationJob::SUCCEEDED) {
- continue;
- }
- }
- // ...
- }
- // ...
- return top_level;
- }
鬼一样的代码,只看最后返回的话,可以看出所有的调用都涉及那个literal。
而这个literal是parse_info的一个属性,初始化时是NULL,在compile的某一步一定进行处理了,于是回头去翻了一遍整个编译过程。
最后终于在CompileTopLevel找到了关键的一行代码。
- if (parse_info->literal() == nullptr && !parsing::ParseProgram(parse_info, isolate)) {
- return MaybeHandle<SharedFunctionInfo>();
- }
而这里,就是解析源代码成抽象语法树的地方,后面会从这里入手,边看边写吧。
深入V8引擎-AST(1)的更多相关文章
- 深入V8引擎-AST(3)
上篇简单介绍了入口方法的流程以及scanner类相关的部分内容,这一篇主要讲scanner的初始化,即 scanner_.Initialize(); 注意,这不是调用静态方法.实际上Parser实例生 ...
- 深入V8引擎-AST(6)
花了5篇才把一个字符串词法给解析完,不知道要多久才能刷完整个流程,GC.复杂数据类型的V8实现那些估计又是几十篇,天呐,真是给自己挖了个大坑. 前面几篇实际上只是执行了scanner.Initiali ...
- 深入V8引擎-AST(2)
先声明一下,这种长系列的大块头博客只能保证尽可能的深入到每一行源码,有些代码我不乐意深究就写个注释说明一下作用.另外,由于本地整理的比较好,博客就随心写了. 整个Compile过程目前只看到asmjs ...
- 深入V8引擎-AST(4)
(再声明一下,为了简单暴力的讲解AST的转换过程,这里的编译内容以"'Hello' + ' World'"作为案例) 上一篇基本上花了一整篇讲完了scanner的Init方法,接下 ...
- 深入V8引擎-AST(5)
懒得发首页了,有时候因为贴的代码太多会被下,而且这东西本来也只是对自己学习的记录,阅读体验极差,所以就本地自娱自乐的写着吧! 由于是解析字符串,所以在开始之前介绍一下词法结构体中关于管理字符串类的属性 ...
- [翻译] V8引擎的解析
原文:Parsing in V8 explained 本文档介绍了 V8 引擎是如何解析 JavaScript 源代码的,以及我们将改进它的计划. 动机 我们有个解析器和一个更快的预解析器(~2x), ...
- 精读《V8 引擎 Lazy Parsing》
1. 引言 本周精读的文章是 V8 引擎 Lazy Parsing,看看 V8 引擎为了优化性能,做了怎样的尝试吧! 这篇文章介绍的优化技术叫 preparser,是通过跳过不必要函数编译的方式优化性 ...
- Javascript的V8引擎研究
1.针对上下文的Snapshot技术 什么是上下文(Contexts)?实际是JS应用程序的运行环境,避免应用程序的修改相互影响,例如一个页面js修改内置对象方法toString,不应该影响到另外页面 ...
- V8引擎——详解
前言 JavaScript绝对是最火的编程语言之一,一直具有很大的用户群,随着在服务端的使用(NodeJs),更是爆发了极强的生命力.编程语言分为编译型语言和解释型语言两类,编译型语言在执行之前要先进 ...
随机推荐
- 将普通java工程转换成maven工程
在MyEclipse10中将Maven项目转成普通Java项目后,想将Java项目转成Maven项目,结果一下子傻眼了.根本就没有攻略中提到的config标签.仔细一看,喵咪的,人家用的是Eclips ...
- Openstack部署总结:“部署过程Error: Local ip for ovs agent must be set when tunneling is enabled”问题
问题叙述性说明 正在使用RDO当多节点部署测试,因为使用了一些老机器和机器类型的差异(一些HP的PC,有些DELL的PC).以下错误出现: Applying 192.168.40.107_neutro ...
- OpenGL(五) 三维变换之模型视图矩阵
计算机三维图形学中,一个基本的任务是如何描述三维空间中一个物体位置的变化,也就是如何 描述物体的运动.通常情况下,物体位置的变化包含三个基本的变化:平移.旋转和缩放,物体的运动也可以用这三个基本的运动 ...
- WPF(C#)中Bitmap与BitmapImage相互转换
原文:WPF(C#)中Bitmap与BitmapImage相互转换 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/wangshubo1989/art ...
- hdoj 5087 Revenge of LIS II 【第二长单调递增子】
称号:hdoj 5087 Revenge of LIS II 题意:非常easy,给你一个序列,让你求第二长单调递增子序列. 分析:事实上非常easy.不知道比赛的时候为什么那么多了判掉了. 我们用O ...
- matlab 深度学习
0. 超参的定义 超参的定义直接使用结构体: opts.alpha = 1; opts.batchsize = 50; opts.numepoch = 5; 1. Autoencoder Train ...
- 关于禅道提示未安装VC++环境的问题(做个记录)
明明安装了VC++环境,总是提示未安装,这个问题有可能是你的mysql或其他服务开启影响的,关闭服务就可以了! 我这边是这个问题,把mysql和其他一些服务停止就好了.
- WPF 窗体显示最前端
原文:WPF 窗体显示最前端 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/jjx0224/article/details/8782845 如何做一 ...
- Android bluetooth介绍(两): android 蓝牙源架构和uart 至rfcomm过程
关键词:蓝牙blueZ UART HCI_UART H4 HCI L2CAP RFCOMM 版本号:基于android4.2先前版本 bluez内核:linux/linux3.08系统:an ...
- node.js学习笔记之json数据转string
Node.js中的JSON问题 var str = '{"dir":"kunhony","param":"archive&qu ...