gpt4 book ai didi

spidermonkey - 蜘蛛猴引擎中 JS_CANONICALIZE_NAN 的目的是什么?

转载 作者:行者123 更新时间:2023-12-01 09:35:08 27 4
gpt4 key购买 nike

我想知道 JS_CANONICALIZE_NAN 的目的是什么,是否所有平台都需要它?

最佳答案

这是一个有趣的!因此,SpiderMonkey 在内部使用标记值表示来表示 JavScript 的“无类型值”——这允许 VM 确定诸如“存储在 a 中的变量是一个数字,而存储在 中的值>b 是一个数字,所以运行 a + b 会进行数字加法”。

有许多不同的值标记方案,SpiderMonkey 使用一种称为“NaN 装箱”的方案。这意味着引擎中的所有无类型值都由 64 位值表示,可以是:

  • 双倍,或
  • 一个标记的非 double ,位于 IEEE double 浮点值的“NaN 空间”中。

这里真正的技巧是现代系统通常使用单个位模式来表示 NaN,您可以将其作为 math.h 的 sqrt(-1)log 的结果来观察(0)。但是根据 IEEE 浮点规范,有很多位模式也被视为 NaN。

double 由子字段组成:

{sign: 1, exponent: 11, significand: 52}

NaN 用 1 填充指数字段并在有效数字中放置一个非零值来表示。

如果你运行这样一个小程序来查看你平台的 NaN 值:

#include <stdio.h>
#include <math.h>
#include <limits>

static unsigned long long
DoubleAsULL(double d) {
return *((unsigned long long *) &d);
}

int main() {
double sqrtNaN = sqrt(-1);
printf("%5f 0x%llx\n", sqrtNaN, DoubleAsULL(sqrtNaN));
double logNaN = log(-1);
printf("%5f 0x%llx\n", logNaN, DoubleAsULL(logNaN));
double compilerNaN = NAN;
printf("%5f 0x%llx\n", compilerNaN, DoubleAsULL(compilerNaN));
double compilerSNAN = std::numeric_limits<double>::signaling_NaN();
printf("%5f 0x%llx\n", compilerSNAN, DoubleAsULL(compilerSNAN));
return 0;
}

你会看到这样的输出:

 -nan 0xfff8000000000000 // Canonical qNaNs...
nan 0x7ff8000000000000
nan 0x7ff8000000000000
nan 0x7ff4000000000000 // sNaN (signaling)

请注意,安静 NaN 的唯一区别在于符号位,后面总是 12 位 1,满足上述 NaN 要求。最后一个,信号 NaN,清除第 12 个(is_quiet)NaN 位,并使第 13 个保持上述 NaN 不变。

除此之外,NaN 空间可以自由发挥——11 位来填充指数,确保符号非零,并且你还有很多空间。在 x64 上,我们使用 47 位虚拟地址假设,留给我们 64 - 47 - 11 = 6 位用于注释值类型。在 x86 上,所有对象指针都适合低 32 位。

但是,我们仍然需要确保非规范的 NaN,如果它们通过 js-ctypes 之类的东西潜入,不会产生看起来像标记的非 double 值的东西,因为这可能会导致可利用的行为虚拟机。 (将数字视为对象是非常糟糕的坏消息。)因此,当我们形成 double 时(如在 DOUBLE_TO_JSVAL 中),我们确保将 d != d 的所有 double 规范化为规范的 NaN表格。

更多信息在 bug 584168 .

关于spidermonkey - 蜘蛛猴引擎中 JS_CANONICALIZE_NAN 的目的是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9435338/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com