v8 - 在 V8 源代码中,BinaryOperation 的自动转换发生在哪里?
问题描述
我又一次在美好的旧时光里跌跌撞撞'12' + 2 = '122'
我想深入了解这里发生了什么,所以我的第一篇论文是
也许 Javascript 将正确的操作数转换为第一个类型,然后进行操作,如下所示:
'12' + String(2) = '122'
一切都很好......
但是不,因为12 + '2' = '122'
也是;因此,引擎的魔力显然有利于 concat 而不是强制转换为数字。
我的第二篇论文是那时
也许引擎会枚举所有操作数并寻找类似于 C# 的“操作员覆盖”?然后喜欢执行它而不是做自我魔术的事情?
当我意识到它也'5' * '8' = 40
将两个操作数都转换为 Number 并执行操作时,我的困惑变得更加奇怪。我可能真正理解的唯一方法是直接从 GitHub 读取 V8 代码
我能找到的最远的地方是v8/src/parsing/parser-base.h
第 2865 行
// We have a "normal" binary operation.
x = factory()->NewBinaryOperation(op, x, y, pos);
if (op == Token::OR || op == Token::AND) {
impl()->RecordBinaryOperationSourceRange(x, right_range);
}
从这里我迷路了,因为我找不到这factory()
是从哪里来的。
长话短说,V8 引擎源代码中的 JavaScript“类型 Magic”从何而来?
解决方案
V8 开发人员在这里。
V8 中有多种加法和其他操作的快速路径。如果你想研究一个规范的(缓慢但完整的)版本,你可以在 src/objects.cc 中查找 Object::Add。
也就是说,这里的事实来源不是任何给定引擎的实现,而是 JavaScript 规范。操作员应该做什么在+
这里定义:https ://tc39.github.io/ecma262/#sec-addition-operator-plus 。任何引擎的实现要么精确地做到这一点,要么从外部无法区分 - 否则它就是一个错误。Object::Add
读取的实现几乎与规范完全相同并非巧合;-)
推荐阅读
- bash - 尽管 set -e 和/或陷阱处于活动状态,但未捕获 Bash 退出状态
- javascript - 由于某种原因,硒导出的脚本以 .text 格式而不是 .js 格式保存
- python - Python 3.7 - 在文件夹中所有 .txt 文件的每一行的开头插入文件名
- reactjs - 切片函数应用于未定义
- groovy - 从 Groovy 中的数组中选择(非)偶数索引上的元素
- vba - 如何在 Outlook 中自动将电子邮件视图从文本更改为 html
- python - 在 python 数据框中查找替换两个索引之间的值
- css - 关键帧动画在 ipad Safari 和 chrome 中都很生涩。如何在 Safari 中平滑动画?
- networking - 如何在 homestead.yaml 中修复 ip homestead
- google-cloud-platform - 即使在 Google Cloud VM 中添加防火墙规则后端口也不会暴露