【问题标题】:Javascript: How to see source code implementation of native functions like toStringJavascript:如何查看 toString 等本机函数的源代码实现
【发布时间】:2016-10-04 06:59:47
【问题描述】:

我希望了解一些 Javascript 函数在底层是如何工作的。例如我想了解 Chrome 的 V8 引擎如何实现一元 (-) 操作或String.prototype.toString() 方法。

如何查看原生的C/C++ 实现?我在这里看到了许多链接到 Chromium 存储库和 V8 存储库的答案,但这些答案都很大,而且对初学者不太友好,而且据我所知,在任何地方都没有任何指南。

我正在寻找这样的东西:

// Pseudo code
function -(arg) {
  return arg * -1
}

显然,我知道我不会发现这个用 Javascript 写的。我只是在寻找类似的详细程度。

我还没有找到简明扼要地说明如何在任何地方找到 Javascript 函数的本机实现的答案。有人能指出我正确的方向吗?

ECMA 规范 here 为一元 - 操作提供以下规范:

一元 - 运算符

一元 - 运算符将其操作数转换为数字类型,然后 否定它。请注意,对 +0 取反产生 -0,对 -0 取反 产生 +0。

产生式 UnaryExpression : - UnaryExpression 被评估为 如下:

expr 成为评估UnaryExpression 的结果。让oldValue成为 ToNumber(GetValue(expr))。如果 oldValue 是 NaN,则返回 NaN。返回 否定oldValue的结果;也就是说,计算一个具有相同的数字 大小但符号相反。

这很有用,但我想了解的是,如何

计算一个大小相同但符号相反的数字

是计算出来的。是number * -1 还是别的什么?还是有多种方式?

【问题讨论】:

  • 我不认为,这涉及乘法,因为符号更改比乘法便宜。所以function -(x) { return -x; }.
  • @NinaScholz 这可能不是乘法,这只是我的猜测。我试图找到它实际上是什么,以了解本机实现
  • 您不会找到比查看 V8 源代码、SpiderMonkey (Mozilla) 或 Chakra (Edge) 更好的东西了 - 或者阅读 ecmascript ecma-262 语言规范以了解这些功能是如何实现的应该可以工作 - 因为毫无疑问 V8、蜘蛛猴和脉轮会做很多不同的事情
  • @JaromandaX 我完全赞成这种方法。但问题是我不是 C 或 C++ 程序员,我不知道从哪里开始。代码库非常大,到目前为止我的搜索还没有证明有用。
  • 这就是困难——你不是 C 或 C++ 程序员,但你想知道 C/C++ 代码是如何工作的……想到两件事……你将如何理解你看到了什么,为什么你需要看看事情是如何运作的?

标签: javascript google-chrome open-source native v8


【解决方案1】:

V8 中没有代码片段或单个运算符的单个实现。 V8 是一个即时编译器,它通过将所有 JavaScript 即时编译为本机代码来执行所有 JavaScript。 V8 支持大约 10 种不同的 CPU 架构,每种架构都有 4 层编译器。这已经使每个运算符有 40 种不同的实现。在其中许多中,编译要经过很长的阶段,将输入转换为实际的机器代码。在每种情况下,确切的转换都取决于编译时可用的类型信息(在以前的运行中收集)。

要了解发生了什么,您需要了解 V8 复杂架构的重要部分,因此几乎不可能在 SO 回复中回答您的问题。如果您只是对语义感兴趣,我建议您查看 EcmaScript 语言定义。

(您引用的 sn-p 只是一个帮助函数,用于在多个阶段之一中为一元运算符转换编译器内部类型信息。)

编辑:您在更新后的问题中引用的 EcmaScript 定义的摘录是正确的地方。请记住,所有 JavaScript 数字都是 IEEE 浮点数。这句话基本上是在说- 只是反转了这样一个数字的符号位。您必须参考 IEEE 754 标准以获取更多详细信息。与 -1.0 相乘是一个复杂得多的运算,但在大多数情况下都会得到相同的结果(可能 NaN 操作数除外)。

【讨论】:

  • 感谢您的回答。这消除了我的一些困惑。我已经用 ECMA 规范更新了这个问题。可以看看吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-10
相关资源
最近更新 更多