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/WasmValidate.cpp

    r209630 r209652  
    111111    bool WARN_UNUSED_RETURN addEndToUnreachable(ControlEntry&);
    112112
    113 
     113    // Calls
    114114    bool WARN_UNUSED_RETURN addCall(unsigned calleeIndex, const Signature*, const Vector<ExpressionType>& args, ExpressionType& result);
     115    bool WARN_UNUSED_RETURN addCallIndirect(const Signature*, const Vector<ExpressionType>& args, ExpressionType& result);
    115116
    116117    void dump(const Vector<ControlEntry>& controlStack, const ExpressionList& expressionStack);
     
    348349}
    349350
     351bool Validate::addCallIndirect(const Signature* signature, const Vector<ExpressionType>& args, ExpressionType& result)
     352{
     353    const auto argumentCount = signature->arguments.size();
     354    if (argumentCount != args.size() - 1) {
     355        StringBuilder builder;
     356        builder.append("Arity mismatch in call_indirect, expected: ");
     357        builder.appendNumber(signature->arguments.size());
     358        builder.append(" but got: ");
     359        builder.appendNumber(args.size());
     360        m_errorMessage = builder.toString();
     361        return false;
     362    }
     363
     364    for (unsigned i = 0; i < argumentCount; ++i) {
     365        if (args[i] != signature->arguments[i]) {
     366            m_errorMessage = makeString("Expected argument type: ", toString(signature->arguments[i]), " does not match passed argument type: ", toString(args[i]));
     367            return false;
     368        }
     369    }
     370
     371    if (args.last() != I32) {
     372        m_errorMessage = makeString("Expected call_indirect target index to have type: i32 but got type: ", toString(args.last()));
     373        return false;
     374    }
     375   
     376    result = signature->returnType;
     377    return true;
     378}
     379
    350380bool Validate::unify(const ExpressionList& values, const ControlType& block)
    351381{
     
    372402}
    373403
    374 String validateFunction(const uint8_t* source, size_t length, const Signature* signature, const FunctionIndexSpace& functionIndexSpace, const MemoryInformation& memory)
    375 {
    376     Validate context(signature->returnType, memory);
    377     FunctionParser<Validate> validator(context, source, length, signature, functionIndexSpace);
     404String validateFunction(const uint8_t* source, size_t length, const Signature* signature, const ImmutableFunctionIndexSpace& functionIndexSpace, const ModuleInformation& info)
     405{
     406    Validate context(signature->returnType, info.memory);
     407    FunctionParser<Validate> validator(context, source, length, signature, functionIndexSpace, info);
     408
    378409    if (!validator.parse()) {
    379410        // FIXME: add better location information here. see: https://bugs.webkit.org/show_bug.cgi?id=164288
Note: See TracChangeset for help on using the changeset viewer.