v8学习笔记(五) 编译过程
v8编译过程(parser.cc文件)
1.创建编译环境MakeAST()
解析器AstBuildingParser parser->扫描器Scanner scanner_
扫描器结构: (1)TokenDesc current_
(2)TokenDesc next_
(3)缓冲 source_
2.语法分析(包含词法分析),创建抽象语法树(AST)FunctionLiteral-----(语句,声明,)
MakeAST()->ParseProgram()->ParseSourceElements():
进入while循环,每次解析一个JS语句
While(peek()!=end_token)
{
Statement* stat = ParseStatement(NULL, CHECK_OK);//解析一个语句
if (stat == NULL || stat->IsEmpty()) continue;//函数声明语句不放入FunctionLiteral
……
processor->Add(stat);//放入最外层FunctionLiteral的ZoneList
}
ParseStatement():解析一个语句
(1)根据下一个Token判断语句类型,并进入相应的语句解析函数
switch (peek()) //取下一个Token
{
case Token::LBRACE:
return ParseBlock(labels, ok); //{}Block语句
case Token::CONST:
case Token::VAR:
stmt = ParseVariableStatement(ok); //变量声明语句
break;
case Token::SEMICOLON:
Next();
return factory()->EmptyStatement(); //空语句
case Token::IF:
stmt = ParseIfStatement(labels, ok); //If语句
break;
case Token::DO:
stmt = ParseDoWhileStatement(labels, ok); //Do循环语句
break;
case Token::WHILE:
stmt = ParseWhileStatement(labels, ok); //While循环语句
break;
case Token::FOR:
stmt = ParseForStatement(labels, ok); //For循环语句
break;
case Token::CONTINUE:
stmt = ParseContinueStatement(ok); //Continue语句
break;
case Token::BREAK:
stmt = ParseBreakStatement(labels, ok); //Break语句
break;
case Token::RETURN:
stmt = ParseReturnStatement(ok); //返回语句
break;
case Token::WITH:
stmt = ParseWithStatement(labels, ok); //With语句??
break;
case Token::SWITCH:
stmt = ParseSwitchStatement(labels, ok); //Switch语句
break;
case Token::THROW:
stmt = ParseThrowStatement(ok); //Throw语句
break;
case Token::TRY:
{……} //Try语句
case Token::FUNCTION:
return ParseFunctionDeclaration(ok); //函数声明语句
case Token::NATIVE:
return ParseNativeDeclaration(ok);
case Token::DEBUGGER:
stmt = ParseDebuggerStatement(ok); //Debugger语句
break;
default: stmt = ParseExpressionOrLabelledStatement(labels, ok);//其他语句(表达式/标号)
}
(2)解析语句
首先,调用扫描器Scanner(对JS源码进行词法分析):每次扫描Scan()得到当前Token和下一个Token,把Token描述信息分别放入TokenDesc current_和 TokenDesc next_中,把Token的值放入缓冲source_中.
其次,根据JS的语法语义进行相应(编译时)处理
最后,
-1-一般(非声明)语句:创建Statement对象,放入FunctionLiteral对象中ZoneList<Statement*>.
-2-变量声明语句:创建Declaration对象放入当前抽象语法树FunctionLiteral的Scope的decls_,
再由CallRuntime语句创建ExpressionStatement对象,放入body_ (JS语句 数组)
-3-函数声明语句:根据函数体创建新的抽象语法树FunctionLiteral,放入新创建的
Declaration对象,再放入当前抽象语法树FunctionLiteral的Scope的 decls_.
解析完所有语句后,得到抽象语法树FunctionLiteral。
附:
抽象语法树4种结点:Statement(语句),Expression(表达式),Declaration(声明)和TargetCollector
---------------------------------------------------------------------------------------------------------------------------------
抽象语法树FunctionLiteral结构
1.ZoneList<Statement*> body_ JS语句数组
2.Scope* scope_
(1)ZoneList<Declaration*> decls_ 变量、函数声明数组(Declaration对象数组)
(2)……….
3.……
---------------------------------------------------------------------------------------------------------------------------------
抽象语法树FunctionLiteral结点的继承层次
ZoneObject
| AstNode
| | Statement
| | | BreakableStatement
| | | | Block
| | | | IterationStatement
| | | | | DoWhileStatement
| | | | | WhileStatement
| | | | | ForStatement
| | | | | ForInstatement
| | | | SwitchStatement
| | | ExpressionStatement
| | | ContinueStatement
| | | BreakStatement
| | | ReturnStatement
| | | WithEnterStatement
| | | WithExitStatement
| | | IfStatement
| | | TryStatement
| | | | TryCatchStatement
| | | | TryFinallyStatement
| | | DebuggerStatement
| | | EmptyStatement
| | Expression (会被转化为ExpressionStatement)
| | | ValidLeftHandSideSentinel
| | | Literal
| | | MaterializedLiteral
| | | | ObjectLiteral
| | | | RegExpLiteral
| | | | ArrayLiteral
| | | CatchExtensionObject
| | | VariableProxy
| | | | VariableProxySentinel
| | | Slot
| | | Property
| | | Call
| | | CallNew
| | | CallRuntime
| | | UnaryOperation
| | | BinaryOperation
| | | CountOperation
| | | CompareOperation
| | | Conditional
| | | Assignment
| | | Throw
| | | FunctionLiteral
| | | ShareFunctionInfoLiteral
| | | ThisFunction
| | Declaration
| | TargetCollector
| CaseClause
v8学习笔记(五) 编译过程相关推荐
- v8学习笔记(七) 执行过程
v8执行过程 JS源码经过v8编译后得到Handle<Script>,调用API Script的Run()运行. (1)由API进入v8内部,取到JSFunction对象 ...
- v8学习笔记(六) 汇编过程
v8汇编过程 根据抽象语法树FunctionLiteral创建Code对象(内含机器指令),返回JSFunction对象. MakeCode(): 1.增加返回语句: Rewriter::Proce ...
- python函数是一段具有特定功能的语句组_Python学习笔记(五)函数和代码复用
本文将为您描述Python学习笔记(五)函数和代码复用,具体完成步骤: 函数能提高应用的模块性,和代码的重复利用率.在很多高级语言中,都可以使用函数实现多种功能.在之前的学习中,相信你已经知道Pyth ...
- 吴恩达《机器学习》学习笔记五——逻辑回归
吴恩达<机器学习>学习笔记五--逻辑回归 一. 分类(classification) 1.定义 2.阈值 二. 逻辑(logistic)回归假设函数 1.假设的表达式 2.假设表达式的意义 ...
- 【AngularJs学习笔记五】AngularJS从构建项目开始
为什么80%的码农都做不了架构师?>>> #0 系列目录# AngularJs学习笔记 [AngularJs学习笔记一]Bower解决js的依赖管理 [AngularJs学习笔 ...
- Python学习笔记五:控制语句
Python学习笔记五:控制语句 Pycharm 开发环境的下载安装配置_项目管理 控制语句 Pycharm 开发环境的使用 Pycharm 下载和安装 激活和选择不同UI 风格 创建项目和初始化配置 ...
- 哈工大操作系统学习笔记五——内核级线程实现
哈工大os学习笔记五(内核级线程实现) 文章目录 哈工大os学习笔记五(内核级线程实现) 一. 中断入口.中断出口(前后两段) 1. 从int中断进入内核(中断入口第一段) 2.中断出口(最后一段) ...
- java中预编译是啥意思_JAVA学习笔记预编译
JAVA学习笔记预编译 (2011-07-30 02:36:17) 标签: 杂谈 第顺次运行jsp时jsp将被改换成servlet(第顺次工夫较长,而尔后就会快许多) 搭配好的利用过程能够穿越设置js ...
- Makefile学习笔记06|编译动态链接库
Makefile学习笔记06|编译动态链接库 希望看到这篇文章的朋友能在评论区留下宝贵的建议来让我们共同成长,谢谢. 这里是目录 静态链接与动态链接 链接分为两种:静态链接.动态链接. 静 ...
最新文章
- 看我用汉语编程(汉语Visual Basic编程软件发布)
- p和li之间的应用上的区别
- [OC]数据库的使用--准备工作
- [渝粤教育] 西南科技大学 工程测量 在线考试复习资料
- js字符串slice_JavaScript子字符串示例-JS中的Slice,Substr和Substring方法
- 中山大学计算机类专业分数线,中山大学计算机类专业2016年在广东理科高考录取最低分数线...
- java模型给泛型_【一天一个基础系列】- java之泛型篇
- Kafka : 报错 KafkaController NoSuchElementException : : key not found : [xxx]
- POJ3076 Sudoku
- 关于防止sql注入的几种手段
- linux下mysql5.7以上my.cnf配置文件配置
- libreelec投屏_我的NAS+HTPC折腾之旅 篇八:LibreELEC部署媒体中心服务器emby和jellyfin篇...
- 2021年茶艺师(初级)考试资料及茶艺师(初级)考试技巧
- FPGA仿真--前仿真和后仿真
- [安全论文翻译] Analysis of Location Data Leakage in the Internet Traffic of Android-based Mobile
- 计算机如何进入桌面,电脑如何设置开机直接进入桌面 开机直接进入桌面设置...
- AMD将坚持x86架构,不会投身ARM架构怀抱
- 良心推荐,一款PDF转JPG图片的免费在线工具
- 中国电子实验记录(ELN)系统行业研究报告(2022版)
- msgbox函数和inputbox函数应该注意的几点