We should have a Wasm callee
authorsbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 4 Dec 2016 21:23:56 +0000 (21:23 +0000)
committersbarati@apple.com <sbarati@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 4 Dec 2016 21:23:56 +0000 (21:23 +0000)
https://bugs.webkit.org/show_bug.cgi?id=165163

Reviewed by Keith Miller.

This patch adds JSWebAssemblyCallee and stores it into the
callee slot in the call frame as part of the prologue of a
wasm function. This is the first step in implementing
unwinding from/through wasm frames. We will use the callee
to identify that a machine frame belongs to wasm code.

* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* jsc.cpp:
(callWasmFunction):
(functionTestWasmModuleFunctions):
* llint/LowLevelInterpreter64.asm:
* runtime/JSGlobalObject.cpp:
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:
* wasm/JSWebAssembly.h:
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::B3IRGenerator):
(JSC::Wasm::parseAndCompile):
* wasm/WasmCallingConvention.h:
(JSC::Wasm::CallingConvention::setupFrameInPrologue):
* wasm/WasmFormat.h:
* wasm/WasmPlan.cpp:
(JSC::Wasm::Plan::initializeCallees):
* wasm/WasmPlan.h:
(JSC::Wasm::Plan::compiledFunction):
(JSC::Wasm::Plan::getCompiledFunctions): Deleted.
* wasm/js/JSWebAssemblyCallee.cpp: Added.
(JSC::JSWebAssemblyCallee::JSWebAssemblyCallee):
(JSC::JSWebAssemblyCallee::finishCreation):
(JSC::JSWebAssemblyCallee::destroy):
* wasm/js/JSWebAssemblyCallee.h: Added.
(JSC::JSWebAssemblyCallee::create):
(JSC::JSWebAssemblyCallee::createStructure):
(JSC::JSWebAssemblyCallee::jsEntryPoint):
* wasm/js/JSWebAssemblyModule.cpp:
(JSC::JSWebAssemblyModule::create):
(JSC::JSWebAssemblyModule::JSWebAssemblyModule):
(JSC::JSWebAssemblyModule::visitChildren):
* wasm/js/JSWebAssemblyModule.h:
(JSC::JSWebAssemblyModule::moduleInformation):
(JSC::JSWebAssemblyModule::callee):
(JSC::JSWebAssemblyModule::callees):
(JSC::JSWebAssemblyModule::offsetOfCallees):
(JSC::JSWebAssemblyModule::allocationSize):
(JSC::JSWebAssemblyModule::compiledFunctions): Deleted.
* wasm/js/WebAssemblyFunction.cpp:
(JSC::callWebAssemblyFunction):
(JSC::WebAssemblyFunction::create):
(JSC::WebAssemblyFunction::visitChildren):
(JSC::WebAssemblyFunction::finishCreation):
* wasm/js/WebAssemblyFunction.h:
(JSC::WebAssemblyFunction::webAssemblyCallee):
(JSC::WebAssemblyFunction::instance):
(JSC::WebAssemblyFunction::signature):
(JSC::CallableWebAssemblyFunction::CallableWebAssemblyFunction): Deleted.
(JSC::WebAssemblyFunction::webAssemblyFunctionCell): Deleted.
* wasm/js/WebAssemblyFunctionCell.cpp:
(JSC::WebAssemblyFunctionCell::create): Deleted.
(JSC::WebAssemblyFunctionCell::WebAssemblyFunctionCell): Deleted.
(JSC::WebAssemblyFunctionCell::destroy): Deleted.
(JSC::WebAssemblyFunctionCell::createStructure): Deleted.
* wasm/js/WebAssemblyFunctionCell.h:
(JSC::WebAssemblyFunctionCell::function): Deleted.
* wasm/js/WebAssemblyModuleConstructor.cpp:
(JSC::constructJSWebAssemblyModule):
* wasm/js/WebAssemblyModuleRecord.cpp:
(JSC::WebAssemblyModuleRecord::link):

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

24 files changed:
Source/JavaScriptCore/CMakeLists.txt
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
Source/JavaScriptCore/jsc.cpp
Source/JavaScriptCore/llint/LowLevelInterpreter64.asm
Source/JavaScriptCore/runtime/JSGlobalObject.cpp
Source/JavaScriptCore/runtime/VM.cpp
Source/JavaScriptCore/runtime/VM.h
Source/JavaScriptCore/wasm/JSWebAssembly.h
Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp
Source/JavaScriptCore/wasm/WasmCallingConvention.h
Source/JavaScriptCore/wasm/WasmFormat.h
Source/JavaScriptCore/wasm/WasmPlan.cpp
Source/JavaScriptCore/wasm/WasmPlan.h
Source/JavaScriptCore/wasm/js/JSWebAssemblyCallee.cpp [new file with mode: 0644]
Source/JavaScriptCore/wasm/js/JSWebAssemblyCallee.h [new file with mode: 0644]
Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.cpp
Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.h
Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp
Source/JavaScriptCore/wasm/js/WebAssemblyFunction.h
Source/JavaScriptCore/wasm/js/WebAssemblyFunctionCell.cpp
Source/JavaScriptCore/wasm/js/WebAssemblyFunctionCell.h
Source/JavaScriptCore/wasm/js/WebAssemblyModuleConstructor.cpp
Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp

index e1c6b76..f8558c1 100644 (file)
@@ -905,6 +905,7 @@ set(JavaScriptCore_SOURCES
     wasm/WasmPlan.cpp
     wasm/WasmValidate.cpp
 
+    wasm/js/JSWebAssemblyCallee.cpp
     wasm/js/JSWebAssemblyCompileError.cpp
     wasm/js/JSWebAssemblyInstance.cpp
     wasm/js/JSWebAssemblyMemory.cpp
@@ -914,7 +915,6 @@ set(JavaScriptCore_SOURCES
     wasm/js/WebAssemblyCompileErrorConstructor.cpp
     wasm/js/WebAssemblyCompileErrorPrototype.cpp
     wasm/js/WebAssemblyFunction.cpp
-    wasm/js/WebAssemblyFunctionCell.cpp
     wasm/js/WebAssemblyInstanceConstructor.cpp
     wasm/js/WebAssemblyInstancePrototype.cpp
     wasm/js/WebAssemblyMemoryConstructor.cpp
index 41a0f83..1fa1da6 100644 (file)
@@ -1,3 +1,80 @@
+2016-12-04  Saam Barati  <sbarati@apple.com>
+
+        We should have a Wasm callee
+        https://bugs.webkit.org/show_bug.cgi?id=165163
+
+        Reviewed by Keith Miller.
+
+        This patch adds JSWebAssemblyCallee and stores it into the
+        callee slot in the call frame as part of the prologue of a
+        wasm function. This is the first step in implementing
+        unwinding from/through wasm frames. We will use the callee
+        to identify that a machine frame belongs to wasm code.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * jsc.cpp:
+        (callWasmFunction):
+        (functionTestWasmModuleFunctions):
+        * llint/LowLevelInterpreter64.asm:
+        * runtime/JSGlobalObject.cpp:
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h:
+        * wasm/JSWebAssembly.h:
+        * wasm/WasmB3IRGenerator.cpp:
+        (JSC::Wasm::B3IRGenerator::B3IRGenerator):
+        (JSC::Wasm::parseAndCompile):
+        * wasm/WasmCallingConvention.h:
+        (JSC::Wasm::CallingConvention::setupFrameInPrologue):
+        * wasm/WasmFormat.h:
+        * wasm/WasmPlan.cpp:
+        (JSC::Wasm::Plan::initializeCallees):
+        * wasm/WasmPlan.h:
+        (JSC::Wasm::Plan::compiledFunction):
+        (JSC::Wasm::Plan::getCompiledFunctions): Deleted.
+        * wasm/js/JSWebAssemblyCallee.cpp: Added.
+        (JSC::JSWebAssemblyCallee::JSWebAssemblyCallee):
+        (JSC::JSWebAssemblyCallee::finishCreation):
+        (JSC::JSWebAssemblyCallee::destroy):
+        * wasm/js/JSWebAssemblyCallee.h: Added.
+        (JSC::JSWebAssemblyCallee::create):
+        (JSC::JSWebAssemblyCallee::createStructure):
+        (JSC::JSWebAssemblyCallee::jsEntryPoint):
+        * wasm/js/JSWebAssemblyModule.cpp:
+        (JSC::JSWebAssemblyModule::create):
+        (JSC::JSWebAssemblyModule::JSWebAssemblyModule):
+        (JSC::JSWebAssemblyModule::visitChildren):
+        * wasm/js/JSWebAssemblyModule.h:
+        (JSC::JSWebAssemblyModule::moduleInformation):
+        (JSC::JSWebAssemblyModule::callee):
+        (JSC::JSWebAssemblyModule::callees):
+        (JSC::JSWebAssemblyModule::offsetOfCallees):
+        (JSC::JSWebAssemblyModule::allocationSize):
+        (JSC::JSWebAssemblyModule::compiledFunctions): Deleted.
+        * wasm/js/WebAssemblyFunction.cpp:
+        (JSC::callWebAssemblyFunction):
+        (JSC::WebAssemblyFunction::create):
+        (JSC::WebAssemblyFunction::visitChildren):
+        (JSC::WebAssemblyFunction::finishCreation):
+        * wasm/js/WebAssemblyFunction.h:
+        (JSC::WebAssemblyFunction::webAssemblyCallee):
+        (JSC::WebAssemblyFunction::instance):
+        (JSC::WebAssemblyFunction::signature):
+        (JSC::CallableWebAssemblyFunction::CallableWebAssemblyFunction): Deleted.
+        (JSC::WebAssemblyFunction::webAssemblyFunctionCell): Deleted.
+        * wasm/js/WebAssemblyFunctionCell.cpp:
+        (JSC::WebAssemblyFunctionCell::create): Deleted.
+        (JSC::WebAssemblyFunctionCell::WebAssemblyFunctionCell): Deleted.
+        (JSC::WebAssemblyFunctionCell::destroy): Deleted.
+        (JSC::WebAssemblyFunctionCell::createStructure): Deleted.
+        * wasm/js/WebAssemblyFunctionCell.h:
+        (JSC::WebAssemblyFunctionCell::function): Deleted.
+        * wasm/js/WebAssemblyModuleConstructor.cpp:
+        (JSC::constructJSWebAssemblyModule):
+        * wasm/js/WebAssemblyModuleRecord.cpp:
+        (JSC::WebAssemblyModuleRecord::link):
+
 2016-12-04  Matt Baker  <mattbaker@apple.com>
 
         Web Inspector: Assertion Failures breakpoint should respect global Breakpoints enabled setting
index 9cb852e..d3fd498 100644 (file)
                79D5CD5A1C1106A900CECA07 /* SamplingProfiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 79D5CD581C1106A900CECA07 /* SamplingProfiler.cpp */; };
                79D5CD5B1C1106A900CECA07 /* SamplingProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 79D5CD591C1106A900CECA07 /* SamplingProfiler.h */; settings = {ATTRIBUTES = (Private, ); }; };
                79DFCBDB1D88C59600527D03 /* HasOwnPropertyCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 79DFCBDA1D88C59600527D03 /* HasOwnPropertyCache.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               79E423E21DEE65320078D355 /* JSWebAssemblyCallee.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 79E423E01DEE65320078D355 /* JSWebAssemblyCallee.cpp */; };
+               79E423E31DEE65320078D355 /* JSWebAssemblyCallee.h in Headers */ = {isa = PBXBuildFile; fileRef = 79E423E11DEE65320078D355 /* JSWebAssemblyCallee.h */; settings = {ATTRIBUTES = (Private, ); }; };
                79EE0BFF1B4AFB85000385C9 /* VariableEnvironment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 79EE0BFD1B4AFB85000385C9 /* VariableEnvironment.cpp */; };
                79EE0C001B4AFB85000385C9 /* VariableEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = 79EE0BFE1B4AFB85000385C9 /* VariableEnvironment.h */; settings = {ATTRIBUTES = (Private, ); }; };
                79F8FC1E1B9FED0F00CA66AB /* DFGMaximalFlushInsertionPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 79F8FC1C1B9FED0F00CA66AB /* DFGMaximalFlushInsertionPhase.cpp */; };
                AD4937C41DDBE6140077C807 /* AbstractModuleRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = AD4937C21DDBE60A0077C807 /* AbstractModuleRecord.h */; settings = {ATTRIBUTES = (Private, ); }; };
                AD4937C71DDD0AAE0077C807 /* WebAssemblyModuleRecord.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD4937C51DDCDCF00077C807 /* WebAssemblyModuleRecord.cpp */; };
                AD4937C81DDD0AAE0077C807 /* WebAssemblyModuleRecord.h in Headers */ = {isa = PBXBuildFile; fileRef = AD4937C61DDCDCF00077C807 /* WebAssemblyModuleRecord.h */; };
-               AD4937D11DDD27DE0077C807 /* WebAssemblyFunctionCell.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD4937CD1DDD27D90077C807 /* WebAssemblyFunctionCell.cpp */; };
-               AD4937D21DDD27DE0077C807 /* WebAssemblyFunctionCell.h in Headers */ = {isa = PBXBuildFile; fileRef = AD4937CE1DDD27D90077C807 /* WebAssemblyFunctionCell.h */; };
                AD4937D31DDD27DE0077C807 /* WebAssemblyFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD4937C91DDD27340077C807 /* WebAssemblyFunction.cpp */; };
                AD4937D41DDD27DE0077C807 /* WebAssemblyFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = AD4937CA1DDD27340077C807 /* WebAssemblyFunction.h */; };
                AD86A93E1AA4D88D002FE77F /* WeakGCMapInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = AD86A93D1AA4D87C002FE77F /* WeakGCMapInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
                79D5CD581C1106A900CECA07 /* SamplingProfiler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SamplingProfiler.cpp; sourceTree = "<group>"; };
                79D5CD591C1106A900CECA07 /* SamplingProfiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SamplingProfiler.h; sourceTree = "<group>"; };
                79DFCBDA1D88C59600527D03 /* HasOwnPropertyCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HasOwnPropertyCache.h; sourceTree = "<group>"; };
+               79E423E01DEE65320078D355 /* JSWebAssemblyCallee.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JSWebAssemblyCallee.cpp; path = js/JSWebAssemblyCallee.cpp; sourceTree = "<group>"; };
+               79E423E11DEE65320078D355 /* JSWebAssemblyCallee.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JSWebAssemblyCallee.h; path = js/JSWebAssemblyCallee.h; sourceTree = "<group>"; };
                79EE0BFD1B4AFB85000385C9 /* VariableEnvironment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VariableEnvironment.cpp; sourceTree = "<group>"; };
                79EE0BFE1B4AFB85000385C9 /* VariableEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VariableEnvironment.h; sourceTree = "<group>"; };
                79F8FC1C1B9FED0F00CA66AB /* DFGMaximalFlushInsertionPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGMaximalFlushInsertionPhase.cpp; path = dfg/DFGMaximalFlushInsertionPhase.cpp; sourceTree = "<group>"; };
                AD4937C61DDCDCF00077C807 /* WebAssemblyModuleRecord.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebAssemblyModuleRecord.h; path = js/WebAssemblyModuleRecord.h; sourceTree = "<group>"; };
                AD4937C91DDD27340077C807 /* WebAssemblyFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebAssemblyFunction.cpp; path = js/WebAssemblyFunction.cpp; sourceTree = "<group>"; };
                AD4937CA1DDD27340077C807 /* WebAssemblyFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebAssemblyFunction.h; path = js/WebAssemblyFunction.h; sourceTree = "<group>"; };
-               AD4937CD1DDD27D90077C807 /* WebAssemblyFunctionCell.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebAssemblyFunctionCell.cpp; path = js/WebAssemblyFunctionCell.cpp; sourceTree = "<group>"; };
-               AD4937CE1DDD27D90077C807 /* WebAssemblyFunctionCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebAssemblyFunctionCell.h; path = js/WebAssemblyFunctionCell.h; sourceTree = "<group>"; };
                AD86A93D1AA4D87C002FE77F /* WeakGCMapInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakGCMapInlines.h; sourceTree = "<group>"; };
                ADDB1F6218D77DB7009B58A8 /* OpaqueRootSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpaqueRootSet.h; sourceTree = "<group>"; };
                B59F89371891AD3300D5CCDC /* UnlinkedInstructionStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnlinkedInstructionStream.h; sourceTree = "<group>"; };
                AD2FCB8A1DB5840000B3E736 /* js */ = {
                        isa = PBXGroup;
                        children = (
-                               AD4937CD1DDD27D90077C807 /* WebAssemblyFunctionCell.cpp */,
-                               AD4937CE1DDD27D90077C807 /* WebAssemblyFunctionCell.h */,
                                AD4937C91DDD27340077C807 /* WebAssemblyFunction.cpp */,
                                AD4937CA1DDD27340077C807 /* WebAssemblyFunction.h */,
                                AD4937C51DDCDCF00077C807 /* WebAssemblyModuleRecord.cpp */,
                                AD4937C61DDCDCF00077C807 /* WebAssemblyModuleRecord.h */,
                                AD2FCC261DB838C400B3E736 /* WebAssemblyPrototype.cpp */,
                                AD2FCC271DB838C400B3E736 /* WebAssemblyPrototype.h */,
+                               79E423E01DEE65320078D355 /* JSWebAssemblyCallee.cpp */,
+                               79E423E11DEE65320078D355 /* JSWebAssemblyCallee.h */,
                                AD2FCBA61DB58DA400B3E736 /* JSWebAssemblyCompileError.cpp */,
                                AD2FCBA71DB58DA400B3E736 /* JSWebAssemblyCompileError.h */,
                                AD2FCBA81DB58DA400B3E736 /* JSWebAssemblyInstance.cpp */,
                                6514F21918B3E1670098FF8B /* Bytecodes.h in Headers */,
                                0F885E111849A3BE00F1E3FA /* BytecodeUseDef.h in Headers */,
                                0F8023EA1613832B00A0BA45 /* ByValInfo.h in Headers */,
+                               79E423E31DEE65320078D355 /* JSWebAssemblyCallee.h in Headers */,
                                65B8392E1BACAD360044E824 /* CachedRecovery.h in Headers */,
                                BC18C3ED0E16F5CD00B34460 /* CallData.h in Headers */,
                                0F64B27A1A7957B2006E4E66 /* CallEdge.h in Headers */,
                                0F7B294D14C3CD4C007C3DB1 /* DFGCommon.h in Headers */,
                                53529A4C1C457B75000B49C6 /* APIUtils.h in Headers */,
                                0FEA0A32170D40BF00BB722C /* DFGCommonData.h in Headers */,
-                               AD4937D21DDD27DE0077C807 /* WebAssemblyFunctionCell.h in Headers */,
                                0F725CB01C506D3B00AD943A /* B3FoldPathConstants.h in Headers */,
                                0F38B01817CFE75500B144D3 /* DFGCompilationKey.h in Headers */,
                                0F9D4C111C3E2C74006CD984 /* FTLPatchpointExceptionHandle.h in Headers */,
                                1482B74E0A43032800517CFC /* JSStringRef.cpp in Sources */,
                                146AAB380B66A94400E55F16 /* JSStringRefCF.cpp in Sources */,
                                0F919D0C157EE09F004A4E7D /* JSSymbolTableObject.cpp in Sources */,
-                               AD4937D11DDD27DE0077C807 /* WebAssemblyFunctionCell.cpp in Sources */,
                                70ECA6051AFDBEA200449739 /* JSTemplateRegistryKey.cpp in Sources */,
                                0F2B66FA17B6B5AB00A7AE3F /* JSTypedArrayConstructors.cpp in Sources */,
                                0F9630391D4192C6005609D9 /* AllocatorAttributes.cpp in Sources */,
                                BCFD8C920EEB2EE700283848 /* JumpTable.cpp in Sources */,
                                0FB5467914F5C46B002C2989 /* LazyOperandValueProfile.cpp in Sources */,
                                148F21B0107EC5410042EC2C /* Lexer.cpp in Sources */,
+                               79E423E21DEE65320078D355 /* JSWebAssemblyCallee.cpp in Sources */,
                                0FF4275715914A20004CB9FF /* LinkBuffer.cpp in Sources */,
                                A7E2EA6C0FB460CF00601F06 /* LiteralParser.cpp in Sources */,
                                A5A1A0951D8CB341004C2EB8 /* DebuggerParseData.cpp in Sources */,
index 88d6358..5f4b950 100644 (file)
@@ -53,6 +53,7 @@
 #include "JSProxy.h"
 #include "JSString.h"
 #include "JSTypedArrays.h"
+#include "JSWebAssemblyCallee.h"
 #include "LLIntData.h"
 #include "LLIntThunks.h"
 #include "ObjectConstructor.h"
@@ -2566,7 +2567,7 @@ static JSValue box(ExecState* exec, VM& vm, JSValue wasmValue)
     return JSValue::decode(bitwise_cast<uint64_t>(result));
 }
 
-static JSValue callWasmFunction(VM* vm, const B3::Compilation& code, Vector<JSValue>& boxedArgs)
+static JSValue callWasmFunction(VM* vm, JSGlobalObject* globalObject, JSWebAssemblyCallee* wasmCallee, Vector<JSValue>& boxedArgs)
 {
     JSValue firstArgument;
     int argCount = 1;
@@ -2579,9 +2580,9 @@ static JSValue callWasmFunction(VM* vm, const B3::Compilation& code, Vector<JSVa
     }
 
     ProtoCallFrame protoCallFrame;
-    protoCallFrame.init(nullptr, nullptr, firstArgument, argCount, remainingArgs);
+    protoCallFrame.init(nullptr, globalObject->globalExec()->jsCallee(), firstArgument, argCount, remainingArgs);
 
-    return JSValue::decode(vmEntryToWasm(code.code().executableAddress(), vm, &protoCallFrame));
+    return JSValue::decode(vmEntryToWasm(wasmCallee->jsEntryPoint(), vm, &protoCallFrame));
 }
 
 // testWasmModule(JSArrayBufferView source, number functionCount, ...[[WasmValue, [WasmValue]]]) where the ith copy of [[result, [args]]] is a list
@@ -2610,10 +2611,18 @@ static EncodedJSValue JSC_HOST_CALL functionTestWasmModuleFunctions(ExecState* e
     if (plan.compiledFunctionCount() != functionCount)
         CRASH();
 
-    for (uint32_t i = 0; i < functionCount; ++i) {
-        if (!plan.compiledFunction(i))
-            dataLogLn("failed to compile function at index", i);
+    MarkedArgumentBuffer callees;
+    {
+        unsigned lastIndex = UINT_MAX;
+        plan.initializeCallees(exec->lexicalGlobalObject(),
+            [&] (unsigned calleeIndex, JSWebAssemblyCallee* callee) {
+                RELEASE_ASSERT(!calleeIndex || (calleeIndex - 1 == lastIndex));
+                callees.append(callee);
+                lastIndex = calleeIndex;
+            });
+    }
 
+    for (uint32_t i = 0; i < functionCount; ++i) {
         JSArray* testCases = jsCast<JSArray*>(exec->argument(i + 2));
         for (unsigned testIndex = 0; testIndex < testCases->length(); ++testIndex) {
             JSArray* test = jsCast<JSArray*>(testCases->getIndexQuickly(testIndex));
@@ -2624,7 +2633,7 @@ static EncodedJSValue JSC_HOST_CALL functionTestWasmModuleFunctions(ExecState* e
             for (unsigned argIndex = 0; argIndex < arguments->length(); ++argIndex)
                 boxedArgs.append(box(exec, vm, arguments->getIndexQuickly(argIndex)));
 
-            JSValue callResult = callWasmFunction(&vm, *plan.compiledFunction(i)->jsEntryPoint, boxedArgs);
+            JSValue callResult = callWasmFunction(&vm, exec->lexicalGlobalObject(), jsCast<JSWebAssemblyCallee*>(callees.at(i)), boxedArgs);
             JSValue expected = box(exec, vm, result);
             if (callResult != expected) {
                 dataLog("Arguments: ");
index 15d8dc2..1d2464b 100644 (file)
@@ -183,6 +183,7 @@ macro doVMEntry(makeCall)
     move 4, t3
 
 .copyHeaderLoop:
+    # Copy the CodeBlock/Callee/ArgumentCount/|this| from protoCallFrame into the callee frame.
     subi 1, t3
     loadq [protoCallFrame, t3, 8], extraTempReg
     storeq extraTempReg, CodeBlock[sp, t3, 8]
index 4b97705..ad5bd81 100644 (file)
 #include "JSWeakMap.h"
 #include "JSWeakSet.h"
 #include "JSWebAssembly.h"
+#include "JSWebAssemblyCallee.h"
 #include "JSWithScope.h"
 #include "LazyClassStructureInlines.h"
 #include "LazyPropertyInlines.h"
index f91e63f..24b01f2 100644 (file)
@@ -230,6 +230,7 @@ VM::VM(VMType vmType, HeapType heapType)
     functionExecutableStructure.set(*this, FunctionExecutable::createStructure(*this, 0, jsNull()));
 #if ENABLE(WEBASSEMBLY)
     webAssemblyExecutableStructure.set(*this, WebAssemblyExecutable::createStructure(*this, 0, jsNull()));
+    webAssemblyCalleeStructure.set(*this, JSWebAssemblyCallee::createStructure(*this, 0, jsNull()));
 #endif
     moduleProgramExecutableStructure.set(*this, ModuleProgramExecutable::createStructure(*this, 0, jsNull()));
     regExpStructure.set(*this, RegExp::createStructure(*this, 0, jsNull()));
@@ -260,7 +261,6 @@ VM::VM(VMType vmType, HeapType heapType)
     functionCodeBlockStructure.set(*this, FunctionCodeBlock::createStructure(*this, 0, jsNull()));
 #if ENABLE(WEBASSEMBLY)
     webAssemblyCodeBlockStructure.set(*this, WebAssemblyCodeBlock::createStructure(*this, 0, jsNull()));
-    webAssemblyFunctionCellStructure.set(*this, WebAssemblyFunctionCell::createStructure(*this, 0, jsNull()));
 #endif
     hashMapBucketSetStructure.set(*this, HashMapBucket<HashMapBucketDataKey>::createStructure(*this, 0, jsNull()));
     hashMapBucketMapStructure.set(*this, HashMapBucket<HashMapBucketDataKeyValue>::createStructure(*this, 0, jsNull()));
index af3614b..dd5d7ff 100644 (file)
@@ -310,7 +310,7 @@ public:
     Strong<Structure> functionExecutableStructure;
 #if ENABLE(WEBASSEMBLY)
     Strong<Structure> webAssemblyExecutableStructure;
-    Strong<Structure> webAssemblyFunctionCellStructure;
+    Strong<Structure> webAssemblyCalleeStructure;
 #endif
     Strong<Structure> moduleProgramExecutableStructure;
     Strong<Structure> regExpStructure;
index dba5a75..4bca1f3 100644 (file)
@@ -28,6 +28,7 @@
 #if ENABLE(WEBASSEMBLY)
 
 #include "JSObject.h"
+#include "js/JSWebAssemblyCallee.h"
 #include "js/JSWebAssemblyCompileError.h"
 #include "js/JSWebAssemblyInstance.h"
 #include "js/JSWebAssemblyMemory.h"
@@ -37,7 +38,6 @@
 #include "js/WebAssemblyCompileErrorConstructor.h"
 #include "js/WebAssemblyCompileErrorPrototype.h"
 #include "js/WebAssemblyFunction.h"
-#include "js/WebAssemblyFunctionCell.h"
 #include "js/WebAssemblyInstanceConstructor.h"
 #include "js/WebAssemblyInstancePrototype.h"
 #include "js/WebAssemblyMemoryConstructor.h"
index d40693d..de89c8c 100644 (file)
@@ -129,7 +129,7 @@ public:
 
     static constexpr ExpressionType emptyExpression = nullptr;
 
-    B3IRGenerator(Memory*, Procedure&, Vector<UnlinkedCall>& unlinkedCalls);
+    B3IRGenerator(Memory*, Procedure&, FunctionCompilation*);
 
     bool WARN_UNUSED_RETURN addArguments(const Vector<Type>&);
     bool WARN_UNUSED_RETURN addLocal(Type, uint32_t);
@@ -189,10 +189,10 @@ private:
     Value* m_zeroValues[numTypes];
 };
 
-B3IRGenerator::B3IRGenerator(Memory* memory, Procedure& procedure, Vector<UnlinkedCall>& unlinkedCalls)
+B3IRGenerator::B3IRGenerator(Memory* memory, Procedure& procedure, FunctionCompilation* compilation)
     : m_memory(memory)
     , m_proc(procedure)
-    , m_unlinkedCalls(unlinkedCalls)
+    , m_unlinkedCalls(compilation->unlinkedCalls)
 {
     m_currentBlock = m_proc.addBlock();
 
@@ -224,6 +224,8 @@ B3IRGenerator::B3IRGenerator(Memory* memory, Procedure& procedure, Vector<Unlink
             jit.breakpoint();
         });
     }
+
+    wasmCallingConvention().setupFrameInPrologue(compilation, m_proc, Origin(), m_currentBlock);
 }
 
 Value* B3IRGenerator::zeroForType(Type type)
@@ -741,7 +743,7 @@ std::unique_ptr<FunctionCompilation> parseAndCompile(VM& vm, const uint8_t* func
     auto result = std::make_unique<FunctionCompilation>();
 
     Procedure procedure;
-    B3IRGenerator context(memory, procedure, result->unlinkedCalls);
+    B3IRGenerator context(memory, procedure, result.get());
     FunctionParser<B3IRGenerator> parser(context, functionStart, functionLength, signature, functions);
     if (!parser.parse())
         RELEASE_ASSERT_NOT_REACHED();
index 950e31a..5c2a512 100644 (file)
@@ -83,6 +83,40 @@ private:
     }
 
 public:
+    void setupFrameInPrologue(FunctionCompilation* compilation, B3::Procedure& proc, B3::Origin origin, B3::BasicBlock* block) const
+    {
+        static_assert(CallFrameSlot::callee * sizeof(Register) < headerSize, "We rely on this here for now.");
+        static_assert(CallFrameSlot::codeBlock * sizeof(Register) < headerSize, "We rely on this here for now.");
+
+        B3::PatchpointValue* getCalleePatchpoint = block->appendNew<B3::PatchpointValue>(proc, B3::Int64, origin);
+        getCalleePatchpoint->resultConstraint = B3::ValueRep::SomeRegister;
+        getCalleePatchpoint->effects = B3::Effects::none();
+        getCalleePatchpoint->setGenerator(
+            [=] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) {
+                GPRReg result = params[0].gpr();
+                MacroAssembler::DataLabelPtr moveLocation = jit.moveWithPatch(MacroAssembler::TrustedImmPtr(nullptr), result);
+                jit.addLinkTask([=] (LinkBuffer& linkBuffer) {
+                    compilation->calleeMoveLocation = linkBuffer.locationOf(moveLocation);
+                });
+            });
+
+        B3::Value* framePointer = block->appendNew<B3::Value>(proc, B3::FramePointer, origin);
+        B3::Value* offsetOfCallee = block->appendNew<B3::Const64Value>(proc, origin, CallFrameSlot::callee * sizeof(Register));
+        block->appendNew<B3::MemoryValue>(proc, B3::Store, origin,
+            getCalleePatchpoint,
+            block->appendNew<B3::Value>(proc, B3::Add, origin, framePointer, offsetOfCallee));
+
+        // FIXME: We shouldn't have to store zero into the CodeBlock* spot in the call frame,
+        // but there are places that interpret non-null CodeBlock slot to mean a valid CodeBlock.
+        // When doing unwinding, we'll need to verify that the entire runtime is OK with a non-null
+        // CodeBlock not implying that the CodeBlock is valid.
+        // https://bugs.webkit.org/show_bug.cgi?id=165321
+        B3::Value* offsetOfCodeBlock = block->appendNew<B3::Const64Value>(proc, origin, CallFrameSlot::codeBlock * sizeof(Register));
+        block->appendNew<B3::MemoryValue>(proc, B3::Store, origin,
+            block->appendNew<B3::Const64Value>(proc, origin, 0),
+            block->appendNew<B3::Value>(proc, B3::Add, origin, framePointer, offsetOfCodeBlock));
+    }
+
     template<typename Functor>
     void loadArguments(const Vector<Type>& argumentTypes, B3::Procedure& proc, B3::BasicBlock* block, B3::Origin origin, const Functor& functor) const
     {
index 274fe7d..c8bd180 100644 (file)
@@ -135,6 +135,7 @@ struct UnlinkedCall {
 
 struct FunctionCompilation {
     Vector<UnlinkedCall> unlinkedCalls;
+    CodeLocationDataLabelPtr calleeMoveLocation;
     std::unique_ptr<B3::Compilation> code;
     std::unique_ptr<B3::Compilation> jsEntryPoint;
 };
index 1e8ea4a..0b07ca3 100644 (file)
@@ -29,6 +29,9 @@
 #if ENABLE(WEBASSEMBLY)
 
 #include "B3Compilation.h"
+#include "JSCInlines.h"
+#include "JSGlobalObject.h"
+#include "JSWebAssemblyCallee.h"
 #include "WasmB3IRGenerator.h"
 #include "WasmCallingConvention.h"
 #include "WasmMemory.h"
@@ -110,6 +113,23 @@ void Plan::run()
     m_failed = false;
 }
 
+void Plan::initializeCallees(JSGlobalObject* globalObject, std::function<void(unsigned, JSWebAssemblyCallee*)> callback)
+{
+    ASSERT(!failed());
+    for (unsigned i = 0; i < m_compiledFunctions.size(); i++) {
+        std::unique_ptr<FunctionCompilation>& compilation = m_compiledFunctions[i];
+        CodeLocationDataLabelPtr calleeMoveLocation = compilation->calleeMoveLocation;
+        JSWebAssemblyCallee* callee = JSWebAssemblyCallee::create(globalObject->vm(), WTFMove(compilation));
+
+        MacroAssembler::repatchPointer(calleeMoveLocation, callee);
+
+        if (verbose)
+            dataLogLn("Made Wasm callee: ", RawPointer(callee));
+
+        callback(i, callee);
+    }
+}
+
 Plan::~Plan() { }
 
 } } // namespace JSC::Wasm
index c5de199..63b49cc 100644 (file)
 #include <wtf/ThreadSafeRefCounted.h>
 #include <wtf/Vector.h>
 
-namespace JSC { namespace Wasm {
+namespace JSC {
+
+class JSGlobalObject;
+class JSWebAssemblyCallee;
+
+namespace Wasm {
+
 class Memory;
 
 class Plan {
@@ -44,6 +50,8 @@ public:
 
     JS_EXPORT_PRIVATE void run();
 
+    JS_EXPORT_PRIVATE void initializeCallees(JSGlobalObject*, std::function<void(unsigned, JSWebAssemblyCallee*)>);
+
     bool WARN_UNUSED_RETURN failed() const { return m_failed; }
     const String& errorMessage() const
     {
@@ -71,11 +79,6 @@ public:
         RELEASE_ASSERT(!failed());
         return m_compiledFunctions.at(i).get();
     }
-    CompiledFunctions& getCompiledFunctions()
-    {
-        RELEASE_ASSERT(!failed());
-        return m_compiledFunctions;
-    }
 
 private:
     std::unique_ptr<ModuleInformation> m_moduleInformation;
diff --git a/Source/JavaScriptCore/wasm/js/JSWebAssemblyCallee.cpp b/Source/JavaScriptCore/wasm/js/JSWebAssemblyCallee.cpp
new file mode 100644 (file)
index 0000000..497ae88
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2016 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 "JSWebAssemblyCallee.h"
+
+#if ENABLE(WEBASSEMBLY)
+
+#include "JSCInlines.h"
+
+namespace JSC {
+
+const ClassInfo JSWebAssemblyCallee::s_info = { "WebAssemblyCallee", nullptr, 0, CREATE_METHOD_TABLE(JSWebAssemblyCallee) };
+
+JSWebAssemblyCallee::JSWebAssemblyCallee(VM& vm)
+    : Base(vm, vm.webAssemblyCalleeStructure.get())
+{ }
+
+void JSWebAssemblyCallee::finishCreation(VM& vm, std::unique_ptr<Wasm::FunctionCompilation>&& compilation)
+{
+    Base::finishCreation(vm);
+
+    m_code = WTFMove(compilation->code);
+    m_jsEntryPoint = WTFMove(compilation->jsEntryPoint);
+}
+
+void JSWebAssemblyCallee::destroy(JSCell* cell)
+{
+    JSWebAssemblyCallee* thisObject = jsCast<JSWebAssemblyCallee*>(cell);
+    thisObject->JSWebAssemblyCallee::~JSWebAssemblyCallee();
+}
+
+} // namespace JSC
+
+#endif // ENABLE(WEBASSEMBLY)
diff --git a/Source/JavaScriptCore/wasm/js/JSWebAssemblyCallee.h b/Source/JavaScriptCore/wasm/js/JSWebAssemblyCallee.h
new file mode 100644 (file)
index 0000000..8b3bad4
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2016 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 "JSCallee.h"
+#include "WasmFormat.h"
+
+namespace JSC {
+
+class JSWebAssemblyCallee : public JSCell {
+public:
+    typedef JSCell Base;
+    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
+
+    static JSWebAssemblyCallee* create(VM& vm, std::unique_ptr<Wasm::FunctionCompilation>&& compilation)
+    {
+        JSWebAssemblyCallee* callee = new (NotNull, allocateCell<JSWebAssemblyCallee>(vm.heap)) JSWebAssemblyCallee(vm);
+        callee->finishCreation(vm, WTFMove(compilation));
+        return callee;
+    }
+
+    static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) 
+    {
+        return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
+    }
+
+    DECLARE_EXPORT_INFO;
+    static const bool needsDestruction = true;
+    static void destroy(JSCell*);
+
+    void* jsEntryPoint() { return m_jsEntryPoint->code().executableAddress(); }
+
+private:
+    void finishCreation(VM&, std::unique_ptr<Wasm::FunctionCompilation>&&);
+    JSWebAssemblyCallee(VM&);
+
+    std::unique_ptr<B3::Compilation> m_code;
+    std::unique_ptr<B3::Compilation> m_jsEntryPoint;
+};
+
+} // namespace JSC
+
+#endif // ENABLE(WEBASSEMBLY)
index 88feb98..08849ff 100644 (file)
 #if ENABLE(WEBASSEMBLY)
 
 #include "JSCInlines.h"
+#include "JSWebAssemblyCallee.h"
 #include "WasmFormat.h"
 #include "WasmMemory.h"
 #include <wtf/StdLibExtras.h>
 
 namespace JSC {
 
-JSWebAssemblyModule* JSWebAssemblyModule::create(VM& vm, Structure* structure, std::unique_ptr<Wasm::ModuleInformation>& moduleInformation, Wasm::CompiledFunctions& compiledFunctions, SymbolTable* exportSymbolTable)
+const ClassInfo JSWebAssemblyModule::s_info = { "WebAssembly.Module", &Base::s_info, nullptr, CREATE_METHOD_TABLE(JSWebAssemblyModule) };
+
+JSWebAssemblyModule* JSWebAssemblyModule::create(VM& vm, Structure* structure, std::unique_ptr<Wasm::ModuleInformation>& moduleInformation,
+    SymbolTable* exportSymbolTable, unsigned calleeCount)
 {
-    auto* instance = new (NotNull, allocateCell<JSWebAssemblyModule>(vm.heap)) JSWebAssemblyModule(vm, structure, moduleInformation, compiledFunctions);
+    auto* instance = new (NotNull, allocateCell<JSWebAssemblyModule>(vm.heap, allocationSize(calleeCount))) JSWebAssemblyModule(vm, structure, moduleInformation, calleeCount);
     instance->finishCreation(vm, exportSymbolTable);
     return instance;
 }
@@ -47,11 +51,12 @@ Structure* JSWebAssemblyModule::createStructure(VM& vm, JSGlobalObject* globalOb
     return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
 }
 
-JSWebAssemblyModule::JSWebAssemblyModule(VM& vm, Structure* structure, std::unique_ptr<Wasm::ModuleInformation>& moduleInformation, Wasm::CompiledFunctions& compiledFunctions)
+JSWebAssemblyModule::JSWebAssemblyModule(VM& vm, Structure* structure, std::unique_ptr<Wasm::ModuleInformation>& moduleInformation, unsigned calleeCount)
     : Base(vm, structure)
     , m_moduleInformation(WTFMove(moduleInformation))
-    , m_compiledFunctions(WTFMove(compiledFunctions))
+    , m_calleeCount(calleeCount)
 {
+    memset(callees(), 0, m_calleeCount * sizeof(WriteBarrier<JSWebAssemblyCallee>));
 }
 
 void JSWebAssemblyModule::finishCreation(VM& vm, SymbolTable* exportSymbolTable)
@@ -73,10 +78,12 @@ void JSWebAssemblyModule::visitChildren(JSCell* cell, SlotVisitor& visitor)
 
     Base::visitChildren(thisObject, visitor);
     visitor.append(&thisObject->m_exportSymbolTable);
+    for (unsigned i = 0; i < thisObject->m_calleeCount; i++) {
+        WriteBarrier<JSWebAssemblyCallee>* callee = &thisObject->callees()[i];
+        visitor.append(callee);
+    }
 }
 
-const ClassInfo JSWebAssemblyModule::s_info = { "WebAssembly.Module", &Base::s_info, 0, CREATE_METHOD_TABLE(JSWebAssemblyModule) };
-
 } // namespace JSC
 
 #endif // ENABLE(WEBASSEMBLY)
index 3134673..1aab233 100644 (file)
 
 namespace JSC {
 
+class JSWebAssemblyCallee;
 class SymbolTable;
 
 class JSWebAssemblyModule : public JSDestructibleObject {
 public:
     typedef JSDestructibleObject Base;
 
-    static JSWebAssemblyModule* create(VM&, Structure*, std::unique_ptr<Wasm::ModuleInformation>&, Wasm::CompiledFunctions&, SymbolTable*);
+    static JSWebAssemblyModule* create(VM&, Structure*, std::unique_ptr<Wasm::ModuleInformation>&, SymbolTable* exports, unsigned calleeCount);
     static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
 
     DECLARE_INFO;
 
     const Wasm::ModuleInformation& moduleInformation() const { return *m_moduleInformation.get(); }
-    const Wasm::CompiledFunctions& compiledFunctions() const { return m_compiledFunctions; }
     SymbolTable* exportSymbolTable() const { return m_exportSymbolTable.get(); }
 
+    JSWebAssemblyCallee* callee(unsigned calleeIndex)
+    {
+        RELEASE_ASSERT(calleeIndex < m_calleeCount);
+        return callees()[calleeIndex].get();
+    }
+
+    WriteBarrier<JSWebAssemblyCallee>* callees()
+    {
+        return bitwise_cast<WriteBarrier<JSWebAssemblyCallee>*>(bitwise_cast<char*>(this) + offsetOfCallees());
+    }
+
 protected:
-    JSWebAssemblyModule(VM&, Structure*, std::unique_ptr<Wasm::ModuleInformation>&, Wasm::CompiledFunctions&);
+    JSWebAssemblyModule(VM&, Structure*, std::unique_ptr<Wasm::ModuleInformation>&, unsigned calleeCount);
     void finishCreation(VM&, SymbolTable*);
     static void destroy(JSCell*);
     static void visitChildren(JSCell*, SlotVisitor&);
+
 private:
+    static size_t offsetOfCallees()
+    {
+        return WTF::roundUpToMultipleOf<sizeof(WriteBarrier<JSWebAssemblyCallee>)>(sizeof(JSWebAssemblyModule));
+    }
+
+    static size_t allocationSize(unsigned numCallees)
+    {
+        return offsetOfCallees() + sizeof(WriteBarrier<JSWebAssemblyCallee>) * numCallees;
+    }
+
     std::unique_ptr<Wasm::ModuleInformation> m_moduleInformation;
-    Wasm::CompiledFunctions m_compiledFunctions;
     WriteBarrier<SymbolTable> m_exportSymbolTable;
+    unsigned m_calleeCount;
 };
 
 } // namespace JSC
index c314487..d682e5d 100644 (file)
 #include "JSCInlines.h"
 #include "JSFunctionInlines.h"
 #include "JSObject.h"
+#include "JSWebAssemblyCallee.h"
 #include "JSWebAssemblyInstance.h"
 #include "LLIntThunks.h"
 #include "ProtoCallFrame.h"
 #include "VM.h"
 #include "WasmFormat.h"
-#include "WebAssemblyFunctionCell.h"
 
 namespace JSC {
 
@@ -45,14 +45,12 @@ const ClassInfo WebAssemblyFunction::s_info = { "WebAssemblyFunction", &Base::s_
 
 static EncodedJSValue JSC_HOST_CALL callWebAssemblyFunction(ExecState* exec)
 {
-    auto& vm = exec->vm();
+    VM& vm = exec->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
-    WebAssemblyFunction* callee = jsDynamicCast<WebAssemblyFunction*>(exec->jsCallee());
-    if (!callee)
+    WebAssemblyFunction* wasmFunction = jsDynamicCast<WebAssemblyFunction*>(exec->jsCallee());
+    if (!wasmFunction)
         return JSValue::encode(throwException(exec, scope, createTypeError(exec, "expected a WebAssembly function", defaultSourceAppender, runtimeTypeForValue(exec->jsCallee()))));
-    const CallableWebAssemblyFunction& callable = callee->webAssemblyFunctionCell()->function();
-    const B3::Compilation* jsEntryPoint = callable.jsEntryPoint;
-    const Wasm::Signature* signature = callable.signature;
+    const Wasm::Signature* signature = wasmFunction->signature();
 
     // FIXME is this the right behavior? https://bugs.webkit.org/show_bug.cgi?id=164876
     if (exec->argumentCount() != signature->arguments.size())
@@ -92,10 +90,14 @@ static EncodedJSValue JSC_HOST_CALL callWebAssemblyFunction(ExecState* exec)
         argCount = boxedArgs.size();
     }
 
+    // Note: we specifically use the WebAsseblyFunction as the callee to begin with in the ProtoCallFrame.
+    // The reason for this is that calling into the llint may stack overflow, and the stack overflow
+    // handler might read the global object from the callee. The JSWebAssemblyCallee doesn't have a
+    // global object, but the WebAssemblyFunction does.
     ProtoCallFrame protoCallFrame;
-    protoCallFrame.init(nullptr, callee, firstArgument, argCount, remainingArgs);
+    protoCallFrame.init(nullptr, wasmFunction, firstArgument, argCount, remainingArgs);
     
-    EncodedJSValue rawResult = vmEntryToWasm(jsEntryPoint->code().executableAddress(), &vm, &protoCallFrame);
+    EncodedJSValue rawResult = vmEntryToWasm(wasmFunction->webAssemblyCallee()->jsEntryPoint(), &vm, &protoCallFrame);
     // FIXME is this correct? https://bugs.webkit.org/show_bug.cgi?id=164876
     switch (signature->returnType) {
     case Wasm::Void:
@@ -116,13 +118,12 @@ static EncodedJSValue JSC_HOST_CALL callWebAssemblyFunction(ExecState* exec)
     return EncodedJSValue();
 }
 
-WebAssemblyFunction* WebAssemblyFunction::create(VM& vm, JSGlobalObject* globalObject, int length, const String& name, JSWebAssemblyInstance* instance, CallableWebAssemblyFunction&& callable)
+WebAssemblyFunction* WebAssemblyFunction::create(VM& vm, JSGlobalObject* globalObject, unsigned length, const String& name, JSWebAssemblyInstance* instance, JSWebAssemblyCallee* callee, Wasm::Signature* signature)
 {
     NativeExecutable* executable = vm.getHostFunction(callWebAssemblyFunction, NoIntrinsic, callHostFunctionAsConstructor, nullptr, name);
-    WebAssemblyFunctionCell* functionCell = WebAssemblyFunctionCell::create(vm, WTFMove(callable));
     Structure* structure = globalObject->webAssemblyFunctionStructure();
     WebAssemblyFunction* function = new (NotNull, allocateCell<WebAssemblyFunction>(vm.heap)) WebAssemblyFunction(vm, globalObject, structure);
-    function->finishCreation(vm, executable, length, name, instance, functionCell);
+    function->finishCreation(vm, executable, length, name, instance, callee, signature);
     return function;
 }
 
@@ -143,15 +144,16 @@ void WebAssemblyFunction::visitChildren(JSCell* cell, SlotVisitor& visitor)
     ASSERT_GC_OBJECT_INHERITS(thisObject, info());
     Base::visitChildren(thisObject, visitor);
     visitor.append(&thisObject->m_instance);
-    visitor.append(&thisObject->m_functionCell);
+    visitor.append(&thisObject->m_wasmCallee);
 }
 
-void WebAssemblyFunction::finishCreation(VM& vm, NativeExecutable* executable, int length, const String& name, JSWebAssemblyInstance* instance, WebAssemblyFunctionCell* functionCell)
+void WebAssemblyFunction::finishCreation(VM& vm, NativeExecutable* executable, unsigned length, const String& name, JSWebAssemblyInstance* instance, JSWebAssemblyCallee* wasmCallee, Wasm::Signature* signature)
 {
     Base::finishCreation(vm, executable, length, name);
     ASSERT(inherits(info()));
     m_instance.set(vm, this, instance);
-    m_functionCell.set(vm, this, functionCell);
+    m_wasmCallee.set(vm, this, wasmCallee);
+    m_signature = signature;
 }
 
 } // namespace JSC
index 9c0eda6..0cb79db 100644 (file)
@@ -33,7 +33,7 @@
 namespace JSC {
 
 class JSGlobalObject;
-class WebAssemblyFunctionCell;
+class JSWebAssemblyCallee;
 class WebAssemblyInstance;
 
 namespace B3 {
@@ -44,22 +44,6 @@ namespace Wasm {
 struct Signature;
 }
 
-class CallableWebAssemblyFunction {
-    WTF_MAKE_NONCOPYABLE(CallableWebAssemblyFunction);
-    CallableWebAssemblyFunction() = delete;
-
-public:
-    CallableWebAssemblyFunction(CallableWebAssemblyFunction&&) = default;
-
-    const B3::Compilation* jsEntryPoint;
-    const Wasm::Signature* signature;
-    CallableWebAssemblyFunction(const B3::Compilation* jsEntryPoint, const Wasm::Signature* signature)
-        : jsEntryPoint(jsEntryPoint)
-        , signature(signature)
-    {
-    }
-};
-
 class WebAssemblyFunction : public JSFunction {
 public:
     typedef JSFunction Base;
@@ -68,21 +52,28 @@ public:
 
     DECLARE_EXPORT_INFO;
 
-    JS_EXPORT_PRIVATE static WebAssemblyFunction* create(VM&, JSGlobalObject*, int, const String&, JSWebAssemblyInstance*, CallableWebAssemblyFunction&&);
+    JS_EXPORT_PRIVATE static WebAssemblyFunction* create(VM&, JSGlobalObject*, unsigned, const String&, JSWebAssemblyInstance*, JSWebAssemblyCallee*, Wasm::Signature*);
     static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
 
-    const WebAssemblyFunctionCell* webAssemblyFunctionCell() const { return m_functionCell.get(); }
+    JSWebAssemblyCallee* webAssemblyCallee() const { return m_wasmCallee.get(); }
+    const JSWebAssemblyInstance* instance() const { return m_instance.get(); }
+    const Wasm::Signature* signature()
+    { 
+        ASSERT(m_signature);
+        return m_signature;
+    }
 
 protected:
     static void visitChildren(JSCell*, SlotVisitor&);
 
-    void finishCreation(VM&, NativeExecutable*, int length, const String& name, JSWebAssemblyInstance*, WebAssemblyFunctionCell*);
+    void finishCreation(VM&, NativeExecutable*, unsigned length, const String& name, JSWebAssemblyInstance*, JSWebAssemblyCallee*, Wasm::Signature*);
 
 private:
     WebAssemblyFunction(VM&, JSGlobalObject*, Structure*);
 
     WriteBarrier<JSWebAssemblyInstance> m_instance;
-    WriteBarrier<WebAssemblyFunctionCell> m_functionCell;
+    WriteBarrier<JSWebAssemblyCallee> m_wasmCallee;
+    Wasm::Signature* m_signature;
 };
 
 } // namespace JSC
index 3d27115..e69de29 100644 (file)
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2016 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 "WebAssemblyFunctionCell.h"
-
-#if ENABLE(WEBASSEMBLY)
-
-#include "JSCInlines.h"
-
-namespace JSC {
-
-const ClassInfo WebAssemblyFunctionCell::s_info = { "WebAssemblyFunctionCell", nullptr, nullptr, CREATE_METHOD_TABLE(WebAssemblyFunctionCell) };
-
-WebAssemblyFunctionCell* WebAssemblyFunctionCell::create(VM& vm, CallableWebAssemblyFunction&& callable)
-{
-    WebAssemblyFunctionCell* nativeFunction = new (NotNull, allocateCell<WebAssemblyFunctionCell>(vm.heap)) WebAssemblyFunctionCell(vm, WTFMove(callable));
-    nativeFunction->finishCreation(vm);
-    return nativeFunction;
-}
-
-WebAssemblyFunctionCell::WebAssemblyFunctionCell(VM& vm, CallableWebAssemblyFunction&& callable)
-    : Base(vm, vm.webAssemblyFunctionCellStructure.get())
-    , m_function(WTFMove(callable))
-{
-}
-
-void WebAssemblyFunctionCell::destroy(JSCell* cell)
-{
-    WebAssemblyFunctionCell* nativeFunction = static_cast<WebAssemblyFunctionCell*>(cell);
-    nativeFunction->WebAssemblyFunctionCell::~WebAssemblyFunctionCell();
-}
-
-Structure* WebAssemblyFunctionCell::createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
-{
-    return Structure::create(vm, globalObject, prototype, TypeInfo(CellType, StructureFlags), info());
-}
-
-}
-
-#endif // ENABLE(WEBASSEMBLY)
index f177425..e69de29 100644 (file)
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2016 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 "JSCell.h"
-#include "WebAssemblyFunction.h"
-
-namespace JSC {
-
-class WebAssemblyFunctionCell : public JSCell {
-public:
-    typedef JSCell Base;
-    static const unsigned StructureFlags = Base::StructureFlags | StructureIsImmortal;
-    static const bool needsDestruction = true;
-
-    static WebAssemblyFunctionCell* create(VM&, CallableWebAssemblyFunction&&);
-    static void destroy(JSCell*);
-    static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
-
-    DECLARE_INFO;
-
-    const CallableWebAssemblyFunction& function() const { return m_function; }
-
-private:
-    WebAssemblyFunctionCell(VM&, CallableWebAssemblyFunction&&);
-
-    CallableWebAssemblyFunction m_function;
-};
-
-} // namespace JSC
-
-#endif // ENABLE(WEBASSEMBLY)
index a34c863..e8aae13 100644 (file)
@@ -33,6 +33,7 @@
 #include "JSArrayBuffer.h"
 #include "JSCInlines.h"
 #include "JSTypedArrays.h"
+#include "JSWebAssemblyCallee.h"
 #include "JSWebAssemblyCompileError.h"
 #include "JSWebAssemblyModule.h"
 #include "SymbolTable.h"
@@ -53,7 +54,7 @@ const ClassInfo WebAssemblyModuleConstructor::s_info = { "Function", &Base::s_in
 
 static EncodedJSValue JSC_HOST_CALL constructJSWebAssemblyModule(ExecState* state)
 {
-    auto& vm = state->vm();
+    VM& vm = state->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
     JSValue val = state->argument(0);
 
@@ -87,7 +88,13 @@ static EncodedJSValue JSC_HOST_CALL constructJSWebAssemblyModule(ExecState* stat
         exportSymbolTable->set(NoLockingNecessary, exp.field.impl(), SymbolTableEntry(VarOffset(offset)));
     }
 
-    return JSValue::encode(JSWebAssemblyModule::create(vm, structure, plan.getModuleInformation(), plan.getCompiledFunctions(), exportSymbolTable));
+    unsigned calleeCount = plan.compiledFunctionCount();
+    JSWebAssemblyModule* result = JSWebAssemblyModule::create(vm, structure, plan.getModuleInformation(), exportSymbolTable, calleeCount);
+    plan.initializeCallees(state->jsCallee()->globalObject(), 
+        [&] (unsigned calleeIndex, JSWebAssemblyCallee* callee) {
+            result->callees()[calleeIndex].set(vm, result, callee);
+        });
+    return JSValue::encode(result);
 }
 
 static EncodedJSValue JSC_HOST_CALL callJSWebAssemblyModule(ExecState* state)
index a618e05..dace16f 100644 (file)
@@ -106,7 +106,6 @@ void WebAssemblyModuleRecord::link(ExecState* state, JSWebAssemblyInstance* inst
     auto* globalObject = state->lexicalGlobalObject();
 
     const Wasm::ModuleInformation& moduleInformation = instance->module()->moduleInformation();
-    const Wasm::CompiledFunctions& compiledFunctions = instance->module()->compiledFunctions();
     SymbolTable* exportSymbolTable = instance->module()->exportSymbolTable();
 
     // FIXME wire up the imports. https://bugs.webkit.org/show_bug.cgi?id=165118
@@ -124,10 +123,9 @@ void WebAssemblyModuleRecord::link(ExecState* state, JSWebAssemblyInstance* inst
             //     a. Let func be an Exported Function Exotic Object created from c.
             //     b. Append func to funcs.
             //     c. Return func.
-            const Wasm::FunctionCompilation* compiledFunction = compiledFunctions.at(exp.functionIndex).get();
-            const B3::Compilation* jsEntryPoint = compiledFunction->jsEntryPoint.get();
-            const Wasm::Signature* signature = moduleInformation.functions.at(exp.functionIndex).signature;
-            WebAssemblyFunction* function = WebAssemblyFunction::create(vm, globalObject, signature->arguments.size(), exp.field.string(), instance, CallableWebAssemblyFunction(jsEntryPoint, signature));
+            JSWebAssemblyCallee* wasmCallee = instance->module()->callee(exp.functionIndex);
+            Wasm::Signature* signature = moduleInformation.functions.at(exp.functionIndex).signature;
+            WebAssemblyFunction* function = WebAssemblyFunction::create(vm, globalObject, signature->arguments.size(), exp.field.string(), instance, wasmCallee, signature);
             exportedValue = function;
             break;
         }