ee498c1c16
If "use asm" is used inside a "function*" or async function, it should bail out. Drive-by: Minor cleanup in {Runtime_InstantiateAsmJs}. R=ecmziegler@chromium.org Bug: chromium:1065852 Change-Id: Ice48126b803a30c4b4ff7b5ae22df85a3f36198a Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2126920 Reviewed-by: Emanuel Ziegler <ecmziegler@chromium.org> Commit-Queue: Clemens Backes <clemensb@chromium.org> Cr-Commit-Position: refs/heads/master@{#66939}
1424 lines
22 KiB
JavaScript
1424 lines
22 KiB
JavaScript
// Copyright 2015 the V8 project authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
// Flags: --validate-asm --allow-natives-syntax
|
|
|
|
var stdlib = this;
|
|
let kMinHeapSize = 4096;
|
|
|
|
function assertValidAsm(func) {
|
|
assertTrue(%IsAsmWasmCode(func), "must be valid asm code");
|
|
}
|
|
|
|
function assertWasm(expected, func, ffi) {
|
|
print("Testing " + func.name + "...");
|
|
assertEquals(
|
|
expected, func(stdlib, ffi, new ArrayBuffer(kMinHeapSize)).caller());
|
|
assertValidAsm(func);
|
|
}
|
|
|
|
function EmptyTest(a, b, c) {
|
|
"use asm";
|
|
function caller() {
|
|
empty();
|
|
return 11;
|
|
}
|
|
function empty() {
|
|
}
|
|
return {caller: caller};
|
|
}
|
|
|
|
assertWasm(11, EmptyTest);
|
|
|
|
function VoidReturnTest(a, b, c) {
|
|
"use asm";
|
|
function caller() {
|
|
empty();
|
|
return 19;
|
|
}
|
|
function empty() {
|
|
var x = 0;
|
|
if (x) return;
|
|
}
|
|
return {caller: caller};
|
|
}
|
|
|
|
assertWasm(19, VoidReturnTest);
|
|
|
|
function IntTest(a, b, c) {
|
|
"use asm";
|
|
function sum(a, b) {
|
|
a = a|0;
|
|
b = b|0;
|
|
var c = 0;
|
|
var d = 3.0;
|
|
var e = 0;
|
|
e = ~~d; // double conversion
|
|
c = (b + 1)|0
|
|
return (a + c + 1)|0;
|
|
}
|
|
|
|
function caller() {
|
|
return sum(77,22) | 0;
|
|
}
|
|
|
|
return {caller: caller};
|
|
}
|
|
|
|
assertWasm(101,IntTest);
|
|
|
|
|
|
function Float64Test() {
|
|
"use asm";
|
|
function sum(a, b) {
|
|
a = +a;
|
|
b = +b;
|
|
return +(a + b);
|
|
}
|
|
|
|
function caller() {
|
|
var a = 0.0;
|
|
var ret = 0;
|
|
a = +sum(70.1,10.2);
|
|
if (a == 80.3) {
|
|
ret = 1|0;
|
|
} else {
|
|
ret = 0|0;
|
|
}
|
|
return ret|0;
|
|
}
|
|
|
|
return {caller: caller};
|
|
}
|
|
|
|
assertWasm(1, Float64Test);
|
|
|
|
|
|
function BadModule() {
|
|
"use asm";
|
|
function caller(a, b) {
|
|
a = a|0;
|
|
b = b+0;
|
|
var c = 0;
|
|
c = (b + 1)|0
|
|
return (a + c + 1)|0;
|
|
}
|
|
|
|
function caller() {
|
|
return call(1, 2)|0;
|
|
}
|
|
|
|
return {caller: caller};
|
|
}
|
|
|
|
assertFalse(%IsAsmWasmCode(BadModule));
|
|
|
|
|
|
function TestReturnInBlock() {
|
|
"use asm";
|
|
|
|
function caller() {
|
|
if(1) {
|
|
{
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
return {caller: caller};
|
|
}
|
|
|
|
assertWasm(1, TestReturnInBlock);
|
|
|
|
|
|
function TestAddSimple() {
|
|
"use asm";
|
|
|
|
function caller() {
|
|
var x = 0;
|
|
x = (x + 1)|0;
|
|
return x|0;
|
|
}
|
|
|
|
return {caller: caller};
|
|
}
|
|
|
|
assertWasm(1, TestAddSimple);
|
|
|
|
|
|
function TestWhileSimple() {
|
|
"use asm";
|
|
|
|
function caller() {
|
|
var x = 0;
|
|
while((x|0) < 5) {
|
|
x = (x + 1)|0;
|
|
}
|
|
return x|0;
|
|
}
|
|
|
|
return {caller: caller};
|
|
}
|
|
|
|
assertWasm(5, TestWhileSimple);
|
|
|
|
|
|
function TestWhileWithoutBraces() {
|
|
"use asm";
|
|
|
|
function caller() {
|
|
var x = 0;
|
|
while((x|0) <= 3)
|
|
x = (x + 1)|0;
|
|
return x|0;
|
|
}
|
|
|
|
return {caller: caller};
|
|
}
|
|
|
|
assertWasm(4, TestWhileWithoutBraces);
|
|
|
|
|
|
function TestReturnInWhile() {
|
|
"use asm";
|
|
|
|
function caller() {
|
|
var x = 0;
|
|
while((x|0) < 10) {
|
|
x = (x + 6)|0;
|
|
return x|0;
|
|
}
|
|
return x|0;
|
|
}
|
|
|
|
return {caller: caller};
|
|
}
|
|
|
|
assertWasm(6, TestReturnInWhile);
|
|
|
|
|
|
function TestReturnInWhileWithoutBraces() {
|
|
"use asm";
|
|
|
|
function caller() {
|
|
var x = 0;
|
|
while((x|0) < 5)
|
|
return 7;
|
|
return x|0;
|
|
}
|
|
|
|
return {caller: caller};
|
|
}
|
|
|
|
assertWasm(7, TestReturnInWhileWithoutBraces);
|
|
|
|
|
|
function TestBreakInIf() {
|
|
"use asm";
|
|
|
|
function caller() {
|
|
label: {
|
|
if(1) break label;
|
|
return 11;
|
|
}
|
|
return 12;
|
|
}
|
|
|
|
return {caller: caller};
|
|
}
|
|
|
|
assertWasm(12, TestBreakInIf);
|
|
|
|
function TestBreakInIfInDoWhileFalse() {
|
|
"use asm";
|
|
|
|
function caller() {
|
|
do {
|
|
if(1) break;
|
|
return 11;
|
|
} while(0);
|
|
return 12;
|
|
}
|
|
|
|
return {caller: caller};
|
|
}
|
|
|
|
assertWasm(12, TestBreakInIfInDoWhileFalse);
|
|
|
|
function TestBreakInElse() {
|
|
"use asm";
|
|
|
|
function caller() {
|
|
do {
|
|
if(0) ;
|
|
else break;
|
|
return 14;
|
|
} while(0);
|
|
return 15;
|
|
}
|
|
|
|
return {caller: caller};
|
|
}
|
|
|
|
assertWasm(15, TestBreakInElse);
|
|
|
|
function TestBreakInWhile() {
|
|
"use asm";
|
|
|
|
function caller() {
|
|
while(1) {
|
|
break;
|
|
}
|
|
return 8;
|
|
}
|
|
|
|
return {caller: caller};
|
|
}
|
|
|
|
assertWasm(8, TestBreakInWhile);
|
|
|
|
|
|
function TestBreakInIfInWhile() {
|
|
"use asm";
|
|
|
|
function caller() {
|
|
while(1) {
|
|
if (1) break;
|
|
else break;
|
|
}
|
|
return 8;
|
|
}
|
|
|
|
return {caller: caller};
|
|
}
|
|
|
|
assertWasm(8, TestBreakInIfInWhile);
|
|
|
|
function TestBreakInNestedWhile() {
|
|
"use asm";
|
|
|
|
function caller() {
|
|
var x = 1.0;
|
|
var ret = 0;
|
|
while(x < 1.5) {
|
|
while(1)
|
|
break;
|
|
x = +(x + 0.25);
|
|
}
|
|
if (x == 1.5) {
|
|
ret = 9;
|
|
}
|
|
return ret|0;
|
|
}
|
|
|
|
return {caller: caller};
|
|
}
|
|
|
|
assertWasm(9, TestBreakInNestedWhile);
|
|
|
|
|
|
function TestBreakInBlock() {
|
|
"use asm";
|
|
|
|
function caller() {
|
|
var x = 0;
|
|
abc: {
|
|
x = 10;
|
|
if ((x|0) == 10) {
|
|
break abc;
|
|
}
|
|
x = 20;
|
|
}
|
|
return x|0;
|
|
}
|
|
|
|
return {caller: caller};
|
|
}
|
|
|
|
assertWasm(10, TestBreakInBlock);
|
|
|
|
|
|
function TestBreakInNamedWhile() {
|
|
"use asm";
|
|
|
|
function caller() {
|
|
var x = 0;
|
|
outer: while (1) {
|
|
x = (x + 1)|0;
|
|
while ((x|0) == 11) {
|
|
break outer;
|
|
}
|
|
}
|
|
return x|0;
|
|
}
|
|
|
|
return {caller: caller};
|
|
}
|
|
|
|
assertWasm(11, TestBreakInNamedWhile);
|
|
|
|
|
|
function TestContinue() {
|
|
"use asm";
|
|
|
|
function caller() {
|
|
var x = 5;
|
|
var ret = 0;
|
|
while ((x|0) >= 0) {
|
|
x = (x - 1)|0;
|
|
if ((x|0) == 2) {
|
|
continue;
|
|
}
|
|
ret = (ret - 1)|0;
|
|
}
|
|
return ret|0;
|
|
}
|
|
|
|
return {caller: caller};
|
|
}
|
|
|
|
assertWasm(-5, TestContinue);
|
|
|
|
|
|
function TestContinueInNamedWhile() {
|
|
"use asm";
|
|
|
|
function caller() {
|
|
var x = 5;
|
|
var y = 0;
|
|
var ret = 0;
|
|
outer: while ((x|0) > 0) {
|
|
x = (x - 1)|0;
|
|
y = 0;
|
|
while ((y|0) < 5) {
|
|
if ((x|0) == 3) {
|
|
continue outer;
|
|
}
|
|
ret = (ret + 1)|0;
|
|
y = (y + 1)|0;
|
|
}
|
|
}
|
|
return ret|0;
|
|
}
|
|
|
|
return {caller: caller};
|
|
}
|
|
|
|
assertWasm(20, TestContinueInNamedWhile);
|
|
|
|
|
|
function TestContinueInDoWhileFalse() {
|
|
"use asm";
|
|
|
|
function caller() {
|
|
do {
|
|
continue;
|
|
} while (0);
|
|
return 47;
|
|
}
|
|
|
|
return {caller: caller};
|
|
}
|
|
|
|
assertWasm(47, TestContinueInDoWhileFalse);
|
|
|
|
|
|
function TestContinueInForLoop() {
|
|
"use asm";
|
|
|
|
function caller() {
|
|
var i = 0;
|
|
for (; (i|0) < 10; i = (i+1)|0) {
|
|
continue;
|
|
}
|
|
return 4711;
|
|
}
|
|
|
|
return {caller: caller};
|
|
}
|
|
|
|
assertWasm(4711, TestContinueInForLoop);
|
|
|
|
|
|
function TestNot() {
|
|
"use asm";
|
|
|
|
function caller() {
|
|
var a = 0;
|
|
a = !(2 > 3);
|
|
return a | 0;
|
|
}
|
|
|
|
return {caller:caller};
|
|
}
|
|
|
|
assertWasm(1, TestNot);
|
|
|
|
|
|
function TestNotEquals() {
|
|
"use asm";
|
|
|
|
function caller() {
|
|
var a = 3;
|
|
if ((a|0) != 2) {
|
|
return 21;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
return {caller:caller};
|
|
}
|
|
|
|
assertWasm(21, TestNotEquals);
|
|
|
|
|
|
function TestUnsignedComparison() {
|
|
"use asm";
|
|
|
|
function caller() {
|
|
var a = 0xffffffff;
|
|
if ((a>>>0) > (0>>>0)) {
|
|
return 22;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
return {caller:caller};
|
|
}
|
|
|
|
assertWasm(22, TestUnsignedComparison);
|
|
|
|
|
|
function TestMixedAdd() {
|
|
"use asm";
|
|
|
|
function caller() {
|
|
var a = 0x80000000;
|
|
var b = 0x7fffffff;
|
|
var c = 0;
|
|
c = ((a>>>0) + b)|0;
|
|
if ((c >>> 0) > (0>>>0)) {
|
|
if ((c|0) < 0) {
|
|
return 23;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
return {caller:caller};
|
|
}
|
|
|
|
assertWasm(23, TestMixedAdd);
|
|
|
|
|
|
|
|
|
|
function TestConvertI32() {
|
|
"use asm";
|
|
|
|
function caller() {
|
|
var a = 1.5;
|
|
if ((~~(a + a)) == 3) {
|
|
return 24;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
return {caller:caller};
|
|
}
|
|
|
|
assertWasm(24, TestConvertI32);
|
|
|
|
|
|
function TestConvertF64FromInt() {
|
|
"use asm";
|
|
|
|
function caller() {
|
|
var a = 1;
|
|
if ((+((a + a)|0)) > 1.5) {
|
|
return 25;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
return {caller:caller};
|
|
}
|
|
|
|
assertWasm(25, TestConvertF64FromInt);
|
|
|
|
|
|
function TestConvertF64FromUnsigned() {
|
|
"use asm";
|
|
|
|
function caller() {
|
|
var a = 0xffffffff;
|
|
if ((+(a>>>0)) > 0.0) {
|
|
if((+(a|0)) < 0.0) {
|
|
return 26;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
return {caller:caller};
|
|
}
|
|
|
|
assertWasm(26, TestConvertF64FromUnsigned);
|
|
|
|
|
|
function TestModInt() {
|
|
"use asm";
|
|
|
|
function caller() {
|
|
var a = -83;
|
|
var b = 28;
|
|
return ((a|0)%(b|0))|0;
|
|
}
|
|
|
|
return {caller:caller};
|
|
}
|
|
|
|
assertWasm(-27,TestModInt);
|
|
|
|
|
|
function TestModUnsignedInt() {
|
|
"use asm";
|
|
|
|
function caller() {
|
|
var a = 0x80000000; //2147483648
|
|
var b = 10;
|
|
return ((a>>>0)%(b>>>0))|0;
|
|
}
|
|
|
|
return {caller:caller};
|
|
}
|
|
|
|
assertWasm(8, TestModUnsignedInt);
|
|
|
|
|
|
function TestModDouble() {
|
|
"use asm";
|
|
|
|
function caller() {
|
|
var a = 5.25;
|
|
var b = 2.5;
|
|
if (a%b == 0.25) {
|
|
return 28;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
return {caller:caller};
|
|
}
|
|
|
|
assertWasm(28, TestModDouble);
|
|
|
|
|
|
function TestModDoubleNegative() {
|
|
"use asm";
|
|
|
|
function caller() {
|
|
var a = -34359738368.25;
|
|
var b = 2.5;
|
|
if (a%b == -0.75) {
|
|
return 28;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
return {caller:caller};
|
|
}
|
|
|
|
assertWasm(28, TestModDoubleNegative);
|
|
|
|
|
|
(function () {
|
|
function TestNamedFunctions() {
|
|
"use asm";
|
|
|
|
var a = 0.0;
|
|
var b = 0.0;
|
|
|
|
function add() {
|
|
return +(a + b);
|
|
}
|
|
|
|
function init() {
|
|
a = 43.25;
|
|
b = 34.25;
|
|
}
|
|
|
|
return {init:init,
|
|
add:add};
|
|
}
|
|
|
|
var module_decl = eval('(' + TestNamedFunctions.toString() + ')');
|
|
var module = module_decl(stdlib);
|
|
assertValidAsm(module_decl);
|
|
module.init();
|
|
assertEquals(77.5, module.add());
|
|
})();
|
|
|
|
|
|
(function () {
|
|
function TestGlobalsWithInit() {
|
|
"use asm";
|
|
|
|
var a = 43.25;
|
|
var b = 34.25;
|
|
|
|
function add() {
|
|
return +(a + b);
|
|
}
|
|
|
|
return {add:add};
|
|
}
|
|
|
|
var module_decl = eval('(' + TestGlobalsWithInit.toString() + ')');
|
|
var module = module_decl(stdlib);
|
|
assertValidAsm(module_decl);
|
|
assertEquals(77.5, module.add());
|
|
})();
|
|
|
|
function TestForLoop() {
|
|
"use asm"
|
|
|
|
function caller() {
|
|
var ret = 0;
|
|
var i = 0;
|
|
for (i = 2; (i|0) <= 10; i = (i+1)|0) {
|
|
ret = (ret + i) | 0;
|
|
}
|
|
return ret|0;
|
|
}
|
|
|
|
return {caller:caller};
|
|
}
|
|
|
|
assertWasm(54, TestForLoop);
|
|
|
|
|
|
function TestForLoopWithoutInit() {
|
|
"use asm"
|
|
|
|
function caller() {
|
|
var ret = 0;
|
|
var i = 0;
|
|
for (; (i|0) < 10; i = (i+1)|0) {
|
|
ret = (ret + 10) | 0;
|
|
}
|
|
return ret|0;
|
|
}
|
|
|
|
return {caller:caller};
|
|
}
|
|
|
|
assertWasm(100,TestForLoopWithoutInit);
|
|
|
|
|
|
function TestForLoopWithoutCondition() {
|
|
"use asm"
|
|
|
|
function caller() {
|
|
var ret = 0;
|
|
var i = 0;
|
|
for (i=1;; i = (i+1)|0) {
|
|
ret = (ret + i) | 0;
|
|
if ((i|0) == 11) {
|
|
break;
|
|
}
|
|
}
|
|
return ret|0;
|
|
}
|
|
|
|
return {caller:caller};
|
|
}
|
|
|
|
assertWasm(66, TestForLoopWithoutCondition);
|
|
|
|
|
|
function TestForLoopWithoutNext() {
|
|
"use asm"
|
|
|
|
function caller() {
|
|
var i = 0;
|
|
for (i=1; (i|0) < 41;) {
|
|
i = (i + 1) | 0;
|
|
}
|
|
return i|0;
|
|
}
|
|
|
|
return {caller:caller};
|
|
}
|
|
|
|
assertWasm(41, TestForLoopWithoutNext);
|
|
|
|
|
|
function TestForLoopWithoutBody() {
|
|
"use asm"
|
|
|
|
function caller() {
|
|
var i = 0;
|
|
for (i=1; (i|0) < 45 ; i = (i+1)|0) {
|
|
}
|
|
return i|0;
|
|
}
|
|
|
|
return {caller:caller};
|
|
}
|
|
|
|
assertWasm(45, TestForLoopWithoutBody);
|
|
|
|
|
|
function TestDoWhile() {
|
|
"use asm"
|
|
|
|
function caller() {
|
|
var i = 0;
|
|
var ret = 21;
|
|
do {
|
|
ret = (ret + ret)|0;
|
|
i = (i + 1)|0;
|
|
} while ((i|0) < 2);
|
|
return ret|0;
|
|
}
|
|
|
|
return {caller:caller};
|
|
}
|
|
|
|
assertWasm(84, TestDoWhile);
|
|
|
|
|
|
function TestConditional() {
|
|
"use asm"
|
|
|
|
function caller() {
|
|
var x = 1;
|
|
return (((x|0) > 0) ? 41 : 71)|0;
|
|
}
|
|
|
|
return {caller:caller};
|
|
}
|
|
|
|
assertWasm(41, TestConditional);
|
|
|
|
|
|
function TestInitFunctionWithNoGlobals() {
|
|
"use asm";
|
|
function caller() {
|
|
return 51;
|
|
}
|
|
return {caller:caller};
|
|
}
|
|
|
|
assertWasm(51, TestInitFunctionWithNoGlobals);
|
|
|
|
|
|
(function () {
|
|
function TestExportNameDifferentFromFunctionName() {
|
|
"use asm";
|
|
function caller() {
|
|
return 55;
|
|
}
|
|
return {alt_caller:caller};
|
|
}
|
|
|
|
var module_decl = eval(
|
|
'(' + TestExportNameDifferentFromFunctionName.toString() + ')');
|
|
var module = module_decl(stdlib);
|
|
assertValidAsm(module_decl);
|
|
assertEquals(55, module.alt_caller());
|
|
})();
|
|
|
|
|
|
function TestFunctionTableSingleFunction() {
|
|
"use asm";
|
|
|
|
function dummy() {
|
|
return 71;
|
|
}
|
|
|
|
function caller() {
|
|
// TODO(jpp): the parser optimizes function_table[0&0] to function table[0].
|
|
var v = 0;
|
|
return function_table[v&0]() | 0;
|
|
}
|
|
|
|
var function_table = [dummy]
|
|
|
|
return {caller:caller};
|
|
}
|
|
|
|
assertWasm(71, TestFunctionTableSingleFunction);
|
|
|
|
|
|
function TestFunctionTableMultipleFunctions() {
|
|
"use asm";
|
|
|
|
function inc1(x) {
|
|
x = x|0;
|
|
return (x+1)|0;
|
|
}
|
|
|
|
function inc2(x) {
|
|
x = x|0;
|
|
return (x+2)|0;
|
|
}
|
|
|
|
function caller() {
|
|
var i = 0, j = 1;
|
|
if ((function_table[i&1](50)|0) == 51) {
|
|
if ((function_table[j&1](60)|0) == 62) {
|
|
return 73;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
var function_table = [inc1, inc2]
|
|
|
|
return {caller:caller};
|
|
}
|
|
|
|
assertWasm(73, TestFunctionTableMultipleFunctions);
|
|
|
|
|
|
(function () {
|
|
function TestFunctionTable(stdlib, foreign, buffer) {
|
|
"use asm";
|
|
|
|
function add(a, b) {
|
|
a = a|0;
|
|
b = b|0;
|
|
return (a+b)|0;
|
|
}
|
|
|
|
function sub(a, b) {
|
|
a = a|0;
|
|
b = b|0;
|
|
return (a-b)|0;
|
|
}
|
|
|
|
function inc(a) {
|
|
a = a|0;
|
|
return (a+1)|0;
|
|
}
|
|
|
|
function caller(table_id, fun_id, arg1, arg2) {
|
|
table_id = table_id|0;
|
|
fun_id = fun_id|0;
|
|
arg1 = arg1|0;
|
|
arg2 = arg2|0;
|
|
if ((table_id|0) == 0) {
|
|
return funBin[fun_id&3](arg1, arg2)|0;
|
|
} else if ((table_id|0) == 1) {
|
|
return fun[fun_id&0](arg1)|0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
var funBin = [add, sub, sub, add];
|
|
var fun = [inc];
|
|
|
|
return {caller:caller};
|
|
}
|
|
|
|
print("TestFunctionTable...");
|
|
var module = TestFunctionTable(stdlib);
|
|
assertEquals(55, module.caller(0, 0, 33, 22));
|
|
assertEquals(11, module.caller(0, 1, 33, 22));
|
|
assertEquals(9, module.caller(0, 2, 54, 45));
|
|
assertEquals(99, module.caller(0, 3, 54, 45));
|
|
assertEquals(23, module.caller(0, 4, 12, 11));
|
|
assertEquals(31, module.caller(1, 0, 30, 11));
|
|
})();
|
|
|
|
|
|
(function TestComma() {
|
|
function CommaModule() {
|
|
"use asm";
|
|
|
|
function ifunc(a, b) {
|
|
a = +a;
|
|
b = b | 0;
|
|
return (a, b) | 0;
|
|
}
|
|
|
|
function dfunc(a, b) {
|
|
a = a | 0;
|
|
b = +b;
|
|
return +(a, b);
|
|
}
|
|
|
|
return {ifunc: ifunc, dfunc: dfunc};
|
|
}
|
|
|
|
var module_decl = eval('(' + CommaModule.toString() + ')');
|
|
var m = module_decl(stdlib);
|
|
assertValidAsm(module_decl);
|
|
assertEquals(123, m.ifunc(456.7, 123));
|
|
assertEquals(123.4, m.dfunc(456, 123.4));
|
|
})();
|
|
|
|
|
|
function TestFloatAsDouble(stdlib) {
|
|
"use asm";
|
|
var fround = stdlib.Math.fround;
|
|
function func() {
|
|
var x = fround(1.0);
|
|
return +fround(x);
|
|
}
|
|
return {caller: func};
|
|
}
|
|
assertWasm(1, TestFloatAsDouble);
|
|
|
|
|
|
function TestOr() {
|
|
"use asm";
|
|
function func() {
|
|
var x = 1;
|
|
var y = 2;
|
|
return (x | y) | 0;
|
|
}
|
|
return {caller: func};
|
|
}
|
|
|
|
assertWasm(3, TestOr);
|
|
|
|
|
|
function TestAnd() {
|
|
"use asm";
|
|
function func() {
|
|
var x = 3;
|
|
var y = 2;
|
|
return (x & y) | 0;
|
|
}
|
|
return {caller: func};
|
|
}
|
|
|
|
assertWasm(2, TestAnd);
|
|
|
|
|
|
function TestXor() {
|
|
"use asm";
|
|
function func() {
|
|
var x = 3;
|
|
var y = 2;
|
|
return (x ^ y) | 0;
|
|
}
|
|
return {caller: func};
|
|
}
|
|
|
|
assertWasm(1, TestXor);
|
|
|
|
|
|
function TestIntegerMultiplyBothWays(stdlib, foreign, heap) {
|
|
"use asm";
|
|
function func() {
|
|
var a = 1;
|
|
return (((a * 3)|0) + ((4 * a)|0)) | 0;
|
|
}
|
|
return {caller: func};
|
|
}
|
|
|
|
assertWasm(7, TestIntegerMultiplyBothWays);
|
|
|
|
|
|
(function TestBadAssignDoubleFromIntish() {
|
|
function Module(stdlib, foreign, heap) {
|
|
"use asm";
|
|
function func() {
|
|
var a = 1;
|
|
var b = 3.0;
|
|
b = a;
|
|
}
|
|
return {func: func};
|
|
}
|
|
print("TestBadAssignDoubleFromIntish...");
|
|
Module(stdlib);
|
|
assertFalse(%IsAsmWasmCode(Module));
|
|
})();
|
|
|
|
|
|
(function TestBadAssignIntFromDouble() {
|
|
function Module(stdlib, foreign, heap) {
|
|
"use asm";
|
|
function func() {
|
|
var a = 1;
|
|
var b = 3.0;
|
|
a = b;
|
|
}
|
|
return {func: func};
|
|
}
|
|
print("TestBadAssignIntFromDouble...");
|
|
Module(stdlib);
|
|
assertFalse(%IsAsmWasmCode(Module));
|
|
})();
|
|
|
|
|
|
(function TestBadMultiplyIntish() {
|
|
function Module(stdlib, foreign, heap) {
|
|
"use asm";
|
|
function func() {
|
|
var a = 1;
|
|
return ((a + a) * 4) | 0;
|
|
}
|
|
return {func: func};
|
|
}
|
|
print("TestBadMultiplyIntish...");
|
|
Module(stdlib);
|
|
assertFalse(%IsAsmWasmCode(Module));
|
|
})();
|
|
|
|
|
|
(function TestBadCastFromInt() {
|
|
function Module(stdlib, foreign, heap) {
|
|
"use asm";
|
|
function func() {
|
|
var a = 1;
|
|
return +a;
|
|
}
|
|
return {func: func};
|
|
}
|
|
print("TestBadCastFromInt...");
|
|
Module(stdlib);
|
|
assertFalse(%IsAsmWasmCode(Module));
|
|
})();
|
|
|
|
|
|
function TestAndNegative() {
|
|
"use asm";
|
|
function func() {
|
|
var x = 1;
|
|
var y = 2;
|
|
var z = 0;
|
|
z = x + y & -1;
|
|
return z | 0;
|
|
}
|
|
return {caller: func};
|
|
}
|
|
|
|
assertWasm(3, TestAndNegative);
|
|
|
|
|
|
function TestNegativeDouble() {
|
|
"use asm";
|
|
function func() {
|
|
var x = -34359738368.25;
|
|
var y = -2.5;
|
|
return +(x + y);
|
|
}
|
|
return {caller: func};
|
|
}
|
|
|
|
assertWasm(-34359738370.75, TestNegativeDouble);
|
|
|
|
|
|
(function TestBadAndDouble() {
|
|
function Module() {
|
|
"use asm";
|
|
function func() {
|
|
var x = 1.0;
|
|
var y = 2.0;
|
|
return (x & y) | 0;
|
|
}
|
|
return {func: func};
|
|
}
|
|
|
|
Module(stdlib);
|
|
assertFalse(%IsAsmWasmCode(Module));
|
|
})();
|
|
|
|
|
|
(function TestBadExportKey() {
|
|
function Module() {
|
|
"use asm";
|
|
function func() {
|
|
}
|
|
return {123: func};
|
|
}
|
|
|
|
Module(stdlib);
|
|
assertFalse(%IsAsmWasmCode(Module));
|
|
})();
|
|
|
|
|
|
/*
|
|
// TODO(bradnelson): Technically invalid, but useful to cover unicode, revises
|
|
// and re-enable.
|
|
(function TestUnicodeExportKey() {
|
|
function Module() {
|
|
"use asm";
|
|
function func() {
|
|
return 42;
|
|
}
|
|
return {"\u00d1\u00e6": func};
|
|
}
|
|
|
|
var m = Module(stdlib);
|
|
assertEquals(42, m.Ñæ());
|
|
assertValidAsm(Module);
|
|
})();
|
|
*/
|
|
|
|
|
|
function TestAndIntAndHeapValue(stdlib, foreign, buffer) {
|
|
"use asm";
|
|
var HEAP32 = new stdlib.Int32Array(buffer);
|
|
function func() {
|
|
var x = 0;
|
|
x = HEAP32[0] & -1;
|
|
return x | 0;
|
|
}
|
|
return {caller: func};
|
|
}
|
|
|
|
assertWasm(0, TestAndIntAndHeapValue);
|
|
|
|
|
|
function TestOutOfBoundsConversion($a,$b,$c){'use asm';
|
|
function aaa() {
|
|
var f = 0.0;
|
|
var a = 0;
|
|
f = 5616315000.000001;
|
|
a = ~~f >>>0;
|
|
return a | 0;
|
|
}
|
|
return { caller : aaa };
|
|
}
|
|
|
|
assertWasm(1321347704, TestOutOfBoundsConversion);
|
|
|
|
|
|
(function TestUnsignedLiterals() {
|
|
function asmModule() {
|
|
"use asm";
|
|
function u0xffffffff() {
|
|
var f = 0xffffffff;
|
|
return +(f >>> 0);
|
|
}
|
|
function u0x80000000() {
|
|
var f = 0x80000000;
|
|
return +(f >>> 0);
|
|
}
|
|
function u0x87654321() {
|
|
var f = 0x87654321;
|
|
return +(f >>> 0);
|
|
}
|
|
return {
|
|
u0xffffffff: u0xffffffff,
|
|
u0x80000000: u0x80000000,
|
|
u0x87654321: u0x87654321,
|
|
};
|
|
}
|
|
var decl = eval('(' + asmModule.toString() + ')');
|
|
var wasm = decl(stdlib);
|
|
assertValidAsm(decl);
|
|
assertEquals(0xffffffff, wasm.u0xffffffff());
|
|
assertEquals(0x80000000, wasm.u0x80000000());
|
|
assertEquals(0x87654321, wasm.u0x87654321());
|
|
})();
|
|
|
|
|
|
function TestIfWithUnsigned() {
|
|
"use asm";
|
|
function main() {
|
|
if (2147483658) { // 2^31 + 10
|
|
return 231;
|
|
}
|
|
return 0;
|
|
}
|
|
return {caller:main};
|
|
}
|
|
|
|
assertWasm(231, TestIfWithUnsigned);
|
|
|
|
|
|
function TestLoopsWithUnsigned() {
|
|
"use asm";
|
|
function main() {
|
|
var val = 1;
|
|
var count = 0;
|
|
for (val = 2147483648; 2147483648;) {
|
|
val = 2147483649;
|
|
break;
|
|
}
|
|
while (val>>>0) {
|
|
val = (val + 1) | 0;
|
|
count = (count + 1)|0;
|
|
if ((count|0) == 9) {
|
|
break;
|
|
}
|
|
}
|
|
count = 0;
|
|
do {
|
|
val = (val + 2) | 0;
|
|
count = (count + 1)|0;
|
|
if ((count|0) == 5) {
|
|
break;
|
|
}
|
|
} while (0xffffffff);
|
|
if ((val>>>0) == 2147483668) {
|
|
return 323;
|
|
}
|
|
return 0;
|
|
}
|
|
return {caller:main};
|
|
}
|
|
|
|
assertWasm(323, TestLoopsWithUnsigned);
|
|
|
|
|
|
function TestSingleFunctionModule() {
|
|
"use asm";
|
|
function add(a, b) {
|
|
a = a | 0;
|
|
b = b | 0;
|
|
return (a + b) | 0;
|
|
}
|
|
return add;
|
|
}
|
|
|
|
assertEquals(7, TestSingleFunctionModule()(3, 4));
|
|
|
|
|
|
function TestNotZero() {
|
|
"use asm";
|
|
function caller() {
|
|
if (!0) {
|
|
return 44;
|
|
} else {
|
|
return 55;
|
|
}
|
|
return 0;
|
|
}
|
|
return {caller: caller};
|
|
}
|
|
|
|
assertWasm(44, TestNotZero);
|
|
|
|
|
|
function TestNotOne() {
|
|
"use asm";
|
|
function caller() {
|
|
if (!1) {
|
|
return 44;
|
|
} else {
|
|
return 55;
|
|
}
|
|
return 0;
|
|
}
|
|
return {caller: caller};
|
|
}
|
|
|
|
assertWasm(55, TestNotOne);
|
|
|
|
|
|
function TestDotfulFloat(stdlib) {
|
|
"use asm";
|
|
var fround = stdlib.Math.fround;
|
|
var foo = fround(55.0);
|
|
function caller() {
|
|
return +foo;
|
|
}
|
|
return {caller: caller};
|
|
}
|
|
|
|
assertWasm(55, TestDotfulFloat);
|
|
|
|
|
|
function TestDotfulLocalFloat(stdlib) {
|
|
"use asm";
|
|
var fround = stdlib.Math.fround;
|
|
function caller() {
|
|
var foo = fround(55.0);
|
|
return +foo;
|
|
}
|
|
return {caller: caller};
|
|
}
|
|
|
|
assertWasm(55, TestDotfulLocalFloat);
|
|
|
|
|
|
function TestDotlessFloat(stdlib) {
|
|
"use asm";
|
|
var fround = stdlib.Math.fround;
|
|
var foo = fround(55);
|
|
function caller() {
|
|
return +foo;
|
|
}
|
|
return {caller: caller};
|
|
}
|
|
|
|
assertWasm(55, TestDotlessFloat);
|
|
|
|
|
|
function TestDotlessLocalFloat(stdlib) {
|
|
"use asm";
|
|
var fround = stdlib.Math.fround;
|
|
function caller() {
|
|
var foo = fround(55);
|
|
return +foo;
|
|
}
|
|
return {caller: caller};
|
|
}
|
|
|
|
assertWasm(55, TestDotlessLocalFloat);
|
|
|
|
|
|
function TestFloatGlobals(stdlib) {
|
|
"use asm";
|
|
var fround = stdlib.Math.fround;
|
|
var foo = fround(1.25);
|
|
function caller() {
|
|
foo = fround(foo + fround(1.0));
|
|
foo = fround(foo + fround(1.0));
|
|
return +foo;
|
|
}
|
|
return {caller: caller};
|
|
}
|
|
|
|
assertWasm(3.25, TestFloatGlobals);
|
|
|
|
|
|
(function TestExportTwice() {
|
|
function asmModule() {
|
|
"use asm";
|
|
function foo() {
|
|
return 42;
|
|
}
|
|
return {bar: foo, baz: foo};
|
|
}
|
|
var m = asmModule();
|
|
assertEquals(42, m.bar());
|
|
assertEquals(42, m.baz());
|
|
})();
|
|
|
|
(function TestGenerator() {
|
|
function* asmModule() {
|
|
"use asm";
|
|
function foo() {
|
|
return 42;
|
|
}
|
|
return {foo: foo};
|
|
}
|
|
asmModule();
|
|
assertFalse(%IsAsmWasmCode(asmModule));
|
|
})();
|
|
|
|
(function TestAsyncFunction() {
|
|
async function asmModule() {
|
|
"use asm";
|
|
function foo() {
|
|
return 42;
|
|
}
|
|
return {foo: foo};
|
|
}
|
|
asmModule();
|
|
assertFalse(%IsAsmWasmCode(asmModule));
|
|
})();
|