v8/test/mjsunit/wasm/asm-wasm.js
bradnelson e42983d147 [wasm] Making compare and conditionals more correct.
Comparisons were allowing asm 'int' values in places
that require strict 'signed' or 'unsigned' but not both.

Fixes crash when these make it to asm-wasm.

BUG=599413
BUG=v8:4203
R=aseemgarg@chromium.org

Review-Url: https://codereview.chromium.org/2106683003
Cr-Commit-Position: refs/heads/master@{#37353}
2016-06-28 23:50:14 +00:00

1545 lines
27 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: --expose-wasm
function assertWasm(expected, func, ffi) {
print("Testing " + func.name + "...");
assertEquals(expected, Wasm.instantiateModuleFromAsm(
func.toString(), ffi).caller());
}
function EmptyTest() {
"use asm";
function caller() {
empty();
return 11;
}
function empty() {
}
return {caller: caller};
}
assertWasm(11, EmptyTest);
function VoidReturnTest() {
"use asm";
function caller() {
empty();
return 19;
}
function empty() {
var x = 0;
if (x) return;
}
return {caller: caller};
}
assertWasm(19, VoidReturnTest);
function IntTest() {
"use asm";
function sum(a, b) {
a = a|0;
b = b|0;
var c = (b + 1)|0
var d = 3.0;
var e = ~~d; // double conversion
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 = +sum(70.1,10.2);
var ret = 0|0;
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 = (b + 1)|0
return (a + c + 1)|0;
}
function caller() {
return call(1, 2)|0;
}
return {caller: caller};
}
assertThrows(function() {
Wasm.instantiateModuleFromAsm(BadModule.toString()).caller();
});
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;
while(x < 1.5) {
while(1)
break;
x = +(x + 0.25);
}
var ret = 0;
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 TestNot() {
"use asm";
function caller() {
var 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 TestInt32HeapAccess(stdlib, foreign, buffer) {
"use asm";
var m = new stdlib.Int32Array(buffer);
function caller() {
var i = 4;
m[0] = (i + 1) | 0;
m[i >> 2] = ((m[0]|0) + 1) | 0;
m[2] = ((m[i >> 2]|0) + 1) | 0;
return m[2] | 0;
}
return {caller: caller};
}
assertWasm(7, TestInt32HeapAccess);
function TestInt32HeapAccessExternal() {
var memory = new ArrayBuffer(1024);
var memory_int32 = new Int32Array(memory);
var module = Wasm.instantiateModuleFromAsm(
TestInt32HeapAccess.toString(), null, memory);
assertEquals(7, module.caller());
assertEquals(7, memory_int32[2]);
}
TestInt32HeapAccessExternal();
function TestHeapAccessIntTypes() {
var types = [
[Int8Array, 'Int8Array', '>> 0'],
[Uint8Array, 'Uint8Array', '>> 0'],
[Int16Array, 'Int16Array', '>> 1'],
[Uint16Array, 'Uint16Array', '>> 1'],
[Int32Array, 'Int32Array', '>> 2'],
[Uint32Array, 'Uint32Array', '>> 2'],
];
for (var i = 0; i < types.length; i++) {
var code = TestInt32HeapAccess.toString();
code = code.replace('Int32Array', types[i][1]);
code = code.replace(/>> 2/g, types[i][2]);
var memory = new ArrayBuffer(1024);
var memory_view = new types[i][0](memory);
var module = Wasm.instantiateModuleFromAsm(code, null, memory);
assertEquals(7, module.caller());
assertEquals(7, memory_view[2]);
assertEquals(7, Wasm.instantiateModuleFromAsm(code).caller());
}
}
TestHeapAccessIntTypes();
function TestFloatHeapAccess(stdlib, foreign, buffer) {
"use asm";
var f32 = new stdlib.Float32Array(buffer);
var f64 = new stdlib.Float64Array(buffer);
var fround = stdlib.Math.fround;
function caller() {
var i = 8;
var j = 8;
var v = 6.0;
f64[2] = v + 1.0;
f64[i >> 3] = +f64[2] + 1.0;
f64[j >> 3] = +f64[j >> 3] + 1.0;
i = +f64[i >> 3] == 9.0;
return i|0;
}
return {caller: caller};
}
assertEquals(1, Wasm.instantiateModuleFromAsm(
TestFloatHeapAccess.toString()).caller());
function TestFloatHeapAccessExternal() {
var memory = new ArrayBuffer(1024);
var memory_float64 = new Float64Array(memory);
var module = Wasm.instantiateModuleFromAsm(
TestFloatHeapAccess.toString(), null, memory);
assertEquals(1, module.caller());
assertEquals(9.0, memory_float64[1]);
}
TestFloatHeapAccessExternal();
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 = Wasm.instantiateModuleFromAsm(TestNamedFunctions.toString());
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 = Wasm.instantiateModuleFromAsm(TestGlobalsWithInit.toString());
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 () {
function TestInitFunctionWithNoGlobals() {
"use asm";
function caller() {
return 51;
}
return {caller};
}
var module = Wasm.instantiateModuleFromAsm(
TestInitFunctionWithNoGlobals.toString());
assertEquals(51, module.caller());
})();
(function () {
function TestExportNameDifferentFromFunctionName() {
"use asm";
function caller() {
return 55;
}
return {alt_caller:caller};
}
var module = Wasm.instantiateModuleFromAsm(
TestExportNameDifferentFromFunctionName.toString());
assertEquals(55, module.alt_caller());
})();
function TestFunctionTableSingleFunction() {
"use asm";
function dummy() {
return 71;
}
function caller() {
return function_table[0&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() {
if ((function_table[0&1](50)|0) == 51) {
if ((function_table[1&1](60)|0) == 62) {
return 73;
}
}
return 0;
}
var function_table = [inc1, inc2]
return {caller:caller};
}
assertWasm(73, TestFunctionTableMultipleFunctions);
(function () {
function TestFunctionTable() {
"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};
}
var module = Wasm.instantiateModuleFromAsm(TestFunctionTable.toString());
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 TestForeignFunctions() {
function AsmModule(stdlib, foreign, buffer) {
"use asm";
var setVal = foreign.setVal;
var getVal = foreign.getVal;
function caller(initial_value, new_value) {
initial_value = initial_value|0;
new_value = new_value|0;
if ((getVal()|0) == (initial_value|0)) {
setVal(new_value|0);
return getVal()|0;
}
return 0;
}
return {caller:caller};
}
function ffi(initial_val) {
var val = initial_val;
function getVal() {
return val;
}
function setVal(new_val) {
val = new_val;
}
return {getVal:getVal, setVal:setVal};
}
var foreign = new ffi(23);
var module = Wasm.instantiateModuleFromAsm(AsmModule.toString(),
foreign, null);
assertEquals(103, module.caller(23, 103));
}
TestForeignFunctions();
function TestForeignFunctionMultipleUse() {
function AsmModule(stdlib, foreign, buffer) {
"use asm";
var getVal = foreign.getVal;
function caller(int_val, double_val) {
int_val = int_val|0;
double_val = +double_val;
if ((getVal()|0) == (int_val|0)) {
if ((+getVal()) == (+double_val)) {
return 89;
}
}
return 0;
}
return {caller:caller};
}
function ffi() {
function getVal() {
return 83.25;
}
return {getVal:getVal};
}
var foreign = new ffi();
var module = Wasm.instantiateModuleFromAsm(AsmModule.toString(),
foreign, null);
assertEquals(89, module.caller(83, 83.25));
}
TestForeignFunctionMultipleUse();
function TestForeignVariables() {
function AsmModule(stdlib, foreign, buffer) {
"use asm";
var i1 = foreign.foo | 0;
var f1 = +foreign.bar;
var i2 = foreign.baz | 0;
var f2 = +foreign.baz;
function geti1() {
return i1|0;
}
function getf1() {
return +f1;
}
function geti2() {
return i2|0;
}
function getf2() {
return +f2;
}
return {geti1:geti1, getf1:getf1, geti2:geti2, getf2:getf2};
}
function TestCase(env, i1, f1, i2, f2) {
print("Testing foreign variables...");
var module = Wasm.instantiateModuleFromAsm(
AsmModule.toString(), env);
assertEquals(i1, module.geti1());
assertEquals(f1, module.getf1());
assertEquals(i2, module.geti2());
assertEquals(f2, module.getf2());
}
// Check normal operation.
TestCase({foo: 123, bar: 234.5, baz: 345.7}, 123, 234.5, 345, 345.7);
// Check partial operation.
TestCase({baz: 345.7}, 0, NaN, 345, 345.7);
// Check that undefined values are converted to proper defaults.
TestCase({qux: 999}, 0, NaN, 0, NaN);
// Check that an undefined ffi is ok.
TestCase(undefined, 0, NaN, 0, NaN);
// Check that true values are converted properly.
TestCase({foo: true, bar: true, baz: true}, 1, 1.0, 1, 1.0);
// Check that false values are converted properly.
TestCase({foo: false, bar: false, baz: false}, 0, 0, 0, 0);
// Check that null values are converted properly.
TestCase({foo: null, bar: null, baz: null}, 0, 0, 0, 0);
// Check that string values are converted properly.
TestCase({foo: 'hi', bar: 'there', baz: 'dude'}, 0, NaN, 0, NaN);
TestCase({foo: '0xff', bar: '234', baz: '456.1'}, 255, 234, 456, 456.1, 456);
// Check that Date values are converted properly.
TestCase({foo: new Date(123), bar: new Date(456),
baz: new Date(789)}, 123, 456, 789, 789);
// Check that list values are converted properly.
TestCase({foo: [], bar: [], baz: []}, 0, 0, 0, 0);
// Check that object values are converted properly.
TestCase({foo: {}, bar: {}, baz: {}}, 0, NaN, 0, NaN);
// Check that getter object values are converted properly.
var o = {
get foo() {
return 123.4;
}
};
TestCase({foo: o.foo, bar: o.foo, baz: o.foo}, 123, 123.4, 123, 123.4);
// Check that getter object values are converted properly.
var o = {
get baz() {
return 123.4;
}
};
TestCase(o, 0, NaN, 123, 123.4);
// Check that objects with valueOf are converted properly.
var o = {
valueOf: function() { return 99; }
};
TestCase({foo: o, bar: o, baz: o}, 99, 99, 99, 99);
// Check that function values are converted properly.
TestCase({foo: TestCase, bar: TestCase, qux: TestCase}, 0, NaN, 0, NaN);
// Check that a missing ffi object is safe.
TestCase(undefined, 0, NaN, 0, NaN);
}
TestForeignVariables();
(function() {
function TestByteHeapAccessCompat(stdlib, foreign, buffer) {
"use asm";
var HEAP8 = new stdlib.Uint8Array(buffer);
var HEAP32 = new stdlib.Int32Array(buffer);
function store(i, v) {
i = i | 0;
v = v | 0;
HEAP32[i >> 2] = v;
}
function storeb(i, v) {
i = i | 0;
v = v | 0;
HEAP8[i | 0] = v;
}
function load(i) {
i = i | 0;
return HEAP8[i] | 0;
}
function iload(i) {
i = i | 0;
return HEAP8[HEAP32[i >> 2] | 0] | 0;
}
return {load: load, iload: iload, store: store, storeb: storeb};
}
var m = Wasm.instantiateModuleFromAsm(
TestByteHeapAccessCompat.toString());
m.store(0, 20);
m.store(4, 21);
m.store(8, 22);
m.storeb(20, 123);
m.storeb(21, 42);
m.storeb(22, 77);
assertEquals(123, m.load(20));
assertEquals(42, m.load(21));
assertEquals(77, m.load(22));
assertEquals(123, m.iload(0));
assertEquals(42, m.iload(4));
assertEquals(77, m.iload(8));
})();
function TestGlobalBlock(stdlib, foreign, buffer) {
"use asm";
var x = foreign.x | 0, y = foreign.y | 0;
function test() {
return (x + y) | 0;
}
return {caller: test};
}
assertWasm(15, TestGlobalBlock, { x: 4, y: 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 m = Wasm.instantiateModuleFromAsm(CommaModule.toString());
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 TestIntishAssignment() {
function Module(stdlib, foreign, heap) {
"use asm";
var HEAP32 = new stdlib.Int32Array(heap);
function func() {
var a = 1;
var b = 2;
HEAP32[0] = a + b;
return HEAP32[0] | 0;
}
return {func: func};
}
var m = Wasm.instantiateModuleFromAsm(Module.toString());
assertEquals(3, m.func());
})();
(function TestFloatishAssignment() {
function Module(stdlib, foreign, heap) {
"use asm";
var HEAPF32 = new stdlib.Float32Array(heap);
var fround = stdlib.Math.fround;
function func() {
var a = fround(1.0);
var b = fround(2.0);
HEAPF32[0] = a + b;
return +HEAPF32[0];
}
return {func: func};
}
var m = Wasm.instantiateModuleFromAsm(Module.toString());
assertEquals(3, m.func());
})();
(function TestDoubleToFloatAssignment() {
function Module(stdlib, foreign, heap) {
"use asm";
var HEAPF32 = new stdlib.Float32Array(heap);
var fround = stdlib.Math.fround;
function func() {
var a = 1.23;
HEAPF32[0] = a;
return +HEAPF32[0];
}
return {func: func};
}
var m = Wasm.instantiateModuleFromAsm(Module.toString());
assertEquals(1.23, m.func());
});
(function TestIntegerMultiplyBothWays() {
function Module(stdlib, foreign, heap) {
"use asm";
function func() {
var a = 1;
return ((a * 3) + (4 * a)) | 0;
}
return {func: func};
}
var m = Wasm.instantiateModuleFromAsm(Module.toString());
assertEquals(7, m.func());
})();
(function TestBadAssignDoubleFromIntish() {
function Module(stdlib, foreign, heap) {
"use asm";
function func() {
var a = 1;
var b = 3.0;
b = a;
}
return {func: func};
}
assertThrows(function() {
Wasm.instantiateModuleFromAsm(Module.toString());
});
})();
(function TestBadAssignIntFromDouble() {
function Module(stdlib, foreign, heap) {
"use asm";
function func() {
var a = 1;
var b = 3.0;
a = b;
}
return {func: func};
}
assertThrows(function() {
Wasm.instantiateModuleFromAsm(Module.toString());
});
})();
(function TestBadMultiplyIntish() {
function Module(stdlib, foreign, heap) {
"use asm";
function func() {
var a = 1;
return ((a + a) * 4) | 0;
}
return {func: func};
}
assertThrows(function() {
Wasm.instantiateModuleFromAsm(Module.toString());
});
})();
(function TestBadCastFromInt() {
function Module(stdlib, foreign, heap) {
"use asm";
function func() {
var a = 1;
return +a;
}
return {func: func};
}
assertThrows(function() {
Wasm.instantiateModuleFromAsm(Module.toString());
});
})();
(function TestAndNegative() {
function Module() {
"use asm";
function func() {
var x = 1;
var y = 2;
var z = 0;
z = x + y & -1;
return z | 0;
}
return {func: func};
}
var m = Wasm.instantiateModuleFromAsm(Module.toString());
assertEquals(3, m.func());
})();
(function TestNegativeDouble() {
function Module() {
"use asm";
function func() {
var x = -(34359738368.25);
var y = -2.5;
return +(x + y);
}
return {func: func};
}
var m = Wasm.instantiateModuleFromAsm(Module.toString());
assertEquals(-34359738370.75, m.func());
})();
(function TestBadAndDouble() {
function Module() {
"use asm";
function func() {
var x = 1.0;
var y = 2.0;
return (x & y) | 0;
}
return {func: func};
}
assertThrows(function() {
Wasm.instantiateModuleFromAsm(Module.toString());
});
})();
(function TestAndIntAndHeapValue() {
function Module(stdlib, foreign, buffer) {
"use asm";
var HEAP32 = new stdlib.Int32Array(buffer);
function func() {
var x = 0;
x = HEAP32[0] & -1;
return x | 0;
}
return {func: func};
}
var m = Wasm.instantiateModuleFromAsm(Module.toString());
assertEquals(0, m.func());
})();
(function TestOutOfBoundsConversion() {
function asmModule($a,$b,$c){'use asm';
function aaa() {
var f = 0.0;
var a = 0;
f = 5616315000.000001;
a = ~~f >>>0;
return a | 0;
}
return { main : aaa };
}
var wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
assertEquals(1321347704, wasm.main());
})();
(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 wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
assertEquals(0xffffffff, wasm.u0xffffffff());
assertEquals(0x80000000, wasm.u0x80000000());
assertEquals(0x87654321, wasm.u0x87654321());
})();
(function TestBadNoDeclaration() {
assertThrows(function() {
Wasm.instantiateModuleFromAsm('33;');
});
})();
(function TestBadVarDeclaration() {
assertThrows(function() {
Wasm.instantiateModuleFromAsm('var x = 3;');
});
})();