Merge V8 5.2.361.47 DO NOT MERGE
https://chromium.googlesource.com/v8/v8/+/5.2.361.47
FPIIM-449
Change-Id: Ibec421b85a9b88cb3a432ada642e469fe7e78346
(cherry picked from commit bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8)
diff --git a/test/mjsunit/wasm/adapter-frame.js b/test/mjsunit/wasm/adapter-frame.js
index 0e5d4b8..39164c7 100644
--- a/test/mjsunit/wasm/adapter-frame.js
+++ b/test/mjsunit/wasm/adapter-frame.js
@@ -27,8 +27,10 @@
var builder = new WasmModuleBuilder();
var sig = new Array();
- sig.push(type);
+ sig.push(args);
for (var i = 0; i < args; i++) sig.push(type);
+ sig.push(1);
+ sig.push(type);
builder.addFunction("select", sig)
.addBody([kExprGetLocal, which])
.exportFunc();
diff --git a/test/mjsunit/wasm/asm-wasm-switch.js b/test/mjsunit/wasm/asm-wasm-switch.js
new file mode 100644
index 0000000..bbdb1a2
--- /dev/null
+++ b/test/mjsunit/wasm/asm-wasm-switch.js
@@ -0,0 +1,468 @@
+// 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: --expose-wasm
+
+(function TestSwitch0() {
+ function asmModule() {
+ "use asm"
+
+ function caller() {
+ var ret = 0;
+ var x = 7;
+ switch (x) {
+ case 1: {
+ return 0;
+ }
+ case 7: {
+ ret = 5;
+ break;
+ }
+ default: return 0;
+ }
+ return ret|0;
+ }
+
+ return {caller:caller};
+ }
+ var wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
+ assertEquals(5, wasm.caller());
+})();
+
+(function TestSwitch() {
+ function asmModule() {
+ "use asm"
+
+ function caller() {
+ var ret = 0;
+ var x = 7;
+ switch (x) {
+ case 1: return 0;
+ case 7: {
+ ret = 12;
+ break;
+ }
+ default: return 0;
+ }
+ switch (x) {
+ case 1: return 0;
+ case 8: return 0;
+ default: ret = (ret + 11)|0;
+ }
+ return ret|0;
+ }
+
+ return {caller:caller};
+ }
+ var wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
+ assertEquals(23, wasm.caller());
+})();
+
+(function TestSwitchFallthrough() {
+ function asmModule() {
+ "use asm"
+
+ function caller() {
+ var x = 17;
+ var ret = 0;
+ switch (x) {
+ 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 = Wasm.instantiateModuleFromAsm(asmModule.toString());
+ assertEquals(42, wasm.caller());
+})();
+
+(function TestNestedSwitch() {
+ function asmModule() {
+ "use asm"
+
+ function caller() {
+ var x = 3;
+ var y = -13;
+ switch (x) {
+ case 1: return 0;
+ case 3: {
+ switch (y) {
+ case 2: return 0;
+ case -13: return 43;
+ default: return 0;
+ }
+ }
+ default: return 0;
+ }
+ return 0;
+ }
+
+ return {caller:caller};
+ }
+ var wasm = Wasm.instantiateModuleFromAsm(asmModule.toString());
+ 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 = Wasm.instantiateModuleFromAsm(asmModule.toString());
+ 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 = Wasm.instantiateModuleFromAsm(asmModule.toString());
+ 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 = Wasm.instantiateModuleFromAsm(asmModule.toString());
+ 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 = Wasm.instantiateModuleFromAsm(asmModule.toString());
+ 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 = Wasm.instantiateModuleFromAsm(asmModule.toString());
+ 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 = Wasm.instantiateModuleFromAsm(asmModule.toString());
+ 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 = Wasm.instantiateModuleFromAsm(asmModule.toString());
+ 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 = Wasm.instantiateModuleFromAsm(asmModule.toString());
+ 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 wasm = Wasm.instantiateModuleFromAsm(str);
+ 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));
+})();
diff --git a/test/mjsunit/wasm/asm-wasm.js b/test/mjsunit/wasm/asm-wasm.js
index 2efb006..54d7d7a 100644
--- a/test/mjsunit/wasm/asm-wasm.js
+++ b/test/mjsunit/wasm/asm-wasm.js
@@ -23,6 +23,20 @@
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";
@@ -193,6 +207,55 @@
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";
@@ -209,6 +272,22 @@
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";
@@ -769,82 +848,6 @@
assertWasm(41, TestConditional);
-function TestSwitch() {
- "use asm"
-
- function caller() {
- var ret = 0;
- var x = 7;
- switch (x) {
- case 1: return 0;
- case 7: {
- ret = 12;
- break;
- }
- default: return 0;
- }
- switch (x) {
- case 1: return 0;
- case 8: return 0;
- default: ret = (ret + 11)|0;
- }
- return ret|0;
- }
-
- return {caller:caller};
-}
-
-assertWasm(23, TestSwitch);
-
-
-function TestSwitchFallthrough() {
- "use asm"
-
- function caller() {
- var x = 17;
- var ret = 0;
- switch (x) {
- 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};
-}
-
-assertWasm(42, TestSwitchFallthrough);
-
-
-function TestNestedSwitch() {
- "use asm"
-
- function caller() {
- var x = 3;
- var y = -13;
- switch (x) {
- case 1: return 0;
- case 3: {
- switch (y) {
- case 2: return 0;
- case -13: return 43;
- default: return 0;
- }
- }
- default: return 0;
- }
- return 0;
- }
-
- return {caller:caller};
-}
-
-assertWasm(43, TestNestedSwitch);
-
-
(function () {
function TestInitFunctionWithNoGlobals() {
"use asm";
diff --git a/test/mjsunit/wasm/calls.js b/test/mjsunit/wasm/calls.js
index 11cc92a..94e97e6 100644
--- a/test/mjsunit/wasm/calls.js
+++ b/test/mjsunit/wasm/calls.js
@@ -37,20 +37,42 @@
assertFalse(exp === null);
assertFalse(exp === 0);
assertEquals("function", typeof exp);
-
return exp;
}
+(function I64SubTest() {
+
+ var builder = new WasmModuleBuilder();
+
+ builder.addMemory(1, 1, true);
+ builder.addFunction("sub", kSig_l_ll)
+ .addBody([ // --
+ kExprGetLocal, 0, // --
+ kExprGetLocal, 1, // --
+ kExprI64Sub]) // --
+ .exportFunc()
+
+ var module = builder.instantiate();
+ assertModule(module, kPageSize);
+
+ // Check the properties of the sub function.
+ var sub = assertFunction(module, "sub");
+ assertEquals(-55, sub(33, 88));
+ assertEquals(-55555, sub(33333, 88888));
+ assertEquals(-5555555, sub(3333333, 8888888));
+})();
+
(function SubTest() {
var builder = new WasmModuleBuilder();
builder.addMemory(1, 1, true);
- builder.addFunction("sub", [kAstI32, kAstI32, kAstI32])
+ builder.addFunction("sub", kSig_i_ii)
.addBody([
- kExprI32Sub, // --
kExprGetLocal, 0, // --
- kExprGetLocal, 1]) // --
+ kExprGetLocal, 1, // --
+ kExprI32Sub, // --
+ ])
.exportFunc()
var module = builder.instantiate();
@@ -70,7 +92,7 @@
var kPages = 2;
builder.addMemory(kPages, kPages, true);
- builder.addFunction("nop", [kAstStmt])
+ builder.addFunction("nop", kSig_v_v)
.addBody([kExprNop])
.exportFunc();
@@ -87,11 +109,12 @@
var kPages = 3;
builder.addMemory(kPages, kPages, true);
- builder.addFunction("flt", [kAstI32, kAstF64, kAstF64])
+ builder.addFunction("flt", kSig_i_dd)
.addBody([
- kExprF64Lt, // --
kExprGetLocal, 0, // --
- kExprGetLocal, 1]) // --
+ kExprGetLocal, 1, // --
+ kExprF64Lt // --
+ ]) // --
.exportFunc();
var module = builder.instantiate();
diff --git a/test/mjsunit/wasm/divrem-trap.js b/test/mjsunit/wasm/divrem-trap.js
index 976e473..6f3ff5d 100644
--- a/test/mjsunit/wasm/divrem-trap.js
+++ b/test/mjsunit/wasm/divrem-trap.js
@@ -33,8 +33,12 @@
function makeBinop(opcode) {
var builder = new WasmModuleBuilder();
- builder.addFunction("main", [kAstI32, kAstI32, kAstI32])
- .addBody([opcode, kExprGetLocal, 0, kExprGetLocal, 1])
+ builder.addFunction("main", kSig_i_ii)
+ .addBody([
+ kExprGetLocal, 0, // --
+ kExprGetLocal, 1, // --
+ opcode, // --
+ ])
.exportFunc();
return builder.instantiate().exports.main;
diff --git a/test/mjsunit/wasm/export-table.js b/test/mjsunit/wasm/export-table.js
index e85da9b..a41d85d 100644
--- a/test/mjsunit/wasm/export-table.js
+++ b/test/mjsunit/wasm/export-table.js
@@ -11,11 +11,12 @@
var kReturnValue = 88;
var builder = new WasmModuleBuilder();
- builder.addFunction("main", [kAstI32])
+ builder.addFunction("main", kSig_i)
.addBody([
- kExprReturn,
kExprI8Const,
- kReturnValue])
+ kReturnValue,
+ kExprReturn, kArity1
+ ])
.exportFunc();
var module = builder.instantiate();
@@ -31,11 +32,12 @@
var builder = new WasmModuleBuilder();
- builder.addFunction("main", [kAstI32])
+ builder.addFunction("main", kSig_i)
.addBody([
- kExprReturn,
kExprI8Const,
- kReturnValue])
+ kReturnValue,
+ kExprReturn, kArity1
+ ])
.exportAs("blah")
.exportAs("foo");
@@ -48,3 +50,25 @@
assertEquals(kReturnValue, module.exports.foo());
assertEquals(kReturnValue, module.exports.blah());
})();
+
+
+(function testNumericName() {
+ var kReturnValue = 93;
+
+ var builder = new WasmModuleBuilder();
+
+ builder.addFunction("main", kSig_i)
+ .addBody([
+ kExprI8Const,
+ kReturnValue,
+ kExprReturn, kArity1
+ ])
+ .exportAs("0");
+
+ var module = builder.instantiate();
+
+ assertEquals("object", typeof module.exports);
+ assertEquals("function", typeof module.exports["0"]);
+
+ assertEquals(kReturnValue, module.exports["0"]());
+})();
diff --git a/test/mjsunit/wasm/ffi-error.js b/test/mjsunit/wasm/ffi-error.js
index 649ee27..b6474c6 100644
--- a/test/mjsunit/wasm/ffi-error.js
+++ b/test/mjsunit/wasm/ffi-error.js
@@ -10,13 +10,14 @@
function testCallFFI(ffi) {
var builder = new WasmModuleBuilder();
- var sig_index = [kAstI32, kAstF64, kAstF64];
+ var sig_index = kSig_i_dd;
builder.addImport("fun", sig_index);
builder.addFunction("main", sig_index)
.addBody([
- kExprCallImport, 0, // --
- kExprGetLocal, 0, // --
- kExprGetLocal, 1]) // --
+ kExprGetLocal, 0, // --
+ kExprGetLocal, 1, // --
+ kExprCallFunction, kArity2, 0, // --
+ ]) // --
.exportFunc();
var module = builder.instantiate(ffi);
diff --git a/test/mjsunit/wasm/ffi.js b/test/mjsunit/wasm/ffi.js
index 61fcf02..87dfe3b 100644
--- a/test/mjsunit/wasm/ffi.js
+++ b/test/mjsunit/wasm/ffi.js
@@ -10,13 +10,14 @@
function testCallFFI(func, check) {
var builder = new WasmModuleBuilder();
- var sig_index = builder.addSignature([kAstI32, kAstF64, kAstF64]);
+ var sig_index = builder.addSignature(kSig_i_dd);
builder.addImport("func", sig_index);
builder.addFunction("main", sig_index)
.addBody([
- kExprCallImport, 0, // --
- kExprGetLocal, 0, // --
- kExprGetLocal, 1]) // --
+ kExprGetLocal, 0, // --
+ kExprGetLocal, 1, // --
+ kExprCallImport, kArity2, 0 // --
+ ]) // --
.exportFunc();
var main = builder.instantiate({func: func}).exports.main;
@@ -184,14 +185,14 @@
var builder = new WasmModuleBuilder();
- builder.addImport("func", [kAstStmt, type, type]);
- builder.addFunction("main", [kAstI32, type, type])
+ builder.addImport("func", makeSig_v_xx(type));
+ builder.addFunction("main", makeSig_r_xx(kAstI32, type))
.addBody([
- kExprBlock, 2, // --
- kExprCallImport, 0, // --
- kExprGetLocal, 0, // --
- kExprGetLocal, 1, // --
- kExprI8Const, 99]) // --
+ kExprGetLocal, 0, // --
+ kExprGetLocal, 1, // --
+ kExprCallImport, kArity2, 0, // --
+ kExprI8Const, 99 // --
+ ]) // --
.exportFunc()
var main = builder.instantiate(ffi).exports.main;
@@ -240,15 +241,15 @@
function testCallPrint() {
var builder = new WasmModuleBuilder();
- builder.addImport("print", [kAstStmt, kAstI32]);
- builder.addImport("print", [kAstStmt, kAstF64]);
- builder.addFunction("main", [kAstStmt, kAstF64])
+ builder.addImport("print", makeSig_v_x(kAstI32));
+ builder.addImport("print", makeSig_v_x(kAstF64));
+ builder.addFunction("main", makeSig_v_x(kAstF64))
.addBody([
- kExprBlock, 2, // --
- kExprCallImport, 0, // --
- kExprI8Const, 97, // --
- kExprCallImport, 1, // --
- kExprGetLocal, 0]) // --
+ kExprI8Const, 97, // --
+ kExprCallImport, kArity1, 0, // --
+ kExprGetLocal, 0, // --
+ kExprCallImport, kArity1, 1 // --
+ ]) // --
.exportFunc()
var main = builder.instantiate({print: print}).exports.main;
diff --git a/test/mjsunit/wasm/function-prototype.js b/test/mjsunit/wasm/function-prototype.js
index db04b95..25339ad 100644
--- a/test/mjsunit/wasm/function-prototype.js
+++ b/test/mjsunit/wasm/function-prototype.js
@@ -10,7 +10,7 @@
(function TestFunctionPrototype() {
var builder = new WasmModuleBuilder();
- builder.addFunction("nine", [kAstI32])
+ builder.addFunction("nine", kSig_i)
.addBody([kExprI8Const, 9])
.exportFunc();
diff --git a/test/mjsunit/wasm/gc-frame.js b/test/mjsunit/wasm/gc-frame.js
index 8387d26..5fa9b05 100644
--- a/test/mjsunit/wasm/gc-frame.js
+++ b/test/mjsunit/wasm/gc-frame.js
@@ -10,14 +10,13 @@
function makeFFI(func, t) {
var builder = new WasmModuleBuilder();
- var sig_index = builder.addSignature([t,t,t,t,t,t,t,t,t,t,t]);
+ var sig_index = builder.addSignature([10,t,t,t,t,t,t,t,t,t,t,1,t]);
builder.addImport("func", sig_index);
// Try to create a frame with lots of spilled values and parameters
// on the stack to try to catch GC bugs in the reference maps for
// the different parts of the stack.
builder.addFunction("main", sig_index)
.addBody([
- kExprCallImport, 0, // --
kExprGetLocal, 0, // --
kExprGetLocal, 1, // --
kExprGetLocal, 2, // --
@@ -28,7 +27,7 @@
kExprGetLocal, 7, // --
kExprGetLocal, 8, // --
kExprGetLocal, 9, // --
- kExprCallImport, 0, // --
+ kExprCallImport, 10, 0, // --
kExprGetLocal, 0, // --
kExprGetLocal, 1, // --
kExprGetLocal, 2, // --
@@ -38,7 +37,8 @@
kExprGetLocal, 6, // --
kExprGetLocal, 7, // --
kExprGetLocal, 8, // --
- kExprGetLocal, 9 // --
+ kExprGetLocal, 9, // --
+ kExprCallImport, 10, 0 // --
]) // --
.exportFunc();
diff --git a/test/mjsunit/wasm/import-table.js b/test/mjsunit/wasm/import-table.js
index 7579901..c3f8cb9 100644
--- a/test/mjsunit/wasm/import-table.js
+++ b/test/mjsunit/wasm/import-table.js
@@ -10,13 +10,13 @@
function testCallImport(func, check) {
var builder = new WasmModuleBuilder();
- var sig_index = builder.addSignature([kAstI32, kAstF64, kAstF64]);
+ var sig_index = builder.addSignature(kSig_i_dd);
builder.addImport("func", sig_index);
builder.addFunction("main", sig_index)
.addBody([
- kExprCallImport, 0, // --
kExprGetLocal, 0, // --
- kExprGetLocal, 1]) // --
+ kExprGetLocal, 1, // --
+ kExprCallImport, 2, 0]) // --
.exportAs("main");
var main = builder.instantiate({func: func}).exports.main;
@@ -186,14 +186,14 @@
var builder = new WasmModuleBuilder();
- builder.addImport("func", [kAstStmt, type, type]);
- builder.addFunction("main", [kAstI32, type, type])
+ builder.addImport("func", makeSig_v_xx(type));
+ builder.addFunction("main", makeSig_r_xx(kAstI32, type))
.addBody([
- kExprBlock, 2, // --
- kExprCallImport, 0, // --
kExprGetLocal, 0, // --
kExprGetLocal, 1, // --
- kExprI8Const, 99])
+ kExprCallImport, 2, 0, // --
+ kExprI8Const, 99, // --
+ ])
.exportFunc("main");
var main = builder.instantiate(ffi).exports.main;
@@ -241,15 +241,15 @@
function testCallPrint() {
var builder = new WasmModuleBuilder();
- builder.addImport("print", [kAstStmt, kAstI32]);
- builder.addImport("print", [kAstStmt, kAstF64]);
- builder.addFunction("main", [kAstStmt, kAstF64])
+ builder.addImport("print", makeSig_v_x(kAstI32));
+ builder.addImport("print", makeSig_r_x(kAstF64, kAstF64));
+ builder.addFunction("main", makeSig_r_x(kAstF64, kAstF64))
.addBody([
- kExprBlock, 2, // --
- kExprCallImport, 0, // --
- kExprI8Const, 97, // --
- kExprCallImport, 1, // --
- kExprGetLocal, 0]) // --
+ kExprI8Const, 97, // --
+ kExprCallImport, kArity1, 0, // --
+ kExprGetLocal, 0, // --
+ kExprCallImport, kArity1, 1 // --
+ ])
.exportFunc();
var main = builder.instantiate({print: print}).exports.main;
@@ -266,13 +266,14 @@
function testCallImport2(foo, bar, expected) {
var builder = new WasmModuleBuilder();
- builder.addImport("foo", [kAstI32]);
- builder.addImport("bar", [kAstI32]);
- builder.addFunction("main", [kAstI32])
+ builder.addImport("foo", kSig_i);
+ builder.addImport("bar", kSig_i);
+ builder.addFunction("main", kSig_i)
.addBody([
+ kExprCallImport, kArity0, 0, // --
+ kExprCallImport, kArity0, 1, // --
kExprI32Add, // --
- kExprCallImport, 0, // --
- kExprCallImport, 1]) // --
+ ]) // --
.exportFunc();
var main = builder.instantiate({foo: foo, bar: bar}).exports.main;
diff --git a/test/mjsunit/wasm/indirect-calls.js b/test/mjsunit/wasm/indirect-calls.js
index 3258687..80bee41 100644
--- a/test/mjsunit/wasm/indirect-calls.js
+++ b/test/mjsunit/wasm/indirect-calls.js
@@ -10,22 +10,25 @@
var module = (function () {
var builder = new WasmModuleBuilder();
- var sig_index = builder.addSignature([kAstI32, kAstI32, kAstI32]);
+ var sig_index = builder.addSignature(kSig_i_ii);
builder.addImport("add", sig_index);
builder.addFunction("add", sig_index)
.addBody([
- kExprCallImport, 0, kExprGetLocal, 0, kExprGetLocal, 1
+ kExprGetLocal, 0, kExprGetLocal, 1, kExprCallImport, kArity2, 0
]);
builder.addFunction("sub", sig_index)
.addBody([
- kExprI32Sub, kExprGetLocal, 0, kExprGetLocal, 1
+ kExprGetLocal, 0, // --
+ kExprGetLocal, 1, // --
+ kExprI32Sub, // --
]);
- builder.addFunction("main", [kAstI32, kAstI32, kAstI32, kAstI32])
+ builder.addFunction("main", kSig_i_iii)
.addBody([
- kExprCallIndirect, sig_index,
kExprGetLocal, 0,
kExprGetLocal, 1,
- kExprGetLocal, 2])
+ kExprGetLocal, 2,
+ kExprCallIndirect, kArity2, sig_index
+ ])
.exportFunc()
builder.appendToFunctionTable([0, 1, 2]);
diff --git a/test/mjsunit/wasm/instantiate-module-basic.js b/test/mjsunit/wasm/instantiate-module-basic.js
index bc13122..800dcc1 100644
--- a/test/mjsunit/wasm/instantiate-module-basic.js
+++ b/test/mjsunit/wasm/instantiate-module-basic.js
@@ -13,7 +13,7 @@
var builder = new WasmModuleBuilder();
builder.addMemory(1, 1, true);
- builder.addFunction("main", [kAstI32])
+ builder.addFunction("main", kSig_i)
.addBody([kExprI8Const, kReturnValue])
.exportFunc();
diff --git a/test/mjsunit/wasm/instantiate-run-basic.js b/test/mjsunit/wasm/instantiate-run-basic.js
index 2e649a0..fe6fc14 100644
--- a/test/mjsunit/wasm/instantiate-run-basic.js
+++ b/test/mjsunit/wasm/instantiate-run-basic.js
@@ -11,7 +11,7 @@
var kReturnValue = 107;
var builder = new WasmModuleBuilder();
- builder.addFunction("main", [kAstI32])
+ builder.addFunction("main", kSig_i_i)
.addBody([kExprI8Const, kReturnValue])
.exportFunc();
diff --git a/test/mjsunit/wasm/module-memory.js b/test/mjsunit/wasm/module-memory.js
index ef85eb2..a5e5f42 100644
--- a/test/mjsunit/wasm/module-memory.js
+++ b/test/mjsunit/wasm/module-memory.js
@@ -13,19 +13,27 @@
var builder = new WasmModuleBuilder();
builder.addMemory(1, 1, true);
- builder.addFunction("main", [kAstI32, kAstI32])
+ builder.addFunction("main", kSig_i_i)
.addBody([
- kExprBlock,2,
- kExprLoop,1,
- kExprIf,
+ // main body: while(i) { if(mem[i]) return -1; i -= 4; } return 0;
+ kExprLoop,
+ kExprGetLocal,0,
+ kExprIf,
kExprGetLocal,0,
- kExprBr, 0,
- kExprIfElse,
- kExprI32LoadMem,0,0,kExprGetLocal,0,
- kExprBr,2, kExprI8Const, 255,
- kExprSetLocal,0,
- kExprI32Sub,kExprGetLocal,0,kExprI8Const,4,
- kExprI8Const,0])
+ kExprI32LoadMem,0,0,
+ kExprIf,
+ kExprI8Const,255,
+ kExprReturn, kArity1,
+ kExprEnd,
+ kExprGetLocal,0,
+ kExprI8Const,4,
+ kExprI32Sub,
+ kExprSetLocal,0,
+ kExprBr, kArity1, 1,
+ kExprEnd,
+ kExprEnd,
+ kExprI8Const,0
+ ])
.exportFunc();
return builder.instantiate(null, memory);
@@ -120,14 +128,16 @@
var builder = new WasmModuleBuilder();
builder.addMemory(1, 1, true);
- builder.addFunction("geti", [kAstI32, kAstI32, kAstI32])
+ builder.addFunction("geti", kSig_i_ii)
.addBody([
- kExprI32StoreMem, 0, 0, kExprGetLocal, 0, kExprI32LoadMem, 0, 0, kExprGetLocal, 1
+ kExprGetLocal, 0,
+ kExprGetLocal, 1,
+ kExprI32LoadMem, 0, 0,
+ kExprI32StoreMem, 0, 0
])
.exportFunc();
var module = builder.instantiate();
-
var offset;
function read() { return module.exports.geti(0, offset); }
diff --git a/test/mjsunit/wasm/parallel_compilation.js b/test/mjsunit/wasm/parallel_compilation.js
new file mode 100644
index 0000000..23c5658
--- /dev/null
+++ b/test/mjsunit/wasm/parallel_compilation.js
@@ -0,0 +1,100 @@
+// 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: --expose-wasm --wasm-num-compilation-tasks=10
+
+load("test/mjsunit/wasm/wasm-constants.js");
+load("test/mjsunit/wasm/wasm-module-builder.js");
+
+function assertModule(module, memsize) {
+ // Check the module exists.
+ assertFalse(module === undefined);
+ assertFalse(module === null);
+ assertFalse(module === 0);
+ assertEquals("object", typeof module);
+
+ // Check the memory is an ArrayBuffer.
+ var mem = module.exports.memory;
+ assertFalse(mem === undefined);
+ assertFalse(mem === null);
+ assertFalse(mem === 0);
+ assertEquals("object", typeof mem);
+ assertTrue(mem instanceof ArrayBuffer);
+ for (var i = 0; i < 4; i++) {
+ module.exports.memory = 0; // should be ignored
+ assertEquals(mem, module.exports.memory);
+ }
+
+ assertEquals(memsize, module.exports.memory.byteLength);
+}
+
+function assertFunction(module, func) {
+ assertEquals("object", typeof module.exports);
+
+ var exp = module.exports[func];
+ assertFalse(exp === undefined);
+ assertFalse(exp === null);
+ assertFalse(exp === 0);
+ assertEquals("function", typeof exp);
+ return exp;
+}
+
+(function CompileFunctionsTest() {
+
+ var builder = new WasmModuleBuilder();
+
+ builder.addMemory(1, 1, true);
+ for (i = 0; i < 1000; i++) {
+ builder.addFunction("sub" + i, kSig_i_i)
+ .addBody([ // --
+ kExprGetLocal, 0, // --
+ kExprI32Const, i % 61, // --
+ kExprI32Sub]) // --
+ .exportFunc()
+ }
+
+ var module = builder.instantiate();
+ assertModule(module, kPageSize);
+
+ // Check the properties of the functions.
+ for (i = 0; i < 1000; i++) {
+ var sub = assertFunction(module, "sub" + i);
+ assertEquals(33 - (i % 61), sub(33));
+ }
+})();
+
+(function CallFunctionsTest() {
+
+ var builder = new WasmModuleBuilder();
+
+ var f = []
+
+ f[0] = builder.addFunction("add0", kSig_i_ii)
+ .addBody([
+ kExprGetLocal, 0, // --
+ kExprGetLocal, 1, // --
+ kExprI32Add, // --
+ ])
+ .exportFunc()
+
+ builder.addMemory(1, 1, true);
+ for (i = 1; i < 256; i++) {
+ f[i] = builder.addFunction("add" + i, kSig_i_ii)
+ .addBody([ // --
+ kExprGetLocal, 0, // --
+ kExprGetLocal, 1, // --
+ kExprCallFunction, kArity2, f[i >>> 1].index]) // --
+ .exportFunc()
+ }
+ var module = builder.instantiate();
+ assertModule(module, kPageSize);
+
+ // Check the properties of the functions.
+ for (i = 0; i < 256; i++) {
+ var add = assertFunction(module, "add" + i);
+ assertEquals(88, add(33, 55));
+ assertEquals(88888, add(33333, 55555));
+ assertEquals(8888888, add(3333333, 5555555));
+ }
+})();
diff --git a/test/mjsunit/wasm/params.js b/test/mjsunit/wasm/params.js
index 7c2b3d1..180ab1c 100644
--- a/test/mjsunit/wasm/params.js
+++ b/test/mjsunit/wasm/params.js
@@ -17,7 +17,7 @@
var builder = new WasmModuleBuilder();
- builder.addFunction("select", [type, type, type])
+ builder.addFunction("select", makeSig_r_xx(type, type))
.addBody([kExprGetLocal, which])
.exportFunc()
@@ -79,7 +79,7 @@
print("type = " + t + ", which = " + which);
var builder = new WasmModuleBuilder();
- builder.addFunction("select", [t,t,t,t,t,t,t,t,t,t,t])
+ builder.addFunction("select", [10,t,t,t,t,t,t,t,t,t,t,1,t])
.addBody([kExprGetLocal, which])
.exportFunc();
diff --git a/test/mjsunit/wasm/stack.js b/test/mjsunit/wasm/stack.js
index ed05517..a45db94 100644
--- a/test/mjsunit/wasm/stack.js
+++ b/test/mjsunit/wasm/stack.js
@@ -2,39 +2,129 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// clang-format off
// Flags: --expose-wasm
load("test/mjsunit/wasm/wasm-constants.js");
load("test/mjsunit/wasm/wasm-module-builder.js");
-var expected = "Error\n" +
- // The line numbers below will change as this test gains / loses lines..
- " at STACK (stack.js:24:11)\n" + // --
- " at <WASM> (<anonymous>)\n" + // TODO(jfb): wasm stack here.
- " at testStack (stack.js:38:18)\n" + // --
- " at stack.js:40:3"; // --
-
// The stack trace contains file path, only keep "stack.js".
function stripPath(s) {
return s.replace(/[^ (]*stack\.js/g, "stack.js");
}
+function verifyStack(frames, expected) {
+ assertEquals(expected.length, frames.length, "number of frames mismatch");
+ expected.forEach(function(exp, i) {
+ if (exp[1] != "?") {
+ assertEquals(exp[1], frames[i].getFunctionName(),
+ "["+i+"].getFunctionName()");
+ }
+ assertEquals(exp[2], frames[i].getLineNumber(), "["+i+"].getLineNumber()");
+ if (exp[0])
+ assertEquals(exp[3], frames[i].getPosition(),
+ "["+i+"].getPosition()");
+ assertContains(exp[4], frames[i].getFileName(), "["+i+"].getFileName()");
+ var toString;
+ if (exp[0]) {
+ var funName = exp[1] == "?" ? "" : exp[1];
+ toString = funName + " (<WASM>:" + exp[2] + ":" + exp[3] + ")";
+ } else {
+ toString = exp[4] + ":" + exp[2] + ":";
+ }
+ assertContains(toString, frames[i].toString(), "["+i+"].toString()");
+ });
+}
+
+
var stack;
function STACK() {
var e = new Error();
stack = e.stack;
}
-(function testStack() {
- var builder = new WasmModuleBuilder();
+var builder = new WasmModuleBuilder();
- builder.addImport("func", [kAstStmt]);
+builder.addImport("func", kSig_v_v);
- builder.addFunction(undefined, [kAstStmt])
- .addBody([kExprCallImport, 0])
- .exportAs("main");
+builder.addFunction("main", kSig_v_v)
+ .addBody([kExprCallImport, kArity0, 0])
+ .exportAs("main");
- var module = builder.instantiate({func: STACK});
+builder.addFunction("exec_unreachable", kSig_v_v)
+ .addBody([kExprUnreachable])
+ .exportAs("exec_unreachable");
+
+// Make this function unnamed, just to test also this case.
+var mem_oob_func = builder.addFunction(undefined, kSig_v_v)
+ // Access the memory at offset -1, to provoke a trap.
+ .addBody([kExprI32Const, 0x7f, kExprI32LoadMem8S, 0, 0])
+ .exportAs("mem_out_of_bounds");
+
+// Call the mem_out_of_bounds function, in order to have two WASM stack frames.
+builder.addFunction("call_mem_out_of_bounds", kSig_v_v)
+ .addBody([kExprCallFunction, kArity0, mem_oob_func.index])
+ .exportAs("call_mem_out_of_bounds");
+
+var module = builder.instantiate({func: STACK});
+
+(function testSimpleStack() {
+ var expected_string = "Error\n" +
+ // The line numbers below will change as this test gains / loses lines..
+ " at STACK (stack.js:42:11)\n" + // --
+ " at main (<WASM>:0:1)\n" + // --
+ " at testSimpleStack (stack.js:79:18)\n" + // --
+ " at stack.js:81:3"; // --
+
module.exports.main();
- assertEquals(expected, stripPath(stack));
+ assertEquals(expected_string, stripPath(stack));
+})();
+
+// For the remaining tests, collect the Callsite objects instead of just a
+// string:
+Error.prepareStackTrace = function(error, frames) {
+ return frames;
+};
+
+(function testStackFrames() {
+ module.exports.main();
+
+ verifyStack(stack, [
+ // isWasm function line pos file
+ [ false, "STACK", 42, 0, "stack.js"],
+ [ true, "main", 0, 1, null],
+ [ false, "testStackFrames", 90, 0, "stack.js"],
+ [ false, null, 99, 0, "stack.js"]
+ ]);
+})();
+
+(function testWasmUnreachable() {
+ try {
+ module.exports.exec_unreachable();
+ fail("expected wasm exception");
+ } catch (e) {
+ assertContains("unreachable", e.message);
+ verifyStack(e.stack, [
+ // isWasm function line pos file
+ [ true, "exec_unreachable", 1, 1, null],
+ [ false, "testWasmUnreachable", 103, 0, "stack.js"],
+ [ false, null, 114, 0, "stack.js"]
+ ]);
+ }
+})();
+
+(function testWasmMemOutOfBounds() {
+ try {
+ module.exports.call_mem_out_of_bounds();
+ fail("expected wasm exception");
+ } catch (e) {
+ assertContains("out of bounds", e.message);
+ verifyStack(e.stack, [
+ // isWasm function line pos file
+ [ true, "?", 2, 3, null],
+ [ true, "call_mem_out_of_bounds", 3, 1, null],
+ [ false, "testWasmMemOutOfBounds", 118, 0, "stack.js"],
+ [ false, null, 130, 0, "stack.js"]
+ ]);
+ }
})();
diff --git a/test/mjsunit/wasm/stackwalk.js b/test/mjsunit/wasm/stackwalk.js
index 8b8fb7e..5e5a1ef 100644
--- a/test/mjsunit/wasm/stackwalk.js
+++ b/test/mjsunit/wasm/stackwalk.js
@@ -10,13 +10,14 @@
function makeFFI(func) {
var builder = new WasmModuleBuilder();
- var sig_index = builder.addSignature([kAstI32, kAstF64, kAstF64]);
+ var sig_index = builder.addSignature(kSig_i_dd);
builder.addImport("func", sig_index);
builder.addFunction("main", sig_index)
.addBody([
- kExprCallImport, 0, // --
- kExprGetLocal, 0, // --
- kExprGetLocal, 1]) // --
+ kExprGetLocal, 0, // --
+ kExprGetLocal, 1, // --
+ kExprCallImport, kArity2, 0, // --
+ ])
.exportFunc()
return builder.instantiate({func: func}).exports.main;
diff --git a/test/mjsunit/wasm/start-function.js b/test/mjsunit/wasm/start-function.js
index bd4ccf2..3c5707a 100644
--- a/test/mjsunit/wasm/start-function.js
+++ b/test/mjsunit/wasm/start-function.js
@@ -37,19 +37,19 @@
return module;
}
-assertVerifies([kAstStmt], [kExprNop]);
-assertVerifies([kAstI32], [kExprI8Const, 0]);
+assertVerifies(kSig_v_v, [kExprNop]);
+assertVerifies(kSig_i, [kExprI8Const, 0]);
// Arguments aren't allow to start functions.
-assertFails([kAstI32, kAstI32], [kExprGetLocal, 0]);
-assertFails([kAstI32, kAstI32, kAstF32], [kExprGetLocal, 0]);
-assertFails([kAstI32, kAstI32, kAstF32, kAstF64], [kExprGetLocal, 0]);
+assertFails(kSig_i_i, [kExprGetLocal, 0]);
+assertFails(kSig_i_ii, [kExprGetLocal, 0]);
+assertFails(kSig_i_dd, [kExprGetLocal, 0]);
(function testInvalidIndex() {
print("testInvalidIndex");
var builder = new WasmModuleBuilder();
- var func = builder.addFunction("", [kAstStmt])
+ var func = builder.addFunction("", kSig_v_v)
.addBody([kExprNop]);
builder.addStart(func.index + 1);
@@ -62,7 +62,7 @@
print("testTwoStartFuncs");
var builder = new WasmModuleBuilder();
- var func = builder.addFunction("", [kAstStmt])
+ var func = builder.addFunction("", kSig_v_v)
.addBody([kExprNop]);
builder.addExplicitSection([kDeclStartFunction, 0]);
@@ -78,8 +78,8 @@
builder.addMemory(12, 12, true);
- var func = builder.addFunction("", [kAstStmt])
- .addBody([kExprI32StoreMem, 0, 0, kExprI8Const, 0, kExprI8Const, 77]);
+ var func = builder.addFunction("", kSig_v_v)
+ .addBody([kExprI8Const, 0, kExprI8Const, 77, kExprI32StoreMem, 0, 0]);
builder.addStart(func.index);
@@ -98,11 +98,11 @@
}};
var builder = new WasmModuleBuilder();
- var sig_index = builder.addSignature([kAstStmt]);
+ var sig_index = builder.addSignature(kSig_v_v);
builder.addImport("foo", sig_index);
var func = builder.addFunction("", sig_index)
- .addBody([kExprCallImport, 0]);
+ .addBody([kExprCallImport, kArity0, 0]);
builder.addStart(func.index);
diff --git a/test/mjsunit/wasm/test-wasm-module-builder.js b/test/mjsunit/wasm/test-wasm-module-builder.js
index 50797d0..969b550 100644
--- a/test/mjsunit/wasm/test-wasm-module-builder.js
+++ b/test/mjsunit/wasm/test-wasm-module-builder.js
@@ -12,7 +12,7 @@
(function BasicTest() {
var module = new WasmModuleBuilder();
module.addMemory(1, 2, false);
- module.addFunction("foo", [kAstI32])
+ module.addFunction("foo", kSig_i)
.addBody([kExprI8Const, 11])
.exportAs("blarg");
@@ -23,9 +23,9 @@
(function ImportTest() {
var module = new WasmModuleBuilder();
- var index = module.addImport("print", [kAstStmt, kAstI32]);
- module.addFunction("foo", [kAstStmt])
- .addBody([kExprCallImport, index, kExprI8Const, 13])
+ var index = module.addImport("print", makeSig_v_x(kAstI32));
+ module.addFunction("foo", kSig_v_v)
+ .addBody([kExprI8Const, 13, kExprCallImport, kArity1, index])
.exportAs("main");
var buffer = module.toBuffer(debug);
@@ -36,9 +36,9 @@
(function LocalsTest() {
var module = new WasmModuleBuilder();
- module.addFunction(undefined, [kAstI32, kAstI32])
+ module.addFunction(undefined, kSig_i_i)
.addLocals({i32_count: 1})
- .addBody([kExprSetLocal, 1, kExprGetLocal, 0])
+ .addBody([kExprGetLocal, 0, kExprSetLocal, 1])
.exportAs("main");
var buffer = module.toBuffer(debug);
@@ -58,9 +58,9 @@
for (p of types) {
var module = new WasmModuleBuilder();
- module.addFunction(undefined, [p.type, p.type])
+ module.addFunction(undefined, makeSig_r_x(p.type, p.type))
.addLocals(p.locals)
- .addBody([kExprSetLocal, 1, kExprGetLocal, 0])
+ .addBody([kExprGetLocal, 0, kExprSetLocal, 1])
.exportAs("main");
var buffer = module.toBuffer(debug);
@@ -72,10 +72,10 @@
(function CallTest() {
var module = new WasmModuleBuilder();
- module.addFunction("add", [kAstI32, kAstI32, kAstI32])
- .addBody([kExprI32Add, kExprGetLocal, 0, kExprGetLocal, 1]);
- module.addFunction("main", [kAstI32, kAstI32, kAstI32])
- .addBody([kExprCallFunction, 0, kExprGetLocal, 0, kExprGetLocal, 1])
+ module.addFunction("add", kSig_i_ii)
+ .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32Add]);
+ module.addFunction("main", kSig_i_ii)
+ .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprCallFunction, kArity2, 0])
.exportAs("main");
var instance = module.instantiate();
@@ -85,11 +85,11 @@
(function IndirectCallTest() {
var module = new WasmModuleBuilder();
- module.addFunction("add", [kAstI32, kAstI32, kAstI32])
- .addBody([kExprI32Add, kExprGetLocal, 0, kExprGetLocal, 1]);
- module.addFunction("main", [kAstI32, kAstI32, kAstI32, kAstI32])
- .addBody([kExprCallIndirect, 0, kExprGetLocal,
- 0, kExprGetLocal, 1, kExprGetLocal, 2])
+ module.addFunction("add", kSig_i_ii)
+ .addBody([kExprGetLocal, 0, kExprGetLocal, 1, kExprI32Add]);
+ module.addFunction("main", kSig_i_iii)
+ .addBody([kExprGetLocal,
+ 0, kExprGetLocal, 1, kExprGetLocal, 2, kExprCallIndirect, kArity2, 0])
.exportAs("main");
module.appendToFunctionTable([0]);
@@ -102,8 +102,8 @@
(function DataSegmentTest() {
var module = new WasmModuleBuilder();
module.addMemory(1, 1, false);
- module.addFunction("load", [kAstI32, kAstI32])
- .addBody([kExprI32LoadMem, 0, 0, kExprGetLocal, 0])
+ module.addFunction("load", kSig_i_i)
+ .addBody([kExprGetLocal, 0, kExprI32LoadMem, 0, 0])
.exportAs("load");
module.addDataSegment(0, [9, 9, 9, 9], true);
@@ -116,7 +116,7 @@
(function BasicTestWithUint8Array() {
var module = new WasmModuleBuilder();
module.addMemory(1, 2, false);
- module.addFunction("foo", [kAstI32])
+ module.addFunction("foo", kSig_i)
.addBody([kExprI8Const, 17])
.exportAs("blarg");
@@ -141,9 +141,9 @@
(function ImportTestTwoLevel() {
var module = new WasmModuleBuilder();
- var index = module.addImportWithModule("mod", "print", [kAstStmt, kAstI32]);
- module.addFunction("foo", [kAstStmt])
- .addBody([kExprCallImport, index, kExprI8Const, 19])
+ var index = module.addImportWithModule("mod", "print", makeSig_v_x(kAstI32));
+ module.addFunction("foo", kSig_v_v)
+ .addBody([kExprI8Const, 19, kExprCallImport, kArity1, index])
.exportAs("main");
var buffer = module.toBuffer(debug);
diff --git a/test/mjsunit/wasm/trap-location.js b/test/mjsunit/wasm/trap-location.js
new file mode 100644
index 0000000..5e3661d
--- /dev/null
+++ b/test/mjsunit/wasm/trap-location.js
@@ -0,0 +1,78 @@
+// 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: --expose-wasm
+
+load("test/mjsunit/wasm/wasm-constants.js");
+load("test/mjsunit/wasm/wasm-module-builder.js");
+
+// Collect the Callsite objects instead of just a string:
+Error.prepareStackTrace = function(error, frames) {
+ return frames;
+};
+
+var builder = new WasmModuleBuilder();
+
+var sig_index = builder.addSignature(kSig_i_v)
+
+// Build a function to resemble this code:
+// if (idx < 2) {
+// return load(-2 / idx);
+// } else if (idx == 2) {
+// unreachable;
+// } else {
+// return call_indirect(idx);
+// }
+// There are four different traps which are triggered by different input values:
+// (0) division by zero; (1) mem oob; (2) unreachable; (3) invalid call target
+// Each of them also has a different location where it traps.
+builder.addFunction("main", kSig_i_i)
+ .addBody([
+ // offset 1
+ kExprBlock,
+ kExprGetLocal, 0,
+ kExprI32Const, 2,
+ kExprI32LtU,
+ kExprIf,
+ // offset 8
+ kExprI32Const, 0x7e /* -2 */,
+ kExprGetLocal, 0,
+ kExprI32DivU,
+ // offset 13
+ kExprI32LoadMem, 0, 0,
+ kExprBr, 1, 1,
+ kExprEnd,
+ // offset 20
+ kExprGetLocal, 0,
+ kExprI32Const, 2,
+ kExprI32Eq,
+ kExprIf,
+ kExprUnreachable,
+ kExprEnd,
+ // offset 28
+ kExprGetLocal, 0,
+ kExprCallIndirect, kArity0, sig_index,
+ kExprEnd,
+ ])
+ .exportAs("main");
+
+var module = builder.instantiate();
+
+function testWasmTrap(value, reason, position) {
+ try {
+ module.exports.main(value);
+ fail("expected wasm exception");
+ } catch (e) {
+ assertEquals(kTrapMsgs[reason], e.message, "trap reason");
+ assertEquals(3, e.stack.length, "number of frames");
+ assertEquals(0, e.stack[0].getLineNumber(), "wasmFunctionIndex");
+ assertEquals(position, e.stack[0].getPosition(), "position");
+ }
+}
+
+// The actual tests:
+testWasmTrap(0, kTrapDivByZero, 12);
+testWasmTrap(1, kTrapMemOutOfBounds, 13);
+testWasmTrap(2, kTrapUnreachable, 26);
+testWasmTrap(3, kTrapFuncInvalid, 30);
diff --git a/test/mjsunit/wasm/unicode-validation.js b/test/mjsunit/wasm/unicode-validation.js
new file mode 100644
index 0000000..b2e4603
--- /dev/null
+++ b/test/mjsunit/wasm/unicode-validation.js
@@ -0,0 +1,121 @@
+// 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: --expose-wasm
+
+load("test/mjsunit/wasm/wasm-constants.js");
+load("test/mjsunit/wasm/wasm-module-builder.js");
+
+function toByteArray(s) {
+ var arr = [];
+ for (var i = 0; i < s.length; ++i) {
+ arr.push(s.charCodeAt(i) & 0xff);
+ }
+ return arr;
+}
+
+function toString(arr) {
+ if (typeof arr === "string") return arr;
+ var s = "";
+ for (var b of arr) s += String.fromCharCode(b);
+ return s;
+}
+
+function toUTF8(arr) {
+ if (typeof arr === "string" || arr === undefined) return arr;
+ return decodeURIComponent(escape(toString(arr)));
+}
+
+function isValidUtf8(arr) {
+ if (typeof arr === "string" || arr === undefined) return true;
+ try {
+ var s = toUTF8(arr);
+ for (var i = 0; i < s.length; ++i)
+ if ((s.charCodeAt(i) & 0xfffe) == 0xfffe)
+ return false;
+ return true;
+ } catch (e) {
+ if (e instanceof URIError) return false;
+ throw e;
+ }
+}
+
+function checkImportsAndExports(imported_module_name, imported_function_name,
+ internal_function_name, exported_function_name, shouldThrow) {
+ var builder = new WasmModuleBuilder();
+
+ builder.addImportWithModule(imported_module_name, imported_function_name,
+ kSig_v_v);
+
+ builder.addFunction(internal_function_name, kSig_v_v)
+ .addBody([kExprCallImport, kArity0, 0])
+ .exportAs(exported_function_name);
+
+ // sanity check: does javascript agree with out shouldThrow annotation?
+ assertEquals(shouldThrow,
+ !isValidUtf8(imported_module_name) ||
+ !isValidUtf8(imported_function_name) ||
+ !isValidUtf8(exported_function_name),
+ "JavaScript does not agree with our shouldThrow expectation");
+
+ if (!shouldThrow) {
+ imported_module_name = toUTF8(imported_module_name);
+ imported_function_name = toUTF8(imported_function_name);
+ }
+
+ var ffi = new Object();
+ if (imported_function_name === undefined) {
+ ffi[imported_module_name] = function() { };
+ } else {
+ ffi[imported_module_name] = new Object();
+ ffi[imported_module_name][imported_function_name] = function() { };
+ }
+
+ var hasThrown = true;
+ try {
+ builder.instantiate(ffi);
+ hasThrown = false;
+ } catch (err) {
+ if (!shouldThrow) print(err);
+ assertTrue(shouldThrow, "Should not throw error on valid names");
+ assertContains("UTF-8", err.toString());
+ }
+ assertEquals(shouldThrow, hasThrown,
+ "Should throw validation error on invalid names");
+}
+
+function checkImportedModuleName(name, shouldThrow) {
+ checkImportsAndExports(name, "imp", "func", undefined, shouldThrow);
+}
+
+function checkImportedFunctionName(name, shouldThrow) {
+ checkImportsAndExports("module", name, "func", "func", shouldThrow);
+}
+
+function checkExportedFunctionName(name, shouldThrow) {
+ checkImportsAndExports("module", "func", "func", name, shouldThrow);
+}
+
+function checkInternalFunctionName(name) {
+ checkImportsAndExports("module", "func", name, "func", false);
+}
+
+function checkAll(name, shouldThrow) {
+ checkImportedModuleName(name, shouldThrow);
+ checkImportedFunctionName(name, shouldThrow);
+ checkExportedFunctionName(name, shouldThrow);
+ checkInternalFunctionName(name);
+}
+
+checkAll("ascii", false);
+checkAll("some math: (½)² = ¼", false);
+checkAll("中国历史系列条目\n北", false);
+checkAll(toByteArray("\xef\xb7\x8f"), false);
+checkAll(toByteArray("a\xc2\x81\xe1\x80\xbf\xf1\x80\xa0\xbf"), false);
+checkAll(toByteArray("\xff"), true);
+checkAll(toByteArray("\xed\xa0\x8f"), true); // surrogate code points
+checkAll(toByteArray("\xe0\x82\x80"), true); // overlong sequence
+checkAll(toByteArray("\xf4\x90\x80\x80"), true); // beyond limit: U+110000
+checkAll(toByteArray("\xef\xbf\xbe"), true); // non-character; U+FFFE
+checkAll(toByteArray("with\x00null"), false);
diff --git a/test/mjsunit/wasm/unreachable.js b/test/mjsunit/wasm/unreachable.js
index 3e2dffb..d77b53e 100644
--- a/test/mjsunit/wasm/unreachable.js
+++ b/test/mjsunit/wasm/unreachable.js
@@ -9,7 +9,7 @@
var main = (function () {
var builder = new WasmModuleBuilder();
- builder.addFunction("main", [kAstStmt])
+ builder.addFunction("main", kSig_v_v)
.addBody([kExprUnreachable])
.exportAs("main");
@@ -23,4 +23,4 @@
print("correctly caught: " + e);
exception = e;
}
-assertEquals("unreachable", exception);
+assertEquals("unreachable", exception.message);
diff --git a/test/mjsunit/wasm/verify-function-simple.js b/test/mjsunit/wasm/verify-function-simple.js
index aa5c676..31c23a6 100644
--- a/test/mjsunit/wasm/verify-function-simple.js
+++ b/test/mjsunit/wasm/verify-function-simple.js
@@ -8,9 +8,9 @@
try {
var data = bytes(
- 0, kAstStmt, // signature
- kDeclNoLocals, // --
- kExprNop // body
+ kWasmFunctionTypeForm, 0, kAstStmt, // signature
+ kDeclNoLocals, // --
+ kExprNop // body
);
Wasm.verifyFunction(data);
@@ -23,9 +23,9 @@
var threw = false;
try {
var data = bytes(
- 0, kAstI32, // signature
- kDeclNoLocals, // --
- kExprBlock, 2, kExprNop, kExprNop // body
+ kWasmFunctionTypeForm, 0, 1, kAstI32, // signature
+ kDeclNoLocals, // --
+ kExprBlock, kExprNop, kExprNop, kExprEnd // body
);
Wasm.verifyFunction(data);
diff --git a/test/mjsunit/wasm/wasm-constants.js b/test/mjsunit/wasm/wasm-constants.js
index cc620bb..389383e 100644
--- a/test/mjsunit/wasm/wasm-constants.js
+++ b/test/mjsunit/wasm/wasm-constants.js
@@ -21,7 +21,7 @@
var kWasmH2 = 0x73;
var kWasmH3 = 0x6d;
-var kWasmV0 = 10;
+var kWasmV0 = 11;
var kWasmV1 = 0;
var kWasmV2 = 0;
var kWasmV3 = 0;
@@ -65,10 +65,16 @@
var kDeclFunctionBodies = 0x0b;
var kDeclNames = 0x0c;
+var kArity0 = 0;
+var kArity1 = 1;
+var kArity2 = 2;
+var kArity3 = 3;
+var kWasmFunctionTypeForm = 0x40;
+
var section_names = [
- "memory", "signatures", "functions", "globals", "data_segments",
- "function_table", "end", "start_function", "import_table", "export_table",
- "function_signatures", "function_bodies", "names"];
+ "memory", "type", "old_function", "global", "data",
+ "table", "end", "start", "import", "export",
+ "function", "code", "name"];
// Function declaration flags
var kDeclFunctionName = 0x01;
@@ -83,31 +89,60 @@
var kAstF32 = 3;
var kAstF64 = 4;
+// Useful signatures
+var kSig_i = [0, 1, kAstI32];
+var kSig_d = [0, 1, kAstF64];
+var kSig_i_i = [1, kAstI32, 1, kAstI32];
+var kSig_i_ii = [2, kAstI32, kAstI32, 1, kAstI32];
+var kSig_i_iii = [3, kAstI32, kAstI32, kAstI32, 1, kAstI32];
+var kSig_d_dd = [2, kAstF64, kAstF64, 1, kAstF64];
+var kSig_l_ll = [2, kAstI64, kAstI64, 1, kAstI64];
+var kSig_i_dd = [2, kAstF64, kAstF64, 1, kAstI32];
+var kSig_v_v = [0, 0];
+var kSig_i_v = [0, 1, kAstI32];
+
+function makeSig_v_xx(x) {
+ return [2, x, x, 0];
+}
+
+function makeSig_v_x(x) {
+ return [1, x, 0];
+}
+
+function makeSig_r_xx(r, x) {
+ return [2, x, x, 1, r];
+}
+
+function makeSig_r_x(r, x) {
+ return [1, x, 1, r];
+}
+
// Opcodes
var kExprNop = 0x00;
var kExprBlock = 0x01;
var kExprLoop = 0x02;
var kExprIf = 0x03;
-var kExprIfElse = 0x04;
+var kExprElse = 0x04;
var kExprSelect = 0x05;
var kExprBr = 0x06;
var kExprBrIf = 0x07;
-var kExprTableSwitch = 0x08;
-var kExprReturn = 0x14;
-var kExprUnreachable = 0x15;
+var kExprBrTable = 0x08;
+var kExprReturn = 0x09;
+var kExprUnreachable = 0x0a;
+var kExprEnd = 0x0f;
-var kExprI8Const = 0x09;
-var kExprI32Const = 0x0a;
-var kExprI64Const = 0x0b;
-var kExprF64Const = 0x0c;
-var kExprF32Const = 0x0d;
-var kExprGetLocal = 0x0e;
-var kExprSetLocal = 0x0f;
-var kExprLoadGlobal = 0x10;
-var kExprStoreGlobal = 0x11;
-var kExprCallFunction = 0x12;
-var kExprCallIndirect = 0x13;
-var kExprCallImport = 0x1F;
+var kExprI32Const = 0x10;
+var kExprI64Const = 0x11;
+var kExprF64Const = 0x12;
+var kExprF32Const = 0x13;
+var kExprGetLocal = 0x14;
+var kExprSetLocal = 0x15;
+var kExprCallFunction = 0x16;
+var kExprCallIndirect = 0x17;
+var kExprCallImport = 0x18;
+var kExprI8Const = 0xcb;
+var kExprLoadGlobal = 0xcc;
+var kExprStoreGlobal = 0xcd;
var kExprI32LoadMem8S = 0x20;
var kExprI32LoadMem8U = 0x21;
@@ -290,8 +325,8 @@
}
threwException = false;
} catch (e) {
- assertEquals("string", typeof e);
- assertEquals(kTrapMsgs[trap], e);
+ assertEquals("object", typeof e);
+ assertEquals(kTrapMsgs[trap], e.message);
// Success.
return;
}
diff --git a/test/mjsunit/wasm/wasm-module-builder.js b/test/mjsunit/wasm/wasm-module-builder.js
index e1d9963..bfc4460 100644
--- a/test/mjsunit/wasm/wasm-module-builder.js
+++ b/test/mjsunit/wasm/wasm-module-builder.js
@@ -53,7 +53,7 @@
return this;
}
-// Add a signature; format is [rettype, param0, param1, ...]
+// Add a signature; format is [param_count, param0, param1, ..., retcount, ret0]
WasmModuleBuilder.prototype.addSignature = function(sig) {
// TODO: canonicalize signatures?
this.signatures.push(sig);
@@ -75,9 +75,7 @@
}
WasmModuleBuilder.prototype.addImport = function(name, sig) {
- var sig_index = (typeof sig) == "number" ? sig : this.addSignature(sig);
- this.imports.push({module: name, name: undefined, sig_index: sig_index});
- return this.imports.length - 1;
+ this.addImportWithModule(name, undefined, sig);
}
WasmModuleBuilder.prototype.addDataSegment = function(addr, data, init) {
@@ -107,9 +105,19 @@
}
function emit_string(bytes, string) {
- emit_varint(bytes, string.length);
- for (var i = 0; i < string.length; i++) {
- emit_u8(bytes, string.charCodeAt(i));
+ // When testing illegal names, we pass a byte array directly.
+ if (string instanceof Array) {
+ emit_varint(bytes, string.length);
+ emit_bytes(bytes, string);
+ return;
+ }
+
+ // This is the hacky way to convert a JavaScript scring to a UTF8 encoded
+ // string only containing single-byte characters.
+ var string_utf8 = unescape(encodeURIComponent(string));
+ emit_varint(bytes, string_utf8.length);
+ for (var i = 0; i < string_utf8.length; i++) {
+ emit_u8(bytes, string_utf8.charCodeAt(i));
}
}
@@ -132,12 +140,14 @@
}
function emit_section(bytes, section_code, content_generator) {
- // Start the section in a temporary buffer: its full length isn't know yet.
+ // Emit section name.
+ emit_string(bytes, section_names[section_code]);
+ // Emit the section to a temporary buffer: its full length isn't know yet.
var tmp_bytes = [];
- emit_string(tmp_bytes, section_names[section_code]);
content_generator(tmp_bytes);
- // Now that we know the section length, emit it and copy the section.
+ // Emit section length.
emit_varint(bytes, tmp_bytes.length);
+ // Copy the temporary buffer.
Array.prototype.push.apply(bytes, tmp_bytes);
}
@@ -149,24 +159,13 @@
var wasm = this;
- // Add memory section
- if (wasm.memory != undefined) {
- if (debug) print("emitting memory @ " + bytes.length);
- emit_section(bytes, kDeclMemory, function(bytes) {
- emit_varint(bytes, wasm.memory.min);
- emit_varint(bytes, wasm.memory.max);
- emit_u8(bytes, wasm.memory.exp ? 1 : 0);
- });
- }
-
// Add signatures section
if (wasm.signatures.length > 0) {
if (debug) print("emitting signatures @ " + bytes.length);
emit_section(bytes, kDeclSignatures, function(bytes) {
emit_varint(bytes, wasm.signatures.length);
for (sig of wasm.signatures) {
- var params = sig.length - 1;
- emit_varint(bytes, params);
+ emit_u8(bytes, kWasmFunctionTypeForm);
for (var j = 0; j < sig.length; j++) {
emit_u8(bytes, sig[j]);
}
@@ -187,7 +186,7 @@
});
}
- // Add functions section
+ // Add functions declarations
var names = false;
var exports = 0;
if (wasm.functions.length > 0) {
@@ -206,6 +205,54 @@
}
});
+ }
+
+ // Add function table.
+ if (wasm.function_table.length > 0) {
+ if (debug) print("emitting function table @ " + bytes.length);
+ emit_section(bytes, kDeclFunctionTable, function(bytes) {
+ emit_varint(bytes, wasm.function_table.length);
+ for (index of wasm.function_table) {
+ emit_varint(bytes, index);
+ }
+ });
+ }
+
+ // Add memory section
+ if (wasm.memory != undefined) {
+ if (debug) print("emitting memory @ " + bytes.length);
+ emit_section(bytes, kDeclMemory, function(bytes) {
+ emit_varint(bytes, wasm.memory.min);
+ emit_varint(bytes, wasm.memory.max);
+ emit_u8(bytes, wasm.memory.exp ? 1 : 0);
+ });
+ }
+
+
+ // Add export table.
+ if (exports > 0) {
+ if (debug) print("emitting exports @ " + bytes.length);
+ emit_section(bytes, kDeclExportTable, function(bytes) {
+ emit_varint(bytes, exports);
+ for (func of wasm.functions) {
+ for (exp of func.exports) {
+ emit_varint(bytes, func.index);
+ emit_string(bytes, exp);
+ }
+ }
+ });
+ }
+
+ // Add start function section.
+ if (wasm.start_index != undefined) {
+ if (debug) print("emitting start function @ " + bytes.length);
+ emit_section(bytes, kDeclStartFunction, function(bytes) {
+ emit_varint(bytes, wasm.start_index);
+ });
+ }
+
+ // Add function bodies.
+ if (wasm.functions.length > 0) {
// emit function bodies
if (debug) print("emitting function bodies @ " + bytes.length);
emit_section(bytes, kDeclFunctionBodies, function(bytes) {
@@ -244,50 +291,7 @@
});
}
- // emit function names
- if (has_names) {
- if (debug) print("emitting names @ " + bytes.length);
- emit_section(bytes, kDeclNames, function(bytes) {
- emit_varint(bytes, wasm.functions.length);
- for (func of wasm.functions) {
- var name = func.name == undefined ? "" : func.name;
- emit_string(bytes, name);
- emit_u8(bytes, 0); // local names count == 0
- }
- });
- }
-
- // Add start function section.
- if (wasm.start_index != undefined) {
- if (debug) print("emitting start function @ " + bytes.length);
- emit_section(bytes, kDeclStartFunction, function(bytes) {
- emit_varint(bytes, wasm.start_index);
- });
- }
-
- if (wasm.function_table.length > 0) {
- if (debug) print("emitting function table @ " + bytes.length);
- emit_section(bytes, kDeclFunctionTable, function(bytes) {
- emit_varint(bytes, wasm.function_table.length);
- for (index of wasm.function_table) {
- emit_varint(bytes, index);
- }
- });
- }
-
- if (exports > 0) {
- if (debug) print("emitting exports @ " + bytes.length);
- emit_section(bytes, kDeclExportTable, function(bytes) {
- emit_varint(bytes, exports);
- for (func of wasm.functions) {
- for (exp of func.exports) {
- emit_varint(bytes, func.index);
- emit_string(bytes, exp);
- }
- }
- });
- }
-
+ // Add data segments.
if (wasm.data_segments.length > 0) {
if (debug) print("emitting data segments @ " + bytes.length);
emit_section(bytes, kDeclDataSegments, function(bytes) {
@@ -300,12 +304,25 @@
});
}
- // Emit any explicitly added sections
+ // Add any explicitly added sections
for (exp of wasm.explicit) {
if (debug) print("emitting explicit @ " + bytes.length);
emit_bytes(bytes, exp);
}
+ // Add function names.
+ if (has_names) {
+ if (debug) print("emitting names @ " + bytes.length);
+ emit_section(bytes, kDeclNames, function(bytes) {
+ emit_varint(bytes, wasm.functions.length);
+ for (func of wasm.functions) {
+ var name = func.name == undefined ? "" : func.name;
+ emit_string(bytes, name);
+ emit_u8(bytes, 0); // local names count == 0
+ }
+ });
+ }
+
// End the module.
if (debug) print("emitting end @ " + bytes.length);
emit_section(bytes, kDeclEnd, function(bytes) {});
diff --git a/test/mjsunit/wasm/wasm-object-api.js b/test/mjsunit/wasm/wasm-object-api.js
index 2f25c66..96088b8 100644
--- a/test/mjsunit/wasm/wasm-object-api.js
+++ b/test/mjsunit/wasm/wasm-object-api.js
@@ -10,3 +10,4 @@
assertEquals("function", typeof Wasm.verifyFunction);
assertEquals("function", typeof Wasm.instantiateModule);
assertEquals("function", typeof Wasm.instantiateModuleFromAsm);
+assertFalse(undefined == Wasm.experimentalVersion);