// Copyright 2016 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 function assertValidAsm(func) { assertTrue(%IsAsmWasmCode(func)); } (function TestSwitch0() { function asmModule() { "use asm" function caller() { var ret = 0; var x = 7; switch (x|0) { case 1: { return 0; } case 7: { ret = 5; break; } default: return 0; } return ret|0; } return {caller:caller}; } var wasm = asmModule(); assertValidAsm(asmModule); assertEquals(5, wasm.caller()); })(); (function TestSwitch() { function asmModule() { "use asm" function caller() { var ret = 0; var x = 7; switch (x|0) { case 1: return 0; case 7: { ret = 12; break; } default: return 0; } switch (x|0) { case 1: return 0; case 8: return 0; default: ret = (ret + 11)|0; } return ret|0; } return {caller:caller}; } var wasm = asmModule(); assertValidAsm(asmModule); assertEquals(23, wasm.caller()); })(); (function TestSwitchFallthrough() { function asmModule() { "use asm" function caller() { var x = 17; var ret = 0; switch (x|0) { case 17: case 14: ret = 39; case 1: ret = (ret + 3)|0; case 4: break; default: ret = (ret + 1)|0; } return ret|0; } return {caller:caller}; } var wasm = asmModule(); assertValidAsm(asmModule); assertEquals(42, wasm.caller()); })(); (function TestNestedSwitch() { function asmModule() { "use asm" function caller() { var x = 3; var y = -13; switch (x|0) { case 1: return 0; case 3: { switch (y|0) { case 2: return 0; case -13: return 43; default: return 0; } } default: return 0; } return 0; } return {caller:caller}; } var wasm = asmModule(); assertValidAsm(asmModule); assertEquals(43, wasm.caller()); })(); (function TestSwitchWithDefaultOnly() { function asmModule() { "use asm"; function main(x) { x = x|0; switch(x|0) { default: return -10; } return 0; } return { main: main, }; } var wasm = asmModule(); assertValidAsm(asmModule); assertEquals(-10, wasm.main(2)); assertEquals(-10, wasm.main(54)); })(); (function TestEmptySwitch() { function asmModule() { "use asm"; function main(x) { x = x|0; switch(x|0) { } return 73; } return { main: main, }; } var wasm = asmModule(); assertValidAsm(asmModule); assertEquals(73, wasm.main(7)); })(); (function TestSwitchWithBrTable() { function asmModule() { "use asm"; function main(x) { x = x|0; switch(x|0) { case 14: return 23; case 12: return 25; case 15: return 29; case 19: return 34; case 18: return 17; case 16: return 16; default: return -1; } return 0; } return { main: main, }; } var wasm = asmModule(); assertValidAsm(asmModule); assertEquals(25, wasm.main(12)); assertEquals(23, wasm.main(14)); assertEquals(29, wasm.main(15)); assertEquals(16, wasm.main(16)); assertEquals(17, wasm.main(18)); assertEquals(34, wasm.main(19)); assertEquals(-1, wasm.main(-1)); })(); (function TestSwitchWithBalancedTree() { function asmModule() { "use asm"; function main(x) { x = x|0; switch(x|0) { case 5: return 52; case 1: return 11; case 6: return 63; case 9: return 19; case -4: return -4; } return 0; } return { main: main, }; } var wasm = asmModule(); assertValidAsm(asmModule); assertEquals(-4, wasm.main(-4)); assertEquals(11, wasm.main(1)); assertEquals(52, wasm.main(5)); assertEquals(63, wasm.main(6)); assertEquals(19, wasm.main(9)); assertEquals(0, wasm.main(11)); })(); (function TestSwitchHybrid() { function asmModule() { "use asm"; function main(x) { x = x|0; switch(x|0) { case 1: return -4; case 2: return 23; case 3: return 32; case 4: return 14; case 7: return 17; case 10: return 10; case 11: return 121; case 12: return 112; case 13: return 31; case 16: return 16; default: return -1; } return 0; } return { main: main, }; } var wasm = asmModule(); assertValidAsm(asmModule); assertEquals(-4, wasm.main(1)); assertEquals(23, wasm.main(2)); assertEquals(32, wasm.main(3)); assertEquals(14, wasm.main(4)); assertEquals(17, wasm.main(7)); assertEquals(10, wasm.main(10)); assertEquals(121, wasm.main(11)); assertEquals(112, wasm.main(12)); assertEquals(31, wasm.main(13)); assertEquals(16, wasm.main(16)); assertEquals(-1, wasm.main(20)); })(); (function TestSwitchFallthroughWithBrTable() { function asmModule() { "use asm"; function main(x) { x = x|0; var ret = 0; switch(x|0) { case 1: { ret = 21; break; } case 2: { ret = 12; break; } case 3: { ret = 43; } case 4: { ret = 54; break; } default: { ret = 10; break; } } return ret|0; } return { main: main, }; } var wasm = asmModule(); assertValidAsm(asmModule); assertEquals(12, wasm.main(2)); assertEquals(10, wasm.main(10)); assertEquals(54, wasm.main(3)); })(); (function TestSwitchFallthroughHybrid() { function asmModule() { "use asm"; function main(x) { x = x|0; var ret = 0; switch(x|0) { case 1: { ret = 1; break; } case 2: { ret = 2; break; } case 3: { ret = 3; break; } case 4: { ret = 4; } case 7: { ret = 7; break; } case 10: { ret = 10; } case 16: { ret = 16; break; } case 17: { ret = 17; break; } case 18: { ret = 18; break; } case 19: { ret = 19; } default: { ret = -1; break; } } return ret|0; } return { main: main, }; } var wasm = asmModule(); assertValidAsm(asmModule); assertEquals(7, wasm.main(4)); assertEquals(16, wasm.main(10)); assertEquals(-1, wasm.main(19)); assertEquals(-1, wasm.main(23)); })(); (function TestSwitchHybridWithNoDefault() { function asmModule() { "use asm"; function main(x) { x = x|0; var ret = 19; switch(x|0) { case 1: { ret = 1; break; } case 2: { ret = 2; break; } case 3: { ret = 3; break; } case 4: { ret = 4; break; } case 7: { ret = 7; break; } } return ret|0; } return { main: main, }; } var wasm = asmModule(); assertValidAsm(asmModule); assertEquals(2, wasm.main(2)); assertEquals(7, wasm.main(7)); assertEquals(19, wasm.main(-1)); })(); (function TestLargeSwitch() { function LargeSwitchGenerator(begin, end, gap, handle_case) { var str = "function asmModule() {\ \"use asm\";\ function main(x) {\ x = x|0;\ switch(x|0) {"; for (var i = begin; i <= end; i = i + gap) { str = str.concat("case ", i.toString(), ": ", handle_case(i)); } str = str.concat("default: return -1;\ }\ return -2;\ }\ return {main: main}; }"); var decl = eval('(' + str + ')'); var wasm = decl(); assertValidAsm(decl); return wasm; } var handle_case = function(k) { return "return ".concat(k, ";"); } var wasm = LargeSwitchGenerator(0, 513, 1, handle_case); for (var i = 0; i <= 513; i++) { assertEquals(i, wasm.main(i)); } assertEquals(-1, wasm.main(-1)); wasm = LargeSwitchGenerator(0, 1024, 3, handle_case); for (var i = 0; i <= 1024; i = i + 3) { assertEquals(i, wasm.main(i)); } assertEquals(-1, wasm.main(-1)); wasm = LargeSwitchGenerator(-2147483648, -2147483000, 1, handle_case); for (var i = -2147483648; i <= -2147483000; i++) { assertEquals(i, wasm.main(i)); } assertEquals(-1, wasm.main(-1)); assertEquals(-1, wasm.main(214748647)); wasm = LargeSwitchGenerator(-2147483648, -2147483000, 3, handle_case); for (var i = -2147483648; i <= -2147483000; i = i + 3) { assertEquals(i, wasm.main(i)); } assertEquals(-1, wasm.main(-1)); assertEquals(-1, wasm.main(214748647)); wasm = LargeSwitchGenerator(2147483000, 2147483647, 1, handle_case); for (var i = 2147483000; i <= 2147483647; i++) { assertEquals(i, wasm.main(i)); } assertEquals(-1, wasm.main(-1)); assertEquals(-1, wasm.main(-214748647)); wasm = LargeSwitchGenerator(2147483000, 2147483647, 4, handle_case); for (var i = 2147483000; i <= 2147483647; i = i + 4) { assertEquals(i, wasm.main(i)); } assertEquals(-1, wasm.main(-1)); assertEquals(-1, wasm.main(-214748647)); handle_case = function(k) { if (k != 7) return "return ".concat(k, ";"); else return "break;"; } wasm = LargeSwitchGenerator(0, 1499, 7, handle_case); for (var i = 0; i <= 1499; i = i + 7) { if (i == 7) assertEquals(-2, wasm.main(i)); else assertEquals(i, wasm.main(i)); } assertEquals(-1, wasm.main(-1)); handle_case = function(k) { if (k != 56) return "break;"; else return "return 23;"; } wasm = LargeSwitchGenerator(0, 638, 2, handle_case); for (var i = 0; i <= 638; i = i + 2) { if (i == 56) assertEquals(23, wasm.main(i)); else assertEquals(-2, wasm.main(i)); } assertEquals(-1, wasm.main(-1)); })();