asm.js如何处理除以零
How does asm.js handle divide-by-zero?
在javascript中,用"integer"参数除以零的行为就像浮点应该:
1/0; // Infinity
-1/0; // -Infinity
0/0; // NaN
asm.js规范规定,带整数参数的除法返回intish
,必须立即将其强制为有符号或无符号。如果我们在javascript中这样做,那么在coersion:之后,用"integer"参数除以零总是返回零
(1/0)|0; // == 0, signed case.
(1/0) >> 0; // == 0, unsigned case.
然而,在Java和C等具有实际整数类型的语言中,将整数除以零是一个错误,执行会以某种方式暂停(例如,抛出异常、触发陷阱等)。
这似乎也违反了asm.js指定的类型签名。Infinity
和NaN
的类型是double
,/
的类型应该是(根据规范):
(签名,签名)→intish∧(无符号,无符号)→intish∧(双?,双?)→双∧(浮动?,浮动?)→漂浮
然而,如果其中任何一个分母为零,则结果为double
,因此该类型似乎只能是:
(双?,双?)→双
asm.js代码中预期会发生什么?它是遵循javascript并返回0,还是除以零会产生运行时错误?如果它遵循javascript,为什么输入错误是可以的?如果它产生了运行时错误,为什么规范中没有提到它?
asm.js是JavaScript的一个子集,因此它必须返回JavaScript的作用:Infinity|0
→0
。
您指出Infinity
是double
,但这混淆了asm.js类型的系统和C类型的系统(在JavaScript中,这些系统是number
):当中间结果不是"正确"类型时,asm.jss使用JavaScript类型强制使其成为"正确"的类型。当JavaScript中的一个小整数溢出到double
时,也会发生同样的事情:它会使用逐位操作被强制返回到整数中。
这里的关键是,它给编译器一个提示,它不需要计算JavaScript通常让它计算的所有东西:小整数是否溢出并不重要,因为它被强制返回为整数,所以编译器可以省略溢出检查并发出直线整数运算。请注意,对于每一个可能的值,它仍然必须正确运行!类型系统基本上提示编译器进行一系列强度降低。
现在回到整数除法:在x86上,这会导致浮点异常(是的!整数除法会导致SIGFPE
!)。编译器知道输出是一个整数,所以它可以进行整数除法,但如果分母为零,它不能停止程序。这里有两个选项:
- 如果输入为零,则在除法周围分支,并直接返回零
- 使用提供的输入进行除法运算,但在程序开始时安装一个信号处理程序,捕获
SIGFPE
。当它出现错误时,会查找代码位置,如果编译器的元数据显示这是除法位置,则将返回值修改为零并继续执行
前者是V8和OdinMonkey实现的。
在ARM上,整数除法指令被定义为始终返回零,除非ARM的ARMv7-R配置文件发生故障(故障是未定义的指令,或者如果SCTRL.DZ == 0
,可以更改为返回零)。ARM最近才添加了带有ARMv7VE扩展(虚拟化扩展)的UDIV
和SDIV
指令,并使其在ARMv7-A处理器中成为可选指令(大多数手机和平板电脑都使用这些指令)。您可以使用/proc/cpuinfo
检查指令,但请注意,有些内核不知道该指令!一种解决方法是在进程开始时通过执行指令并使用sigsetjmp
/siglongjmp
捕获未处理的情况来检查指令。这还有一个进一步的警告,即还要捕捉内核"有用"的情况,并在不支持它的处理器上模拟UDIV
/IDIV
!如果指令不存在,则必须使用C库的整数除法指令(libgcc
或compiler_rt
包含__udivmoddi4
等函数)。请注意,此函数在除以零时的行为可能因实现方式而异,并且必须使用零分母上的分支进行处理或在加载时进行检查(与上面针对UDIV
/SDIV
概述的相同)。
我将给您一个问题:当执行以下C代码:INT_MIN/-1
时,asm.js中会发生什么?
- 可以't让我的if语句处理js中的html表单输入
- 在 Node.js 中处理.js和.css
- 当我们使用基于标记的DOM就绪执行时,如何处理js函数
- PHP无法处理js表单
- 正在处理.js - 当鼠标离开画布时继续交互
- JavaScript 函数中的 JQuery 函数 :: 处理.js.
- 从画布动态“卸载”处理 JS 草图
- 处理.js:p.keyRelease不是一个函数/模拟keyRelease
- 裁剪图像处理.js
- 在处理 JS 中导入
- 处理 js - 关卡滚动
- 处理.js计时器
- 在 3D 场景中处理.js对象选择
- 处理 JS 和代码隐藏中的字符串中的单引号
- 什么是对列表重新排序进行动画处理.js反应友好方式
- 在处理.js中,如何声明对象类型和对象数组
- 如何处理JS错误
- Rails+Ajax:如何在点击一个元素后处理JS代码
- "超过了最大调用堆栈大小“;在处理JS时实现Fractal工厂时出错
- 存储/导入变量&函数处理(JS)