我只是在学习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;
答案 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 validation和operator table。
所必需的但是,您的a
和b
变量已分配NumericLiterals,仅验证为fixnum
,int
类型,编译器不知道它们是否为if ( a>>>0 < b>>>0 )
是否签名。
因此,您需要使用显式表达式来告诉它,以验证它们的类型是否为无符号
if ( a|0 < b|0 ) // any of &, ^, <<, >> or ~~ should work
或签名
{{1}}