Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Flags: --expose-wasm | 5 // Flags: --expose-wasm |
| 6 | 6 |
| 7 load("test/mjsunit/wasm/wasm-constants.js"); | 7 load("test/mjsunit/wasm/wasm-constants.js"); |
| 8 load("test/mjsunit/wasm/wasm-module-builder.js"); | 8 load("test/mjsunit/wasm/wasm-module-builder.js"); |
| 9 | 9 |
| 10 function AddFunctions(builder) { | 10 function AddFunctions(builder) { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 23 ]); | 23 ]); |
| 24 let sub = builder.addFunction("sub", sig_index) | 24 let sub = builder.addFunction("sub", sig_index) |
| 25 .addBody([ | 25 .addBody([ |
| 26 kExprGetLocal, 0, // -- | 26 kExprGetLocal, 0, // -- |
| 27 kExprGetLocal, 1, // -- | 27 kExprGetLocal, 1, // -- |
| 28 kExprI32Sub // -- | 28 kExprI32Sub // -- |
| 29 ]); | 29 ]); |
| 30 return {mul: mul, add: add, sub: sub}; | 30 return {mul: mul, add: add, sub: sub}; |
| 31 } | 31 } |
| 32 | 32 |
| 33 function js_div(a, b) { return (a / b) | 0; } | |
| 34 | |
| 33 (function ExportedTableTest() { | 35 (function ExportedTableTest() { |
| 34 print("ExportedTableTest..."); | 36 print("ExportedTableTest..."); |
| 35 | 37 |
| 36 let builder = new WasmModuleBuilder(); | 38 let builder = new WasmModuleBuilder(); |
| 37 | 39 |
| 38 let d = builder.addImport("js_div", kSig_i_ii); | 40 let d = builder.addImport("js_div", kSig_i_ii); |
| 39 let f = AddFunctions(builder); | 41 let f = AddFunctions(builder); |
| 40 builder.addFunction("main", kSig_i_ii) | 42 builder.addFunction("main", kSig_i_ii) |
| 41 .addBody([ | 43 .addBody([ |
| 42 kExprI32Const, 33, // -- | 44 kExprI32Const, 33, // -- |
| 43 kExprGetLocal, 0, // -- | 45 kExprGetLocal, 0, // -- |
| 44 kExprGetLocal, 1, // -- | 46 kExprGetLocal, 1, // -- |
| 45 kExprCallIndirect, 0, kTableZero]) // -- | 47 kExprCallIndirect, 0, kTableZero]) // -- |
| 46 .exportAs("main"); | 48 .exportAs("main"); |
| 47 | 49 |
| 48 f.add.exportAs("blarg"); | 50 f.add.exportAs("blarg"); |
| 49 | 51 |
| 50 builder.setFunctionTableLength(10); | 52 builder.setFunctionTableLength(10); |
| 51 let g = builder.addImportedGlobal("base", undefined, kAstI32); | 53 let g = builder.addImportedGlobal("base", undefined, kAstI32); |
| 52 builder.addFunctionTableInit(g, true, [f.mul.index, f.add.index, | 54 builder.addFunctionTableInit(g, true, [f.mul.index, f.add.index, |
| 53 f.sub.index, | 55 f.sub.index, |
| 54 d]); | 56 d]); |
| 55 builder.addExportOfKind("table", kExternalTable, 0); | 57 builder.addExportOfKind("table", kExternalTable, 0); |
| 56 | 58 |
| 57 let module = new WebAssembly.Module(builder.toBuffer()); | 59 let module = new WebAssembly.Module(builder.toBuffer()); |
| 58 | 60 |
| 59 function js_div(a, b) { return (a / b) | 0; } | |
| 60 | |
| 61 for (let i = 0; i < 5; i++) { | 61 for (let i = 0; i < 5; i++) { |
| 62 print(" base = " + i); | 62 print(" base = " + i); |
| 63 let instance = new WebAssembly.Instance(module, {base: i, js_div: js_div}); | 63 let instance = new WebAssembly.Instance(module, {base: i, js_div: js_div}); |
| 64 main = instance.exports.main; | 64 main = instance.exports.main; |
| 65 let table = instance.exports.table; | 65 let table = instance.exports.table; |
| 66 assertTrue(table instanceof WebAssembly.Table); | 66 assertTrue(table instanceof WebAssembly.Table); |
| 67 assertEquals(10, table.length); | 67 assertEquals(10, table.length); |
| 68 for (let j = 0; j < i; j++) { | 68 for (let j = 0; j < i; j++) { |
| 69 assertSame(null, table.get(j)); | 69 assertSame(null, table.get(j)); |
| 70 } | 70 } |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 93 for (let j = i + 4; j < 10; j++) { | 93 for (let j = i + 4; j < 10; j++) { |
| 94 assertSame(null, table.get(j)); | 94 assertSame(null, table.get(j)); |
| 95 } | 95 } |
| 96 | 96 |
| 97 assertEquals(-33, mul(-11, 3)); | 97 assertEquals(-33, mul(-11, 3)); |
| 98 assertEquals(4444444, add(3333333, 1111111)); | 98 assertEquals(4444444, add(3333333, 1111111)); |
| 99 assertEquals(-9999, sub(1, 10000)); | 99 assertEquals(-9999, sub(1, 10000)); |
| 100 assertEquals(-44, exp_div(-88.1, 2)); | 100 assertEquals(-44, exp_div(-88.1, 2)); |
| 101 } | 101 } |
| 102 })(); | 102 })(); |
| 103 | |
| 104 | |
| 105 (function ImportedTableTest() { | |
| 106 let kTableSize = 10; | |
| 107 print("ImportedTableTest..."); | |
| 108 var builder = new WasmModuleBuilder(); | |
| 109 | |
| 110 let d = builder.addImport("js_div", kSig_i_ii); | |
| 111 let f = AddFunctions(builder); | |
| 112 builder.setFunctionTableLength(kTableSize); | |
| 113 let g = builder.addImportedGlobal("base", undefined, kAstI32); | |
| 114 builder.addFunctionTableInit(g, true, [f.mul.index, f.add.index, | |
| 115 f.sub.index, | |
| 116 d]); | |
| 117 builder.addExportOfKind("table", kExternalTable, 0); | |
| 118 | |
| 119 let m1 = new WebAssembly.Module(builder.toBuffer()); | |
| 120 | |
| 121 var builder = new WasmModuleBuilder(); | |
| 122 | |
| 123 builder.addImportedTable("table", undefined, kTableSize, kTableSize); | |
| 124 builder.addFunction("main", kSig_i_ii) | |
| 125 .addBody([ | |
| 126 kExprI32Const, 33, // -- | |
| 127 kExprGetLocal, 0, // -- | |
| 128 kExprGetLocal, 1, // -- | |
| 129 kExprCallIndirect, 0, kTableZero]) // -- | |
| 130 .exportAs("main"); | |
| 131 | |
| 132 let m2 = new WebAssembly.Module(builder.toBuffer()); | |
| 133 | |
| 134 // Run 5 trials at different table bases. | |
| 135 for (let i = 0; i < 5; i++) { | |
| 136 print(" base = " + i); | |
| 137 let i1 = new WebAssembly.Instance(m1, {base: i, js_div: js_div}); | |
| 138 let table = i1.exports.table; | |
| 139 assertEquals(10, table.length); | |
| 140 let i2 = new WebAssembly.Instance(m2, {table: table}); | |
| 141 let main = i2.exports.main; | |
| 142 | |
| 143 for (var j = 0; j < i; j++) { | |
| 144 assertThrows(() => main(0, j)); | |
| 145 assertSame(null, table.get(j)); | |
| 146 } | |
| 147 | |
| 148 // mul | |
| 149 assertEquals("function", typeof table.get(i+0)); | |
| 150 assertEquals(0, main(0, i+0)); | |
| 151 assertEquals(66, main(2, i+0)); | |
| 152 | |
| 153 // add | |
| 154 assertEquals("function", typeof table.get(i+1)); | |
| 155 assertEquals(33, main(0, i+1)); | |
| 156 assertEquals(38, main(5, i+1)); | |
| 157 | |
| 158 // sub | |
| 159 assertEquals("function", typeof table.get(i+2)); | |
| 160 assertEquals(32, main(1, i+2)); | |
| 161 assertEquals(28, main(5, i+2)); | |
| 162 | |
| 163 // div | |
| 164 assertEquals("function", typeof table.get(i+3)); | |
| 165 assertEquals(8, main(4, i+3)); | |
| 166 assertEquals(3, main(11, i+3)); | |
| 167 | |
| 168 for (var j = i + 4; j < (kTableSize + 5); j++) { | |
| 169 assertThrows(x => main(0, j)); | |
| 170 if (j < kTableSize) assertSame(null, table.get(j)); | |
| 171 } | |
| 172 } | |
| 173 })(); | |
| 174 | |
| 175 (function ImportedTableTest() { | |
| 176 let kTableSize = 10; | |
| 177 print("ManualTableTest..."); | |
| 178 | |
| 179 var builder = new WasmModuleBuilder(); | |
| 180 | |
| 181 let d = builder.addImport("js_div", kSig_i_ii); | |
| 182 builder.addImportedTable("table", undefined, kTableSize, kTableSize); | |
| 183 let g = builder.addImportedGlobal("base", undefined, kAstI32); | |
| 184 let f = AddFunctions(builder); | |
| 185 builder.addFunctionTableInit(g, true, [f.mul.index, f.add.index, | |
| 186 f.sub.index, | |
| 187 d]); | |
| 188 builder.addFunction("main", kSig_i_ii) | |
| 189 .addBody([ | |
| 190 kExprI32Const, 55, // -- | |
| 191 kExprGetLocal, 0, // -- | |
| 192 kExprGetLocal, 1, // -- | |
| 193 kExprCallIndirect, 0, kTableZero]) // -- | |
| 194 .exportAs("main"); | |
| 195 | |
| 196 let m2 = new WebAssembly.Module(builder.toBuffer()); | |
| 197 | |
| 198 // Run 5 trials at different table bases. | |
| 199 for (let i = 0; i < 5; i++) { | |
| 200 print(" base = " + i); | |
| 201 let table = new WebAssembly.Table({element: "anyfunc", initial: kTableSize}) ; | |
|
bradnelson
2016/10/28 16:59:01
>80
titzer
2016/10/28 17:29:09
Done.
| |
| 202 assertEquals(10, table.length); | |
| 203 let i2 = new WebAssembly.Instance(m2, {base: i, table: table, js_div: js_div }); | |
|
bradnelson
2016/10/28 16:59:01
>80
titzer
2016/10/28 17:29:09
Done.
| |
| 204 let main = i2.exports.main; | |
| 205 | |
| 206 for (var j = 0; j < i; j++) { | |
| 207 assertThrows(() => main(0, j)); | |
| 208 assertSame(null, table.get(j)); | |
| 209 } | |
| 210 | |
| 211 // mul | |
| 212 assertEquals("function", typeof table.get(i+0)); | |
| 213 assertEquals(0, main(0, i+0)); | |
| 214 assertEquals(110, main(2, i+0)); | |
| 215 | |
| 216 // add | |
| 217 assertEquals("function", typeof table.get(i+1)); | |
| 218 assertEquals(55, main(0, i+1)); | |
| 219 assertEquals(60, main(5, i+1)); | |
| 220 | |
| 221 // sub | |
| 222 assertEquals("function", typeof table.get(i+2)); | |
| 223 assertEquals(54, main(1, i+2)); | |
| 224 assertEquals(50, main(5, i+2)); | |
| 225 | |
| 226 // div | |
| 227 assertEquals("function", typeof table.get(i+3)); | |
| 228 assertEquals(13, main(4, i+3)); | |
| 229 assertEquals(5, main(11, i+3)); | |
| 230 | |
| 231 for (var j = i + 4; j < (kTableSize + 5); j++) { | |
| 232 assertThrows(x => main(0, j)); | |
| 233 if (j < kTableSize) assertSame(null, table.get(j)); | |
| 234 } | |
| 235 } | |
| 236 })(); | |
| 237 | |
| 238 | |
| 239 (function CumulativeTest() { | |
| 240 print("CumulativeTest..."); | |
| 241 | |
| 242 let kTableSize = 10; | |
| 243 let table = new WebAssembly.Table({element: "anyfunc", initial: 10}); | |
| 244 | |
| 245 var builder = new WasmModuleBuilder(); | |
| 246 | |
| 247 builder.addImportedTable("table", undefined, kTableSize, kTableSize); | |
| 248 let g = builder.addImportedGlobal("base", undefined, kAstI32); | |
| 249 let sig_index = builder.addType(kSig_i_v); | |
| 250 builder.addFunction("g", sig_index) | |
| 251 .addBody([ | |
| 252 kExprGetGlobal, g | |
| 253 ]); | |
| 254 builder.addFunction("main", kSig_i_ii) | |
| 255 .addBody([ | |
| 256 kExprGetLocal, 0, | |
| 257 kExprCallIndirect, sig_index, kTableZero]) // -- | |
| 258 .exportAs("main"); | |
| 259 builder.addFunctionTableInit(g, true, [g]); | |
| 260 | |
| 261 let module = new WebAssembly.Module(builder.toBuffer()); | |
| 262 | |
| 263 for (var i = 0; i < kTableSize; i++) { | |
| 264 print(" base = " + i); | |
| 265 let instance = new WebAssembly.Instance(module, {base: i, table: table}); | |
| 266 | |
| 267 for (var j = 0; j < kTableSize; j++) { | |
| 268 let func = table.get(j); | |
| 269 if (j > i) { | |
| 270 assertSame(null, func); | |
| 271 assertTraps(kTrapFuncSigMismatch, () => instance.exports.main(j)); | |
| 272 } else { | |
| 273 assertEquals("function", typeof func); | |
| 274 assertEquals(j, func()); | |
| 275 assertEquals(j, instance.exports.main(j)); | |
| 276 } | |
| 277 } | |
| 278 } | |
| 279 })(); | |
| 280 | |
| 281 (function TwoWayTest() { | |
| 282 print("TwoWayTest..."); | |
| 283 let kTableSize = 3; | |
| 284 | |
| 285 // Module {m1} defines the table and exports it. | |
| 286 var builder = new WasmModuleBuilder(); | |
| 287 builder.addType(kSig_i_i); | |
| 288 builder.addType(kSig_i_ii); | |
| 289 var sig_index1 = builder.addType(kSig_i_v); | |
| 290 var f1 = builder.addFunction("f1", sig_index1) | |
| 291 .addBody([kExprI32Const, 11]); | |
| 292 | |
| 293 builder.addFunction("main", kSig_i_ii) | |
| 294 .addBody([ | |
| 295 kExprGetLocal, 0, // -- | |
| 296 kExprCallIndirect, sig_index1, kTableZero]) // -- | |
| 297 .exportAs("main"); | |
| 298 | |
| 299 builder.setFunctionTableLength(kTableSize); | |
| 300 builder.addFunctionTableInit(0, false, [f1.index]); | |
| 301 builder.addExportOfKind("table", kExternalTable, 0); | |
| 302 | |
| 303 var m1 = new WebAssembly.Module(builder.toBuffer()); | |
| 304 | |
| 305 // Module {m2} imports the table and adds {f2}. | |
| 306 var builder = new WasmModuleBuilder(); | |
| 307 builder.addType(kSig_i_ii); | |
| 308 var sig_index2 = builder.addType(kSig_i_v); | |
| 309 var f2 = builder.addFunction("f2", sig_index2) | |
| 310 .addBody([kExprI32Const, 22]); | |
| 311 | |
| 312 builder.addFunction("main", kSig_i_ii) | |
| 313 .addBody([ | |
| 314 kExprGetLocal, 0, // -- | |
| 315 kExprCallIndirect, sig_index2, kTableZero]) // -- | |
| 316 .exportAs("main"); | |
| 317 | |
| 318 builder.setFunctionTableLength(kTableSize); | |
| 319 builder.addFunctionTableInit(1, false, [f2.index]); | |
| 320 builder.addImportedTable("table", undefined, kTableSize, kTableSize); | |
| 321 | |
| 322 var m2 = new WebAssembly.Module(builder.toBuffer()); | |
| 323 | |
| 324 assertFalse(sig_index1 == sig_index2); | |
| 325 | |
| 326 var i1 = new WebAssembly.Instance(m1); | |
| 327 var i2 = new WebAssembly.Instance(m2, {table: i1.exports.table}); | |
| 328 | |
| 329 assertEquals(11, i1.exports.main(0)); | |
| 330 assertEquals(11, i2.exports.main(0)); | |
| 331 | |
| 332 assertEquals(22, i1.exports.main(1)); | |
| 333 assertEquals(22, i2.exports.main(1)); | |
| 334 | |
| 335 assertThrows(() => i1.exports.main(2)); | |
| 336 assertThrows(() => i2.exports.main(2)); | |
| 337 assertThrows(() => i1.exports.main(3)); | |
| 338 assertThrows(() => i2.exports.main(3)); | |
| 339 | |
| 340 })(); | |
| 341 | |
| 342 // TODO(titzer): a test that all instances using a table get updated | |
|
bradnelson
2016/10/28 16:59:01
Also one for import table size doesn't match initi
titzer
2016/10/28 17:29:09
Done.
| |
| 343 // (would fail at the moment). | |
| 344 // TODO(titzer): add a test for signature canonicalization across modules. | |
| OLD | NEW |