asm.js类型错误:比较的参数必须都是signed,unsigned或double

don*_*aka 11 javascript asm.js

我只是在学习asmjs的基础知识,但我有一个错误.我不知道我错了什么.

TypeError: asm.js type error: arguments to a comparison must both be signed, unsigned or doubles; int and int are given
Run Code Online (Sandbox Code Playgroud)

码:

window.onload = (function(stdlib, foreign) {
    "use asm";

    var log = foreign.log;

    function main() {
        var a=0, b=0;

        a=10;
        b=20;

        if(a<b) {
            log(0.0);
        } else {
            log(1.0);
        }

        return;
    }

    return {main:main};
}(window, {log:console.log})).main;
Run Code Online (Sandbox Code Playgroud)

voi*_*hos 9

这里有一些规范的不同部分.让我们从错误中向后工作.

错误说明:arguments to a comparison must both be signed, unsigned or doubles; int and int are given.因此,问题在于以下代码行:

    ...
    if(a < b) { // <- Here
        log(0.0);
    } else {
        log(1.0);
    }
    ...
Run Code Online (Sandbox Code Playgroud)

如果我们查找运算符<类型语义,我们得到下表:

(signed, signed) ? int ?
(unsigned, unsigned) ? int ?
(double, double) ? int
Run Code Online (Sandbox Code Playgroud)

这清楚地反映了错误信息的措辞; 该<操作仅适用于符号,无符号,或双类型之间的比较."但为什么?",你问?

类型描述int可能会给我们一个提示.这是一段摘录:

int类型是32位整数的类型,其中的签名是未知的.在asm.js中,变量的类型永远不会具有已知的签名.[...]但是,此表示会在有符号和无符号数字之间创建重叠,这会导致确定它们所代表的JavaScript编号的模糊性.例如,位模式0xffffffff可以表示4294967295或-1,具体取决于签名.因此,不允许int类型的值转义为外部(非asm.js)JavaScript代码.

因此,单独进行比较操作时,ASM.js无法知道这两个int值中的哪一个小于另一个,因为它不知道整数的符号.

那么,为什么变量被解析为类型int

既然你要在函数内部声明变量,我们必须参考规范的以下部分:

变量声明的类型由其初始化程序确定.变量初始值设定项可以是浮点文字,它是具有该字符的任何数字文字.在他们的来源,并有类型.或者,初始化器可以是[-231,232]范围内整数文字,其类型为int.

我们走了.因为你正在将变量初始化为var a=0, b=0;,这对应于规范的后半部分,因此解析为一种类型int.


那么我们如何解决这个问题呢?好吧,我们需要一个类型转换为<运营商支持的东西.该|运营商可以采取两种intish表达式,并返回一个signed,这样就足够了.

    if ((a|0) < (b|0)) {
        log(0.0);
    } else {
    ...
Run Code Online (Sandbox Code Playgroud)

注意: 在尝试调试类似问题时,类型图操作符类型规则非常有用.