深入V8引擎-AST(1)
2019-08-14 10:01:12来源:博客园 阅读 ()
没办法了,开坑吧,接下来的几篇会讲述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>(); }
而这里,就是解析源代码成抽象语法树的地方,后面会从这里入手,边看边写吧。
原文链接:https://www.cnblogs.com/QH-Jimmy/p/11113303.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:哈喽!我申请到博客了!
下一篇:深入V8引擎-AST(2)
- 深入理解JavaScript是如何实现继承的 2020-02-25
- 高性能JavaScript模板引擎实现原理详解 2020-02-15
- javascript错误处理 2019-08-14
- 用JavaScript带你体验V8引擎解析标识符 2019-08-14
- 前端笔记之React(五)Redux深入浅出 2019-08-14
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash