Diff
Copied: trunk/Source/_javascript_Core/B3CallingConventions.cpp (from rev 205329, trunk/Source/_javascript_Core/llint/LLIntThunks.h) (0 => 205330)
--- trunk/Source/_javascript_Core/B3CallingConventions.cpp (rev 0)
+++ trunk/Source/_javascript_Core/B3CallingConventions.cpp 2016-09-02 01:19:42 UTC (rev 205330)
@@ -0,0 +1,52 @@
+/*
+ * 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 "B3CallingConventions.h"
+
+#include <wtf/NeverDestroyed.h>
+
+#if ENABLE(B3_JIT)
+
+namespace JSC {
+
+namespace B3 {
+
+JSCCallingConvention& jscCallingConvention()
+{
+ static LazyNeverDestroyed<JSCCallingConvention> staticJSCCallingConvention;
+ static std::once_flag staticJSCCallingConventionFlag;
+ std::call_once(staticJSCCallingConventionFlag, [] () {
+ staticJSCCallingConvention.construct(Vector<GPRReg>(), RegisterSet::calleeSaveRegisters());
+ });
+
+ return staticJSCCallingConvention;
+}
+
+} // namespace B3
+
+} // namespace JSC
+
+#endif // ENABLE(B3_JIT)
Added: trunk/Source/_javascript_Core/B3CallingConventions.h (0 => 205330)
--- trunk/Source/_javascript_Core/B3CallingConventions.h (rev 0)
+++ trunk/Source/_javascript_Core/B3CallingConventions.h 2016-09-02 01:19:42 UTC (rev 205330)
@@ -0,0 +1,94 @@
+/*
+ * 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(B3_JIT)
+
+#include "B3ArgumentRegValue.h"
+#include "B3BasicBlock.h"
+#include "B3Const64Value.h"
+#include "B3MemoryValue.h"
+#include "B3Type.h"
+#include "CallFrame.h"
+#include "RegisterSet.h"
+
+namespace JSC {
+
+namespace B3 {
+
+typedef unsigned (*NextOffset)(unsigned currentOffset, Type type);
+
+template<unsigned offset, NextOffset updateOffset>
+class CallingConvention {
+public:
+ static const unsigned headerSize = offset;
+
+ CallingConvention(Vector<GPRReg>&& registerArguments, RegisterSet&& calleeSaveRegisters)
+ : m_registerArguments(registerArguments)
+ , m_calleeSaveRegisters(calleeSaveRegisters)
+ {
+ }
+
+ template<typename Functor>
+ void iterate(const Vector<Type>& argumentTypes, Procedure& proc, BasicBlock* block, Origin origin, const Functor& functor) const
+ {
+ unsigned currentOffset = headerSize;
+ Value* framePointer = block->appendNew<Value>(proc, FramePointer, origin);
+
+ for (unsigned i = 0; i < argumentTypes.size(); ++i) {
+ Value* argument;
+ if (i < m_registerArguments.size())
+ argument = block->appendNew<ArgumentRegValue>(proc, origin, m_registerArguments[i]);
+ else {
+ Value* address = block->appendNew<Value>(proc, Add, origin, framePointer,
+ block->appendNew<Const64Value>(proc, origin, currentOffset));
+ argument = block->appendNew<MemoryValue>(proc, Load, argumentTypes[i], origin, address);
+ currentOffset = updateOffset(currentOffset, argumentTypes[i]);
+ }
+ functor(argument, i);
+ }
+ }
+
+ const Vector<GPRReg> m_registerArguments;
+ const RegisterSet m_calleeSaveRegisters;
+ const RegisterSet m_callerSaveRegisters;
+};
+
+inline unsigned nextJSCOffset(unsigned currentOffset, Type)
+{
+ return currentOffset + sizeof(Register);
+}
+
+constexpr unsigned jscHeaderSize = ExecState::headerSizeInRegisters * sizeof(Register);
+typedef CallingConvention<jscHeaderSize, nextJSCOffset> JSCCallingConvention;
+
+JSCCallingConvention& jscCallingConvention();
+
+} // namespace B3
+
+} // namespace JSC
+
+#endif // ENABLE(B3_JIT)
Modified: trunk/Source/_javascript_Core/ChangeLog (205329 => 205330)
--- trunk/Source/_javascript_Core/ChangeLog 2016-09-02 01:16:56 UTC (rev 205329)
+++ trunk/Source/_javascript_Core/ChangeLog 2016-09-02 01:19:42 UTC (rev 205330)
@@ -81,6 +81,50 @@
2016-09-01 Keith Miller <[email protected]>
+ WASM functions should be able to use arguments
+ https://bugs.webkit.org/show_bug.cgi?id=161471
+
+ Reviewed by Benjamin Poulain.
+
+ This patch does a couple of changes:
+
+ 1) Adds a new Calling Convention class for B3. This class is used to make it easy to specify the calling convention of a function. In particular it knows which arguments are in registers and which ones should be on the stack. For now, nothing uses the argument registers, in the future we will use these for WASM and/or JS. Additonally, it knows the callee save registers for any given function. The main advantage of this class is that it makes it easy to iterate over the arguments of your function without having to worry about the details of the calling convention you are using.
+
+ 2) Makes the WASM calling convention the same as the JS one. Currently, the CodeBlock, CodeOrigin, and Callee are all 0. Since they have no value. Additionally, since we call into WASM from C++ through vmEntryToJavaScript, if there are no arguments to the callee we insert a null pointer as the first argument.
+
+ 3) Since WASM expects the arguments to be mapped to function locals we map the argument stack slots to variables immediately after the function prologue.
+
+ * B3CallingConventions.cpp: Copied from Source/_javascript_Core/llint/LLIntThunks.h.
+ (JSC::B3::jscCallingConvention):
+ * B3CallingConventions.h: Added.
+ (JSC::B3::CallingConvention::CallingConvention):
+ (JSC::B3::CallingConvention::iterate):
+ (JSC::B3::nextJSCOffset):
+ * _javascript_Core.xcodeproj/project.pbxproj:
+ * interpreter/ProtoCallFrame.h:
+ * llint/LLIntThunks.cpp:
+ (JSC::vmEntryToWASM):
+ * llint/LLIntThunks.h:
+ * testWASM.cpp:
+ (invoke):
+ (box):
+ (runWASMTests):
+ * wasm/WASMB3IRGenerator.cpp:
+ (JSC::WASM::B3IRGenerator::addLocal):
+ (JSC::WASM::B3IRGenerator::addArguments):
+ (JSC::WASM::B3IRGenerator::getLocal):
+ * wasm/WASMFormat.h:
+ * wasm/WASMFunctionParser.h:
+ (JSC::WASM::FunctionParser<Context>::FunctionParser):
+ (JSC::WASM::FunctionParser<Context>::parseExpression):
+ * wasm/WASMModuleParser.cpp:
+ (JSC::WASM::ModuleParser::parseFunctionTypes):
+ (JSC::WASM::ModuleParser::parseFunctionSignatures):
+ * wasm/WASMModuleParser.h:
+ * wasm/WASMOps.h:
+
+2016-09-01 Keith Miller <[email protected]>
+
Rename WASM classes dropping the WASM prefix
https://bugs.webkit.org/show_bug.cgi?id=161500
Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (205329 => 205330)
--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2016-09-02 01:16:56 UTC (rev 205329)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj 2016-09-02 01:19:42 UTC (rev 205330)
@@ -1179,6 +1179,7 @@
52C952B919A28A1C0069B386 /* TypeProfiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52C952B819A28A1C0069B386 /* TypeProfiler.cpp */; };
531374BD1D5CE67600AF7A0B /* WASMPlan.h in Headers */ = {isa = PBXBuildFile; fileRef = 531374BC1D5CE67600AF7A0B /* WASMPlan.h */; };
531374BF1D5CE95000AF7A0B /* WASMPlan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 531374BE1D5CE95000AF7A0B /* WASMPlan.cpp */; };
+ 531B3C871D74C603005B3236 /* B3CallingConventions.h in Headers */ = {isa = PBXBuildFile; fileRef = 531B3C861D74C603005B3236 /* B3CallingConventions.h */; };
53486BB71C1795C300F6F3AF /* JSTypedArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 53486BB61C1795C300F6F3AF /* JSTypedArray.h */; settings = {ATTRIBUTES = (Public, ); }; };
53486BBB1C18E84500F6F3AF /* JSTypedArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53486BBA1C18E84500F6F3AF /* JSTypedArray.cpp */; };
534902851C7276B70012BCB8 /* TypedArrayCTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 534902821C7242C80012BCB8 /* TypedArrayCTest.cpp */; };
@@ -1187,6 +1188,7 @@
53529A4C1C457B75000B49C6 /* APIUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 53529A4B1C457B75000B49C6 /* APIUtils.h */; };
5370B4F51BF26202005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5370B4F31BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.cpp */; };
5370B4F61BF26205005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 5370B4F41BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h */; };
+ 5388B4041D76640B00D3D852 /* B3CallingConventions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5388B4031D76640B00D3D852 /* B3CallingConventions.cpp */; };
53917E7B1B7906FA000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 53917E7A1B7906E4000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h */; };
539EB0791D55607000C82EF7 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51F0EB6105C86C6B00E6DF1B /* Foundation.framework */; };
539EB07A1D55607000C82EF7 /* _javascript_Core.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 932F5BD90822A1C700736975 /* _javascript_Core.framework */; };
@@ -3371,6 +3373,7 @@
52C952B819A28A1C0069B386 /* TypeProfiler.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TypeProfiler.cpp; sourceTree = "<group>"; };
531374BC1D5CE67600AF7A0B /* WASMPlan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WASMPlan.h; sourceTree = "<group>"; };
531374BE1D5CE95000AF7A0B /* WASMPlan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WASMPlan.cpp; sourceTree = "<group>"; };
+ 531B3C861D74C603005B3236 /* B3CallingConventions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = B3CallingConventions.h; sourceTree = "<group>"; };
53486BB61C1795C300F6F3AF /* JSTypedArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTypedArray.h; sourceTree = "<group>"; };
53486BBA1C18E84500F6F3AF /* JSTypedArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTypedArray.cpp; sourceTree = "<group>"; };
534902821C7242C80012BCB8 /* TypedArrayCTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TypedArrayCTest.cpp; path = API/tests/TypedArrayCTest.cpp; sourceTree = "<group>"; };
@@ -3381,6 +3384,7 @@
53529A4B1C457B75000B49C6 /* APIUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIUtils.h; sourceTree = "<group>"; };
5370B4F31BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AdaptiveInferredPropertyValueWatchpointBase.cpp; sourceTree = "<group>"; };
5370B4F41BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AdaptiveInferredPropertyValueWatchpointBase.h; sourceTree = "<group>"; };
+ 5388B4031D76640B00D3D852 /* B3CallingConventions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = B3CallingConventions.cpp; sourceTree = "<group>"; };
53917E7A1B7906E4000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGenericTypedArrayViewPrototypeFunctions.h; sourceTree = "<group>"; };
53917E7C1B791106000EBD33 /* JSTypedArrayViewPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTypedArrayViewPrototype.h; sourceTree = "<group>"; };
53917E831B791CB8000EBD33 /* TypedArrayPrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; name = TypedArrayPrototype.js; path = builtins/TypedArrayPrototype.js; sourceTree = SOURCE_ROOT; };
@@ -4775,6 +4779,8 @@
DCFDFBD71D1F5D9800FE3D72 /* B3BottomProvider.h */,
0F6B8ADE1C4EFE1700969052 /* B3BreakCriticalEdges.cpp */,
0F6B8ADF1C4EFE1700969052 /* B3BreakCriticalEdges.h */,
+ 5388B4031D76640B00D3D852 /* B3CallingConventions.cpp */,
+ 531B3C861D74C603005B3236 /* B3CallingConventions.h */,
DC9A0C1C1D2D94EF0085124E /* B3CaseCollection.cpp */,
DC9A0C1D1D2D94EF0085124E /* B3CaseCollection.h */,
DC9A0C1E1D2D94EF0085124E /* B3CaseCollectionInlines.h */,
@@ -4889,9 +4895,9 @@
0FEC84EF1BDACDAC0080FF74 /* B3SwitchValue.cpp */,
0FEC84F01BDACDAC0080FF74 /* B3SwitchValue.h */,
0F45703E1BE584CA0062A629 /* B3TimingScope.cpp */,
+ 0FEC84F21BDACDAC0080FF74 /* B3Type.h */,
0F45703F1BE584CA0062A629 /* B3TimingScope.h */,
0FEC84F11BDACDAC0080FF74 /* B3Type.cpp */,
- 0FEC84F21BDACDAC0080FF74 /* B3Type.h */,
DCFDFBD81D1F5D9800FE3D72 /* B3TypeMap.h */,
0FEC84F31BDACDAC0080FF74 /* B3UpsilonValue.cpp */,
0FEC84F41BDACDAC0080FF74 /* B3UpsilonValue.h */,
@@ -8265,6 +8271,7 @@
99DA00B11BD5994E00F4575C /* UpdateContents.py in Headers */,
0F963B3813FC6FE90002D9B2 /* ValueProfile.h in Headers */,
0F426A481460CBB300131F8F /* ValueRecovery.h in Headers */,
+ 531B3C871D74C603005B3236 /* B3CallingConventions.h in Headers */,
79EE0C001B4AFB85000385C9 /* VariableEnvironment.h in Headers */,
0F6C73511AC9F99F00BE1682 /* VariableWriteFireDetail.h in Headers */,
0FE0502D1AA9095600D33B33 /* VarOffset.h in Headers */,
@@ -8916,6 +8923,7 @@
7094C4DE1AE439530041A2EE /* BytecodeIntrinsicRegistry.cpp in Sources */,
C2FCAE1217A9C24E0034C735 /* BytecodeLivenessAnalysis.cpp in Sources */,
0F338E0D1BF0276C0013C88F /* B3DataSection.cpp in Sources */,
+ 5388B4041D76640B00D3D852 /* B3CallingConventions.cpp in Sources */,
65B8392F1BACAD6A0044E824 /* CachedRecovery.cpp in Sources */,
1428082D107EC0570013E7B2 /* CallData.cpp in Sources */,
0F64B2791A7957B2006E4E66 /* CallEdge.cpp in Sources */,
Modified: trunk/Source/_javascript_Core/interpreter/ProtoCallFrame.h (205329 => 205330)
--- trunk/Source/_javascript_Core/interpreter/ProtoCallFrame.h 2016-09-02 01:16:56 UTC (rev 205329)
+++ trunk/Source/_javascript_Core/interpreter/ProtoCallFrame.h 2016-09-02 01:19:42 UTC (rev 205330)
@@ -30,7 +30,7 @@
namespace JSC {
-struct ProtoCallFrame {
+struct JS_EXPORT_PRIVATE ProtoCallFrame {
Register codeBlockValue;
Register calleeValue;
Register argCountAndCodeOriginValue;
Modified: trunk/Source/_javascript_Core/llint/LLIntThunks.cpp (205329 => 205330)
--- trunk/Source/_javascript_Core/llint/LLIntThunks.cpp 2016-09-02 01:16:56 UTC (rev 205329)
+++ trunk/Source/_javascript_Core/llint/LLIntThunks.cpp 2016-09-02 01:19:42 UTC (rev 205330)
@@ -41,6 +41,11 @@
namespace JSC {
+EncodedJSValue JS_EXPORT_PRIVATE vmEntryToWASM(void* code, VM* vm, ProtoCallFrame* frame)
+{
+ return vmEntryToJavaScript(code, vm, frame);
+}
+
#if ENABLE(JIT)
namespace LLInt {
Modified: trunk/Source/_javascript_Core/llint/LLIntThunks.h (205329 => 205330)
--- trunk/Source/_javascript_Core/llint/LLIntThunks.h 2016-09-02 01:16:56 UTC (rev 205329)
+++ trunk/Source/_javascript_Core/llint/LLIntThunks.h 2016-09-02 01:19:42 UTC (rev 205330)
@@ -38,6 +38,8 @@
EncodedJSValue vmEntryToNative(void*, VM*, ProtoCallFrame*);
}
+EncodedJSValue JS_EXPORT_PRIVATE vmEntryToWASM(void*, VM*, ProtoCallFrame*);
+
namespace LLInt {
MacroAssemblerCodeRef functionForCallEntryThunkGenerator(VM*);
Modified: trunk/Source/_javascript_Core/testWASM.cpp (205329 => 205330)
--- trunk/Source/_javascript_Core/testWASM.cpp 2016-09-02 01:16:56 UTC (rev 205329)
+++ trunk/Source/_javascript_Core/testWASM.cpp 2016-09-02 01:19:42 UTC (rev 205330)
@@ -27,7 +27,10 @@
#include "B3Compilation.h"
#include "InitializeThreading.h"
+#include "JSCJSValueInlines.h"
#include "JSString.h"
+#include "LLIntThunks.h"
+#include "ProtoCallFrame.h"
#include "VM.h"
#include "WASMPlan.h"
#include <wtf/DataLog.h>
@@ -190,19 +193,38 @@
using namespace WASM;
using namespace B3;
-template<typename T, typename... Arguments>
-T invoke(MacroAssemblerCodePtr ptr, Arguments... arguments)
+template<typename T>
+T invoke(MacroAssemblerCodePtr ptr, std::initializer_list<JSValue> args)
{
- T (*function)(Arguments...) = bitwise_cast<T(*)(Arguments...)>(ptr.executableAddress());
- return function(arguments...);
+ JSValue firstArgument;
+ // Since vmEntryToJavaScript expects a this value we claim there is one... there isn't.
+ int argCount = 1;
+ JSValue* remainingArguments = nullptr;
+ if (args.size()) {
+ remainingArguments = const_cast<JSValue*>(args.begin());
+ firstArgument = *remainingArguments;
+ remainingArguments++;
+ argCount = args.size();
+ }
+
+ ProtoCallFrame protoCallFrame;
+ protoCallFrame.init(nullptr, nullptr, firstArgument, argCount, remainingArguments);
+
+ // This won't work for floating point values but we don't have those yet.
+ return static_cast<T>(vmEntryToWASM(ptr.executableAddress(), vm, &protoCallFrame));
}
-template<typename T, typename... Arguments>
-T invoke(const Compilation& code, Arguments... arguments)
+template<typename T>
+T invoke(const Compilation& code, std::initializer_list<JSValue> args)
{
- return invoke<T>(code.code(), arguments...);
+ return invoke<T>(code.code(), args);
}
+inline JSValue box(uint64_t value)
+{
+ return JSValue::decode(value);
+}
+
// For now we inline the test files.
static void runWASMTests()
{
@@ -224,7 +246,7 @@
}
// Test this doesn't crash.
- RELEASE_ASSERT(invoke<int>(*plan.result[0]) == 5);
+ RELEASE_ASSERT(invoke<int>(*plan.result[0], { }) == 5);
}
@@ -246,7 +268,7 @@
}
// Test this doesn't crash.
- RELEASE_ASSERT(invoke<int>(*plan.result[0]) == 11);
+ RELEASE_ASSERT(invoke<int>(*plan.result[0], { }) == 11);
}
{
@@ -267,7 +289,7 @@
}
// Test this doesn't crash.
- RELEASE_ASSERT(invoke<int>(*plan.result[0]) == 11);
+ RELEASE_ASSERT(invoke<int>(*plan.result[0], { }) == 11);
}
{
@@ -288,8 +310,30 @@
}
// Test this doesn't crash.
- RELEASE_ASSERT(invoke<int>(*plan.result[0]) == 11);
+ RELEASE_ASSERT(invoke<int>(*plan.result[0], { }) == 11);
}
+
+ {
+ // Generated from: (module (func $add (param $x i32) (param $y i32) (result i32) (return (i32.add (get_local $x) (get_local $y)))) )
+ Vector<uint8_t> vector = {
+ 0x00, 0x61, 0x73, 0x6d, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x74, 0x79, 0x70, 0x65, 0x87, 0x80, 0x80,
+ 0x00, 0x01, 0x40, 0x02, 0x01, 0x01, 0x01, 0x01, 0x08, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
+ 0x6e, 0x82, 0x80, 0x80, 0x00, 0x01, 0x00, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x8e, 0x80, 0x80, 0x00,
+ 0x01, 0x89, 0x80, 0x80, 0x00, 0x00, 0x14, 0x00, 0x14, 0x01, 0x40, 0x09, 0x01, 0x0f
+ };
+
+ Plan plan(*vm, vector);
+ if (plan.result.size() != 1 || !plan.result[0]) {
+ dataLogLn("Module failed to compile correctly.");
+ CRASH();
+ }
+
+ // Test this doesn't crash.
+ RELEASE_ASSERT(invoke<int>(*plan.result[0], {box(0), box(1)}) == 1);
+ RELEASE_ASSERT(invoke<int>(*plan.result[0], {box(100), box(1)}) == 101);
+ RELEASE_ASSERT(invoke<int>(*plan.result[0], {box(-1), box(1)}) == 0);
+ RELEASE_ASSERT(invoke<int>(*plan.result[0], {box(std::numeric_limits<int>::max()), box(1)}) == std::numeric_limits<int>::min());
+ }
}
#endif // ENABLE(WEBASSEMBLY)
Modified: trunk/Source/_javascript_Core/wasm/WASMB3IRGenerator.cpp (205329 => 205330)
--- trunk/Source/_javascript_Core/wasm/WASMB3IRGenerator.cpp 2016-09-02 01:16:56 UTC (rev 205329)
+++ trunk/Source/_javascript_Core/wasm/WASMB3IRGenerator.cpp 2016-09-02 01:19:42 UTC (rev 205330)
@@ -29,9 +29,11 @@
#if ENABLE(WEBASSEMBLY)
#include "B3BasicBlockInlines.h"
+#include "B3CallingConventions.h"
#include "B3ValueInlines.h"
#include "B3Variable.h"
#include "B3VariableValue.h"
+#include "VirtualRegister.h"
#include "WASMFunctionParser.h"
#include <wtf/Optional.h>
@@ -67,9 +69,12 @@
B3IRGenerator(Procedure&);
+ void addArguments(const Vector<Type>&);
void addLocal(Type, uint32_t);
ExpressionType addConstant(Type, uint64_t);
+ bool WARN_UNUSED_RETURN getLocal(uint32_t index, ExpressionType& result);
+
bool WARN_UNUSED_RETURN binaryOp(BinaryOpType, ExpressionType left, ExpressionType right, ExpressionType& result);
bool WARN_UNUSED_RETURN unaryOp(UnaryOpType, ExpressionType arg, ExpressionType& result);
@@ -88,6 +93,7 @@
BasicBlock* m_currentBlock;
// This is a pair of the continuation and the types expected on the stack for that continuation.
Vector<std::pair<BasicBlock*, Optional<Vector<Variable*>>>> m_controlStack;
+ Vector<Variable*> m_locals;
};
B3IRGenerator::B3IRGenerator(Procedure& procedure)
@@ -96,11 +102,33 @@
m_currentBlock = m_proc.addBlock();
}
-void B3IRGenerator::addLocal(Type, uint32_t)
+void B3IRGenerator::addLocal(Type type, uint32_t count)
{
+ m_locals.reserveCapacity(m_locals.size() + count);
+ for (uint32_t i = 0; i < count; ++i)
+ m_locals.append(m_proc.addVariable(type));
+}
+
+void B3IRGenerator::addArguments(const Vector<Type>& types)
+{
// TODO: Add locals.
+ ASSERT(!m_locals.size());
+ m_locals.grow(types.size());
+ jscCallingConvention().iterate(types, m_proc, m_currentBlock, Origin(),
+ [&] (ExpressionType argument, unsigned i) {
+ Variable* argumentVariable = m_proc.addVariable(argument->type());
+ m_locals[i] = argumentVariable;
+ m_currentBlock->appendNew<VariableValue>(m_proc, Set, Origin(), argumentVariable, argument);
+ });
}
+bool WARN_UNUSED_RETURN B3IRGenerator::getLocal(uint32_t index, ExpressionType& result)
+{
+ ASSERT(m_locals[index]);
+ result = m_currentBlock->appendNew<VariableValue>(m_proc, B3::Get, Origin(), m_locals[index]);
+ return true;
+}
+
bool B3IRGenerator::unaryOp(UnaryOpType op, ExpressionType arg, ExpressionType& result)
{
result = m_currentBlock->appendNew<Value>(m_proc, toB3Op(op), Origin(), arg);
Modified: trunk/Source/_javascript_Core/wasm/WASMFormat.h (205329 => 205330)
--- trunk/Source/_javascript_Core/wasm/WASMFormat.h 2016-09-02 01:16:56 UTC (rev 205329)
+++ trunk/Source/_javascript_Core/wasm/WASMFormat.h 2016-09-02 01:19:42 UTC (rev 205330)
@@ -90,6 +90,7 @@
};
struct FunctionInformation {
+ Signature* signature;
size_t start;
size_t end;
};
Modified: trunk/Source/_javascript_Core/wasm/WASMFunctionParser.h (205329 => 205330)
--- trunk/Source/_javascript_Core/wasm/WASMFunctionParser.h 2016-09-02 01:16:56 UTC (rev 205329)
+++ trunk/Source/_javascript_Core/wasm/WASMFunctionParser.h 2016-09-02 01:19:42 UTC (rev 205330)
@@ -61,6 +61,7 @@
: Parser(sourceBuffer, info.start, info.end)
, m_context(context)
{
+ m_context.addArguments(info.signature->arguments);
}
template<typename Context>
@@ -138,6 +139,18 @@
return true;
}
+ case OpType::GetLocal: {
+ uint32_t index;
+ if (!parseVarUInt32(index))
+ return false;
+ ExpressionType result;
+ if (!m_context.getLocal(index, result))
+ return false;
+
+ m_expressionStack.append(result);
+ return true;
+ }
+
case OpType::Block: {
if (!m_context.addBlock())
return false;
Modified: trunk/Source/_javascript_Core/wasm/WASMModuleParser.cpp (205329 => 205330)
--- trunk/Source/_javascript_Core/wasm/WASMModuleParser.cpp 2016-09-02 01:16:56 UTC (rev 205329)
+++ trunk/Source/_javascript_Core/wasm/WASMModuleParser.cpp 2016-09-02 01:19:42 UTC (rev 205330)
@@ -140,6 +140,8 @@
if (verbose)
dataLogLn("count: ", count);
+ m_signatures.resize(count);
+
for (uint32_t i = 0; i < count; ++i) {
uint8_t type;
if (!parseUInt7(type))
@@ -181,8 +183,7 @@
} else
returnType = Type::Void;
- // TODO: Actually do something with this data...
- UNUSED_PARAM(returnType);
+ m_signatures[i] = { returnType, WTFMove(argumentTypes) };
}
return true;
}
@@ -199,6 +200,11 @@
uint32_t typeNumber;
if (!parseVarUInt32(typeNumber))
return false;
+
+ if (typeNumber >= m_signatures.size())
+ return false;
+
+ m_functions[i].signature = &m_signatures[typeNumber];
}
return true;
Modified: trunk/Source/_javascript_Core/wasm/WASMModuleParser.h (205329 => 205330)
--- trunk/Source/_javascript_Core/wasm/WASMModuleParser.h 2016-09-02 01:16:56 UTC (rev 205329)
+++ trunk/Source/_javascript_Core/wasm/WASMModuleParser.h 2016-09-02 01:19:42 UTC (rev 205330)
@@ -58,6 +58,7 @@
bool WARN_UNUSED_RETURN parseExpression(OpType);
Vector<FunctionInformation> m_functions;
+ Vector<Signature> m_signatures;
};
} // namespace WASM
Modified: trunk/Source/_javascript_Core/wasm/WASMOps.h (205329 => 205330)
--- trunk/Source/_javascript_Core/wasm/WASMOps.h 2016-09-02 01:16:56 UTC (rev 205329)
+++ trunk/Source/_javascript_Core/wasm/WASMOps.h 2016-09-02 01:19:42 UTC (rev 205330)
@@ -32,7 +32,8 @@
namespace WASM {
#define FOR_EACH_WASM_SPECIAL_OP(macro) \
- macro(I32Const, 0x10, NA)
+ macro(I32Const, 0x10, NA) \
+ macro(GetLocal, 0x14, NA)
#define FOR_EACH_WASM_CONTROL_FLOW_OP(macro) \
macro(Block, 0x01, NA) \