jjzjj

javascript - asm.js 如何处理被零除?

coder 2024-12-26 原文

在 javascript 中,用“整数”参数除以零就像 float 一样:

 1/0;    // Infinity
-1/0;    // -Infinity
 0/0;    // NaN

asm.js 规范说整数参数除法返回 intish,必须立即将其强制转换为有符号或无符号。如果我们在 javascript 中这样做,用“整数”参数除以零总是在强制转换后返回零:

(1/0)|0;    // == 0, signed case.
(1/0) >> 0; // == 0, unsigned case.

但是,在具有实际整数类型的语言(如 Java 和 C)中,将整数除以零是错误的,并且执行会以某种方式停止(例如,抛出异常、触发陷阱等)。

这似乎也违反了 asm.js 指定的类型签名。 InfinityNaN 的类型是 double/ 的类型应该是(来自规范):

(signed, signed) → intish ∧ (unsigned, unsigned) → intish ∧ (double?, double?) → double ∧ (float?, float?) → floatish

但是,如果其中任何一个的分母为零,则结果为 double,因此类型似乎只能是:

(double?, double?) → double

asm.js 代码中预期会发生什么?它是遵循 javascript 并返回 0 还是除以零会产生运行时错误?如果它遵循javascript,为什么输入错误就可以了?如果它产生运行时错误,为什么规范没有提到它?

最佳答案

asm.js 是 JavaScript 的一个子集,因此它必须返回 JavaScript 所做的事情:Infinity|00

您指出 Infinitydouble,但这混淆了 asm.js 类型系统和 C 类型系统(在 JavaScript 中它们是 number): asm.js 使用 JavaScript 类型强制使中间结果成为“正确的”类型,而实际上它们不是。当 JavaScript 中的一个小整数溢出为 double 时,也会发生同样的事情:它会使用按位运算强制变回整数。

这里的关键是它给编译器一个提示,它不需要计算 JavaScript 通常要它计算的所有东西:一个小整数是否溢出并不重要,因为它被强制转换回一个整数,因此编译器可以省略溢出检查并发出直线整数运算。请注意,对于每个可能的值,它仍然必须正确运行!类型系统基本上提示编译器进行一系列强度缩减。

现在回到整数除法:在 x86 上这会导致浮点异常(是的!整数除法会导致 SIGFPE!)。编译器知道输出是一个整数,因此它可以进行整数除法,但如果分母为零,它就不能停止程序。这里有两个选项:

  • 如果输入为零则围绕除法分支,并直接返回零。
  • 使用提供的输入进行除法,但在程序开始时安装一个信号处理程序,捕获 SIGFPE。当它查找代码位置出错时,如果编译器的元数据表明这是一个除法位置,则将返回值修改为零并继续执行。

前者是 V8 和 OdinMonkey 实现的。

在 ARM 上,整数除法指令被定义为始终返回零,除了 ARM 的 ARMv7-R 配置文件出现故障(故障是未定义的指令,或者如果 SCTRL.DZ == 0 则可以更改为返回零)。 ARM 最近才在 ARMv7VE 扩展(虚拟化扩展)中添加了 UDIVSDIV 指令,并使其在 ARMv7-A 处理器中成为可选(大多数手机和平板电脑都使用这些)。您可以使用 /proc/cpuinfo 检查指令,但请注意,某些内核不知道该指令!解决方法是在进程启动时检查指令,方法是执行指令并使用 sigsetjmp/siglongjmp 捕获未处理的情况。这还有一个进一步的警告,即捕捉内核“有用”并在不支持它的处理器上模拟 UDIV/IDIV 的情况!如果该指令不存在,则您必须使用 C 库的整数除法指令(libgcccompiler_rt 包含诸如 __udivmoddi4 之类的函数)。请注意,此函数在除以零时的行为可能因实现而异,并且必须使用零分母上的分支来处理或在加载时检查(与上面概述的 UDIV/SDIV 相同) )。

我会留下一个问题:当执行以下 C 代码时,asm.js 中会发生什么:INT_MIN/-1

关于javascript - asm.js 如何处理被零除?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29179876/

有关javascript - asm.js 如何处理被零除?的更多相关文章

  1. ruby-on-rails - Enumerator.new 如何处理已通过的 block ? - 2

    我在理解Enumerator.new方法的工作原理时遇到了一些困难。假设文档中的示例:fib=Enumerator.newdo|y|a=b=1loopdoy[1,1,2,3,5,8,13,21,34,55]循环中断条件在哪里,它如何知道循环应该迭代多少次(因为它没有任何明确的中断条件并且看起来像无限循环)? 最佳答案 Enumerator使用Fibers在内部。您的示例等效于:require'fiber'fiber=Fiber.newdoa=b=1loopdoFiber.yieldaa,b=b,a+bendend10.times.m

  2. ruby-on-rails - 如何处理 Grape 中特定操作的过滤器之前? - 2

    我正在我的Rails项目中安装Grape以构建RESTfulAPI。现在一些端点的操作需要身份验证,而另一些则不需要身份验证。例如,我有users端点,看起来像这样:moduleBackendmoduleV1classUsers现在如您所见,除了password/forget之外的所有操作都需要用户登录/验证。创建一个新的端点也没有意义,比如passwords并且只是删除password/forget从逻辑上讲,这个端点应该与用户资源。问题是Grapebefore过滤器没有像except,only这样的选项,我可以在其中说对某些操作应用过滤器。您通常如何干净利落地处理这种情况?

  3. Ruby - 如何处理子类意外覆盖父类(super class)私有(private)字段的问题? - 2

    假设您编写了一个类Sup,我决定将其扩展为SubSup。我不仅需要了解你发布的接口(interface),还需要了解你的私有(private)字段。见证这次失败:classSupdefinitialize@privateField="fromsup"enddefgetXreturn@privateFieldendendclassSub问题是,解决这个问题的正确方法是什么?看起来子类应该能够使用它想要的任何字段而不会弄乱父类(superclass)。编辑:equivalentexampleinJava返回"fromSup",这也是它应该产生的答案。 最佳答案

  4. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  5. ruby-on-rails - Assets 管道损坏 : Not compiling on the fly css and js files - 2

    我开始了一个新的Rails3.2.5项目,Assets管道不再工作了。CSS和Javascript文件不再编译。这是尝试生成Assets时日志的输出:StartedGET"/assets/application.css?body=1"for127.0.0.1at2012-06-1623:59:11-0700Servedasset/application.css-200OK(0ms)[2012-06-1623:59:11]ERRORNoMethodError:undefinedmethod`each'fornil:NilClass/Users/greg/.rbenv/versions/1

  6. ruby-on-rails - Rails - 理解 application.js 和 application.css - 2

    rails新手。只是想了解\assests目录中的这两个文件。例如,application.js文件有如下行://=requirejquery//=requirejquery_ujs//=require_tree.我理解require_tree。只是将所有JS文件添加到当前目录中。根据上下文,我可以看出requirejquery添加了jQuery库。但是它从哪里得到这些jQuery库呢?我没有在我的Assets文件夹中看到任何jquery.js文件——或者直接在我的整个应用程序中没有看到任何jquery.js文件?同样,我正在按照一些说明安装TwitterBootstrap(http:

  7. ruby - 在 Mechanize 中使用 JavaScript 单击链接 - 2

    我有这个:AccountSummary我想单击该链接,但在使用link_to时出现错误。我试过:bot.click(page.link_with(:href=>/menu_home/))bot.click(page.link_with(:class=>'top_level_active'))bot.click(page.link_with(:href=>/AccountSummary/))我得到的错误是:NoMethodError:nil:NilClass的未定义方法“[]” 最佳答案 那是一个javascript链接。Mechan

  8. ruby-on-rails - 我如何处理 View 中的 nils? - 2

    我设置了以下模型:classContact:no_freq?validates_presence_of:freq,:if=>:no_band?protecteddefno_freq?freq.nil?enddefno_band?band.nil?endendclassBand当我在我的新View中输入频率时,如果输入了频率,则不允许指定波段。这在我的其他观点中造成了问题,因为band现在为零。我如何允许不指定band并在我的index和showView中显示为空,然后在editView中允许在以后指定一个。通过执行以下操作,我已经能够让我的索引显示空白:contact.band&&co

  9. node.js - 如何在 Travis CI 上的一个项目中运行 Node.js 和 Ruby 测试 - 2

    我有一个包含多个组件的存储库,其中大部分是用JavaScript(Node.js)编写的,一个是用Ruby(RubyonRails)编写的。我想要一个.travis.yml文件来触发一个运行每个组件的所有测试的构建。根据thisTravisCIGoogleGroupthread,目前还没有官方支持。我的目录结构是这样的:.├──构建服务器├──核心├──扩展├──网络应用├──流浪文件├──package.json├──.travis.yml└──生成文件我希望能够运行特定版本的Ruby(2.2.2)和Node.js(0.12.2)。我已经有了一个make目标,所以maketest在每

  10. javascript - jQuery 的 jquery-1.10.2.min.map 正在触发 404(未找到) - 2

    我看到有关未找到文件min.map的错误消息:GETjQuery'sjquery-1.10.2.min.mapistriggeringa404(NotFound)截图这是从哪里来的? 最佳答案 如果ChromeDevTools报告.map文件的404(可能是jquery-1.10.2.min.map、jquery.min.map或jquery-2.0.3.min.map,但任何事情都可能发生)首先要知道的是,这仅在使用DevTools时才会请求。您的用户不会遇到此404。现在您可以修复此问题或禁用sourcemap功能。修复:获取文

随机推荐