首页 > 解决方案 > 在 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 开发人员在这里。

V8 中有多种加法和其他操作的快速路径。如果你想研究一个规范的(缓慢但完整的)版本,你可以在 src/objects.cc 中查找 Object::Add。

也就是说,这里的事实来源不是任何给定引擎的实现,而是 JavaScript 规范。操作员应该做什么在+这里定义:https ://tc39.github.io/ecma262/#sec-addition-operator-plus 。任何引擎的实现要么精确地做到这一点,要么从外部无法区分 - 否则它就是一个错误。Object::Add读取的实现几乎与规范完全相同并非巧合;-)


推荐阅读