[WebAssembly] Move type conversion code of JSToWasm return type to JS wasm wrapper
authoryusukesuzuki@slowstart.org <yusukesuzuki@slowstart.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 1 Oct 2018 09:25:41 +0000 (09:25 +0000)
committeryusukesuzuki@slowstart.org <yusukesuzuki@slowstart.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 1 Oct 2018 09:25:41 +0000 (09:25 +0000)
https://bugs.webkit.org/show_bug.cgi?id=189498

Reviewed by Saam Barati.

To call JS-to-Wasm code we need to convert the result value from wasm function to
the JS type. Previously this is done by callWebAssemblyFunction by using swtich
over signature.returnType(). But since we know the value of `signature.returnType()`
at compiling phase, we can emit a small conversion code directly to JSToWasm glue
and remove this switch from callWebAssemblyFunction.

In JSToWasm glue code, we do not have tag registers. So we use DoNotHaveTagRegisters
in boxInt32 and boxDouble. Since boxDouble does not have DoNotHaveTagRegisters version,
we add an implementation for that.

* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::boxDouble):
* wasm/js/JSToWasm.cpp:
(JSC::Wasm::createJSToWasmWrapper):
* wasm/js/WebAssemblyFunction.cpp:
(JSC::callWebAssemblyFunction):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@236651 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/jit/AssemblyHelpers.h
Source/JavaScriptCore/wasm/js/JSToWasm.cpp
Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp

index 917ecc3..c178af4 100644 (file)
@@ -1,3 +1,27 @@
+2018-10-01  Yusuke Suzuki  <yusukesuzuki@slowstart.org>
+
+        [WebAssembly] Move type conversion code of JSToWasm return type to JS wasm wrapper
+        https://bugs.webkit.org/show_bug.cgi?id=189498
+
+        Reviewed by Saam Barati.
+
+        To call JS-to-Wasm code we need to convert the result value from wasm function to
+        the JS type. Previously this is done by callWebAssemblyFunction by using swtich
+        over signature.returnType(). But since we know the value of `signature.returnType()`
+        at compiling phase, we can emit a small conversion code directly to JSToWasm glue
+        and remove this switch from callWebAssemblyFunction.
+
+        In JSToWasm glue code, we do not have tag registers. So we use DoNotHaveTagRegisters
+        in boxInt32 and boxDouble. Since boxDouble does not have DoNotHaveTagRegisters version,
+        we add an implementation for that.
+
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::boxDouble):
+        * wasm/js/JSToWasm.cpp:
+        (JSC::Wasm::createJSToWasmWrapper):
+        * wasm/js/WebAssemblyFunction.cpp:
+        (JSC::callWebAssemblyFunction):
+
 2018-09-30  Caio Lima  <ticaiolima@gmail.com>
 
         [BigInt] BigInt.proptotype.toString is broken when radix is power of 2
index 01731a5..9f1d30b 100644 (file)
@@ -1244,11 +1244,15 @@ public:
 
     // These methods convert between doubles, and doubles boxed and JSValues.
 #if USE(JSVALUE64)
-    GPRReg boxDouble(FPRReg fpr, GPRReg gpr)
+    GPRReg boxDouble(FPRReg fpr, GPRReg gpr, TagRegistersMode mode = HaveTagRegisters)
     {
         moveDoubleTo64(fpr, gpr);
-        sub64(GPRInfo::tagTypeNumberRegister, gpr);
-        jitAssertIsJSDouble(gpr);
+        if (mode == DoNotHaveTagRegisters)
+            sub64(TrustedImm64(TagTypeNumber), gpr);
+        else {
+            sub64(GPRInfo::tagTypeNumberRegister, gpr);
+            jitAssertIsJSDouble(gpr);
+        }
         return gpr;
     }
     FPRReg unboxDoubleWithoutAssertions(GPRReg gpr, GPRReg resultGPR, FPRReg fpr)
@@ -1263,9 +1267,9 @@ public:
         return unboxDoubleWithoutAssertions(gpr, resultGPR, fpr);
     }
     
-    void boxDouble(FPRReg fpr, JSValueRegs regs)
+    void boxDouble(FPRReg fpr, JSValueRegs regs, TagRegistersMode mode = HaveTagRegisters)
     {
-        boxDouble(fpr, regs.gpr());
+        boxDouble(fpr, regs.gpr(), mode);
     }
 
     void unboxDoubleNonDestructive(JSValueRegs regs, FPRReg destFPR, GPRReg resultGPR, FPRReg)
index a603f4b..2334d6b 100644 (file)
@@ -209,11 +209,27 @@ std::unique_ptr<InternalFunction> createJSToWasmWrapper(CompilationContext& comp
     }
 
     switch (signature.returnType()) {
+    case Wasm::Void:
+        jit.moveTrustedValue(jsUndefined(), JSValueRegs { GPRInfo::returnValueGPR });
+        break;
+    case Wasm::I32:
+        jit.zeroExtend32ToPtr(GPRInfo::returnValueGPR, GPRInfo::returnValueGPR);
+        jit.boxInt32(GPRInfo::returnValueGPR, JSValueRegs { GPRInfo::returnValueGPR }, DoNotHaveTagRegisters);
+        break;
     case Wasm::F32:
-        jit.moveFloatTo32(FPRInfo::returnValueFPR, GPRInfo::returnValueGPR);
+        jit.convertFloatToDouble(FPRInfo::returnValueFPR, FPRInfo::returnValueFPR);
+        FALLTHROUGH;
+    case Wasm::F64: {
+        jit.moveTrustedValue(jsNumber(pureNaN()), JSValueRegs { GPRInfo::returnValueGPR });
+        auto isNaN = jit.branchDouble(CCallHelpers::DoubleNotEqualOrUnordered, FPRInfo::returnValueFPR, FPRInfo::returnValueFPR);
+        jit.boxDouble(FPRInfo::returnValueFPR, JSValueRegs { GPRInfo::returnValueGPR }, DoNotHaveTagRegisters);
+        isNaN.link(&jit);
         break;
-    case Wasm::F64:
-        jit.moveDoubleTo64(FPRInfo::returnValueFPR, GPRInfo::returnValueGPR);
+    }
+    case Wasm::I64:
+    case Wasm::Func:
+    case Wasm::Anyfunc:
+        jit.breakpoint();
         break;
     default:
         break;
index ec619da..4d9a8f9 100644 (file)
@@ -161,22 +161,7 @@ static EncodedJSValue JSC_HOST_CALL callWebAssemblyFunction(ExecState* exec)
     vm.wasmContext.store(prevWasmInstance, vm.softStackLimit());
     RETURN_IF_EXCEPTION(scope, { });
 
-    switch (signature.returnType()) {
-    case Wasm::Void:
-        return JSValue::encode(jsUndefined());
-    case Wasm::I32:
-        return JSValue::encode(jsNumber(static_cast<int32_t>(rawResult)));
-    case Wasm::F32:
-        return JSValue::encode(jsNumber(purifyNaN(static_cast<double>(bitwise_cast<float>(static_cast<int32_t>(rawResult))))));
-    case Wasm::F64:
-        return JSValue::encode(jsNumber(purifyNaN(bitwise_cast<double>(rawResult))));
-    case Wasm::I64:
-    case Wasm::Func:
-    case Wasm::Anyfunc:
-        RELEASE_ASSERT_NOT_REACHED();
-    }
-
-    return EncodedJSValue();
+    return rawResult;
 }
 
 WebAssemblyFunction* WebAssemblyFunction::create(VM& vm, JSGlobalObject* globalObject, unsigned length, const String& name, JSWebAssemblyInstance* instance, Wasm::Callee& jsEntrypoint, Wasm::WasmToWasmImportableFunction::LoadLocation wasmToWasmEntrypointLoadLocation, Wasm::SignatureIndex signatureIndex)