<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[205552] trunk/Source/JavaScriptCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/205552">205552</a></dd>
<dt>Author</dt> <dd>keith_miller@apple.com</dd>
<dt>Date</dt> <dd>2016-09-07 10:12:08 -0700 (Wed, 07 Sep 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>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.
* JavaScriptCore.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/JavaScriptCore/B3CallingConventions.cpp.
(JSC::WASM::jscCallingConvention):
* wasm/WASMCallingConvention.h: Renamed from Source/JavaScriptCore/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&lt;Context&gt;::parse):
(JSC::WASM::FunctionParser&lt;Context&gt;::parseExpression):
* wasm/WASMModuleParser.cpp:
(JSC::WASM::ModuleParser::parseFunctionTypes):
* wasm/WASMOps.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreCMakeListstxt">trunk/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3B3Typeh">trunk/Source/JavaScriptCore/b3/B3Type.h</a></li>
<li><a href="#trunkSourceJavaScriptCoretestWASMcpp">trunk/Source/JavaScriptCore/testWASM.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWASMB3IRGeneratorcpp">trunk/Source/JavaScriptCore/wasm/WASMB3IRGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWASMB3IRGeneratorh">trunk/Source/JavaScriptCore/wasm/WASMB3IRGenerator.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWASMFormath">trunk/Source/JavaScriptCore/wasm/WASMFormat.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWASMFunctionParserh">trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWASMModuleParsercpp">trunk/Source/JavaScriptCore/wasm/WASMModuleParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWASMModuleParserh">trunk/Source/JavaScriptCore/wasm/WASMModuleParser.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWASMOpsh">trunk/Source/JavaScriptCore/wasm/WASMOps.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWASMParserh">trunk/Source/JavaScriptCore/wasm/WASMParser.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWASMPlancpp">trunk/Source/JavaScriptCore/wasm/WASMPlan.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWASMPlanh">trunk/Source/JavaScriptCore/wasm/WASMPlan.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWASMSectionscpp">trunk/Source/JavaScriptCore/wasm/WASMSections.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWASMSectionsh">trunk/Source/JavaScriptCore/wasm/WASMSections.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCorewasmWASMCallingConventioncpp">trunk/Source/JavaScriptCore/wasm/WASMCallingConvention.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWASMCallingConventionh">trunk/Source/JavaScriptCore/wasm/WASMCallingConvention.h</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreB3CallingConventionscpp">trunk/Source/JavaScriptCore/B3CallingConventions.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreB3CallingConventionsh">trunk/Source/JavaScriptCore/B3CallingConventions.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreB3CallingConventionscpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/B3CallingConventions.cpp (205551 => 205552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/B3CallingConventions.cpp        2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/JavaScriptCore/B3CallingConventions.cpp        2016-09-07 17:12:08 UTC (rev 205552)
</span><span class="lines">@@ -1,52 +0,0 @@
</span><del>-/*
- * 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 &quot;config.h&quot;
-#include &quot;B3CallingConventions.h&quot;
-
-#include &lt;wtf/NeverDestroyed.h&gt;
-
-#if ENABLE(B3_JIT)
-
-namespace JSC {
-
-namespace B3 {
-
-JSCCallingConvention&amp; jscCallingConvention()
-{
-    static LazyNeverDestroyed&lt;JSCCallingConvention&gt; staticJSCCallingConvention;
-    static std::once_flag staticJSCCallingConventionFlag;
-    std::call_once(staticJSCCallingConventionFlag, [] () {
-        staticJSCCallingConvention.construct(Vector&lt;GPRReg&gt;(), RegisterSet::calleeSaveRegisters());
-    });
-
-    return staticJSCCallingConvention;
-}
-
-} // namespace B3
-
-} // namespace JSC
-
-#endif // ENABLE(B3_JIT)
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreB3CallingConventionsh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/B3CallingConventions.h (205551 => 205552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/B3CallingConventions.h        2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/JavaScriptCore/B3CallingConventions.h        2016-09-07 17:12:08 UTC (rev 205552)
</span><span class="lines">@@ -1,94 +0,0 @@
</span><del>-/*
- * 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 &quot;B3ArgumentRegValue.h&quot;
-#include &quot;B3BasicBlock.h&quot;
-#include &quot;B3Const64Value.h&quot;
-#include &quot;B3MemoryValue.h&quot;
-#include &quot;B3Type.h&quot;
-#include &quot;CallFrame.h&quot;
-#include &quot;RegisterSet.h&quot;
-
-namespace JSC {
-
-namespace B3 {
-
-typedef unsigned (*NextOffset)(unsigned currentOffset, Type type);
-
-template&lt;unsigned offset, NextOffset updateOffset&gt;
-class CallingConvention {
-public:
-    static const unsigned headerSize = offset;
-
-    CallingConvention(Vector&lt;GPRReg&gt;&amp;&amp; registerArguments, RegisterSet&amp;&amp; calleeSaveRegisters)
-        : m_registerArguments(registerArguments)
-        , m_calleeSaveRegisters(calleeSaveRegisters)
-    {
-    }
-
-    template&lt;typename Functor&gt;
-    void iterate(const Vector&lt;Type&gt;&amp; argumentTypes, Procedure&amp; proc, BasicBlock* block, Origin origin, const Functor&amp; functor) const
-    {
-        unsigned currentOffset = headerSize;
-        Value* framePointer = block-&gt;appendNew&lt;Value&gt;(proc, FramePointer, origin);
-
-        for (unsigned i = 0; i &lt; argumentTypes.size(); ++i) {
-            Value* argument;
-            if (i &lt; m_registerArguments.size())
-                argument = block-&gt;appendNew&lt;ArgumentRegValue&gt;(proc, origin, m_registerArguments[i]);
-            else {
-                Value* address = block-&gt;appendNew&lt;Value&gt;(proc, Add, origin, framePointer,
-                    block-&gt;appendNew&lt;Const64Value&gt;(proc, origin, currentOffset));
-                argument = block-&gt;appendNew&lt;MemoryValue&gt;(proc, Load, argumentTypes[i], origin, address);
-                currentOffset = updateOffset(currentOffset, argumentTypes[i]);
-            }
-            functor(argument, i);
-        }
-    }
-
-    const Vector&lt;GPRReg&gt; 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&lt;jscHeaderSize, nextJSCOffset&gt; JSCCallingConvention;
-
-JSCCallingConvention&amp; jscCallingConvention();
-
-} // namespace B3
-
-} // namespace JSC
-
-#endif // ENABLE(B3_JIT)
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (205551 => 205552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2016-09-07 17:12:08 UTC (rev 205552)
</span><span class="lines">@@ -854,6 +854,7 @@
</span><span class="cx">     wasm/WASMModuleParser.cpp
</span><span class="cx">     wasm/WASMPlan.cpp
</span><span class="cx">     wasm/WASMSections.cpp
</span><ins>+    wasm/WASMCallingConventions.cpp
</ins><span class="cx"> 
</span><span class="cx">     yarr/RegularExpression.cpp
</span><span class="cx">     yarr/YarrCanonicalizeUCS2.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (205551 => 205552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-09-07 17:12:08 UTC (rev 205552)
</span><span class="lines">@@ -1,3 +1,78 @@
</span><ins>+2016-09-03  Keith Miller  &lt;keith_miller@apple.com&gt;
+
+        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.
+        * JavaScriptCore.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/JavaScriptCore/B3CallingConventions.cpp.
+        (JSC::WASM::jscCallingConvention):
+        * wasm/WASMCallingConvention.h: Renamed from Source/JavaScriptCore/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&lt;Context&gt;::parse):
+        (JSC::WASM::FunctionParser&lt;Context&gt;::parseExpression):
+        * wasm/WASMModuleParser.cpp:
+        (JSC::WASM::ModuleParser::parseFunctionTypes):
+        * wasm/WASMOps.h:
+
</ins><span class="cx"> 2016-09-07  Youenn Fablet  &lt;youenn@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [Streams API] Separate compile flag for ReadableStream and WritableStream
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (205551 => 205552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2016-09-07 17:12:08 UTC (rev 205552)
</span><span class="lines">@@ -1195,7 +1195,6 @@
</span><span class="cx">                 52C952B919A28A1C0069B386 /* TypeProfiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52C952B819A28A1C0069B386 /* TypeProfiler.cpp */; };
</span><span class="cx">                 531374BD1D5CE67600AF7A0B /* WASMPlan.h in Headers */ = {isa = PBXBuildFile; fileRef = 531374BC1D5CE67600AF7A0B /* WASMPlan.h */; };
</span><span class="cx">                 531374BF1D5CE95000AF7A0B /* WASMPlan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 531374BE1D5CE95000AF7A0B /* WASMPlan.cpp */; };
</span><del>-                531B3C871D74C603005B3236 /* B3CallingConventions.h in Headers */ = {isa = PBXBuildFile; fileRef = 531B3C861D74C603005B3236 /* B3CallingConventions.h */; };
</del><span class="cx">                 53486BB71C1795C300F6F3AF /* JSTypedArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 53486BB61C1795C300F6F3AF /* JSTypedArray.h */; settings = {ATTRIBUTES = (Public, ); }; };
</span><span class="cx">                 53486BBB1C18E84500F6F3AF /* JSTypedArray.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53486BBA1C18E84500F6F3AF /* JSTypedArray.cpp */; };
</span><span class="cx">                 534902851C7276B70012BCB8 /* TypedArrayCTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 534902821C7242C80012BCB8 /* TypedArrayCTest.cpp */; };
</span><span class="lines">@@ -1204,7 +1203,6 @@
</span><span class="cx">                 53529A4C1C457B75000B49C6 /* APIUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = 53529A4B1C457B75000B49C6 /* APIUtils.h */; };
</span><span class="cx">                 5370B4F51BF26202005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5370B4F31BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.cpp */; };
</span><span class="cx">                 5370B4F61BF26205005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h in Headers */ = {isa = PBXBuildFile; fileRef = 5370B4F41BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h */; };
</span><del>-                5388B4041D76640B00D3D852 /* B3CallingConventions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 5388B4031D76640B00D3D852 /* B3CallingConventions.cpp */; };
</del><span class="cx">                 53917E7B1B7906FA000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 53917E7A1B7906E4000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h */; };
</span><span class="cx">                 539EB0791D55607000C82EF7 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 51F0EB6105C86C6B00E6DF1B /* Foundation.framework */; };
</span><span class="cx">                 539EB07A1D55607000C82EF7 /* JavaScriptCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 932F5BD90822A1C700736975 /* JavaScriptCore.framework */; };
</span><span class="lines">@@ -1222,6 +1220,8 @@
</span><span class="cx">                 53F6BF6D1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F6BF6C1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 53FA2AE11CF37F3F0022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 53FA2AE01CF37F3F0022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 53FA2AE31CF380390022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53FA2AE21CF380390022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp */; };
</span><ins>+                53FD04D31D7AB277003287D3 /* WASMCallingConvention.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 53FD04D11D7AB187003287D3 /* WASMCallingConvention.cpp */; };
+                53FD04D41D7AB291003287D3 /* WASMCallingConvention.h in Headers */ = {isa = PBXBuildFile; fileRef = 53FD04D21D7AB187003287D3 /* WASMCallingConvention.h */; };
</ins><span class="cx">                 5D5D8AD10E0D0EBE00F9C692 /* libedit.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */; };
</span><span class="cx">                 5DBB151B131D0B310056AD36 /* testapi.js in Copy Support Script */ = {isa = PBXBuildFile; fileRef = 14D857740A4696C80032146C /* testapi.js */; };
</span><span class="cx">                 5DBB1525131D0BD70056AD36 /* minidom.js in Copy Support Script */ = {isa = PBXBuildFile; fileRef = 1412110D0A48788700480255 /* minidom.js */; };
</span><span class="lines">@@ -3409,7 +3409,6 @@
</span><span class="cx">                 52C952B819A28A1C0069B386 /* TypeProfiler.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TypeProfiler.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 531374BC1D5CE67600AF7A0B /* WASMPlan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WASMPlan.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 531374BE1D5CE95000AF7A0B /* WASMPlan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WASMPlan.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                531B3C861D74C603005B3236 /* B3CallingConventions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = B3CallingConventions.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 53486BB61C1795C300F6F3AF /* JSTypedArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTypedArray.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 53486BBA1C18E84500F6F3AF /* JSTypedArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTypedArray.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 534902821C7242C80012BCB8 /* TypedArrayCTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TypedArrayCTest.cpp; path = API/tests/TypedArrayCTest.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -3420,7 +3419,6 @@
</span><span class="cx">                 53529A4B1C457B75000B49C6 /* APIUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIUtils.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 5370B4F31BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AdaptiveInferredPropertyValueWatchpointBase.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 5370B4F41BF25EA2005C40FC /* AdaptiveInferredPropertyValueWatchpointBase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AdaptiveInferredPropertyValueWatchpointBase.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                5388B4031D76640B00D3D852 /* B3CallingConventions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = B3CallingConventions.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 53917E7A1B7906E4000EBD33 /* JSGenericTypedArrayViewPrototypeFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGenericTypedArrayViewPrototypeFunctions.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 53917E7C1B791106000EBD33 /* JSTypedArrayViewPrototype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSTypedArrayViewPrototype.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 53917E831B791CB8000EBD33 /* TypedArrayPrototype.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; name = TypedArrayPrototype.js; path = builtins/TypedArrayPrototype.js; sourceTree = SOURCE_ROOT; };
</span><span class="lines">@@ -3440,6 +3438,8 @@
</span><span class="cx">                 53F6BF6C1C3F060A00F41E5D /* InternalFunctionAllocationProfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InternalFunctionAllocationProfile.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 53FA2AE01CF37F3F0022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LLIntPrototypeLoadAdaptiveStructureWatchpoint.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 53FA2AE21CF380390022711D /* LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LLIntPrototypeLoadAdaptiveStructureWatchpoint.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                53FD04D11D7AB187003287D3 /* WASMCallingConvention.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WASMCallingConvention.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                53FD04D21D7AB187003287D3 /* WASMCallingConvention.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WASMCallingConvention.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 593D43CCA0BBE06D89C59707 /* MapDataInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapDataInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 5D5D8AD00E0D0EBE00F9C692 /* libedit.dylib */ = {isa = PBXFileReference; lastKnownFileType = &quot;compiled.mach-o.dylib&quot;; name = libedit.dylib; path = /usr/lib/libedit.dylib; sourceTree = &quot;&lt;absolute&gt;&quot;; };
</span><span class="cx">                 5DAFD6CB146B686300FBEFB4 /* JSC.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = JSC.xcconfig; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -4819,8 +4819,6 @@
</span><span class="cx">                                 DCFDFBD71D1F5D9800FE3D72 /* B3BottomProvider.h */,
</span><span class="cx">                                 0F6B8ADE1C4EFE1700969052 /* B3BreakCriticalEdges.cpp */,
</span><span class="cx">                                 0F6B8ADF1C4EFE1700969052 /* B3BreakCriticalEdges.h */,
</span><del>-                                5388B4031D76640B00D3D852 /* B3CallingConventions.cpp */,
-                                531B3C861D74C603005B3236 /* B3CallingConventions.h */,
</del><span class="cx">                                 DC9A0C1C1D2D94EF0085124E /* B3CaseCollection.cpp */,
</span><span class="cx">                                 DC9A0C1D1D2D94EF0085124E /* B3CaseCollection.h */,
</span><span class="cx">                                 DC9A0C1E1D2D94EF0085124E /* B3CaseCollectionInlines.h */,
</span><span class="lines">@@ -5628,10 +5626,12 @@
</span><span class="cx">                         children = (
</span><span class="cx">                                 7B98D1341B60CD5A0023B1A4 /* JSWASMModule.cpp */,
</span><span class="cx">                                 7B98D1351B60CD5A0023B1A4 /* JSWASMModule.h */,
</span><ins>+                                53F40E8E1D5902820099A1B6 /* WASMB3IRGenerator.cpp */,
+                                53F40E921D5A4AB30099A1B6 /* WASMB3IRGenerator.h */,
+                                53FD04D11D7AB187003287D3 /* WASMCallingConvention.cpp */,
+                                53FD04D21D7AB187003287D3 /* WASMCallingConvention.h */,
</ins><span class="cx">                                 53F40E901D5903020099A1B6 /* WASMOps.h */,
</span><span class="cx">                                 7BC547D21B69599B00959B58 /* WASMFormat.h */,
</span><del>-                                53F40E8E1D5902820099A1B6 /* WASMB3IRGenerator.cpp */,
-                                53F40E921D5A4AB30099A1B6 /* WASMB3IRGenerator.h */,
</del><span class="cx">                                 53F40E8A1D5901BB0099A1B6 /* WASMFunctionParser.h */,
</span><span class="cx">                                 53F40E961D5A7BEC0099A1B6 /* WASMModuleParser.cpp */,
</span><span class="cx">                                 53F40E941D5A7AEF0099A1B6 /* WASMModuleParser.h */,
</span><span class="lines">@@ -8295,6 +8295,7 @@
</span><span class="cx">                                 996B73271BDA08EF00331B84 /* SymbolConstructor.lut.h in Headers */,
</span><span class="cx">                                 705B41B01A6E501E00716757 /* SymbolObject.h in Headers */,
</span><span class="cx">                                 0F33FCFC1C1625BE00323F67 /* B3Dominators.h in Headers */,
</span><ins>+                                53FD04D41D7AB291003287D3 /* WASMCallingConvention.h in Headers */,
</ins><span class="cx">                                 705B41B21A6E501E00716757 /* SymbolPrototype.h in Headers */,
</span><span class="cx">                                 996B73281BDA08EF00331B84 /* SymbolPrototype.lut.h in Headers */,
</span><span class="cx">                                 BC18C46B0E16F5CD00B34460 /* SymbolTable.h in Headers */,
</span><span class="lines">@@ -8343,7 +8344,6 @@
</span><span class="cx">                                 99DA00B11BD5994E00F4575C /* UpdateContents.py in Headers */,
</span><span class="cx">                                 0F963B3813FC6FE90002D9B2 /* ValueProfile.h in Headers */,
</span><span class="cx">                                 0F426A481460CBB300131F8F /* ValueRecovery.h in Headers */,
</span><del>-                                531B3C871D74C603005B3236 /* B3CallingConventions.h in Headers */,
</del><span class="cx">                                 79EE0C001B4AFB85000385C9 /* VariableEnvironment.h in Headers */,
</span><span class="cx">                                 0F6C73511AC9F99F00BE1682 /* VariableWriteFireDetail.h in Headers */,
</span><span class="cx">                                 0FE0502D1AA9095600D33B33 /* VarOffset.h in Headers */,
</span><span class="lines">@@ -8996,7 +8996,6 @@
</span><span class="cx">                                 7094C4DE1AE439530041A2EE /* BytecodeIntrinsicRegistry.cpp in Sources */,
</span><span class="cx">                                 C2FCAE1217A9C24E0034C735 /* BytecodeLivenessAnalysis.cpp in Sources */,
</span><span class="cx">                                 0F338E0D1BF0276C0013C88F /* B3DataSection.cpp in Sources */,
</span><del>-                                5388B4041D76640B00D3D852 /* B3CallingConventions.cpp in Sources */,
</del><span class="cx">                                 65B8392F1BACAD6A0044E824 /* CachedRecovery.cpp in Sources */,
</span><span class="cx">                                 1428082D107EC0570013E7B2 /* CallData.cpp in Sources */,
</span><span class="cx">                                 0F64B2791A7957B2006E4E66 /* CallEdge.cpp in Sources */,
</span><span class="lines">@@ -9129,6 +9128,7 @@
</span><span class="cx">                                 0FC97F3F18202119002C9B26 /* DFGJumpReplacement.cpp in Sources */,
</span><span class="cx">                                 FEA0C4021CDD7D1D00481991 /* FunctionWhitelist.cpp in Sources */,
</span><span class="cx">                                 A73A535A1799CD5D00170C19 /* DFGLazyJSValue.cpp in Sources */,
</span><ins>+                                53FD04D31D7AB277003287D3 /* WASMCallingConvention.cpp in Sources */,
</ins><span class="cx">                                 62F2AA371B0BEDE300610C7A /* DFGLazyNode.cpp in Sources */,
</span><span class="cx">                                 A7D9A29717A0BC7400EE2618 /* DFGLICMPhase.cpp in Sources */,
</span><span class="cx">                                 79C4B15D1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3B3Typeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/B3Type.h (205551 => 205552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/B3Type.h        2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/JavaScriptCore/b3/B3Type.h        2016-09-07 17:12:08 UTC (rev 205552)
</span><span class="lines">@@ -39,12 +39,11 @@
</span><span class="cx"> namespace JSC { namespace B3 {
</span><span class="cx"> 
</span><span class="cx"> enum Type : int8_t {
</span><ins>+    Void,
</ins><span class="cx">     Int32,
</span><span class="cx">     Int64,
</span><span class="cx">     Float,
</span><span class="cx">     Double,
</span><del>-    LastValueType = Double,
-    Void
</del><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> inline bool isInt(Type type)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestWASMcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/testWASM.cpp (205551 => 205552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/testWASM.cpp        2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/JavaScriptCore/testWASM.cpp        2016-09-07 17:12:08 UTC (rev 205552)
</span><span class="lines">@@ -82,38 +82,50 @@
</span><span class="cx"> 
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+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 &quot; == &quot; #y, &quot; (&quot; #x &quot; == &quot;, __x, &quot;, &quot; #y &quot; == &quot;, __y, &quot;)&quot;).data()); \
+        CRASH(); \
+    } while (false)
+
</ins><span class="cx"> #define FOR_EACH_UNSIGNED_LEB_TEST(macro) \
</span><span class="cx">     /* Simple tests that use all the bits in the array */ \
</span><del>-    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) \
</del><ins>+    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) \
</ins><span class="cx">     /* Test with extra trailing numbers */ \
</span><del>-    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) \
</del><ins>+    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) \
</ins><span class="cx">     /* Test with preceeding numbers */ \
</span><del>-    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) \
</del><ins>+    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) \
</ins><span class="cx">     /* Test in the middle */ \
</span><del>-    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) \
</del><ins>+    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) \
</ins><span class="cx">     /* Test decode too long */ \
</span><del>-    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) \
</del><ins>+    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) \
</ins><span class="cx">     /* Test decode off end of array */ \
</span><del>-    macro(({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff}), 2, false, 0x0, 0) \
</del><ins>+    macro(({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff}), 2, false, 0x0lu, 0lu) \
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> #define TEST_UNSIGNED_LEB_DECODE(init, startOffset, expectedStatus, expectedResult, expectedOffset) \
</span><span class="lines">@@ -122,10 +134,10 @@
</span><span class="cx">         size_t offset = startOffset; \
</span><span class="cx">         uint32_t result; \
</span><span class="cx">         bool status = decodeUInt32(vector.data(), vector.size(), offset, result); \
</span><del>-        RELEASE_ASSERT(status == expectedStatus); \
</del><ins>+        CHECK_EQ(status, expectedStatus); \
</ins><span class="cx">         if (expectedStatus) { \
</span><del>-            RELEASE_ASSERT(result == expectedResult); \
-            RELEASE_ASSERT(offset == expectedOffset); \
</del><ins>+            CHECK_EQ(result, expectedResult); \
+            CHECK_EQ(offset, expectedOffset); \
</ins><span class="cx">         } \
</span><span class="cx">     };
</span><span class="cx"> 
</span><span class="lines">@@ -132,36 +144,36 @@
</span><span class="cx"> 
</span><span class="cx"> #define FOR_EACH_SIGNED_LEB_TEST(macro) \
</span><span class="cx">     /* Simple tests that use all the bits in the array */ \
</span><del>-    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) \
</del><ins>+    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) \
</ins><span class="cx">     /* Test with extra trailing numbers */ \
</span><del>-    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) \
</del><ins>+    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) \
</ins><span class="cx">     /* Test with preceeding numbers */ \
</span><del>-    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) \
</del><ins>+    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) \
</ins><span class="cx">     /* Test in the middle */ \
</span><del>-    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) \
</del><ins>+    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) \
</ins><span class="cx">     /* Test decode too long */ \
</span><del>-    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) \
</del><ins>+    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) \
</ins><span class="cx">     /* Test decode off end of array */ \
</span><del>-    macro(({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff}), 2, false, 0x0, 0) \
</del><ins>+    macro(({ 0x80, 0x80, 0xab, 0x8a, 0x9a, 0xa3, 0xff}), 2, false, 0x0, 0lu) \
</ins><span class="cx"> 
</span><span class="cx"> 
</span><span class="cx"> #define TEST_SIGNED_LEB_DECODE(init, startOffset, expectedStatus, expectedResult, expectedOffset) \
</span><span class="lines">@@ -170,11 +182,11 @@
</span><span class="cx">         size_t offset = startOffset; \
</span><span class="cx">         int32_t result; \
</span><span class="cx">         bool status = decodeInt32(vector.data(), vector.size(), offset, result); \
</span><del>-        RELEASE_ASSERT(status == expectedStatus); \
</del><ins>+        CHECK_EQ(status, expectedStatus); \
</ins><span class="cx">         if (expectedStatus) { \
</span><span class="cx">             int32_t expected = expectedResult; \
</span><del>-            RELEASE_ASSERT(result == expected); \
-            RELEASE_ASSERT(offset == expectedOffset); \
</del><ins>+            CHECK_EQ(result, expected); \
+            CHECK_EQ(offset, expectedOffset); \
</ins><span class="cx">         } \
</span><span class="cx">     };
</span><span class="cx"> 
</span><span class="lines">@@ -246,7 +258,7 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><del>-        RELEASE_ASSERT(invoke&lt;int&gt;(*plan.result[0], { }) == 5);
</del><ins>+        CHECK_EQ(invoke&lt;int&gt;(*plan.result[0], { }), 5);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> 
</span><span class="lines">@@ -268,7 +280,7 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><del>-        RELEASE_ASSERT(invoke&lt;int&gt;(*plan.result[0], { }) == 11);
</del><ins>+        CHECK_EQ(invoke&lt;int&gt;(*plan.result[0], { }), 11);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     {
</span><span class="lines">@@ -289,7 +301,7 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><del>-        RELEASE_ASSERT(invoke&lt;int&gt;(*plan.result[0], { }) == 11);
</del><ins>+        CHECK_EQ(invoke&lt;int&gt;(*plan.result[0], { }), 11);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     {
</span><span class="lines">@@ -310,7 +322,7 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><del>-        RELEASE_ASSERT(invoke&lt;int&gt;(*plan.result[0], { }) == 11);
</del><ins>+        CHECK_EQ(invoke&lt;int&gt;(*plan.result[0], { }), 11);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     {
</span><span class="lines">@@ -329,11 +341,187 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><del>-        RELEASE_ASSERT(invoke&lt;int&gt;(*plan.result[0], {box(0), box(1)}) == 1);
-        RELEASE_ASSERT(invoke&lt;int&gt;(*plan.result[0], {box(100), box(1)}) == 101);
-        RELEASE_ASSERT(invoke&lt;int&gt;(*plan.result[0], {box(-1), box(1)}) == 0);
-        RELEASE_ASSERT(invoke&lt;int&gt;(*plan.result[0], {box(std::numeric_limits&lt;int&gt;::max()), box(1)}) == std::numeric_limits&lt;int&gt;::min());
</del><ins>+        CHECK_EQ(invoke&lt;int&gt;(*plan.result[0], { box(0), box(1) }), 1);
+        CHECK_EQ(invoke&lt;int&gt;(*plan.result[0], { box(100), box(1) }), 101);
+        CHECK_EQ(invoke&lt;int&gt;(*plan.result[0], { box(-1), box(1)}), 0);
+        CHECK_EQ(invoke&lt;int&gt;(*plan.result[0], { box(std::numeric_limits&lt;int&gt;::max()), box(1) }), std::numeric_limits&lt;int&gt;::min());
</ins><span class="cx">     }
</span><ins>+
+    {
+        // Generated from:
+        //    (module
+        //     (func &quot;locals&quot; (param $x i32) (result i32) (local $num i32)
+        //      (set_local $num (get_local $x))
+        //      (return (get_local $num))
+        //      )
+        //     )
+        Vector&lt;uint8_t&gt; 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(&quot;Module failed to compile correctly.&quot;);
+            CRASH();
+        }
+
+        // Test this doesn't crash.
+        CHECK_EQ(invoke&lt;int&gt;(*plan.result[0], { box(0) }), 0);
+        CHECK_EQ(invoke&lt;int&gt;(*plan.result[0], { box(10) }), 10);
+    }
+
+    {
+        // Generated from:
+        //    (module
+        //     (func &quot;dumb-mult&quot; (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&lt;uint8_t&gt; 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(&quot;Module failed to compile correctly.&quot;);
+            CRASH();
+        }
+
+        // Test this doesn't crash.
+        CHECK_EQ(invoke&lt;int&gt;(*plan.result[0], { box(0) }), 0);
+        CHECK_EQ(invoke&lt;int&gt;(*plan.result[0], { box(1) }), 1);
+        CHECK_EQ(invoke&lt;int&gt;(*plan.result[0], { box(2)}), 3);
+        CHECK_EQ(invoke&lt;int&gt;(*plan.result[0], { box(100) }), 5050);
+    }
+
+    {
+        // Generated from:
+        //    (module
+        //     (func &quot;dumb-mult&quot; (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&lt;uint8_t&gt; 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(&quot;Module failed to compile correctly.&quot;);
+            CRASH();
+        }
+
+        // Test this doesn't crash.
+        CHECK_EQ(invoke&lt;int&gt;(*plan.result[0], { box(0), box(1) }), 0);
+        CHECK_EQ(invoke&lt;int&gt;(*plan.result[0], { box(1), box(0) }), 0);
+        CHECK_EQ(invoke&lt;int&gt;(*plan.result[0], { box(2), box(1) }), 2);
+        CHECK_EQ(invoke&lt;int&gt;(*plan.result[0], { box(1), box(2) }), 2);
+        CHECK_EQ(invoke&lt;int&gt;(*plan.result[0], { box(2), box(2) }), 4);
+        CHECK_EQ(invoke&lt;int&gt;(*plan.result[0], { box(2), box(6) }), 12);
+        CHECK_EQ(invoke&lt;int&gt;(*plan.result[0], { box(100), box(6) }), 600);
+        CHECK_EQ(invoke&lt;int&gt;(*plan.result[0], { box(100), box(100) }), 10000);
+    }
+
+    {
+        // Generated from:
+        //    (module
+        //     (func &quot;dumb-less-than&quot; (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&lt;uint8_t&gt; 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(&quot;Module failed to compile correctly.&quot;);
+            CRASH();
+        }
+
+        // Test this doesn't crash.
+        CHECK_EQ(invoke&lt;int&gt;(*plan.result[0], { box(0), box(1) }), 1);
+        CHECK_EQ(invoke&lt;int&gt;(*plan.result[0], { box(1), box(0) }), 0);
+        CHECK_EQ(invoke&lt;int&gt;(*plan.result[0], { box(2), box(1) }), 0);
+        CHECK_EQ(invoke&lt;int&gt;(*plan.result[0], { box(1), box(2) }), 1);
+        CHECK_EQ(invoke&lt;int&gt;(*plan.result[0], { box(2), box(2) }), 0);
+        CHECK_EQ(invoke&lt;int&gt;(*plan.result[0], { box(1), box(1) }), 0);
+        CHECK_EQ(invoke&lt;int&gt;(*plan.result[0], { box(2), box(6) }), 1);
+        CHECK_EQ(invoke&lt;int&gt;(*plan.result[0], { box(100), box(6) }), 0);
+    }
+
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(WEBASSEMBLY)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWASMB3IRGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WASMB3IRGenerator.cpp (205551 => 205552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WASMB3IRGenerator.cpp        2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/JavaScriptCore/wasm/WASMB3IRGenerator.cpp        2016-09-07 17:12:08 UTC (rev 205552)
</span><span class="lines">@@ -29,20 +29,24 @@
</span><span class="cx"> #if ENABLE(WEBASSEMBLY)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;B3BasicBlockInlines.h&quot;
</span><del>-#include &quot;B3CallingConventions.h&quot;
</del><ins>+#include &quot;B3FixSSA.h&quot;
+#include &quot;B3Validate.h&quot;
</ins><span class="cx"> #include &quot;B3ValueInlines.h&quot;
</span><span class="cx"> #include &quot;B3Variable.h&quot;
</span><span class="cx"> #include &quot;B3VariableValue.h&quot;
</span><span class="cx"> #include &quot;VirtualRegister.h&quot;
</span><ins>+#include &quot;WASMCallingConvention.h&quot;
</ins><span class="cx"> #include &quot;WASMFunctionParser.h&quot;
</span><span class="cx"> #include &lt;wtf/Optional.h&gt;
</span><span class="cx"> 
</span><del>-namespace JSC {
</del><ins>+namespace JSC { namespace WASM {
</ins><span class="cx"> 
</span><del>-namespace WASM {
</del><ins>+namespace {
</ins><span class="cx"> 
</span><span class="cx"> using namespace B3;
</span><span class="cx"> 
</span><ins>+const bool verbose = false;
+
</ins><span class="cx"> inline B3::Opcode toB3Op(BinaryOpType op)
</span><span class="cx"> {
</span><span class="cx">     switch (op) {
</span><span class="lines">@@ -64,8 +68,66 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> class B3IRGenerator {
</span><ins>+private:
+    class LazyBlock {
+    public:
+        explicit operator bool() { return !!m_block; }
+
+        BasicBlock* get(Procedure&amp; proc)
+        {
+            if (!m_block)
+                m_block = proc.addBlock();
+            return m_block;
+        }
+
+        void dump(PrintStream&amp; out) const
+        {
+            if (m_block)
+                out.print(*m_block);
+            else
+                out.print(&quot;Uninitialized&quot;);
+        }
+
+    private:
+        BasicBlock* m_block { nullptr };
+    };
+
+    struct ControlData {
+        ControlData(Optional&lt;Vector&lt;Variable*&gt;&gt;&amp;&amp; stack, BasicBlock* loopTarget = nullptr)
+            : loopTarget(loopTarget)
+            , stack(stack)
+        {
+        }
+
+        void dump(PrintStream&amp; out) const
+        {
+            out.print(&quot;Continuation: &quot;, continuation, &quot;, Target: &quot;);
+            if (loopTarget)
+                out.print(*loopTarget);
+            else
+                out.print(continuation);
+        }
+
+        BasicBlock* targetBlockForBranch(Procedure&amp; 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&lt;Vector&lt;Variable*&gt;&gt; stack;
+    };
+
</ins><span class="cx"> public:
</span><span class="cx">     typedef Value* ExpressionType;
</span><ins>+    static constexpr ExpressionType emptyExpression = nullptr;
</ins><span class="cx"> 
</span><span class="cx">     B3IRGenerator(Procedure&amp;);
</span><span class="cx"> 
</span><span class="lines">@@ -74,25 +136,34 @@
</span><span class="cx">     ExpressionType addConstant(Type, uint64_t);
</span><span class="cx"> 
</span><span class="cx">     bool WARN_UNUSED_RETURN getLocal(uint32_t index, ExpressionType&amp; result);
</span><ins>+    bool WARN_UNUSED_RETURN setLocal(uint32_t index, ExpressionType value);
</ins><span class="cx"> 
</span><span class="cx">     bool WARN_UNUSED_RETURN binaryOp(BinaryOpType, ExpressionType left, ExpressionType right, ExpressionType&amp; result);
</span><span class="cx">     bool WARN_UNUSED_RETURN unaryOp(UnaryOpType, ExpressionType arg, ExpressionType&amp; result);
</span><span class="cx"> 
</span><span class="cx">     bool WARN_UNUSED_RETURN addBlock();
</span><del>-    bool WARN_UNUSED_RETURN endBlock(Vector&lt;ExpressionType&gt;&amp; expressionStack);
</del><ins>+    bool WARN_UNUSED_RETURN addLoop();
+    bool WARN_UNUSED_RETURN endBlock(Vector&lt;ExpressionType, 1&gt;&amp; expressionStack);
+
</ins><span class="cx">     bool WARN_UNUSED_RETURN addReturn(const Vector&lt;ExpressionType, 1&gt;&amp; returnValues);
</span><ins>+    bool WARN_UNUSED_RETURN addBranch(ExpressionType condition, const Vector&lt;ExpressionType, 1&gt;&amp; returnValues, uint32_t target);
</ins><span class="cx"> 
</span><ins>+    void dumpGraphAndControlStack();
+
</ins><span class="cx"> private:
</span><del>-    Optional&lt;Vector&lt;Variable*&gt;&gt;&amp; stackForControlLevel(unsigned);
-    BasicBlock* blockForControlLevel(unsigned);
</del><ins>+    ControlData&amp; controlDataForLevel(unsigned);
</ins><span class="cx">     void unify(Variable* target, const ExpressionType source);
</span><del>-    Vector&lt;Variable*&gt; initializeIncommingTypes(BasicBlock*, const Vector&lt;ExpressionType&gt;&amp;);
-    void unifyValuesWithLevel(const Vector&lt;ExpressionType&gt;&amp; resultStack, unsigned);
</del><ins>+    Vector&lt;Variable*&gt; initializeIncommingTypes(BasicBlock*, const Vector&lt;ExpressionType, 1&gt;&amp;);
+    void unifyValuesWithBlock(const Vector&lt;ExpressionType, 1&gt;&amp; resultStack, Optional&lt;Vector&lt;Variable*&gt;&gt;&amp; stack, BasicBlock* target);
</ins><span class="cx"> 
</span><ins>+public:
+    unsigned unreachable { 0 };
+
+private:
</ins><span class="cx">     Procedure&amp; m_proc;
</span><span class="cx">     BasicBlock* m_currentBlock;
</span><span class="cx">     // This is a pair of the continuation and the types expected on the stack for that continuation.
</span><del>-    Vector&lt;std::pair&lt;BasicBlock*, Optional&lt;Vector&lt;Variable*&gt;&gt;&gt;&gt; m_controlStack;
</del><ins>+    Vector&lt;ControlData&gt; m_controlStack;
</ins><span class="cx">     Vector&lt;Variable*&gt; m_locals;
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -106,12 +177,11 @@
</span><span class="cx"> {
</span><span class="cx">     m_locals.reserveCapacity(m_locals.size() + count);
</span><span class="cx">     for (uint32_t i = 0; i &lt; count; ++i)
</span><del>-        m_locals.append(m_proc.addVariable(type));
</del><ins>+        m_locals.append(m_proc.addVariable(toB3Type(type)));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void B3IRGenerator::addArguments(const Vector&lt;Type&gt;&amp; types)
</span><span class="cx"> {
</span><del>-    // TODO: Add locals.
</del><span class="cx">     ASSERT(!m_locals.size());
</span><span class="cx">     m_locals.grow(types.size());
</span><span class="cx">     jscCallingConvention().iterate(types, m_proc, m_currentBlock, Origin(),
</span><span class="lines">@@ -129,6 +199,13 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool WARN_UNUSED_RETURN B3IRGenerator::setLocal(uint32_t index, ExpressionType value)
+{
+    ASSERT(m_locals[index]);
+    m_currentBlock-&gt;appendNew&lt;VariableValue&gt;(m_proc, B3::Set, Origin(), m_locals[index], value);
+    return true;
+}
+
</ins><span class="cx"> bool B3IRGenerator::unaryOp(UnaryOpType op, ExpressionType arg, ExpressionType&amp; result)
</span><span class="cx"> {
</span><span class="cx">     result = m_currentBlock-&gt;appendNew&lt;Value&gt;(m_proc, toB3Op(op), Origin(), arg);
</span><span class="lines">@@ -160,12 +237,50 @@
</span><span class="cx"> 
</span><span class="cx"> bool B3IRGenerator::addBlock()
</span><span class="cx"> {
</span><del>-    m_controlStack.append(std::make_pair(m_proc.addBlock(), Nullopt));
</del><ins>+    if (unreachable) {
+        unreachable++;
+        return true;
+    }
+
+    if (verbose) {
+        dataLogLn(&quot;Adding block&quot;);
+        dumpGraphAndControlStack();
+    }
+    m_controlStack.append(ControlData(Nullopt));
+
</ins><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool B3IRGenerator::endBlock(Vector&lt;ExpressionType&gt;&amp; expressionStack)
</del><ins>+bool B3IRGenerator::addLoop()
</ins><span class="cx"> {
</span><ins>+    if (unreachable) {
+        unreachable++;
+        return true;
+    }
+
+    if (verbose) {
+        dataLogLn(&quot;Adding loop&quot;);
+        dumpGraphAndControlStack();
+    }
+    BasicBlock* body = m_proc.addBlock();
+    m_currentBlock-&gt;appendNewControlValue(m_proc, Jump, Origin(), body);
+    body-&gt;addPredecessor(m_currentBlock);
+    m_currentBlock = body;
+    m_controlStack.append(ControlData(Vector&lt;Variable*&gt;(), body));
+    return true;
+}
+
+bool B3IRGenerator::endBlock(Vector&lt;ExpressionType, 1&gt;&amp; expressionStack)
+{
+    if (unreachable &gt; 1) {
+        unreachable--;
+        return true;
+    }
+
+    if (verbose) {
+        dataLogLn(&quot;Falling out of block&quot;);
+        dumpGraphAndControlStack();
+    }
</ins><span class="cx">     // This means that we are exiting the function.
</span><span class="cx">     if (!m_controlStack.size()) {
</span><span class="cx">         // FIXME: Should this require the stack is empty? It's not clear from the current spec.
</span><span class="lines">@@ -172,33 +287,86 @@
</span><span class="cx">         return !expressionStack.size();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    unifyValuesWithLevel(expressionStack, 0);
</del><ins>+    ControlData data = m_controlStack.takeLast();
+    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;
+    }
</ins><span class="cx"> 
</span><del>-    m_currentBlock = m_controlStack.takeLast().first;
</del><ins>+    BasicBlock* continuation = data.continuation.get(m_proc);
+    unifyValuesWithBlock(expressionStack, data.stack, continuation);
+    m_currentBlock-&gt;appendNewControlValue(m_proc, Jump, Origin(), continuation);
+    continuation-&gt;addPredecessor(m_currentBlock);
+    m_currentBlock = continuation;
</ins><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool B3IRGenerator::addReturn(const Vector&lt;ExpressionType, 1&gt;&amp; returnValues)
</span><span class="cx"> {
</span><ins>+    if (unreachable)
+        return true;
+
+    if (verbose) {
+        dataLogLn(&quot;Adding return&quot;);
+        dumpGraphAndControlStack();
+    }
+
</ins><span class="cx">     ASSERT(returnValues.size() &lt;= 1);
</span><span class="cx">     if (returnValues.size())
</span><span class="cx">         m_currentBlock-&gt;appendNewControlValue(m_proc, B3::Return, Origin(), returnValues[0]);
</span><span class="cx">     else
</span><span class="cx">         m_currentBlock-&gt;appendNewControlValue(m_proc, B3::Return, Origin());
</span><ins>+    unreachable = 1;
</ins><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool B3IRGenerator::addBranch(ExpressionType condition, const Vector&lt;ExpressionType, 1&gt;&amp; returnValues, uint32_t level)
+{
+    if (unreachable)
+        return true;
+
+    ASSERT(level &lt; m_controlStack.size());
+    ControlData&amp; data = controlDataForLevel(level);
+    if (verbose) {
+        dataLogLn(&quot;Adding Branch from: &quot;,  *m_currentBlock, &quot; targeting: &quot;, level, &quot; with data: &quot;, data);
+        dumpGraphAndControlStack();
+    }
+
+
+    BasicBlock* target = data.targetBlockForBranch(m_proc);
+    unifyValuesWithBlock(returnValues, data.stack, target);
+    if (condition) {
+        BasicBlock* continuation = m_proc.addBlock();
+        m_currentBlock-&gt;appendNew&lt;Value&gt;(m_proc, B3::Branch, Origin(), condition);
+        m_currentBlock-&gt;setSuccessors(FrequentedBlock(target), FrequentedBlock(continuation));
+        target-&gt;addPredecessor(m_currentBlock);
+        continuation-&gt;addPredecessor(m_currentBlock);
+        m_currentBlock = continuation;
+    } else {
+        m_currentBlock-&gt;appendNewControlValue(m_proc, Jump, Origin(), FrequentedBlock(target));
+        target-&gt;addPredecessor(m_currentBlock);
+        unreachable = 1;
+    }
+
+    return true;
+}
+
</ins><span class="cx"> void B3IRGenerator::unify(Variable* variable, ExpressionType source)
</span><span class="cx"> {
</span><span class="cx">     m_currentBlock-&gt;appendNew&lt;VariableValue&gt;(m_proc, Set, Origin(), variable, source);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Vector&lt;Variable*&gt; B3IRGenerator::initializeIncommingTypes(BasicBlock* block, const Vector&lt;ExpressionType&gt;&amp; source)
</del><ins>+Vector&lt;Variable*&gt; B3IRGenerator::initializeIncommingTypes(BasicBlock* block, const Vector&lt;ExpressionType, 1&gt;&amp; source)
</ins><span class="cx"> {
</span><span class="cx">     Vector&lt;Variable*&gt; result;
</span><span class="cx">     result.reserveInitialCapacity(source.size());
</span><span class="cx">     for (ExpressionType expr : source) {
</span><del>-        ASSERT(expr-&gt;type() != Void);
</del><ins>+        ASSERT(expr-&gt;type() != B3::Void);
</ins><span class="cx">         Variable* var = m_proc.addVariable(expr-&gt;type());
</span><span class="cx">         result.append(var);
</span><span class="cx">         block-&gt;appendNew&lt;VariableValue&gt;(m_proc, B3::Get, Origin(), var);
</span><span class="lines">@@ -207,32 +375,37 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void B3IRGenerator::unifyValuesWithLevel(const Vector&lt;ExpressionType&gt;&amp; resultStack, unsigned level)
</del><ins>+void B3IRGenerator::unifyValuesWithBlock(const Vector&lt;ExpressionType, 1&gt;&amp; resultStack, Optional&lt;Vector&lt;Variable*&gt;&gt;&amp; stack, BasicBlock* target)
</ins><span class="cx"> {
</span><del>-    ASSERT(level &lt; m_controlStack.size());
-
-    Optional&lt;Vector&lt;Variable*&gt;&gt;&amp; expectedStack = stackForControlLevel(level);
-    if (!expectedStack) {
-        expectedStack = initializeIncommingTypes(blockForControlLevel(level), resultStack);
</del><ins>+    if (!stack) {
+        stack = initializeIncommingTypes(target, resultStack);
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    ASSERT(expectedStack.value().size() != resultStack.size());
</del><ins>+    ASSERT(stack.value().size() == resultStack.size());
</ins><span class="cx"> 
</span><span class="cx">     for (size_t i = 0; i &lt; resultStack.size(); ++i)
</span><del>-        unify(expectedStack.value()[i], resultStack[i]);
</del><ins>+        unify(stack.value()[i], resultStack[i]);
</ins><span class="cx"> }
</span><span class="cx">     
</span><del>-Optional&lt;Vector&lt;Variable*&gt;&gt;&amp; B3IRGenerator::stackForControlLevel(unsigned level)
</del><ins>+B3IRGenerator::ControlData&amp; B3IRGenerator::controlDataForLevel(unsigned level)
</ins><span class="cx"> {
</span><del>-    return m_controlStack[m_controlStack.size() - 1 - level].second;
</del><ins>+    return m_controlStack[m_controlStack.size() - 1 - level];
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-BasicBlock* B3IRGenerator::blockForControlLevel(unsigned level)
</del><ins>+void B3IRGenerator::dumpGraphAndControlStack()
</ins><span class="cx"> {
</span><del>-    return m_controlStack[m_controlStack.size() - 1 - level].first;
</del><ins>+    dataLogLn(&quot;Processing Graph:&quot;);
+    dataLog(m_proc);
+    dataLogLn(&quot;With current block:&quot;, *m_currentBlock);
+    dataLogLn(&quot;With Control Stack:&quot;);
+    for (unsigned i = 0; i &lt; m_controlStack.size(); ++i)
+        dataLogLn(&quot;[&quot;, i, &quot;] &quot;, m_controlStack[i]);
+    dataLogLn(&quot;\n&quot;);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+} // anonymous namespace
+
</ins><span class="cx"> std::unique_ptr&lt;Compilation&gt; parseAndCompile(VM&amp; vm, Vector&lt;uint8_t&gt;&amp; source, FunctionInformation info, unsigned optLevel)
</span><span class="cx"> {
</span><span class="cx">     Procedure procedure;
</span><span class="lines">@@ -241,11 +414,14 @@
</span><span class="cx">     if (!parser.parse())
</span><span class="cx">         RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> 
</span><ins>+    validate(procedure, &quot;After parsing:\n&quot;);
+
+    fixSSA(procedure);
+    if (verbose)
+        dataLog(&quot;Post SSA: &quot;, procedure);
</ins><span class="cx">     return std::make_unique&lt;Compilation&gt;(vm, procedure, optLevel);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-} // namespace WASM
</del><ins>+} } // namespace JSC::WASM
</ins><span class="cx"> 
</span><del>-} // namespace JSC
-
</del><span class="cx"> #endif // ENABLE(WEBASSEMBLY)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWASMB3IRGeneratorh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WASMB3IRGenerator.h (205551 => 205552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WASMB3IRGenerator.h        2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/JavaScriptCore/wasm/WASMB3IRGenerator.h        2016-09-07 17:12:08 UTC (rev 205552)
</span><span class="lines">@@ -31,14 +31,10 @@
</span><span class="cx"> #include &quot;VM.h&quot;
</span><span class="cx"> #include &quot;WASMFormat.h&quot;
</span><span class="cx"> 
</span><del>-namespace JSC {
</del><ins>+namespace JSC { namespace WASM {
</ins><span class="cx"> 
</span><del>-namespace WASM {
-
</del><span class="cx"> std::unique_ptr&lt;B3::Compilation&gt; parseAndCompile(VM&amp;, Vector&lt;uint8_t&gt;&amp;, FunctionInformation, unsigned optLevel = 1);
</span><span class="cx"> 
</span><del>-} // namespace WASM
</del><ins>+} } // namespace JSC::WASM
</ins><span class="cx"> 
</span><del>-} // namespace JSC
-
</del><span class="cx"> #endif // ENABLE(WEBASSEMBLY)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWASMCallingConventioncppfromrev205550trunkSourceJavaScriptCoreB3CallingConventionscpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/JavaScriptCore/wasm/WASMCallingConvention.cpp (from rev 205550, trunk/Source/JavaScriptCore/B3CallingConventions.cpp) (0 => 205552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WASMCallingConvention.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/wasm/WASMCallingConvention.cpp        2016-09-07 17:12:08 UTC (rev 205552)
</span><span class="lines">@@ -0,0 +1,48 @@
</span><ins>+/*
+ * 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 &quot;config.h&quot;
+#include &quot;WASMCallingConvention.h&quot;
+
+#if ENABLE(WEBASSEMBLY)
+
+#include &lt;wtf/NeverDestroyed.h&gt;
+
+namespace JSC { namespace WASM {
+
+const JSCCallingConvention&amp; jscCallingConvention()
+{
+    static LazyNeverDestroyed&lt;JSCCallingConvention&gt; staticJSCCallingConvention;
+    static std::once_flag staticJSCCallingConventionFlag;
+    std::call_once(staticJSCCallingConventionFlag, [] () {
+        staticJSCCallingConvention.construct(Vector&lt;GPRReg&gt;(), RegisterSet::calleeSaveRegisters());
+    });
+
+    return staticJSCCallingConvention;
+}
+
+} } // namespace JSC::WASM
+
+#endif // ENABLE(B3_JIT)
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWASMCallingConventionhfromrev205550trunkSourceJavaScriptCoreB3CallingConventionsh"></a>
<div class="copfile"><h4>Copied: trunk/Source/JavaScriptCore/wasm/WASMCallingConvention.h (from rev 205550, trunk/Source/JavaScriptCore/B3CallingConventions.h) (0 => 205552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WASMCallingConvention.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/wasm/WASMCallingConvention.h        2016-09-07 17:12:08 UTC (rev 205552)
</span><span class="lines">@@ -0,0 +1,90 @@
</span><ins>+/*
+ * 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 &quot;B3ArgumentRegValue.h&quot;
+#include &quot;B3BasicBlock.h&quot;
+#include &quot;B3Const64Value.h&quot;
+#include &quot;B3MemoryValue.h&quot;
+#include &quot;CallFrame.h&quot;
+#include &quot;RegisterSet.h&quot;
+#include &quot;WASMFormat.h&quot;
+
+namespace JSC { namespace WASM {
+
+typedef unsigned (*NextOffset)(unsigned currentOffset, Type type);
+
+template&lt;unsigned offset, NextOffset updateOffset&gt;
+class CallingConvention {
+public:
+    static const unsigned headerSize = offset;
+
+    CallingConvention(Vector&lt;GPRReg&gt;&amp;&amp; registerArguments, RegisterSet&amp;&amp; calleeSaveRegisters)
+        : m_registerArguments(registerArguments)
+        , m_calleeSaveRegisters(calleeSaveRegisters)
+    {
+    }
+
+    template&lt;typename Functor&gt;
+    void iterate(const Vector&lt;Type&gt;&amp; argumentTypes, B3::Procedure&amp; proc, B3::BasicBlock* block, B3::Origin origin, const Functor&amp; functor) const
+    {
+        unsigned currentOffset = headerSize;
+        B3::Value* framePointer = block-&gt;appendNew&lt;B3::Value&gt;(proc, B3::FramePointer, origin);
+
+        for (unsigned i = 0; i &lt; argumentTypes.size(); ++i) {
+            B3::Value* argument;
+            if (i &lt; m_registerArguments.size())
+                argument = block-&gt;appendNew&lt;B3::ArgumentRegValue&gt;(proc, origin, m_registerArguments[i]);
+            else {
+                B3::Value* address = block-&gt;appendNew&lt;B3::Value&gt;(proc, B3::Add, origin, framePointer,
+                    block-&gt;appendNew&lt;B3::Const64Value&gt;(proc, origin, currentOffset));
+                argument = block-&gt;appendNew&lt;B3::MemoryValue&gt;(proc, B3::Load, toB3Type(argumentTypes[i]), origin, address);
+                currentOffset = updateOffset(currentOffset, argumentTypes[i]);
+            }
+            functor(argument, i);
+        }
+    }
+
+    const Vector&lt;GPRReg&gt; 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&lt;jscHeaderSize, nextJSCOffset&gt; JSCCallingConvention;
+
+const JSCCallingConvention&amp; jscCallingConvention();
+
+} } // namespace JSC::WASM
+
+#endif // ENABLE(WEBASSEMBLY)
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWASMFormath"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WASMFormat.h (205551 => 205552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WASMFormat.h        2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/JavaScriptCore/wasm/WASMFormat.h        2016-09-07 17:12:08 UTC (rev 205552)
</span><span class="lines">@@ -54,17 +54,48 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WASM {
</span><span class="cx"> 
</span><del>-using B3::Type;
-using B3::Int32;
-using B3::Int64;
-using B3::Float;
-using B3::Double;
</del><ins>+enum Type : uint8_t {
+    I32 = 1,
+    I64,
+    F32,
+    F64,
+    LastValueType = F64,
+    Void
+};
</ins><span class="cx"> 
</span><del>-static_assert(Int32 == 0, &quot;WASM needs B3::Type::Int32 to have the value 0&quot;);
-static_assert(Int64 == 1, &quot;WASM needs B3::Type::Int64 to have the value 1&quot;);
-static_assert(Float == 2, &quot;WASM needs B3::Type::Float to have the value 2&quot;);
-static_assert(Double == 3, &quot;WASM needs B3::Type::Double to have the value 3&quot;);
</del><ins>+static_assert(I32 == 1, &quot;WASM needs I32 to have the value 1&quot;);
+static_assert(I64 == 2, &quot;WASM needs I64 to have the value 2&quot;);
+static_assert(F32 == 3, &quot;WASM needs F32 to have the value 3&quot;);
+static_assert(F64 == 4, &quot;WASM needs F64 to have the value 4&quot;);
</ins><span class="cx"> 
</span><ins>+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;
+}
+
+
</ins><span class="cx"> struct Signature {
</span><span class="cx">     Type returnType;
</span><span class="cx">     Vector&lt;Type&gt; arguments;
</span><span class="lines">@@ -95,8 +126,6 @@
</span><span class="cx">     size_t end;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-} // namespace WASM
</del><ins>+} } // namespace JSC::WASM
</ins><span class="cx"> 
</span><del>-} // namespace JSC
-
</del><span class="cx"> #endif // ENABLE(WEBASSEMBLY)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWASMFunctionParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.h (205551 => 205552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.h        2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.h        2016-09-07 17:12:08 UTC (rev 205552)
</span><span class="lines">@@ -30,10 +30,8 @@
</span><span class="cx"> #include &quot;WASMParser.h&quot;
</span><span class="cx"> #include &lt;wtf/DataLog.h&gt;
</span><span class="cx"> 
</span><del>-namespace JSC {
</del><ins>+namespace JSC { namespace WASM {
</ins><span class="cx"> 
</span><del>-namespace WASM {
-
</del><span class="cx"> template&lt;typename Context&gt;
</span><span class="cx"> class FunctionParser : public Parser {
</span><span class="cx"> public:
</span><span class="lines">@@ -53,7 +51,7 @@
</span><span class="cx">     Optional&lt;Vector&lt;ExpressionType&gt;&gt;&amp; stackForControlLevel(unsigned level);
</span><span class="cx"> 
</span><span class="cx">     Context&amp; m_context;
</span><del>-    Vector&lt;ExpressionType&gt; m_expressionStack;
</del><ins>+    Vector&lt;ExpressionType, 1&gt; m_expressionStack;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename Context&gt;
</span><span class="lines">@@ -72,8 +70,8 @@
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     for (uint32_t i = 0; i &lt; localCount; ++i) {
</span><del>-        uint32_t numberOfLocalsWithType;
-        if (!parseUInt32(numberOfLocalsWithType))
</del><ins>+        uint32_t numberOfLocals;
+        if (!parseVarUInt32(numberOfLocals))
</ins><span class="cx">             return false;
</span><span class="cx"> 
</span><span class="cx">         Type typeOfLocal;
</span><span class="lines">@@ -80,6 +78,7 @@
</span><span class="cx">         if (!parseValueType(typeOfLocal))
</span><span class="cx">             return false;
</span><span class="cx"> 
</span><ins>+        m_context.addLocal(typeOfLocal, numberOfLocals);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return parseBlock();
</span><span class="lines">@@ -109,11 +108,14 @@
</span><span class="cx"> template&lt;typename Context&gt;
</span><span class="cx"> bool FunctionParser&lt;Context&gt;::parseExpression(OpType op)
</span><span class="cx"> {
</span><ins>+    if (m_context.unreachable &amp;&amp; !isControlOp(op))
+        return true;
+
</ins><span class="cx">     switch (op) {
</span><span class="cx"> #define CREATE_CASE(name, id, b3op) case name:
</span><span class="cx">     FOR_EACH_WASM_BINARY_OP(CREATE_CASE) {
</span><ins>+        ExpressionType right = m_expressionStack.takeLast();
</ins><span class="cx">         ExpressionType left = m_expressionStack.takeLast();
</span><del>-        ExpressionType right = m_expressionStack.takeLast();
</del><span class="cx">         ExpressionType result;
</span><span class="cx">         if (!m_context.binaryOp(static_cast&lt;BinaryOpType&gt;(op), left, right, result))
</span><span class="cx">             return false;
</span><span class="lines">@@ -135,7 +137,7 @@
</span><span class="cx">         uint32_t constant;
</span><span class="cx">         if (!parseVarUInt32(constant))
</span><span class="cx">             return false;
</span><del>-        m_expressionStack.append(m_context.addConstant(Int32, constant));
</del><ins>+        m_expressionStack.append(m_context.addConstant(I32, constant));
</ins><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -151,6 +153,14 @@
</span><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    case OpType::SetLocal: {
+        uint32_t index;
+        if (!parseVarUInt32(index))
+            return false;
+        ExpressionType value = m_expressionStack.takeLast();
+        return m_context.setLocal(index, value);
+    }
+
</ins><span class="cx">     case OpType::Block: {
</span><span class="cx">         if (!m_context.addBlock())
</span><span class="cx">             return false;
</span><span class="lines">@@ -157,6 +167,34 @@
</span><span class="cx">         return parseBlock();
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    case OpType::Loop: {
+        if (!m_context.addLoop())
+            return false;
+        return parseBlock();
+    }
+
+    case OpType::Branch:
+    case OpType::BranchIf: {
+        uint32_t arity;
+        if (!parseVarUInt32(arity) || arity &gt; 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&lt;ExpressionType, 1&gt; values(arity);
+        for (unsigned i = arity; i; i--)
+            values[i-1] = m_expressionStack.takeLast();
+
+        return m_context.addBranch(condition, values, target);
+    }
+
</ins><span class="cx">     case OpType::Return: {
</span><span class="cx">         uint8_t returnCount;
</span><span class="cx">         if (!parseVarUInt1(returnCount))
</span><span class="lines">@@ -177,8 +215,6 @@
</span><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-} // namespace WASM
</del><ins>+} } // namespace JSC::WASM
</ins><span class="cx"> 
</span><del>-} // namespace JSC
-
</del><span class="cx"> #endif // ENABLE(WEBASSEMBLY)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWASMModuleParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WASMModuleParser.cpp (205551 => 205552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WASMModuleParser.cpp        2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/JavaScriptCore/wasm/WASMModuleParser.cpp        2016-09-07 17:12:08 UTC (rev 205552)
</span><span class="lines">@@ -32,10 +32,8 @@
</span><span class="cx"> #include &quot;WASMOps.h&quot;
</span><span class="cx"> #include &quot;WASMSections.h&quot;
</span><span class="cx"> 
</span><del>-namespace JSC {
</del><ins>+namespace JSC { namespace WASM {
</ins><span class="cx"> 
</span><del>-namespace WASM {
-
</del><span class="cx"> static const bool verbose = false;
</span><span class="cx"> 
</span><span class="cx"> bool ModuleParser::parse()
</span><span class="lines">@@ -163,9 +161,9 @@
</span><span class="cx">         argumentTypes.resize(argumentCount);
</span><span class="cx"> 
</span><span class="cx">         for (unsigned i = 0; i &lt; argumentCount; ++i) {
</span><del>-            if (!parseUInt7(type) || type &gt;= static_cast&lt;uint8_t&gt;(Type::LastValueType))
</del><ins>+            if (!parseUInt7(type) || !isValueType(static_cast&lt;Type&gt;(type)))
</ins><span class="cx">                 return false;
</span><del>-            argumentTypes.append(static_cast&lt;Type&gt;(type));
</del><ins>+            argumentTypes[i] = static_cast&lt;Type&gt;(type);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         if (!parseVarUInt1(type))
</span><span class="lines">@@ -233,8 +231,6 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-} // namespace WASM
</del><ins>+} } // namespace JSC::WASM
</ins><span class="cx"> 
</span><del>-} // namespace JSC
-
</del><span class="cx"> #endif // ENABLE(WEBASSEMBLY)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWASMModuleParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WASMModuleParser.h (205551 => 205552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WASMModuleParser.h        2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/JavaScriptCore/wasm/WASMModuleParser.h        2016-09-07 17:12:08 UTC (rev 205552)
</span><span class="lines">@@ -31,10 +31,8 @@
</span><span class="cx"> #include &quot;WASMParser.h&quot;
</span><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="cx"> 
</span><del>-namespace JSC {
</del><ins>+namespace JSC { namespace WASM {
</ins><span class="cx"> 
</span><del>-namespace WASM {
-
</del><span class="cx"> class ModuleParser : public Parser {
</span><span class="cx"> public:
</span><span class="cx"> 
</span><span class="lines">@@ -61,8 +59,6 @@
</span><span class="cx">     Vector&lt;Signature&gt; m_signatures;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-} // namespace WASM
</del><ins>+} } // namespace JSC::WASM
</ins><span class="cx"> 
</span><del>-} // namespace JSC
-
</del><span class="cx"> #endif // ENABLE(WEBASSEMBLY)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWASMOpsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WASMOps.h (205551 => 205552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WASMOps.h        2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/JavaScriptCore/wasm/WASMOps.h        2016-09-07 17:12:08 UTC (rev 205552)
</span><span class="lines">@@ -27,16 +27,18 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(WEBASSEMBLY)
</span><span class="cx"> 
</span><del>-namespace JSC {
</del><ins>+namespace JSC { namespace WASM {
</ins><span class="cx"> 
</span><del>-namespace WASM {
-
</del><span class="cx"> #define FOR_EACH_WASM_SPECIAL_OP(macro) \
</span><span class="cx">     macro(I32Const, 0x10, NA) \
</span><del>-    macro(GetLocal, 0x14, NA)
</del><ins>+    macro(GetLocal, 0x14, NA) \
+    macro(SetLocal, 0x15, NA)
</ins><span class="cx"> 
</span><span class="cx"> #define FOR_EACH_WASM_CONTROL_FLOW_OP(macro) \
</span><span class="cx">     macro(Block, 0x01, NA) \
</span><ins>+    macro(Loop, 0x02, NA) \
+    macro(Branch, 0x06, NA) \
+    macro(BranchIf, 0x07, NA) \
</ins><span class="cx">     macro(Return, 0x09, NA) \
</span><span class="cx">     macro(End, 0x0f, NA)
</span><span class="cx"> 
</span><span class="lines">@@ -121,8 +123,19 @@
</span><span class="cx"> 
</span><span class="cx"> #undef CREATE_ENUM_VALUE
</span><span class="cx"> 
</span><del>-} // namespace WASM
</del><ins>+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;
+}
</ins><span class="cx"> 
</span><del>-} // namespace JSC
</del><ins>+} } // namespace JSC::WASM
</ins><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(WEBASSEMBLY)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWASMParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WASMParser.h (205551 => 205552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WASMParser.h        2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/JavaScriptCore/wasm/WASMParser.h        2016-09-07 17:12:08 UTC (rev 205552)
</span><span class="lines">@@ -34,10 +34,8 @@
</span><span class="cx"> #include &quot;WASMSections.h&quot;
</span><span class="cx"> #include &lt;wtf/LEBDecoder.h&gt;
</span><span class="cx"> 
</span><del>-namespace JSC {
</del><ins>+namespace JSC { namespace WASM {
</ins><span class="cx"> 
</span><del>-namespace WASM {
-
</del><span class="cx"> class Parser {
</span><span class="cx"> protected:
</span><span class="cx">     Parser(const Vector&lt;uint8_t&gt;&amp;, size_t start, size_t end);
</span><span class="lines">@@ -127,8 +125,6 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-} // namespace WASM
</del><ins>+} } // namespace JSC::WASM
</ins><span class="cx"> 
</span><del>-} // namespace JSC
-
</del><span class="cx"> #endif // ENABLE(WEBASSEMBLY)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWASMPlancpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WASMPlan.cpp (205551 => 205552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WASMPlan.cpp        2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/JavaScriptCore/wasm/WASMPlan.cpp        2016-09-07 17:12:08 UTC (rev 205552)
</span><span class="lines">@@ -33,10 +33,8 @@
</span><span class="cx"> #include &quot;WASMModuleParser.h&quot;
</span><span class="cx"> #include &lt;wtf/DataLog.h&gt;
</span><span class="cx"> 
</span><del>-namespace JSC {
</del><ins>+namespace JSC { namespace WASM {
</ins><span class="cx"> 
</span><del>-namespace WASM {
-
</del><span class="cx"> static const bool verbose = false;
</span><span class="cx"> 
</span><span class="cx"> Plan::Plan(VM&amp; vm, Vector&lt;uint8_t&gt; source)
</span><span class="lines">@@ -59,8 +57,6 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-} // namespace WASM
</del><ins>+} } // namespace JSC::WASM
</ins><span class="cx"> 
</span><del>-} // namespace JSC
-
</del><span class="cx"> #endif // ENABLE(WEBASSEMBLY)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWASMPlanh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WASMPlan.h (205551 => 205552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WASMPlan.h        2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/JavaScriptCore/wasm/WASMPlan.h        2016-09-07 17:12:08 UTC (rev 205552)
</span><span class="lines">@@ -48,8 +48,6 @@
</span><span class="cx">     Vector&lt;std::unique_ptr&lt;B3::Compilation&gt;&gt; result;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-} // namespace WASM
</del><ins>+} } // namespace JSC::WASM
</ins><span class="cx"> 
</span><del>-} // namespace JSC
-
</del><span class="cx"> #endif // ENABLE(WEBASSEMBLY)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWASMSectionscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WASMSections.cpp (205551 => 205552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WASMSections.cpp        2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/JavaScriptCore/wasm/WASMSections.cpp        2016-09-07 17:12:08 UTC (rev 205552)
</span><span class="lines">@@ -31,10 +31,8 @@
</span><span class="cx"> #include &lt;wtf/DataLog.h&gt;
</span><span class="cx"> #include &lt;wtf/text/WTFString.h&gt;
</span><span class="cx"> 
</span><del>-namespace JSC {
</del><ins>+namespace JSC { namespace WASM {
</ins><span class="cx"> 
</span><del>-namespace WASM {
-
</del><span class="cx"> struct SectionData {
</span><span class="cx">     unsigned length;
</span><span class="cx">     const char* name;
</span><span class="lines">@@ -62,8 +60,6 @@
</span><span class="cx">     return Sections::Unknown;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-} // namespace WASM
</del><ins>+} } // namespace JSC::WASM
</ins><span class="cx"> 
</span><del>-} // namespace JSC
-
</del><span class="cx"> #endif // ENABLE(WEBASSEMBLY)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWASMSectionsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WASMSections.h (205551 => 205552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WASMSections.h        2016-09-07 17:04:45 UTC (rev 205551)
+++ trunk/Source/JavaScriptCore/wasm/WASMSections.h        2016-09-07 17:12:08 UTC (rev 205552)
</span><span class="lines">@@ -27,10 +27,8 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(WEBASSEMBLY)
</span><span class="cx"> 
</span><del>-namespace JSC {
</del><ins>+namespace JSC { namespace WASM {
</ins><span class="cx"> 
</span><del>-namespace WASM {
-
</del><span class="cx"> // These should be in the order that we expect them to be in the binary.
</span><span class="cx"> #define FOR_EACH_WASM_SECTION_TYPE(macro) \
</span><span class="cx">     macro(FunctionTypes, &quot;type&quot;) \
</span><span class="lines">@@ -56,8 +54,6 @@
</span><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-} // namespace WASM
</del><ins>+} } // namespace JSC::WASM
</ins><span class="cx"> 
</span><del>-} // namespace JSC
-
</del><span class="cx"> #endif // ENABLE(WEBASSEMBLY)
</span></span></pre>
</div>
</div>

</body>
</html>