Ignore:
Timestamp:
Dec 9, 2016, 11:12:53 PM (9 years ago)
Author:
[email protected]
Message:

Wasm should support call_indirect
https://bugs.webkit.org/show_bug.cgi?id=165718

Reviewed by Filip Pizlo.

JSTests:

  • wasm/Builder.js:
  • wasm/function-tests/call-indirect-params.js: Added.
  • wasm/function-tests/call-indirect.js: Added.
  • wasm/js-api/call-indirect.js: Added.

(const.wasmModuleWhichImportJS):
(MonomorphicImport):
(Polyphic2Import):
(VirtualImport):

  • wasm/wasm.json:

Source/JavaScriptCore:

This patch adds support for call_indirect. The basic framework for
an indirect call is that the module holds a buffer containing a
stub for each function in the index space. Whenever a function
needs to do an indirect call it gets a index into that table. In
order to ensure call_indirect is calling a valid function the
functionIndexSpace also needs a pointer to a canonicalized
signature. When making an indirect call, we first check the index
is in range, then check the signature matches the value we were given.

This patch also differentiates between FunctionIndexSpaces and
ImmutableFunctionIndexSpaces. Since we don't know the size of the
FunctionIndexSpace when we start parsing we need to be able to
resize the IndexSpace. However, once we have finished parsing all
the sections we want to prevent an relocation of the function
index space pointer.

  • wasm/WasmB3IRGenerator.cpp:

(JSC::Wasm::B3IRGenerator::B3IRGenerator):
(JSC::Wasm::B3IRGenerator::addCall):
(JSC::Wasm::B3IRGenerator::addCallIndirect):
(JSC::Wasm::createJSToWasmWrapper):
(JSC::Wasm::parseAndCompile):

  • wasm/WasmB3IRGenerator.h:
  • wasm/WasmCallingConvention.h:

(JSC::Wasm::CallingConvention::setupCall):

  • wasm/WasmFormat.h:
  • wasm/WasmFunctionParser.h:

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

  • wasm/WasmPlan.cpp:

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

  • wasm/WasmPlan.h:

(JSC::Wasm::Plan::takeFunctionIndexSpace):

  • wasm/WasmValidate.cpp:

(JSC::Wasm::Validate::addCallIndirect):
(JSC::Wasm::validateFunction):

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

(JSC::JSWebAssemblyModule::create):
(JSC::JSWebAssemblyModule::JSWebAssemblyModule):

  • wasm/js/JSWebAssemblyModule.h:

(JSC::JSWebAssemblyModule::signatureForFunctionIndexSpace):
(JSC::JSWebAssemblyModule::offsetOfFunctionIndexSpace):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/wasm/WasmPlan.cpp

    r209630 r209652  
    7373        m_moduleInformation = WTFMove(moduleParser.moduleInformation());
    7474        m_functionLocationInBinary = WTFMove(moduleParser.functionLocationInBinary());
    75         m_functionIndexSpace = WTFMove(moduleParser.functionIndexSpace());
     75        m_functionIndexSpace.size = moduleParser.functionIndexSpace().size();
     76        m_functionIndexSpace.buffer = moduleParser.functionIndexSpace().releaseBuffer();
    7677    }
    7778    if (verbose)
     
    104105        Signature* signature = m_moduleInformation->importFunctions.at(import->kindIndex);
    105106        m_wasmToJSStubs.uncheckedAppend(importStubGenerator(m_vm, m_callLinkInfos, signature, importFunctionIndex));
    106         m_functionIndexSpace[importFunctionIndex].code = m_wasmToJSStubs[importFunctionIndex].code().executableAddress();
     107        m_functionIndexSpace.buffer.get()[importFunctionIndex].code = m_wasmToJSStubs[importFunctionIndex].code().executableAddress();
    107108    }
    108109
     
    115116        Signature* signature = m_moduleInformation->internalFunctionSignatures[functionIndex];
    116117        unsigned functionIndexSpace = m_wasmToJSStubs.size() + functionIndex;
    117         ASSERT(m_functionIndexSpace[functionIndexSpace].signature == signature);
     118        ASSERT(m_functionIndexSpace.buffer.get()[functionIndexSpace].signature == signature);
    118119
    119         String error = validateFunction(functionStart, functionLength, signature, m_functionIndexSpace, m_moduleInformation->memory);
     120        String error = validateFunction(functionStart, functionLength, signature, m_functionIndexSpace, *m_moduleInformation);
    120121        if (!error.isNull()) {
    121122            if (verbose) {
     
    129130
    130131        unlinkedWasmToWasmCalls.uncheckedAppend(Vector<UnlinkedWasmToWasmCall>());
    131         m_wasmInternalFunctions.uncheckedAppend(parseAndCompile(*m_vm, functionStart, functionLength, m_moduleInformation->memory, signature, unlinkedWasmToWasmCalls.at(functionIndex), m_functionIndexSpace));
    132         m_functionIndexSpace[functionIndexSpace].code = m_wasmInternalFunctions[functionIndex]->code->code().executableAddress();
     132        m_wasmInternalFunctions.uncheckedAppend(parseAndCompile(*m_vm, functionStart, functionLength, signature, unlinkedWasmToWasmCalls.at(functionIndex), m_functionIndexSpace, *m_moduleInformation));
     133        m_functionIndexSpace.buffer.get()[functionIndexSpace].code = m_wasmInternalFunctions[functionIndex]->code->code().executableAddress();
    133134    }
    134135
     
    136137    for (auto& unlinked : unlinkedWasmToWasmCalls) {
    137138        for (auto& call : unlinked)
    138             MacroAssembler::repatchCall(call.callLocation, CodeLocationLabel(m_functionIndexSpace[call.functionIndex].code));
     139            MacroAssembler::repatchCall(call.callLocation, CodeLocationLabel(m_functionIndexSpace.buffer.get()[call.functionIndex].code));
    139140    }
    140141
Note: See TracChangeset for help on using the changeset viewer.