【发布时间】:2020-07-07 15:19:13
【问题描述】:
我试图了解 v8 是如何工作的,但我无法找到它实际上在代码中的哪个位置获取输入的原始 js 脚本来解析它并将其编译成 c++。
我看过 api.cc 并尝试在编译器函数中设置断点,但没有运气(我使用 chromium 这样做),它永远不会命中这个函数。
MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context,
Source* source,
CompileOptions options,
NoCacheReason no_cache_reason)
***** 更新 ****
@jmrk 回复后,我一直在试图弄清楚 JS 究竟从哪里开始,我真正感兴趣的是了解网站如何呈现,然后将脚本传递到 V8 进行编译。 我找到了很多关于该主题的信息,但我仍然无法理解整个画面:
原来第一步不是解析器而是扫描器,它获取一个 UTF-16 流作为输入。
源代码首先被分解成块;每个块可能是 与不同的编码相关联。一个流然后统一所有的块 UTF-16编码下。
在解析之前,扫描器将 UTF-16 流分解为 令牌。标记是具有语义的脚本的最小单元 意义。有几种类型的标记,包括空格 (用于自动分号插入)、标识符、关键字和 代理对(仅当该对为 不被识别为其他任何东西)。然后将这些令牌首先馈送到 预解析器,然后到解析器。
https://blog.logrocket.com/how-javascript-works-optimizing-for-parsing-efficiency/
我还发现它确实从 Blink 获得了这个流:
UTF16CharacterStream 提供了一个(可能是缓冲的)UTF-16 视图,以覆盖 V8 从 Chrome 接收到的底层 Latin1、UTF-8 或 UTF-16 编码,而 Chrome 又从网络接收到这些编码。除了支持多种编码之外,扫描器和字符流之间的分离允许 V8 透明地扫描,就好像整个源都可用一样,即使到目前为止我们可能只通过网络收到了一部分数据。
扫描器似乎也将令牌提供给解析器:
V8 的解析器使用“扫描器”提供的“令牌”。代币是 具有单一语义含义的一个或多个字符块: 一个字符串、一个标识符、一个像 ++ 这样的运算符。扫描仪构造 这些标记通过组合底层的连续字符 字符流。
但问题仍然存在,从 Blink 进入 V8 的 Javascript 原始代码在哪里? 如何查看 chrome 读取的内容以及它在哪里初始化 v8?
【问题讨论】:
标签: javascript chromium v8 blink embedded-v8