binary.js (21756B)
1 load(libdir + "wasm-binary.js"); 2 3 const { extractStackFrameFunction } = WasmHelpers; 4 5 const { Module, RuntimeError, CompileError } = WebAssembly; 6 7 const magicError = /failed to match magic number/; 8 const unknownSection = /expected custom section/; 9 10 function sectionError(section) { 11 return RegExp(`failed to start ${section} section`); 12 } 13 14 function versionError(actual) { 15 var expect = encodingVersion; 16 var str = `binary version 0x${actual.toString(16)} does not match expected version 0x${expect.toString(16)}`; 17 return RegExp(str); 18 } 19 20 const U32MAX_LEB = [255, 255, 255, 255, 15]; 21 22 const wasmEval = (code, imports) => new WebAssembly.Instance(new Module(code), imports).exports; 23 24 assertErrorMessage(() => wasmEval(toU8([])), CompileError, magicError); 25 assertErrorMessage(() => wasmEval(toU8([42])), CompileError, magicError); 26 assertErrorMessage(() => wasmEval(toU8([magic0, magic1, magic2])), CompileError, magicError); 27 assertErrorMessage(() => wasmEval(toU8([1,2,3,4])), CompileError, magicError); 28 assertErrorMessage(() => wasmEval(toU8([magic0, magic1, magic2, magic3])), CompileError, versionError(0x6d736100)); 29 assertErrorMessage(() => wasmEval(toU8([magic0, magic1, magic2, magic3, 1])), CompileError, versionError(0x6d736100)); 30 assertErrorMessage(() => wasmEval(toU8([magic0, magic1, magic2, magic3, ver0])), CompileError, versionError(0x6d736100)); 31 assertErrorMessage(() => wasmEval(toU8([magic0, magic1, magic2, magic3, ver0, ver1, ver2])), CompileError, versionError(0x6d736100)); 32 33 var o = wasmEval(toU8(moduleHeaderThen())); 34 assertEq(Object.getOwnPropertyNames(o).length, 0); 35 36 // shared array buffer is not supported as a buffer source for compilation 37 if (globalThis.SharedArrayBuffer) { 38 assertErrorMessage(() => wasmEval(toSharedU8(moduleHeaderThen())), TypeError, /first argument must be an ArrayBuffer/); 39 } 40 41 // unfinished known sections 42 assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(typeId))), CompileError, sectionError("type")); 43 assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(importId))), CompileError, sectionError("import")); 44 assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(functionId))), CompileError, sectionError("function")); 45 assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(tableId))), CompileError, sectionError("table")); 46 assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(memoryId))), CompileError, sectionError("memory")); 47 assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(globalId))), CompileError, sectionError("global")); 48 assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(exportId))), CompileError, sectionError("export")); 49 assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(startId))), CompileError, sectionError("start")); 50 assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(elemId))), CompileError, sectionError("elem")); 51 assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(codeId))), CompileError, sectionError("code")); 52 assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(dataId))), CompileError, sectionError("data")); 53 54 // unknown sections are unconditionally rejected 55 assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(37))), CompileError, unknownSection); 56 assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(37, 0))), CompileError, unknownSection); 57 assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(37, 1, 0))), CompileError, unknownSection); 58 59 // user sections have special rules 60 assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(0))), CompileError, sectionError("custom")); // no length 61 assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(0, 0))), CompileError, sectionError("custom")); // no id 62 assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(0, 0, 0))), CompileError, sectionError("custom")); // payload too small to have id length 63 assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(0, 1, 1))), CompileError, sectionError("custom")); // id not present 64 assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(0, 1, 1, 65))), CompileError, sectionError("custom")); // id length doesn't fit in section 65 assertErrorMessage(() => wasmEval(toU8(moduleHeaderThen(0, 1, 0, 0))), CompileError, sectionError("custom")); // second, unfinished custom section 66 wasmEval(toU8(moduleHeaderThen(0, 1, 0))); // empty id 67 wasmEval(toU8(moduleHeaderThen(0, 1, 0, 0, 1, 0))); // 2x empty id 68 wasmEval(toU8(moduleHeaderThen(0, 2, 1, 65))); // id = "A" 69 70 const v2vSig = {args:[], ret:VoidCode}; 71 const v2vSigSection = sigSection([v2vSig]); 72 const i2vSig = {args:[I32Code], ret:VoidCode}; 73 const v2vBody = funcBody({locals:[], body:[]}); 74 75 assertErrorMessage(() => wasmEval(moduleWithSections([ {name: typeId, body: U32MAX_LEB } ])), CompileError, /too many types/); 76 assertErrorMessage(() => wasmEval(moduleWithSections([ {name: typeId, body: [1, 0], } ])), CompileError, /expected type form/); 77 assertErrorMessage(() => wasmEval(moduleWithSections([ {name: typeId, body: [1, FuncCode, ...U32MAX_LEB], } ])), CompileError, /too many arguments in signature/); 78 79 assertThrowsInstanceOf(() => wasmEval(moduleWithSections([{name: typeId, body: [1]}])), CompileError); 80 assertThrowsInstanceOf(() => wasmEval(moduleWithSections([{name: typeId, body: [1, 1, 0]}])), CompileError); 81 82 wasmEval(moduleWithSections([sigSection([])])); 83 wasmEval(moduleWithSections([v2vSigSection])); 84 wasmEval(moduleWithSections([sigSection([i2vSig])])); 85 wasmEval(moduleWithSections([sigSection([v2vSig, i2vSig])])); 86 87 assertErrorMessage(() => wasmEval(moduleWithSections([sigSection([{args:[], ret:33}])])), CompileError, /bad type/); 88 assertErrorMessage(() => wasmEval(moduleWithSections([sigSection([{args:[33], ret:VoidCode}])])), CompileError, /bad type/); 89 90 assertThrowsInstanceOf(() => wasmEval(moduleWithSections([sigSection([]), declSection([0])])), CompileError, /signature index out of range/); 91 assertThrowsInstanceOf(() => wasmEval(moduleWithSections([v2vSigSection, declSection([1])])), CompileError, /signature index out of range/); 92 assertErrorMessage(() => wasmEval(moduleWithSections([v2vSigSection, declSection([0])])), CompileError, /expected code section/); 93 wasmEval(moduleWithSections([v2vSigSection, declSection([0]), bodySection([v2vBody])])); 94 95 assertErrorMessage(() => wasmEval(moduleWithSections([v2vSigSection, declSection([0]), bodySection([v2vBody.concat(v2vBody)])])), CompileError, /byte size mismatch in code section/); 96 97 assertThrowsInstanceOf(() => wasmEval(moduleWithSections([v2vSigSection, {name: importId, body:[]}])), CompileError); 98 assertErrorMessage(() => wasmEval(moduleWithSections([importSection([{module:"a", item:"b", funcTypeIndex:0}])])), CompileError, /signature index out of range/); 99 assertErrorMessage(() => wasmEval(moduleWithSections([v2vSigSection, importSection([{module:"a", item:"b", funcTypeIndex:1}])])), CompileError, /signature index out of range/); 100 wasmEval(moduleWithSections([v2vSigSection, importSection([])])); 101 wasmEval(moduleWithSections([v2vSigSection, importSection([{module:"a", item:"", funcTypeIndex:0}])]), {a:{"":()=>{}}}); 102 103 wasmEval(moduleWithSections([ 104 v2vSigSection, 105 importSection([{module:"a", item:"", funcTypeIndex:0}]), 106 declSection([0]), 107 bodySection([v2vBody]) 108 ]), {a:{"":()=>{}}}); 109 110 assertErrorMessage(() => wasmEval(moduleWithSections([ dataSection([{offset:1, elems:[]}]) ])), CompileError, /data segment requires a memory section/); 111 112 wasmEval(moduleWithSections([defaultTableSection(0)])); 113 wasmEval(moduleWithSections([elemSection([])])); 114 wasmEval(moduleWithSections([defaultTableSection(0), elemSection([])])); 115 wasmEval(moduleWithSections([defaultTableSection(1), elemSection([{offset:1, elems:[]}])])); 116 assertErrorMessage(() => wasmEval(moduleWithSections([defaultTableSection(1), elemSection([{offset:0, elems:[0]}])])), CompileError, /element index out of range/); 117 wasmEval(moduleWithSections([v2vSigSection, declSection([0]), defaultTableSection(1), elemSection([{offset:0, elems:[0]}]), bodySection([v2vBody])])); 118 wasmEval(moduleWithSections([v2vSigSection, declSection([0]), defaultTableSection(2), elemSection([{offset:0, elems:[0,0]}]), bodySection([v2vBody])])); 119 assertErrorMessage(() => wasmEval(moduleWithSections([v2vSigSection, declSection([0]), defaultTableSection(2), elemSection([{offset:0, elems:[0,1]}]), bodySection([v2vBody])])), CompileError, /element index out of range/); 120 wasmEval(moduleWithSections([v2vSigSection, declSection([0,0,0]), defaultTableSection(4), elemSection([{offset:0, elems:[0,1,0,2]}]), bodySection([v2vBody, v2vBody, v2vBody])])); 121 wasmEval(moduleWithSections([sigSection([v2vSig,i2vSig]), declSection([0,0,1]), defaultTableSection(3), elemSection([{offset:0,elems:[0,1,2]}]), bodySection([v2vBody, v2vBody, v2vBody])])); 122 123 wasmEval(moduleWithSections([tableSection0()])); 124 125 wasmEval(moduleWithSections([memorySection(0)])); 126 127 function memorySection2() { 128 var body = []; 129 body.push(...varU32(2)); // number of memories 130 body.push(...varU32(0x0)); 131 body.push(...varU32(0)); 132 body.push(...varU32(0x0)); 133 body.push(...varU32(0)); 134 return { name: memoryId, body }; 135 } 136 137 wasmEval(moduleWithSections([memorySection0()])); 138 wasmEval(moduleWithSections([memorySection2()])); 139 140 // Test early 'end' 141 const bodyMismatch = /(function body length mismatch)|(operators remaining after end of function)/; 142 assertErrorMessage(() => wasmEval(moduleWithSections([v2vSigSection, declSection([0]), bodySection([funcBody({locals:[], body:[EndCode]})])])), CompileError, bodyMismatch); 143 assertErrorMessage(() => wasmEval(moduleWithSections([v2vSigSection, declSection([0]), bodySection([funcBody({locals:[], body:[UnreachableCode,EndCode]})])])), CompileError, bodyMismatch); 144 assertErrorMessage(() => wasmEval(moduleWithSections([v2vSigSection, declSection([0]), bodySection([funcBody({locals:[], body:[EndCode,UnreachableCode]})])])), CompileError, bodyMismatch); 145 146 // Ignore errors in name section. 147 var tooBigNameSection = { 148 name: userDefinedId, 149 body: [...string(nameName), ...varU32(Math.pow(2, 31))] // declare 2**31 functions. 150 }; 151 wasmEval(moduleWithSections([tooBigNameSection])); 152 153 // Custom sections must have valid UTF-8 names 154 assertErrorMessage(() => wasmEval(toU8([0,97,115,109,1,0,0,0,0,3,2,254,255,])), CompileError, /failed to start custom section/); 155 156 // Skip custom sections before any expected section 157 var customDefSec = customSection("wee", 42, 13); 158 var declSec = declSection([0]); 159 var bodySec = bodySection([v2vBody]); 160 var nameSec = nameSection([funcNameSubsection([{name:'hi'}])]); 161 wasmEval(moduleWithSections([customDefSec, v2vSigSection, declSec, bodySec])); 162 wasmEval(moduleWithSections([v2vSigSection, customDefSec, declSec, bodySec])); 163 wasmEval(moduleWithSections([v2vSigSection, declSec, customDefSec, bodySec])); 164 wasmEval(moduleWithSections([v2vSigSection, declSec, bodySec, customDefSec])); 165 wasmEval(moduleWithSections([customDefSec, customDefSec, v2vSigSection, declSec, bodySec])); 166 wasmEval(moduleWithSections([customDefSec, customDefSec, v2vSigSection, customDefSec, declSec, customDefSec, bodySec])); 167 168 // custom sections reflection: 169 function checkCustomSection(buf, val) { 170 assertEq(buf instanceof ArrayBuffer, true); 171 assertEq(buf.byteLength, 1); 172 assertEq(new Uint8Array(buf)[0], val); 173 } 174 var custom1 = customSection("one", 1); 175 var custom2 = customSection("one", 2); 176 var custom3 = customSection("two", 3); 177 var custom4 = customSection("three", 4); 178 var custom5 = customSection("three", 5); 179 var custom6 = customSection("three", 6); 180 var m = new Module(moduleWithSections([custom1, v2vSigSection, custom2, declSec, custom3, bodySec, custom4, nameSec, custom5, custom6])); 181 var arr = Module.customSections(m, "one"); 182 assertEq(arr.length, 2); 183 checkCustomSection(arr[0], 1); 184 checkCustomSection(arr[1], 2); 185 var arr = Module.customSections(m, "two"); 186 assertEq(arr.length, 1); 187 checkCustomSection(arr[0], 3); 188 var arr = Module.customSections(m, "three"); 189 assertEq(arr.length, 3); 190 checkCustomSection(arr[0], 4); 191 checkCustomSection(arr[1], 5); 192 checkCustomSection(arr[2], 6); 193 var arr = Module.customSections(m, "name"); 194 assertEq(arr.length, 1); 195 assertEq(arr[0].byteLength, nameSec.body.length - 5 /* 4name */); 196 197 // Test name/custom section warnings: 198 const nameWarning = /validated with warning.*'name' custom section/; 199 const okNameSec = nameSection([]); 200 assertNoWarning(() => wasmEval(moduleWithSections([v2vSigSection, declSec, bodySec, okNameSec]))); 201 const badNameSec1 = nameSection([]); 202 badNameSec1.body.push(1); 203 assertWarning(() => wasmEval(moduleWithSections([v2vSigSection, declSec, bodySec, badNameSec1])), nameWarning); 204 const badNameSec2 = nameSection([funcNameSubsection([{name:'blah'}])]); 205 badNameSec2.body.push(100, 20, 42, 83); 206 assertWarning(() => wasmEval(moduleWithSections([v2vSigSection, declSec, bodySec, badNameSec2])), nameWarning); 207 const badNameSec3 = nameSection([funcNameSubsection([{name:'blah'}])]); 208 badNameSec3.body.pop(); 209 assertWarning(() => wasmEval(moduleWithSections([v2vSigSection, declSec, bodySec, badNameSec3])), nameWarning); 210 assertNoWarning(() => wasmEval(moduleWithSections([nameSection([moduleNameSubsection('hi')])]))); 211 assertWarning(() => wasmEval(moduleWithSections([nameSection([moduleNameSubsection('hi'), moduleNameSubsection('boo')])])), nameWarning); 212 // Unknown name subsection 213 assertNoWarning(() => wasmEval(moduleWithSections([nameSection([moduleNameSubsection('hi'), [4, 0]])]))); 214 assertWarning(() => wasmEval(moduleWithSections([nameSection([moduleNameSubsection('hi'), [4, 1]])])), nameWarning); 215 assertNoWarning(() => wasmEval(moduleWithSections([nameSection([moduleNameSubsection('hi'), [4, 1, 42]])]))); 216 217 // Provide a module name but no function names. 218 assertErrorMessage(() => wasmEval(moduleWithSections([ 219 v2vSigSection, 220 declSection([0]), 221 exportSection([{funcIndex: 0, name: "f"}]), 222 bodySection([funcBody({locals:[], body:[UnreachableCode]})]), 223 nameSection([moduleNameSubsection('hi')])]) 224 ).f(), RuntimeError, /unreachable/); 225 226 // Diagnose invalid block signature types. 227 for (var bad of [0xff, 1, 0x3f]) 228 assertErrorMessage(() => wasmEval(moduleWithSections([sigSection([v2vSig]), declSection([0]), bodySection([funcBody({locals:[], body:[BlockCode, bad, EndCode]})])])), CompileError, /(invalid .*block type)|(unknown type)/); 229 230 const multiValueModule = moduleWithSections([sigSection([v2vSig]), declSection([0]), bodySection([funcBody({locals:[], body:[BlockCode, 0, EndCode]})])]); 231 // In this test module, 0 denotes a void-to-void block type. 232 assertEq(WebAssembly.validate(multiValueModule), true); 233 234 // Ensure all invalid opcodes are rejected. Note that the game here (and for 235 // the prefixed cases below) is to present only opcodes which will be rejected by 236 // *both* Baseline and Ion. 237 for (let op of undefinedOpcodes) { 238 let binary = moduleWithSections([v2vSigSection, declSection([0]), bodySection([funcBody({locals:[], body:[op]})])]); 239 assertErrorMessage(() => wasmEval(binary), CompileError, /((unrecognized|Unknown) opcode)|(tail calls support is not enabled)|(Exceptions support is not enabled)|(Unexpected EOF)/); 240 assertEq(WebAssembly.validate(binary), false); 241 } 242 243 // Prefixed opcodes 244 245 function checkIllegalPrefixed(prefix, opcode) { 246 let binary = moduleWithSections([v2vSigSection, 247 declSection([0]), 248 bodySection([funcBody({locals:[], 249 body:[prefix, ...varU32(opcode)]})])]); 250 assertErrorMessage(() => wasmEval(binary), CompileError, /((unrecognized|Unknown) opcode)|(Unknown.*subopcode)|(Unexpected EOF)|(SIMD support is not enabled)|(invalid lane index)/); 251 assertEq(WebAssembly.validate(binary), false); 252 } 253 254 // Illegal GcPrefix opcodes 255 256 let reservedGc = { 257 // Structure operations 258 0x00: true, 0x01: true, 0x02: true, 0x03: true, 0x04: true, 0x05: true, 259 // Array operations 260 0x06: true, 0x07: true, 0x08: true, 0x09: true, 0x0a: true, 0x0b: true, 261 0x0c: true, 0x0d: true, 0x0e: true, 0x0f: true, 0x10: true, 0x11: true, 262 0x12: true, 0x13: true, 263 // Ref operations 264 0x14: true, 0x15: true, 0x16: true, 0x17: true, 0x18: true, 0x19: true, 265 0x1a: true, 0x1b: true, 266 // i31 operations 267 0x1c: true, 0x1d: true, 0x1e: true, 268 }; 269 for (let i = 0; i < 256; i++) { 270 if (reservedGc.hasOwnProperty(i)) { 271 continue; 272 } 273 checkIllegalPrefixed(GcPrefix, i); 274 } 275 276 // Illegal ThreadPrefix opcodes 277 // 278 // June 2017 threads draft: 279 // 280 // 0x00 .. 0x03 are wait/wake/fence ops 281 // 0x10 .. 0x4f are primitive atomic ops 282 283 for (let i = 0x4; i < 0x10; i++) 284 checkIllegalPrefixed(ThreadPrefix, i); 285 286 for (let i = 0x4f; i < 0x100; i++) 287 checkIllegalPrefixed(ThreadPrefix, i); 288 289 // Illegal Misc opcodes 290 291 var reservedMisc = 292 { // Saturating conversions (standardized) 293 0x00: true, 0x01: true, 0x02: true, 0x03: true, 0x04: true, 0x05: true, 0x06: true, 0x07: true, 294 // Bulk memory (proposed) 295 0x08: true, 0x09: true, 0x0a: true, 0x0b: true, 0x0c: true, 0x0d: true, 0x0e: true, 296 // Table (proposed) 297 0x0f: true, 0x10: true, 0x11: true, 0x12: true, 298 // Structure operations (experimental, internal) 299 0x50: true, 0x51: true, 0x52: true, 0x53: true }; 300 301 for (let i = 0; i < 256; i++) { 302 if (reservedMisc.hasOwnProperty(i)) 303 continue; 304 checkIllegalPrefixed(MiscPrefix, i); 305 } 306 307 // Illegal SIMD opcodes - the upper bound is actually very large, not much to be 308 // done about that. 309 310 if (!wasmSimdEnabled()) { 311 for (let i = 0; i < 0x130; i++) { 312 checkIllegalPrefixed(SimdPrefix, i); 313 } 314 } else { 315 let reservedSimd = [ 316 0x9a, 0xa2, 0xa5, 0xa6, 0xaf, 0xb0, 0xb2, 0xb3, 0xb4, 0xbb, 317 0xc2, 0xc5, 0xc6, 0xcf, 0xd0, 0xd2, 0xd3, 0xd4, 0xe2, 0xee, 318 0x115, 0x116, 0x117, 319 0x118, 0x119, 0x11a, 0x11b, 0x11c, 0x11d, 0x11e, 0x11f, 320 0x120, 0x121, 0x122, 0x123, 0x124, 0x125, 0x126, 0x127, 321 0x128, 0x129, 0x12a, 0x12b, 0x12c, 0x12d, 0x12e, 0x12f, 322 ]; 323 for (let i of reservedSimd) { 324 checkIllegalPrefixed(SimdPrefix, i); 325 } 326 } 327 328 // Illegal MozPrefix opcodes (all of them) 329 for (let i = 0; i < 256; i++) 330 checkIllegalPrefixed(MozPrefix, i); 331 332 for (let prefix of [ThreadPrefix, MiscPrefix, SimdPrefix, MozPrefix]) { 333 // Prefix without a subsequent opcode. We must ask funcBody not to add an 334 // End code after the prefix, so the body really is just the prefix byte. 335 let binary = moduleWithSections([v2vSigSection, declSection([0]), bodySection([funcBody({locals:[], body:[prefix]}, /*withEndCode=*/false)])]); 336 assertErrorMessage(() => wasmEval(binary), CompileError, /(unable to read opcode)|(Unexpected EOF)|(Unknown opcode)/); 337 assertEq(WebAssembly.validate(binary), false); 338 } 339 340 // Checking stack trace. 341 function runStackTraceTest(moduleName, funcNames, expectedName) { 342 var sections = [ 343 sigSection([v2vSig]), 344 importSection([{module:"env", item:"callback", funcTypeIndex:0}]), 345 declSection([0]), 346 exportSection([{funcIndex:1, name: "run"}]), 347 bodySection([funcBody({locals: [], body: [CallCode, varU32(0)]})]), 348 customSection("whoa"), 349 customSection("wee", 42), 350 ]; 351 if (moduleName || funcNames) { 352 var subsections = []; 353 if (moduleName) 354 subsections.push(moduleNameSubsection(moduleName)); 355 if (funcNames) 356 subsections.push(funcNameSubsection(funcNames)); 357 sections.push(nameSection(subsections)); 358 } 359 sections.push(customSection("yay", 13)); 360 361 var result = ""; 362 var callback = () => { 363 result = extractStackFrameFunction(new Error().stack.split('\n')[1]); 364 }; 365 wasmEval(moduleWithSections(sections), {"env": { callback }}).run(); 366 assertEq(result, expectedName); 367 }; 368 369 runStackTraceTest(null, null, 'wasm-function[1]'); 370 runStackTraceTest(null, [{name:'blah'}, {name:'test'}], 'test'); 371 runStackTraceTest(null, [{name:'test', index:1}], 'test'); 372 runStackTraceTest(null, [{name:'blah'}, {name:'test', locals: [{name: 'var1'}, {name: 'var2'}]}], 'test'); 373 runStackTraceTest(null, [{name:'blah'}, {name:'test', locals: [{name: 'var1'}, {name: 'var2'}]}], 'test'); 374 runStackTraceTest(null, [{name:'blah'}, {name:'test1'}], 'test1'); 375 runStackTraceTest(null, [{name:'blah'}, {name:'test☃'}], 'test☃'); 376 runStackTraceTest(null, [{name:'blah'}, {name:'te\xE0\xFF'}], 'te\xE0\xFF'); 377 runStackTraceTest(null, [{name:'blah'}], 'wasm-function[1]'); 378 runStackTraceTest(null, [], 'wasm-function[1]'); 379 runStackTraceTest("", [{name:'blah'}, {name:'test'}], 'test'); 380 runStackTraceTest("a", [{name:'blah'}, {name:'test'}], 'a.test'); 381 // Notice that invalid names section content shall not fail the parsing 382 runStackTraceTest(null, [{name:'blah'}, {name:'test', index: 2}], 'wasm-function[1]'); // invalid index 383 runStackTraceTest(null, [{name:'blah'}, {name:'test', index: 100000}], 'wasm-function[1]'); // invalid index 384 runStackTraceTest(null, [{name:'blah'}, {name:'test', nameLen: 100}], 'wasm-function[1]'); // invalid name size 385 runStackTraceTest(null, [{name:'blah'}, {name:''}], 'wasm-function[1]'); // empty name 386 387 // Enable and disable Gecko profiling mode, to ensure all live instances 388 // names won't make us crash. 389 enableGeckoProfiling(); 390 disableGeckoProfiling(); 391 392 function testValidNameSectionWithProfiling() { 393 enableGeckoProfiling(); 394 wasmEval(moduleWithSections([v2vSigSection, declSec, bodySec, nameSec])); 395 disableGeckoProfiling(); 396 } 397 testValidNameSectionWithProfiling(); 398 399 // Memory alignment can use non-minimal LEB128 400 wasmEval(moduleWithSections([ 401 v2vSigSection, 402 declSection([0]), 403 memorySection(0), 404 bodySection([ 405 funcBody({locals: [], body: [ 406 I32ConstCode, 0x00, // i32.const 0 407 I32Load, 408 0x81, 0x00, // alignment 1, non-minimal 409 0x00, // offset 0 410 DropCode, 411 ]}), 412 ]), 413 ]));