没办法了,开坑吧,接下来的几篇会讲述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)的更多相关文章

  1. 深入V8引擎-AST(3)

    上篇简单介绍了入口方法的流程以及scanner类相关的部分内容,这一篇主要讲scanner的初始化,即 scanner_.Initialize(); 注意,这不是调用静态方法.实际上Parser实例生 ...

  2. 深入V8引擎-AST(6)

    花了5篇才把一个字符串词法给解析完,不知道要多久才能刷完整个流程,GC.复杂数据类型的V8实现那些估计又是几十篇,天呐,真是给自己挖了个大坑. 前面几篇实际上只是执行了scanner.Initiali ...

  3. 深入V8引擎-AST(2)

    先声明一下,这种长系列的大块头博客只能保证尽可能的深入到每一行源码,有些代码我不乐意深究就写个注释说明一下作用.另外,由于本地整理的比较好,博客就随心写了. 整个Compile过程目前只看到asmjs ...

  4. 深入V8引擎-AST(4)

    (再声明一下,为了简单暴力的讲解AST的转换过程,这里的编译内容以"'Hello' + ' World'"作为案例) 上一篇基本上花了一整篇讲完了scanner的Init方法,接下 ...

  5. 深入V8引擎-AST(5)

    懒得发首页了,有时候因为贴的代码太多会被下,而且这东西本来也只是对自己学习的记录,阅读体验极差,所以就本地自娱自乐的写着吧! 由于是解析字符串,所以在开始之前介绍一下词法结构体中关于管理字符串类的属性 ...

  6. [翻译] V8引擎的解析

    原文:Parsing in V8 explained 本文档介绍了 V8 引擎是如何解析 JavaScript 源代码的,以及我们将改进它的计划. 动机 我们有个解析器和一个更快的预解析器(~2x), ...

  7. 精读《V8 引擎 Lazy Parsing》

    1. 引言 本周精读的文章是 V8 引擎 Lazy Parsing,看看 V8 引擎为了优化性能,做了怎样的尝试吧! 这篇文章介绍的优化技术叫 preparser,是通过跳过不必要函数编译的方式优化性 ...

  8. Javascript的V8引擎研究

    1.针对上下文的Snapshot技术 什么是上下文(Contexts)?实际是JS应用程序的运行环境,避免应用程序的修改相互影响,例如一个页面js修改内置对象方法toString,不应该影响到另外页面 ...

  9. V8引擎——详解

    前言 JavaScript绝对是最火的编程语言之一,一直具有很大的用户群,随着在服务端的使用(NodeJs),更是爆发了极强的生命力.编程语言分为编译型语言和解释型语言两类,编译型语言在执行之前要先进 ...

随机推荐

  1. 为什么台湾人工智能可能抢输大陆?(XPU时代来临)

    到了 2020 年,每 3 支手机,就会有一支内建有 AI 芯片. 但目前浮出水面的 AI 芯片新创,几乎都是大陆公司. 为什么台湾这回选择缺席? 「我听说 CPU.GPU,没有听过 NPU? 」11 ...

  2. Win7使用初体验

    作者:朱金灿 来源:http://blog.csdn.net/clever101 最近装了个Win7旗舰版.随着年纪渐大,我对软件使用越来越趋于务实,不再追求最新版本,因为我评价一个好软件的标准是适用 ...

  3. Linux(Centos7)下自动启动程序

    1.文件转移 先将要执行的文件转移或复制到路径较短的地方如:/usr/local 主要是为了方便,同时防止误删.2.编写Service文件 $ vim /usr/lib/systemd/system/ ...

  4. 王立平--GC

    Gabage Collection:垃圾回收 是.net中对内存管理的一种功能. 垃圾回收器跟踪并回收托管内存中分配的对象,定期运行垃圾回收以回收分配给没有有效引用的对象的内存. 当使用可用内存不能满 ...

  5. 取消Jquery mobile自动省略的文本

    在使用jquery moblie做移动客户端app时,listview控件下的列表文本不能完全显示,只能显示一行,超过字数jquery mobile会自动用省略号代替.很是纠结啊. 最后在一个岛国网站 ...

  6. java项目采用exe4j打包成exe档

    java项目采用exe4j打包成exe档 前言:我们都知道java是平台无关性.能够打包成jar文件,到不论什么操作系统有jre环境的电脑都能够同意!可是我们打包成exe文件就相当于舍弃了这一大优势, ...

  7. Hibernate4与hibernate3有错误的版本号的主要区别所造成的不一致

    Hibernate版本号修改 Hibernate4的修改较大仅仅有spring3.1以上版本号可以支持,Spring3.1取消了HibernateTemplate,由于Hibernate4的事务管理已 ...

  8. IAA32过程调用保护规则注册

    因为操作系统共享性质,所以,寄存器已成为各种处理或共享资源的处理.然后,该过程发生 当所谓的.假设呼叫者使用内部寄存器值.但这个寄存器的内容,很可能在该呼叫者的执行的过程中改变,用过程执行之前,对该寄 ...

  9. POJ读书笔记2.1 —— 鸡兔笼带

    http://blog.csdn.net/pipisorry/article/details/36433305 问题描写叙述  一个笼子里面关了鸡和兔子(鸡有2仅仅脚.兔子有4仅仅脚.没有例外). 已 ...

  10. C++异常机制的实现方式和开销分析 (大图,编译器会为每个函数增加EHDL结构,组成一个单向链表,非常著名的“内存访问违例”出错对话框就是该机制的一种体现)

    白杨 http://baiy.cn 在我几年前开始写<C++编码规范与指导>一文时,就已经规划着要加入这样一篇讨论 C++ 异常机制的文章了.没想到时隔几年以后才有机会把这个尾巴补完 :- ...