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

时间:2013-09-08 16:54:49

标签: 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

代码:

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;

2 个答案:

答案 0 :(得分:9)

这里有specification的几个不同部分。让我们从错误中向后工作。

错误说明: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);
    }
    ...

如果我们查找type semantics of the operator <,我们会看到下表:

(signed, signed) → int ∧
(unsigned, unsigned) → int ∧
(double, double) → int

这清楚地反映了错误信息的措辞; <运算符仅对有符号,无符号或双精度类型之间的比较有效。 “但为什么?”,你问?

description of the int type可能会给我们一个提示。这是一段摘录:

  

int类型是签名性所在的32位整数的类型   不知道。在asm.js中,变量的类型永远不会已知   符号类型。 [...]然而,这种表现形成了一个   有符号和无符号数字之间的重叠会导致歧义   确定他们代表哪个JavaScript编号。例如,   位模式0xffffffff可以表示4294967295或-1,具体取决于   在签名上。因此,int类型的值是   不允许转义为外部(非asm.js)JavaScript代码。

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

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

由于你在函数内部声明了变量,我们必须引用the following part of the spec

  

变量声明的类型由它们决定   初始化。变量初始值设定项可以是浮点字面值,   这是源代码中带有字符。的任何数字文字   类型。或者,初始化器可以是整数   在[-231,232] 范围内的字面值,其类型为 int

我们走了。由于您将变量初始化为var a=0, b=0;,因此对应于规范的后半部分,从而解析为int类型。


所以我们如何解决此问题?好吧,我们需要对<运算符支持的类型转换。 |运算符可以使用两个intish表达式,并返回signed,这样就足够了。

    if ((a|0) < (b|0)) {
        log(0.0);
    } else {
    ...

注意: The type diagram以及operator type rules在尝试调试类似问题时非常有用。

答案 1 :(得分:3)

正如错误消息所解释的,比较的参数必须是签名的,无符号的或双打的;这是RelationalExpression validationoperator table

所必需的

但是,您的ab变量已分配NumericLiterals,仅验证为fixnumint类型,编译器不知道它们是否为if ( a>>>0 < b>>>0 ) 是否签名。

因此,您需要使用显式表达式来告诉它,以验证它们的类型是否为无符号

if ( a|0 < b|0 ) // any of &, ^, <<, >> or ~~ should work

或签名

{{1}}