Changeset 210026 in webkit
- Timestamp:
- Dec 20, 2016 10:54:33 AM (7 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 25 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r210010 r210026 1 2016-12-20 JF Bastien <jfbastien@apple.com> 2 3 WebAssembly: unique function signatures 4 https://bugs.webkit.org/show_bug.cgi?id=165957 5 <rdar://problem/29735737> 6 7 Reviewed by Saam Barati. 8 9 * wasm/function-tests/table-basic.js: FIXME is now addressed, 10 though instance to instance calls still need work which bug 11 #165282 will address 12 (i.assert.eq.foo): 13 * wasm/js-api/unique-signature.js: Added. 14 (CallIndirectWithDuplicateSignatures): 15 1 16 2016-12-19 Mark Lam <mark.lam@apple.com> 2 17 -
trunk/JSTests/wasm/function-tests/table-basic.js
r209928 r210026 45 45 assert.eq(table.get(0), exports.bar); 46 46 47 for (let i = 0; i < 1000; i++) { 48 if (foo(0, i) !== i + 42) 49 throw new Error("Bad call indirect"); 50 } 47 for (let i = 0; i < 1000; i++) 48 assert.eq(foo(0, i), i + 42, "call_indirect"); 51 49 } 52 50 53 // FIXME: make this work cross module. The reason it doesn't54 // now is that we don't unique Signature*.55 // https://bugs.webkit.org/show_bug.cgi?id=16551156 51 { 57 52 const {instance, table} = makeInstance(); … … 59 54 table.set(0, makeInstance().instance.exports.bar); // Cross instance function. 60 55 61 for (let i = 0; i < 1000; i++) { 62 assert.throws(() => foo(0, i), WebAssembly.RuntimeError, "call_indirect to a signature that does not match"); 63 } 56 for (let i = 0; i < 1000; i++) 57 assert.eq(foo(0, i), i + 42, "call_indirect"); 64 58 } -
trunk/Source/JavaScriptCore/CMakeLists.txt
r209928 r210026 907 907 wasm/WasmModuleParser.cpp 908 908 wasm/WasmPlan.cpp 909 wasm/WasmSignature.cpp 909 910 wasm/WasmValidate.cpp 910 911 -
trunk/Source/JavaScriptCore/ChangeLog
r210023 r210026 1 2016-12-20 JF Bastien <jfbastien@apple.com> 2 3 WebAssembly: unique function signatures 4 https://bugs.webkit.org/show_bug.cgi?id=165957 5 <rdar://problem/29735737> 6 7 Reviewed by Saam Barati. 8 9 Signatures in a Module's Type section can be duplicated, we 10 therefore need to unique them so that call_indirect only needs to 11 do a single integer compare to check that a callee's Signature is 12 the same as the Signature declared at the call site. Without 13 uniquing we'd either trap when duplicate Signatures are used, or 14 we'd need to do multiple comparisons. This patch makes that narrow 15 usecase function correctly. 16 17 There's further complication when calling from wasm to 18 wasm, in which case the Signatures must also match. Such 19 cross-instance calls will be improved in bug #165282, but this 20 patch sets the groundwork for it: 21 22 - Signatures are now owned by SignatureInformation which lives on 23 VM, and is shared by all Modules. 24 - When parsing a Module, a Signature is created for every Type 25 entry, and then uniqued by SignatureInformation's adopt 26 method. Duplicate Signatures are dropped and the previous 27 SignatureIndex is returned, new Signatures are adopted and a new 28 SignatureIndex is created. 29 - The SignatureIndex values are monotonic. 0 is used to represent 30 invalid indices, which trap. This can only occur through Table. 31 - SignatureInformation is used while generating code to map a 32 SignatureIndex back to the Signature* when return / argument 33 information is needed. This is a simple lookup into a Vector. It 34 isn't used at runtime. 35 - These Signatures live forever on VM because the bookkeeping 36 likely isn't worth it. We may want to empty things out if all 37 Modules die, this is tracked in bug #166037. 38 - We can further improve things by bit-packing SignatureIndex with 39 Code*, which is tracked by bug #165511. 40 41 * CMakeLists.txt: 42 * JavaScriptCore.xcodeproj/project.pbxproj: 43 * runtime/VM.h: wasm signatures are uniqued here, but aren't accessed frequently (only during parsing) so indirection is fine 44 * wasm/WasmB3IRGenerator.cpp: use SignatureIndex instead of Signature* when appropriate, and when still using Signature* do so with its new API 45 (JSC::Wasm::createJSToWasmWrapper): 46 (JSC::Wasm::parseAndCompile): 47 * wasm/WasmBinding.cpp: 48 (JSC::Wasm::importStubGenerator): use SignatureIndex 49 * wasm/WasmBinding.h: 50 * wasm/WasmCallingConvention.h: 51 (JSC::Wasm::CallingConvention::loadArguments): 52 * wasm/WasmFormat.cpp: drive-by move of alloc/free functions to the implementation file, allows the .h file to drop an FastMalloc.h 53 (JSC::Wasm::Segment::create): 54 (JSC::Wasm::Segment::destroy): 55 (JSC::Wasm::Segment::createPtr): 56 * wasm/WasmFormat.h: move Signature to its own file 57 (JSC::Wasm::CallableFunction::CallableFunction): 58 * wasm/WasmFunctionParser.h: 59 (JSC::Wasm::FunctionParser<Context>::FunctionParser): 60 * wasm/WasmModuleParser.cpp: 61 * wasm/WasmModuleParser.h: 62 (JSC::Wasm::ModuleParser::ModuleParser): 63 * wasm/WasmParser.h: 64 (JSC::Wasm::Parser<SuccessType>::Parser): 65 * wasm/WasmPlan.cpp: 66 (JSC::Wasm::Plan::parseAndValidateModule): 67 (JSC::Wasm::Plan::run): 68 * wasm/WasmSignature.cpp: Added. 69 (JSC::Wasm::Signature::dump): 70 (JSC::Wasm::Signature::hash): 71 (JSC::Wasm::Signature::create): 72 (JSC::Wasm::Signature::createInvalid): 73 (JSC::Wasm::Signature::destroy): 74 (JSC::Wasm::SignatureInformation::~SignatureInformation): 75 (JSC::Wasm::SignatureInformation::adopt): 76 (JSC::Wasm::SignatureInformation::get): 77 * wasm/WasmSignature.h: Added. 78 (JSC::Wasm::Signature::Signature): 79 (JSC::Wasm::Signature::storage): 80 (JSC::Wasm::Signature::allocatedSize): 81 (JSC::Wasm::Signature::returnType): 82 (JSC::Wasm::Signature::returnCount): 83 (JSC::Wasm::Signature::argumentCount): 84 (JSC::Wasm::Signature::argument): 85 (JSC::Wasm::Signature::operator==): 86 (JSC::Wasm::SignatureHash::empty): 87 (JSC::Wasm::SignatureHash::deleted): 88 (JSC::Wasm::SignatureHash::SignatureHash): 89 (JSC::Wasm::SignatureHash::operator==): 90 (JSC::Wasm::SignatureHash::equal): 91 (JSC::Wasm::SignatureHash::hash): 92 (JSC::Wasm::SignatureHash::isHashTableDeletedValue): 93 * wasm/WasmValidate.cpp: 94 (JSC::Wasm::validateFunction): 95 * wasm/WasmValidate.h: 96 * wasm/js/JSWebAssemblyInstance.cpp: 97 (JSC::JSWebAssemblyInstance::create): 98 * wasm/js/JSWebAssemblyModule.h: 99 (JSC::JSWebAssemblyModule::signatureForFunctionIndexSpace): 100 * wasm/js/JSWebAssemblyTable.cpp: 101 (JSC::JSWebAssemblyTable::JSWebAssemblyTable): 102 (JSC::JSWebAssemblyTable::clearFunction): 103 (JSC::JSWebAssemblyTable::setFunction): 104 * wasm/js/WebAssemblyFunction.cpp: 105 (JSC::callWebAssemblyFunction): 106 (JSC::WebAssemblyFunction::call): 107 (JSC::WebAssemblyFunction::create): 108 (JSC::WebAssemblyFunction::WebAssemblyFunction): 109 (JSC::WebAssemblyFunction::finishCreation): 110 * wasm/js/WebAssemblyFunction.h: 111 (JSC::WebAssemblyFunction::signatureIndex): 112 * wasm/js/WebAssemblyModuleRecord.cpp: 113 (JSC::WebAssemblyModuleRecord::link): 114 (JSC::WebAssemblyModuleRecord::evaluate): 115 1 116 2016-12-20 Konstantin Tokarev <annulen@yandex.ru> 2 117 -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r209928 r210026 2023 2023 AD4B1DF91DF244E20071AE32 /* WasmBinding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD4B1DF71DF244D70071AE32 /* WasmBinding.cpp */; }; 2024 2024 AD4B1DFA1DF244E20071AE32 /* WasmBinding.h in Headers */ = {isa = PBXBuildFile; fileRef = AD4B1DF81DF244D70071AE32 /* WasmBinding.h */; }; 2025 AD7438C01E0457A400FD0C2A /* WasmSignature.h in Headers */ = {isa = PBXBuildFile; fileRef = AD7438BF1E04579200FD0C2A /* WasmSignature.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2026 AD7438C11E0457AA00FD0C2A /* WasmSignature.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD7438BE1E04579200FD0C2A /* WasmSignature.cpp */; }; 2025 2027 AD86A93E1AA4D88D002FE77F /* WeakGCMapInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = AD86A93D1AA4D87C002FE77F /* WeakGCMapInlines.h */; settings = {ATTRIBUTES = (Private, ); }; }; 2026 2028 ADBC54D41DF8EA2B005BF738 /* WebAssemblyToJSCallee.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ADBC54D21DF8EA00005BF738 /* WebAssemblyToJSCallee.cpp */; }; … … 4499 4501 AD4B1DF71DF244D70071AE32 /* WasmBinding.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmBinding.cpp; sourceTree = "<group>"; }; 4500 4502 AD4B1DF81DF244D70071AE32 /* WasmBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmBinding.h; sourceTree = "<group>"; }; 4503 AD7438BE1E04579200FD0C2A /* WasmSignature.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmSignature.cpp; sourceTree = "<group>"; }; 4504 AD7438BF1E04579200FD0C2A /* WasmSignature.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmSignature.h; sourceTree = "<group>"; }; 4501 4505 AD86A93D1AA4D87C002FE77F /* WeakGCMapInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakGCMapInlines.h; sourceTree = "<group>"; }; 4502 4506 ADBC54D21DF8EA00005BF738 /* WebAssemblyToJSCallee.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebAssemblyToJSCallee.cpp; path = js/WebAssemblyToJSCallee.cpp; sourceTree = "<group>"; }; … … 6035 6039 531374BC1D5CE67600AF7A0B /* WasmPlan.h */, 6036 6040 53F40E841D58F9770099A1B6 /* WasmSections.h */, 6041 AD7438BE1E04579200FD0C2A /* WasmSignature.cpp */, 6042 AD7438BF1E04579200FD0C2A /* WasmSignature.h */, 6037 6043 53FF7F9A1DBFD2B900A26CCC /* WasmValidate.cpp */, 6038 6044 53FF7F981DBFCD9000A26CCC /* WasmValidate.h */, … … 8052 8058 0F9D36951AE9CC33000D4DFB /* DFGCleanUpPhase.h in Headers */, 8053 8059 A77A424017A0BBFD00A8DB81 /* DFGClobberize.h in Headers */, 8060 AD7438C01E0457A400FD0C2A /* WasmSignature.h in Headers */, 8054 8061 A77A424217A0BBFD00A8DB81 /* DFGClobberSet.h in Headers */, 8055 8062 0F3C1F1B1B868E7900ABB08B /* DFGClobbersExitState.h in Headers */, … … 10394 10401 0F919D2515853CE0004A4E7D /* Watchpoint.cpp in Sources */, 10395 10402 1ACF7377171CA6FB00C9BB1E /* Weak.cpp in Sources */, 10403 AD7438C11E0457AA00FD0C2A /* WasmSignature.cpp in Sources */, 10396 10404 14E84F9E14EE1ACC00D6D5D4 /* WeakBlock.cpp in Sources */, 10397 10405 14F7256514EE265E00B1652B /* WeakHandleOwner.cpp in Sources */, -
trunk/Source/JavaScriptCore/runtime/VM.h
r209764 r210026 148 148 class Signature; 149 149 } 150 #if ENABLE(WEBASSEMBLY) 151 namespace Wasm { 152 class SignatureInformation; 153 } 154 #endif 150 155 151 156 struct HashTable; … … 355 360 Strong<JSCell> emptyPropertyNameEnumerator; 356 361 362 #if ENABLE(WEBASSEMBLY) 363 std::once_flag m_wasmSignatureInformationOnceFlag; 364 std::unique_ptr<Wasm::SignatureInformation> m_wasmSignatureInformation; 365 #endif 366 357 367 AtomicStringTable* m_atomicStringTable; 358 368 WTF::SymbolRegistry m_symbolRegistry; -
trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp
r209966 r210026 155 155 B3IRGenerator(VM&, const ModuleInformation&, Procedure&, WasmInternalFunction*, Vector<UnlinkedWasmToWasmCall>&, const ImmutableFunctionIndexSpace&); 156 156 157 PartialResult WARN_UNUSED_RETURN addArguments(const Vector<Type>&);157 PartialResult WARN_UNUSED_RETURN addArguments(const Signature*); 158 158 PartialResult WARN_UNUSED_RETURN addLocal(Type, uint32_t); 159 159 ExpressionType addConstant(Type, uint64_t); … … 193 193 // Calls 194 194 PartialResult WARN_UNUSED_RETURN addCall(uint32_t calleeIndex, const Signature*, Vector<ExpressionType>& args, ExpressionType& result); 195 PartialResult WARN_UNUSED_RETURN addCallIndirect(const Signature*, Vector<ExpressionType>& args, ExpressionType& result);195 PartialResult WARN_UNUSED_RETURN addCallIndirect(const Signature*, SignatureIndex, Vector<ExpressionType>& args, ExpressionType& result); 196 196 PartialResult WARN_UNUSED_RETURN addUnreachable(); 197 197 … … 303 303 } 304 304 305 auto B3IRGenerator::addArguments(const Vector<Type>& types) -> PartialResult305 auto B3IRGenerator::addArguments(const Signature* signature) -> PartialResult 306 306 { 307 307 ASSERT(!m_locals.size()); 308 WASM_COMPILE_FAIL_IF(!m_locals.tryReserveCapacity( types.size()), "can't allocate memory for ", types.size(), " arguments");309 310 m_locals.grow( types.size());311 wasmCallingConvention().loadArguments( types, m_proc, m_currentBlock, Origin(),308 WASM_COMPILE_FAIL_IF(!m_locals.tryReserveCapacity(signature->argumentCount()), "can't allocate memory for ", signature->argumentCount(), " arguments"); 309 310 m_locals.grow(signature->argumentCount()); 311 wasmCallingConvention().loadArguments(signature, m_proc, m_currentBlock, Origin(), 312 312 [&] (ExpressionType argument, unsigned i) { 313 313 Variable* argumentVariable = m_proc.addVariable(argument->type()); … … 683 683 auto B3IRGenerator::addCall(uint32_t functionIndex, const Signature* signature, Vector<ExpressionType>& args, ExpressionType& result) -> PartialResult 684 684 { 685 ASSERT(signature->argument s.size() == args.size());686 687 Type returnType = signature->returnType ;685 ASSERT(signature->argumentCount() == args.size()); 686 687 Type returnType = signature->returnType(); 688 688 689 689 result = wasmCallingConvention().setupCall(m_proc, m_currentBlock, Origin(), args, toB3Type(returnType), … … 705 705 } 706 706 707 auto B3IRGenerator::addCallIndirect(const Signature* signature, Vector<ExpressionType>& args, ExpressionType& result) -> PartialResult 708 { 707 auto B3IRGenerator::addCallIndirect(const Signature* signature, SignatureIndex signatureIndex, Vector<ExpressionType>& args, ExpressionType& result) -> PartialResult 708 { 709 ASSERT(signatureIndex != Signature::invalidIndex); 709 710 ExpressionType calleeIndex = args.takeLast(); 710 ASSERT(signature->argument s.size() == args.size());711 ASSERT(signature->argumentCount() == args.size()); 711 712 712 713 ExpressionType callableFunctionBuffer; … … 737 738 ExpressionType callableFunction = m_currentBlock->appendNew<Value>(m_proc, Add, Origin(), callableFunctionBuffer, offset); 738 739 739 // Check that the CallableFunction is initialized. We trap if it isn't. A null Signature* indicates it's not initialized. 740 ExpressionType calleeSignature = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), Origin(), callableFunction, OBJECT_OFFSETOF(CallableFunction, signature)); 740 // Check that the CallableFunction is initialized. We trap if it isn't. An "invalid" SignatureIndex indicates it's not initialized. 741 static_assert(sizeof(CallableFunction::signatureIndex) == sizeof(uint32_t), "Load codegen assumes i32"); 742 ExpressionType calleeSignatureIndex = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, Int32, Origin(), callableFunction, OBJECT_OFFSETOF(CallableFunction, signatureIndex)); 741 743 { 742 744 CheckValue* check = m_currentBlock->appendNew<CheckValue>(m_proc, Check, Origin(), 743 m_currentBlock->appendNew<Value>(m_proc, Equal, Origin(), 744 calleeSignature ,745 m_currentBlock->appendNew<Const PtrValue>(m_proc, Origin(), 0)));745 m_currentBlock->appendNew<Value>(m_proc, Equal, Origin(), 746 calleeSignatureIndex, 747 m_currentBlock->appendNew<Const32Value>(m_proc, Origin(), Signature::invalidIndex))); 746 748 747 749 check->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { … … 752 754 // Check the signature matches the value we expect. 753 755 { 754 ExpressionType expectedSignature = m_currentBlock->appendNew<ConstPtrValue>(m_proc, Origin(), signature);756 ExpressionType expectedSignatureIndex = m_currentBlock->appendNew<Const32Value>(m_proc, Origin(), signatureIndex); 755 757 CheckValue* check = m_currentBlock->appendNew<CheckValue>(m_proc, Check, Origin(), 756 m_currentBlock->appendNew<Value>(m_proc, NotEqual, Origin(), calleeSignature , expectedSignature));758 m_currentBlock->appendNew<Value>(m_proc, NotEqual, Origin(), calleeSignatureIndex, expectedSignatureIndex)); 757 759 758 760 check->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams&) { … … 763 765 ExpressionType calleeCode = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), Origin(), callableFunction, OBJECT_OFFSETOF(CallableFunction, code)); 764 766 765 Type returnType = signature->returnType ;767 Type returnType = signature->returnType(); 766 768 result = wasmCallingConvention().setupCall(m_proc, m_currentBlock, Origin(), args, toB3Type(returnType), 767 769 [&] (PatchpointValue* patchpoint) { … … 835 837 block->appendNew<Value>(proc, Add, origin, framePointer, offSetOfArgumentCount)); 836 838 837 Value* expectedArgumentCount = block->appendNew<Const32Value>(proc, origin, signature->argument s.size());839 Value* expectedArgumentCount = block->appendNew<Const32Value>(proc, origin, signature->argumentCount()); 838 840 839 841 CheckValue* argumentCountCheck = block->appendNew<CheckValue>(proc, Check, origin, … … 862 864 // Get our arguments. 863 865 Vector<Value*> arguments; 864 jscCallingConvention().loadArguments(signature ->arguments, proc, block, origin, [&] (Value* argument, unsigned) {866 jscCallingConvention().loadArguments(signature, proc, block, origin, [&] (Value* argument, unsigned) { 865 867 arguments.append(argument); 866 868 }); 867 869 868 870 // Move the arguments into place. 869 Value* result = wasmCallingConvention().setupCall(proc, block, origin, arguments, toB3Type(signature->returnType ), [&] (PatchpointValue* patchpoint) {871 Value* result = wasmCallingConvention().setupCall(proc, block, origin, arguments, toB3Type(signature->returnType()), [&] (PatchpointValue* patchpoint) { 870 872 if (!!memory) { 871 873 ASSERT(sizes.size() == memory.pinnedRegisters().sizeRegisters.size()); … … 886 888 887 889 // Return the result, if needed. 888 switch (signature->returnType ) {890 switch (signature->returnType()) { 889 891 case Wasm::Void: 890 892 block->appendNewControlValue(proc, B3::Return, origin); … … 914 916 Procedure procedure; 915 917 B3IRGenerator context(vm, info, procedure, result.get(), unlinkedWasmToWasmCalls, functionIndexSpace); 916 FunctionParser<B3IRGenerator> parser( context, functionStart, functionLength, signature, functionIndexSpace, info);918 FunctionParser<B3IRGenerator> parser(&vm, context, functionStart, functionLength, signature, functionIndexSpace, info); 917 919 WASM_FAIL_IF_HELPER_FAILS(parser.parse()); 918 920 -
trunk/Source/JavaScriptCore/wasm/WasmBinding.cpp
r209963 r210026 37 37 namespace JSC { namespace Wasm { 38 38 39 WasmToJSStub importStubGenerator(VM* vm, Bag<CallLinkInfo>& callLinkInfos, Signature * signature, unsigned importIndex)39 WasmToJSStub importStubGenerator(VM* vm, Bag<CallLinkInfo>& callLinkInfos, SignatureIndex signatureIndex, unsigned importIndex) 40 40 { 41 41 const WasmCallingConvention& wasmCC = wasmCallingConvention(); 42 42 const JSCCallingConvention& jsCC = jscCallingConvention(); 43 unsigned argCount = signature->arguments.size(); 43 const Signature* signature = SignatureInformation::get(vm, signatureIndex); 44 unsigned argCount = signature->argumentCount(); 44 45 typedef AssemblyHelpers JIT; 45 46 JIT jit(vm, nullptr); … … 73 74 unsigned frOffset = CallFrameSlot::firstArgument * static_cast<int>(sizeof(Register)); 74 75 for (unsigned argNum = 0; argNum < argCount; ++argNum) { 75 Type argType = signature->argument s[argNum];76 Type argType = signature->argument(argNum); 76 77 switch (argType) { 77 78 case Void: … … 162 163 done.link(&jit); 163 164 164 switch (signature->returnType ) {165 switch (signature->returnType()) { 165 166 case Void: 166 167 // Discard. … … 231 232 CodeLocationNearCall hotPathOther = patchBuffer.locationOfNearCall(fastCall); 232 233 callLinkInfo->setCallLocations(callReturnLocation, hotPathBegin, hotPathOther); 233 return FINALIZE_CODE(patchBuffer, ("WebAssembly import[%i] stub for signature % p", importIndex, signature));234 return FINALIZE_CODE(patchBuffer, ("WebAssembly import[%i] stub for signature %i", importIndex, signatureIndex)); 234 235 } 235 236 -
trunk/Source/JavaScriptCore/wasm/WasmBinding.h
r209560 r210026 39 39 namespace Wasm { 40 40 41 WasmToJSStub importStubGenerator(VM*, Bag<CallLinkInfo>&, Signature *, unsigned);41 WasmToJSStub importStubGenerator(VM*, Bag<CallLinkInfo>&, SignatureIndex, unsigned); 42 42 43 43 } } // namespace JSC::Wasm -
trunk/Source/JavaScriptCore/wasm/WasmCallingConvention.h
r209696 r210026 119 119 120 120 template<typename Functor> 121 void loadArguments(const Vector<Type>& argumentTypes, B3::Procedure& proc, B3::BasicBlock* block, B3::Origin origin, const Functor& functor) const121 void loadArguments(const Signature* signature, B3::Procedure& proc, B3::BasicBlock* block, B3::Origin origin, const Functor& functor) const 122 122 { 123 123 B3::Value* framePointer = block->appendNew<B3::Value>(proc, B3::FramePointer, origin); … … 127 127 size_t stackOffset = headerSize; 128 128 129 for (size_t i = 0; i < argumentTypes.size(); ++i) {130 B3::Type type = toB3Type( argumentTypes[i]);129 for (size_t i = 0; i < signature->argumentCount(); ++i) { 130 B3::Type type = toB3Type(signature->argument(i)); 131 131 B3::Value* argument; 132 132 B3::ValueRep rep = marshallArgument(type, gpArgumentCount, fpArgumentCount, stackOffset); -
trunk/Source/JavaScriptCore/wasm/WasmFormat.cpp
r209642 r210026 31 31 32 32 #include "WasmMemory.h" 33 #include <wtf/FastMalloc.h> 33 34 34 35 namespace JSC { namespace Wasm { 36 37 Segment* Segment::create(uint32_t offset, uint32_t sizeInBytes) 38 { 39 auto allocated = tryFastCalloc(sizeof(Segment) + sizeInBytes, 1); 40 Segment* segment; 41 if (!allocated.getValue(segment)) 42 return nullptr; 43 segment->offset = offset; 44 segment->sizeInBytes = sizeInBytes; 45 return segment; 46 } 47 48 void Segment::destroy(Segment *segment) 49 { 50 fastFree(segment); 51 } 52 53 Segment::Ptr Segment::adoptPtr(Segment* segment) 54 { 55 return Ptr(segment, &Segment::destroy); 56 } 35 57 36 58 JS_EXPORT_PRIVATE ModuleInformation::~ModuleInformation() { } -
trunk/Source/JavaScriptCore/wasm/WasmFormat.h
r209880 r210026 1 1 /* 2 * Copyright (C) 2015 Apple Inc. All rights reserved.2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved. 3 3 * 4 4 * Redistribution and use in source and binary forms, with or without … … 37 37 #include "WasmOps.h" 38 38 #include "WasmPageCount.h" 39 #include "WasmSignature.h" 40 #include <limits> 39 41 #include <memory> 40 #include <wtf/FastMalloc.h>41 42 #include <wtf/Optional.h> 42 43 #include <wtf/Vector.h> … … 101 102 } 102 103 103 struct Signature {104 Type returnType;105 Vector<Type> arguments;106 };107 108 104 struct Import { 109 105 Identifier module; … … 147 143 uint32_t sizeInBytes; 148 144 // Bytes are allocated at the end. 149 static Segment* make(uint32_t offset, uint32_t sizeInBytes)150 {151 auto allocated = tryFastCalloc(sizeof(Segment) + sizeInBytes, 1);152 Segment* segment;153 if (!allocated.getValue(segment))154 return nullptr;155 segment->offset = offset;156 segment->sizeInBytes = sizeInBytes;157 return segment;158 }159 static void destroy(Segment *segment)160 {161 fastFree(segment);162 }163 145 uint8_t& byte(uint32_t pos) 164 146 { … … 166 148 return *reinterpret_cast<uint8_t*>(reinterpret_cast<char*>(this) + sizeof(offset) + sizeof(sizeInBytes) + pos); 167 149 } 150 static Segment* create(uint32_t, uint32_t); 151 static void destroy(Segment*); 168 152 typedef std::unique_ptr<Segment, decltype(&Segment::destroy)> Ptr; 169 static Ptr makePtr(Segment* segment) 170 { 171 return Ptr(segment, &Segment::destroy); 172 } 153 static Ptr adoptPtr(Segment*); 173 154 }; 174 155 … … 207 188 208 189 struct ModuleInformation { 209 Vector<Signature > signatures;190 Vector<SignatureIndex> signatureIndices; 210 191 Vector<Import> imports; 211 Vector<Signature *> importFunctions;212 Vector<Signature *> internalFunctionSignatures;192 Vector<SignatureIndex> importFunctionSignatureIndices; 193 Vector<SignatureIndex> internalFunctionSignatureIndices; 213 194 MemoryInformation memory; 214 195 Vector<Export> exports; … … 248 229 CallableFunction() = default; 249 230 250 CallableFunction(Signature * signature, void* code = nullptr)251 : signature (signature)231 CallableFunction(SignatureIndex signatureIndex, void* code = nullptr) 232 : signatureIndex(signatureIndex) 252 233 , code(code) 253 234 { 254 235 } 255 236 256 // FIXME pack this inside a (uniqued) integer (for correctness the parser should unique Signatures), 257 // and then pack that integer into the code pointer. https://bugs.webkit.org/show_bug.cgi?id=165511 258 Signature* signature { nullptr }; 237 // FIXME pack the SignatureIndex and the code pointer into one 64-bit value. https://bugs.webkit.org/show_bug.cgi?id=165511 238 SignatureIndex signatureIndex { Signature::invalidIndex }; 259 239 void* code { nullptr }; 260 240 }; -
trunk/Source/JavaScriptCore/wasm/WasmFunctionParser.h
r209955 r210026 46 46 typedef typename Context::ExpressionList ExpressionList; 47 47 48 FunctionParser( Context&, const uint8_t* functionStart, size_t functionLength, const Signature*, const ImmutableFunctionIndexSpace&, const ModuleInformation&);48 FunctionParser(VM*, Context&, const uint8_t* functionStart, size_t functionLength, const Signature*, const ImmutableFunctionIndexSpace&, const ModuleInformation&); 49 49 50 50 Result WARN_UNUSED_RETURN parse(); … … 89 89 90 90 template<typename Context> 91 FunctionParser<Context>::FunctionParser( Context& context, const uint8_t* functionStart, size_t functionLength, const Signature* signature, const ImmutableFunctionIndexSpace& functionIndexSpace, const ModuleInformation& info)92 : Parser( functionStart, functionLength)91 FunctionParser<Context>::FunctionParser(VM* vm, Context& context, const uint8_t* functionStart, size_t functionLength, const Signature* signature, const ImmutableFunctionIndexSpace& functionIndexSpace, const ModuleInformation& info) 92 : Parser(vm, functionStart, functionLength) 93 93 , m_context(context) 94 94 , m_signature(signature) … … 105 105 uint32_t localCount; 106 106 107 WASM_PARSER_FAIL_IF(!m_context.addArguments(m_signature ->arguments), "can't add ", m_signature->arguments.size(), " arguments to Function");107 WASM_PARSER_FAIL_IF(!m_context.addArguments(m_signature), "can't add ", m_signature->argumentCount(), " arguments to Function"); 108 108 WASM_PARSER_FAIL_IF(!parseVarUInt32(localCount), "can't get local count"); 109 109 WASM_PARSER_FAIL_IF(localCount == std::numeric_limits<uint32_t>::max(), "Function section's local count is too big ", localCount); … … 156 156 { 157 157 ExpressionList returnValues; 158 if (m_signature->returnType != Void) {158 if (m_signature->returnType() != Void) { 159 159 ExpressionType returnValue; 160 160 WASM_TRY_POP_EXPRESSION_STACK_INTO(returnValue, "return"); … … 330 330 WASM_PARSER_FAIL_IF(functionIndex >= m_functionIndexSpace.size, "call function index ", functionIndex, " exceeds function index space ", m_functionIndexSpace.size); 331 331 332 const Signature* calleeSignature = m_functionIndexSpace.buffer.get()[functionIndex].signature; 333 WASM_PARSER_FAIL_IF(calleeSignature->arguments.size() > m_expressionStack.size(), "call function index ", functionIndex, " has ", calleeSignature->arguments.size(), " arguments, but the expression stack currently holds ", m_expressionStack.size(), " values"); 334 335 size_t firstArgumentIndex = m_expressionStack.size() - calleeSignature->arguments.size(); 332 SignatureIndex calleeSignatureIndex = m_functionIndexSpace.buffer.get()[functionIndex].signatureIndex; 333 const Signature* calleeSignature = SignatureInformation::get(m_vm, calleeSignatureIndex); 334 WASM_PARSER_FAIL_IF(calleeSignature->argumentCount() > m_expressionStack.size(), "call function index ", functionIndex, " has ", calleeSignature->argumentCount(), " arguments, but the expression stack currently holds ", m_expressionStack.size(), " values"); 335 336 size_t firstArgumentIndex = m_expressionStack.size() - calleeSignature->argumentCount(); 336 337 Vector<ExpressionType> args; 337 WASM_PARSER_FAIL_IF(!args.tryReserveCapacity(calleeSignature->argument s.size()), "can't allocate enough memory for call's ", calleeSignature->arguments.size(), " arguments");338 WASM_PARSER_FAIL_IF(!args.tryReserveCapacity(calleeSignature->argumentCount()), "can't allocate enough memory for call's ", calleeSignature->argumentCount(), " arguments"); 338 339 for (size_t i = firstArgumentIndex; i < m_expressionStack.size(); ++i) 339 340 args.uncheckedAppend(m_expressionStack[i]); … … 356 357 WASM_PARSER_FAIL_IF(!parseVarUInt1(reserved), "can't get call_indirect's reserved byte"); 357 358 WASM_PARSER_FAIL_IF(reserved, "call_indirect's 'reserved' varuint1 must be 0x0"); 358 WASM_PARSER_FAIL_IF(m_info.signatures.size() <= signatureIndex, "call_indirect's signature index ", signatureIndex, " exceeds known signatures ", m_info.signatures.size()); 359 360 const Signature* calleeSignature = &m_info.signatures[signatureIndex]; 361 size_t argumentCount = calleeSignature->arguments.size() + 1; // Add the callee's index. 359 WASM_PARSER_FAIL_IF(m_info.signatureIndices.size() <= signatureIndex, "call_indirect's signature index ", signatureIndex, " exceeds known signatures ", m_info.signatureIndices.size()); 360 361 SignatureIndex calleeSignatureIndex = m_info.signatureIndices[signatureIndex]; 362 const Signature* calleeSignature = SignatureInformation::get(m_vm, calleeSignatureIndex); 363 size_t argumentCount = calleeSignature->argumentCount() + 1; // Add the callee's index. 362 364 WASM_PARSER_FAIL_IF(argumentCount > m_expressionStack.size(), "call_indirect expects ", argumentCount, " arguments, but the expression stack currently holds ", m_expressionStack.size(), " values"); 363 365 … … 370 372 371 373 ExpressionType result = Context::emptyExpression; 372 WASM_TRY_ADD_TO_CONTEXT(addCallIndirect(calleeSignature, args, result));374 WASM_TRY_ADD_TO_CONTEXT(addCallIndirect(calleeSignature, calleeSignatureIndex, args, result)); 373 375 374 376 if (result != Context::emptyExpression) -
trunk/Source/JavaScriptCore/wasm/WasmModuleParser.cpp
r209880 r210026 100 100 WASM_PARSER_FAIL_IF(!parseVarUInt32(count), "can't get Type section's count"); 101 101 WASM_PARSER_FAIL_IF(count == std::numeric_limits<uint32_t>::max(), "Type section's count is too big ", count); 102 WASM_PARSER_FAIL_IF(!m_result.module->signature s.tryReserveCapacity(count), "can't allocate enough memory for Type section's ", count, " entries");102 WASM_PARSER_FAIL_IF(!m_result.module->signatureIndices.tryReserveCapacity(count), "can't allocate enough memory for Type section's ", count, " entries"); 103 103 104 104 for (uint32_t i = 0; i < count; ++i) { … … 111 111 WASM_PARSER_FAIL_IF(!parseVarUInt32(argumentCount), "can't get ", i, "th Type's argument count"); 112 112 WASM_PARSER_FAIL_IF(argumentCount == std::numeric_limits<uint32_t>::max(), i, "th argument count is too big ", argumentCount); 113 WASM_PARSER_FAIL_IF(!argumentTypes.tryReserveCapacity(argumentCount), "can't allocate enough memory for Type section's ", i, "th ", argumentCount, " arguments"); 113 std::unique_ptr<Signature, void (*)(Signature*)> signature(Signature::create(argumentCount), &Signature::destroy); 114 WASM_PARSER_FAIL_IF(!signature, "can't allocate enough memory for Type section's ", i, "th signature"); 114 115 115 116 for (unsigned i = 0; i < argumentCount; ++i) { 116 117 Type argumentType; 117 118 WASM_PARSER_FAIL_IF(!parseResultType(argumentType), "can't get ", i, "th argument Type"); 118 argumentTypes.uncheckedAppend(argumentType);119 signature->argument(i) = argumentType; 119 120 } 120 121 … … 122 123 WASM_PARSER_FAIL_IF(!parseVarUInt1(returnCount), "can't get ", i, "th Type's return count"); 123 124 Type returnType; 124 125 125 if (returnCount) { 126 126 Type value; … … 129 129 } else 130 130 returnType = Type::Void; 131 132 m_result.module->signatures.uncheckedAppend({ returnType, WTFMove(argumentTypes) }); 131 signature->returnType() = returnType; 132 133 SignatureIndex signatureIndex = SignatureInformation::adopt(m_vm, signature.release()); 134 m_result.module->signatureIndices.uncheckedAppend(signatureIndex); 133 135 } 134 136 return { }; … … 142 144 WASM_PARSER_FAIL_IF(!m_result.module->globals.tryReserveCapacity(importCount), "can't allocate enough memory for ", importCount, " globals"); // FIXME this over-allocates when we fix the FIXMEs below. 143 145 WASM_PARSER_FAIL_IF(!m_result.module->imports.tryReserveCapacity(importCount), "can't allocate enough memory for ", importCount, " imports"); // FIXME this over-allocates when we fix the FIXMEs below. 144 WASM_PARSER_FAIL_IF(!m_result.module->importFunction s.tryReserveCapacity(importCount), "can't allocate enough memory for ", importCount, " import functions"); // FIXME this over-allocates when we fix the FIXMEs below.146 WASM_PARSER_FAIL_IF(!m_result.module->importFunctionSignatureIndices.tryReserveCapacity(importCount), "can't allocate enough memory for ", importCount, " import function signatures"); // FIXME this over-allocates when we fix the FIXMEs below. 145 147 WASM_PARSER_FAIL_IF(!m_result.functionIndexSpace.tryReserveCapacity(importCount), "can't allocate enough memory for ", importCount, " functions in the index space"); // FIXME this over-allocates when we fix the FIXMEs below. We'll allocate some more here when we know how many functions to expect. 146 148 … … 165 167 uint32_t functionSignatureIndex; 166 168 WASM_PARSER_FAIL_IF(!parseVarUInt32(functionSignatureIndex), "can't get ", importNumber, "th Import's function signature in module '", moduleString, "' field '", fieldString, "'"); 167 WASM_PARSER_FAIL_IF(functionSignatureIndex >= m_result.module->signature s.size(), "invalid function signature for ", importNumber, "th Import, ", functionSignatureIndex, " is out of range of ", m_result.module->signatures.size(), " in module '", moduleString, "' field '", fieldString, "'");168 imp.kindIndex = m_result.module->importFunction s.size();169 Signature * signature = &m_result.module->signatures[functionSignatureIndex];170 m_result.module->importFunction s.uncheckedAppend(signature);171 m_result.functionIndexSpace.uncheckedAppend(signature );169 WASM_PARSER_FAIL_IF(functionSignatureIndex >= m_result.module->signatureIndices.size(), "invalid function signature for ", importNumber, "th Import, ", functionSignatureIndex, " is out of range of ", m_result.module->signatureIndices.size(), " in module '", moduleString, "' field '", fieldString, "'"); 170 imp.kindIndex = m_result.module->importFunctionSignatureIndices.size(); 171 SignatureIndex signatureIndex = m_result.module->signatureIndices[functionSignatureIndex]; 172 m_result.module->importFunctionSignatureIndices.uncheckedAppend(signatureIndex); 173 m_result.functionIndexSpace.uncheckedAppend(signatureIndex); 172 174 break; 173 175 } … … 209 211 WASM_PARSER_FAIL_IF(!parseVarUInt32(count), "can't get Function section's count"); 210 212 WASM_PARSER_FAIL_IF(count == std::numeric_limits<uint32_t>::max(), "Function section's count is too big ", count); 211 WASM_PARSER_FAIL_IF(!m_result.module->internalFunctionSignature s.tryReserveCapacity(count), "can't allocate enough memory for ", count, " Function signatures");213 WASM_PARSER_FAIL_IF(!m_result.module->internalFunctionSignatureIndices.tryReserveCapacity(count), "can't allocate enough memory for ", count, " Function signatures"); 212 214 WASM_PARSER_FAIL_IF(!m_result.functionLocationInBinary.tryReserveCapacity(count), "can't allocate enough memory for ", count, "Function locations"); 213 215 WASM_PARSER_FAIL_IF(!m_result.functionIndexSpace.tryReserveCapacity(m_result.functionIndexSpace.size() + count), "can't allocate enough memory for ", count, " more functions in the function index space"); … … 216 218 uint32_t typeNumber; 217 219 WASM_PARSER_FAIL_IF(!parseVarUInt32(typeNumber), "can't get ", i, "th Function's type number"); 218 WASM_PARSER_FAIL_IF(typeNumber >= m_result.module->signature s.size(), i, "th Function type number is invalid ", typeNumber);219 220 Signature * signature = &m_result.module->signatures[typeNumber];220 WASM_PARSER_FAIL_IF(typeNumber >= m_result.module->signatureIndices.size(), i, "th Function type number is invalid ", typeNumber); 221 222 SignatureIndex signatureIndex = m_result.module->signatureIndices[typeNumber]; 221 223 // The Code section fixes up start and end. 222 224 size_t start = 0; 223 225 size_t end = 0; 224 m_result.module->internalFunctionSignature s.uncheckedAppend(signature);226 m_result.module->internalFunctionSignatureIndices.uncheckedAppend(signatureIndex); 225 227 m_result.functionLocationInBinary.uncheckedAppend({ start, end }); 226 m_result.functionIndexSpace.uncheckedAppend(signature );228 m_result.functionIndexSpace.uncheckedAppend(signatureIndex); 227 229 } 228 230 … … 426 428 WASM_PARSER_FAIL_IF(!parseVarUInt32(startFunctionIndex), "can't get Start index"); 427 429 WASM_PARSER_FAIL_IF(startFunctionIndex >= m_result.functionIndexSpace.size(), "Start index ", startFunctionIndex, " exceeds function index space ", m_result.functionIndexSpace.size()); 428 Signature* signature = m_result.functionIndexSpace[startFunctionIndex].signature; 429 WASM_PARSER_FAIL_IF(!signature->arguments.isEmpty(), "Start function can't have arguments"); 430 WASM_PARSER_FAIL_IF(signature->returnType != Void, "Start function can't return a value"); 430 SignatureIndex signatureIndex = m_result.functionIndexSpace[startFunctionIndex].signatureIndex; 431 const Signature* signature = SignatureInformation::get(m_vm, signatureIndex); 432 WASM_PARSER_FAIL_IF(signature->argumentCount(), "Start function can't have arguments"); 433 WASM_PARSER_FAIL_IF(signature->returnType() != Void, "Start function can't return a value"); 431 434 m_result.module->startFunctionIndexSpace = startFunctionIndex; 432 435 return { }; … … 595 598 WASM_PARSER_FAIL_IF(dataByteLength == std::numeric_limits<uint32_t>::max(), segmentNumber, "th Data segment's data byte length is too big ", dataByteLength); 596 599 597 Segment* segment = Segment:: make(offset, dataByteLength);600 Segment* segment = Segment::create(offset, dataByteLength); 598 601 WASM_PARSER_FAIL_IF(!segment, "can't allocate enough memory for ", segmentNumber, "th Data segment of size ", dataByteLength); 599 m_result.module->data.uncheckedAppend(Segment:: makePtr(segment));602 m_result.module->data.uncheckedAppend(Segment::adoptPtr(segment)); 600 603 for (uint32_t dataByte = 0; dataByte < dataByteLength; ++dataByte) { 601 604 uint8_t byte; -
trunk/Source/JavaScriptCore/wasm/WasmModuleParser.h
r209880 r210026 45 45 46 46 ModuleParser(VM* vm, const uint8_t* sourceBuffer, size_t sourceLength) 47 : Parser(sourceBuffer, sourceLength) 48 , m_vm(vm) 47 : Parser(vm, sourceBuffer, sourceLength) 49 48 { 50 49 } … … 68 67 PartialResult WARN_UNUSED_RETURN parseInitExpr(uint8_t&, uint64_t&); 69 68 70 VM* m_vm;71 69 ModuleParserResult m_result; 72 70 bool m_hasTable { false }; -
trunk/Source/JavaScriptCore/wasm/WasmParser.h
r209880 r210026 57 57 58 58 protected: 59 Parser( const uint8_t*, size_t);59 Parser(VM*, const uint8_t*, size_t); 60 60 61 61 bool WARN_UNUSED_RETURN consumeCharacter(char); … … 82 82 size_t length() const { return m_sourceLength; } 83 83 84 VM* m_vm; 84 85 size_t m_offset = 0; 85 86 … … 107 108 108 109 template<typename SuccessType> 109 ALWAYS_INLINE Parser<SuccessType>::Parser(const uint8_t* sourceBuffer, size_t sourceLength) 110 : m_source(sourceBuffer) 110 ALWAYS_INLINE Parser<SuccessType>::Parser(VM* vm, const uint8_t* sourceBuffer, size_t sourceLength) 111 : m_vm(vm) 112 , m_source(sourceBuffer) 111 113 , m_sourceLength(sourceLength) 112 114 { -
trunk/Source/JavaScriptCore/wasm/WasmPlan.cpp
r209979 r210026 80 80 size_t functionLength = m_functionLocationInBinary[functionIndex].end - m_functionLocationInBinary[functionIndex].start; 81 81 ASSERT(Checked<uintptr_t>(bitwise_cast<uintptr_t>(functionStart)) + functionLength <= Checked<uintptr_t>(bitwise_cast<uintptr_t>(m_source)) + m_sourceLength); 82 Signature* signature = m_moduleInformation->internalFunctionSignatures[functionIndex]; 82 SignatureIndex signatureIndex = m_moduleInformation->internalFunctionSignatureIndices[functionIndex]; 83 const Signature* signature = SignatureInformation::get(m_vm, signatureIndex); 83 84 84 auto validationResult = validateFunction( functionStart, functionLength, signature, m_functionIndexSpace, *m_moduleInformation);85 auto validationResult = validateFunction(m_vm, functionStart, functionLength, signature, m_functionIndexSpace, *m_moduleInformation); 85 86 if (!validationResult) { 86 87 if (verbose) { … … 115 116 116 117 Vector<Vector<UnlinkedWasmToWasmCall>> unlinkedWasmToWasmCalls; 117 if (!tryReserveCapacity(m_wasmToJSStubs, m_moduleInformation->importFunction s.size(), " WebAssembly to JavaScript stubs")118 if (!tryReserveCapacity(m_wasmToJSStubs, m_moduleInformation->importFunctionSignatureIndices.size(), " WebAssembly to JavaScript stubs") 118 119 || !tryReserveCapacity(unlinkedWasmToWasmCalls, m_functionLocationInBinary.size(), " unlinked WebAssembly to WebAssembly calls") 119 120 || !tryReserveCapacity(m_wasmInternalFunctions, m_functionLocationInBinary.size(), " WebAssembly functions")) … … 127 128 if (verbose) 128 129 dataLogLn("Processing import function number ", importFunctionIndex, ": ", import->module, ": ", import->field); 129 Signature * signature = m_moduleInformation->importFunctions.at(import->kindIndex);130 m_wasmToJSStubs.uncheckedAppend(importStubGenerator(m_vm, m_callLinkInfos, signature , importFunctionIndex));130 SignatureIndex signatureIndex = m_moduleInformation->importFunctionSignatureIndices.at(import->kindIndex); 131 m_wasmToJSStubs.uncheckedAppend(importStubGenerator(m_vm, m_callLinkInfos, signatureIndex, importFunctionIndex)); 131 132 m_functionIndexSpace.buffer.get()[importFunctionIndex].code = m_wasmToJSStubs[importFunctionIndex].code().executableAddress(); 132 133 } … … 138 139 size_t functionLength = m_functionLocationInBinary[functionIndex].end - m_functionLocationInBinary[functionIndex].start; 139 140 ASSERT(functionLength <= m_sourceLength); 140 Signature* signature = m_moduleInformation->internalFunctionSignatures[functionIndex]; 141 SignatureIndex signatureIndex = m_moduleInformation->internalFunctionSignatureIndices[functionIndex]; 142 const Signature* signature = SignatureInformation::get(m_vm, signatureIndex); 141 143 unsigned functionIndexSpace = m_wasmToJSStubs.size() + functionIndex; 142 ASSERT(m_functionIndexSpace.buffer.get()[functionIndexSpace].signature == signature);144 ASSERT(m_functionIndexSpace.buffer.get()[functionIndexSpace].signatureIndex == signatureIndex); 143 145 144 ASSERT(validateFunction( functionStart, functionLength, signature, m_functionIndexSpace, *m_moduleInformation));146 ASSERT(validateFunction(m_vm, functionStart, functionLength, signature, m_functionIndexSpace, *m_moduleInformation)); 145 147 146 148 unlinkedWasmToWasmCalls.uncheckedAppend(Vector<UnlinkedWasmToWasmCall>()); -
trunk/Source/JavaScriptCore/wasm/WasmValidate.cpp
r209899 r210026 93 93 } while (0) 94 94 95 Result WARN_UNUSED_RETURN addArguments(const Vector<Type>&);95 Result WARN_UNUSED_RETURN addArguments(const Signature*); 96 96 Result WARN_UNUSED_RETURN addLocal(Type, uint32_t); 97 97 ExpressionType addConstant(Type type, uint64_t) { return type; } … … 133 133 // Calls 134 134 Result WARN_UNUSED_RETURN addCall(unsigned calleeIndex, const Signature*, const Vector<ExpressionType>& args, ExpressionType& result); 135 Result WARN_UNUSED_RETURN addCallIndirect(const Signature*, const Vector<ExpressionType>& args, ExpressionType& result);135 Result WARN_UNUSED_RETURN addCallIndirect(const Signature*, SignatureIndex, const Vector<ExpressionType>& args, ExpressionType& result); 136 136 137 137 bool hasMemory() const { return !!m_module.memory; } … … 156 156 }; 157 157 158 auto Validate::addArguments(const Vector<Type>& args) -> Result159 { 160 for ( Type arg : args)161 WASM_FAIL_IF_HELPER_FAILS(addLocal( arg, 1));158 auto Validate::addArguments(const Signature* signature) -> Result 159 { 160 for (size_t i = 0; i < signature->argumentCount(); ++i) 161 WASM_FAIL_IF_HELPER_FAILS(addLocal(signature->argument(i), 1)); 162 162 return { }; 163 163 } … … 311 311 auto Validate::addCall(unsigned, const Signature* signature, const Vector<ExpressionType>& args, ExpressionType& result) -> Result 312 312 { 313 WASM_VALIDATOR_FAIL_IF(signature->argument s.size() != args.size(), "arity mismatch in call, got ", args.size(), " arguments, expected ", signature->arguments.size());313 WASM_VALIDATOR_FAIL_IF(signature->argumentCount() != args.size(), "arity mismatch in call, got ", args.size(), " arguments, expected ", signature->argumentCount()); 314 314 315 315 for (unsigned i = 0; i < args.size(); ++i) 316 WASM_VALIDATOR_FAIL_IF(args[i] != signature->arguments[i], "argument type mismatch in call, got ", args[i], ", expected ", signature->arguments[i]); 317 318 result = signature->returnType; 319 return { }; 320 } 321 322 auto Validate::addCallIndirect(const Signature* signature, const Vector<ExpressionType>& args, ExpressionType& result) -> Result 323 { 324 const auto argumentCount = signature->arguments.size(); 316 WASM_VALIDATOR_FAIL_IF(args[i] != signature->argument(i), "argument type mismatch in call, got ", args[i], ", expected ", signature->argument(i)); 317 318 result = signature->returnType(); 319 return { }; 320 } 321 322 auto Validate::addCallIndirect(const Signature* signature, SignatureIndex signatureIndex, const Vector<ExpressionType>& args, ExpressionType& result) -> Result 323 { 324 UNUSED_PARAM(signatureIndex); 325 ASSERT(signatureIndex != Signature::invalidIndex); 326 const auto argumentCount = signature->argumentCount(); 325 327 WASM_VALIDATOR_FAIL_IF(argumentCount != args.size() - 1, "arity mismatch in call_indirect, got ", args.size() - 1, " arguments, expected ", argumentCount); 326 328 327 329 for (unsigned i = 0; i < argumentCount; ++i) 328 WASM_VALIDATOR_FAIL_IF(args[i] != signature->argument s[i], "argument type mismatch in call_indirect, got ", args[i], ", expected ", signature->arguments[i]);330 WASM_VALIDATOR_FAIL_IF(args[i] != signature->argument(i), "argument type mismatch in call_indirect, got ", args[i], ", expected ", signature->argument(i)); 329 331 330 332 WASM_VALIDATOR_FAIL_IF(args.last() != I32, "non-i32 call_indirect index ", args.last()); 331 333 332 result = signature->returnType ;334 result = signature->returnType(); 333 335 return { }; 334 336 } … … 352 354 } 353 355 354 Expected<void, String> validateFunction( const uint8_t* source, size_t length, const Signature* signature, const ImmutableFunctionIndexSpace& functionIndexSpace, const ModuleInformation& module)355 { 356 Validate context(signature->returnType , module);357 FunctionParser<Validate> validator( context, source, length, signature, functionIndexSpace, module);356 Expected<void, String> validateFunction(VM* vm, const uint8_t* source, size_t length, const Signature* signature, const ImmutableFunctionIndexSpace& functionIndexSpace, const ModuleInformation& module) 357 { 358 Validate context(signature->returnType(), module); 359 FunctionParser<Validate> validator(vm, context, source, length, signature, functionIndexSpace, module); 358 360 WASM_FAIL_IF_HELPER_FAILS(validator.parse()); 359 361 return { }; -
trunk/Source/JavaScriptCore/wasm/WasmValidate.h
r209880 r210026 31 31 #include <wtf/Expected.h> 32 32 33 namespace JSC { namespace Wasm {33 namespace JSC { 34 34 35 Expected<void, String> validateFunction(const uint8_t*, size_t, const Signature*, const ImmutableFunctionIndexSpace&, const ModuleInformation&); 35 class VM; 36 37 namespace Wasm { 38 39 Expected<void, String> validateFunction(VM*, const uint8_t*, size_t, const Signature*, const ImmutableFunctionIndexSpace&, const ModuleInformation&); 36 40 37 41 } } // namespace JSC::Wasm -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp
r209897 r210026 42 42 { 43 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().importFunction s.size()))) JSWebAssemblyInstance(vm, structure, module->moduleInformation().importFunctions.size());44 auto* instance = new (NotNull, allocateCell<JSWebAssemblyInstance>(vm.heap, allocationSize(module->moduleInformation().importFunctionSignatureIndices.size()))) JSWebAssemblyInstance(vm, structure, module->moduleInformation().importFunctionSignatureIndices.size()); 45 45 instance->finishCreation(vm, module, moduleNamespaceObject); 46 46 return instance; -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.h
r209696 r210026 51 51 const Wasm::ModuleInformation& moduleInformation() const { return *m_moduleInformation.get(); } 52 52 SymbolTable* exportSymbolTable() const { return m_exportSymbolTable.get(); } 53 Wasm::Signature* signatureForFunctionIndexSpace(unsigned functionIndexSpace) const { ASSERT(functionIndexSpace < m_functionIndexSpace.size); return m_functionIndexSpace.buffer.get()[functionIndexSpace].signature; } 53 Wasm::SignatureIndex signatureForFunctionIndexSpace(unsigned functionIndexSpace) const 54 { 55 ASSERT(functionIndexSpace < m_functionIndexSpace.size); 56 return m_functionIndexSpace.buffer.get()[functionIndexSpace].signatureIndex; 57 } 54 58 unsigned importCount() const { return m_wasmToJSStubs.size(); } 55 59 -
trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.cpp
r209897 r210026 68 68 for (uint32_t i = 0; i < m_size; ++i) { 69 69 new (&m_functions.get()[i]) Wasm::CallableFunction(); 70 ASSERT( !m_functions.get()[i].signature); // We rely on this in compiled code.70 ASSERT(m_functions.get()[i].signatureIndex == Wasm::Signature::invalidIndex); // We rely on this in compiled code. 71 71 new (&m_jsFunctions.get()[i]) WriteBarrier<WebAssemblyFunction>(); 72 72 } … … 122 122 m_jsFunctions.get()[index] = WriteBarrier<WebAssemblyFunction>(); 123 123 m_functions.get()[index] = Wasm::CallableFunction(); 124 ASSERT( !m_functions.get()[index].signature); // We rely on this in compiled code.124 ASSERT(m_functions.get()[index].signatureIndex == Wasm::Signature::invalidIndex); // We rely on this in compiled code. 125 125 } 126 126 … … 129 129 RELEASE_ASSERT(index < m_size); 130 130 m_jsFunctions.get()[index].set(vm, this, function); 131 m_functions.get()[index] = Wasm::CallableFunction(function->signature (), function->wasmEntrypoint());131 m_functions.get()[index] = Wasm::CallableFunction(function->signatureIndex(), function->wasmEntrypoint()); 132 132 } 133 133 -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp
r209897 r210026 53 53 if (!wasmFunction) 54 54 return JSValue::encode(throwException(exec, scope, createTypeError(exec, "expected a WebAssembly function", defaultSourceAppender, runtimeTypeForValue(exec->jsCallee())))); 55 const Wasm::Signature* signature = wasmFunction->signature(); 55 Wasm::SignatureIndex signatureIndex = wasmFunction->signatureIndex(); 56 const Wasm::Signature* signature = Wasm::SignatureInformation::get(&vm, signatureIndex); 56 57 57 58 // FIXME is this the right behavior? https://bugs.webkit.org/show_bug.cgi?id=164876 58 if (exec->argumentCount() != signature->argument s.size())59 if (exec->argumentCount() != signature->argumentCount()) 59 60 return JSValue::encode(throwException(exec, scope, createNotEnoughArgumentsError(exec, defaultSourceAppender))); 60 61 … … 63 64 for (unsigned argIndex = 0; argIndex < exec->argumentCount(); ++argIndex) { 64 65 JSValue arg = exec->uncheckedArgument(argIndex); 65 switch (signature->argument s[argIndex]) {66 switch (signature->argument(argIndex)) { 66 67 case Wasm::I32: 67 68 arg = JSValue::decode(arg.toInt32(exec)); … … 122 123 123 124 // FIXME is this correct? https://bugs.webkit.org/show_bug.cgi?id=164876 124 switch ( signature()->returnType) {125 switch (m_returnType) { 125 126 case Wasm::Void: 126 127 return JSValue::encode(jsUndefined()); … … 141 142 } 142 143 143 WebAssemblyFunction* WebAssemblyFunction::create(VM& vm, JSGlobalObject* globalObject, unsigned length, const String& name, JSWebAssemblyInstance* instance, JSWebAssemblyCallee* jsEntrypoint, JSWebAssemblyCallee* wasmEntrypoint, Wasm::Signature * signature)144 WebAssemblyFunction* WebAssemblyFunction::create(VM& vm, JSGlobalObject* globalObject, unsigned length, const String& name, JSWebAssemblyInstance* instance, JSWebAssemblyCallee* jsEntrypoint, JSWebAssemblyCallee* wasmEntrypoint, Wasm::SignatureIndex signatureIndex) 144 145 { 145 146 NativeExecutable* executable = vm.getHostFunction(callWebAssemblyFunction, NoIntrinsic, callHostFunctionAsConstructor, nullptr, name); 146 147 Structure* structure = globalObject->webAssemblyFunctionStructure(); 147 WebAssemblyFunction* function = new (NotNull, allocateCell<WebAssemblyFunction>(vm.heap)) WebAssemblyFunction(vm, globalObject, structure );148 function->finishCreation(vm, executable, length, name, instance, jsEntrypoint, wasmEntrypoint , signature);148 WebAssemblyFunction* function = new (NotNull, allocateCell<WebAssemblyFunction>(vm.heap)) WebAssemblyFunction(vm, globalObject, structure, signatureIndex); 149 function->finishCreation(vm, executable, length, name, instance, jsEntrypoint, wasmEntrypoint); 149 150 return function; 150 151 } … … 156 157 } 157 158 158 WebAssemblyFunction::WebAssemblyFunction(VM& vm, JSGlobalObject* globalObject, Structure* structure )159 WebAssemblyFunction::WebAssemblyFunction(VM& vm, JSGlobalObject* globalObject, Structure* structure, Wasm::SignatureIndex signatureIndex) 159 160 : Base(vm, globalObject, structure) 161 , m_signatureIndex(signatureIndex) 160 162 { 163 // Don't cache the signature pointer: it's a global on VM and can change as new WebAssembly.Module are created. 164 const Wasm::Signature* signature = Wasm::SignatureInformation::get(&vm, m_signatureIndex); 165 m_returnType = signature->returnType(); 161 166 } 162 167 … … 171 176 } 172 177 173 void WebAssemblyFunction::finishCreation(VM& vm, NativeExecutable* executable, unsigned length, const String& name, JSWebAssemblyInstance* instance, JSWebAssemblyCallee* jsEntrypoint, JSWebAssemblyCallee* wasmEntrypoint , Wasm::Signature* signature)178 void WebAssemblyFunction::finishCreation(VM& vm, NativeExecutable* executable, unsigned length, const String& name, JSWebAssemblyInstance* instance, JSWebAssemblyCallee* jsEntrypoint, JSWebAssemblyCallee* wasmEntrypoint) 174 179 { 175 180 Base::finishCreation(vm, executable, length, name); … … 179 184 m_jsEntrypoint.set(vm, this, jsEntrypoint); 180 185 m_wasmEntrypoint.set(vm, this, wasmEntrypoint); 181 m_signature = signature;182 186 } 183 187 -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.h
r209771 r210026 42 42 } 43 43 44 namespace Wasm {45 struct Signature;46 }47 48 44 class WebAssemblyFunction : public JSFunction { 49 45 public: … … 54 50 DECLARE_EXPORT_INFO; 55 51 56 JS_EXPORT_PRIVATE static WebAssemblyFunction* create(VM&, JSGlobalObject*, unsigned, const String&, JSWebAssemblyInstance*, JSWebAssemblyCallee* jsEntrypoint, JSWebAssemblyCallee* wasmEntrypoint, Wasm::Signature *);52 JS_EXPORT_PRIVATE static WebAssemblyFunction* create(VM&, JSGlobalObject*, unsigned, const String&, JSWebAssemblyInstance*, JSWebAssemblyCallee* jsEntrypoint, JSWebAssemblyCallee* wasmEntrypoint, Wasm::SignatureIndex); 57 53 static Structure* createStructure(VM&, JSGlobalObject*, JSValue); 58 54 59 55 JSWebAssemblyInstance* instance() const { return m_instance.get(); } 60 Wasm::Signature* signature() 61 { 62 ASSERT(m_signature); 63 return m_signature; 64 } 56 Wasm::SignatureIndex signatureIndex() const { return m_signatureIndex; } 65 57 EncodedJSValue call(VM&, ProtoCallFrame*); 66 58 void* wasmEntrypoint() { return m_wasmEntrypoint->entrypoint(); } … … 69 61 static void visitChildren(JSCell*, SlotVisitor&); 70 62 71 void finishCreation(VM&, NativeExecutable*, unsigned length, const String& name, JSWebAssemblyInstance*, JSWebAssemblyCallee* jsEntrypoint, JSWebAssemblyCallee* wasmEntrypoint , Wasm::Signature*);63 void finishCreation(VM&, NativeExecutable*, unsigned length, const String& name, JSWebAssemblyInstance*, JSWebAssemblyCallee* jsEntrypoint, JSWebAssemblyCallee* wasmEntrypoint); 72 64 73 65 private: 74 WebAssemblyFunction(VM&, JSGlobalObject*, Structure* );66 WebAssemblyFunction(VM&, JSGlobalObject*, Structure*, Wasm::SignatureIndex); 75 67 76 68 WriteBarrier<JSWebAssemblyInstance> m_instance; 77 69 WriteBarrier<JSWebAssemblyCallee> m_jsEntrypoint; 78 70 WriteBarrier<JSWebAssemblyCallee> m_wasmEntrypoint; 79 Wasm::Signature* m_signature; 71 Wasm::SignatureIndex m_signatureIndex; 72 Wasm::Type m_returnType; 80 73 }; 81 74 -
trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp
r209897 r210026 37 37 #include "ProtoCallFrame.h" 38 38 #include "WasmFormat.h" 39 #include "WasmSignature.h" 39 40 #include "WebAssemblyFunction.h" 40 41 #include <limits> … … 120 121 JSWebAssemblyCallee* jsEntrypointCallee = module->jsEntrypointCalleeFromFunctionIndexSpace(exp.kindIndex); 121 122 JSWebAssemblyCallee* wasmEntrypointCallee = module->wasmEntrypointCalleeFromFunctionIndexSpace(exp.kindIndex); 122 Wasm::Signature* signature = module->signatureForFunctionIndexSpace(exp.kindIndex); 123 WebAssemblyFunction* function = WebAssemblyFunction::create(vm, globalObject, signature->arguments.size(), exp.field.string(), instance, jsEntrypointCallee, wasmEntrypointCallee, signature); 123 Wasm::SignatureIndex signatureIndex = module->signatureForFunctionIndexSpace(exp.kindIndex); 124 const Wasm::Signature* signature = Wasm::SignatureInformation::get(&vm, signatureIndex); 125 WebAssemblyFunction* function = WebAssemblyFunction::create(vm, globalObject, signature->argumentCount(), exp.field.string(), instance, jsEntrypointCallee, wasmEntrypointCallee, signatureIndex); 124 126 exportedValue = function; 125 127 if (hasStart && startFunctionIndexSpace == exp.kindIndex) … … 176 178 177 179 if (hasStart) { 178 Wasm::Signature* signature = module->signatureForFunctionIndexSpace(startFunctionIndexSpace); 180 Wasm::SignatureIndex signatureIndex = module->signatureForFunctionIndexSpace(startFunctionIndexSpace); 181 const Wasm::Signature* signature = Wasm::SignatureInformation::get(&vm, signatureIndex); 179 182 // The start function must not take any arguments or return anything. This is enforced by the parser. 180 ASSERT(!signature->argument s.size());181 ASSERT(signature->returnType == Wasm::Void);183 ASSERT(!signature->argumentCount()); 184 ASSERT(signature->returnType() == Wasm::Void); 182 185 // FIXME can start call imports / tables? This assumes not. https://github.com/WebAssembly/design/issues/896 183 186 if (!m_startFunction.get()) { … … 185 188 JSWebAssemblyCallee* jsEntrypointCallee = module->jsEntrypointCalleeFromFunctionIndexSpace(startFunctionIndexSpace); 186 189 JSWebAssemblyCallee* wasmEntrypointCallee = module->wasmEntrypointCalleeFromFunctionIndexSpace(startFunctionIndexSpace); 187 WebAssemblyFunction* function = WebAssemblyFunction::create(vm, globalObject, signature->argument s.size(), "start", instance, jsEntrypointCallee, wasmEntrypointCallee, signature);190 WebAssemblyFunction* function = WebAssemblyFunction::create(vm, globalObject, signature->argumentCount(), "start", instance, jsEntrypointCallee, wasmEntrypointCallee, signatureIndex); 188 191 m_startFunction.set(vm, this, function); 189 192 } … … 237 240 JSWebAssemblyCallee* jsEntrypointCallee = module->jsEntrypointCalleeFromFunctionIndexSpace(functionIndex); 238 241 JSWebAssemblyCallee* wasmEntrypointCallee = module->wasmEntrypointCalleeFromFunctionIndexSpace(functionIndex); 239 Wasm::Signature* signature = module->signatureForFunctionIndexSpace(functionIndex); 242 Wasm::SignatureIndex signatureIndex = module->signatureForFunctionIndexSpace(functionIndex); 243 const Wasm::Signature* signature = Wasm::SignatureInformation::get(&vm, signatureIndex); 240 244 // FIXME: Say we export local function "foo" at funciton index 0. 241 245 // What if we also set it to the table an Element w/ index 0. … … 243 247 // https://bugs.webkit.org/show_bug.cgi?id=165825 244 248 WebAssemblyFunction* function = WebAssemblyFunction::create( 245 vm, m_instance->globalObject(), signature->argument s.size(), String(), m_instance.get(), jsEntrypointCallee, wasmEntrypointCallee, signature);249 vm, m_instance->globalObject(), signature->argumentCount(), String(), m_instance.get(), jsEntrypointCallee, wasmEntrypointCallee, signatureIndex); 246 250 247 251 table->setFunction(vm, tableIndex, function);
Note: See TracChangeset
for help on using the changeset viewer.