Changeset 238376 in webkit


Ignore:
Timestamp:
Nov 19, 2018 8:49:43 AM (5 years ago)
Author:
yusukesuzuki@slowstart.org
Message:

[WebAssembly] I64 arguments / return value check should be moved from callWebAssemblyFunction to JSToWasm wrapper
https://bugs.webkit.org/show_bug.cgi?id=190512

Reviewed by Keith Miller.

This patch moves I64 arguments / return value check from callWebAssemblyFunction to JSToWasm wrapper. Since this
check can be done when compiling the function, we should encode the result into the generated wrapper instead of
checking every time we call callWebAssemblyFunction. This change is also one of the steps removing callWebAssemblyFunction
entirely.

  • wasm/WasmExceptionType.h:
  • wasm/js/JSToWasm.cpp:

(JSC::Wasm::createJSToWasmWrapper):

  • wasm/js/WebAssemblyFunction.cpp:

(JSC::callWebAssemblyFunction):

  • wasm/js/WebAssemblyWrapperFunction.cpp:

(JSC::callWebAssemblyWrapperFunction):

Location:
trunk/Source/JavaScriptCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r238367 r238376  
     12018-11-19  Yusuke Suzuki  <yusukesuzuki@slowstart.org>
     2
     3        [WebAssembly] I64 arguments / return value check should be moved from callWebAssemblyFunction to JSToWasm wrapper
     4        https://bugs.webkit.org/show_bug.cgi?id=190512
     5
     6        Reviewed by Keith Miller.
     7
     8        This patch moves I64 arguments / return value check from callWebAssemblyFunction to JSToWasm wrapper. Since this
     9        check can be done when compiling the function, we should encode the result into the generated wrapper instead of
     10        checking every time we call callWebAssemblyFunction. This change is also one of the steps removing callWebAssemblyFunction
     11        entirely.
     12
     13        * wasm/WasmExceptionType.h:
     14        * wasm/js/JSToWasm.cpp:
     15        (JSC::Wasm::createJSToWasmWrapper):
     16        * wasm/js/WebAssemblyFunction.cpp:
     17        (JSC::callWebAssemblyFunction):
     18        * wasm/js/WebAssemblyWrapperFunction.cpp:
     19        (JSC::callWebAssemblyWrapperFunction):
     20
    1212018-11-12  Yusuke Suzuki  <yusukesuzuki@slowstart.org>
    222
  • trunk/Source/JavaScriptCore/wasm/WasmExceptionType.h

    r217060 r238376  
    4141    macro(DivisionByZero, "Division by zero") \
    4242    macro(IntegerOverflow, "Integer overflow") \
    43     macro(StackOverflow, "Stack overflow")
     43    macro(StackOverflow, "Stack overflow") \
     44    macro(I64ArgumentType, "WebAssembly function with an i64 argument can't be called from JavaScript") \
     45    macro(I64ReturnType, "WebAssembly function that returns i64 can't be called from JavaScript")
    4446
    4547enum class ExceptionType : uint32_t {
  • trunk/Source/JavaScriptCore/wasm/js/JSToWasm.cpp

    r236734 r238376  
    3131#include "CCallHelpers.h"
    3232#include "JSWebAssemblyInstance.h"
     33#include "JSWebAssemblyRuntimeError.h"
     34#include "MaxFrameExtentForSlowPathCall.h"
    3335#include "WasmCallingConvention.h"
    3436#include "WasmContextInlines.h"
    3537#include "WasmSignatureInlines.h"
     38#include "WasmToJS.h"
    3639
    3740namespace JSC { namespace Wasm {
     
    7174    unsigned numGPRs = 0;
    7275    unsigned numFPRs = 0;
     76    bool argumentsIncludeI64 = false;
    7377    for (unsigned i = 0; i < signature.argumentCount(); i++) {
    7478        switch (signature.argument(i)) {
    7579        case Wasm::I64:
     80            argumentsIncludeI64 = true;
     81            FALLTHROUGH;
    7682        case Wasm::I32:
    7783            if (numGPRs >= wasmCallingConvention().m_gprArgs.size())
     
    101107        ptrdiff_t offset = regAtOffset.offset();
    102108        jit.storePtr(reg, CCallHelpers::Address(GPRInfo::callFrameRegister, offset));
     109    }
     110
     111    if (argumentsIncludeI64 || signature.returnType() == Wasm::I64) {
     112        if (Context::useFastTLS())
     113            jit.loadWasmContextInstance(GPRInfo::argumentGPR2);
     114        else {
     115            // vmEntryToWasm passes the JSWebAssemblyInstance corresponding to Wasm::Context*'s
     116            // instance as the first JS argument when we're not using fast TLS to hold the
     117            // Wasm::Context*'s instance.
     118            jit.loadPtr(CCallHelpers::Address(GPRInfo::callFrameRegister, CallFrameSlot::thisArgument * sizeof(EncodedJSValue)), GPRInfo::argumentGPR2);
     119            jit.loadPtr(CCallHelpers::Address(GPRInfo::argumentGPR2, JSWebAssemblyInstance::offsetOfPoisonedInstance()), GPRInfo::argumentGPR2);
     120            jit.move(CCallHelpers::TrustedImm64(JSWebAssemblyInstancePoison::key()), GPRInfo::argumentGPR0);
     121            jit.xor64(GPRInfo::argumentGPR0, GPRInfo::argumentGPR2);
     122        }
     123
     124        jit.loadPtr(CCallHelpers::Address(GPRInfo::argumentGPR2, Instance::offsetOfPointerToTopEntryFrame()), GPRInfo::argumentGPR0);
     125        jit.loadPtr(CCallHelpers::Address(GPRInfo::argumentGPR0), GPRInfo::argumentGPR0);
     126        jit.copyCalleeSavesToEntryFrameCalleeSavesBuffer(GPRInfo::argumentGPR0);
     127        jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
     128        jit.move(CCallHelpers::TrustedImm32(static_cast<int32_t>(argumentsIncludeI64 ? ExceptionType::I64ArgumentType : ExceptionType::I64ReturnType)), GPRInfo::argumentGPR1);
     129
     130        CCallHelpers::Call call = jit.call(OperationPtrTag);
     131
     132        jit.jump(GPRInfo::returnValueGPR, ExceptionHandlerPtrTag);
     133        jit.breakpoint(); // We should not reach this.
     134
     135        jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
     136            linkBuffer.link(call, FunctionPtr<OperationPtrTag>(wasmToJSException));
     137        });
     138        return result;
    103139    }
    104140
     
    201237    });
    202238
    203 
    204239    for (const RegisterAtOffset& regAtOffset : registersToSpill) {
    205240        GPRReg reg = regAtOffset.reg().gpr();
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp

    r237042 r238376  
    5656    VM& vm = exec->vm();
    5757    auto scope = DECLARE_THROW_SCOPE(vm);
    58     WebAssemblyFunction* wasmFunction = jsDynamicCast<WebAssemblyFunction*>(vm, exec->jsCallee());
    59     if (!wasmFunction)
    60         return JSValue::encode(throwException(exec, scope, createTypeError(exec, "expected a WebAssembly function", defaultSourceAppender, runtimeTypeForValue(vm, exec->jsCallee()))));
     58    WebAssemblyFunction* wasmFunction = jsCast<WebAssemblyFunction*>(exec->jsCallee());
    6159    Wasm::SignatureIndex signatureIndex = wasmFunction->signatureIndex();
    6260    const Wasm::Signature& signature = Wasm::SignatureInformation::get(signatureIndex);
     
    6462    // Make sure that the memory we think we are going to run with matches the one we expect.
    6563    ASSERT(wasmFunction->instance()->instance().codeBlock()->isSafeToRun(wasmFunction->instance()->memory()->memory().mode()));
    66     {
    67         // Check if we have a disallowed I64 use.
    68 
    69         for (unsigned argIndex = 0; argIndex < signature.argumentCount(); ++argIndex) {
    70             if (signature.argument(argIndex) == Wasm::I64) {
    71                 JSWebAssemblyRuntimeError* error = JSWebAssemblyRuntimeError::create(exec, vm, exec->lexicalGlobalObject()->WebAssemblyRuntimeErrorStructure(),
    72                     "WebAssembly function with an i64 argument can't be called from JavaScript");
    73                 return JSValue::encode(throwException(exec, scope, error));
    74             }
    75         }
    76 
    77         if (signature.returnType() == Wasm::I64) {
    78             JSWebAssemblyRuntimeError* error = JSWebAssemblyRuntimeError::create(exec, vm, exec->lexicalGlobalObject()->WebAssemblyRuntimeErrorStructure(),
    79                 "WebAssembly function that returns i64 can't be called from JavaScript");
    80             return JSValue::encode(throwException(exec, scope, error));
    81         }
    82     }
    8364
    8465    std::optional<TraceScope> traceScope;
     
    10081            arg = JSValue::decode(arg.toInt32(exec));
    10182            break;
     83        case Wasm::I64:
     84            arg = JSValue();
     85            break;
    10286        case Wasm::F32:
    10387            arg = JSValue::decode(bitwise_cast<uint32_t>(arg.toFloat(exec)));
     
    10791            break;
    10892        case Wasm::Void:
    109         case Wasm::I64:
    11093        case Wasm::Func:
    11194        case Wasm::Anyfunc:
  • trunk/Source/JavaScriptCore/wasm/js/WebAssemblyWrapperFunction.cpp

    r236697 r238376  
    4343    VM& vm = exec->vm();
    4444    auto scope = DECLARE_THROW_SCOPE(vm);
    45     WebAssemblyWrapperFunction* wasmFunction = jsDynamicCast<WebAssemblyWrapperFunction*>(vm, exec->jsCallee());
    46     if (!wasmFunction)
    47         return JSValue::encode(throwException(exec, scope, createTypeError(exec, "expected a WebAssembly function")));
    48 
     45    WebAssemblyWrapperFunction* wasmFunction = jsCast<WebAssemblyWrapperFunction*>(exec->jsCallee());
    4946    CallData callData;
    5047    JSObject* function = wasmFunction->function();
Note: See TracChangeset for help on using the changeset viewer.