Title: [205552] trunk/Source/_javascript_Core
Revision
205552
Author
keith_mil...@apple.com
Date
2016-09-07 10:12:08 -0700 (Wed, 07 Sep 2016)

Log Message

Add support for WASM Loops and Branches
https://bugs.webkit.org/show_bug.cgi?id=161569

Reviewed by Benjamin Poulain.

This patch adds support for loops and branches to WASM. In order
to support loops, we needed to change the way the B3IRGenerator
tracked control information. Now, the control data holds three
pieces of information: The continuation block, the loop branch
target, and variables exiting the block. Whenever we branch to
some control point we first check if it is a loop by checking that
the loop branch target is non-null. If the branch is not targeting
a loop, we map the stack values to the associated B3 variables for
that stack slot.

Another interesting thing of note is that we now only allocate the
continuation basic block lazily. This is beneficial when the
continuation would just fall through to another block anyway. For
example, in code like: (block ... (block (add 1 2) end) end) the
continuation for the inner block just falls through to the outer
block's continuation so we don't need an extra block.

* B3CallingConventions.cpp:
(JSC::B3::jscCallingConvention): Deleted.
* B3CallingConventions.h:
(JSC::B3::CallingConvention::CallingConvention): Deleted.
(JSC::B3::CallingConvention::iterate): Deleted.
(JSC::B3::nextJSCOffset): Deleted.
* _javascript_Core.xcodeproj/project.pbxproj:
* b3/B3Type.h:
* testWASM.cpp:
(runWASMTests):
* wasm/WASMB3IRGenerator.cpp:
(JSC::WASM::B3IRGenerator::LazyBlock::LazyBlock):
(JSC::WASM::B3IRGenerator::LazyBlock::operator bool):
(JSC::WASM::B3IRGenerator::LazyBlock::get):
(JSC::WASM::B3IRGenerator::LazyBlock::dump):
(JSC::WASM::B3IRGenerator::ControlData::ControlData):
(JSC::WASM::B3IRGenerator::ControlData::dump):
(JSC::WASM::B3IRGenerator::ControlData::targetBlockForBranch):
(JSC::WASM::B3IRGenerator::ControlData::isLoop):
(JSC::WASM::B3IRGenerator::addLocal):
(JSC::WASM::B3IRGenerator::addArguments):
(JSC::WASM::B3IRGenerator::setLocal):
(JSC::WASM::B3IRGenerator::addBlock):
(JSC::WASM::B3IRGenerator::addLoop):
(JSC::WASM::B3IRGenerator::endBlock):
(JSC::WASM::B3IRGenerator::addReturn):
(JSC::WASM::B3IRGenerator::addBranch):
(JSC::WASM::B3IRGenerator::initializeIncommingTypes):
(JSC::WASM::B3IRGenerator::unifyValuesWithBlock):
(JSC::WASM::B3IRGenerator::controlDataForLevel):
(JSC::WASM::B3IRGenerator::dumpGraphAndControlStack):
(JSC::WASM::parseAndCompile):
(JSC::WASM::B3IRGenerator::unifyValuesWithLevel): Deleted.
(JSC::WASM::B3IRGenerator::stackForControlLevel): Deleted.
(JSC::WASM::B3IRGenerator::blockForControlLevel): Deleted.
* wasm/WASMCallingConvention.cpp: Renamed from Source/_javascript_Core/B3CallingConventions.cpp.
(JSC::WASM::jscCallingConvention):
* wasm/WASMCallingConvention.h: Renamed from Source/_javascript_Core/B3CallingConventions.h.
(JSC::WASM::CallingConvention::CallingConvention):
(JSC::WASM::CallingConvention::iterate):
(JSC::WASM::nextJSCOffset):
* wasm/WASMFormat.h:
(JSC::WASM::toB3Type):
(JSC::WASM::isValueType):
* wasm/WASMFunctionParser.h:
(JSC::WASM::FunctionParser<Context>::parse):
(JSC::WASM::FunctionParser<Context>::parseExpression):
* wasm/WASMModuleParser.cpp:
(JSC::WASM::ModuleParser::parseFunctionTypes):
* wasm/WASMOps.h:

Modified Paths

Added Paths

Removed Paths

Diff

Deleted: trunk/Source/_javascript_Core/B3CallingConventions.cpp (205551 => 205552)


--- trunk/Source/_javascript_Core/B3CallingConventions.cpp	2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/_javascript_Core/B3CallingConventions.cpp	2016-09-07 17:12:08 UTC (rev 205552)
@@ -1,52 +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 "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)

Deleted: trunk/Source/_javascript_Core/B3CallingConventions.h (205551 => 205552)


--- trunk/Source/_javascript_Core/B3CallingConventions.h	2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/_javascript_Core/B3CallingConventions.h	2016-09-07 17:12:08 UTC (rev 205552)
@@ -1,94 +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(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/CMakeLists.txt (205551 => 205552)


--- trunk/Source/_javascript_Core/CMakeLists.txt	2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/_javascript_Core/CMakeLists.txt	2016-09-07 17:12:08 UTC (rev 205552)
@@ -854,6 +854,7 @@
     wasm/WASMModuleParser.cpp
     wasm/WASMPlan.cpp
     wasm/WASMSections.cpp
+    wasm/WASMCallingConventions.cpp
 
     yarr/RegularExpression.cpp
     yarr/YarrCanonicalizeUCS2.cpp

Modified: trunk/Source/_javascript_Core/ChangeLog (205551 => 205552)


--- trunk/Source/_javascript_Core/ChangeLog	2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-09-07 17:12:08 UTC (rev 205552)
@@ -1,3 +1,78 @@
+2016-09-03  Keith Miller  <keith_mil...@apple.com>
+
+        Add support for WASM Loops and Branches
+        https://bugs.webkit.org/show_bug.cgi?id=161569
+
+        Reviewed by Benjamin Poulain.
+
+        This patch adds support for loops and branches to WASM. In order
+        to support loops, we needed to change the way the B3IRGenerator
+        tracked control information. Now, the control data holds three
+        pieces of information: The continuation block, the loop branch
+        target, and variables exiting the block. Whenever we branch to
+        some control point we first check if it is a loop by checking that
+        the loop branch target is non-null. If the branch is not targeting
+        a loop, we map the stack values to the associated B3 variables for
+        that stack slot.
+
+        Another interesting thing of note is that we now only allocate the
+        continuation basic block lazily. This is beneficial when the
+        continuation would just fall through to another block anyway. For
+        example, in code like: (block ... (block (add 1 2) end) end) the
+        continuation for the inner block just falls through to the outer
+        block's continuation so we don't need an extra block.
+
+        * B3CallingConventions.cpp:
+        (JSC::B3::jscCallingConvention): Deleted.
+        * B3CallingConventions.h:
+        (JSC::B3::CallingConvention::CallingConvention): Deleted.
+        (JSC::B3::CallingConvention::iterate): Deleted.
+        (JSC::B3::nextJSCOffset): Deleted.
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * b3/B3Type.h:
+        * testWASM.cpp:
+        (runWASMTests):
+        * wasm/WASMB3IRGenerator.cpp:
+        (JSC::WASM::B3IRGenerator::LazyBlock::LazyBlock):
+        (JSC::WASM::B3IRGenerator::LazyBlock::operator bool):
+        (JSC::WASM::B3IRGenerator::LazyBlock::get):
+        (JSC::WASM::B3IRGenerator::LazyBlock::dump):
+        (JSC::WASM::B3IRGenerator::ControlData::ControlData):
+        (JSC::WASM::B3IRGenerator::ControlData::dump):
+        (JSC::WASM::B3IRGenerator::ControlData::targetBlockForBranch):
+        (JSC::WASM::B3IRGenerator::ControlData::isLoop):
+        (JSC::WASM::B3IRGenerator::addLocal):
+        (JSC::WASM::B3IRGenerator::addArguments):
+        (JSC::WASM::B3IRGenerator::setLocal):
+        (JSC::WASM::B3IRGenerator::addBlock):
+        (JSC::WASM::B3IRGenerator::addLoop):
+        (JSC::WASM::B3IRGenerator::endBlock):
+        (JSC::WASM::B3IRGenerator::addReturn):
+        (JSC::WASM::B3IRGenerator::addBranch):
+        (JSC::WASM::B3IRGenerator::initializeIncommingTypes):
+        (JSC::WASM::B3IRGenerator::unifyValuesWithBlock):
+        (JSC::WASM::B3IRGenerator::controlDataForLevel):
+        (JSC::WASM::B3IRGenerator::dumpGraphAndControlStack):
+        (JSC::WASM::parseAndCompile):
+        (JSC::WASM::B3IRGenerator::unifyValuesWithLevel): Deleted.
+        (JSC::WASM::B3IRGenerator::stackForControlLevel): Deleted.
+        (JSC::WASM::B3IRGenerator::blockForControlLevel): Deleted.
+        * wasm/WASMCallingConvention.cpp: Renamed from Source/_javascript_Core/B3CallingConventions.cpp.
+        (JSC::WASM::jscCallingConvention):
+        * wasm/WASMCallingConvention.h: Renamed from Source/_javascript_Core/B3CallingConventions.h.
+        (JSC::WASM::CallingConvention::CallingConvention):
+        (JSC::WASM::CallingConvention::iterate):
+        (JSC::WASM::nextJSCOffset):
+        * wasm/WASMFormat.h:
+        (JSC::WASM::toB3Type):
+        (JSC::WASM::isValueType):
+        * wasm/WASMFunctionParser.h:
+        (JSC::WASM::FunctionParser<Context>::parse):
+        (JSC::WASM::FunctionParser<Context>::parseExpression):
+        * wasm/WASMModuleParser.cpp:
+        (JSC::WASM::ModuleParser::parseFunctionTypes):
+        * wasm/WASMOps.h:
+
 2016-09-07  Youenn Fablet  <you...@apple.com>
 
         [Streams API] Separate compile flag for ReadableStream and WritableStream

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (205551 => 205552)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2016-09-07 17:12:08 UTC (rev 205552)
@@ -1195,7 +1195,6 @@
 		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 */; };
@@ -1204,7 +1203,6 @@
 		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 */; };
@@ -1222,6 +1220,8 @@
 		53F6BF6D1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F6BF6C1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		53FA2AE11CF37F3F0022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 53FA2AE01CF37F3F0022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		53FA2AE31CF380390022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53FA2AE21CF380390022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp */; };
+		53FD04D31D7AB277003287D3 /* WASMCallingConvention.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53FD04D11D7AB187003287D3 /* WASMCallingConvention.cpp */; };
+		53FD04D41D7AB291003287D3 /* WASMCallingConvention.h in Headers */ = {isa = PBXBuildFile; fileRef = 53FD04D21D7AB187003287D3 /* WASMCallingConvention.h */; };
 		5D5D8AD10E0D0EBE00F9C692 /* libedit.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */; };
 		5DBB151B131D0B310056AD36 /* testapi.js in Copy Support Script */ = {isa = PBXBuildFile; fileRef = 14D857740A4696C80032146C /* testapi.js */; };
 		5DBB1525131D0BD70056AD36 /* minidom.js in Copy Support Script */ = {isa = PBXBuildFile; fileRef = 1412110D0A48788700480255 /* minidom.js */; };
@@ -3409,7 +3409,6 @@
 		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>"; };
@@ -3420,7 +3419,6 @@
 		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; };
@@ -3440,6 +3438,8 @@
 		53F6BF6C1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InternalFunctionAllocationProfile.h; sourceTree = "<group>"; };
 		53FA2AE01CF37F3F0022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLIntPrototypeLoadAdaptiveStructureWatchpoint.h; sourceTree = "<group>"; };
 		53FA2AE21CF380390022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp; sourceTree = "<group>"; };
+		53FD04D11D7AB187003287D3 /* WASMCallingConvention.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WASMCallingConvention.cpp; sourceTree = "<group>"; };
+		53FD04D21D7AB187003287D3 /* WASMCallingConvention.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WASMCallingConvention.h; sourceTree = "<group>"; };
 		593D43CCA0BBE06D89C59707 /* MapDataInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapDataInlines.h; sourceTree = "<group>"; };
 		5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libedit.dylib; path = /usr/lib/libedit.dylib; sourceTree = "<absolute>"; };
 		5DAFD6CB146B686300FBEFB4 /* JSC.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = JSC.xcconfig; sourceTree = "<group>"; };
@@ -4819,8 +4819,6 @@
 				DCFDFBD71D1F5D9800FE3D72 /* B3BottomProvider.h */,
 				0F6B8ADE1C4EFE1700969052 /* B3BreakCriticalEdges.cpp */,
 				0F6B8ADF1C4EFE1700969052 /* B3BreakCriticalEdges.h */,
-				5388B4031D76640B00D3D852 /* B3CallingConventions.cpp */,
-				531B3C861D74C603005B3236 /* B3CallingConventions.h */,
 				DC9A0C1C1D2D94EF0085124E /* B3CaseCollection.cpp */,
 				DC9A0C1D1D2D94EF0085124E /* B3CaseCollection.h */,
 				DC9A0C1E1D2D94EF0085124E /* B3CaseCollectionInlines.h */,
@@ -5628,10 +5626,12 @@
 			children = (
 				7B98D1341B60CD5A0023B1A4 /* JSWASMModule.cpp */,
 				7B98D1351B60CD5A0023B1A4 /* JSWASMModule.h */,
+				53F40E8E1D5902820099A1B6 /* WASMB3IRGenerator.cpp */,
+				53F40E921D5A4AB30099A1B6 /* WASMB3IRGenerator.h */,
+				53FD04D11D7AB187003287D3 /* WASMCallingConvention.cpp */,
+				53FD04D21D7AB187003287D3 /* WASMCallingConvention.h */,
 				53F40E901D5903020099A1B6 /* WASMOps.h */,
 				7BC547D21B69599B00959B58 /* WASMFormat.h */,
-				53F40E8E1D5902820099A1B6 /* WASMB3IRGenerator.cpp */,
-				53F40E921D5A4AB30099A1B6 /* WASMB3IRGenerator.h */,
 				53F40E8A1D5901BB0099A1B6 /* WASMFunctionParser.h */,
 				53F40E961D5A7BEC0099A1B6 /* WASMModuleParser.cpp */,
 				53F40E941D5A7AEF0099A1B6 /* WASMModuleParser.h */,
@@ -8295,6 +8295,7 @@
 				996B73271BDA08EF00331B84 /* SymbolConstructor.lut.h in Headers */,
 				705B41B01A6E501E00716757 /* SymbolObject.h in Headers */,
 				0F33FCFC1C1625BE00323F67 /* B3Dominators.h in Headers */,
+				53FD04D41D7AB291003287D3 /* WASMCallingConvention.h in Headers */,
 				705B41B21A6E501E00716757 /* SymbolPrototype.h in Headers */,
 				996B73281BDA08EF00331B84 /* SymbolPrototype.lut.h in Headers */,
 				BC18C46B0E16F5CD00B34460 /* SymbolTable.h in Headers */,
@@ -8343,7 +8344,6 @@
 				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 */,
@@ -8996,7 +8996,6 @@
 				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 */,
@@ -9129,6 +9128,7 @@
 				0FC97F3F18202119002C9B26 /* DFGJumpReplacement.cpp in Sources */,
 				FEA0C4021CDD7D1D00481991 /* FunctionWhitelist.cpp in Sources */,
 				A73A535A1799CD5D00170C19 /* DFGLazyJSValue.cpp in Sources */,
+				53FD04D31D7AB277003287D3 /* WASMCallingConvention.cpp in Sources */,
 				62F2AA371B0BEDE300610C7A /* DFGLazyNode.cpp in Sources */,
 				A7D9A29717A0BC7400EE2618 /* DFGLICMPhase.cpp in Sources */,
 				79C4B15D1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.cpp in Sources */,

Modified: trunk/Source/_javascript_Core/b3/B3Type.h (205551 => 205552)


--- trunk/Source/_javascript_Core/b3/B3Type.h	2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/_javascript_Core/b3/B3Type.h	2016-09-07 17:12:08 UTC (rev 205552)
@@ -39,12 +39,11 @@
 namespace JSC { namespace B3 {
 
 enum Type : int8_t {
+    Void,
     Int32,
     Int64,
     Float,
     Double,
-    LastValueType = Double,
-    Void
 };
 
 inline bool isInt(Type type)

Modified: trunk/Source/_javascript_Core/testWASM.cpp (205551 => 205552)


--- trunk/Source/_javascript_Core/testWASM.cpp	2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/_javascript_Core/testWASM.cpp	2016-09-07 17:12:08 UTC (rev 205552)
@@ -82,38 +82,50 @@
 
 }
 
+StaticLock crashLock;
+
+#define CHECK_EQ(x, y) do { \
+        auto __x = (x); \
+        auto __y = (y); \
+        if (__x == __y) \
+        break; \
+        crashLock.lock(); \
+        WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, toCString(#x " == " #y, " (" #x " == ", __x, ", " #y " == ", __y, ")").data()); \
+        CRASH(); \
+    } while (false)
+
 #define FOR_EACH_UNSIGNED_LEB_TEST(macro) \
     /* Simple tests that use all the bits in the array */ \
-    macro(({ 0x07 }), 0, true, 0x7, 1) \
-    macro(({ 0x77 }), 0, true, 0x77, 1) \
-    macro(({ 0x80, 0x07 }), 0, true, 0x380, 2) \
-    macro(({ 0x89, 0x12 }), 0, true, 0x909, 2) \
-    macro(({ 0xf3, 0x85, 0x02 }), 0, true, 0x82f3, 3) \
-    macro(({ 0xf3, 0x85, 0xff, 0x74 }), 0, true, 0xe9fc2f3, 4) \
-    macro(({ 0xf3, 0x85, 0xff, 0xf4, 0x7f }), 0, true, 0xfe9fc2f3, 5) \
+    macro(({ 0x07 }), 0, true, 0x7lu, 1lu) \
+    macro(({ 0x77 }), 0, true, 0x77lu, 1lu) \
+    macro(({ 0x80, 0x07 }), 0, true, 0x380lu, 2lu) \
+    macro(({ 0x89, 0x12 }), 0, true, 0x909lu, 2lu) \
+    macro(({ 0xf3, 0x85, 0x02 }), 0, true, 0x82f3lu, 3lu) \
+    macro(({ 0xf3, 0x85, 0xff, 0x74 }), 0, true, 0xe9fc2f3lu, 4lu) \
+    macro(({ 0xf3, 0x85, 0xff, 0xf4, 0x7f }), 0, true, 0xfe9fc2f3lu, 5lu) \
     /* Test with extra trailing numbers */ \
-    macro(({ 0x07, 0x80 }), 0, true, 0x7, 1) \
-    macro(({ 0x07, 0x75 }), 0, true, 0x7, 1) \
-    macro(({ 0xf3, 0x85, 0xff, 0x74, 0x43 }), 0, true, 0xe9fc2f3, 4) \
-    macro(({ 0xf3, 0x85, 0xff, 0x74, 0x80 }), 0, true, 0xe9fc2f3, 4) \
+    macro(({ 0x07, 0x80 }), 0, true, 0x7lu, 1lu) \
+    macro(({ 0x07, 0x75 }), 0, true, 0x7lu, 1lu) \
+    macro(({ 0xf3, 0x85, 0xff, 0x74, 0x43 }), 0, true, 0xe9fc2f3lu, 4lu) \
+    macro(({ 0xf3, 0x85, 0xff, 0x74, 0x80 }), 0, true, 0xe9fc2f3lu, 4lu) \
     /* Test with preceeding numbers */ \
-    macro(({ 0xf3, 0x07 }), 1, true, 0x7, 2) \
-    macro(({ 0x03, 0x07 }), 1, true, 0x7, 2) \
-    macro(({ 0xf2, 0x53, 0x43, 0x67, 0x79, 0x77 }), 5, true, 0x77, 6) \
-    macro(({ 0xf2, 0x53, 0x43, 0xf7, 0x84, 0x77 }), 5, true, 0x77, 6) \
-    macro(({ 0xf2, 0x53, 0x43, 0xf3, 0x85, 0x02 }), 3, true, 0x82f3, 6) \
+    macro(({ 0xf3, 0x07 }), 1, true, 0x7lu, 2lu) \
+    macro(({ 0x03, 0x07 }), 1, true, 0x7lu, 2lu) \
+    macro(({ 0xf2, 0x53, 0x43, 0x67, 0x79, 0x77 }), 5, true, 0x77lu, 6lu) \
+    macro(({ 0xf2, 0x53, 0x43, 0xf7, 0x84, 0x77 }), 5, true, 0x77lu, 6ul) \
+    macro(({ 0xf2, 0x53, 0x43, 0xf3, 0x85, 0x02 }), 3, true, 0x82f3lu, 6lu) \
     /* Test in the middle */ \
-    macro(({ 0xf3, 0x07, 0x89 }), 1, true, 0x7, 2) \
-    macro(({ 0x03, 0x07, 0x23 }), 1, true, 0x7, 2) \
-    macro(({ 0xf2, 0x53, 0x43, 0x67, 0x79, 0x77, 0x43 }), 5, true, 0x77, 6) \
-    macro(({ 0xf2, 0x53, 0x43, 0xf7, 0x84, 0x77, 0xf9 }), 5, true, 0x77, 6) \
-    macro(({ 0xf2, 0x53, 0x43, 0xf3, 0x85, 0x02, 0xa4 }), 3, true, 0x82f3, 6) \
+    macro(({ 0xf3, 0x07, 0x89 }), 1, true, 0x7lu, 2lu) \
+    macro(({ 0x03, 0x07, 0x23 }), 1, true, 0x7lu, 2lu) \
+    macro(({ 0xf2, 0x53, 0x43, 0x67, 0x79, 0x77, 0x43 }), 5, true, 0x77lu, 6lu) \
+    macro(({ 0xf2, 0x53, 0x43, 0xf7, 0x84, 0x77, 0xf9 }), 5, true, 0x77lu, 6lu) \
+    macro(({ 0xf2, 0x53, 0x43, 0xf3, 0x85, 0x02, 0xa4 }), 3, true, 0x82f3lu, 6lu) \
     /* Test decode too long */ \
-    macro(({ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}), 0, false, 0x0, 0) \
-    macro(({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff}), 1, false, 0x0, 0) \
-    macro(({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff}), 0, false, 0x0, 0) \
+    macro(({ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}), 0, false, 0x0lu, 0lu) \
+    macro(({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff}), 1, false, 0x0lu, 0lu) \
+    macro(({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff}), 0, false, 0x0lu, 0lu) \
     /* Test decode off end of array */ \
-    macro(({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff}), 2, false, 0x0, 0) \
+    macro(({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff}), 2, false, 0x0lu, 0lu) \
 
 
 #define TEST_UNSIGNED_LEB_DECODE(init, startOffset, expectedStatus, expectedResult, expectedOffset) \
@@ -122,10 +134,10 @@
         size_t offset = startOffset; \
         uint32_t result; \
         bool status = decodeUInt32(vector.data(), vector.size(), offset, result); \
-        RELEASE_ASSERT(status == expectedStatus); \
+        CHECK_EQ(status, expectedStatus); \
         if (expectedStatus) { \
-            RELEASE_ASSERT(result == expectedResult); \
-            RELEASE_ASSERT(offset == expectedOffset); \
+            CHECK_EQ(result, expectedResult); \
+            CHECK_EQ(offset, expectedOffset); \
         } \
     };
 
@@ -132,36 +144,36 @@
 
 #define FOR_EACH_SIGNED_LEB_TEST(macro) \
     /* Simple tests that use all the bits in the array */ \
-    macro(({ 0x07 }), 0, true, 0x7, 1) \
-    macro(({ 0x77 }), 0, true, -0x9, 1) \
-    macro(({ 0x80, 0x07 }), 0, true, 0x380, 2) \
-    macro(({ 0x89, 0x12 }), 0, true, 0x909, 2) \
-    macro(({ 0xf3, 0x85, 0x02 }), 0, true, 0x82f3, 3) \
-    macro(({ 0xf3, 0x85, 0xff, 0x74 }), 0, true, 0xfe9fc2f3, 4) \
-    macro(({ 0xf3, 0x85, 0xff, 0xf4, 0x7f }), 0, true, 0xfe9fc2f3, 5) \
+    macro(({ 0x07 }), 0, true, 0x7, 1lu) \
+    macro(({ 0x77 }), 0, true, -0x9, 1lu) \
+    macro(({ 0x80, 0x07 }), 0, true, 0x380, 2lu) \
+    macro(({ 0x89, 0x12 }), 0, true, 0x909, 2lu) \
+    macro(({ 0xf3, 0x85, 0x02 }), 0, true, 0x82f3, 3lu) \
+    macro(({ 0xf3, 0x85, 0xff, 0x74 }), 0, true, 0xfe9fc2f3, 4lu) \
+    macro(({ 0xf3, 0x85, 0xff, 0xf4, 0x7f }), 0, true, 0xfe9fc2f3, 5lu) \
     /* Test with extra trailing numbers */ \
-    macro(({ 0x07, 0x80 }), 0, true, 0x7, 1) \
-    macro(({ 0x07, 0x75 }), 0, true, 0x7, 1) \
-    macro(({ 0xf3, 0x85, 0xff, 0x74, 0x43 }), 0, true, 0xfe9fc2f3, 4) \
-    macro(({ 0xf3, 0x85, 0xff, 0x74, 0x80 }), 0, true, 0xfe9fc2f3, 4) \
+    macro(({ 0x07, 0x80 }), 0, true, 0x7, 1lu) \
+    macro(({ 0x07, 0x75 }), 0, true, 0x7, 1lu) \
+    macro(({ 0xf3, 0x85, 0xff, 0x74, 0x43 }), 0, true, 0xfe9fc2f3, 4lu) \
+    macro(({ 0xf3, 0x85, 0xff, 0x74, 0x80 }), 0, true, 0xfe9fc2f3, 4lu) \
     /* Test with preceeding numbers */ \
-    macro(({ 0xf3, 0x07 }), 1, true, 0x7, 2) \
-    macro(({ 0x03, 0x07 }), 1, true, 0x7, 2) \
-    macro(({ 0xf2, 0x53, 0x43, 0x67, 0x79, 0x77 }), 5, true, -0x9, 6) \
-    macro(({ 0xf2, 0x53, 0x43, 0xf7, 0x84, 0x77 }), 5, true, -0x9, 6) \
-    macro(({ 0xf2, 0x53, 0x43, 0xf3, 0x85, 0x02 }), 3, true, 0x82f3, 6) \
+    macro(({ 0xf3, 0x07 }), 1, true, 0x7, 2lu) \
+    macro(({ 0x03, 0x07 }), 1, true, 0x7, 2lu) \
+    macro(({ 0xf2, 0x53, 0x43, 0x67, 0x79, 0x77 }), 5, true, -0x9, 6lu) \
+    macro(({ 0xf2, 0x53, 0x43, 0xf7, 0x84, 0x77 }), 5, true, -0x9, 6lu) \
+    macro(({ 0xf2, 0x53, 0x43, 0xf3, 0x85, 0x02 }), 3, true, 0x82f3, 6lu) \
     /* Test in the middle */ \
-    macro(({ 0xf3, 0x07, 0x89 }), 1, true, 0x7, 2) \
-    macro(({ 0x03, 0x07, 0x23 }), 1, true, 0x7, 2) \
-    macro(({ 0xf2, 0x53, 0x43, 0x67, 0x79, 0x77, 0x43 }), 5, true, -0x9, 6) \
-    macro(({ 0xf2, 0x53, 0x43, 0xf7, 0x84, 0x77, 0xf9 }), 5, true, -0x9, 6) \
-    macro(({ 0xf2, 0x53, 0x43, 0xf3, 0x85, 0x02, 0xa4 }), 3, true, 0x82f3, 6) \
+    macro(({ 0xf3, 0x07, 0x89 }), 1, true, 0x7, 2lu) \
+    macro(({ 0x03, 0x07, 0x23 }), 1, true, 0x7, 2lu) \
+    macro(({ 0xf2, 0x53, 0x43, 0x67, 0x79, 0x77, 0x43 }), 5, true, -0x9, 6lu) \
+    macro(({ 0xf2, 0x53, 0x43, 0xf7, 0x84, 0x77, 0xf9 }), 5, true, -0x9, 6lu) \
+    macro(({ 0xf2, 0x53, 0x43, 0xf3, 0x85, 0x02, 0xa4 }), 3, true, 0x82f3, 6lu) \
     /* Test decode too long */ \
-    macro(({ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}), 0, false, 0x0, 0) \
-    macro(({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff}), 1, false, 0x0, 0) \
-    macro(({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff}), 0, false, 0x0, 0) \
+    macro(({ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80}), 0, false, 0x0, 0lu) \
+    macro(({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff}), 1, false, 0x0, 0lu) \
+    macro(({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff}), 0, false, 0x0, 0lu) \
     /* Test decode off end of array */ \
-    macro(({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff}), 2, false, 0x0, 0) \
+    macro(({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff}), 2, false, 0x0, 0lu) \
 
 
 #define TEST_SIGNED_LEB_DECODE(init, startOffset, expectedStatus, expectedResult, expectedOffset) \
@@ -170,11 +182,11 @@
         size_t offset = startOffset; \
         int32_t result; \
         bool status = decodeInt32(vector.data(), vector.size(), offset, result); \
-        RELEASE_ASSERT(status == expectedStatus); \
+        CHECK_EQ(status, expectedStatus); \
         if (expectedStatus) { \
             int32_t expected = expectedResult; \
-            RELEASE_ASSERT(result == expected); \
-            RELEASE_ASSERT(offset == expectedOffset); \
+            CHECK_EQ(result, expected); \
+            CHECK_EQ(offset, expectedOffset); \
         } \
     };
 
@@ -246,7 +258,7 @@
         }
 
         // Test this doesn't crash.
-        RELEASE_ASSERT(invoke<int>(*plan.result[0], { }) == 5);
+        CHECK_EQ(invoke<int>(*plan.result[0], { }), 5);
     }
 
 
@@ -268,7 +280,7 @@
         }
 
         // Test this doesn't crash.
-        RELEASE_ASSERT(invoke<int>(*plan.result[0], { }) == 11);
+        CHECK_EQ(invoke<int>(*plan.result[0], { }), 11);
     }
     
     {
@@ -289,7 +301,7 @@
         }
 
         // Test this doesn't crash.
-        RELEASE_ASSERT(invoke<int>(*plan.result[0], { }) == 11);
+        CHECK_EQ(invoke<int>(*plan.result[0], { }), 11);
     }
 
     {
@@ -310,7 +322,7 @@
         }
 
         // Test this doesn't crash.
-        RELEASE_ASSERT(invoke<int>(*plan.result[0], { }) == 11);
+        CHECK_EQ(invoke<int>(*plan.result[0], { }), 11);
     }
 
     {
@@ -329,11 +341,187 @@
         }
 
         // 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());
+        CHECK_EQ(invoke<int>(*plan.result[0], { box(0), box(1) }), 1);
+        CHECK_EQ(invoke<int>(*plan.result[0], { box(100), box(1) }), 101);
+        CHECK_EQ(invoke<int>(*plan.result[0], { box(-1), box(1)}), 0);
+        CHECK_EQ(invoke<int>(*plan.result[0], { box(std::numeric_limits<int>::max()), box(1) }), std::numeric_limits<int>::min());
     }
+
+    {
+        // Generated from:
+        //    (module
+        //     (func "locals" (param $x i32) (result i32) (local $num i32)
+        //      (set_local $num (get_local $x))
+        //      (return (get_local $num))
+        //      )
+        //     )
+        Vector<uint8_t> vector = {
+            0x00, 0x61, 0x73, 0x6d, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x74, 0x79, 0x70, 0x65, 0x86, 0x80, 0x80,
+            0x00, 0x01, 0x40, 0x01, 0x01, 0x01, 0x01, 0x08, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
+            0x82, 0x80, 0x80, 0x00, 0x01, 0x00, 0x06, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x89, 0x80, 0x80,
+            0x00, 0x01, 0x00, 0x06, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x73, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x91,
+            0x80, 0x80, 0x00, 0x01, 0x8c, 0x80, 0x80, 0x00, 0x01, 0x01, 0x01, 0x14, 0x00, 0x15, 0x01, 0x14,
+            0x01, 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.
+        CHECK_EQ(invoke<int>(*plan.result[0], { box(0) }), 0);
+        CHECK_EQ(invoke<int>(*plan.result[0], { box(10) }), 10);
+    }
+
+    {
+        // Generated from:
+        //    (module
+        //     (func "dumb-mult" (param $x i32) (param $y i32) (result i32) (local $total i32) (local $i i32) (local $j i32)
+        //      (set_local $total (i32.const 0))
+        //      (set_local $i (i32.const 0))
+        //      (block
+        //       (loop
+        //        (br_if 1 (i32.eq (get_local $i) (get_local $x)))
+        //        (set_local $j (i32.const 0))
+        //        (set_local $i (i32.add (get_local $i) (i32.const 1)))
+        //        (loop
+        //         (br_if 1 (i32.eq (get_local $j) (get_local $y)))
+        //         (set_local $total (i32.add (get_local $total) (i32.const 1)))
+        //         (set_local $j (i32.add (get_local $j) (i32.const 1)))
+        //         (br 0)
+        //         )
+        //        )
+        //       )
+        //      (return (get_local $total))
+        //      )
+        //     )
+        Vector<uint8_t> vector = {
+            0x00, 0x61, 0x73, 0x6d, 0x0c, 0x00, 0x00, 0x00, 0x04, 0x74, 0x79, 0x70, 0x65, 0x86, 0x80, 0x80,
+            0x00, 0x01, 0x40, 0x01, 0x01, 0x01, 0x01, 0x08, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
+            0x82, 0x80, 0x80, 0x00, 0x01, 0x00, 0x06, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x86, 0x80, 0x80,
+            0x00, 0x01, 0x00, 0x03, 0x73, 0x75, 0x6d, 0x04, 0x63, 0x6f, 0x64, 0x65, 0xae, 0x80, 0x80, 0x00,
+            0x01, 0xa9, 0x80, 0x80, 0x00, 0x01, 0x01, 0x01, 0x10, 0x00, 0x15, 0x01, 0x02, 0x01, 0x14, 0x00,
+            0x10, 0x00, 0x4d, 0x07, 0x00, 0x00, 0x14, 0x00, 0x14, 0x01, 0x40, 0x15, 0x01, 0x14, 0x00, 0x10,
+            0x01, 0x41, 0x15, 0x00, 0x06, 0x00, 0x01, 0x0f, 0x0f, 0x14, 0x01, 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.
+        CHECK_EQ(invoke<int>(*plan.result[0], { box(0) }), 0);
+        CHECK_EQ(invoke<int>(*plan.result[0], { box(1) }), 1);
+        CHECK_EQ(invoke<int>(*plan.result[0], { box(2)}), 3);
+        CHECK_EQ(invoke<int>(*plan.result[0], { box(100) }), 5050);
+    }
+
+    {
+        // Generated from:
+        //    (module
+        //     (func "dumb-mult" (param $x i32) (param $y i32) (result i32) (local $total i32) (local $i i32) (local $j i32)
+        //      (set_local $total (i32.const 0))
+        //      (set_local $i (i32.const 0))
+        //      (block (loop
+        //              (br_if 1 (i32.eq (get_local $i) (get_local $x)))
+        //              (set_local $j (i32.const 0))
+        //              (set_local $i (i32.add (get_local $i) (i32.const 1)))
+        //              (loop
+        //               (br_if 1 (i32.eq (get_local $j) (get_local $y)))
+        //               (set_local $total (i32.add (get_local $total) (i32.const 1)))
+        //               (set_local $j (i32.add (get_local $j) (i32.const 1)))
+        //               (br 0)
+        //               )
+        //              ))
+        //      (return (get_local $total))
+        //      )
+        //     )
+        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, 0x06, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x8c, 0x80,
+            0x80, 0x00, 0x01, 0x00, 0x09, 0x64, 0x75, 0x6d, 0x62, 0x2d, 0x6d, 0x75, 0x6c, 0x74, 0x04, 0x63,
+            0x6f, 0x64, 0x65, 0xc7, 0x80, 0x80, 0x00, 0x01, 0xc2, 0x80, 0x80, 0x00, 0x01, 0x03, 0x01, 0x10,
+            0x00, 0x15, 0x02, 0x10, 0x00, 0x15, 0x03, 0x01, 0x02, 0x14, 0x03, 0x14, 0x00, 0x4d, 0x07, 0x00,
+            0x01, 0x10, 0x00, 0x15, 0x04, 0x14, 0x03, 0x10, 0x01, 0x40, 0x15, 0x03, 0x02, 0x14, 0x04, 0x14,
+            0x01, 0x4d, 0x07, 0x00, 0x01, 0x14, 0x02, 0x10, 0x01, 0x40, 0x15, 0x02, 0x14, 0x04, 0x10, 0x01,
+            0x40, 0x15, 0x04, 0x06, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x14, 0x02, 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.
+        CHECK_EQ(invoke<int>(*plan.result[0], { box(0), box(1) }), 0);
+        CHECK_EQ(invoke<int>(*plan.result[0], { box(1), box(0) }), 0);
+        CHECK_EQ(invoke<int>(*plan.result[0], { box(2), box(1) }), 2);
+        CHECK_EQ(invoke<int>(*plan.result[0], { box(1), box(2) }), 2);
+        CHECK_EQ(invoke<int>(*plan.result[0], { box(2), box(2) }), 4);
+        CHECK_EQ(invoke<int>(*plan.result[0], { box(2), box(6) }), 12);
+        CHECK_EQ(invoke<int>(*plan.result[0], { box(100), box(6) }), 600);
+        CHECK_EQ(invoke<int>(*plan.result[0], { box(100), box(100) }), 10000);
+    }
+
+    {
+        // Generated from:
+        //    (module
+        //     (func "dumb-less-than" (param $x i32) (param $y i32) (result i32)
+        //      (loop
+        //       (block
+        //        (block
+        //         (br_if 0 (i32.eq (get_local $x) (i32.const 0)))
+        //         (br 1)
+        //         )
+        //        (return (i32.const 1))
+        //        )
+        //       (block
+        //        (block
+        //         (br_if 0 (i32.eq (get_local $x) (get_local $y)))
+        //         (br 1)
+        //         )
+        //        (return (i32.const 0))
+        //        )
+        //       (set_local $x (i32.sub (get_local $x) (i32.const 1)))
+        //       (br 0)
+        //       )
+        //      )
+        //     )
+        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, 0x06, 0x65, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x91, 0x80,
+            0x80, 0x00, 0x01, 0x00, 0x0e, 0x64, 0x75, 0x6d, 0x62, 0x2d, 0x6c, 0x65, 0x73, 0x73, 0x2d, 0x74,
+            0x68, 0x61, 0x6e, 0x04, 0x63, 0x6f, 0x64, 0x65, 0xb9, 0x80, 0x80, 0x00, 0x01, 0xb4, 0x80, 0x80,
+            0x00, 0x00, 0x02, 0x01, 0x01, 0x14, 0x00, 0x14, 0x01, 0x4d, 0x07, 0x00, 0x00, 0x06, 0x00, 0x01,
+            0x0f, 0x10, 0x00, 0x09, 0x01, 0x0f, 0x01, 0x01, 0x14, 0x00, 0x10, 0x00, 0x4d, 0x07, 0x00, 0x00,
+            0x06, 0x00, 0x01, 0x0f, 0x10, 0x01, 0x09, 0x01, 0x0f, 0x14, 0x00, 0x10, 0x01, 0x41, 0x15, 0x00,
+            0x06, 0x00, 0x00, 0x0f, 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.
+        CHECK_EQ(invoke<int>(*plan.result[0], { box(0), box(1) }), 1);
+        CHECK_EQ(invoke<int>(*plan.result[0], { box(1), box(0) }), 0);
+        CHECK_EQ(invoke<int>(*plan.result[0], { box(2), box(1) }), 0);
+        CHECK_EQ(invoke<int>(*plan.result[0], { box(1), box(2) }), 1);
+        CHECK_EQ(invoke<int>(*plan.result[0], { box(2), box(2) }), 0);
+        CHECK_EQ(invoke<int>(*plan.result[0], { box(1), box(1) }), 0);
+        CHECK_EQ(invoke<int>(*plan.result[0], { box(2), box(6) }), 1);
+        CHECK_EQ(invoke<int>(*plan.result[0], { box(100), box(6) }), 0);
+    }
+
 }
 
 #endif // ENABLE(WEBASSEMBLY)

Modified: trunk/Source/_javascript_Core/wasm/WASMB3IRGenerator.cpp (205551 => 205552)


--- trunk/Source/_javascript_Core/wasm/WASMB3IRGenerator.cpp	2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/_javascript_Core/wasm/WASMB3IRGenerator.cpp	2016-09-07 17:12:08 UTC (rev 205552)
@@ -29,20 +29,24 @@
 #if ENABLE(WEBASSEMBLY)
 
 #include "B3BasicBlockInlines.h"
-#include "B3CallingConventions.h"
+#include "B3FixSSA.h"
+#include "B3Validate.h"
 #include "B3ValueInlines.h"
 #include "B3Variable.h"
 #include "B3VariableValue.h"
 #include "VirtualRegister.h"
+#include "WASMCallingConvention.h"
 #include "WASMFunctionParser.h"
 #include <wtf/Optional.h>
 
-namespace JSC {
+namespace JSC { namespace WASM {
 
-namespace WASM {
+namespace {
 
 using namespace B3;
 
+const bool verbose = false;
+
 inline B3::Opcode toB3Op(BinaryOpType op)
 {
     switch (op) {
@@ -64,8 +68,66 @@
 }
 
 class B3IRGenerator {
+private:
+    class LazyBlock {
+    public:
+        explicit operator bool() { return !!m_block; }
+
+        BasicBlock* get(Procedure& proc)
+        {
+            if (!m_block)
+                m_block = proc.addBlock();
+            return m_block;
+        }
+
+        void dump(PrintStream& out) const
+        {
+            if (m_block)
+                out.print(*m_block);
+            else
+                out.print("Uninitialized");
+        }
+
+    private:
+        BasicBlock* m_block { nullptr };
+    };
+
+    struct ControlData {
+        ControlData(Optional<Vector<Variable*>>&& stack, BasicBlock* loopTarget = nullptr)
+            : loopTarget(loopTarget)
+            , stack(stack)
+        {
+        }
+
+        void dump(PrintStream& out) const
+        {
+            out.print("Continuation: ", continuation, ", Target: ");
+            if (loopTarget)
+                out.print(*loopTarget);
+            else
+                out.print(continuation);
+        }
+
+        BasicBlock* targetBlockForBranch(Procedure& proc)
+        {
+            if (loopTarget)
+                return loopTarget;
+            return continuation.get(proc);
+        }
+
+        bool isLoop() { return !!loopTarget; }
+
+        // We use a LazyBlock for the continuation since B3::validate does not like orphaned blocks. Note,
+        // it's possible to create an orphaned block by doing something like (block (return (...))). In
+        // that example, if we eagerly allocate a BasicBlock for the continuation it will never be reachable.
+        LazyBlock continuation;
+        BasicBlock* loopTarget;
+        Optional<Vector<Variable*>> stack;
+    };
+
 public:
     typedef Value* ExpressionType;
+    static constexpr ExpressionType emptyExpression = nullptr;
 
     B3IRGenerator(Procedure&);
 
@@ -74,25 +136,34 @@
     ExpressionType addConstant(Type, uint64_t);
 
     bool WARN_UNUSED_RETURN getLocal(uint32_t index, ExpressionType& result);
+    bool WARN_UNUSED_RETURN setLocal(uint32_t index, ExpressionType value);
 
     bool WARN_UNUSED_RETURN binaryOp(BinaryOpType, ExpressionType left, ExpressionType right, ExpressionType& result);
     bool WARN_UNUSED_RETURN unaryOp(UnaryOpType, ExpressionType arg, ExpressionType& result);
 
     bool WARN_UNUSED_RETURN addBlock();
-    bool WARN_UNUSED_RETURN endBlock(Vector<ExpressionType>& expressionStack);
+    bool WARN_UNUSED_RETURN addLoop();
+    bool WARN_UNUSED_RETURN endBlock(Vector<ExpressionType, 1>& expressionStack);
+
     bool WARN_UNUSED_RETURN addReturn(const Vector<ExpressionType, 1>& returnValues);
+    bool WARN_UNUSED_RETURN addBranch(ExpressionType condition, const Vector<ExpressionType, 1>& returnValues, uint32_t target);
 
+    void dumpGraphAndControlStack();
+
 private:
-    Optional<Vector<Variable*>>& stackForControlLevel(unsigned);
-    BasicBlock* blockForControlLevel(unsigned);
+    ControlData& controlDataForLevel(unsigned);
     void unify(Variable* target, const ExpressionType source);
-    Vector<Variable*> initializeIncommingTypes(BasicBlock*, const Vector<ExpressionType>&);
-    void unifyValuesWithLevel(const Vector<ExpressionType>& resultStack, unsigned);
+    Vector<Variable*> initializeIncommingTypes(BasicBlock*, const Vector<ExpressionType, 1>&);
+    void unifyValuesWithBlock(const Vector<ExpressionType, 1>& resultStack, Optional<Vector<Variable*>>& stack, BasicBlock* target);
 
+public:
+    unsigned unreachable { 0 };
+
+private:
     Procedure& m_proc;
     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<ControlData> m_controlStack;
     Vector<Variable*> m_locals;
 };
 
@@ -106,12 +177,11 @@
 {
     m_locals.reserveCapacity(m_locals.size() + count);
     for (uint32_t i = 0; i < count; ++i)
-        m_locals.append(m_proc.addVariable(type));
+        m_locals.append(m_proc.addVariable(toB3Type(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(),
@@ -129,6 +199,13 @@
     return true;
 }
 
+bool WARN_UNUSED_RETURN B3IRGenerator::setLocal(uint32_t index, ExpressionType value)
+{
+    ASSERT(m_locals[index]);
+    m_currentBlock->appendNew<VariableValue>(m_proc, B3::Set, Origin(), m_locals[index], value);
+    return true;
+}
+
 bool B3IRGenerator::unaryOp(UnaryOpType op, ExpressionType arg, ExpressionType& result)
 {
     result = m_currentBlock->appendNew<Value>(m_proc, toB3Op(op), Origin(), arg);
@@ -160,12 +237,50 @@
 
 bool B3IRGenerator::addBlock()
 {
-    m_controlStack.append(std::make_pair(m_proc.addBlock(), Nullopt));
+    if (unreachable) {
+        unreachable++;
+        return true;
+    }
+
+    if (verbose) {
+        dataLogLn("Adding block");
+        dumpGraphAndControlStack();
+    }
+    m_controlStack.append(ControlData(Nullopt));
+
     return true;
 }
 
-bool B3IRGenerator::endBlock(Vector<ExpressionType>& expressionStack)
+bool B3IRGenerator::addLoop()
 {
+    if (unreachable) {
+        unreachable++;
+        return true;
+    }
+
+    if (verbose) {
+        dataLogLn("Adding loop");
+        dumpGraphAndControlStack();
+    }
+    BasicBlock* body = m_proc.addBlock();
+    m_currentBlock->appendNewControlValue(m_proc, Jump, Origin(), body);
+    body->addPredecessor(m_currentBlock);
+    m_currentBlock = body;
+    m_controlStack.append(ControlData(Vector<Variable*>(), body));
+    return true;
+}
+
+bool B3IRGenerator::endBlock(Vector<ExpressionType, 1>& expressionStack)
+{
+    if (unreachable > 1) {
+        unreachable--;
+        return true;
+    }
+
+    if (verbose) {
+        dataLogLn("Falling out of block");
+        dumpGraphAndControlStack();
+    }
     // This means that we are exiting the function.
     if (!m_controlStack.size()) {
         // FIXME: Should this require the stack is empty? It's not clear from the current spec.
@@ -172,33 +287,86 @@
         return !expressionStack.size();
     }
 
-    unifyValuesWithLevel(expressionStack, 0);
+    ControlData data = ""
+    if (unreachable) {
+        // If nothing targets the continuation of the current block then we don't want to create
+        // an orphaned BasicBlock since it can't be reached by fallthrough.
+        if (data.continuation) {
+            m_currentBlock = data.continuation.get(m_proc);
+            unreachable--;
+        }
+        return true;
+    }
 
-    m_currentBlock = m_controlStack.takeLast().first;
+    BasicBlock* continuation = data.continuation.get(m_proc);
+    unifyValuesWithBlock(expressionStack, data.stack, continuation);
+    m_currentBlock->appendNewControlValue(m_proc, Jump, Origin(), continuation);
+    continuation->addPredecessor(m_currentBlock);
+    m_currentBlock = continuation;
     return true;
 }
 
 bool B3IRGenerator::addReturn(const Vector<ExpressionType, 1>& returnValues)
 {
+    if (unreachable)
+        return true;
+
+    if (verbose) {
+        dataLogLn("Adding return");
+        dumpGraphAndControlStack();
+    }
+
     ASSERT(returnValues.size() <= 1);
     if (returnValues.size())
         m_currentBlock->appendNewControlValue(m_proc, B3::Return, Origin(), returnValues[0]);
     else
         m_currentBlock->appendNewControlValue(m_proc, B3::Return, Origin());
+    unreachable = 1;
     return true;
 }
 
+bool B3IRGenerator::addBranch(ExpressionType condition, const Vector<ExpressionType, 1>& returnValues, uint32_t level)
+{
+    if (unreachable)
+        return true;
+
+    ASSERT(level < m_controlStack.size());
+    ControlData& data = ""
+    if (verbose) {
+        dataLogLn("Adding Branch from: ",  *m_currentBlock, " targeting: ", level, " with data: ", data);
+        dumpGraphAndControlStack();
+    }
+
+
+    BasicBlock* target = data.targetBlockForBranch(m_proc);
+    unifyValuesWithBlock(returnValues, data.stack, target);
+    if (condition) {
+        BasicBlock* continuation = m_proc.addBlock();
+        m_currentBlock->appendNew<Value>(m_proc, B3::Branch, Origin(), condition);
+        m_currentBlock->setSuccessors(FrequentedBlock(target), FrequentedBlock(continuation));
+        target->addPredecessor(m_currentBlock);
+        continuation->addPredecessor(m_currentBlock);
+        m_currentBlock = continuation;
+    } else {
+        m_currentBlock->appendNewControlValue(m_proc, Jump, Origin(), FrequentedBlock(target));
+        target->addPredecessor(m_currentBlock);
+        unreachable = 1;
+    }
+
+    return true;
+}
+
 void B3IRGenerator::unify(Variable* variable, ExpressionType source)
 {
     m_currentBlock->appendNew<VariableValue>(m_proc, Set, Origin(), variable, source);
 }
 
-Vector<Variable*> B3IRGenerator::initializeIncommingTypes(BasicBlock* block, const Vector<ExpressionType>& source)
+Vector<Variable*> B3IRGenerator::initializeIncommingTypes(BasicBlock* block, const Vector<ExpressionType, 1>& source)
 {
     Vector<Variable*> result;
     result.reserveInitialCapacity(source.size());
     for (ExpressionType expr : source) {
-        ASSERT(expr->type() != Void);
+        ASSERT(expr->type() != B3::Void);
         Variable* var = m_proc.addVariable(expr->type());
         result.append(var);
         block->appendNew<VariableValue>(m_proc, B3::Get, Origin(), var);
@@ -207,32 +375,37 @@
     return result;
 }
 
-void B3IRGenerator::unifyValuesWithLevel(const Vector<ExpressionType>& resultStack, unsigned level)
+void B3IRGenerator::unifyValuesWithBlock(const Vector<ExpressionType, 1>& resultStack, Optional<Vector<Variable*>>& stack, BasicBlock* target)
 {
-    ASSERT(level < m_controlStack.size());
-
-    Optional<Vector<Variable*>>& expectedStack = stackForControlLevel(level);
-    if (!expectedStack) {
-        expectedStack = initializeIncommingTypes(blockForControlLevel(level), resultStack);
+    if (!stack) {
+        stack = initializeIncommingTypes(target, resultStack);
         return;
     }
 
-    ASSERT(expectedStack.value().size() != resultStack.size());
+    ASSERT(stack.value().size() == resultStack.size());
 
     for (size_t i = 0; i < resultStack.size(); ++i)
-        unify(expectedStack.value()[i], resultStack[i]);
+        unify(stack.value()[i], resultStack[i]);
 }
     
-Optional<Vector<Variable*>>& B3IRGenerator::stackForControlLevel(unsigned level)
+B3IRGenerator::ControlData& B3IRGenerator::controlDataForLevel(unsigned level)
 {
-    return m_controlStack[m_controlStack.size() - 1 - level].second;
+    return m_controlStack[m_controlStack.size() - 1 - level];
 }
 
-BasicBlock* B3IRGenerator::blockForControlLevel(unsigned level)
+void B3IRGenerator::dumpGraphAndControlStack()
 {
-    return m_controlStack[m_controlStack.size() - 1 - level].first;
+    dataLogLn("Processing Graph:");
+    dataLog(m_proc);
+    dataLogLn("With current block:", *m_currentBlock);
+    dataLogLn("With Control Stack:");
+    for (unsigned i = 0; i < m_controlStack.size(); ++i)
+        dataLogLn("[", i, "] ", m_controlStack[i]);
+    dataLogLn("\n");
 }
 
+} // anonymous namespace
+
 std::unique_ptr<Compilation> parseAndCompile(VM& vm, Vector<uint8_t>& source, FunctionInformation info, unsigned optLevel)
 {
     Procedure procedure;
@@ -241,11 +414,14 @@
     if (!parser.parse())
         RELEASE_ASSERT_NOT_REACHED();
 
+    validate(procedure, "After parsing:\n");
+
+    fixSSA(procedure);
+    if (verbose)
+        dataLog("Post SSA: ", procedure);
     return std::make_unique<Compilation>(vm, procedure, optLevel);
 }
 
-} // namespace WASM
+} } // namespace JSC::WASM
 
-} // namespace JSC
-
 #endif // ENABLE(WEBASSEMBLY)

Modified: trunk/Source/_javascript_Core/wasm/WASMB3IRGenerator.h (205551 => 205552)


--- trunk/Source/_javascript_Core/wasm/WASMB3IRGenerator.h	2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/_javascript_Core/wasm/WASMB3IRGenerator.h	2016-09-07 17:12:08 UTC (rev 205552)
@@ -31,14 +31,10 @@
 #include "VM.h"
 #include "WASMFormat.h"
 
-namespace JSC {
+namespace JSC { namespace WASM {
 
-namespace WASM {
-
 std::unique_ptr<B3::Compilation> parseAndCompile(VM&, Vector<uint8_t>&, FunctionInformation, unsigned optLevel = 1);
 
-} // namespace WASM
+} } // namespace JSC::WASM
 
-} // namespace JSC
-
 #endif // ENABLE(WEBASSEMBLY)

Copied: trunk/Source/_javascript_Core/wasm/WASMCallingConvention.cpp (from rev 205550, trunk/Source/_javascript_Core/B3CallingConventions.cpp) (0 => 205552)


--- trunk/Source/_javascript_Core/wasm/WASMCallingConvention.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/wasm/WASMCallingConvention.cpp	2016-09-07 17:12:08 UTC (rev 205552)
@@ -0,0 +1,48 @@
+/*
+ * 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 "WASMCallingConvention.h"
+
+#if ENABLE(WEBASSEMBLY)
+
+#include <wtf/NeverDestroyed.h>
+
+namespace JSC { namespace WASM {
+
+const JSCCallingConvention& jscCallingConvention()
+{
+    static LazyNeverDestroyed<JSCCallingConvention> staticJSCCallingConvention;
+    static std::once_flag staticJSCCallingConventionFlag;
+    std::call_once(staticJSCCallingConventionFlag, [] () {
+        staticJSCCallingConvention.construct(Vector<GPRReg>(), RegisterSet::calleeSaveRegisters());
+    });
+
+    return staticJSCCallingConvention;
+}
+
+} } // namespace JSC::WASM
+
+#endif // ENABLE(B3_JIT)

Copied: trunk/Source/_javascript_Core/wasm/WASMCallingConvention.h (from rev 205550, trunk/Source/_javascript_Core/B3CallingConventions.h) (0 => 205552)


--- trunk/Source/_javascript_Core/wasm/WASMCallingConvention.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/wasm/WASMCallingConvention.h	2016-09-07 17:12:08 UTC (rev 205552)
@@ -0,0 +1,90 @@
+/*
+ * 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 "B3ArgumentRegValue.h"
+#include "B3BasicBlock.h"
+#include "B3Const64Value.h"
+#include "B3MemoryValue.h"
+#include "CallFrame.h"
+#include "RegisterSet.h"
+#include "WASMFormat.h"
+
+namespace JSC { namespace WASM {
+
+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, B3::Procedure& proc, B3::BasicBlock* block, B3::Origin origin, const Functor& functor) const
+    {
+        unsigned currentOffset = headerSize;
+        B3::Value* framePointer = block->appendNew<B3::Value>(proc, B3::FramePointer, origin);
+
+        for (unsigned i = 0; i < argumentTypes.size(); ++i) {
+            B3::Value* argument;
+            if (i < m_registerArguments.size())
+                argument = block->appendNew<B3::ArgumentRegValue>(proc, origin, m_registerArguments[i]);
+            else {
+                B3::Value* address = block->appendNew<B3::Value>(proc, B3::Add, origin, framePointer,
+                    block->appendNew<B3::Const64Value>(proc, origin, currentOffset));
+                argument = block->appendNew<B3::MemoryValue>(proc, B3::Load, toB3Type(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;
+
+const JSCCallingConvention& jscCallingConvention();
+
+} } // namespace JSC::WASM
+
+#endif // ENABLE(WEBASSEMBLY)

Modified: trunk/Source/_javascript_Core/wasm/WASMFormat.h (205551 => 205552)


--- trunk/Source/_javascript_Core/wasm/WASMFormat.h	2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/_javascript_Core/wasm/WASMFormat.h	2016-09-07 17:12:08 UTC (rev 205552)
@@ -54,17 +54,48 @@
 
 namespace WASM {
 
-using B3::Type;
-using B3::Int32;
-using B3::Int64;
-using B3::Float;
-using B3::Double;
+enum Type : uint8_t {
+    I32 = 1,
+    I64,
+    F32,
+    F64,
+    LastValueType = F64,
+    Void
+};
 
-static_assert(Int32 == 0, "WASM needs B3::Type::Int32 to have the value 0");
-static_assert(Int64 == 1, "WASM needs B3::Type::Int64 to have the value 1");
-static_assert(Float == 2, "WASM needs B3::Type::Float to have the value 2");
-static_assert(Double == 3, "WASM needs B3::Type::Double to have the value 3");
+static_assert(I32 == 1, "WASM needs I32 to have the value 1");
+static_assert(I64 == 2, "WASM needs I64 to have the value 2");
+static_assert(F32 == 3, "WASM needs F32 to have the value 3");
+static_assert(F64 == 4, "WASM needs F64 to have the value 4");
 
+inline B3::Type toB3Type(Type type)
+{
+    switch (type) {
+    case I32: return B3::Int32;
+    case I64: return B3::Int64;
+    case F32: return B3::Float;
+    case F64: return B3::Double;
+    case Void: return B3::Void;
+    default: break;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
+inline bool isValueType(Type type)
+{
+    switch (type) {
+    case I32:
+    case I64:
+    case F32:
+    case F64:
+        return true;
+    default:
+        break;
+    }
+    return false;
+}
+
+
 struct Signature {
     Type returnType;
     Vector<Type> arguments;
@@ -95,8 +126,6 @@
     size_t end;
 };
 
-} // namespace WASM
+} } // namespace JSC::WASM
 
-} // namespace JSC
-
 #endif // ENABLE(WEBASSEMBLY)

Modified: trunk/Source/_javascript_Core/wasm/WASMFunctionParser.h (205551 => 205552)


--- trunk/Source/_javascript_Core/wasm/WASMFunctionParser.h	2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/_javascript_Core/wasm/WASMFunctionParser.h	2016-09-07 17:12:08 UTC (rev 205552)
@@ -30,10 +30,8 @@
 #include "WASMParser.h"
 #include <wtf/DataLog.h>
 
-namespace JSC {
+namespace JSC { namespace WASM {
 
-namespace WASM {
-
 template<typename Context>
 class FunctionParser : public Parser {
 public:
@@ -53,7 +51,7 @@
     Optional<Vector<ExpressionType>>& stackForControlLevel(unsigned level);
 
     Context& m_context;
-    Vector<ExpressionType> m_expressionStack;
+    Vector<ExpressionType, 1> m_expressionStack;
 };
 
 template<typename Context>
@@ -72,8 +70,8 @@
         return false;
 
     for (uint32_t i = 0; i < localCount; ++i) {
-        uint32_t numberOfLocalsWithType;
-        if (!parseUInt32(numberOfLocalsWithType))
+        uint32_t numberOfLocals;
+        if (!parseVarUInt32(numberOfLocals))
             return false;
 
         Type typeOfLocal;
@@ -80,6 +78,7 @@
         if (!parseValueType(typeOfLocal))
             return false;
 
+        m_context.addLocal(typeOfLocal, numberOfLocals);
     }
 
     return parseBlock();
@@ -109,11 +108,14 @@
 template<typename Context>
 bool FunctionParser<Context>::parseExpression(OpType op)
 {
+    if (m_context.unreachable && !isControlOp(op))
+        return true;
+
     switch (op) {
 #define CREATE_CASE(name, id, b3op) case name:
     FOR_EACH_WASM_BINARY_OP(CREATE_CASE) {
+        ExpressionType right = m_expressionStack.takeLast();
         ExpressionType left = m_expressionStack.takeLast();
-        ExpressionType right = m_expressionStack.takeLast();
         ExpressionType result;
         if (!m_context.binaryOp(static_cast<BinaryOpType>(op), left, right, result))
             return false;
@@ -135,7 +137,7 @@
         uint32_t constant;
         if (!parseVarUInt32(constant))
             return false;
-        m_expressionStack.append(m_context.addConstant(Int32, constant));
+        m_expressionStack.append(m_context.addConstant(I32, constant));
         return true;
     }
 
@@ -151,6 +153,14 @@
         return true;
     }
 
+    case OpType::SetLocal: {
+        uint32_t index;
+        if (!parseVarUInt32(index))
+            return false;
+        ExpressionType value = m_expressionStack.takeLast();
+        return m_context.setLocal(index, value);
+    }
+
     case OpType::Block: {
         if (!m_context.addBlock())
             return false;
@@ -157,6 +167,34 @@
         return parseBlock();
     }
 
+    case OpType::Loop: {
+        if (!m_context.addLoop())
+            return false;
+        return parseBlock();
+    }
+
+    case OpType::Branch:
+    case OpType::BranchIf: {
+        uint32_t arity;
+        if (!parseVarUInt32(arity) || arity > m_expressionStack.size())
+            return false;
+
+        uint32_t target;
+        if (!parseVarUInt32(target))
+            return false;
+
+        ExpressionType condition = Context::emptyExpression;
+        if (op == OpType::BranchIf)
+            condition = m_expressionStack.takeLast();
+
+
+        Vector<ExpressionType, 1> values(arity);
+        for (unsigned i = arity; i; i--)
+            values[i-1] = m_expressionStack.takeLast();
+
+        return m_context.addBranch(condition, values, target);
+    }
+
     case OpType::Return: {
         uint8_t returnCount;
         if (!parseVarUInt1(returnCount))
@@ -177,8 +215,6 @@
     return false;
 }
 
-} // namespace WASM
+} } // namespace JSC::WASM
 
-} // namespace JSC
-
 #endif // ENABLE(WEBASSEMBLY)

Modified: trunk/Source/_javascript_Core/wasm/WASMModuleParser.cpp (205551 => 205552)


--- trunk/Source/_javascript_Core/wasm/WASMModuleParser.cpp	2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/_javascript_Core/wasm/WASMModuleParser.cpp	2016-09-07 17:12:08 UTC (rev 205552)
@@ -32,10 +32,8 @@
 #include "WASMOps.h"
 #include "WASMSections.h"
 
-namespace JSC {
+namespace JSC { namespace WASM {
 
-namespace WASM {
-
 static const bool verbose = false;
 
 bool ModuleParser::parse()
@@ -163,9 +161,9 @@
         argumentTypes.resize(argumentCount);
 
         for (unsigned i = 0; i < argumentCount; ++i) {
-            if (!parseUInt7(type) || type >= static_cast<uint8_t>(Type::LastValueType))
+            if (!parseUInt7(type) || !isValueType(static_cast<Type>(type)))
                 return false;
-            argumentTypes.append(static_cast<Type>(type));
+            argumentTypes[i] = static_cast<Type>(type);
         }
 
         if (!parseVarUInt1(type))
@@ -233,8 +231,6 @@
     return true;
 }
 
-} // namespace WASM
+} } // namespace JSC::WASM
 
-} // namespace JSC
-
 #endif // ENABLE(WEBASSEMBLY)

Modified: trunk/Source/_javascript_Core/wasm/WASMModuleParser.h (205551 => 205552)


--- trunk/Source/_javascript_Core/wasm/WASMModuleParser.h	2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/_javascript_Core/wasm/WASMModuleParser.h	2016-09-07 17:12:08 UTC (rev 205552)
@@ -31,10 +31,8 @@
 #include "WASMParser.h"
 #include <wtf/Vector.h>
 
-namespace JSC {
+namespace JSC { namespace WASM {
 
-namespace WASM {
-
 class ModuleParser : public Parser {
 public:
 
@@ -61,8 +59,6 @@
     Vector<Signature> m_signatures;
 };
 
-} // namespace WASM
+} } // namespace JSC::WASM
 
-} // namespace JSC
-
 #endif // ENABLE(WEBASSEMBLY)

Modified: trunk/Source/_javascript_Core/wasm/WASMOps.h (205551 => 205552)


--- trunk/Source/_javascript_Core/wasm/WASMOps.h	2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/_javascript_Core/wasm/WASMOps.h	2016-09-07 17:12:08 UTC (rev 205552)
@@ -27,16 +27,18 @@
 
 #if ENABLE(WEBASSEMBLY)
 
-namespace JSC {
+namespace JSC { namespace WASM {
 
-namespace WASM {
-
 #define FOR_EACH_WASM_SPECIAL_OP(macro) \
     macro(I32Const, 0x10, NA) \
-    macro(GetLocal, 0x14, NA)
+    macro(GetLocal, 0x14, NA) \
+    macro(SetLocal, 0x15, NA)
 
 #define FOR_EACH_WASM_CONTROL_FLOW_OP(macro) \
     macro(Block, 0x01, NA) \
+    macro(Loop, 0x02, NA) \
+    macro(Branch, 0x06, NA) \
+    macro(BranchIf, 0x07, NA) \
     macro(Return, 0x09, NA) \
     macro(End, 0x0f, NA)
 
@@ -121,8 +123,19 @@
 
 #undef CREATE_ENUM_VALUE
 
-} // namespace WASM
+inline bool isControlOp(OpType op)
+{
+    switch (op) {
+#define CREATE_CASE(name, id, b3op) case OpType::name:
+    FOR_EACH_WASM_CONTROL_FLOW_OP(CREATE_CASE)
+        return true;
+#undef CREATE_CASE
+    default:
+        break;
+    }
+    return false;
+}
 
-} // namespace JSC
+} } // namespace JSC::WASM
 
 #endif // ENABLE(WEBASSEMBLY)

Modified: trunk/Source/_javascript_Core/wasm/WASMParser.h (205551 => 205552)


--- trunk/Source/_javascript_Core/wasm/WASMParser.h	2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/_javascript_Core/wasm/WASMParser.h	2016-09-07 17:12:08 UTC (rev 205552)
@@ -34,10 +34,8 @@
 #include "WASMSections.h"
 #include <wtf/LEBDecoder.h>
 
-namespace JSC {
+namespace JSC { namespace WASM {
 
-namespace WASM {
-
 class Parser {
 protected:
     Parser(const Vector<uint8_t>&, size_t start, size_t end);
@@ -127,8 +125,6 @@
     return true;
 }
 
-} // namespace WASM
+} } // namespace JSC::WASM
 
-} // namespace JSC
-
 #endif // ENABLE(WEBASSEMBLY)

Modified: trunk/Source/_javascript_Core/wasm/WASMPlan.cpp (205551 => 205552)


--- trunk/Source/_javascript_Core/wasm/WASMPlan.cpp	2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/_javascript_Core/wasm/WASMPlan.cpp	2016-09-07 17:12:08 UTC (rev 205552)
@@ -33,10 +33,8 @@
 #include "WASMModuleParser.h"
 #include <wtf/DataLog.h>
 
-namespace JSC {
+namespace JSC { namespace WASM {
 
-namespace WASM {
-
 static const bool verbose = false;
 
 Plan::Plan(VM& vm, Vector<uint8_t> source)
@@ -59,8 +57,6 @@
     }
 }
 
-} // namespace WASM
+} } // namespace JSC::WASM
 
-} // namespace JSC
-
 #endif // ENABLE(WEBASSEMBLY)

Modified: trunk/Source/_javascript_Core/wasm/WASMPlan.h (205551 => 205552)


--- trunk/Source/_javascript_Core/wasm/WASMPlan.h	2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/_javascript_Core/wasm/WASMPlan.h	2016-09-07 17:12:08 UTC (rev 205552)
@@ -48,8 +48,6 @@
     Vector<std::unique_ptr<B3::Compilation>> result;
 };
 
-} // namespace WASM
+} } // namespace JSC::WASM
 
-} // namespace JSC
-
 #endif // ENABLE(WEBASSEMBLY)

Modified: trunk/Source/_javascript_Core/wasm/WASMSections.cpp (205551 => 205552)


--- trunk/Source/_javascript_Core/wasm/WASMSections.cpp	2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/_javascript_Core/wasm/WASMSections.cpp	2016-09-07 17:12:08 UTC (rev 205552)
@@ -31,10 +31,8 @@
 #include <wtf/DataLog.h>
 #include <wtf/text/WTFString.h>
 
-namespace JSC {
+namespace JSC { namespace WASM {
 
-namespace WASM {
-
 struct SectionData {
     unsigned length;
     const char* name;
@@ -62,8 +60,6 @@
     return Sections::Unknown;
 }
 
-} // namespace WASM
+} } // namespace JSC::WASM
 
-} // namespace JSC
-
 #endif // ENABLE(WEBASSEMBLY)

Modified: trunk/Source/_javascript_Core/wasm/WASMSections.h (205551 => 205552)


--- trunk/Source/_javascript_Core/wasm/WASMSections.h	2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/_javascript_Core/wasm/WASMSections.h	2016-09-07 17:12:08 UTC (rev 205552)
@@ -27,10 +27,8 @@
 
 #if ENABLE(WEBASSEMBLY)
 
-namespace JSC {
+namespace JSC { namespace WASM {
 
-namespace WASM {
-
 // These should be in the order that we expect them to be in the binary.
 #define FOR_EACH_WASM_SECTION_TYPE(macro) \
     macro(FunctionTypes, "type") \
@@ -56,8 +54,6 @@
     }
 };
 
-} // namespace WASM
+} } // namespace JSC::WASM
 
-} // namespace JSC
-
 #endif // ENABLE(WEBASSEMBLY)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to