WebAssembly: When Wasm calls to C, it should use Wasm::Context* instead of ExecState...
authorsbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 31 Mar 2017 01:15:25 +0000 (01:15 +0000)
committersbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 31 Mar 2017 01:15:25 +0000 (01:15 +0000)
https://bugs.webkit.org/show_bug.cgi?id=170185

Reviewed by Michael Saboff.

This is one more step in the direction of PIC-ified Wasm.
When we lift WasmCallee above VM, we will no longer be
able to get VM from ExecState*. This patch ensures that
we don't do that from within the Wasm runtime. Instead,
we use the Wasm::Context* to get the VM.

This patch also adds a new class, Wasm::Thunks. There
is a single Wasm::Thunks that lives in the process. It
is responsible for generating a thunk that Wasm relies on.
The only such thunk right now is the exception throwing
thunk.

This patch also rids WasmFaultSignalHandler from any knowledge
of VM. Previously, it relied on VM to get the exception handling
thunk.

The only part of the Wasm runtime that will be allowed
to get VM& from ExecState will be WasmBinding. In the
future, we plan to keep the calls out to JS to keep
a JSCell as the callee.

* JavaScriptCore.xcodeproj/project.pbxproj:
* dfg/DFGOSREntry.cpp:
(JSC::DFG::prepareOSREntry):
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileStub):
* interpreter/Interpreter.cpp:
(JSC::UnwindFunctor::copyCalleeSavesToVMEntryFrameCalleeSavesBuffer):
* jit/AssemblyHelpers.cpp:
(JSC::AssemblyHelpers::restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer):
(JSC::AssemblyHelpers::copyCalleeSavesToVMEntryFrameCalleeSavesBufferImpl):
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::copyCalleeSavesToVMEntryFrameCalleeSavesBuffer):
* jit/ThunkGenerators.cpp:
(JSC::throwExceptionFromWasmThunkGenerator): Deleted.
* jit/ThunkGenerators.h:
* runtime/InitializeThreading.cpp:
(JSC::initializeThreading):
* runtime/VM.cpp:
(JSC::VM::VM):
(JSC::VM::getAllCalleeSaveRegisterOffsets):
* runtime/VM.h:
(JSC::VM::topVMEntryFrameOffset):
(JSC::VM::getAllCalleeSaveRegisterOffsets): Deleted.
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::emitExceptionCheck):
* wasm/WasmFaultSignalHandler.cpp:
(JSC::Wasm::trapHandler):
* wasm/WasmMemory.cpp:
(JSC::Wasm::tryGetFastMemory):
* wasm/WasmThunks.cpp: Added.
(JSC::Wasm::throwExceptionFromWasmThunkGenerator):
(JSC::Wasm::Thunks::initialize):
(JSC::Wasm::Thunks::singleton):
(JSC::Wasm::Thunks::stub):
(JSC::Wasm::Thunks::existingStub):
* wasm/WasmThunks.h: Added.
* wasm/js/JSWebAssemblyInstance.cpp:
(JSC::JSWebAssemblyInstance::JSWebAssemblyInstance):
* wasm/js/JSWebAssemblyInstance.h:
(JSC::JSWebAssemblyInstance::offsetOfVM):
* wasm/js/JSWebAssemblyMemory.cpp:
(JSC::JSWebAssemblyMemory::grow):
* wasm/js/JSWebAssemblyMemory.h:
* wasm/js/WebAssemblyMemoryPrototype.cpp:
(JSC::webAssemblyMemoryProtoFuncGrow):

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

25 files changed:
Source/JavaScriptCore/CMakeLists.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/dfg/DFGOSREntry.cpp
Source/JavaScriptCore/ftl/FTLOSRExitCompiler.cpp
Source/JavaScriptCore/interpreter/Interpreter.cpp
Source/JavaScriptCore/jit/AssemblyHelpers.cpp
Source/JavaScriptCore/jit/AssemblyHelpers.h
Source/JavaScriptCore/jit/ThunkGenerators.cpp
Source/JavaScriptCore/jit/ThunkGenerators.h
Source/JavaScriptCore/runtime/InitializeThreading.cpp
Source/JavaScriptCore/runtime/VM.cpp
Source/JavaScriptCore/runtime/VM.h
Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp
Source/JavaScriptCore/wasm/WasmFaultSignalHandler.cpp
Source/JavaScriptCore/wasm/WasmFaultSignalHandler.h
Source/JavaScriptCore/wasm/WasmMemory.cpp
Source/JavaScriptCore/wasm/WasmThunks.cpp [new file with mode: 0644]
Source/JavaScriptCore/wasm/WasmThunks.h [new file with mode: 0644]
Source/JavaScriptCore/wasm/js/JSWebAssemblyCallee.cpp
Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp
Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h
Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.cpp
Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.h
Source/JavaScriptCore/wasm/js/WebAssemblyMemoryPrototype.cpp

index 7ec2ada..eeda428 100644 (file)
@@ -947,6 +947,7 @@ set(JavaScriptCore_SOURCES
     wasm/WasmPlan.cpp
     wasm/WasmOpcodeOrigin.cpp
     wasm/WasmSignature.cpp
+    wasm/WasmThunks.cpp
     wasm/WasmValidate.cpp
     wasm/WasmWorklist.cpp
 
index 66d4bd6..6bb1f5b 100644 (file)
@@ -1,3 +1,77 @@
+2017-03-30  Saam Barati  <sbarati@apple.com>
+
+        WebAssembly: When Wasm calls to C, it should use Wasm::Context* instead of ExecState* to get VM
+        https://bugs.webkit.org/show_bug.cgi?id=170185
+
+        Reviewed by Michael Saboff.
+
+        This is one more step in the direction of PIC-ified Wasm.
+        When we lift WasmCallee above VM, we will no longer be
+        able to get VM from ExecState*. This patch ensures that
+        we don't do that from within the Wasm runtime. Instead,
+        we use the Wasm::Context* to get the VM.
+
+        This patch also adds a new class, Wasm::Thunks. There
+        is a single Wasm::Thunks that lives in the process. It
+        is responsible for generating a thunk that Wasm relies on.
+        The only such thunk right now is the exception throwing
+        thunk.
+
+        This patch also rids WasmFaultSignalHandler from any knowledge
+        of VM. Previously, it relied on VM to get the exception handling
+        thunk.
+
+        The only part of the Wasm runtime that will be allowed
+        to get VM& from ExecState will be WasmBinding. In the
+        future, we plan to keep the calls out to JS to keep
+        a JSCell as the callee.
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * dfg/DFGOSREntry.cpp:
+        (JSC::DFG::prepareOSREntry):
+        * ftl/FTLOSRExitCompiler.cpp:
+        (JSC::FTL::compileStub):
+        * interpreter/Interpreter.cpp:
+        (JSC::UnwindFunctor::copyCalleeSavesToVMEntryFrameCalleeSavesBuffer):
+        * jit/AssemblyHelpers.cpp:
+        (JSC::AssemblyHelpers::restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer):
+        (JSC::AssemblyHelpers::copyCalleeSavesToVMEntryFrameCalleeSavesBufferImpl):
+        * jit/AssemblyHelpers.h:
+        (JSC::AssemblyHelpers::copyCalleeSavesToVMEntryFrameCalleeSavesBuffer):
+        * jit/ThunkGenerators.cpp:
+        (JSC::throwExceptionFromWasmThunkGenerator): Deleted.
+        * jit/ThunkGenerators.h:
+        * runtime/InitializeThreading.cpp:
+        (JSC::initializeThreading):
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        (JSC::VM::getAllCalleeSaveRegisterOffsets):
+        * runtime/VM.h:
+        (JSC::VM::topVMEntryFrameOffset):
+        (JSC::VM::getAllCalleeSaveRegisterOffsets): Deleted.
+        * wasm/WasmB3IRGenerator.cpp:
+        (JSC::Wasm::B3IRGenerator::emitExceptionCheck):
+        * wasm/WasmFaultSignalHandler.cpp:
+        (JSC::Wasm::trapHandler):
+        * wasm/WasmMemory.cpp:
+        (JSC::Wasm::tryGetFastMemory):
+        * wasm/WasmThunks.cpp: Added.
+        (JSC::Wasm::throwExceptionFromWasmThunkGenerator):
+        (JSC::Wasm::Thunks::initialize):
+        (JSC::Wasm::Thunks::singleton):
+        (JSC::Wasm::Thunks::stub):
+        (JSC::Wasm::Thunks::existingStub):
+        * wasm/WasmThunks.h: Added.
+        * wasm/js/JSWebAssemblyInstance.cpp:
+        (JSC::JSWebAssemblyInstance::JSWebAssemblyInstance):
+        * wasm/js/JSWebAssemblyInstance.h:
+        (JSC::JSWebAssemblyInstance::offsetOfVM):
+        * wasm/js/JSWebAssemblyMemory.cpp:
+        (JSC::JSWebAssemblyMemory::grow):
+        * wasm/js/JSWebAssemblyMemory.h:
+        * wasm/js/WebAssemblyMemoryPrototype.cpp:
+        (JSC::webAssemblyMemoryProtoFuncGrow):
+
 2017-03-30  Mark Lam  <mark.lam@apple.com>
 
         IntlObject should not be using JSArray::initializeIndex().
index d5bae0c..10ba17d 100644 (file)
                4443AE3316E188D90076F110 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51F0EB6105C86C6B00E6DF1B /* Foundation.framework */; };
                451539B912DC994500EF7AC4 /* Yarr.h in Headers */ = {isa = PBXBuildFile; fileRef = 451539B812DC994500EF7AC4 /* Yarr.h */; settings = {ATTRIBUTES = (Private, ); }; };
                473DA4A4764C45FE871B0485 /* DefinePropertyAttributes.h in Headers */ = {isa = PBXBuildFile; fileRef = 169948EDE68D4054B01EF797 /* DefinePropertyAttributes.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               5250D2D11E8DA05A0029A932 /* WasmThunks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5250D2CF1E8DA05A0029A932 /* WasmThunks.cpp */; };
+               5250D2D21E8DA05A0029A932 /* WasmThunks.h in Headers */ = {isa = PBXBuildFile; fileRef = 5250D2D01E8DA05A0029A932 /* WasmThunks.h */; settings = {ATTRIBUTES = (Private, ); }; };
                52678F8E1A031009006A306D /* BasicBlockLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52678F8C1A031009006A306D /* BasicBlockLocation.cpp */; };
                52678F8F1A031009006A306D /* BasicBlockLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = 52678F8D1A031009006A306D /* BasicBlockLocation.h */; settings = {ATTRIBUTES = (Private, ); }; };
                52678F911A04177C006A306D /* ControlFlowProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 52678F901A04177C006A306D /* ControlFlowProfiler.h */; settings = {ATTRIBUTES = (Private, ); }; };
                4CE978E385A8498199052153 /* ModuleNamespaceAccessCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ModuleNamespaceAccessCase.h; sourceTree = "<group>"; };
                51F0EB6105C86C6B00E6DF1B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = "<absolute>"; };
                51F0EC0705C86C9A00E6DF1B /* libobjc.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libobjc.dylib; path = /usr/lib/libobjc.dylib; sourceTree = "<absolute>"; };
+               5250D2CF1E8DA05A0029A932 /* WasmThunks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmThunks.cpp; sourceTree = "<group>"; };
+               5250D2D01E8DA05A0029A932 /* WasmThunks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmThunks.h; sourceTree = "<group>"; };
                52678F8C1A031009006A306D /* BasicBlockLocation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BasicBlockLocation.cpp; sourceTree = "<group>"; };
                52678F8D1A031009006A306D /* BasicBlockLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BasicBlockLocation.h; sourceTree = "<group>"; };
                52678F901A04177C006A306D /* ControlFlowProfiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ControlFlowProfiler.h; sourceTree = "<group>"; };
                                53F40E841D58F9770099A1B6 /* WasmSections.h */,
                                AD7438BE1E04579200FD0C2A /* WasmSignature.cpp */,
                                AD7438BF1E04579200FD0C2A /* WasmSignature.h */,
+                               5250D2CF1E8DA05A0029A932 /* WasmThunks.cpp */,
+                               5250D2D01E8DA05A0029A932 /* WasmThunks.h */,
                                53FF7F9A1DBFD2B900A26CCC /* WasmValidate.cpp */,
                                53FF7F981DBFCD9000A26CCC /* WasmValidate.h */,
                                530FB3031E7A1146003C19DD /* WasmWorklist.cpp */,
                                70B791971C024A29002481E2 /* GeneratorFunctionPrototype.h in Headers */,
                                70B791991C024A29002481E2 /* GeneratorPrototype.h in Headers */,
                                70B7919D1C024A56002481E2 /* GeneratorPrototype.lut.h in Headers */,
+                               5250D2D21E8DA05A0029A932 /* WasmThunks.h in Headers */,
                                0FE050191AA9091100D33B33 /* GenericArguments.h in Headers */,
                                0FE0501A1AA9091100D33B33 /* GenericArgumentsInlines.h in Headers */,
                                0FE0501B1AA9091100D33B33 /* GenericOffset.h in Headers */,
                                0FDDBFB51666EED800C55FEF /* DFGVariableAccessDataDump.cpp in Sources */,
                                0F2BDC5115228FFD00CD8910 /* DFGVariableEvent.cpp in Sources */,
                                0F2BDC4A1522809A00CD8910 /* DFGVariableEventStream.cpp in Sources */,
+                               5250D2D11E8DA05A0029A932 /* WasmThunks.cpp in Sources */,
                                0FFFC95F14EF90BB00C72532 /* DFGVirtualRegisterAllocationPhase.cpp in Sources */,
                                0FC97F4118202119002C9B26 /* DFGWatchpointCollectionPhase.cpp in Sources */,
                                0FDB2CE7174830A2007B3C1B /* DFGWorklist.cpp in Sources */,
index d3fe793..1818b4d 100644 (file)
@@ -312,7 +312,7 @@ void* prepareOSREntry(ExecState* exec, CodeBlock* codeBlock, unsigned bytecodeIn
     // 6) Copy our callee saves to buffer.
 #if NUMBER_OF_CALLEE_SAVES_REGISTERS > 0
     RegisterAtOffsetList* registerSaveLocations = codeBlock->calleeSaveRegisters();
-    RegisterAtOffsetList* allCalleeSaves = vm->getAllCalleeSaveRegisterOffsets();
+    RegisterAtOffsetList* allCalleeSaves = VM::getAllCalleeSaveRegisterOffsets();
     RegisterSet dontSaveRegisters = RegisterSet(RegisterSet::stackRegisters(), RegisterSet::allFPRs());
 
     unsigned registerCount = registerSaveLocations->size();
index f91df37..e7b6a05 100644 (file)
@@ -409,7 +409,7 @@ static void compileStub(
 
     RegisterSet allFTLCalleeSaves = RegisterSet::ftlCalleeSaveRegisters();
     RegisterAtOffsetList* baselineCalleeSaves = baselineCodeBlock->calleeSaveRegisters();
-    RegisterAtOffsetList* vmCalleeSaves = vm->getAllCalleeSaveRegisterOffsets();
+    RegisterAtOffsetList* vmCalleeSaves = VM::getAllCalleeSaveRegisterOffsets();
     RegisterSet vmCalleeSavesToSkip = RegisterSet::stackRegisters();
     if (exit.isExceptionHandler()) {
         jit.loadPtr(&vm->topVMEntryFrame, GPRInfo::regT1);
index 901987d..f3dfa2f 100644 (file)
@@ -635,7 +635,7 @@ private:
             return;
 
         VM& vm = m_callFrame->vm();
-        RegisterAtOffsetList* allCalleeSaves = vm.getAllCalleeSaveRegisterOffsets();
+        RegisterAtOffsetList* allCalleeSaves = VM::getAllCalleeSaveRegisterOffsets();
         RegisterSet dontCopyRegisters = RegisterSet::stackRegisters();
         intptr_t* frame = reinterpret_cast<intptr_t*>(m_callFrame->registers());
 
index 2d057bf..316fd99 100644 (file)
@@ -582,7 +582,7 @@ void AssemblyHelpers::emitRandomThunk(VM& vm, GPRReg scratch0, GPRReg scratch1,
 void AssemblyHelpers::restoreCalleeSavesFromVMEntryFrameCalleeSavesBuffer(VM& vm)
 {
 #if NUMBER_OF_CALLEE_SAVES_REGISTERS > 0
-    RegisterAtOffsetList* allCalleeSaves = vm.getAllCalleeSaveRegisterOffsets();
+    RegisterAtOffsetList* allCalleeSaves = VM::getAllCalleeSaveRegisterOffsets();
     RegisterSet dontRestoreRegisters = RegisterSet::stackRegisters();
     unsigned registerCount = allCalleeSaves->size();
 
@@ -872,6 +872,29 @@ void AssemblyHelpers::debugCall(VM& vm, V_DebugOperation_EPP function, void* arg
     }
 }
 
+void AssemblyHelpers::copyCalleeSavesToVMEntryFrameCalleeSavesBufferImpl(GPRReg calleeSavesBuffer)
+{
+#if NUMBER_OF_CALLEE_SAVES_REGISTERS > 0
+    addPtr(TrustedImm32(VMEntryFrame::calleeSaveRegistersBufferOffset()), calleeSavesBuffer);
+
+    RegisterAtOffsetList* allCalleeSaves = VM::getAllCalleeSaveRegisterOffsets();
+    RegisterSet dontCopyRegisters = RegisterSet::stackRegisters();
+    unsigned registerCount = allCalleeSaves->size();
+    
+    for (unsigned i = 0; i < registerCount; i++) {
+        RegisterAtOffset entry = allCalleeSaves->at(i);
+        if (dontCopyRegisters.get(entry.reg()))
+            continue;
+        if (entry.reg().isGPR())
+            storePtr(entry.reg().gpr(), Address(calleeSavesBuffer, entry.offset()));
+        else
+            storeDouble(entry.reg().fpr(), Address(calleeSavesBuffer, entry.offset()));
+    }
+#else
+    UNUSED_PARAM(calleeSavesBuffer);
+#endif
+}
+
 } // namespace JSC
 
 #endif // ENABLE(JIT)
index 9d4a8a5..0385639 100644 (file)
@@ -333,27 +333,23 @@ public:
 #endif
     }
 
+    // If you use this, be aware that vmGPR will get trashed.
+    void copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(GPRReg vmGPR)
+    {
+#if NUMBER_OF_CALLEE_SAVES_REGISTERS > 0
+        loadPtr(Address(vmGPR, VM::topVMEntryFrameOffset()), vmGPR);
+        copyCalleeSavesToVMEntryFrameCalleeSavesBufferImpl(vmGPR);
+#else
+        UNUSED_PARAM(vmGPR);
+#endif
+    }
+
     void copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(VM& vm, const TempRegisterSet& usedRegisters = { RegisterSet::stubUnavailableRegisters() })
     {
 #if NUMBER_OF_CALLEE_SAVES_REGISTERS > 0
         GPRReg temp1 = usedRegisters.getFreeGPR(0);
-
         loadPtr(&vm.topVMEntryFrame, temp1);
-        addPtr(TrustedImm32(VMEntryFrame::calleeSaveRegistersBufferOffset()), temp1);
-
-        RegisterAtOffsetList* allCalleeSaves = vm.getAllCalleeSaveRegisterOffsets();
-        RegisterSet dontCopyRegisters = RegisterSet::stackRegisters();
-        unsigned registerCount = allCalleeSaves->size();
-        
-        for (unsigned i = 0; i < registerCount; i++) {
-            RegisterAtOffset entry = allCalleeSaves->at(i);
-            if (dontCopyRegisters.get(entry.reg()))
-                continue;
-            if (entry.reg().isGPR())
-                storePtr(entry.reg().gpr(), Address(temp1, entry.offset()));
-            else
-                storeDouble(entry.reg().fpr(), Address(temp1, entry.offset()));
-        }
+        copyCalleeSavesToVMEntryFrameCalleeSavesBufferImpl(temp1);
 #else
         UNUSED_PARAM(vm);
         UNUSED_PARAM(usedRegisters);
@@ -376,7 +372,7 @@ public:
         loadPtr(&vm.topVMEntryFrame, temp1);
         addPtr(TrustedImm32(VMEntryFrame::calleeSaveRegistersBufferOffset()), temp1);
 
-        RegisterAtOffsetList* allCalleeSaves = vm.getAllCalleeSaveRegisterOffsets();
+        RegisterAtOffsetList* allCalleeSaves = VM::getAllCalleeSaveRegisterOffsets();
         RegisterAtOffsetList* currentCalleeSaves = codeBlock()->calleeSaveRegisters();
         RegisterSet dontCopyRegisters = RegisterSet::stackRegisters();
         unsigned registerCount = allCalleeSaves->size();
@@ -1591,6 +1587,8 @@ public:
 #endif
 
 protected:
+    void copyCalleeSavesToVMEntryFrameCalleeSavesBufferImpl(GPRReg calleeSavesBuffer);
+
     CodeBlock* m_codeBlock;
     CodeBlock* m_baselineCodeBlock;
 
index b5f490f..a08a622 100644 (file)
 #include "JSArray.h"
 #include "JSBoundFunction.h"
 #include "JSCInlines.h"
-#include "JSWebAssemblyInstance.h"
-#include "JSWebAssemblyRuntimeError.h"
 #include "MathCommon.h"
 #include "MaxFrameExtentForSlowPathCall.h"
 #include "SpecializedThunkJIT.h"
-#include "WasmExceptionType.h"
 #include <wtf/InlineASM.h>
 #include <wtf/StringPrintStream.h>
 #include <wtf/text/StringImpl.h>
@@ -1133,47 +1130,6 @@ MacroAssemblerCodeRef boundThisNoArgsFunctionCallGenerator(VM* vm)
         linkBuffer, ("Specialized thunk for bound function calls with no arguments"));
 }
 
-#if ENABLE(WEBASSEMBLY)
-MacroAssemblerCodeRef throwExceptionFromWasmThunkGenerator(VM* vm)
-{
-    CCallHelpers jit;
-
-    // The thing that jumps here must move ExceptionType into the argumentGPR1 and jump here.
-    // We're allowed to use temp registers here, but not callee saves.
-    {
-        RegisterSet usedRegisters = RegisterSet::stubUnavailableRegisters();
-        usedRegisters.set(GPRInfo::argumentGPR1);
-        jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(*vm, usedRegisters);
-    }
-
-    jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
-    jit.loadWasmContext(GPRInfo::argumentGPR2);
-    CCallHelpers::Call call = jit.call();
-    jit.jumpToExceptionHandler(*vm);
-
-    void (*throwWasmException)(ExecState*, Wasm::ExceptionType, JSWebAssemblyInstance*) = [] (ExecState* exec, Wasm::ExceptionType type, JSWebAssemblyInstance* wasmContext) {
-        VM* vm = &exec->vm();
-        NativeCallFrameTracer tracer(vm, exec);
-
-        {
-            auto throwScope = DECLARE_THROW_SCOPE(*vm);
-            JSGlobalObject* globalObject = wasmContext->globalObject();
-
-            JSWebAssemblyRuntimeError* error = JSWebAssemblyRuntimeError::create(exec, *vm, globalObject->WebAssemblyRuntimeErrorStructure(), Wasm::errorMessageForExceptionType(type));
-            throwException(exec, throwScope, error);
-        }
-
-        genericUnwind(vm, exec);
-        ASSERT(!!vm->callFrameForCatch);
-    };
-
-    LinkBuffer linkBuffer(jit, GLOBAL_THUNK_ID);
-    linkBuffer.link(call, throwWasmException);
-    return FINALIZE_CODE(
-        linkBuffer, ("Throw exception from Wasm"));
-}
-#endif // ENABLE(WEBASSEMBLY)
-
 } // namespace JSC
 
 #endif // ENABLE(JIT)
index 90740c0..1ba9eb8 100644 (file)
@@ -64,10 +64,5 @@ MacroAssemblerCodeRef randomThunkGenerator(VM*);
 MacroAssemblerCodeRef truncThunkGenerator(VM*);
 
 MacroAssemblerCodeRef boundThisNoArgsFunctionCallGenerator(VM*);
-
-#if ENABLE(WEBASSEMBLY)
-MacroAssemblerCodeRef throwExceptionFromWasmThunkGenerator(VM*);
-#endif
-
 }
 #endif // ENABLE(JIT)
index 90eee7a..be6b6f1 100644 (file)
@@ -39,6 +39,7 @@
 #include "Options.h"
 #include "StructureIDTable.h"
 #include "SuperSampler.h"
+#include "WasmThunks.h"
 #include "WriteBarrier.h"
 #include <mutex>
 #include <wtf/MainThread.h>
@@ -70,6 +71,10 @@ void initializeThreading()
         initializeSuperSampler();
         WTFThreadData& threadData = wtfThreadData();
         threadData.setSavedLastStackTop(threadData.stack().origin());
+
+#if ENABLE(WEBASSEMBLY)
+        Wasm::Thunks::initialize();
+#endif
     });
 }
 
index 4af991e..f9ff906 100644 (file)
@@ -283,7 +283,6 @@ VM::VM(VMType vmType, HeapType heapType)
 
 #if ENABLE(JIT)
     jitStubs = std::make_unique<JITThunks>();
-    allCalleeSaveRegisterOffsets = std::make_unique<RegisterAtOffsetList>(RegisterSet::vmCalleeSaveRegisters(), RegisterAtOffsetList::ZeroBased);
 #endif
     arityCheckData = std::make_unique<CommonSlowPaths::ArityCheckData>();
 
@@ -939,4 +938,18 @@ void VM::verifyExceptionCheckNeedIsSatisfied(unsigned recursionDepth, ExceptionE
 }
 #endif
 
+#if ENABLE(JIT)
+RegisterAtOffsetList* VM::getAllCalleeSaveRegisterOffsets()
+{
+    static RegisterAtOffsetList* result;
+
+    static std::once_flag calleeSavesFlag;
+    std::call_once(calleeSavesFlag, [] () {
+        result = new RegisterAtOffsetList(RegisterSet::vmCalleeSaveRegisters(), RegisterAtOffsetList::ZeroBased);
+    });
+
+    return result;
+}
+#endif // ENABLE(JIT)
+
 } // namespace JSC
index f9686a7..b373a18 100644 (file)
@@ -456,9 +456,7 @@ public:
         return jitStubs->ctiStub(this, generator);
     }
     
-    std::unique_ptr<RegisterAtOffsetList> allCalleeSaveRegisterOffsets;
-    
-    RegisterAtOffsetList* getAllCalleeSaveRegisterOffsets() { return allCalleeSaveRegisterOffsets.get(); }
+    static RegisterAtOffsetList* getAllCalleeSaveRegisterOffsets();
 
 #endif // ENABLE(JIT)
     std::unique_ptr<CommonSlowPaths::ArityCheckData> arityCheckData;
@@ -483,6 +481,11 @@ public:
         return OBJECT_OFFSETOF(VM, targetMachinePCForThrow);
     }
 
+    static ptrdiff_t topVMEntryFrameOffset()
+    {
+        return OBJECT_OFFSETOF(VM, topVMEntryFrame);
+    }
+
     void restorePreviousException(Exception* exception) { setException(exception); }
 
     void clearLastException() { m_lastException = nullptr; }
index 6d497b1..7511579 100644 (file)
@@ -57,6 +57,7 @@
 #include "WasmFunctionParser.h"
 #include "WasmMemory.h"
 #include "WasmOpcodeOrigin.h"
+#include "WasmThunks.h"
 #include <wtf/Optional.h>
 
 void dumpProcedure(void* ptr)
@@ -161,7 +162,7 @@ public:
             return fail(__VA_ARGS__);             \
     } while (0)
 
-    B3IRGenerator(VM&, const ModuleInformation&, Procedure&, WasmInternalFunction*, Vector<UnlinkedWasmToWasmCall>&, MemoryMode);
+    B3IRGenerator(const ModuleInformation&, Procedure&, WasmInternalFunction*, Vector<UnlinkedWasmToWasmCall>&, MemoryMode);
 
     PartialResult WARN_UNUSED_RETURN addArguments(const Signature*);
     PartialResult WARN_UNUSED_RETURN addLocal(Type, uint32_t);
@@ -232,7 +233,6 @@ private:
 
     Origin origin();
 
-    VM& m_vm;
     FunctionParser<B3IRGenerator>* m_parser;
     const ModuleInformation& m_info;
     MemoryMode m_mode;
@@ -302,9 +302,8 @@ void B3IRGenerator::restoreWasmContext(Procedure& proc, BasicBlock* block, Value
     });
 }
 
-B3IRGenerator::B3IRGenerator(VM& vm, const ModuleInformation& info, Procedure& procedure, WasmInternalFunction* compilation, Vector<UnlinkedWasmToWasmCall>& unlinkedWasmToWasmCalls, MemoryMode mode)
-    : m_vm(vm)
-    , m_info(info)
+B3IRGenerator::B3IRGenerator(const ModuleInformation& info, Procedure& procedure, WasmInternalFunction* compilation, Vector<UnlinkedWasmToWasmCall>& unlinkedWasmToWasmCalls, MemoryMode mode)
+    : m_info(info)
     , m_mode(mode)
     , m_proc(procedure)
     , m_unlinkedWasmToWasmCalls(unlinkedWasmToWasmCalls)
@@ -376,9 +375,8 @@ void B3IRGenerator::emitExceptionCheck(CCallHelpers& jit, ExceptionType type)
     jit.move(CCallHelpers::TrustedImm32(static_cast<uint32_t>(type)), GPRInfo::argumentGPR1);
     auto jumpToExceptionStub = jit.jump();
 
-    VM* vm = &m_vm;
-    jit.addLinkTask([vm, jumpToExceptionStub] (LinkBuffer& linkBuffer) {
-        linkBuffer.link(jumpToExceptionStub, CodeLocationLabel(vm->getCTIStub(throwExceptionFromWasmThunkGenerator).code()));
+    jit.addLinkTask([jumpToExceptionStub] (LinkBuffer& linkBuffer) {
+        linkBuffer.link(jumpToExceptionStub, CodeLocationLabel(Thunks::singleton().stub(throwExceptionFromWasmThunkGenerator).code()));
     });
 }
 
@@ -443,8 +441,8 @@ auto B3IRGenerator::addUnreachable() -> PartialResult
 
 auto B3IRGenerator::addGrowMemory(ExpressionType delta, ExpressionType& result) -> PartialResult
 {
-    int32_t (*growMemory) (ExecState*, JSWebAssemblyInstance*, int32_t) = [] (ExecState* exec, JSWebAssemblyInstance* wasmContext, int32_t delta) -> int32_t {
-        VM& vm = exec->vm();
+    int32_t (*growMemory) (Context*, int32_t) = [] (Context* wasmContext, int32_t delta) -> int32_t {
+        VM& vm = *wasmContext->vm();
         auto scope = DECLARE_THROW_SCOPE(vm);
 
         JSWebAssemblyMemory* wasmMemory = wasmContext->memory();
@@ -453,7 +451,9 @@ auto B3IRGenerator::addGrowMemory(ExpressionType delta, ExpressionType& result)
             return -1;
 
         bool shouldThrowExceptionsOnFailure = false;
-        PageCount result = wasmMemory->grow(exec, static_cast<uint32_t>(delta), shouldThrowExceptionsOnFailure);
+        // grow() does not require ExecState* if it doesn't throw exceptions.
+        ExecState* exec = nullptr; 
+        PageCount result = wasmMemory->grow(vm, exec, static_cast<uint32_t>(delta), shouldThrowExceptionsOnFailure);
         RELEASE_ASSERT(!scope.exception());
         if (!result)
             return -1;
@@ -463,7 +463,7 @@ auto B3IRGenerator::addGrowMemory(ExpressionType delta, ExpressionType& result)
 
     result = m_currentBlock->appendNew<CCallValue>(m_proc, Int32, origin(),
         m_currentBlock->appendNew<ConstPtrValue>(m_proc, origin(), bitwise_cast<void*>(growMemory)),
-        m_currentBlock->appendNew<B3::Value>(m_proc, B3::FramePointer, origin()), m_instanceValue, delta);
+        m_instanceValue, delta);
 
     restoreWebAssemblyGlobalState(m_info.memory, m_instanceValue, m_proc, m_currentBlock);
 
@@ -1277,7 +1277,7 @@ Expected<std::unique_ptr<WasmInternalFunction>, String> parseAndCompile(VM& vm,
             out.print("Wasm: ", bitwise_cast<OpcodeOrigin>(origin));
     });
 
-    B3IRGenerator context(vm, info, procedure, result.get(), unlinkedWasmToWasmCalls, mode);
+    B3IRGenerator context(info, procedure, result.get(), unlinkedWasmToWasmCalls, mode);
     FunctionParser<B3IRGenerator> parser(&vm, context, functionStart, functionLength, signature, info, moduleSignatureIndicesToUniquedSignatureIndices);
     WASM_FAIL_IF_HELPER_FAILS(parser.parse());
 
index c1c6c22..67bb57d 100644 (file)
@@ -33,6 +33,7 @@
 #include "VM.h"
 #include "WasmExceptionType.h"
 #include "WasmMemory.h"
+#include "WasmThunks.h"
 
 #include <signal.h>
 #include <wtf/Lock.h>
@@ -49,7 +50,7 @@ static struct sigaction oldSigBusHandler;
 static struct sigaction oldSigSegvHandler;
 static bool fastHandlerInstalled { false };
 static StaticLock codeLocationsLock;
-static LazyNeverDestroyed<HashSet<std::tuple<VM*, void*, void*>>> codeLocations; // (vm, start, end)
+static LazyNeverDestroyed<HashSet<std::tuple<void*, void*>>> codeLocations; // (start, end)
 
 static void trapHandler(int signal, siginfo_t* sigInfo, void* ucontext)
 {
@@ -81,14 +82,13 @@ static void trapHandler(int signal, siginfo_t* sigInfo, void* ucontext)
             dataLogLnIf(verbose, "found active fast memory for faulting address");
             LockHolder locker(codeLocationsLock);
             for (auto range : codeLocations.get()) {
-                VM* vm;
                 void* start;
                 void* end;
-                std::tie(vm, start, end) = range;
+                std::tie(start, end) = range;
                 dataLogLnIf(verbose, "function start: ", RawPointer(start), " end: ", RawPointer(end));
                 if (start <= faultingInstruction && faultingInstruction < end) {
                     dataLogLnIf(verbose, "found match");
-                    MacroAssemblerCodeRef exceptionStub = vm->jitStubs->existingCTIStub(throwExceptionFromWasmThunkGenerator);
+                    MacroAssemblerCodeRef exceptionStub = Thunks::singleton().existingStub(throwExceptionFromWasmThunkGenerator);
                     // If for whatever reason we don't have a stub then we should just treat this like a regular crash.
                     if (!exceptionStub)
                         break;
@@ -108,20 +108,20 @@ static void trapHandler(int signal, siginfo_t* sigInfo, void* ucontext)
         sigaction(signal, &oldSigSegvHandler, nullptr);
 }
 
-void registerCode(VM& vm, void* start, void* end)
+void registerCode(void* start, void* end)
 {
     if (!fastMemoryEnabled())
         return;
     LockHolder locker(codeLocationsLock);
-    codeLocations->add(std::make_tuple(&vm, start, end));
+    codeLocations->add(std::make_tuple(start, end));
 }
 
-void unregisterCode(VM& vm, void* start, void* end)
+void unregisterCode(void* start, void* end)
 {
     if (!fastMemoryEnabled())
         return;
     LockHolder locker(codeLocationsLock);
-    codeLocations->remove(std::make_tuple(&vm, start, end));
+    codeLocations->remove(std::make_tuple(start, end));
 }
 
 bool fastMemoryEnabled()
index 6319e01..3812836 100644 (file)
@@ -31,8 +31,8 @@ class VM;
 
 namespace Wasm {
 
-void registerCode(VM&, void* start, void* end);
-void unregisterCode(VM&, void* start, void* end);
+void registerCode(void* start, void* end);
+void unregisterCode(void* start, void* end);
 
 bool fastMemoryEnabled();
 JS_EXPORT_PRIVATE void enableFastMemory();
index 6c25389..1bd2bc2 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "VM.h"
 #include "WasmFaultSignalHandler.h"
+#include "WasmThunks.h"
 
 #include <wtf/HexNumber.h>
 #include <wtf/NeverDestroyed.h>
@@ -131,7 +132,7 @@ inline bool tryGetFastMemory(VM& vm, void*& memory, size_t& mappedCapacity, Memo
         return fail();
 
     // We need to be sure we have a stub prior to running code.
-    if (UNLIKELY(!vm.getCTIStub(throwExceptionFromWasmThunkGenerator).size()))
+    if (UNLIKELY(!Thunks::singleton().stub(throwExceptionFromWasmThunkGenerator)))
         return fail();
 
     ASSERT(allocatedFastMemories <= maxFastMemories);
diff --git a/Source/JavaScriptCore/wasm/WasmThunks.cpp b/Source/JavaScriptCore/wasm/WasmThunks.cpp
new file mode 100644 (file)
index 0000000..3d339dd
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "WasmThunks.h"
+
+#if ENABLE(WEBASSEMBLY)
+
+#include "CCallHelpers.h"
+#include "FrameTracers.h"
+#include "HeapCellInlines.h"
+#include "JITExceptions.h"
+#include "JSWebAssemblyInstance.h"
+#include "JSWebAssemblyRuntimeError.h"
+#include "LinkBuffer.h"
+#include "WasmContext.h"
+#include "WasmExceptionType.h"
+
+namespace JSC { namespace Wasm {
+
+MacroAssemblerCodeRef throwExceptionFromWasmThunkGenerator()
+{
+    CCallHelpers jit;
+
+    // The thing that jumps here must move ExceptionType into the argumentGPR1 before jumping here.
+    // We're allowed to use temp registers here. We are not allowed to use callee saves.
+    jit.loadWasmContext(GPRInfo::argumentGPR2);
+    jit.loadPtr(CCallHelpers::Address(GPRInfo::argumentGPR2, Context::offsetOfVM()), GPRInfo::argumentGPR0);
+    jit.copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(GPRInfo::argumentGPR0);
+    jit.move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
+    CCallHelpers::Call call = jit.call();
+    jit.jump(GPRInfo::returnValueGPR);
+    jit.breakpoint(); // We should not reach this.
+
+    void* (*throwWasmException)(ExecState*, Wasm::ExceptionType, Wasm::Context*) = [] (ExecState* exec, Wasm::ExceptionType type, Wasm::Context* wasmContext) -> void* {
+        VM* vm = wasmContext->vm();
+        NativeCallFrameTracer tracer(vm, exec);
+
+        {
+            auto throwScope = DECLARE_THROW_SCOPE(*vm);
+            JSGlobalObject* globalObject = wasmContext->globalObject();
+
+            JSWebAssemblyRuntimeError* error = JSWebAssemblyRuntimeError::create(
+                exec, *vm, globalObject->WebAssemblyRuntimeErrorStructure(), Wasm::errorMessageForExceptionType(type));
+            throwException(exec, throwScope, error);
+        }
+
+        genericUnwind(vm, exec);
+        ASSERT(!!vm->callFrameForCatch);
+        ASSERT(!!vm->targetMachinePCForThrow);
+        return vm->targetMachinePCForThrow;
+    };
+
+    LinkBuffer linkBuffer(jit, GLOBAL_THUNK_ID);
+    linkBuffer.link(call, throwWasmException);
+    return FINALIZE_CODE(linkBuffer, ("Throw exception from Wasm"));
+}
+
+static Thunks* thunks;
+void Thunks::initialize()
+{
+    thunks = new Thunks;
+}
+
+Thunks& Thunks::singleton()
+{
+    ASSERT(thunks);
+    return *thunks;
+}
+
+MacroAssemblerCodeRef Thunks::stub(ThunkGenerator generator)
+{
+    auto locker = holdLock(m_lock);
+
+    ASSERT(!!generator);
+    auto addResult = m_stubs.add(generator, MacroAssemblerCodeRef());
+    if (addResult.isNewEntry)
+        addResult.iterator->value = generator();
+    return addResult.iterator->value;
+}
+
+MacroAssemblerCodeRef Thunks::existingStub(ThunkGenerator generator)
+{
+    auto locker = holdLock(m_lock);
+
+    auto iter = m_stubs.find(generator);
+    if (iter != m_stubs.end())
+        return iter->value;
+
+    return MacroAssemblerCodeRef();
+}
+
+} } // namespace JSC::Wasm
+
+#endif // ENABLE(WEBASSEMBLY)
diff --git a/Source/JavaScriptCore/wasm/WasmThunks.h b/Source/JavaScriptCore/wasm/WasmThunks.h
new file mode 100644 (file)
index 0000000..65375d6
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEBASSEMBLY)
+
+#include "MacroAssemblerCodeRef.h"
+
+namespace JSC { namespace Wasm {
+
+MacroAssemblerCodeRef throwExceptionFromWasmThunkGenerator();
+
+typedef MacroAssemblerCodeRef (*ThunkGenerator)();
+
+class Thunks {
+public:
+    static void initialize();
+    static Thunks& singleton();
+
+    MacroAssemblerCodeRef stub(ThunkGenerator);
+    MacroAssemblerCodeRef existingStub(ThunkGenerator);
+
+private:
+    Thunks() = default;
+
+    HashMap<ThunkGenerator, MacroAssemblerCodeRef> m_stubs;
+    Lock m_lock;
+};
+
+} } // namespace JSC::Wasm
+
+#endif // ENABLE(WEBASSEMBLY)
index 5171278..74feaf3 100644 (file)
@@ -44,13 +44,13 @@ void JSWebAssemblyCallee::finishCreation(VM& vm, Wasm::Entrypoint&& entrypoint)
     Base::finishCreation(vm);
 
     m_entrypoint = WTFMove(entrypoint);
-    Wasm::registerCode(vm, m_entrypoint.compilation->codeRef().executableMemory()->start(), m_entrypoint.compilation->codeRef().executableMemory()->end());
+    Wasm::registerCode(m_entrypoint.compilation->codeRef().executableMemory()->start(), m_entrypoint.compilation->codeRef().executableMemory()->end());
 }
 
 void JSWebAssemblyCallee::destroy(JSCell* cell)
 {
     JSWebAssemblyCallee* thisObject = static_cast<JSWebAssemblyCallee*>(cell);
-    Wasm::unregisterCode(*cell->vm(), thisObject->m_entrypoint.compilation->codeRef().executableMemory()->start(), thisObject->m_entrypoint.compilation->codeRef().executableMemory()->end());
+    Wasm::unregisterCode(thisObject->m_entrypoint.compilation->codeRef().executableMemory()->start(), thisObject->m_entrypoint.compilation->codeRef().executableMemory()->end());
     thisObject->JSWebAssemblyCallee::~JSWebAssemblyCallee();
 }
 
index e8589f3..30b17b1 100644 (file)
@@ -51,6 +51,7 @@ Structure* JSWebAssemblyInstance::createStructure(VM& vm, JSGlobalObject* global
 
 JSWebAssemblyInstance::JSWebAssemblyInstance(VM& vm, Structure* structure, unsigned numImportFunctions)
     : Base(vm, structure)
+    , m_vm(&vm)
     , m_numImportFunctions(numImportFunctions)
 {
     memset(importFunctions(), 0, m_numImportFunctions * sizeof(WriteBarrier<JSObject>));
index e9f766d..a275465 100644 (file)
@@ -78,6 +78,7 @@ public:
     static ptrdiff_t offsetOfTable() { return OBJECT_OFFSETOF(JSWebAssemblyInstance, m_table); }
     static ptrdiff_t offsetOfCallee() { return OBJECT_OFFSETOF(JSWebAssemblyInstance, m_callee); }
     static ptrdiff_t offsetOfGlobals() { return OBJECT_OFFSETOF(JSWebAssemblyInstance, m_globals); }
+    static ptrdiff_t offsetOfVM() { return OBJECT_OFFSETOF(JSWebAssemblyInstance, m_vm); }
     static size_t offsetOfImportFunctions() { return WTF::roundUpToMultipleOf<sizeof(WriteBarrier<JSCell>)>(sizeof(JSWebAssemblyInstance)); }
     static size_t offsetOfImportFunction(size_t importFunctionNum) { return offsetOfImportFunctions() + importFunctionNum * sizeof(sizeof(WriteBarrier<JSCell>)); }
 
@@ -93,6 +94,7 @@ protected:
     }
 
 private:
+    VM* m_vm;
     WriteBarrier<JSObject>* importFunctions() { return bitwise_cast<WriteBarrier<JSObject>*>(bitwise_cast<char*>(this) + offsetOfImportFunctions()); }
 
     WriteBarrier<JSWebAssemblyModule> m_module;
index bf51b4d..3369c0e 100644 (file)
@@ -73,9 +73,9 @@ JSArrayBuffer* JSWebAssemblyMemory::buffer(VM& vm, JSGlobalObject* globalObject)
     return m_bufferWrapper.get();
 }
 
-Wasm::PageCount JSWebAssemblyMemory::grow(ExecState* exec, uint32_t delta, bool shouldThrowExceptionsOnFailure)
+Wasm::PageCount JSWebAssemblyMemory::grow(VM& vm, ExecState* exec, uint32_t delta, bool shouldThrowExceptionsOnFailure)
 {
-    VM& vm = exec->vm();
+    // Note: We can only use exec if shouldThrowExceptionsOnFailure is true.
     auto throwScope = DECLARE_THROW_SCOPE(vm);
 
     Wasm::PageCount oldPageCount = memory().sizeInPages();
index c5f3ef8..2193699 100644 (file)
@@ -48,7 +48,7 @@ public:
 
     Wasm::Memory& memory() { return m_memory.get(); }
     JSArrayBuffer* buffer(VM& vm, JSGlobalObject*);
-    Wasm::PageCount grow(ExecState*, uint32_t delta, bool shouldThrowExceptionsOnFailure);
+    Wasm::PageCount grow(VM&, ExecState*, uint32_t delta, bool shouldThrowExceptionsOnFailure);
 
     static ptrdiff_t offsetOfMemory() { return OBJECT_OFFSETOF(JSWebAssemblyMemory, m_memoryBase); }
     static ptrdiff_t offsetOfSize() { return OBJECT_OFFSETOF(JSWebAssemblyMemory, m_memorySize); }
index 2284b30..822f63b 100644 (file)
@@ -79,7 +79,7 @@ EncodedJSValue JSC_HOST_CALL webAssemblyMemoryProtoFuncGrow(ExecState* exec)
     RETURN_IF_EXCEPTION(throwScope, { });
 
     bool shouldThrowExceptionsOnFailure = true;
-    Wasm::PageCount result = memory->grow(exec, delta, shouldThrowExceptionsOnFailure);
+    Wasm::PageCount result = memory->grow(vm, exec, delta, shouldThrowExceptionsOnFailure);
     RETURN_IF_EXCEPTION(throwScope, { });
 
     return JSValue::encode(jsNumber(result.pageCount()));