没办法了,开坑吧,接下来的几篇会讲述JavaScript字符串源码在v8中转换成AST(抽象语法树)的过程。html
JS代码在V8的解析只有简单的几步,其中第一步就是将源字符串转换为抽象语法树,很是相似于vue中将html转换为VNODE的过程。该过程涉及的类并很少,均位于/src/parsing文件夹中,包括parsing、parser、scanner、token等等,先简单介绍一下各种的做用。vue
这些全部的类经过互相合做,最后产出一个类型为FunctionLiteral的结果,将其传入asm模块,生成底层代码。spa
类型的继承关系树以下。code
其实发现这个过程仍是挺痛苦的,由于从Compile一路看下来,发现直接就进了asm变成了汇编语言,能够说一切来的那么忽然,我根本找不到突破点。固然,若是去掉一些无关的配置和CHECK,能够找到编译核心属性,好比说最后的AsmJs部分是这样调用的。htm
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。blog
而这个literal是parse_info的一个属性,初始化时是NULL,在compile的某一步必定进行处理了,因而回头去翻了一遍整个编译过程。继承
最后终于在CompileTopLevel找到了关键的一行代码。token
if (parse_info->literal() == nullptr && !parsing::ParseProgram(parse_info, isolate)) { return MaybeHandle<SharedFunctionInfo>(); }
而这里,就是解析源代码成抽象语法树的地方,后面会从这里入手,边看边写吧。ip