| // 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()); |
| })(); |