Changeset 209830 in webkit
- Timestamp:
- Dec 14, 2016 1:29:14 PM (7 years ago)
- Location:
- trunk
- Files:
-
- 6 added
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r209785 r209830 1 2016-12-14 Keith Miller <keith_miller@apple.com> 2 3 WebAssembly JS API: implement Global 4 https://bugs.webkit.org/show_bug.cgi?id=164133 5 6 Reviewed by Saam Barati. 7 8 * wasm/Builder.js: 9 (export.default.Builder.prototype._registerSectionBuilders.switch.case.string_appeared_here.this.section): 10 * wasm/Builder_WebAssemblyBinary.js: 11 (const.valueType.WASM.description.type.i32.type.const.putGlobalType): 12 (const.putOp): 13 (const.putInitExpr): 14 (const.emitters.Import): 15 (const.emitters.Global): 16 (const.emitters.Export): 17 (const.emitters.Code): 18 * wasm/LowLevelBinary.js: 19 (export.default.LowLevelBinary.prototype.varuint32): 20 (export.default.LowLevelBinary.prototype.varint32): 21 * wasm/js-api/global-error.js: Added. 22 (catch): 23 (assert.truthy): 24 * wasm/js-api/global-external-init-from-import.js: Added. 25 * wasm/js-api/global-internal-init-from-import.js: Added. 26 * wasm/js-api/global-mutate.js: Added. 27 (createInternalGlobalModule): 28 * wasm/js-api/globals-export.js: Added. 29 * wasm/js-api/globals-import.js: Added. 30 * wasm/wasm.json: 31 1 32 2016-12-13 Saam Barati <sbarati@apple.com> 2 33 -
trunk/JSTests/wasm/Builder.js
r209785 r209830 175 175 }; 176 176 177 const _normalizeMutability = (mutability) => { 178 if (mutability === "mutable") 179 return 1; 180 else if (mutability === "immutable") 181 return 0; 182 else 183 throw new Error(`mutability should be either "mutable" or "immutable", but got ${global.mutablity}`); 184 }; 185 186 const _exportGlobalContinuation = (builder, section, nextBuilder) => { 187 return (field, index) => { 188 assert.isNumber(index, `Global exports only support number indices right now`); 189 section.data.push({ field, kind: "Global", index }); 190 return nextBuilder; 191 } 192 }; 193 194 const _importGlobalContinuation = (builder, section, nextBuilder) => { 195 return () => { 196 const globalBuilder = { 197 End: () => nextBuilder 198 }; 199 for (let op of WASM.description.value_type) { 200 globalBuilder[_toJavaScriptName(op)] = (module, field, mutability) => { 201 assert.isString(module, `Import global module should be a string, got "${module}"`); 202 assert.isString(field, `Import global field should be a string, got "${field}"`); 203 assert.isString(mutability, `Import global mutability should be a string, got "${mutability}"`); 204 section.data.push({ globalDescription: { type: op, mutability: _normalizeMutability(mutability) }, module, field, kind: "Global" }); 205 return globalBuilder; 206 }; 207 } 208 return globalBuilder; 209 }; 210 }; 211 177 212 const _checkStackArgs = (op, param) => { 178 213 for (let expect of param) { … … 203 238 // Handle our own meta-types. 204 239 switch (expect) { 240 case "any": break; 205 241 case "bool": break; // FIXME implement bool. https://bugs.webkit.org/show_bug.cgi?id=163421 206 242 case "call": break; // FIXME implement call stack return check based on function signature. https://bugs.webkit.org/show_bug.cgi?id=163421 … … 408 444 const importBuilder = { 409 445 End: () => this, 410 Global: () => { throw new Error(`Unimplemented: import global`); },411 };446 }; 447 importBuilder.Global = _importGlobalContinuation(this, s, importBuilder); 412 448 importBuilder.Function = _importFunctionContinuation(this, s, importBuilder); 413 449 importBuilder.Memory = _importMemoryContinuation(this, s, importBuilder); … … 457 493 458 494 case "Global": 459 // FIXME implement global https://bugs.webkit.org/show_bug.cgi?id=164133 460 this[section] = () => { throw new Error(`Unimplemented: section type "${section}"`); }; 495 this[section] = function() { 496 const s = this._addSection(section); 497 const globalBuilder = { 498 End: () => this, 499 GetGlobal: (type, initValue, mutability) => { 500 s.data.push({ type, op: "get_global", mutability: _normalizeMutability(mutability), initValue }); 501 return globalBuilder; 502 } 503 }; 504 for (let op of WASM.description.value_type) { 505 globalBuilder[_toJavaScriptName(op)] = (initValue, mutability) => { 506 s.data.push({ type: op, op: op + ".const", mutability: _normalizeMutability(mutability), initValue }); 507 return globalBuilder; 508 }; 509 } 510 return globalBuilder; 511 }; 461 512 break; 462 513 … … 468 519 Table: () => { throw new Error(`Unimplemented: export table`); }, 469 520 Memory: () => { throw new Error(`Unimplemented: export memory`); }, 470 Global: () => { throw new Error(`Unimplemented: export global`); },471 };521 }; 522 exportBuilder.Global = _exportGlobalContinuation(this, s, exportBuilder); 472 523 exportBuilder.Function = _exportFunctionContinuation(this, s, exportBuilder); 473 524 return exportBuilder; … … 509 560 const codeBuilder = { 510 561 End: () => { 511 // We now have enough information to remap the export section's "type" and "index" according to the Code section we 're currently ending.562 // We now have enough information to remap the export section's "type" and "index" according to the Code section we are currently ending. 512 563 const typeSection = builder._getSection("Type"); 513 564 const importSection = builder._getSection("Import"); … … 517 568 if (exportSection) { 518 569 for (const e of exportSection.data) { 570 if (e.kind !== "Function" || typeof(e.type) !== "undefined") 571 continue; 519 572 switch (typeof(e.index)) { 520 573 default: throw new Error(`Unexpected export index "${e.index}"`); -
trunk/JSTests/wasm/Builder_WebAssemblyBinary.js
r209785 r209830 52 52 }; 53 53 54 const valueType = WASM.description.type.i32.type 55 56 const putGlobalType = (bin, global) => { 57 put(bin, valueType, WASM.typeValue[global.type]); 58 put(bin, "varuint1", global.mutability); 59 }; 60 61 const putOp = (bin, op) => { 62 put(bin, "uint8", op.value); 63 if (op.arguments.length !== 0) 64 throw new Error(`Unimplemented: arguments`); // FIXME https://bugs.webkit.org/show_bug.cgi?id=162706 65 66 switch (op.name) { 67 default: 68 for (let i = 0; i < op.immediates.length; ++i) { 69 const type = WASM.description.opcode[op.name].immediate[i].type 70 if (!bin[type]) 71 throw new TypeError(`Unknown type: ${type} in op: ${op.name}`); 72 put(bin, type, op.immediates[i]); 73 } 74 break; 75 case "br_table": 76 put(bin, "varuint32", op.immediates.length - 1); 77 for (let imm of op.immediates) 78 put(bin, "varuint32", imm); 79 break; 80 } 81 }; 82 83 const putInitExpr = (bin, expr) => { 84 putOp(bin, { value: WASM.description.opcode[expr.op].value, name: expr.op, immediates: [expr.initValue], arguments: [] }); 85 putOp(bin, { value: WASM.description.opcode.end.value, name: "end", immediates: [], arguments: [] }); 86 }; 87 54 88 const emitters = { 55 89 Type: (section, bin) => { … … 89 123 break; 90 124 }; 91 case "Global": throw new Error(`Not yet implemented`); 125 case "Global": 126 putGlobalType(bin, entry.globalDescription); 127 break; 92 128 } 93 129 } … … 118 154 }, 119 155 120 Global: (section, bin) => { throw new Error(`Not yet implemented`); }, 156 Global: (section, bin) => { 157 put(bin, "varuint32", section.data.length); 158 for (const global of section.data) { 159 putGlobalType(bin, global); 160 putInitExpr(bin, global) 161 } 162 }, 163 121 164 Export: (section, bin) => { 122 165 put(bin, "varuint32", section.data.length); … … 126 169 switch (entry.kind) { 127 170 default: throw new Error(`Implementation problem: unexpected kind ${entry.kind}`); 128 case "Function": put(bin, "varuint32", entry.index); break; 171 case "Global": 172 case "Function": 173 put(bin, "varuint32", entry.index); 174 break; 129 175 case "Table": throw new Error(`Not yet implemented`); 130 176 case "Memory": throw new Error(`Not yet implemented`); 131 case "Global": throw new Error(`Not yet implemented`); 177 132 178 } 133 179 } … … 165 211 } 166 212 167 for (const op of func.code) { 168 put(funcBin, "uint8", op.value); 169 if (op.arguments.length !== 0) 170 throw new Error(`Unimplemented: arguments`); // FIXME https://bugs.webkit.org/show_bug.cgi?id=162706 171 172 switch (op.name) { 173 default: 174 for (let i = 0; i < op.immediates.length; ++i) { 175 const type = WASM.description.opcode[op.name].immediate[i].type 176 if (!funcBin[type]) 177 throw new TypeError(`Unknown type: ${type} in op: ${op.name}`); 178 put(funcBin, type, op.immediates[i]); 179 } 180 break; 181 case "br_table": 182 put(funcBin, "varuint32", op.immediates.length - 1); 183 for (let imm of op.immediates) 184 put(funcBin, "varuint32", imm); 185 break; 186 } 187 } 213 for (const op of func.code) 214 putOp(funcBin, op); 215 188 216 funcBin.apply(); 189 217 } -
trunk/JSTests/wasm/LowLevelBinary.js
r209306 r209830 124 124 } 125 125 varuint32(v) { 126 assert.isNumber(v); 126 127 if (v < varuint32Min || varuint32Max < v) 127 128 throw new RangeError(`Invalid varuint32 ${v} range is [${varuint32Min}, ${varuint32Max}]`); … … 133 134 } 134 135 varint32(v) { 136 assert.isNumber(v); 135 137 if (v < varint32Min || varint32Max < v) 136 138 throw new RangeError(`Invalid varint32 ${v} range is [${varint32Min}, ${varint32Max}]`); -
trunk/JSTests/wasm/wasm.json
r209652 r209830 59 59 "f64.const": { "category": "special", "value": 68, "return": ["f64"], "parameter": [], "immediate": [{"name": "value", "type": "uint64"}], "description": "a constant value interpreted as f64" }, 60 60 "f32.const": { "category": "special", "value": 67, "return": ["f32"], "parameter": [], "immediate": [{"name": "value", "type": "uint32"}], "description": "a constant value interpreted as f32" }, 61 "get_local": { "category": "special", "value": 32, "return": [" local"], "parameter": [], "immediate": [{"name": "local_index", "type": "varuint32"}], "description": "read a local variable or parameter" },62 "set_local": { "category": "special", "value": 33, "return": [], "parameter": [" local"], "immediate": [{"name": "local_index", "type": "varuint32"}], "description": "write a local variable or parameter" },63 "tee_local": { "category": "special", "value": 34, "return": [" prev"], "parameter": ["any"], "immediate": [{"name": "local_index", "type": "varuint32"}], "description": "write a local variable or parameter and return the same value" },64 "get_global": { "category": "special", "value": 35, "return": [" global"], "parameter": [], "immediate": [{"name": "global_index", "type": "varuint32"}], "description": "read a global variable" },65 "set_global": { "category": "special", "value": 36, "return": [ ""], "parameter": ["global"], "immediate": [{"name": "global_index", "type": "varuint32"}], "description": "write a global variable" },61 "get_local": { "category": "special", "value": 32, "return": ["any"], "parameter": [], "immediate": [{"name": "local_index", "type": "varuint32"}], "description": "read a local variable or parameter" }, 62 "set_local": { "category": "special", "value": 33, "return": [], "parameter": ["any"], "immediate": [{"name": "local_index", "type": "varuint32"}], "description": "write a local variable or parameter" }, 63 "tee_local": { "category": "special", "value": 34, "return": ["any"], "parameter": ["any"], "immediate": [{"name": "local_index", "type": "varuint32"}], "description": "write a local variable or parameter and return the same value" }, 64 "get_global": { "category": "special", "value": 35, "return": ["any"], "parameter": [], "immediate": [{"name": "global_index", "type": "varuint32"}], "description": "read a global variable" }, 65 "set_global": { "category": "special", "value": 36, "return": [], "parameter": ["any"], "immediate": [{"name": "global_index", "type": "varuint32"}], "description": "write a global variable" }, 66 66 "call": { "category": "call", "value": 16, "return": ["call"], "parameter": ["call"], "immediate": [{"name": "function_index", "type": "varuint32"}], "description": "call a function by its index" }, 67 67 "call_indirect": { "category": "call", "value": 17, "return": ["call"], "parameter": ["call"], "immediate": [{"name": "type_index", "type": "varuint32"}, {"name": "reserved", "type": "varuint1"}], "description": "call a function indirect with an expected signature" }, -
trunk/Source/JavaScriptCore/ChangeLog
r209827 r209830 1 2016-12-14 Keith Miller <keith_miller@apple.com> 2 3 WebAssembly JS API: implement Global 4 https://bugs.webkit.org/show_bug.cgi?id=164133 5 6 Reviewed by Saam Barati. 7 8 This patch adds support for globals. It handles imports, exports 9 and internal globals. In the MVP only internal globals are allowed 10 to be mutable. This means we can store a C-array of 64-bit slots 11 off the instance holding them. When globals are exported to JS 12 they are done so as numbers. This means that i64 globals cannot be 13 imported or exported. 14 15 * wasm/WasmB3IRGenerator.cpp: 16 (JSC::Wasm::B3IRGenerator::B3IRGenerator): 17 (JSC::Wasm::B3IRGenerator::getGlobal): 18 (JSC::Wasm::B3IRGenerator::setGlobal): 19 (JSC::Wasm::B3IRGenerator::addCallIndirect): 20 (JSC::Wasm::parseAndCompile): 21 * wasm/WasmFormat.h: 22 * wasm/WasmFunctionParser.h: 23 (JSC::Wasm::FunctionParser<Context>::parseExpression): 24 * wasm/WasmModuleParser.cpp: 25 (JSC::Wasm::ModuleParser::parseImport): 26 (JSC::Wasm::ModuleParser::parseGlobal): 27 (JSC::Wasm::ModuleParser::parseExport): 28 (JSC::Wasm::ModuleParser::parseElement): 29 (JSC::Wasm::ModuleParser::parseInitExpr): 30 (JSC::Wasm::ModuleParser::parseGlobalType): 31 (JSC::Wasm::ModuleParser::parseData): 32 * wasm/WasmModuleParser.h: 33 * wasm/WasmParser.h: 34 (JSC::Wasm::Parser::parseVarInt32): 35 (JSC::Wasm::Parser::parseVarInt64): 36 (JSC::Wasm::Parser::parseUInt64): 37 * wasm/WasmValidate.cpp: 38 (JSC::Wasm::Validate::hasMemory): 39 (JSC::Wasm::Validate::Validate): 40 (JSC::Wasm::Validate::getGlobal): 41 (JSC::Wasm::Validate::setGlobal): 42 (JSC::Wasm::validateFunction): 43 * wasm/generateWasmOpsHeader.py: 44 * wasm/js/JSWebAssemblyInstance.cpp: 45 (JSC::JSWebAssemblyInstance::create): 46 (JSC::JSWebAssemblyInstance::finishCreation): 47 (JSC::JSWebAssemblyInstance::visitChildren): 48 * wasm/js/JSWebAssemblyInstance.h: 49 (JSC::JSWebAssemblyInstance::loadI32Global): 50 (JSC::JSWebAssemblyInstance::loadI64Global): 51 (JSC::JSWebAssemblyInstance::loadF32Global): 52 (JSC::JSWebAssemblyInstance::loadF64Global): 53 (JSC::JSWebAssemblyInstance::setGlobal): 54 (JSC::JSWebAssemblyInstance::offsetOfGlobals): 55 * wasm/js/WebAssemblyInstanceConstructor.cpp: 56 (JSC::constructJSWebAssemblyInstance): 57 * wasm/js/WebAssemblyModuleRecord.cpp: 58 (JSC::WebAssemblyModuleRecord::finishCreation): 59 (JSC::WebAssemblyModuleRecord::link): 60 1 61 2016-12-14 Filip Pizlo <fpizlo@apple.com> 2 62 -
trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp
r209771 r209830 138 138 static constexpr ExpressionType emptyExpression = nullptr; 139 139 140 B3IRGenerator(VM&, const M emoryInformation&, Procedure&, WasmInternalFunction*, Vector<UnlinkedWasmToWasmCall>&, const ImmutableFunctionIndexSpace&);140 B3IRGenerator(VM&, const ModuleInformation&, Procedure&, WasmInternalFunction*, Vector<UnlinkedWasmToWasmCall>&, const ImmutableFunctionIndexSpace&); 141 141 142 142 bool WARN_UNUSED_RETURN addArguments(const Vector<Type>&); … … 147 147 bool WARN_UNUSED_RETURN getLocal(uint32_t index, ExpressionType& result); 148 148 bool WARN_UNUSED_RETURN setLocal(uint32_t index, ExpressionType value); 149 150 // Globals 151 bool WARN_UNUSED_RETURN getGlobal(uint32_t index, ExpressionType& result); 152 bool WARN_UNUSED_RETURN setGlobal(uint32_t index, ExpressionType value); 149 153 150 154 // Memory … … 191 195 VM& m_vm; 192 196 const ImmutableFunctionIndexSpace& m_functionIndexSpace; 197 const ModuleInformation& m_info; 193 198 Procedure& m_proc; 194 199 BasicBlock* m_currentBlock; … … 198 203 GPRReg m_memorySizeGPR; 199 204 Value* m_zeroValues[numTypes]; 200 Value* m_functionIndexSpaceValue; 205 Value* m_instanceValue; 206 201 207 }; 202 208 203 B3IRGenerator::B3IRGenerator(VM& vm, const M emoryInformation& memory, Procedure& procedure, WasmInternalFunction* compilation, Vector<UnlinkedWasmToWasmCall>& unlinkedWasmToWasmCalls, const ImmutableFunctionIndexSpace& functionIndexSpace)209 B3IRGenerator::B3IRGenerator(VM& vm, const ModuleInformation& info, Procedure& procedure, WasmInternalFunction* compilation, Vector<UnlinkedWasmToWasmCall>& unlinkedWasmToWasmCalls, const ImmutableFunctionIndexSpace& functionIndexSpace) 204 210 : m_vm(vm) 205 211 , m_functionIndexSpace(functionIndexSpace) 212 , m_info(info) 206 213 , m_proc(procedure) 207 214 , m_unlinkedWasmToWasmCalls(unlinkedWasmToWasmCalls) … … 223 230 } 224 231 225 if (!! memory) {226 m_memoryBaseGPR = memory.pinnedRegisters().baseMemoryPointer;232 if (!!info.memory) { 233 m_memoryBaseGPR = info.memory.pinnedRegisters().baseMemoryPointer; 227 234 m_proc.pinRegister(m_memoryBaseGPR); 228 ASSERT(! memory.pinnedRegisters().sizeRegisters[0].sizeOffset);229 m_memorySizeGPR = memory.pinnedRegisters().sizeRegisters[0].sizeRegister;230 for (const PinnedSizeRegisterInfo& info :memory.pinnedRegisters().sizeRegisters)231 m_proc.pinRegister( info.sizeRegister);235 ASSERT(!info.memory.pinnedRegisters().sizeRegisters[0].sizeOffset); 236 m_memorySizeGPR = info.memory.pinnedRegisters().sizeRegisters[0].sizeRegister; 237 for (const PinnedSizeRegisterInfo& regInfo : info.memory.pinnedRegisters().sizeRegisters) 238 m_proc.pinRegister(regInfo.sizeRegister); 232 239 233 240 m_proc.setWasmBoundsCheckGenerator([=] (CCallHelpers& jit, GPRReg pinnedGPR, unsigned) { … … 272 279 wasmCallingConvention().setupFrameInPrologue(&compilation->wasmCalleeMoveLocation, m_proc, Origin(), m_currentBlock); 273 280 274 m_functionIndexSpaceValue = m_currentBlock->appendNew<ConstPtrValue>(m_proc, Origin(), functionIndexSpace.buffer.get()); 281 m_instanceValue = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), Origin(), 282 m_currentBlock->appendNew<ConstPtrValue>(m_proc, Origin(), &m_vm.topJSWebAssemblyInstance)); 275 283 } 276 284 … … 323 331 ASSERT(m_locals[index]); 324 332 m_currentBlock->appendNew<VariableValue>(m_proc, B3::Set, Origin(), m_locals[index], value); 333 return true; 334 } 335 336 bool B3IRGenerator::getGlobal(uint32_t index, ExpressionType& result) 337 { 338 Value* globalsArray = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), Origin(), m_instanceValue, JSWebAssemblyInstance::offsetOfGlobals()); 339 result = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, toB3Type(m_info.globals[index].type), Origin(), globalsArray, index * sizeof(Register)); 340 return true; 341 } 342 343 bool B3IRGenerator::setGlobal(uint32_t index, ExpressionType value) 344 { 345 ASSERT(toB3Type(m_info.globals[index].type) == value->type()); 346 Value* globalsArray = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), Origin(), m_instanceValue, JSWebAssemblyInstance::offsetOfGlobals()); 347 m_currentBlock->appendNew<MemoryValue>(m_proc, Store, Origin(), value, globalsArray, index * sizeof(Register)); 325 348 return true; 326 349 } … … 675 698 ExpressionType callableFunctionBufferSize; 676 699 { 677 ExpressionType topInstance = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), Origin(),678 m_currentBlock->appendNew<ConstPtrValue>(m_proc, Origin(), &m_vm.topJSWebAssemblyInstance));679 700 ExpressionType table = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), Origin(), 680 topInstance, JSWebAssemblyInstance::offsetOfTable());701 m_instanceValue, JSWebAssemblyInstance::offsetOfTable()); 681 702 callableFunctionBuffer = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), Origin(), 682 703 table, JSWebAssemblyTable::offsetOfFunctions()); … … 873 894 874 895 Procedure procedure; 875 B3IRGenerator context(vm, info .memory, procedure, result.get(), unlinkedWasmToWasmCalls, functionIndexSpace);896 B3IRGenerator context(vm, info, procedure, result.get(), unlinkedWasmToWasmCalls, functionIndexSpace); 876 897 FunctionParser<B3IRGenerator> parser(context, functionStart, functionLength, signature, functionIndexSpace, info); 877 898 if (!parser.parse()) -
trunk/Source/JavaScriptCore/wasm/WasmFormat.h
r209785 r209830 94 94 Vector<Type> arguments; 95 95 }; 96 96 97 97 struct Import { 98 98 Identifier module; … … 105 105 Identifier field; 106 106 External::Kind kind; 107 union { 108 uint32_t functionIndex; 109 // FIXME implement Table https://bugs.webkit.org/show_bug.cgi?id=165782 110 // FIXME implement Memory https://bugs.webkit.org/show_bug.cgi?id=165671 111 // FIXME implement Global https://bugs.webkit.org/show_bug.cgi?id=164133 107 unsigned kindIndex; // Index in the vector of the corresponding kind. 108 }; 109 110 struct Global { 111 enum Mutability : uint8_t { 112 // FIXME auto-generate this. https://bugs.webkit.org/show_bug.cgi?id=165231 113 Mutable = 1, 114 Immutable = 0 112 115 }; 116 117 enum InitializationType { 118 IsImport, 119 FromGlobalImport, 120 FromExpression 121 }; 122 123 Mutability mutability; 124 Type type; 125 InitializationType initializationType { IsImport }; 126 uint64_t initialBitsOrImportNumber { 0 }; 113 127 }; 114 128 … … 185 199 Vector<Import> imports; 186 200 Vector<Signature*> importFunctions; 187 // FIXME implement import Global https://bugs.webkit.org/show_bug.cgi?id=164133188 201 Vector<Signature*> internalFunctionSignatures; 189 202 MemoryInformation memory; … … 193 206 Vector<Element> elements; 194 207 TableInformation tableInformation; 208 Vector<Global> globals; 209 unsigned firstInternalGlobal { 0 }; 195 210 196 211 ~ModuleInformation(); -
trunk/Source/JavaScriptCore/wasm/WasmFunctionParser.h
r209771 r209830 352 352 } 353 353 354 case OpType::GetGlobal: { 355 uint32_t index; 356 if (!parseVarUInt32(index)) 357 return false; 358 ExpressionType result; 359 if (!m_context.getGlobal(index, result)) 360 return false; 361 362 m_expressionStack.append(result); 363 return true; 364 } 365 366 case OpType::SetGlobal: { 367 uint32_t index; 368 if (!parseVarUInt32(index)) 369 return false; 370 ExpressionType value; 371 if (!popExpressionStack(value)) 372 return false; 373 return m_context.setGlobal(index, value); 374 } 375 354 376 case OpType::Call: { 355 377 uint32_t functionIndex; … … 564 586 case OpType::GrowMemory: 565 587 case OpType::CurrentMemory: 566 case OpType::GetGlobal:567 case OpType::SetGlobal: {568 588 // FIXME: Not yet implemented. 569 589 return false; 570 }571 590 } 572 591 -
trunk/Source/JavaScriptCore/wasm/WasmModuleParser.cpp
r209785 r209830 218 218 if (!parseVarUInt32(importCount) 219 219 || importCount == std::numeric_limits<uint32_t>::max() 220 || !m_module->globals.tryReserveCapacity(importCount) // FIXME this over-allocates when we fix the FIXMEs below. 220 221 || !m_module->imports.tryReserveCapacity(importCount) // FIXME this over-allocates when we fix the FIXMEs below. 221 222 || !m_module->importFunctions.tryReserveCapacity(importCount) // FIXME this over-allocates when we fix the FIXMEs below. … … 264 265 } 265 266 case External::Global: { 266 // FIXME https://bugs.webkit.org/show_bug.cgi?id=164133 267 // In the MVP, only immutable global variables can be imported. 267 Global global; 268 if (!parseGlobalType(global)) 269 return false; 270 271 if (global.mutability == Global::Mutable) 272 return false; 273 274 imp.kindIndex = m_module->globals.size(); 275 m_module->globals.uncheckedAppend(WTFMove(global)); 268 276 break; 269 277 } … … 273 281 } 274 282 283 m_module->firstInternalGlobal = m_module->globals.size(); 275 284 return true; 276 285 } … … 424 433 bool ModuleParser::parseGlobal() 425 434 { 426 // FIXME https://bugs.webkit.org/show_bug.cgi?id=164133 427 RELEASE_ASSERT_NOT_REACHED(); 435 uint32_t globalCount; 436 if (!parseVarUInt32(globalCount)) 437 return false; 438 if (!m_module->globals.tryReserveCapacity(globalCount + m_module->firstInternalGlobal)) 439 return false; 440 441 for (uint32_t globalIndex = 0; globalIndex < globalCount; ++globalIndex) { 442 Global global; 443 if (!parseGlobalType(global)) 444 return false; 445 446 uint8_t initOpcode; 447 if (!parseInitExpr(initOpcode, global.initialBitsOrImportNumber)) 448 return false; 449 450 global.initializationType = Global::FromExpression; 451 Type typeForInitOpcode; 452 switch (initOpcode) { 453 case I32Const: 454 typeForInitOpcode = I32; 455 break; 456 case I64Const: 457 typeForInitOpcode = I64; 458 break; 459 case F32Const: 460 typeForInitOpcode = F32; 461 break; 462 case F64Const: 463 typeForInitOpcode = F64; 464 break; 465 case GetGlobal: 466 if (global.initialBitsOrImportNumber >= m_module->firstInternalGlobal) 467 return false; 468 typeForInitOpcode = m_module->globals[global.initialBitsOrImportNumber].type; 469 global.initializationType = Global::FromGlobalImport; 470 break; 471 default: 472 RELEASE_ASSERT_NOT_REACHED(); 473 } 474 475 if (typeForInitOpcode != global.type) 476 return false; 477 478 m_module->globals.uncheckedAppend(WTFMove(global)); 479 } 480 428 481 return true; 429 482 } … … 449 502 return false; 450 503 504 if (!parseVarUInt32(exp.kindIndex)) 505 return false; 506 451 507 switch (exp.kind) { 452 508 case External::Function: { 453 if (!parseVarUInt32(exp.functionIndex) 454 || exp.functionIndex >= m_functionIndexSpace.size()) 509 if (exp.kindIndex >= m_functionIndexSpace.size()) 455 510 return false; 456 511 break; … … 465 520 } 466 521 case External::Global: { 467 // FIXME https://bugs.webkit.org/show_bug.cgi?id=164133 468 // In the MVP, only immutable global variables can be exported. 522 if (exp.kindIndex >= m_module->globals.size()) 523 return false; 524 525 if (m_module->globals[exp.kindIndex].mutability != Global::Immutable) 526 return false; 469 527 break; 470 528 } … … 510 568 return false; 511 569 512 uint32_t offset; 513 if (!parseInitExpr(offset)) 570 uint64_t offset; 571 uint8_t initOpcode; 572 if (!parseInitExpr(initOpcode, offset)) 573 return false; 574 575 if (initOpcode != OpType::I32Const) 514 576 return false; 515 577 … … 578 640 } 579 641 580 bool ModuleParser::parseInitExpr(uint32_t& value) 581 { 582 // FIXME allow complex init_expr here. https://bugs.webkit.org/show_bug.cgi?id=165700 583 // For now we only handle i32.const as offset. 584 585 uint8_t opcode; 642 bool ModuleParser::parseInitExpr(uint8_t& opcode, uint64_t& bitsOrImportNumber) 643 { 644 if (!parseUInt8(opcode)) 645 return false; 646 647 switch (opcode) { 648 case I32Const: { 649 int32_t constant; 650 if (!parseVarInt32(constant)) 651 return false; 652 bitsOrImportNumber = static_cast<uint64_t>(constant); 653 break; 654 } 655 656 case I64Const: { 657 int64_t constant; 658 if (!parseVarInt64(constant)) 659 return false; 660 bitsOrImportNumber = constant; 661 break; 662 } 663 664 case F32Const: { 665 uint32_t constant; 666 if (!parseUInt32(constant)) 667 return false; 668 bitsOrImportNumber = constant; 669 break; 670 } 671 672 case F64Const: { 673 uint64_t constant; 674 if (!parseUInt64(constant)) 675 return false; 676 bitsOrImportNumber = constant; 677 break; 678 } 679 680 case GetGlobal: { 681 uint32_t index; 682 if (!parseVarUInt32(index)) 683 return false; 684 685 if (index >= m_module->imports.size()) 686 return false; 687 const Import& import = m_module->imports[index]; 688 if (m_module->imports[index].kind != External::Global 689 || import.kindIndex >= m_module->firstInternalGlobal) 690 return false; 691 692 ASSERT(m_module->globals[import.kindIndex].mutability == Global::Immutable); 693 694 bitsOrImportNumber = index; 695 break; 696 } 697 698 default: 699 return false; 700 } 701 586 702 uint8_t endOpcode; 587 if (!parseUInt8(opcode) 588 || opcode != Wasm::I32Const 589 || !parseVarUInt32(value) 590 || !parseUInt8(endOpcode) 591 || endOpcode != Wasm::End) 592 return false; 703 if (!parseUInt8(endOpcode) || endOpcode != OpType::End) 704 return false; 705 706 return true; 707 } 708 709 bool ModuleParser::parseGlobalType(Global& global) 710 { 711 uint8_t mutability; 712 if (!parseValueType(global.type) || !parseVarUInt1(mutability)) 713 return false; 714 global.mutability = static_cast<Global::Mutability>(mutability); 593 715 return true; 594 716 } … … 608 730 dataLogLn(" segment #", segmentNumber); 609 731 uint32_t index; 610 uint32_t offset; 732 uint64_t offset; 733 uint8_t initOpcode; 611 734 uint32_t dataByteLength; 612 735 if (!parseVarUInt32(index) … … 614 737 return false; 615 738 616 if (!parseInitExpr(offset)) 617 return false; 739 if (!parseInitExpr(initOpcode, offset)) 740 return false; 741 742 if (initOpcode != OpType::I32Const) 743 return false; 744 618 745 if (verbose) 619 746 dataLogLn(" offset: ", offset); -
trunk/Source/JavaScriptCore/wasm/WasmModuleParser.h
r209785 r209830 75 75 76 76 private: 77 bool parseGlobalType(Global&); 78 77 79 #define WASM_SECTION_DECLARE_PARSER(NAME, ID, DESCRIPTION) bool WARN_UNUSED_RETURN parse ## NAME(); 78 80 FOR_EACH_WASM_SECTION(WASM_SECTION_DECLARE_PARSER) … … 82 84 bool WARN_UNUSED_RETURN parseTableHelper(bool isImport); 83 85 bool WARN_UNUSED_RETURN parseResizableLimits(uint32_t& initial, std::optional<uint32_t>& maximum); 84 bool WARN_UNUSED_RETURN parseInitExpr(uint 32_t&);86 bool WARN_UNUSED_RETURN parseInitExpr(uint8_t&, uint64_t&); 85 87 86 88 VM* m_vm; -
trunk/Source/JavaScriptCore/wasm/WasmParser.h
r209560 r209830 52 52 bool WARN_UNUSED_RETURN parseUInt8(uint8_t&); 53 53 bool WARN_UNUSED_RETURN parseUInt32(uint32_t&); 54 bool WARN_UNUSED_RETURN parseUInt64(uint64_t&); 54 55 bool WARN_UNUSED_RETURN parseVarUInt32(uint32_t&); 55 56 bool WARN_UNUSED_RETURN parseVarUInt64(uint64_t&); 57 58 bool WARN_UNUSED_RETURN parseVarInt32(int32_t&); 59 bool WARN_UNUSED_RETURN parseVarInt64(int64_t&); 56 60 57 61 bool WARN_UNUSED_RETURN parseResultType(Type&); … … 125 129 } 126 130 131 ALWAYS_INLINE bool Parser::parseVarInt32(int32_t& result) 132 { 133 return WTF::LEBDecoder::decodeInt32(m_source, m_sourceLength, m_offset, result); 134 } 135 136 ALWAYS_INLINE bool Parser::parseVarInt64(int64_t& result) 137 { 138 return WTF::LEBDecoder::decodeInt64(m_source, m_sourceLength, m_offset, result); 139 } 140 127 141 ALWAYS_INLINE bool Parser::parseUInt32(uint32_t& result) 128 142 { … … 131 145 result = *reinterpret_cast<const uint32_t*>(source() + m_offset); 132 146 m_offset += 4; 147 return true; 148 } 149 150 ALWAYS_INLINE bool Parser::parseUInt64(uint64_t& result) 151 { 152 if (length() < 8 || m_offset > length() - 8) 153 return false; 154 result = *reinterpret_cast<const uint64_t*>(source() + m_offset); 155 m_offset += 8; 133 156 return true; 134 157 } -
trunk/Source/JavaScriptCore/wasm/WasmValidate.cpp
r209652 r209830 87 87 bool WARN_UNUSED_RETURN setLocal(uint32_t index, ExpressionType value); 88 88 89 // Globals 90 bool WARN_UNUSED_RETURN getGlobal(uint32_t index, ExpressionType& result); 91 bool WARN_UNUSED_RETURN setGlobal(uint32_t index, ExpressionType value); 92 89 93 // Memory 90 94 bool WARN_UNUSED_RETURN load(LoadOpType, ExpressionType pointer, ExpressionType& result, uint32_t offset); … … 117 121 void dump(const Vector<ControlEntry>& controlStack, const ExpressionList& expressionStack); 118 122 119 bool hasMemory() const { return !!m_m emory; }123 bool hasMemory() const { return !!m_module.memory; } 120 124 121 125 void setErrorMessage(String&& message) { ASSERT(m_errorMessage.isNull()); m_errorMessage = WTFMove(message); } 122 126 String errorMessage() const { return m_errorMessage; } 123 Validate(ExpressionType returnType, const M emoryInformation& memory)127 Validate(ExpressionType returnType, const ModuleInformation& module) 124 128 : m_returnType(returnType) 125 , m_m emory(memory)129 , m_module(module) 126 130 { 127 131 } … … 136 140 Vector<Type> m_locals; 137 141 String m_errorMessage; 138 const M emoryInformation& m_memory;142 const ModuleInformation& m_module; 139 143 }; 140 144 … … 178 182 179 183 m_errorMessage = makeString("Attempt to set local with type: ", toString(localType), " with a variable of type: ", toString(value)); 184 return false; 185 } 186 187 bool Validate::getGlobal(uint32_t index, ExpressionType& result) 188 { 189 if (index < m_module.globals.size()) { 190 result = m_module.globals[index].type; 191 ASSERT(isValueType(result)); 192 return true; 193 } 194 m_errorMessage = ASCIILiteral("Attempt to use unknown global."); 195 return false; 196 } 197 198 bool Validate::setGlobal(uint32_t index, ExpressionType value) 199 { 200 if (index >= m_module.globals.size()) { 201 m_errorMessage = ASCIILiteral("Attempt to use unknown global."); 202 return false; 203 } 204 205 if (m_module.globals[index].mutability == Global::Immutable) { 206 m_errorMessage = ASCIILiteral("Attempt to store to immutable global."); 207 return false; 208 } 209 210 ExpressionType globalType = m_module.globals[index].type; 211 ASSERT(isValueType(globalType)); 212 if (globalType == value) 213 return true; 214 215 m_errorMessage = makeString("Attempt to set global with type: ", toString(globalType), " with a variable of type: ", toString(value)); 180 216 return false; 181 217 } … … 402 438 } 403 439 404 String validateFunction(const uint8_t* source, size_t length, const Signature* signature, const ImmutableFunctionIndexSpace& functionIndexSpace, const ModuleInformation& info)405 { 406 Validate context(signature->returnType, info.memory);407 FunctionParser<Validate> validator(context, source, length, signature, functionIndexSpace, info);440 String validateFunction(const uint8_t* source, size_t length, const Signature* signature, const ImmutableFunctionIndexSpace& functionIndexSpace, const ModuleInformation& module) 441 { 442 Validate context(signature->returnType, module); 443 FunctionParser<Validate> validator(context, source, length, signature, functionIndexSpace, module); 408 444 409 445 if (!validator.parse()) { -
trunk/Source/JavaScriptCore/wasm/generateWasmOpsHeader.py
r209503 r209830 151 151 #undef CREATE_CASE 152 152 153 #define CREATE_CASE(name, id, b3type, inc) case name: return "name";153 #define CREATE_CASE(name, id, b3type, inc) case name: return #name; 154 154 inline const char* toString(Type type) 155 155 { -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp
r209771 r209830 39 39 namespace JSC { 40 40 41 JSWebAssemblyInstance* JSWebAssemblyInstance::create(VM& vm, Structure* structure, JSWebAssemblyModule* module, JSModuleNamespaceObject* moduleNamespaceObject , unsigned numImportFunctions)41 JSWebAssemblyInstance* JSWebAssemblyInstance::create(VM& vm, Structure* structure, JSWebAssemblyModule* module, JSModuleNamespaceObject* moduleNamespaceObject) 42 42 { 43 auto* instance = new (NotNull, allocateCell<JSWebAssemblyInstance>(vm.heap, allocationSize(numImportFunctions))) JSWebAssemblyInstance(vm, structure, numImportFunctions); 43 // FIXME: These objects could be pretty big we should try to throw OOM here. 44 auto* instance = new (NotNull, allocateCell<JSWebAssemblyInstance>(vm.heap, allocationSize(module->moduleInformation().importFunctions.size()))) JSWebAssemblyInstance(vm, structure, module->moduleInformation().importFunctions.size()); 44 45 instance->finishCreation(vm, module, moduleNamespaceObject); 45 46 return instance; … … 62 63 Base::finishCreation(vm); 63 64 ASSERT(inherits(info())); 65 66 const size_t extraMemorySize = module->moduleInformation().globals.size() * sizeof(Register); 67 m_globals = MallocPtr<uint64_t>::malloc(extraMemorySize); 68 heap()->reportExtraMemoryAllocated(extraMemorySize); 69 64 70 m_module.set(vm, this, module); 65 71 m_moduleNamespaceObject.set(vm, this, moduleNamespaceObject); … … 82 88 visitor.append(&thisObject->m_memory); 83 89 visitor.append(&thisObject->m_table); 90 visitor.reportExtraMemoryVisited(thisObject->module()->moduleInformation().globals.size()); 84 91 for (unsigned i = 0; i < thisObject->m_numImportFunctions; ++i) 85 92 visitor.append(thisObject->importFunction(i)); -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h
r209771 r209830 43 43 44 44 45 static JSWebAssemblyInstance* create(VM&, Structure*, JSWebAssemblyModule*, JSModuleNamespaceObject* , unsigned);45 static JSWebAssemblyInstance* create(VM&, Structure*, JSWebAssemblyModule*, JSModuleNamespaceObject*); 46 46 static Structure* createStructure(VM&, JSGlobalObject*, JSValue); 47 47 … … 76 76 void setTable(VM& vm, JSWebAssemblyTable* table) { m_table.set(vm, this, table); } 77 77 78 int32_t loadI32Global(unsigned i) const { return m_globals.get()[i]; } 79 int64_t loadI64Global(unsigned i) const { return m_globals.get()[i]; } 80 float loadF32Global(unsigned i) const { return bitwise_cast<float>(loadI32Global(i)); } 81 double loadF64Global(unsigned i) const { return bitwise_cast<double>(loadI64Global(i)); } 82 void setGlobal(unsigned i, int64_t bits) { m_globals.get()[i] = bits; } 83 78 84 static size_t offsetOfImportFunction(unsigned idx) 79 85 { … … 82 88 83 89 static ptrdiff_t offsetOfTable() { return OBJECT_OFFSETOF(JSWebAssemblyInstance, m_table); } 90 static ptrdiff_t offsetOfGlobals() { return OBJECT_OFFSETOF(JSWebAssemblyInstance, m_globals); } 84 91 85 92 protected: 86 JSWebAssemblyInstance(VM&, Structure*, unsigned );93 JSWebAssemblyInstance(VM&, Structure*, unsigned numImportFunctions); 87 94 void finishCreation(VM&, JSWebAssemblyModule*, JSModuleNamespaceObject*); 88 95 static void destroy(JSCell*); … … 104 111 WriteBarrier<JSWebAssemblyMemory> m_memory; 105 112 WriteBarrier<JSWebAssemblyTable> m_table; 113 MallocPtr<uint64_t> m_globals; 106 114 unsigned m_numImportFunctions; 107 115 }; -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyInstanceConstructor.cpp
r209771 r209830 82 82 RETURN_IF_EXCEPTION(throwScope, { }); 83 83 84 JSWebAssemblyInstance* instance = JSWebAssemblyInstance::create(vm, instanceStructure, jsModule, moduleRecord->getModuleNamespace(exec) , moduleInformation.imports.size());84 JSWebAssemblyInstance* instance = JSWebAssemblyInstance::create(vm, instanceStructure, jsModule, moduleRecord->getModuleNamespace(exec)); 85 85 RETURN_IF_EXCEPTION(throwScope, { }); 86 86 … … 88 88 // Let imports be an initially-empty list of external values. 89 89 unsigned numImportFunctions = 0; 90 91 // FIXME implement Global https://bugs.webkit.org/show_bug.cgi?id=164133 90 unsigned numImportGlobals = 0; 92 91 93 92 bool hasMemoryImport = false; … … 196 195 case Wasm::External::Global: { 197 196 // 5. If i is a global import: 198 // FIXME implement Global https://bugs.webkit.org/show_bug.cgi?id=164133199 197 // i. If i is not an immutable global, throw a TypeError. 198 ASSERT(moduleInformation.globals[import.kindIndex].mutability == Wasm::Global::Immutable); 200 199 // ii. If Type(v) is not Number, throw a TypeError. 200 if (!value.isNumber()) 201 return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, ASCIILiteral("imported global must be a number"), defaultSourceAppender, runtimeTypeForValue(value)))); 201 202 // iii. Append ToWebAssemblyValue(v) to imports. 202 RELEASE_ASSERT_NOT_REACHED(); 203 switch (moduleInformation.globals[import.kindIndex].type) { 204 case Wasm::I32: 205 instance->setGlobal(numImportGlobals++, value.toInt32(exec)); 206 break; 207 case Wasm::F32: 208 instance->setGlobal(numImportGlobals++, bitwise_cast<uint32_t>(value.toFloat(exec))); 209 break; 210 case Wasm::F64: 211 instance->setGlobal(numImportGlobals++, bitwise_cast<uint64_t>(value.asNumber())); 212 break; 213 default: 214 RELEASE_ASSERT_NOT_REACHED(); 215 } 216 ASSERT(!throwScope.exception()); 203 217 break; 204 218 } … … 242 256 } 243 257 258 // Globals 259 { 260 ASSERT(numImportGlobals == moduleInformation.firstInternalGlobal); 261 for (size_t globalIndex = numImportGlobals; globalIndex < moduleInformation.globals.size(); ++globalIndex) { 262 const auto& global = moduleInformation.globals[globalIndex]; 263 ASSERT(global.initializationType != Wasm::Global::IsImport); 264 if (global.initializationType == Wasm::Global::FromGlobalImport) { 265 ASSERT(global.initialBitsOrImportNumber < numImportGlobals); 266 instance->setGlobal(globalIndex, instance->loadI64Global(global.initialBitsOrImportNumber)); 267 } else 268 instance->setGlobal(globalIndex, global.initialBitsOrImportNumber); 269 } 270 } 271 244 272 moduleRecord->link(exec, instance); 245 273 RETURN_IF_EXCEPTION(throwScope, { }); 274 246 275 if (verbose) 247 276 moduleRecord->dump(); -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp
r209785 r209830 86 86 } 87 87 case Wasm::External::Global: { 88 // FIXME https://bugs.webkit.org/show_bug.cgi?id=16413389 88 // In the MVP, only immutable global variables can be exported. 89 addExportEntry(ExportEntry::createLocal(exp.field, exp.field)); 90 90 break; 91 91 } … … 129 129 // i. If there is an Exported Function Exotic Object func in funcs whose func.[[Closure]] equals c, then return func. 130 130 // ii. (Note: At most one wrapper is created for any closure, so func is unique, even if there are multiple occurrances in the list. Moreover, if the item was an import that is already an Exported Function Exotic Object, then the original function object will be found. For imports that are regular JS functions, a new wrapper will be created.) 131 if (exp. functionIndex < importCount) {131 if (exp.kindIndex < importCount) { 132 132 // FIXME Implement re-exporting an import. https://bugs.webkit.org/show_bug.cgi?id=165510 133 133 RELEASE_ASSERT_NOT_REACHED(); … … 137 137 // b. Append func to funcs. 138 138 // c. Return func. 139 JSWebAssemblyCallee* jsEntrypointCallee = module->jsEntrypointCalleeFromFunctionIndexSpace(exp. functionIndex);140 JSWebAssemblyCallee* wasmEntrypointCallee = module->wasmEntrypointCalleeFromFunctionIndexSpace(exp. functionIndex);141 Wasm::Signature* signature = module->signatureForFunctionIndexSpace(exp. functionIndex);139 JSWebAssemblyCallee* jsEntrypointCallee = module->jsEntrypointCalleeFromFunctionIndexSpace(exp.kindIndex); 140 JSWebAssemblyCallee* wasmEntrypointCallee = module->wasmEntrypointCalleeFromFunctionIndexSpace(exp.kindIndex); 141 Wasm::Signature* signature = module->signatureForFunctionIndexSpace(exp.kindIndex); 142 142 WebAssemblyFunction* function = WebAssemblyFunction::create(vm, globalObject, signature->arguments.size(), exp.field.string(), instance, jsEntrypointCallee, wasmEntrypointCallee, signature); 143 143 exportedValue = function; 144 if (hasStart && startFunctionIndexSpace == exp. functionIndex)144 if (hasStart && startFunctionIndexSpace == exp.kindIndex) 145 145 m_startFunction.set(vm, this, function); 146 146 break; … … 154 154 break; 155 155 } 156 156 157 case Wasm::External::Global: { 157 // FIXME https://bugs.webkit.org/show_bug.cgi?id=164133 158 // In the MVP, only immutable global variables can be exported. 158 // Assert: the global is immutable by MVP validation constraint. 159 const Wasm::Global& global = moduleInformation.globals[exp.kindIndex]; 160 ASSERT(global.mutability == Wasm::Global::Immutable); 161 // Return ToJSValue(v). 162 switch (global.type) { 163 case Wasm::I32: 164 exportedValue = JSValue(instance->loadI32Global(exp.kindIndex)); 165 break; 166 167 case Wasm::F32: 168 exportedValue = JSValue(instance->loadF32Global(exp.kindIndex)); 169 break; 170 171 case Wasm::F64: 172 exportedValue = JSValue(instance->loadF64Global(exp.kindIndex)); 173 break; 174 175 default: 176 RELEASE_ASSERT_NOT_REACHED(); 177 } 159 178 break; 160 179 }
Note: See TracChangeset
for help on using the changeset viewer.