深入V8引擎-AST(4)
(再声明一下,为了简单暴力的讲解AST的转换过程,这里的编译内容以"'Hello' + ' World'"作为案例)
上一篇基本上花了一整篇讲完了scanner的Init方法,接下来就是Scan了,Init的方法基本上都是在Stream类下操作,但是本节回到了scanner层级。
/**
* Scan
* 仅仅只涉及next_指针
*/
void Scanner::Scan() { Scan(next_); }
void Scanner::Scan(TokenDesc* next_desc) {
next_desc->token = ScanSingleToken();
/**
* 设置当前词法的结束位置
*/
next_desc->location.end_pos = source_pos();
}
虽然这里只有简简单单的两步(砍掉了所有的CHECK和DEBUG内容),但这个ScanSingleToken已经够讲了。从字面意思理解,就是对单个词法的解析,源码如下。
/**
* 这个ScanSingleToken方法可TM太长了
*/
V8_INLINE Token::Value Scanner::ScanSingleToken() {
Token::Value token;
do {
/**
* 设置当前词法的起始位置
*/
next().location.beg_pos = source_pos();
/**
* Ascii码是从0 ~ 127
* 简单的判断一下合法性
*/
if (V8_LIKELY(static_cast<unsigned>(c0_) <= kMaxAscii)) {
/**
* 这是一个mapping数组
* 对所有的Unicode => Ascii做了映射
*/
token = one_char_tokens[c0_];
/**
* 包含非常多的case...先不展开了
* 根据Token类型进行不同的处理
*/
switch (token) {
case Token::LPAREN:
case Token::RPAREN:
// 其他单符号...
// One character tokens.
return Select(token);
case Token::STRING:
return ScanString(); // 更多...
default:
UNREACHABLE();
}
}
/**
* 处理结束符、空格、异常符号等特殊情况
*/
// ...
} while (token == Token::WHITESPACE); return token;
}
作为一个词法解析方法,长度其实还是可以接受的,已经删掉了大部分的case判断,由于本系列专注于"'Hello' + ' World'"的编译,所以留下了STRING类型。
讲两个点,第一个是那个source_pos,位置的属性和方法是真的多,比较简单,看看就行了。
/**
* 上一篇解析了第一个字符 所以pos移动到了1
* 然而记录location需要从头开始 所以这里做了一个偏移
*/
static const int kCharacterLookaheadBufferSize = ;
int source_pos() {
return static_cast<int>(source_->pos()) - kCharacterLookaheadBufferSize;
}
然后那个mapping数组可以稍微给一下出处,源码如下。
/**
* 总结起来就是GetOneCharToken(0),GetOneCharToken(1),...,GetOneCharToken(127)全部调用一遍
* 其中IsDecimalDigit负责判断是否是数字
* 而IsAsciiIdentifier负责判断是否是标识符,例如$、_、a-z等等
* 最后生成的one_char_tokens数组下标代表Unicode编码 值代表对应的Token类型
*/ #define INT_0_TO_127_LIST(V) \
V() V() V() V() V() V() V() V() V() V() \
// ...
V() V() V() V() V() V() V() V() static const constexpr Token::Value one_char_tokens[] = {
#define CALL_GET_SCAN_FLAGS(N) GetOneCharToken(N),
INT_0_TO_127_LIST(CALL_GET_SCAN_FLAGS)
#undef CALL_GET_SCAN_FLAGS
}; constexpr Token::Value GetOneCharToken(char c) {
// clang-format off
return
c == '(' ? Token::LPAREN :
c == ')' ? Token::RPAREN :
// 其余字符...
IsDecimalDigit(c) ? Token::NUMBER :
IsAsciiIdentifier(c) ? Token::IDENTIFIER :
Token::ILLEGAL;
}
之前说过,c0_代表的是当前解析字符的Unicode编码,于是这里直接通过数组索引查找其对应的类型,按照例子中,我们的字符是一个单引号,而单引号的类型如下。
/**
* 单双引号均会被识别为字符串标记
* 而es6的模板字符串比较特殊 暂时不搞他
*/
c == '"' ? Token::STRING :
c == '\'' ? Token::STRING :
c == '`' ? Token::TEMPLATE_SPAN :
所以,当前token被赋值为Token::STRING,因此,case分支进入ScanString的方法。这个方法内容比较多,下一篇讲吧,午休时间。
深入V8引擎-AST(4)的更多相关文章
- 深入V8引擎-AST(1)
没办法了,开坑吧,接下来的几篇会讲述JavaScript字符串源码在v8中转换成AST(抽象语法树)的过程. JS代码在V8的解析只有简单的几步,其中第一步就是将源字符串转换为抽象语法树,非常类似于v ...
- 深入V8引擎-AST(3)
上篇简单介绍了入口方法的流程以及scanner类相关的部分内容,这一篇主要讲scanner的初始化,即 scanner_.Initialize(); 注意,这不是调用静态方法.实际上Parser实例生 ...
- 深入V8引擎-AST(6)
花了5篇才把一个字符串词法给解析完,不知道要多久才能刷完整个流程,GC.复杂数据类型的V8实现那些估计又是几十篇,天呐,真是给自己挖了个大坑. 前面几篇实际上只是执行了scanner.Initiali ...
- 深入V8引擎-AST(2)
先声明一下,这种长系列的大块头博客只能保证尽可能的深入到每一行源码,有些代码我不乐意深究就写个注释说明一下作用.另外,由于本地整理的比较好,博客就随心写了. 整个Compile过程目前只看到asmjs ...
- 深入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),更是爆发了极强的生命力.编程语言分为编译型语言和解释型语言两类,编译型语言在执行之前要先进 ...
随机推荐
- OpenCV图像修复
在OpenCV的"photo.hpp"中定义了一个inpaint函数,可以用来实现图像的修复和复原功能,inpaint函数的原型如下: void inpaint( InputArr ...
- 写一个去除AI2XAML注释及多余数字位数的WPF窗体程序
原文:写一个去除AI2XAML注释及多余数字位数的WPF窗体程序 使用正则表达式去除多余注释及冗余数字位,关键代码: string pattern = @"/b(/d+ ...
- silverlight,WPF动画终极攻略之番外 3D切换导航篇(Blend 4开发)
原文:silverlight,WPF动画终极攻略之番外 3D切换导航篇(Blend 4开发) 这篇介绍的是3D导航,点击图标,页面360°翻转的效果!有什么不足的欢迎大家指出来. 1.新建一个user ...
- WPF4文字模糊不清晰、边框线条粗细不一致的解决方法
原文:WPF4文字模糊不清晰.边框线条粗细不一致的解决方法 软件测试过程中发现在一台1600*900的分辨率电脑上文字模糊,甚至某些个文字出现压缩扭曲 经过实践,发现按下面方法能解决一点问题: 在窗口 ...
- WPF“天狗食月”效果
原文:WPF"天狗食月"效果 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/yangyisen0713/article/deta ...
- css 浏览器兼容性问题解决
一个.!important (功能有限) 随着IE7正确!important支持, !important 方法现在只IE6兼容.(注意措辞.我记得这句话需要推进的位置.) : #example ...
- boost库交叉编译(Linux生成ARM的库)
1. 环境: Linux系统:Ubuntu 14.04 编译工具:arm-fsl-linux-gnueabi-gcc 2.下载boost源码: 地址:https://sourceforge.net/p ...
- halcon基础数据类型
halcon基础数据类型 使用变量不需定义 等号 := 不等号 # 字符串赋值 str:='sdff' 等于比较符 if(q=0) 与 if(a< ...
- jQuery省市联动
<!DOCTYPE html><html lang="en" xmlns="http://www.w3.org/1999/xhtml"> ...
- API Hook基本原理和实现
API Hook基本原理和实现 2009-03-14 20:09 windows系统下的编程,消息message的传递是贯穿其始终的.这个消息我们可以简单理解为一个有特定意义的整数,正如我们看过的老故 ...