Changeset 210026 in webkit


Ignore:
Timestamp:
Dec 20, 2016 10:54:33 AM (7 years ago)
Author:
jfbastien@apple.com
Message:

WebAssembly: unique function signatures
https://bugs.webkit.org/show_bug.cgi?id=165957
<rdar://problem/29735737>

Reviewed by Saam Barati.

JSTests:

  • wasm/function-tests/table-basic.js: FIXME is now addressed,

though instance to instance calls still need work which bug
#165282 will address
(i.assert.eq.foo):

  • wasm/js-api/unique-signature.js: Added.

(CallIndirectWithDuplicateSignatures):

Source/JavaScriptCore:

Signatures in a Module's Type section can be duplicated, we
therefore need to unique them so that call_indirect only needs to
do a single integer compare to check that a callee's Signature is
the same as the Signature declared at the call site. Without
uniquing we'd either trap when duplicate Signatures are used, or
we'd need to do multiple comparisons. This patch makes that narrow
usecase function correctly.

There's further complication when calling from wasm to
wasm, in which case the Signatures must also match. Such
cross-instance calls will be improved in bug #165282, but this
patch sets the groundwork for it:

  • Signatures are now owned by SignatureInformation which lives on VM, and is shared by all Modules.
  • When parsing a Module, a Signature is created for every Type entry, and then uniqued by SignatureInformation's adopt method. Duplicate Signatures are dropped and the previous SignatureIndex is returned, new Signatures are adopted and a new SignatureIndex is created.
  • The SignatureIndex values are monotonic. 0 is used to represent invalid indices, which trap. This can only occur through Table.
  • SignatureInformation is used while generating code to map a SignatureIndex back to the Signature* when return / argument information is needed. This is a simple lookup into a Vector. It isn't used at runtime.
  • These Signatures live forever on VM because the bookkeeping likely isn't worth it. We may want to empty things out if all Modules die, this is tracked in bug #166037.
  • We can further improve things by bit-packing SignatureIndex with Code*, which is tracked by bug #165511.
  • CMakeLists.txt:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • runtime/VM.h: wasm signatures are uniqued here, but aren't accessed frequently (only during parsing) so indirection is fine
  • wasm/WasmB3IRGenerator.cpp: use SignatureIndex instead of Signature* when appropriate, and when still using Signature* do so with its new API

(JSC::Wasm::createJSToWasmWrapper):
(JSC::Wasm::parseAndCompile):

  • wasm/WasmBinding.cpp:

(JSC::Wasm::importStubGenerator): use SignatureIndex

  • wasm/WasmBinding.h:
  • wasm/WasmCallingConvention.h:

(JSC::Wasm::CallingConvention::loadArguments):

  • wasm/WasmFormat.cpp: drive-by move of alloc/free functions to the implementation file, allows the .h file to drop an FastMalloc.h

(JSC::Wasm::Segment::create):
(JSC::Wasm::Segment::destroy):
(JSC::Wasm::Segment::createPtr):

  • wasm/WasmFormat.h: move Signature to its own file

(JSC::Wasm::CallableFunction::CallableFunction):

  • wasm/WasmFunctionParser.h:

(JSC::Wasm::FunctionParser<Context>::FunctionParser):

  • wasm/WasmModuleParser.cpp:
  • wasm/WasmModuleParser.h:

(JSC::Wasm::ModuleParser::ModuleParser):

  • wasm/WasmParser.h:

(JSC::Wasm::Parser<SuccessType>::Parser):

  • wasm/WasmPlan.cpp:

(JSC::Wasm::Plan::parseAndValidateModule):
(JSC::Wasm::Plan::run):

  • wasm/WasmSignature.cpp: Added.

(JSC::Wasm::Signature::dump):
(JSC::Wasm::Signature::hash):
(JSC::Wasm::Signature::create):
(JSC::Wasm::Signature::createInvalid):
(JSC::Wasm::Signature::destroy):
(JSC::Wasm::SignatureInformation::~SignatureInformation):
(JSC::Wasm::SignatureInformation::adopt):
(JSC::Wasm::SignatureInformation::get):

  • wasm/WasmSignature.h: Added.

(JSC::Wasm::Signature::Signature):
(JSC::Wasm::Signature::storage):
(JSC::Wasm::Signature::allocatedSize):
(JSC::Wasm::Signature::returnType):
(JSC::Wasm::Signature::returnCount):
(JSC::Wasm::Signature::argumentCount):
(JSC::Wasm::Signature::argument):
(JSC::Wasm::Signature::operator==):
(JSC::Wasm::SignatureHash::empty):
(JSC::Wasm::SignatureHash::deleted):
(JSC::Wasm::SignatureHash::SignatureHash):
(JSC::Wasm::SignatureHash::operator==):
(JSC::Wasm::SignatureHash::equal):
(JSC::Wasm::SignatureHash::hash):
(JSC::Wasm::SignatureHash::isHashTableDeletedValue):

  • wasm/WasmValidate.cpp:

(JSC::Wasm::validateFunction):

  • wasm/WasmValidate.h:
  • wasm/js/JSWebAssemblyInstance.cpp:

(JSC::JSWebAssemblyInstance::create):

  • wasm/js/JSWebAssemblyModule.h:

(JSC::JSWebAssemblyModule::signatureForFunctionIndexSpace):

  • wasm/js/JSWebAssemblyTable.cpp:

(JSC::JSWebAssemblyTable::JSWebAssemblyTable):
(JSC::JSWebAssemblyTable::clearFunction):
(JSC::JSWebAssemblyTable::setFunction):

  • wasm/js/WebAssemblyFunction.cpp:

(JSC::callWebAssemblyFunction):
(JSC::WebAssemblyFunction::call):
(JSC::WebAssemblyFunction::create):
(JSC::WebAssemblyFunction::WebAssemblyFunction):
(JSC::WebAssemblyFunction::finishCreation):

  • wasm/js/WebAssemblyFunction.h:

(JSC::WebAssemblyFunction::signatureIndex):

  • wasm/js/WebAssemblyModuleRecord.cpp:

(JSC::WebAssemblyModuleRecord::link):
(JSC::WebAssemblyModuleRecord::evaluate):

Location:
trunk
Files:
3 added
25 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r210010 r210026  
     12016-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
    1162016-12-19  Mark Lam  <mark.lam@apple.com>
    217
  • trunk/JSTests/wasm/function-tests/table-basic.js

    r209928 r210026  
    4545    assert.eq(table.get(0), exports.bar);
    4646
    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");
    5149}
    5250
    53 // FIXME: make this work cross module. The reason it doesn't
    54 // now is that we don't unique Signature*.
    55 // https://bugs.webkit.org/show_bug.cgi?id=165511
    5651{
    5752    const {instance, table} = makeInstance();
     
    5954    table.set(0, makeInstance().instance.exports.bar); // Cross instance function.
    6055
    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");
    6458}
  • trunk/Source/JavaScriptCore/CMakeLists.txt

    r209928 r210026  
    907907    wasm/WasmModuleParser.cpp
    908908    wasm/WasmPlan.cpp
     909    wasm/WasmSignature.cpp
    909910    wasm/WasmValidate.cpp
    910911
  • trunk/Source/JavaScriptCore/ChangeLog

    r210023 r210026  
     12016-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
    11162016-12-20  Konstantin Tokarev  <annulen@yandex.ru>
    2117
  • trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj

    r209928 r210026  
    20232023                AD4B1DF91DF244E20071AE32 /* WasmBinding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD4B1DF71DF244D70071AE32 /* WasmBinding.cpp */; };
    20242024                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 */; };
    20252027                AD86A93E1AA4D88D002FE77F /* WeakGCMapInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = AD86A93D1AA4D87C002FE77F /* WeakGCMapInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
    20262028                ADBC54D41DF8EA2B005BF738 /* WebAssemblyToJSCallee.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ADBC54D21DF8EA00005BF738 /* WebAssemblyToJSCallee.cpp */; };
     
    44994501                AD4B1DF71DF244D70071AE32 /* WasmBinding.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmBinding.cpp; sourceTree = "<group>"; };
    45004502                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>"; };
    45014505                AD86A93D1AA4D87C002FE77F /* WeakGCMapInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakGCMapInlines.h; sourceTree = "<group>"; };
    45024506                ADBC54D21DF8EA00005BF738 /* WebAssemblyToJSCallee.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebAssemblyToJSCallee.cpp; path = js/WebAssemblyToJSCallee.cpp; sourceTree = "<group>"; };
     
    60356039                                531374BC1D5CE67600AF7A0B /* WasmPlan.h */,
    60366040                                53F40E841D58F9770099A1B6 /* WasmSections.h */,
     6041                                AD7438BE1E04579200FD0C2A /* WasmSignature.cpp */,
     6042                                AD7438BF1E04579200FD0C2A /* WasmSignature.h */,
    60376043                                53FF7F9A1DBFD2B900A26CCC /* WasmValidate.cpp */,
    60386044                                53FF7F981DBFCD9000A26CCC /* WasmValidate.h */,
     
    80528058                                0F9D36951AE9CC33000D4DFB /* DFGCleanUpPhase.h in Headers */,
    80538059                                A77A424017A0BBFD00A8DB81 /* DFGClobberize.h in Headers */,
     8060                                AD7438C01E0457A400FD0C2A /* WasmSignature.h in Headers */,
    80548061                                A77A424217A0BBFD00A8DB81 /* DFGClobberSet.h in Headers */,
    80558062                                0F3C1F1B1B868E7900ABB08B /* DFGClobbersExitState.h in Headers */,
     
    1039410401                                0F919D2515853CE0004A4E7D /* Watchpoint.cpp in Sources */,
    1039510402                                1ACF7377171CA6FB00C9BB1E /* Weak.cpp in Sources */,
     10403                                AD7438C11E0457AA00FD0C2A /* WasmSignature.cpp in Sources */,
    1039610404                                14E84F9E14EE1ACC00D6D5D4 /* WeakBlock.cpp in Sources */,
    1039710405                                14F7256514EE265E00B1652B /* WeakHandleOwner.cpp in Sources */,
  • trunk/Source/JavaScriptCore/runtime/VM.h

    r209764 r210026  
    148148class Signature;
    149149}
     150#if ENABLE(WEBASSEMBLY)
     151namespace Wasm {
     152class SignatureInformation;
     153}
     154#endif
    150155
    151156struct HashTable;
     
    355360    Strong<JSCell> emptyPropertyNameEnumerator;
    356361
     362#if ENABLE(WEBASSEMBLY)
     363    std::once_flag m_wasmSignatureInformationOnceFlag;
     364    std::unique_ptr<Wasm::SignatureInformation> m_wasmSignatureInformation;
     365#endif
     366
    357367    AtomicStringTable* m_atomicStringTable;
    358368    WTF::SymbolRegistry m_symbolRegistry;
  • trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp

    r209966 r210026  
    155155    B3IRGenerator(VM&, const ModuleInformation&, Procedure&, WasmInternalFunction*, Vector<UnlinkedWasmToWasmCall>&, const ImmutableFunctionIndexSpace&);
    156156
    157     PartialResult WARN_UNUSED_RETURN addArguments(const Vector<Type>&);
     157    PartialResult WARN_UNUSED_RETURN addArguments(const Signature*);
    158158    PartialResult WARN_UNUSED_RETURN addLocal(Type, uint32_t);
    159159    ExpressionType addConstant(Type, uint64_t);
     
    193193    // Calls
    194194    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);
    196196    PartialResult WARN_UNUSED_RETURN addUnreachable();
    197197
     
    303303}
    304304
    305 auto B3IRGenerator::addArguments(const Vector<Type>& types) -> PartialResult
     305auto B3IRGenerator::addArguments(const Signature* signature) -> PartialResult
    306306{
    307307    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(),
    312312        [&] (ExpressionType argument, unsigned i) {
    313313            Variable* argumentVariable = m_proc.addVariable(argument->type());
     
    683683auto B3IRGenerator::addCall(uint32_t functionIndex, const Signature* signature, Vector<ExpressionType>& args, ExpressionType& result) -> PartialResult
    684684{
    685     ASSERT(signature->arguments.size() == args.size());
    686 
    687     Type returnType = signature->returnType;
     685    ASSERT(signature->argumentCount() == args.size());
     686
     687    Type returnType = signature->returnType();
    688688
    689689    result = wasmCallingConvention().setupCall(m_proc, m_currentBlock, Origin(), args, toB3Type(returnType),
     
    705705}
    706706
    707 auto B3IRGenerator::addCallIndirect(const Signature* signature, Vector<ExpressionType>& args, ExpressionType& result) -> PartialResult
    708 {
     707auto B3IRGenerator::addCallIndirect(const Signature* signature, SignatureIndex signatureIndex, Vector<ExpressionType>& args, ExpressionType& result) -> PartialResult
     708{
     709    ASSERT(signatureIndex != Signature::invalidIndex);
    709710    ExpressionType calleeIndex = args.takeLast();
    710     ASSERT(signature->arguments.size() == args.size());
     711    ASSERT(signature->argumentCount() == args.size());
    711712
    712713    ExpressionType callableFunctionBuffer;
     
    737738    ExpressionType callableFunction = m_currentBlock->appendNew<Value>(m_proc, Add, Origin(), callableFunctionBuffer, offset);
    738739
    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));
    741743    {
    742744        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<ConstPtrValue>(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)));
    746748
    747749        check->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams&) {
     
    752754    // Check the signature matches the value we expect.
    753755    {
    754         ExpressionType expectedSignature = m_currentBlock->appendNew<ConstPtrValue>(m_proc, Origin(), signature);
     756        ExpressionType expectedSignatureIndex = m_currentBlock->appendNew<Const32Value>(m_proc, Origin(), signatureIndex);
    755757        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));
    757759
    758760        check->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams&) {
     
    763765    ExpressionType calleeCode = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), Origin(), callableFunction, OBJECT_OFFSETOF(CallableFunction, code));
    764766
    765     Type returnType = signature->returnType;
     767    Type returnType = signature->returnType();
    766768    result = wasmCallingConvention().setupCall(m_proc, m_currentBlock, Origin(), args, toB3Type(returnType),
    767769        [&] (PatchpointValue* patchpoint) {
     
    835837            block->appendNew<Value>(proc, Add, origin, framePointer, offSetOfArgumentCount));
    836838
    837         Value* expectedArgumentCount = block->appendNew<Const32Value>(proc, origin, signature->arguments.size());
     839        Value* expectedArgumentCount = block->appendNew<Const32Value>(proc, origin, signature->argumentCount());
    838840
    839841        CheckValue* argumentCountCheck = block->appendNew<CheckValue>(proc, Check, origin,
     
    862864    // Get our arguments.
    863865    Vector<Value*> arguments;
    864     jscCallingConvention().loadArguments(signature->arguments, proc, block, origin, [&] (Value* argument, unsigned) {
     866    jscCallingConvention().loadArguments(signature, proc, block, origin, [&] (Value* argument, unsigned) {
    865867        arguments.append(argument);
    866868    });
    867869
    868870    // 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) {
    870872        if (!!memory) {
    871873            ASSERT(sizes.size() == memory.pinnedRegisters().sizeRegisters.size());
     
    886888
    887889    // Return the result, if needed.
    888     switch (signature->returnType) {
     890    switch (signature->returnType()) {
    889891    case Wasm::Void:
    890892        block->appendNewControlValue(proc, B3::Return, origin);
     
    914916    Procedure procedure;
    915917    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);
    917919    WASM_FAIL_IF_HELPER_FAILS(parser.parse());
    918920
  • trunk/Source/JavaScriptCore/wasm/WasmBinding.cpp

    r209963 r210026  
    3737namespace JSC { namespace Wasm {
    3838
    39 WasmToJSStub importStubGenerator(VM* vm, Bag<CallLinkInfo>& callLinkInfos, Signature* signature, unsigned importIndex)
     39WasmToJSStub importStubGenerator(VM* vm, Bag<CallLinkInfo>& callLinkInfos, SignatureIndex signatureIndex, unsigned importIndex)
    4040{
    4141    const WasmCallingConvention& wasmCC = wasmCallingConvention();
    4242    const JSCCallingConvention& jsCC = jscCallingConvention();
    43     unsigned argCount = signature->arguments.size();
     43    const Signature* signature = SignatureInformation::get(vm, signatureIndex);
     44    unsigned argCount = signature->argumentCount();
    4445    typedef AssemblyHelpers JIT;
    4546    JIT jit(vm, nullptr);
     
    7374    unsigned frOffset = CallFrameSlot::firstArgument * static_cast<int>(sizeof(Register));
    7475    for (unsigned argNum = 0; argNum < argCount; ++argNum) {
    75         Type argType = signature->arguments[argNum];
     76        Type argType = signature->argument(argNum);
    7677        switch (argType) {
    7778        case Void:
     
    162163    done.link(&jit);
    163164
    164     switch (signature->returnType) {
     165    switch (signature->returnType()) {
    165166    case Void:
    166167        // Discard.
     
    231232    CodeLocationNearCall hotPathOther = patchBuffer.locationOfNearCall(fastCall);
    232233    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));
    234235}
    235236
  • trunk/Source/JavaScriptCore/wasm/WasmBinding.h

    r209560 r210026  
    3939namespace Wasm {
    4040
    41 WasmToJSStub importStubGenerator(VM*, Bag<CallLinkInfo>&, Signature*, unsigned);
     41WasmToJSStub importStubGenerator(VM*, Bag<CallLinkInfo>&, SignatureIndex, unsigned);
    4242
    4343} } // namespace JSC::Wasm
  • trunk/Source/JavaScriptCore/wasm/WasmCallingConvention.h

    r209696 r210026  
    119119
    120120    template<typename Functor>
    121     void loadArguments(const Vector<Type>& argumentTypes, B3::Procedure& proc, B3::BasicBlock* block, B3::Origin origin, const Functor& functor) const
     121    void loadArguments(const Signature* signature, B3::Procedure& proc, B3::BasicBlock* block, B3::Origin origin, const Functor& functor) const
    122122    {
    123123        B3::Value* framePointer = block->appendNew<B3::Value>(proc, B3::FramePointer, origin);
     
    127127        size_t stackOffset = headerSize;
    128128
    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));
    131131            B3::Value* argument;
    132132            B3::ValueRep rep = marshallArgument(type, gpArgumentCount, fpArgumentCount, stackOffset);
  • trunk/Source/JavaScriptCore/wasm/WasmFormat.cpp

    r209642 r210026  
    3131
    3232#include "WasmMemory.h"
     33#include <wtf/FastMalloc.h>
    3334
    3435namespace JSC { namespace Wasm {
     36
     37Segment* 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
     48void Segment::destroy(Segment *segment)
     49{
     50    fastFree(segment);
     51}
     52
     53Segment::Ptr Segment::adoptPtr(Segment* segment)
     54{
     55    return Ptr(segment, &Segment::destroy);
     56}
    3557
    3658JS_EXPORT_PRIVATE ModuleInformation::~ModuleInformation() { }
  • trunk/Source/JavaScriptCore/wasm/WasmFormat.h

    r209880 r210026  
    11/*
    2  * Copyright (C) 2015 Apple Inc. All rights reserved.
     2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
    33 *
    44 * Redistribution and use in source and binary forms, with or without
     
    3737#include "WasmOps.h"
    3838#include "WasmPageCount.h"
     39#include "WasmSignature.h"
     40#include <limits>
    3941#include <memory>
    40 #include <wtf/FastMalloc.h>
    4142#include <wtf/Optional.h>
    4243#include <wtf/Vector.h>
     
    101102}
    102103
    103 struct Signature {
    104     Type returnType;
    105     Vector<Type> arguments;
    106 };
    107 
    108104struct Import {
    109105    Identifier module;
     
    147143    uint32_t sizeInBytes;
    148144    // 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     }
    163145    uint8_t& byte(uint32_t pos)
    164146    {
     
    166148        return *reinterpret_cast<uint8_t*>(reinterpret_cast<char*>(this) + sizeof(offset) + sizeof(sizeInBytes) + pos);
    167149    }
     150    static Segment* create(uint32_t, uint32_t);
     151    static void destroy(Segment*);
    168152    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*);
    173154};
    174155
     
    207188
    208189struct ModuleInformation {
    209     Vector<Signature> signatures;
     190    Vector<SignatureIndex> signatureIndices;
    210191    Vector<Import> imports;
    211     Vector<Signature*> importFunctions;
    212     Vector<Signature*> internalFunctionSignatures;
     192    Vector<SignatureIndex> importFunctionSignatureIndices;
     193    Vector<SignatureIndex> internalFunctionSignatureIndices;
    213194    MemoryInformation memory;
    214195    Vector<Export> exports;
     
    248229    CallableFunction() = default;
    249230
    250     CallableFunction(Signature* signature, void* code = nullptr)
    251         : signature(signature)
     231    CallableFunction(SignatureIndex signatureIndex, void* code = nullptr)
     232        : signatureIndex(signatureIndex)
    252233        , code(code)
    253234    {
    254235    }
    255236
    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 };
    259239    void* code { nullptr };
    260240};
  • trunk/Source/JavaScriptCore/wasm/WasmFunctionParser.h

    r209955 r210026  
    4646    typedef typename Context::ExpressionList ExpressionList;
    4747
    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&);
    4949
    5050    Result WARN_UNUSED_RETURN parse();
     
    8989
    9090template<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)
     91FunctionParser<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)
    9393    , m_context(context)
    9494    , m_signature(signature)
     
    105105    uint32_t localCount;
    106106
    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");
    108108    WASM_PARSER_FAIL_IF(!parseVarUInt32(localCount), "can't get local count");
    109109    WASM_PARSER_FAIL_IF(localCount == std::numeric_limits<uint32_t>::max(), "Function section's local count is too big ", localCount);
     
    156156{
    157157    ExpressionList returnValues;
    158     if (m_signature->returnType != Void) {
     158    if (m_signature->returnType() != Void) {
    159159        ExpressionType returnValue;
    160160        WASM_TRY_POP_EXPRESSION_STACK_INTO(returnValue, "return");
     
    330330        WASM_PARSER_FAIL_IF(functionIndex >= m_functionIndexSpace.size, "call function index ", functionIndex, " exceeds function index space ", m_functionIndexSpace.size);
    331331
    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();
    336337        Vector<ExpressionType> args;
    337         WASM_PARSER_FAIL_IF(!args.tryReserveCapacity(calleeSignature->arguments.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");
    338339        for (size_t i = firstArgumentIndex; i < m_expressionStack.size(); ++i)
    339340            args.uncheckedAppend(m_expressionStack[i]);
     
    356357        WASM_PARSER_FAIL_IF(!parseVarUInt1(reserved), "can't get call_indirect's reserved byte");
    357358        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.
    362364        WASM_PARSER_FAIL_IF(argumentCount > m_expressionStack.size(), "call_indirect expects ", argumentCount, " arguments, but the expression stack currently holds ", m_expressionStack.size(), " values");
    363365
     
    370372
    371373        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));
    373375
    374376        if (result != Context::emptyExpression)
  • trunk/Source/JavaScriptCore/wasm/WasmModuleParser.cpp

    r209880 r210026  
    100100    WASM_PARSER_FAIL_IF(!parseVarUInt32(count), "can't get Type section's count");
    101101    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->signatures.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");
    103103
    104104    for (uint32_t i = 0; i < count; ++i) {
     
    111111        WASM_PARSER_FAIL_IF(!parseVarUInt32(argumentCount), "can't get ", i, "th Type's argument count");
    112112        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");
    114115
    115116        for (unsigned i = 0; i < argumentCount; ++i) {
    116117            Type argumentType;
    117118            WASM_PARSER_FAIL_IF(!parseResultType(argumentType), "can't get ", i, "th argument Type");
    118             argumentTypes.uncheckedAppend(argumentType);
     119            signature->argument(i) = argumentType;
    119120        }
    120121
     
    122123        WASM_PARSER_FAIL_IF(!parseVarUInt1(returnCount), "can't get ", i, "th Type's return count");
    123124        Type returnType;
    124 
    125125        if (returnCount) {
    126126            Type value;
     
    129129        } else
    130130            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);
    133135    }
    134136    return { };
     
    142144    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.
    143145    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->importFunctions.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.
    145147    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.
    146148
     
    165167            uint32_t functionSignatureIndex;
    166168            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->signatures.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->importFunctions.size();
    169             Signature* signature = &m_result.module->signatures[functionSignatureIndex];
    170             m_result.module->importFunctions.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);
    172174            break;
    173175        }
     
    209211    WASM_PARSER_FAIL_IF(!parseVarUInt32(count), "can't get Function section's count");
    210212    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->internalFunctionSignatures.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");
    212214    WASM_PARSER_FAIL_IF(!m_result.functionLocationInBinary.tryReserveCapacity(count), "can't allocate enough memory for ", count, "Function locations");
    213215    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");
     
    216218        uint32_t typeNumber;
    217219        WASM_PARSER_FAIL_IF(!parseVarUInt32(typeNumber), "can't get ", i, "th Function's type number");
    218         WASM_PARSER_FAIL_IF(typeNumber >= m_result.module->signatures.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];
    221223        // The Code section fixes up start and end.
    222224        size_t start = 0;
    223225        size_t end = 0;
    224         m_result.module->internalFunctionSignatures.uncheckedAppend(signature);
     226        m_result.module->internalFunctionSignatureIndices.uncheckedAppend(signatureIndex);
    225227        m_result.functionLocationInBinary.uncheckedAppend({ start, end });
    226         m_result.functionIndexSpace.uncheckedAppend(signature);
     228        m_result.functionIndexSpace.uncheckedAppend(signatureIndex);
    227229    }
    228230
     
    426428    WASM_PARSER_FAIL_IF(!parseVarUInt32(startFunctionIndex), "can't get Start index");
    427429    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");
    431434    m_result.module->startFunctionIndexSpace = startFunctionIndex;
    432435    return { };
     
    595598        WASM_PARSER_FAIL_IF(dataByteLength == std::numeric_limits<uint32_t>::max(), segmentNumber, "th Data segment's data byte length is too big ", dataByteLength);
    596599
    597         Segment* segment = Segment::make(offset, dataByteLength);
     600        Segment* segment = Segment::create(offset, dataByteLength);
    598601        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));
    600603        for (uint32_t dataByte = 0; dataByte < dataByteLength; ++dataByte) {
    601604            uint8_t byte;
  • trunk/Source/JavaScriptCore/wasm/WasmModuleParser.h

    r209880 r210026  
    4545
    4646    ModuleParser(VM* vm, const uint8_t* sourceBuffer, size_t sourceLength)
    47         : Parser(sourceBuffer, sourceLength)
    48         , m_vm(vm)
     47        : Parser(vm, sourceBuffer, sourceLength)
    4948    {
    5049    }
     
    6867    PartialResult WARN_UNUSED_RETURN parseInitExpr(uint8_t&, uint64_t&);
    6968
    70     VM* m_vm;
    7169    ModuleParserResult m_result;
    7270    bool m_hasTable { false };
  • trunk/Source/JavaScriptCore/wasm/WasmParser.h

    r209880 r210026  
    5757
    5858protected:
    59     Parser(const uint8_t*, size_t);
     59    Parser(VM*, const uint8_t*, size_t);
    6060
    6161    bool WARN_UNUSED_RETURN consumeCharacter(char);
     
    8282    size_t length() const { return m_sourceLength; }
    8383
     84    VM* m_vm;
    8485    size_t m_offset = 0;
    8586
     
    107108
    108109template<typename SuccessType>
    109 ALWAYS_INLINE Parser<SuccessType>::Parser(const uint8_t* sourceBuffer, size_t sourceLength)
    110     : m_source(sourceBuffer)
     110ALWAYS_INLINE Parser<SuccessType>::Parser(VM* vm, const uint8_t* sourceBuffer, size_t sourceLength)
     111    : m_vm(vm)
     112    , m_source(sourceBuffer)
    111113    , m_sourceLength(sourceLength)
    112114{
  • trunk/Source/JavaScriptCore/wasm/WasmPlan.cpp

    r209979 r210026  
    8080        size_t functionLength = m_functionLocationInBinary[functionIndex].end - m_functionLocationInBinary[functionIndex].start;
    8181        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);
    8384
    84         auto validationResult = validateFunction(functionStart, functionLength, signature, m_functionIndexSpace, *m_moduleInformation);
     85        auto validationResult = validateFunction(m_vm, functionStart, functionLength, signature, m_functionIndexSpace, *m_moduleInformation);
    8586        if (!validationResult) {
    8687            if (verbose) {
     
    115116
    116117    Vector<Vector<UnlinkedWasmToWasmCall>> unlinkedWasmToWasmCalls;
    117     if (!tryReserveCapacity(m_wasmToJSStubs, m_moduleInformation->importFunctions.size(), " WebAssembly to JavaScript stubs")
     118    if (!tryReserveCapacity(m_wasmToJSStubs, m_moduleInformation->importFunctionSignatureIndices.size(), " WebAssembly to JavaScript stubs")
    118119        || !tryReserveCapacity(unlinkedWasmToWasmCalls, m_functionLocationInBinary.size(), " unlinked WebAssembly to WebAssembly calls")
    119120        || !tryReserveCapacity(m_wasmInternalFunctions, m_functionLocationInBinary.size(), " WebAssembly functions"))
     
    127128        if (verbose)
    128129            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));
    131132        m_functionIndexSpace.buffer.get()[importFunctionIndex].code = m_wasmToJSStubs[importFunctionIndex].code().executableAddress();
    132133    }
     
    138139        size_t functionLength = m_functionLocationInBinary[functionIndex].end - m_functionLocationInBinary[functionIndex].start;
    139140        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);
    141143        unsigned functionIndexSpace = m_wasmToJSStubs.size() + functionIndex;
    142         ASSERT(m_functionIndexSpace.buffer.get()[functionIndexSpace].signature == signature);
     144        ASSERT(m_functionIndexSpace.buffer.get()[functionIndexSpace].signatureIndex == signatureIndex);
    143145
    144         ASSERT(validateFunction(functionStart, functionLength, signature, m_functionIndexSpace, *m_moduleInformation));
     146        ASSERT(validateFunction(m_vm, functionStart, functionLength, signature, m_functionIndexSpace, *m_moduleInformation));
    145147
    146148        unlinkedWasmToWasmCalls.uncheckedAppend(Vector<UnlinkedWasmToWasmCall>());
  • trunk/Source/JavaScriptCore/wasm/WasmValidate.cpp

    r209899 r210026  
    9393    } while (0)
    9494
    95     Result WARN_UNUSED_RETURN addArguments(const Vector<Type>&);
     95    Result WARN_UNUSED_RETURN addArguments(const Signature*);
    9696    Result WARN_UNUSED_RETURN addLocal(Type, uint32_t);
    9797    ExpressionType addConstant(Type type, uint64_t) { return type; }
     
    133133    // Calls
    134134    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);
    136136
    137137    bool hasMemory() const { return !!m_module.memory; }
     
    156156};
    157157
    158 auto Validate::addArguments(const Vector<Type>& args) -> Result
    159 {
    160     for (Type arg : args)
    161         WASM_FAIL_IF_HELPER_FAILS(addLocal(arg, 1));
     158auto 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));
    162162    return { };
    163163}
     
    311311auto Validate::addCall(unsigned, const Signature* signature, const Vector<ExpressionType>& args, ExpressionType& result) -> Result
    312312{
    313     WASM_VALIDATOR_FAIL_IF(signature->arguments.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());
    314314
    315315    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
     322auto 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();
    325327    WASM_VALIDATOR_FAIL_IF(argumentCount != args.size() - 1, "arity mismatch in call_indirect, got ", args.size() - 1, " arguments, expected ", argumentCount);
    326328
    327329    for (unsigned i = 0; i < argumentCount; ++i)
    328         WASM_VALIDATOR_FAIL_IF(args[i] != signature->arguments[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));
    329331
    330332    WASM_VALIDATOR_FAIL_IF(args.last() != I32, "non-i32 call_indirect index ", args.last());
    331333
    332     result = signature->returnType;
     334    result = signature->returnType();
    333335    return { };
    334336}
     
    352354}
    353355
    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);
     356Expected<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);
    358360    WASM_FAIL_IF_HELPER_FAILS(validator.parse());
    359361    return { };
  • trunk/Source/JavaScriptCore/wasm/WasmValidate.h

    r209880 r210026  
    3131#include <wtf/Expected.h>
    3232
    33 namespace JSC { namespace Wasm {
     33namespace JSC {
    3434
    35 Expected<void, String> validateFunction(const uint8_t*, size_t, const Signature*, const ImmutableFunctionIndexSpace&, const ModuleInformation&);
     35class VM;
     36
     37namespace Wasm {
     38
     39Expected<void, String> validateFunction(VM*, const uint8_t*, size_t, const Signature*, const ImmutableFunctionIndexSpace&, const ModuleInformation&);
    3640
    3741} } // namespace JSC::Wasm
  • trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp

    r209897 r210026  
    4242{
    4343    // 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    auto* instance = new (NotNull, allocateCell<JSWebAssemblyInstance>(vm.heap, allocationSize(module->moduleInformation().importFunctionSignatureIndices.size()))) JSWebAssemblyInstance(vm, structure, module->moduleInformation().importFunctionSignatureIndices.size());
    4545    instance->finishCreation(vm, module, moduleNamespaceObject);
    4646    return instance;
  • trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.h

    r209696 r210026  
    5151    const Wasm::ModuleInformation& moduleInformation() const { return *m_moduleInformation.get(); }
    5252    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    }
    5458    unsigned importCount() const { return m_wasmToJSStubs.size(); }
    5559
  • trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.cpp

    r209897 r210026  
    6868    for (uint32_t i = 0; i < m_size; ++i) {
    6969        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.
    7171        new (&m_jsFunctions.get()[i]) WriteBarrier<WebAssemblyFunction>();
    7272    }
     
    122122    m_jsFunctions.get()[index] = WriteBarrier<WebAssemblyFunction>();
    123123    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.
    125125}
    126126
     
    129129    RELEASE_ASSERT(index < m_size);
    130130    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());
    132132}
    133133
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp

    r209897 r210026  
    5353    if (!wasmFunction)
    5454        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);
    5657
    5758    // FIXME is this the right behavior? https://bugs.webkit.org/show_bug.cgi?id=164876
    58     if (exec->argumentCount() != signature->arguments.size())
     59    if (exec->argumentCount() != signature->argumentCount())
    5960        return JSValue::encode(throwException(exec, scope, createNotEnoughArgumentsError(exec, defaultSourceAppender)));
    6061
     
    6364    for (unsigned argIndex = 0; argIndex < exec->argumentCount(); ++argIndex) {
    6465        JSValue arg = exec->uncheckedArgument(argIndex);
    65         switch (signature->arguments[argIndex]) {
     66        switch (signature->argument(argIndex)) {
    6667        case Wasm::I32:
    6768            arg = JSValue::decode(arg.toInt32(exec));
     
    122123
    123124    // FIXME is this correct? https://bugs.webkit.org/show_bug.cgi?id=164876
    124     switch (signature()->returnType) {
     125    switch (m_returnType) {
    125126    case Wasm::Void:
    126127        return JSValue::encode(jsUndefined());
     
    141142}
    142143
    143 WebAssemblyFunction* WebAssemblyFunction::create(VM& vm, JSGlobalObject* globalObject, unsigned length, const String& name, JSWebAssemblyInstance* instance, JSWebAssemblyCallee* jsEntrypoint, JSWebAssemblyCallee* wasmEntrypoint, Wasm::Signature* signature)
     144WebAssemblyFunction* WebAssemblyFunction::create(VM& vm, JSGlobalObject* globalObject, unsigned length, const String& name, JSWebAssemblyInstance* instance, JSWebAssemblyCallee* jsEntrypoint, JSWebAssemblyCallee* wasmEntrypoint, Wasm::SignatureIndex signatureIndex)
    144145{
    145146    NativeExecutable* executable = vm.getHostFunction(callWebAssemblyFunction, NoIntrinsic, callHostFunctionAsConstructor, nullptr, name);
    146147    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);
    149150    return function;
    150151}
     
    156157}
    157158
    158 WebAssemblyFunction::WebAssemblyFunction(VM& vm, JSGlobalObject* globalObject, Structure* structure)
     159WebAssemblyFunction::WebAssemblyFunction(VM& vm, JSGlobalObject* globalObject, Structure* structure, Wasm::SignatureIndex signatureIndex)
    159160    : Base(vm, globalObject, structure)
     161    , m_signatureIndex(signatureIndex)
    160162{
     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();
    161166}
    162167
     
    171176}
    172177
    173 void WebAssemblyFunction::finishCreation(VM& vm, NativeExecutable* executable, unsigned length, const String& name, JSWebAssemblyInstance* instance, JSWebAssemblyCallee* jsEntrypoint, JSWebAssemblyCallee* wasmEntrypoint, Wasm::Signature* signature)
     178void WebAssemblyFunction::finishCreation(VM& vm, NativeExecutable* executable, unsigned length, const String& name, JSWebAssemblyInstance* instance, JSWebAssemblyCallee* jsEntrypoint, JSWebAssemblyCallee* wasmEntrypoint)
    174179{
    175180    Base::finishCreation(vm, executable, length, name);
     
    179184    m_jsEntrypoint.set(vm, this, jsEntrypoint);
    180185    m_wasmEntrypoint.set(vm, this, wasmEntrypoint);
    181     m_signature = signature;
    182186}
    183187
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.h

    r209771 r210026  
    4242}
    4343
    44 namespace Wasm {
    45 struct Signature;
    46 }
    47 
    4844class WebAssemblyFunction : public JSFunction {
    4945public:
     
    5450    DECLARE_EXPORT_INFO;
    5551
    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);
    5753    static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
    5854
    5955    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; }
    6557    EncodedJSValue call(VM&, ProtoCallFrame*);
    6658    void* wasmEntrypoint() { return m_wasmEntrypoint->entrypoint(); }
     
    6961    static void visitChildren(JSCell*, SlotVisitor&);
    7062
    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);
    7264
    7365private:
    74     WebAssemblyFunction(VM&, JSGlobalObject*, Structure*);
     66    WebAssemblyFunction(VM&, JSGlobalObject*, Structure*, Wasm::SignatureIndex);
    7567
    7668    WriteBarrier<JSWebAssemblyInstance> m_instance;
    7769    WriteBarrier<JSWebAssemblyCallee> m_jsEntrypoint;
    7870    WriteBarrier<JSWebAssemblyCallee> m_wasmEntrypoint;
    79     Wasm::Signature* m_signature;
     71    Wasm::SignatureIndex m_signatureIndex;
     72    Wasm::Type m_returnType;
    8073};
    8174
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp

    r209897 r210026  
    3737#include "ProtoCallFrame.h"
    3838#include "WasmFormat.h"
     39#include "WasmSignature.h"
    3940#include "WebAssemblyFunction.h"
    4041#include <limits>
     
    120121            JSWebAssemblyCallee* jsEntrypointCallee = module->jsEntrypointCalleeFromFunctionIndexSpace(exp.kindIndex);
    121122            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);
    124126            exportedValue = function;
    125127            if (hasStart && startFunctionIndexSpace == exp.kindIndex)
     
    176178
    177179    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);
    179182        // The start function must not take any arguments or return anything. This is enforced by the parser.
    180         ASSERT(!signature->arguments.size());
    181         ASSERT(signature->returnType == Wasm::Void);
     183        ASSERT(!signature->argumentCount());
     184        ASSERT(signature->returnType() == Wasm::Void);
    182185        // FIXME can start call imports / tables? This assumes not. https://github.com/WebAssembly/design/issues/896
    183186        if (!m_startFunction.get()) {
     
    185188            JSWebAssemblyCallee* jsEntrypointCallee = module->jsEntrypointCalleeFromFunctionIndexSpace(startFunctionIndexSpace);
    186189            JSWebAssemblyCallee* wasmEntrypointCallee = module->wasmEntrypointCalleeFromFunctionIndexSpace(startFunctionIndexSpace);
    187             WebAssemblyFunction* function = WebAssemblyFunction::create(vm, globalObject, signature->arguments.size(), "start", instance, jsEntrypointCallee, wasmEntrypointCallee, signature);
     190            WebAssemblyFunction* function = WebAssemblyFunction::create(vm, globalObject, signature->argumentCount(), "start", instance, jsEntrypointCallee, wasmEntrypointCallee, signatureIndex);
    188191            m_startFunction.set(vm, this, function);
    189192        }
     
    237240                JSWebAssemblyCallee* jsEntrypointCallee = module->jsEntrypointCalleeFromFunctionIndexSpace(functionIndex);
    238241                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);
    240244                // FIXME: Say we export local function "foo" at funciton index 0.
    241245                // What if we also set it to the table an Element w/ index 0.
     
    243247                // https://bugs.webkit.org/show_bug.cgi?id=165825
    244248                WebAssemblyFunction* function = WebAssemblyFunction::create(
    245                     vm, m_instance->globalObject(), signature->arguments.size(), String(), m_instance.get(), jsEntrypointCallee, wasmEntrypointCallee, signature);
     249                    vm, m_instance->globalObject(), signature->argumentCount(), String(), m_instance.get(), jsEntrypointCallee, wasmEntrypointCallee, signatureIndex);
    246250
    247251                table->setFunction(vm, tableIndex, function);
Note: See TracChangeset for help on using the changeset viewer.