<!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>[208627] trunk</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/208627">208627</a></dd>
<dt>Author</dt> <dd>keith_miller@apple.com</dd>
<dt>Date</dt> <dd>2016-11-11 16:29:36 -0800 (Fri, 11 Nov 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Move Wasm tests to JS
https://bugs.webkit.org/show_bug.cgi?id=164611

Reviewed by Geoffrey Garen.

This patch translates most of the tests from testWasm.cpp to the JS testing api. Most of the
ommited tests were earliest tests, which tested trivial things, like adding two
constants. Some tests are ommited for other reasons, however. These are:

1) Tests using I64 since the testing api does not yet know how to handle 64-bit numbers.  2)
Tests that would validate the memory of the module once wasm was done with it since that's
not really possible in JS.

In order to make such a translation easier this patch also adds some features to the JS
testing api:

1) Blocks can now be done lexically by adding a lambda as the last argument of the block
opcode. For example one can do:
    ...
    .Block(&quot;i32&quot;, b =&gt; b.I32Const(1) )

and the nested lambda will automatically have an end attached.

2) The JS testing api can now handle inline signature types.

3) Relocate some code to make it easier to follow and prevent 44 space indentation.

4) Rename varuint/varint to varuint32/varint32, this lets them be directly called from the
wasm.json without being remapped.

5) Add support for Memory and Function sections to the Builder.

6) Add support for local variables.

On the JSC side, we needed to expose a new function to validate the compiled wasm code
behaves the way we expect. At least until the JS Wasm API is finished. The new validation
function, testWasmModuleFunctions, takes an array buffer containing the wasm binary, the
number of functions in the blob and tests for each of those functions.

JSTests:

* wasm/Builder.js:
(const._maybeRegisterType):
(const): Deleted.
(switch.typeof): Deleted.
* wasm/Builder_WebAssemblyBinary.js:
(const.emitters.Type):
(const.emitters.Import):
(const.emitters.Function):
(const.emitters.Memory):
(const.emitters.Code):
(export.const.Binary):
* wasm/LowLevelBinary.js:
(export.default.LowLevelBinary.prototype.get return):
(export.default.LowLevelBinary.prototype.varuint32):
(export.default.LowLevelBinary.prototype.varint32):
(export.default.LowLevelBinary.prototype.varuint1):
(export.default.LowLevelBinary.prototype.varint7):
(export.default.LowLevelBinary.prototype.varuint7):
(export.default.LowLevelBinary.prototype.inline_signature_type):
(export.default.LowLevelBinary.prototype.string):
(export.default.LowLevelBinary.prototype.getVaruint32):
(export.default.LowLevelBinary.prototype.getVarint32):
(export.default.LowLevelBinary.prototype.getVaruint7):
(export.default.LowLevelBinary.prototype.getString):
(export.default.LowLevelBinary):
(export.default.LowLevelBinary.prototype.varuint): Deleted.
(export.default.LowLevelBinary.prototype.varint): Deleted.
(export.default.LowLevelBinary.prototype.getVaruint): Deleted.
(export.default.LowLevelBinary.prototype.getVarint): Deleted.
* wasm/js-api/test_old_tests.js: Added.
(ret5):
(brTableWithLoop):
(brTableManyValues):
(run.brTableManyValues.brTableAsIf):
(ifThenFallthrough):
(ifThenElseFallthrough):
(dumbLessThanFallthrough):
(run.dumbLessThanFallthrough.floatSub):
(run.floatSub.add12):
(run.add12.factorial):
(i32load):
(run.i32load.i32load8s):
(run.i32load8s.dumbEqIfThenElse):
(run.dumbEqIfThenElse.dumbEqIfThenElse):
(run.dumbEqIfThenElse.dumbLessThanIfThenElse):
(run.dumbLessThanIfThenElse.loopSum):
(run.loopSum.loopMult):
(brIfLoopLessThan):
(run.brIfLoopLessThan.run):
* wasm/self-test/test_LowLevelBinary_varint32.js: Renamed from JSTests/wasm/self-test/test_LowLevelBinary_varint.js.
* wasm/self-test/test_LowLevelBinary_varuint32.js: Renamed from JSTests/wasm/self-test/test_LowLevelBinary_varuint.js.

* wasm/Builder.js:
(const._maybeRegisterType):
(const): Deleted.
(switch.typeof): Deleted.
* wasm/Builder_WebAssemblyBinary.js:
(const.emitters.Type):
(const.emitters.Import):
(const.emitters.Function):
(const.emitters.Memory):
(const.emitters.Code):
(export.const.Binary):
* wasm/LowLevelBinary.js:
(export.default.LowLevelBinary.prototype.get return):
(export.default.LowLevelBinary.prototype.varuint32):
(export.default.LowLevelBinary.prototype.varint32):
(export.default.LowLevelBinary.prototype.varuint1):
(export.default.LowLevelBinary.prototype.varint7):
(export.default.LowLevelBinary.prototype.varuint7):
(export.default.LowLevelBinary.prototype.inline_signature_type):
(export.default.LowLevelBinary.prototype.string):
(export.default.LowLevelBinary.prototype.getVaruint32):
(export.default.LowLevelBinary.prototype.getVarint32):
(export.default.LowLevelBinary.prototype.getVaruint7):
(export.default.LowLevelBinary.prototype.getString):
(export.default.LowLevelBinary):
(export.default.LowLevelBinary.prototype.varuint): Deleted.
(export.default.LowLevelBinary.prototype.varint): Deleted.
(export.default.LowLevelBinary.prototype.getVaruint): Deleted.
(export.default.LowLevelBinary.prototype.getVarint): Deleted.
* wasm/js-api/function-tests/add-12.js: Added.
* wasm/js-api/function-tests/br-if-loop-less-than.js: Added.
* wasm/js-api/function-tests/brTableAsIf.js: Added.
* wasm/js-api/function-tests/brTableManyValues.js: Added.
* wasm/js-api/function-tests/brTableWithLoop.js: Added.
* wasm/js-api/function-tests/dumb-eq-if-then-else.js: Added.
* wasm/js-api/function-tests/dumb-less-than-fallthrough.js: Added.
* wasm/js-api/function-tests/dumb-less-than-ite.js: Added.
* wasm/js-api/function-tests/factorial.js: Added.
* wasm/js-api/function-tests/float-sub.js: Added.
* wasm/js-api/function-tests/i32-load.js: Added.
* wasm/js-api/function-tests/i32-load8-s.js: Added.
* wasm/js-api/function-tests/if-then-else-fallthrough.js: Added.
* wasm/js-api/function-tests/if-then-fallthrough.js: Added.
* wasm/js-api/function-tests/loop-mult.js: Added.
* wasm/js-api/function-tests/loop-sum.js: Added.
* wasm/js-api/function-tests/ret5.js: Added.
* wasm/self-test/test_LowLevelBinary_varint32.js: Renamed from JSTests/wasm/self-test/test_LowLevelBinary_varint.js.
* wasm/self-test/test_LowLevelBinary_varuint32.js: Renamed from JSTests/wasm/self-test/test_LowLevelBinary_varuint.js.

Source/JavaScriptCore:

* jsc.cpp:
(GlobalObject::finishCreation):
(box):
(callWasmFunction):
(functionTestWasmModuleFunctions):
* testWasm.cpp:
(checkPlan):
(runWasmTests):
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::parseAndCompile):
* wasm/WasmFunctionParser.h:
(JSC::Wasm::FunctionParser&lt;Context&gt;::parse):
(JSC::Wasm::FunctionParser&lt;Context&gt;::parseBody):
(JSC::Wasm::FunctionParser&lt;Context&gt;::parseBlock): Deleted.
* wasm/WasmModuleParser.cpp:
(JSC::Wasm::ModuleParser::parseMemory):
(JSC::Wasm::ModuleParser::parseExport):
* wasm/WasmPlan.cpp:
(JSC::Wasm::Plan::Plan):
(JSC::Wasm::Plan::run):
* wasm/WasmPlan.h:
* wasm/js/WebAssemblyModuleConstructor.cpp:
(JSC::constructJSWebAssemblyModule):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkJSTestsChangeLog">trunk/JSTests/ChangeLog</a></li>
<li><a href="#trunkJSTestswasmBuilderjs">trunk/JSTests/wasm/Builder.js</a></li>
<li><a href="#trunkJSTestswasmBuilder_WebAssemblyBinaryjs">trunk/JSTests/wasm/Builder_WebAssemblyBinary.js</a></li>
<li><a href="#trunkJSTestswasmLowLevelBinaryjs">trunk/JSTests/wasm/LowLevelBinary.js</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCorejsccpp">trunk/Source/JavaScriptCore/jsc.cpp</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="#trunkSourceJavaScriptCorewasmWasmFunctionParserh">trunk/Source/JavaScriptCore/wasm/WasmFunctionParser.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmModuleParsercpp">trunk/Source/JavaScriptCore/wasm/WasmModuleParser.cpp</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="#trunkSourceJavaScriptCorewasmjsWebAssemblyModuleConstructorcpp">trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleConstructor.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li>trunk/JSTests/wasm/js-api/function-tests/</li>
<li><a href="#trunkJSTestswasmjsapifunctiontestsadd12js">trunk/JSTests/wasm/js-api/function-tests/add-12.js</a></li>
<li><a href="#trunkJSTestswasmjsapifunctiontestsbriflooplessthanjs">trunk/JSTests/wasm/js-api/function-tests/br-if-loop-less-than.js</a></li>
<li><a href="#trunkJSTestswasmjsapifunctiontestsbrTableAsIfjs">trunk/JSTests/wasm/js-api/function-tests/brTableAsIf.js</a></li>
<li><a href="#trunkJSTestswasmjsapifunctiontestsbrTableManyValuesjs">trunk/JSTests/wasm/js-api/function-tests/brTableManyValues.js</a></li>
<li><a href="#trunkJSTestswasmjsapifunctiontestsbrTableWithLoopjs">trunk/JSTests/wasm/js-api/function-tests/brTableWithLoop.js</a></li>
<li><a href="#trunkJSTestswasmjsapifunctiontestsdumbeqifthenelsejs">trunk/JSTests/wasm/js-api/function-tests/dumb-eq-if-then-else.js</a></li>
<li><a href="#trunkJSTestswasmjsapifunctiontestsdumblessthanfallthroughjs">trunk/JSTests/wasm/js-api/function-tests/dumb-less-than-fallthrough.js</a></li>
<li><a href="#trunkJSTestswasmjsapifunctiontestsdumblessthanitejs">trunk/JSTests/wasm/js-api/function-tests/dumb-less-than-ite.js</a></li>
<li><a href="#trunkJSTestswasmjsapifunctiontestsfactorialjs">trunk/JSTests/wasm/js-api/function-tests/factorial.js</a></li>
<li><a href="#trunkJSTestswasmjsapifunctiontestsfloatsubjs">trunk/JSTests/wasm/js-api/function-tests/float-sub.js</a></li>
<li><a href="#trunkJSTestswasmjsapifunctiontestsi32loadjs">trunk/JSTests/wasm/js-api/function-tests/i32-load.js</a></li>
<li><a href="#trunkJSTestswasmjsapifunctiontestsi32load8sjs">trunk/JSTests/wasm/js-api/function-tests/i32-load8-s.js</a></li>
<li><a href="#trunkJSTestswasmjsapifunctiontestsifthenelsefallthroughjs">trunk/JSTests/wasm/js-api/function-tests/if-then-else-fallthrough.js</a></li>
<li><a href="#trunkJSTestswasmjsapifunctiontestsifthenfallthroughjs">trunk/JSTests/wasm/js-api/function-tests/if-then-fallthrough.js</a></li>
<li><a href="#trunkJSTestswasmjsapifunctiontestsloopmultjs">trunk/JSTests/wasm/js-api/function-tests/loop-mult.js</a></li>
<li><a href="#trunkJSTestswasmjsapifunctiontestsloopsumjs">trunk/JSTests/wasm/js-api/function-tests/loop-sum.js</a></li>
<li><a href="#trunkJSTestswasmjsapifunctiontestsret5js">trunk/JSTests/wasm/js-api/function-tests/ret5.js</a></li>
<li><a href="#trunkJSTestswasmselftesttest_LowLevelBinary_varint32js">trunk/JSTests/wasm/self-test/test_LowLevelBinary_varint32.js</a></li>
<li><a href="#trunkJSTestswasmselftesttest_LowLevelBinary_varuint32js">trunk/JSTests/wasm/self-test/test_LowLevelBinary_varuint32.js</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkJSTestswasmselftesttest_LowLevelBinary_varintjs">trunk/JSTests/wasm/self-test/test_LowLevelBinary_varint.js</a></li>
<li><a href="#trunkJSTestswasmselftesttest_LowLevelBinary_varuintjs">trunk/JSTests/wasm/self-test/test_LowLevelBinary_varuint.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkJSTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/ChangeLog (208626 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/ChangeLog        2016-11-12 00:28:29 UTC (rev 208626)
+++ trunk/JSTests/ChangeLog        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -1,3 +1,145 @@
</span><ins>+2016-11-11  Keith Miller  &lt;keith_miller@apple.com&gt;
+
+        Move Wasm tests to JS
+        https://bugs.webkit.org/show_bug.cgi?id=164611
+
+        Reviewed by Geoffrey Garen.
+
+        This patch translates most of the tests from testWasm.cpp to the JS testing api. Most of the
+        ommited tests were earliest tests, which tested trivial things, like adding two
+        constants. Some tests are ommited for other reasons, however. These are:
+
+        1) Tests using I64 since the testing api does not yet know how to handle 64-bit numbers.  2)
+        Tests that would validate the memory of the module once wasm was done with it since that's
+        not really possible in JS.
+
+        In order to make such a translation easier this patch also adds some features to the JS
+        testing api:
+
+        1) Blocks can now be done lexically by adding a lambda as the last argument of the block
+        opcode. For example one can do:
+            ...
+            .Block(&quot;i32&quot;, b =&gt; b.I32Const(1) )
+
+        and the nested lambda will automatically have an end attached.
+
+        2) The JS testing api can now handle inline signature types.
+
+        3) Relocate some code to make it easier to follow and prevent 44 space indentation.
+
+        4) Rename varuint/varint to varuint32/varint32, this lets them be directly called from the
+        wasm.json without being remapped.
+
+        5) Add support for Memory and Function sections to the Builder.
+
+        6) Add support for local variables.
+
+        On the JSC side, we needed to expose a new function to validate the compiled wasm code
+        behaves the way we expect. At least until the JS Wasm API is finished. The new validation
+        function, testWasmModuleFunctions, takes an array buffer containing the wasm binary, the
+        number of functions in the blob and tests for each of those functions.
+
+        * wasm/Builder.js:
+        (const._maybeRegisterType):
+        (const): Deleted.
+        (switch.typeof): Deleted.
+        * wasm/Builder_WebAssemblyBinary.js:
+        (const.emitters.Type):
+        (const.emitters.Import):
+        (const.emitters.Function):
+        (const.emitters.Memory):
+        (const.emitters.Code):
+        (export.const.Binary):
+        * wasm/LowLevelBinary.js:
+        (export.default.LowLevelBinary.prototype.get return):
+        (export.default.LowLevelBinary.prototype.varuint32):
+        (export.default.LowLevelBinary.prototype.varint32):
+        (export.default.LowLevelBinary.prototype.varuint1):
+        (export.default.LowLevelBinary.prototype.varint7):
+        (export.default.LowLevelBinary.prototype.varuint7):
+        (export.default.LowLevelBinary.prototype.inline_signature_type):
+        (export.default.LowLevelBinary.prototype.string):
+        (export.default.LowLevelBinary.prototype.getVaruint32):
+        (export.default.LowLevelBinary.prototype.getVarint32):
+        (export.default.LowLevelBinary.prototype.getVaruint7):
+        (export.default.LowLevelBinary.prototype.getString):
+        (export.default.LowLevelBinary):
+        (export.default.LowLevelBinary.prototype.varuint): Deleted.
+        (export.default.LowLevelBinary.prototype.varint): Deleted.
+        (export.default.LowLevelBinary.prototype.getVaruint): Deleted.
+        (export.default.LowLevelBinary.prototype.getVarint): Deleted.
+        * wasm/js-api/test_old_tests.js: Added.
+        (ret5):
+        (brTableWithLoop):
+        (brTableManyValues):
+        (run.brTableManyValues.brTableAsIf):
+        (ifThenFallthrough):
+        (ifThenElseFallthrough):
+        (dumbLessThanFallthrough):
+        (run.dumbLessThanFallthrough.floatSub):
+        (run.floatSub.add12):
+        (run.add12.factorial):
+        (i32load):
+        (run.i32load.i32load8s):
+        (run.i32load8s.dumbEqIfThenElse):
+        (run.dumbEqIfThenElse.dumbEqIfThenElse):
+        (run.dumbEqIfThenElse.dumbLessThanIfThenElse):
+        (run.dumbLessThanIfThenElse.loopSum):
+        (run.loopSum.loopMult):
+        (brIfLoopLessThan):
+        (run.brIfLoopLessThan.run):
+        * wasm/self-test/test_LowLevelBinary_varint32.js: Renamed from JSTests/wasm/self-test/test_LowLevelBinary_varint.js.
+        * wasm/self-test/test_LowLevelBinary_varuint32.js: Renamed from JSTests/wasm/self-test/test_LowLevelBinary_varuint.js.
+
+        * wasm/Builder.js:
+        (const._maybeRegisterType):
+        (const): Deleted.
+        (switch.typeof): Deleted.
+        * wasm/Builder_WebAssemblyBinary.js:
+        (const.emitters.Type):
+        (const.emitters.Import):
+        (const.emitters.Function):
+        (const.emitters.Memory):
+        (const.emitters.Code):
+        (export.const.Binary):
+        * wasm/LowLevelBinary.js:
+        (export.default.LowLevelBinary.prototype.get return):
+        (export.default.LowLevelBinary.prototype.varuint32):
+        (export.default.LowLevelBinary.prototype.varint32):
+        (export.default.LowLevelBinary.prototype.varuint1):
+        (export.default.LowLevelBinary.prototype.varint7):
+        (export.default.LowLevelBinary.prototype.varuint7):
+        (export.default.LowLevelBinary.prototype.inline_signature_type):
+        (export.default.LowLevelBinary.prototype.string):
+        (export.default.LowLevelBinary.prototype.getVaruint32):
+        (export.default.LowLevelBinary.prototype.getVarint32):
+        (export.default.LowLevelBinary.prototype.getVaruint7):
+        (export.default.LowLevelBinary.prototype.getString):
+        (export.default.LowLevelBinary):
+        (export.default.LowLevelBinary.prototype.varuint): Deleted.
+        (export.default.LowLevelBinary.prototype.varint): Deleted.
+        (export.default.LowLevelBinary.prototype.getVaruint): Deleted.
+        (export.default.LowLevelBinary.prototype.getVarint): Deleted.
+        * wasm/js-api/function-tests/add-12.js: Added.
+        * wasm/js-api/function-tests/br-if-loop-less-than.js: Added.
+        * wasm/js-api/function-tests/brTableAsIf.js: Added.
+        * wasm/js-api/function-tests/brTableManyValues.js: Added.
+        * wasm/js-api/function-tests/brTableWithLoop.js: Added.
+        * wasm/js-api/function-tests/dumb-eq-if-then-else.js: Added.
+        * wasm/js-api/function-tests/dumb-less-than-fallthrough.js: Added.
+        * wasm/js-api/function-tests/dumb-less-than-ite.js: Added.
+        * wasm/js-api/function-tests/factorial.js: Added.
+        * wasm/js-api/function-tests/float-sub.js: Added.
+        * wasm/js-api/function-tests/i32-load.js: Added.
+        * wasm/js-api/function-tests/i32-load8-s.js: Added.
+        * wasm/js-api/function-tests/if-then-else-fallthrough.js: Added.
+        * wasm/js-api/function-tests/if-then-fallthrough.js: Added.
+        * wasm/js-api/function-tests/loop-mult.js: Added.
+        * wasm/js-api/function-tests/loop-sum.js: Added.
+        * wasm/js-api/function-tests/ret5.js: Added.
+        * wasm/self-test/test_LowLevelBinary_varint32.js: Renamed from JSTests/wasm/self-test/test_LowLevelBinary_varint.js.
+        * wasm/self-test/test_LowLevelBinary_varuint32.js: Renamed from JSTests/wasm/self-test/test_LowLevelBinary_varuint.js.
+
</ins><span class="cx"> 2016-11-11  Saam Barati  &lt;sbarati@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         We recursively grab a lock in the DFGBytecodeParser causing us to deadlock
</span></span></pre></div>
<a id="trunkJSTestswasmBuilderjs"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/wasm/Builder.js (208626 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/Builder.js        2016-11-12 00:28:29 UTC (rev 208626)
+++ trunk/JSTests/wasm/Builder.js        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -60,14 +60,14 @@
</span><span class="cx">     if (typeof(type) === &quot;number&quot;) {
</span><span class="cx">         // Type numbers already refer to the type section, no need to register them.
</span><span class="cx">         if (builder._checked) {
</span><del>-            assert.isNotUndef(typeSection, `Can't use type ${type} if a type section isn't present`);
-            assert.isNotUndef(typeSection.data[type], `Type ${type} doesn't exist in type section`);
</del><ins>+            assert.isNotUndef(typeSection, `Can not use type ${type} if a type section is not present`);
+            assert.isNotUndef(typeSection.data[type], `Type ${type} does not exist in type section`);
</ins><span class="cx">         }
</span><span class="cx">         return type;
</span><span class="cx">     }
</span><span class="cx">     assert.hasObjectProperty(type, &quot;params&quot;, `Expected type to be a number or object with 'params' and optionally 'ret' fields`);
</span><span class="cx">     const [params, ret] = _normalizeFunctionSignature(type.params, type.ret);
</span><del>-    assert.isNotUndef(typeSection, `Can't add type if a type section isn't present`);
</del><ins>+    assert.isNotUndef(typeSection, `Can not add type if a type section is not present`);
</ins><span class="cx">     // Try reusing an equivalent type from the type section.
</span><span class="cx">     types:
</span><span class="cx">     for (let i = 0; i !== typeSection.data.length; ++i) {
</span><span class="lines">@@ -154,6 +154,156 @@
</span><span class="cx">     };
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+const _checkStackArgs = (op, param) =&gt; {
+    for (let expect of paramn) {
+        if (WASM.isValidValueType(expect)) {
+            // FIXME implement stack checks for arguments. https://bugs.webkit.org/show_bug.cgi?id=163421
+        } else {
+            // Handle our own meta-types.
+            switch (expect) {
+            case &quot;addr&quot;: break; // FIXME implement addr. https://bugs.webkit.org/show_bug.cgi?id=163421
+            case &quot;any&quot;: break; // FIXME implement any. https://bugs.webkit.org/show_bug.cgi?id=163421
+            case &quot;bool&quot;: break; // FIXME implement bool. https://bugs.webkit.org/show_bug.cgi?id=163421
+            case &quot;call&quot;: break; // FIXME implement call stack argument checks based on function signature. https://bugs.webkit.org/show_bug.cgi?id=163421
+            case &quot;global&quot;: break; // FIXME implement global. https://bugs.webkit.org/show_bug.cgi?id=163421
+            case &quot;local&quot;: break; // FIXME implement local. https://bugs.webkit.org/show_bug.cgi?id=163421
+            case &quot;prev&quot;: break; // FIXME implement prev, checking for whetever the previous value was. https://bugs.webkit.org/show_bug.cgi?id=163421
+            case &quot;size&quot;: break; // FIXME implement size. https://bugs.webkit.org/show_bug.cgi?id=163421
+            default: throw new Error(`Implementation problem: unhandled meta-type &quot;${expect}&quot; on &quot;${op}&quot;`);
+            }
+        }
+    }
+}
+
+const _checkStackReturn = (op, ret) =&gt; {
+    for (let expect of ret) {
+        if (WASM.isValidValueType(expect)) {
+            // FIXME implement stack checks for return. https://bugs.webkit.org/show_bug.cgi?id=163421
+        } else {
+            // Handle our own meta-types.
+            switch (expect) {
+            case &quot;bool&quot;: break; // FIXME implement bool. https://bugs.webkit.org/show_bug.cgi?id=163421
+            case &quot;call&quot;: break; // FIXME implement call stack return check based on function signature. https://bugs.webkit.org/show_bug.cgi?id=163421
+            case &quot;control&quot;: break; // FIXME implement control. https://bugs.webkit.org/show_bug.cgi?id=163421
+            case &quot;global&quot;: break; // FIXME implement global. https://bugs.webkit.org/show_bug.cgi?id=163421
+            case &quot;local&quot;: break; // FIXME implement local. https://bugs.webkit.org/show_bug.cgi?id=163421
+            case &quot;prev&quot;: break; // FIXME implement prev, checking for whetever the parameter type was. https://bugs.webkit.org/show_bug.cgi?id=163421
+            case &quot;size&quot;: break; // FIXME implement size. https://bugs.webkit.org/show_bug.cgi?id=163421
+            default: throw new Error(`Implementation problem: unhandled meta-type &quot;${expect}&quot; on &quot;${op}&quot;`);
+                                            }
+        }
+    }
+};
+
+const _checkImms = (op, imms, expectedImms) =&gt; {
+    assert.eq(imms.length, expectedImms.length, `&quot;${op}&quot; expects ${expectedImms.length} immediates, got ${imms.length}`);
+    for (let idx = 0; idx !== expectedImms.length; ++idx) {
+        const got = imms[idx];
+        const expect = expectedImms[idx];
+        switch (expect.name) {
+        case &quot;function_index&quot;:
+            assert.truthy(_isValidValue(got, &quot;i32&quot;), `Invalid value on ${op}: got &quot;${got}&quot;, expected i32`);
+            // FIXME check function indices. https://bugs.webkit.org/show_bug.cgi?id=163421
+            break;
+        case &quot;local_index&quot;: throw new Error(`Unimplemented: &quot;${expect.name}&quot; on &quot;${op}&quot;`);
+        case &quot;global_index&quot;: throw new Error(`Unimplemented: &quot;${expect.name}&quot; on &quot;${op}&quot;`);
+        case &quot;type_index&quot;: throw new Error(`Unimplemented: &quot;${expect.name}&quot; on &quot;${op}&quot;`);
+        case &quot;value&quot;:
+            assert.truthy(_isValidValue(got, ret[0]), `Invalid value on ${op}: got &quot;${got}&quot;, expected ${ret[0]}`);
+            break;
+        case &quot;flags&quot;: throw new Error(`Unimplemented: &quot;${expect.name}&quot; on &quot;${op}&quot;`);
+        case &quot;offset&quot;: throw new Error(`Unimplemented: &quot;${expect.name}&quot; on &quot;${op}&quot;`);
+            // Control:
+        case &quot;default_target&quot;: throw new Error(`Unimplemented: &quot;${expect.name}&quot; on &quot;${op}&quot;`);
+        case &quot;relative_depth&quot;: throw new Error(`Unimplemented: &quot;${expect.name}&quot; on &quot;${op}&quot;`);
+        case &quot;sig&quot;: throw new Error(`Unimplemented: &quot;${expect.name}&quot; on &quot;${op}&quot;`);
+        case &quot;target_count&quot;: throw new Error(`Unimplemented: &quot;${expect.name}&quot; on &quot;${op}&quot;`);
+        case &quot;target_table&quot;: throw new Error(`Unimplemented: &quot;${expect.name}&quot; on &quot;${op}&quot;`);
+        default: throw new Error(`Implementation problem: unhandled immediate &quot;${expect.name}&quot; on &quot;${op}&quot;`);
+        }
+    }
+};
+
+const _createFunctionBuilder = (func, builder, previousBuilder) =&gt; {
+    let functionBuilder = {};
+    for (const op in WASM.description.opcode) {
+        const name = _toJavaScriptName(op);
+        const value = WASM.description.opcode[op].value;
+        const ret = WASM.description.opcode[op][&quot;return&quot;];
+        const param = WASM.description.opcode[op].parameter;
+        const imm = WASM.description.opcode[op].immediate;
+
+        const checkStackArgs = builder._checked ? _checkStackArgs : () =&gt; {};
+        const checkStackReturn = builder._checked ? _checkStackReturn : () =&gt; {};
+        const checkImms = builder._checked ? _checkImms : () =&gt; {};
+
+        functionBuilder[name] = (...args) =&gt; {
+            let nextBuilder;
+            switch (name) {
+            default:
+                nextBuilder = functionBuilder;
+                break;
+                case &quot;End&quot;:
+                nextBuilder = previousBuilder;
+                    break;
+            case &quot;Block&quot;:
+                case &quot;Loop&quot;:
+            case &quot;If&quot;:
+                nextBuilder = _createFunctionBuilder(func, builder, functionBuilder);
+                break;
+            }
+
+            // Passing a function as the argument is a way to nest blocks lexically.
+            const continuation = args[args.length - 1];
+            const hasContinuation = typeof(continuation) === &quot;function&quot;;
+            const imms = hasContinuation ? args.slice(0, -1) : args; // FIXME: allow passing in stack values, as-if code were a stack machine. Just check for a builder to this function, and drop. https://bugs.webkit.org/show_bug.cgi?id=163422
+            checkImms(op, imms, imm);
+            checkStackArgs(op, param);
+            checkStackReturn(op, ret);
+            const stackArgs = []; // FIXME https://bugs.webkit.org/show_bug.cgi?id=162706
+            func.code.push({ name: op, value: value, arguments: stackArgs, immediates: imms });
+            if (hasContinuation)
+                return continuation(nextBuilder).End();
+            return nextBuilder;
+        };
+    }
+    return functionBuilder;
+}
+
+const _createFunction = (section, builder, previousBuilder) =&gt; {
+    return (...args) =&gt; {
+        const nameOffset = (typeof(args[0]) === &quot;string&quot;) &gt;&gt;&gt; 0;
+        const functionName = nameOffset ? args[0] : undefined;
+        let signature = args[0 + nameOffset];
+        const locals = args[1 + nameOffset] === undefined ? [] : args[1 + nameOffset];
+        for (const local of locals)
+            assert.truthy(WASM.isValidValueType(local), `Type of local: ${local} needs to be a valid value type`);
+
+        if (typeof(signature) === &quot;undefined&quot;)
+            signature = { params: [] };
+        assert.hasObjectProperty(signature, &quot;params&quot;, `Expect function signature to be an object with a &quot;params&quot; field, got &quot;${signature}&quot;`);
+        const [params, ret] = _normalizeFunctionSignature(signature.params, signature.ret);
+        signature = { params: params, ret: ret };
+        const func = {
+            name: functionName,
+            type: _maybeRegisterType(builder, signature),
+            signature: signature,
+            locals: params.concat(locals), // Parameters are the first locals.
+            parameterCount: params.length,
+            code: []
+        };
+
+        const functionSection = builder._getSection(&quot;Function&quot;);
+        if (functionSection)
+            functionSection.data.push(func.type);
+
+        section.data.push(func);
+        builder._registerFunctionToIndexSpace(functionName);
+
+        return _createFunctionBuilder(func, builder, previousBuilder);
+    }
+};
+
</ins><span class="cx"> export default class Builder {
</span><span class="cx">     constructor() {
</span><span class="cx">         this.setChecked(true);
</span><span class="lines">@@ -218,6 +368,7 @@
</span><span class="cx">                     return importBuilder;
</span><span class="cx">                 };
</span><span class="cx">                 break;
</span><ins>+
</ins><span class="cx">             case &quot;Export&quot;:
</span><span class="cx">                 this[section] = function() {
</span><span class="cx">                     const s = this._addSection(section);
</span><span class="lines">@@ -231,6 +382,32 @@
</span><span class="cx">                     return exportBuilder;
</span><span class="cx">                 };
</span><span class="cx">                 break;
</span><ins>+
+            case &quot;Memory&quot;:
+                this[section] = function() {
+                    const s = this._addSection(section);
+                    const exportBuilder = {
+                        End: () =&gt; this,
+                        InitialMaxPages: (initial, max) =&gt; {
+                            s.data.push({ initial, max });
+                            return exportBuilder;
+                        }
+                    };
+                    return exportBuilder;
+                }
+                break;
+
+            case &quot;Function&quot;:
+                this[section] = function() {
+                    const s = this._addSection(section);
+                    const exportBuilder = {
+                        End: () =&gt; this
+                        // FIXME: add ability to add this with whatever.
+                    }
+                    return exportBuilder;
+                }
+                break;
+
</ins><span class="cx">             case &quot;Code&quot;:
</span><span class="cx">                 this[section] = function() {
</span><span class="cx">                     const s = this._addSection(section);
</span><span class="lines">@@ -254,7 +431,7 @@
</span><span class="cx">                                     case &quot;number&quot;: {
</span><span class="cx">                                         const index = builder._getFunctionFromIndexSpace(e.index);
</span><span class="cx">                                         if (builder._checked)
</span><del>-                                            assert.isNotUndef(index, `Export &quot;${e.field}&quot; doesn't correspond to a defined value in the function index space`);
</del><ins>+                                            assert.isNotUndef(index, `Export &quot;${e.field}&quot; does not correspond to a defined value in the function index space`);
</ins><span class="cx">                                     } break;
</span><span class="cx">                                     case &quot;undefined&quot;:
</span><span class="cx">                                         throw new Error(`Unimplemented: Function().End() with undefined export index`); // FIXME
</span><span class="lines">@@ -269,115 +446,13 @@
</span><span class="cx">                             }
</span><span class="cx">                             return builder;
</span><span class="cx">                         },
</span><del>-                        Function: (a0, a1) =&gt; {
-                            let signature = typeof(a0) === &quot;string&quot; ? a1 : a0;
-                            const functionName = typeof(a0) === &quot;string&quot; ? a0 : undefined;
-                            if (typeof(signature) === &quot;undefined&quot;)
-                                signature = { params: [] };
-                            assert.hasObjectProperty(signature, &quot;params&quot;, `Expect function signature to be an object with a &quot;params&quot; field, got &quot;${signature}&quot;`);
-                            const [params, ret] = _normalizeFunctionSignature(signature.params, signature.ret);
-                            signature = { params: params, ret: ret };
-                            const func = {
-                                name: functionName,
-                                type: _maybeRegisterType(builder, signature),
-                                signature: signature,
-                                locals: params, // Parameters are the first locals.
-                                parameterCount: params.length,
-                                code: []
-                            };
-                            s.data.push(func);
-                            builder._registerFunctionToIndexSpace(functionName);
-                            let functionBuilder = {};
-                            for (const op in WASM.description.opcode) {
-                                const name = _toJavaScriptName(op);
-                                const value = WASM.description.opcode[op].value;
-                                const ret = WASM.description.opcode[op][&quot;return&quot;];
-                                const param = WASM.description.opcode[op].parameter;
-                                const imm = WASM.description.opcode[op].immediate;
-                                const checkStackArgs = builder._checked ? op =&gt; {
-                                    for (let expect of param) {
-                                        if (WASM.isValidValueType(expect)) {
-                                            // FIXME implement stack checks for arguments. https://bugs.webkit.org/show_bug.cgi?id=163421
-                                        } else {
-                                            // Handle our own meta-types.
-                                            switch (expect) {
-                                            case &quot;addr&quot;: break; // FIXME implement addr. https://bugs.webkit.org/show_bug.cgi?id=163421
-                                            case &quot;any&quot;: break; // FIXME implement any. https://bugs.webkit.org/show_bug.cgi?id=163421
-                                            case &quot;bool&quot;: break; // FIXME implement bool. https://bugs.webkit.org/show_bug.cgi?id=163421
-                                            case &quot;call&quot;: break; // FIXME implement call stack argument checks based on function signature. https://bugs.webkit.org/show_bug.cgi?id=163421
-                                            case &quot;global&quot;: break; // FIXME implement global. https://bugs.webkit.org/show_bug.cgi?id=163421
-                                            case &quot;local&quot;: break; // FIXME implement local. https://bugs.webkit.org/show_bug.cgi?id=163421
-                                            case &quot;prev&quot;: break; // FIXME implement prev, checking for whetever the previous value was. https://bugs.webkit.org/show_bug.cgi?id=163421
-                                            case &quot;size&quot;: break; // FIXME implement size. https://bugs.webkit.org/show_bug.cgi?id=163421
-                                            default: throw new Error(`Implementation problem: unhandled meta-type &quot;${expect}&quot; on &quot;${op}&quot;`);
-                                            }
-                                        }
-                                    }
-                                } : () =&gt; {};
-                                const checkStackReturn = builder._checked ? op =&gt; {
-                                    for (let expect of ret) {
-                                        if (WASM.isValidValueType(expect)) {
-                                            // FIXME implement stack checks for return. https://bugs.webkit.org/show_bug.cgi?id=163421
-                                        } else {
-                                            // Handle our own meta-types.
-                                            switch (expect) {
-                                            case &quot;bool&quot;: break; // FIXME implement bool. https://bugs.webkit.org/show_bug.cgi?id=163421
-                                            case &quot;call&quot;: break; // FIXME implement call stack return check based on function signature. https://bugs.webkit.org/show_bug.cgi?id=163421
-                                            case &quot;control&quot;: break; // FIXME implement control. https://bugs.webkit.org/show_bug.cgi?id=163421
-                                            case &quot;global&quot;: break; // FIXME implement global. https://bugs.webkit.org/show_bug.cgi?id=163421
-                                            case &quot;local&quot;: break; // FIXME implement local. https://bugs.webkit.org/show_bug.cgi?id=163421
-                                            case &quot;prev&quot;: break; // FIXME implement prev, checking for whetever the parameter type was. https://bugs.webkit.org/show_bug.cgi?id=163421
-                                            case &quot;size&quot;: break; // FIXME implement size. https://bugs.webkit.org/show_bug.cgi?id=163421
-                                            default: throw new Error(`Implementation problem: unhandled meta-type &quot;${expect}&quot; on &quot;${op}&quot;`);
-                                            }
-                                        }
-                                    }
-                                } : () =&gt; {};
-                                const checkImms = builder._checked ? (op, imms) =&gt; {
-                                    assert.eq(imms.length, imm.length, `&quot;${op}&quot; expects ${imm.length} immediates, got ${imms.length}`);
-                                    for (let idx = 0; idx !== imm.length; ++idx) {
-                                        const got = imms[idx];
-                                        const expect = imm[idx];
-                                        switch (expect.name) {
-                                        case &quot;function_index&quot;:
-                                            assert.truthy(_isValidValue(got, &quot;i32&quot;), `Invalid value on ${op}: got &quot;${got}&quot;, expected i32`);
-                                            // FIXME check function indices. https://bugs.webkit.org/show_bug.cgi?id=163421
-                                            break;
-                                        case &quot;local_index&quot;: throw new Error(`Unimplemented: &quot;${expect.name}&quot; on &quot;${op}&quot;`);
-                                        case &quot;global_index&quot;: throw new Error(`Unimplemented: &quot;${expect.name}&quot; on &quot;${op}&quot;`);
-                                        case &quot;type_index&quot;: throw new Error(`Unimplemented: &quot;${expect.name}&quot; on &quot;${op}&quot;`);
-                                        case &quot;value&quot;:
-                                            assert.truthy(_isValidValue(got, ret[0]), `Invalid value on ${op}: got &quot;${got}&quot;, expected ${ret[0]}`);
-                                            break;
-                                        case &quot;flags&quot;: throw new Error(`Unimplemented: &quot;${expect.name}&quot; on &quot;${op}&quot;`);
-                                        case &quot;offset&quot;: throw new Error(`Unimplemented: &quot;${expect.name}&quot; on &quot;${op}&quot;`);
-                                        // Control:
-                                        case &quot;default_target&quot;: throw new Error(`Unimplemented: &quot;${expect.name}&quot; on &quot;${op}&quot;`);
-                                        case &quot;relative_depth&quot;: throw new Error(`Unimplemented: &quot;${expect.name}&quot; on &quot;${op}&quot;`);
-                                        case &quot;sig&quot;: throw new Error(`Unimplemented: &quot;${expect.name}&quot; on &quot;${op}&quot;`);
-                                        case &quot;target_count&quot;: throw new Error(`Unimplemented: &quot;${expect.name}&quot; on &quot;${op}&quot;`);
-                                        case &quot;target_table&quot;: throw new Error(`Unimplemented: &quot;${expect.name}&quot; on &quot;${op}&quot;`);
-                                        default: throw new Error(`Implementation problem: unhandled immediate &quot;${expect.name}&quot; on &quot;${op}&quot;`);
-                                        }
-                                    }
-                                } : () =&gt; {};
-                                const nextBuilder = name === &quot;End&quot; ? codeBuilder : functionBuilder;
-                                functionBuilder[name] = (...args) =&gt; {
-                                    const imms = args; // FIXME: allow passing in stack values, as-if code were a stack machine. Just check for a builder to this function, and drop. https://bugs.webkit.org/show_bug.cgi?id=163422
-                                    checkImms(op, imms);
-                                    checkStackArgs(op);
-                                    checkStackReturn(op);
-                                    const stackArgs = []; // FIXME https://bugs.webkit.org/show_bug.cgi?id=162706
-                                    func.code.push({ name: op, value: value, arguments: stackArgs, immediates: imms });
-                                    return nextBuilder;
-                                };
-                            }
-                            return functionBuilder;
-                        }
</del><ins>+
</ins><span class="cx">                     };
</span><ins>+                    codeBuilder.Function = _createFunction(s, builder, codeBuilder);
</ins><span class="cx">                     return codeBuilder;
</span><span class="cx">                 };
</span><span class="cx">                 break;
</span><ins>+
</ins><span class="cx">             default:
</span><span class="cx">                 this[section] = () =&gt; { throw new Error(`Unimplemented: section type &quot;${section}&quot;`); };
</span><span class="cx">                 break;
</span><span class="lines">@@ -420,7 +495,7 @@
</span><span class="cx">     }
</span><span class="cx">     _getSection(nameOrNumber) {
</span><span class="cx">         switch (typeof(nameOrNumber)) {
</span><del>-        default: throw new Error(`Implementation problem: can't get section &quot;${nameOrNumber}&quot;`);
</del><ins>+        default: throw new Error(`Implementation problem: can not get section &quot;${nameOrNumber}&quot;`);
</ins><span class="cx">         case &quot;string&quot;:
</span><span class="cx">             for (const s of this._sections)
</span><span class="cx">                 if (s.name === nameOrNumber)
</span></span></pre></div>
<a id="trunkJSTestswasmBuilder_WebAssemblyBinaryjs"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/wasm/Builder_WebAssemblyBinary.js (208626 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/Builder_WebAssemblyBinary.js        2016-11-12 00:28:29 UTC (rev 208626)
+++ trunk/JSTests/wasm/Builder_WebAssemblyBinary.js        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -23,6 +23,7 @@
</span><span class="cx">  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx">  */
</span><span class="cx"> 
</span><ins>+import * as assert from 'assert.js';
</ins><span class="cx"> import LowLevelBinary from 'LowLevelBinary.js';
</span><span class="cx"> import * as WASM from 'WASM.js';
</span><span class="cx"> 
</span><span class="lines">@@ -30,11 +31,11 @@
</span><span class="cx"> 
</span><span class="cx"> const emitters = {
</span><span class="cx">     Type: (section, bin) =&gt; {
</span><del>-        put(bin, &quot;varuint&quot;, section.data.length);
</del><ins>+        put(bin, &quot;varuint32&quot;, section.data.length);
</ins><span class="cx">         for (const entry of section.data) {
</span><span class="cx">             const funcTypeConstructor = -0x20; // FIXME Move this to wasm.json.
</span><span class="cx">             put(bin, &quot;varint7&quot;, funcTypeConstructor);
</span><del>-            put(bin, &quot;varuint&quot;, entry.params.length);
</del><ins>+            put(bin, &quot;varuint32&quot;, entry.params.length);
</ins><span class="cx">             for (const param of entry.params)
</span><span class="cx">                 put(bin, &quot;uint8&quot;, WASM.valueTypeValue[param]);
</span><span class="cx">             if (entry.ret === &quot;void&quot;)
</span><span class="lines">@@ -46,7 +47,7 @@
</span><span class="cx">         }
</span><span class="cx">     },
</span><span class="cx">     Import: (section, bin) =&gt; {
</span><del>-        put(bin, &quot;varuint&quot;, section.data.length);
</del><ins>+        put(bin, &quot;varuint32&quot;, section.data.length);
</ins><span class="cx">         for (const entry of section.data) {
</span><span class="cx">             put(bin, &quot;string&quot;, entry.module);
</span><span class="cx">             put(bin, &quot;string&quot;, entry.field);
</span><span class="lines">@@ -53,7 +54,7 @@
</span><span class="cx">             put(bin, &quot;uint8&quot;, WASM.externalKindValue[entry.kind]);
</span><span class="cx">             switch (entry.kind) {
</span><span class="cx">             default: throw new Error(`Implementation problem: unexpected kind ${entry.kind}`);
</span><del>-            case &quot;Function&quot;: put(bin, &quot;varuint&quot;, entry.type); break;
</del><ins>+            case &quot;Function&quot;: put(bin, &quot;varuint32&quot;, entry.type); break;
</ins><span class="cx">             case &quot;Table&quot;: throw new Error(`Not yet implemented`);
</span><span class="cx">             case &quot;Memory&quot;: throw new Error(`Not yet implemented`);
</span><span class="cx">             case &quot;Global&quot;: throw new Error(`Not yet implemented`);
</span><span class="lines">@@ -60,28 +61,67 @@
</span><span class="cx">             }
</span><span class="cx">         }
</span><span class="cx">     },
</span><del>-    Function: (section, bin) =&gt; { throw new Error(`Not yet implemented`); },
</del><ins>+
+    Function: (section, bin) =&gt; {
+        put(bin, &quot;varuint32&quot;, section.data.length);
+        for (const signature of section.data)
+            put(bin, &quot;varuint32&quot;, signature);
+    },
+
</ins><span class="cx">     Table: (section, bin) =&gt; { throw new Error(`Not yet implemented`); },
</span><del>-    Memory: (section, bin) =&gt; { throw new Error(`Not yet implemented`); },
</del><ins>+
+    Memory: (section, bin) =&gt; {
+        // Flags, currently can only be [0,1]
+        put(bin, &quot;varuint1&quot;, section.data.length);
+        for (const memory of section.data) {
+            put(bin, &quot;varuint32&quot;, memory.max ? 1 : 0);
+            put(bin, &quot;varuint32&quot;, memory.initial);
+            if (memory.max)
+                put(bin, &quot;varuint32&quot;, memory.max);
+        }
+    },
+
</ins><span class="cx">     Global: (section, bin) =&gt; { throw new Error(`Not yet implemented`); },
</span><span class="cx">     Export: (section, bin) =&gt; { throw new Error(`Not yet implemented`); },
</span><span class="cx">     Start: (section, bin) =&gt; { throw new Error(`Not yet implemented`); },
</span><span class="cx">     Element: (section, bin) =&gt; { throw new Error(`Not yet implemented`); },
</span><ins>+
</ins><span class="cx">     Code: (section, bin) =&gt; {
</span><del>-        put(bin, &quot;varuint&quot;, section.data.length);
</del><ins>+        put(bin, &quot;varuint32&quot;, section.data.length);
</ins><span class="cx">         for (const func of section.data) {
</span><del>-            let funcBin = bin.newPatchable(&quot;varuint&quot;);
-            const localCount = func.locals.length;
-            put(funcBin, &quot;varuint&quot;, localCount);
-            if (localCount !== 0) throw new Error(`Unimplemented: locals`); // FIXME https://bugs.webkit.org/show_bug.cgi?id=162706
</del><ins>+            let funcBin = bin.newPatchable(&quot;varuint32&quot;);
+            const localCount = func.locals.length - func.parameterCount;
+            put(funcBin, &quot;varuint32&quot;, localCount);
+            for (let i = func.parameterCount; i &lt; func.locals.length; ++i) {
+                put(funcBin, &quot;varuint32&quot;, 1);
+                put(funcBin, &quot;uint8&quot;, WASM.valueTypeValue[func.locals[i]]);
+            }
+
</ins><span class="cx">             for (const op of func.code) {
</span><span class="cx">                 put(funcBin, &quot;uint8&quot;, op.value);
</span><del>-                if (op.arguments.length !== 0) throw new Error(`Unimplemented: arguments`); // FIXME https://bugs.webkit.org/show_bug.cgi?id=162706
-                if (op.immediates.length !== 0) throw new Error(`Unimplemented: immediates`); // FIXME https://bugs.webkit.org/show_bug.cgi?id=162706
</del><ins>+                if (op.arguments.length !== 0)
+                    throw new Error(`Unimplemented: arguments`); // FIXME https://bugs.webkit.org/show_bug.cgi?id=162706
+
+                switch (op.name) {
+                default:
+                    for (let i = 0; i &lt; op.immediates.length; ++i) {
+                        const type = WASM.description.opcode[op.name].immediate[i].type
+                        if (!funcBin[type])
+                            throw new TypeError(`Unknown type: ${type} in op: ${op.name}`);
+                        put(funcBin, type, op.immediates[i]);
+                    }
+                    break;
+                case &quot;br_table&quot;:
+                    put(funcBin, &quot;varuint32&quot;, op.immediates.length - 1);
+                    for (let imm of op.immediates)
+                        put(funcBin, &quot;varuint32&quot;, imm);
+                    break;
+                }
</ins><span class="cx">             }
</span><span class="cx">             funcBin.apply();
</span><span class="cx">         }
</span><span class="cx">     },
</span><ins>+
</ins><span class="cx">     Data: (section, bin) =&gt; { throw new Error(`Not yet implemented`); },
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -91,7 +131,7 @@
</span><span class="cx">         put(wasmBin, p.type, preamble[p.name]);
</span><span class="cx">     for (const section of sections) {
</span><span class="cx">         put(wasmBin, WASM.sectionEncodingType, section.id);
</span><del>-        let sectionBin = wasmBin.newPatchable(&quot;varuint&quot;);
</del><ins>+        let sectionBin = wasmBin.newPatchable(&quot;varuint32&quot;);
</ins><span class="cx">         const emitter = emitters[section.name];
</span><span class="cx">         if (emitter)
</span><span class="cx">             emitter(section, sectionBin);
</span></span></pre></div>
<a id="trunkJSTestswasmLowLevelBinaryjs"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/wasm/LowLevelBinary.js (208626 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/LowLevelBinary.js        2016-11-12 00:28:29 UTC (rev 208626)
+++ trunk/JSTests/wasm/LowLevelBinary.js        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -23,16 +23,18 @@
</span><span class="cx">  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
</span><span class="cx">  */
</span><span class="cx"> 
</span><ins>+import * as WASM from 'WASM.js';
+
</ins><span class="cx"> const _initialAllocationSize = 1024;
</span><span class="cx"> const _growAllocationSize = allocated =&gt; allocated * 2;
</span><span class="cx"> 
</span><del>-export const varuintMin = 0;
</del><ins>+export const varuint32Min = 0;
</ins><span class="cx"> export const varint7Min = -0b1000000;
</span><span class="cx"> export const varint7Max = 0b111111;
</span><span class="cx"> export const varuint7Max = 0b1111111;
</span><del>-export const varuintMax = ((((1 &lt;&lt; 31) &gt;&gt;&gt; 0) - 1) * 2) + 1;
-export const varintMin = -((1 &lt;&lt; 31) &gt;&gt;&gt; 0);
-export const varintMax = ((1 &lt;&lt; 31) - 1) &gt;&gt;&gt; 0;
</del><ins>+export const varuint32Max = ((((1 &lt;&lt; 31) &gt;&gt;&gt; 0) - 1) * 2) + 1;
+export const varint32Min = -((1 &lt;&lt; 31) &gt;&gt;&gt; 0);
+export const varint32Max = ((1 &lt;&lt; 31) - 1) &gt;&gt;&gt; 0;
</ins><span class="cx"> export const varBitsMax = 5;
</span><span class="cx"> 
</span><span class="cx"> const _getterRangeCheck = (llb, at, size) =&gt; {
</span><span class="lines">@@ -75,6 +77,8 @@
</span><span class="cx"> 
</span><span class="cx">     // Utilities.
</span><span class="cx">     get() { return this._buf; }
</span><ins>+    trim() { this._buf = this._buf.slice(0, this._used); }
+
</ins><span class="cx">     hexdump() { return _hexdump(this._buf, this._used); }
</span><span class="cx">     trim() { this._buf = this._buf.slice(0, this._used); }
</span><span class="cx">     _maybeGrow(bytes) {
</span><span class="lines">@@ -110,9 +114,9 @@
</span><span class="cx">         this._push8(v &gt;&gt;&gt; 16);
</span><span class="cx">         this._push8(v &gt;&gt;&gt; 24);
</span><span class="cx">     }
</span><del>-    varuint(v) {
-        if (v &lt; varuintMin || varuintMax &lt; v)
-            throw new RangeError(`Invalid varuint ${v} range is [${varuintMin}, ${varuintMax}]`);
</del><ins>+    varuint32(v) {
+        if (v &lt; varuint32Min || varuint32Max &lt; v)
+            throw new RangeError(`Invalid varuint32 ${v} range is [${varuint32Min}, ${varuint32Max}]`);
</ins><span class="cx">         while (v &gt;= 0x80) {
</span><span class="cx">             this.uint8(0x80 | (v &amp; 0x7F));
</span><span class="cx">             v &gt;&gt;&gt;= 7;
</span><span class="lines">@@ -119,9 +123,9 @@
</span><span class="cx">         }
</span><span class="cx">         this.uint8(v);
</span><span class="cx">     }
</span><del>-    varint(v) {
-        if (v &lt; varintMin || varintMax &lt; v)
-            throw new RangeError(`Invalid varint ${v} range is [${varintMin}, ${varintMax}]`);
</del><ins>+    varint32(v) {
+        if (v &lt; varint32Min || varint32Max &lt; v)
+            throw new RangeError(`Invalid varint32 ${v} range is [${varint32Min}, ${varint32Max}]`);
</ins><span class="cx">         do {
</span><span class="cx">             const b = v &amp; 0x7F;
</span><span class="cx">             v &gt;&gt;= 7;
</span><span class="lines">@@ -135,20 +139,23 @@
</span><span class="cx">     varuint1(v) {
</span><span class="cx">         if (v !== 0 &amp;&amp; v !== 1)
</span><span class="cx">             throw new RangeError(`Invalid varuint1 ${v} range is [0, 1]`);
</span><del>-        this.varuint(v);
</del><ins>+        this.varuint32(v);
</ins><span class="cx">     }
</span><span class="cx">     varint7(v) {
</span><span class="cx">         if (v &lt; varint7Min || varint7Max &lt; v)
</span><span class="cx">             throw new RangeError(`Invalid varint7 ${v} range is [${varint7Min}, ${varint7Max}]`);
</span><del>-        this.varint(v);
</del><ins>+        this.varint32(v);
</ins><span class="cx">     }
</span><span class="cx">     varuint7(v) {
</span><del>-        if (v &lt; varuintMin || varuint7Max &lt; v)
-            throw new RangeError(`Invalid varuint7 ${v} range is [${varuintMin}, ${varuint7Max}]`);
-        this.varuint(v);
</del><ins>+        if (v &lt; varuint32Min || varuint7Max &lt; v)
+            throw new RangeError(`Invalid varuint7 ${v} range is [${varuint32Min}, ${varuint7Max}]`);
+        this.varuint32(v);
</ins><span class="cx">     }
</span><ins>+    inline_signature_type(v) {
+        this.varint7(WASM.valueTypeValue[v]);
+    }
</ins><span class="cx">     string(str) {
</span><del>-        let patch = this.newPatchable(&quot;varuint&quot;);
</del><ins>+        let patch = this.newPatchable(&quot;varuint32&quot;);
</ins><span class="cx">         for (const char of str)
</span><span class="cx">             patch.uint16(char.charCodeAt());
</span><span class="cx">         patch.apply();
</span><span class="lines">@@ -168,7 +175,7 @@
</span><span class="cx">         _getterRangeCheck(this, at, 4);
</span><span class="cx">         return (this._buf[at] | (this._buf[at + 1] &lt;&lt; 8) | (this._buf[at + 2] &lt;&lt; 16) | (this._buf[at + 3] &lt;&lt; 24)) &gt;&gt;&gt; 0;
</span><span class="cx">     }
</span><del>-    getVaruint(at) {
</del><ins>+    getVaruint32(at) {
</ins><span class="cx">         let v = 0;
</span><span class="cx">         let shift = 0;
</span><span class="cx">         let byte = 0;
</span><span class="lines">@@ -179,10 +186,10 @@
</span><span class="cx">             shift += 7;
</span><span class="cx">         } while ((byte &amp; 0x80) !== 0);
</span><span class="cx">         if (shift - 7 &gt; 32) throw new RangeError(`Shifting too much at ${at}`);
</span><del>-        if ((shift == 35) &amp;&amp; ((byte &amp; 0xF0) != 0)) throw new Error(`Unexpected non-significant varuint bits in last byte 0x${byte.toString(16)}`);
</del><ins>+        if ((shift == 35) &amp;&amp; ((byte &amp; 0xF0) != 0)) throw new Error(`Unexpected non-significant varuint32 bits in last byte 0x${byte.toString(16)}`);
</ins><span class="cx">         return { value: v, next: at };
</span><span class="cx">     }
</span><del>-    getVarint(at) {
</del><ins>+    getVarint32(at) {
</ins><span class="cx">         let v = 0;
</span><span class="cx">         let shift = 0;
</span><span class="cx">         let byte = 0;
</span><span class="lines">@@ -192,7 +199,7 @@
</span><span class="cx">             shift += 7;
</span><span class="cx">         } while ((byte &amp; 0x80) !== 0);
</span><span class="cx">         if (shift - 7 &gt; 32) throw new RangeError(`Shifting too much at ${at}`);
</span><del>-        if ((shift == 35) &amp;&amp; (((byte &lt;&lt; 26) &gt;&gt; 30) != ((byte &lt;&lt; 25) &gt;&gt; 31))) throw new Error(`Unexpected non-significant varint bits in last byte 0x${byte.toString(16)}`);
</del><ins>+        if ((shift == 35) &amp;&amp; (((byte &lt;&lt; 26) &gt;&gt; 30) != ((byte &lt;&lt; 25) &gt;&gt; 31))) throw new Error(`Unexpected non-significant varint32 bits in last byte 0x${byte.toString(16)}`);
</ins><span class="cx">         if ((byte &amp; 0x40) === 0x40) {
</span><span class="cx">             const sext = shift &lt; 32 ? 32 - shift : 0;
</span><span class="cx">             v = (v &lt;&lt; sext) &gt;&gt; sext;
</span><span class="lines">@@ -200,12 +207,12 @@
</span><span class="cx">         return { value: v, next: at };
</span><span class="cx">     }
</span><span class="cx">     getVaruint7(at) {
</span><del>-        const res = this.getVaruint(at);
</del><ins>+        const res = this.getVaruint32(at);
</ins><span class="cx">         if (res.value &gt; varuint7Max) throw new Error(`Expected a varuint7, got value ${res.value}`);
</span><span class="cx">         return res;
</span><span class="cx">     }
</span><span class="cx">     getString(at) {
</span><del>-        const size = this.getVaruint(at);
</del><ins>+        const size = this.getVaruint32(at);
</ins><span class="cx">         let str = &quot;&quot;;
</span><span class="cx">         for (let i = size.next; i !== size.next + size.value; i += 2)
</span><span class="cx">             str += String.fromCharCode(this.getUint16(i));
</span></span></pre></div>
<a id="trunkJSTestswasmjsapifunctiontestsadd12js"></a>
<div class="addfile"><h4>Added: trunk/JSTests/wasm/js-api/function-tests/add-12.js (0 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/js-api/function-tests/add-12.js                                (rev 0)
+++ trunk/JSTests/wasm/js-api/function-tests/add-12.js        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -0,0 +1,61 @@
</span><ins>+import Builder from '../../Builder.js'
+
+const b = new Builder();
+b.setChecked(false);
+b.Type().End()
+    .Function().End()
+    .Code()
+    .Function({ params: [&quot;i32&quot;, &quot;i32&quot;, &quot;i32&quot;, &quot;i32&quot;, &quot;i32&quot;, &quot;i32&quot;, &quot;i32&quot;, &quot;i32&quot;, &quot;i32&quot;, &quot;i32&quot;, &quot;i32&quot;, &quot;i32&quot;], ret: &quot;i32&quot; }, [])
+    .GetLocal(0)
+    .GetLocal(1)
+    .I32Add()
+    .GetLocal(2)
+    .I32Add()
+    .GetLocal(3)
+    .I32Add()
+    .GetLocal(4)
+    .I32Add()
+    .GetLocal(5)
+    .I32Add()
+    .GetLocal(6)
+    .I32Add()
+    .GetLocal(7)
+    .I32Add()
+    .GetLocal(8)
+    .I32Add()
+    .GetLocal(9)
+    .I32Add()
+    .GetLocal(10)
+    .I32Add()
+    .GetLocal(11)
+    .I32Add()
+    .Return()
+    .End()
+
+    .Function({ params: [&quot;i32&quot;], ret: &quot;i32&quot; })
+    .GetLocal(0)
+    .GetLocal(0)
+    .GetLocal(0)
+    .GetLocal(0)
+    .GetLocal(0)
+    .GetLocal(0)
+    .GetLocal(0)
+    .GetLocal(0)
+    .GetLocal(0)
+    .GetLocal(0)
+    .GetLocal(0)
+    .GetLocal(0)
+    .Call(0)
+    .End()
+
+const bin = b.WebAssembly()
+bin.trim();
+testWasmModuleFunctions(bin.get(), 2,
+                        [[{ type: &quot;i32&quot;, value: 78 }, [{ type: &quot;i32&quot;, value: 1 }, { type: &quot;i32&quot;, value: 2 }, { type: &quot;i32&quot;, value: 3 }, { type: &quot;i32&quot;, value: 4 }, { type: &quot;i32&quot;, value: 5 }, { type: &quot;i32&quot;, value: 6 }, { type: &quot;i32&quot;, value: 7 }, { type: &quot;i32&quot;, value: 8 }, { type: &quot;i32&quot;, value: 9 }, { type: &quot;i32&quot;, value: 10 }, { type: &quot;i32&quot;, value: 11 }, { type: &quot;i32&quot;, value: 12 }]],
+                         [{ type: &quot;i32&quot;, value: 166 }, [{ type: &quot;i32&quot;, value: 1 }, { type: &quot;i32&quot;, value: 2 }, { type: &quot;i32&quot;, value: 3 }, { type: &quot;i32&quot;, value: 4 }, { type: &quot;i32&quot;, value: 5 }, { type: &quot;i32&quot;, value: 6 }, { type: &quot;i32&quot;, value: 7 }, { type: &quot;i32&quot;, value: 8 }, { type: &quot;i32&quot;, value: 9 }, { type: &quot;i32&quot;, value: 10 }, { type: &quot;i32&quot;, value: 11 }, { type: &quot;i32&quot;, value: 100 }]]
+                        ],
+                        [[{ type: &quot;i32&quot;, value: 12 }, [{ type: &quot;i32&quot;, value: 1 }]],
+                         [{ type: &quot;i32&quot;, value: 1200 }, [{ type: &quot;i32&quot;, value: 100 }]],
+                         [{ type: &quot;i32&quot;, value: 0 }, [{ type: &quot;i32&quot;, value: 0 }]],
+                        ]
+                       );
</ins></span></pre></div>
<a id="trunkJSTestswasmjsapifunctiontestsbriflooplessthanjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/wasm/js-api/function-tests/br-if-loop-less-than.js (0 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/js-api/function-tests/br-if-loop-less-than.js                                (rev 0)
+++ trunk/JSTests/wasm/js-api/function-tests/br-if-loop-less-than.js        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -0,0 +1,51 @@
</span><ins>+import Builder from '../../Builder.js'
+
+const b = new Builder();
+b.setChecked(false);
+b.Type().End()
+    .Function().End()
+    .Code()
+    .Function({ params: [&quot;i32&quot;, &quot;i32&quot;], ret: &quot;i32&quot; }, [])
+    .Loop(&quot;void&quot;)
+    .Block(&quot;void&quot;, b =&gt;
+           b.Block(&quot;void&quot;, b =&gt;
+                   b.GetLocal(0)
+                   .GetLocal(1)
+                   .I32Eq()
+                   .BrIf(0)
+                   .Br(1)
+                  )
+           .I32Const(0)
+           .Return()
+          )
+    .Block(&quot;void&quot;, b =&gt;
+           b.Block(&quot;void&quot;, b =&gt;
+                   b.GetLocal(0)
+                   .I32Const(0)
+                   .I32Eq()
+                   .BrIf(0)
+                   .Br(1)
+                  )
+           .I32Const(1)
+           .Return()
+          )
+    .GetLocal(0)
+    .I32Const(1)
+    .I32Sub()
+    .SetLocal(0)
+    .Br(0)
+    .End()
+    .Unreachable()
+    .End()
+
+const bin = b.WebAssembly()
+bin.trim();
+testWasmModuleFunctions(bin.get(), 1, [[{type: &quot;i32&quot;, value: 1 }, [{ type: &quot;i32&quot;, value: 0 }, { type: &quot;i32&quot;, value: 1 }]],
+                                       [{type: &quot;i32&quot;, value: 0 }, [{ type: &quot;i32&quot;, value: 1 }, { type: &quot;i32&quot;, value: 0 }]],
+                                       [{type: &quot;i32&quot;, value: 0 }, [{ type: &quot;i32&quot;, value: 2 }, { type: &quot;i32&quot;, value: 1 }]],
+                                       [{type: &quot;i32&quot;, value: 1 }, [{ type: &quot;i32&quot;, value: 1 }, { type: &quot;i32&quot;, value: 2 }]],
+                                       [{type: &quot;i32&quot;, value: 0 }, [{ type: &quot;i32&quot;, value: 2 }, { type: &quot;i32&quot;, value: 2 }]],
+                                       [{type: &quot;i32&quot;, value: 0 }, [{ type: &quot;i32&quot;, value: 1 }, { type: &quot;i32&quot;, value: 1 }]],
+                                       [{type: &quot;i32&quot;, value: 1 }, [{ type: &quot;i32&quot;, value: 2 }, { type: &quot;i32&quot;, value: 6 }]],
+                                       [{type: &quot;i32&quot;, value: 0 }, [{ type: &quot;i32&quot;, value: 100 }, { type: &quot;i32&quot;, value: 6 }]]
+                                      ]);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkJSTestswasmjsapifunctiontestsbrTableAsIfjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/wasm/js-api/function-tests/brTableAsIf.js (0 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/js-api/function-tests/brTableAsIf.js                                (rev 0)
+++ trunk/JSTests/wasm/js-api/function-tests/brTableAsIf.js        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -0,0 +1,26 @@
</span><ins>+import Builder from '../../Builder.js'
+
+const b = new Builder();
+b.setChecked(false);
+b.Type().End()
+    .Function().End()
+    .Code()
+    .Function({ params: [&quot;i32&quot;], ret: &quot;i32&quot; }, [&quot;i32&quot;])
+    .Block(&quot;void&quot;, (b) =&gt;
+           b.Block(&quot;void&quot;, (b) =&gt;
+                   b.GetLocal(0)
+                   .BrTable(1, 0)
+                   .I32Const(21)
+                   .Return()
+                  ).I32Const(20)
+           .Return()
+          ).I32Const(22)
+    .End()
+
+const bin = b.WebAssembly()
+bin.trim();
+testWasmModuleFunctions(bin.get(), 1, [[{type: &quot;i32&quot;, value: 22 }, [{ type: &quot;i32&quot;, value: 0 }]],
+                                       [{type: &quot;i32&quot;, value: 20 }, [{ type: &quot;i32&quot;, value: 1 }]],
+                                       [{type: &quot;i32&quot;, value: 20 }, [{ type: &quot;i32&quot;, value: 11 }]],
+                                       [{type: &quot;i32&quot;, value: 20 }, [{ type: &quot;i32&quot;, value: -100 }]]
+                                      ]);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkJSTestswasmjsapifunctiontestsbrTableManyValuesjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/wasm/js-api/function-tests/brTableManyValues.js (0 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/js-api/function-tests/brTableManyValues.js                                (rev 0)
+++ trunk/JSTests/wasm/js-api/function-tests/brTableManyValues.js        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -0,0 +1,43 @@
</span><ins>+import Builder from '../../Builder.js'
+
+const b = new Builder();
+b.setChecked(false);
+b.Type().End()
+    .Function().End()
+    .Code()
+    .Function({ params: [&quot;i32&quot;], ret: &quot;i32&quot; }, [&quot;i32&quot;])
+    .Block(&quot;i32&quot;, (b) =&gt;
+           b.Block(&quot;i32&quot;, (b) =&gt;
+                   b.Block(&quot;i32&quot;, (b) =&gt;
+                           b.Block(&quot;i32&quot;, (b) =&gt;
+                                   b.Block(&quot;i32&quot;, (b) =&gt;
+                                           b.I32Const(200)
+                                           .GetLocal(0)
+                                           .BrTable(3, 2, 1, 0, 4)
+                                          ).I32Const(10)
+                                   .I32Add()
+                                   .Return()
+                                  ).I32Const(11)
+                           .I32Add()
+                           .Return()
+                          ).I32Const(12)
+                   .I32Add()
+                   .Return()
+                  ).I32Const(13)
+           .I32Add()
+           .Return()
+          ).I32Const(14)
+    .I32Add()
+    .Return()
+    .End()
+const bin = b.WebAssembly()
+bin.trim();
+testWasmModuleFunctions(bin.get(), 1, [[{type: &quot;i32&quot;, value: 213 }, [{ type: &quot;i32&quot;, value: 0 }]],
+                                       [{type: &quot;i32&quot;, value: 212 }, [{ type: &quot;i32&quot;, value: 1 }]],
+                                       [{type: &quot;i32&quot;, value: 211 }, [{ type: &quot;i32&quot;, value: 2 }]],
+                                       [{type: &quot;i32&quot;, value: 210 }, [{ type: &quot;i32&quot;, value: 3 }]],
+                                       [{type: &quot;i32&quot;, value: 214 }, [{ type: &quot;i32&quot;, value: 4 }]],
+                                       [{type: &quot;i32&quot;, value: 214 }, [{ type: &quot;i32&quot;, value: 5 }]],
+                                       [{type: &quot;i32&quot;, value: 214 }, [{ type: &quot;i32&quot;, value: -1 }]],
+                                       [{type: &quot;i32&quot;, value: 214 }, [{ type: &quot;i32&quot;, value: -1000 }]]
+                                      ]);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkJSTestswasmjsapifunctiontestsbrTableWithLoopjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/wasm/js-api/function-tests/brTableWithLoop.js (0 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/js-api/function-tests/brTableWithLoop.js                                (rev 0)
+++ trunk/JSTests/wasm/js-api/function-tests/brTableWithLoop.js        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -0,0 +1,30 @@
</span><ins>+import Builder from '../../Builder.js'
+
+const b = new Builder();
+b.setChecked(false);
+b.Type().End()
+    .Function().End()
+    .Code()
+    .Function({ params: [&quot;i32&quot;], ret: &quot;i32&quot; }, [&quot;i32&quot;])
+    .Loop(&quot;void&quot;)
+    .Block(&quot;void&quot;, (b) =&gt;
+
+           b.GetLocal(0)
+           .GetLocal(1)
+           .I32Const(1)
+           .I32Add()
+           .SetLocal(1)
+           .GetLocal(0)
+           .I32Const(1)
+           .I32Sub()
+           .SetLocal(0)
+           .BrTable(0, 1))
+
+    .End()
+    .GetLocal(1)
+    .End()
+const bin = b.WebAssembly()
+bin.trim();
+testWasmModuleFunctions(bin.get(), 1, [[{type: &quot;i32&quot;, value: 1 }, [{ type: &quot;i32&quot;, value: 0 }]],
+                                       [{type: &quot;i32&quot;, value: 2 }, [{ type: &quot;i32&quot;, value: 1 }]]
+                                      ]);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkJSTestswasmjsapifunctiontestsdumbeqifthenelsejs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/wasm/js-api/function-tests/dumb-eq-if-then-else.js (0 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/js-api/function-tests/dumb-eq-if-then-else.js                                (rev 0)
+++ trunk/JSTests/wasm/js-api/function-tests/dumb-eq-if-then-else.js        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -0,0 +1,34 @@
</span><ins>+import Builder from '../../Builder.js'
+
+const b = new Builder();
+b.setChecked(false);
+b.Type().End()
+    .Function().End()
+    .Memory().InitialMaxPages(1, 1).End()
+    .Code()
+    .Function({ params: [&quot;i32&quot;, &quot;i32&quot;], ret: &quot;i32&quot; }, [])
+    .GetLocal(0)
+    .GetLocal(1)
+    .I32Eq()
+    .If(&quot;void&quot;, b =&gt;
+        b.Br(0)
+        .Else()
+            .I32Const(1)
+        .Return()
+       )
+        .I32Const(0)
+    .Return()
+    .End()
+
+const bin = b.WebAssembly()
+bin.trim();
+testWasmModuleFunctions(bin.get(), 1, [[{type: &quot;i32&quot;, value: 1 }, [{ type: &quot;i32&quot;, value: 0 }, { type: &quot;i32&quot;, value: 1 }]],
+                                       [{type: &quot;i32&quot;, value: 1 }, [{ type: &quot;i32&quot;, value: 1 }, { type: &quot;i32&quot;, value: 0 }]],
+                                       [{type: &quot;i32&quot;, value: 1 }, [{ type: &quot;i32&quot;, value: 2 }, { type: &quot;i32&quot;, value: 1 }]],
+                                       [{type: &quot;i32&quot;, value: 1 }, [{ type: &quot;i32&quot;, value: 1 }, { type: &quot;i32&quot;, value: 2 }]],
+                                       [{type: &quot;i32&quot;, value: 0 }, [{ type: &quot;i32&quot;, value: 2 }, { type: &quot;i32&quot;, value: 2 }]],
+                                       [{type: &quot;i32&quot;, value: 0 }, [{ type: &quot;i32&quot;, value: 1 }, { type: &quot;i32&quot;, value: 1 }]],
+                                       [{type: &quot;i32&quot;, value: 0 }, [{ type: &quot;i32&quot;, value: 0 }, { type: &quot;i32&quot;, value: 0 }]],
+                                       [{type: &quot;i32&quot;, value: 1 }, [{ type: &quot;i32&quot;, value: 2 }, { type: &quot;i32&quot;, value: 6 }]],
+                                       [{type: &quot;i32&quot;, value: 1 }, [{ type: &quot;i32&quot;, value: 100 }, { type: &quot;i32&quot;, value: 6 }]]
+                                      ]);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkJSTestswasmjsapifunctiontestsdumblessthanfallthroughjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/wasm/js-api/function-tests/dumb-less-than-fallthrough.js (0 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/js-api/function-tests/dumb-less-than-fallthrough.js                                (rev 0)
+++ trunk/JSTests/wasm/js-api/function-tests/dumb-less-than-fallthrough.js        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -0,0 +1,39 @@
</span><ins>+import Builder from '../../Builder.js'
+
+const b = new Builder();
+b.setChecked(false);
+b.Type().End()
+    .Function().End()
+    .Code()
+    .Function({ params: [&quot;i32&quot;, &quot;i32&quot;], ret: &quot;i32&quot; }, [])
+    .Loop(&quot;i32&quot;, b =&gt;
+          b.GetLocal(0)
+          .GetLocal(1)
+          .I32Eq()
+          .If(&quot;i32&quot;, b =&gt;
+              b.I32Const(0)
+              .Return()
+              .Else()
+                  .GetLocal(0)
+              .GetLocal(0)
+              .I32Const(1)
+              .I32Sub()
+              .SetLocal(0)
+              .I32Const(0)
+              .I32Ne()
+              .BrIf(1)
+              .I32Const(1)
+          )
+    ).End()
+
+const bin = b.WebAssembly()
+bin.trim();
+testWasmModuleFunctions(bin.get(), 1, [[{type: &quot;i32&quot;, value: 1 }, [{ type: &quot;i32&quot;, value: 0 }, { type: &quot;i32&quot;, value: 1 }]],
+                                       [{type: &quot;i32&quot;, value: 0 }, [{ type: &quot;i32&quot;, value: 1 }, { type: &quot;i32&quot;, value: 0 }]],
+                                       [{type: &quot;i32&quot;, value: 0 }, [{ type: &quot;i32&quot;, value: 2 }, { type: &quot;i32&quot;, value: 1 }]],
+                                       [{type: &quot;i32&quot;, value: 1 }, [{ type: &quot;i32&quot;, value: 1 }, { type: &quot;i32&quot;, value: 2 }]],
+                                       [{type: &quot;i32&quot;, value: 0 }, [{ type: &quot;i32&quot;, value: 2 }, { type: &quot;i32&quot;, value: 2 }]],
+                                       [{type: &quot;i32&quot;, value: 0 }, [{ type: &quot;i32&quot;, value: 1 }, { type: &quot;i32&quot;, value: 1 }]],
+                                       [{type: &quot;i32&quot;, value: 1 }, [{ type: &quot;i32&quot;, value: 2 }, { type: &quot;i32&quot;, value: 6 }]],
+                                       [{type: &quot;i32&quot;, value: 0 }, [{ type: &quot;i32&quot;, value: 100 }, { type: &quot;i32&quot;, value: 6 }]]
+                                      ]);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkJSTestswasmjsapifunctiontestsdumblessthanitejs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/wasm/js-api/function-tests/dumb-less-than-ite.js (0 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/js-api/function-tests/dumb-less-than-ite.js                                (rev 0)
+++ trunk/JSTests/wasm/js-api/function-tests/dumb-less-than-ite.js        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -0,0 +1,45 @@
</span><ins>+import Builder from '../../Builder.js'
+
+const b = new Builder();
+b.setChecked(false);
+b.Type().End()
+    .Function().End()
+    .Code()
+    .Function({ params: [&quot;i32&quot;, &quot;i32&quot;], ret: &quot;i32&quot; }, [])
+    .Loop(&quot;void&quot;)
+    .GetLocal(0)
+    .GetLocal(1)
+    .I32Eq()
+    .If(&quot;void&quot;, b =&gt;
+        b.I32Const(0)
+        .Return()
+        .Else()
+            .GetLocal(0)
+        .I32Const(0)
+        .I32Eq()
+        .If(&quot;void&quot;, b =&gt;
+            b.I32Const(1)
+            .Return()
+           )
+            )
+        .GetLocal(0)
+    .I32Const(1)
+    .I32Sub()
+    .SetLocal(0)
+    .Br(0)
+    .End()
+    .Unreachable()
+    .End()
+
+const bin = b.WebAssembly()
+bin.trim();
+testWasmModuleFunctions(bin.get(), 1, [[{type: &quot;i32&quot;, value: 1 }, [{ type: &quot;i32&quot;, value: 0 }, { type: &quot;i32&quot;, value: 1 }]],
+                                       [{type: &quot;i32&quot;, value: 0 }, [{ type: &quot;i32&quot;, value: 1 }, { type: &quot;i32&quot;, value: 0 }]],
+                                       [{type: &quot;i32&quot;, value: 0 }, [{ type: &quot;i32&quot;, value: 2 }, { type: &quot;i32&quot;, value: 1 }]],
+                                       [{type: &quot;i32&quot;, value: 1 }, [{ type: &quot;i32&quot;, value: 1 }, { type: &quot;i32&quot;, value: 2 }]],
+                                       [{type: &quot;i32&quot;, value: 0 }, [{ type: &quot;i32&quot;, value: 2 }, { type: &quot;i32&quot;, value: 2 }]],
+                                       [{type: &quot;i32&quot;, value: 0 }, [{ type: &quot;i32&quot;, value: 1 }, { type: &quot;i32&quot;, value: 1 }]],
+                                       [{type: &quot;i32&quot;, value: 0 }, [{ type: &quot;i32&quot;, value: 0 }, { type: &quot;i32&quot;, value: 0 }]],
+                                       [{type: &quot;i32&quot;, value: 1 }, [{ type: &quot;i32&quot;, value: 2 }, { type: &quot;i32&quot;, value: 6 }]],
+                                       [{type: &quot;i32&quot;, value: 0 }, [{ type: &quot;i32&quot;, value: 100 }, { type: &quot;i32&quot;, value: 6 }]]
+                                      ]);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkJSTestswasmjsapifunctiontestsfactorialjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/wasm/js-api/function-tests/factorial.js (0 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/js-api/function-tests/factorial.js                                (rev 0)
+++ trunk/JSTests/wasm/js-api/function-tests/factorial.js        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -0,0 +1,31 @@
</span><ins>+import Builder from '../../Builder.js'
+
+const b = new Builder();
+b.setChecked(false);
+b.Type().End()
+    .Function().End()
+    .Code()
+    .Function({ params: [&quot;i32&quot;], ret: &quot;i32&quot; }, [])
+    .GetLocal(0)
+    .I32Const(0)
+    .I32Eq()
+    .If(&quot;void&quot;, b =&gt;
+        b.I32Const(1)
+        .Return()
+       )
+        .GetLocal(0)
+    .GetLocal(0)
+    .I32Const(1)
+    .I32Sub()
+    .Call(0)
+    .I32Mul()
+    .Return()
+    .End()
+
+const bin = b.WebAssembly()
+bin.trim();
+testWasmModuleFunctions(bin.get(), 1, [[{type: &quot;i32&quot;, value: 1 }, [{ type: &quot;i32&quot;, value: 0 }]],
+                                       [{type: &quot;i32&quot;, value: 1 }, [{ type: &quot;i32&quot;, value: 1 }]],
+                                       [{type: &quot;i32&quot;, value: 2 }, [{ type: &quot;i32&quot;, value: 2 }]],
+                                       [{type: &quot;i32&quot;, value: 24 }, [{ type: &quot;i32&quot;, value: 4 }]],
+                                      ]);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkJSTestswasmjsapifunctiontestsfloatsubjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/wasm/js-api/function-tests/float-sub.js (0 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/js-api/function-tests/float-sub.js                                (rev 0)
+++ trunk/JSTests/wasm/js-api/function-tests/float-sub.js        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -0,0 +1,31 @@
</span><ins>+import Builder from '../../Builder.js'
+
+const b = new Builder();
+b.setChecked(false);
+b.Type().End()
+    .Function().End()
+    .Code()
+    .Function({ params: [&quot;f32&quot;, &quot;f32&quot;], ret: &quot;f32&quot; }, [])
+    .GetLocal(0)
+    .GetLocal(1)
+    .F32Sub()
+    .Return()
+    .End()
+
+    .Function({ params: [&quot;f32&quot;, &quot;f32&quot;], ret: &quot;f32&quot; }, [])
+    .GetLocal(0)
+    .GetLocal(1)
+    .Call(0)
+    .Return()
+    .End()
+
+const bin = b.WebAssembly()
+bin.trim();
+testWasmModuleFunctions(bin.get(), 2,
+                        [[{type: &quot;f32&quot;, value: -1.5 }, [{ type: &quot;f32&quot;, value: 0 }, { type: &quot;f32&quot;, value: 1.5 }]],
+                         [{type: &quot;f32&quot;, value: 87.6234 }, [{ type: &quot;f32&quot;, value: 100.1234 }, { type: &quot;f32&quot;, value: 12.5 }]]
+                        ],
+                        [[{type: &quot;f32&quot;, value: -1.5 }, [{ type: &quot;f32&quot;, value: 0 }, { type: &quot;f32&quot;, value: 1.5 }]],
+                         [{type: &quot;f32&quot;, value: 87.6234 }, [{ type: &quot;f32&quot;, value: 100.1234 }, { type: &quot;f32&quot;, value: 12.5 }]]
+                        ]
+                       );
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkJSTestswasmjsapifunctiontestsi32loadjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/wasm/js-api/function-tests/i32-load.js (0 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/js-api/function-tests/i32-load.js                                (rev 0)
+++ trunk/JSTests/wasm/js-api/function-tests/i32-load.js        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+import Builder from '../../Builder.js'
+
+const b = new Builder();
+b.setChecked(false);
+b.Type().End()
+    .Function().End()
+    .Memory().InitialMaxPages(1, 1).End()
+    .Code()
+    .Function({ params: [&quot;i32&quot;, &quot;i32&quot;], ret: &quot;i32&quot; }, [])
+    .GetLocal(1)
+    .GetLocal(0)
+    .I32Store(2, 0)
+    .GetLocal(1)
+    .I32Load(2, 0)
+    .Return()
+    .End()
+
+const bin = b.WebAssembly()
+bin.trim();
+testWasmModuleFunctions(bin.get(), 1, [[{type: &quot;i32&quot;, value: 0 }, [{ type: &quot;i32&quot;, value: 0 }, { type: &quot;i32&quot;, value: 10 }]],
+                                       [{type: &quot;i32&quot;, value: 100 }, [{ type: &quot;i32&quot;, value: 100 }, { type: &quot;i32&quot;, value: 112 }]],
+                                       [{type: &quot;i32&quot;, value: 1000000 }, [{ type: &quot;i32&quot;, value: 1000000 }, { type: &quot;i32&quot;, value: 10 }]]
+                                      ]);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkJSTestswasmjsapifunctiontestsi32load8sjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/wasm/js-api/function-tests/i32-load8-s.js (0 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/js-api/function-tests/i32-load8-s.js                                (rev 0)
+++ trunk/JSTests/wasm/js-api/function-tests/i32-load8-s.js        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+import Builder from '../../Builder.js'
+
+const b = new Builder();
+b.setChecked(false);
+b.Type().End()
+    .Function().End()
+    .Memory().InitialMaxPages(1, 1).End()
+    .Code()
+    .Function({ params: [&quot;i32&quot;, &quot;i32&quot;], ret: &quot;i32&quot; }, [])
+    .GetLocal(1)
+    .GetLocal(0)
+    .I32Store(2, 0)
+    .GetLocal(1)
+    .I32Load8S(2, 0)
+    .Return()
+    .End()
+
+const bin = b.WebAssembly()
+bin.trim();
+testWasmModuleFunctions(bin.get(), 1, [[{type: &quot;i32&quot;, value: 0 }, [{ type: &quot;i32&quot;, value: 0 }, { type: &quot;i32&quot;, value: 10 }]],
+                                       [{type: &quot;i32&quot;, value: 100 }, [{ type: &quot;i32&quot;, value: 100 }, { type: &quot;i32&quot;, value: 112 }]],
+                                       [{type: &quot;i32&quot;, value: 0x40 }, [{ type: &quot;i32&quot;, value: 1000000 }, { type: &quot;i32&quot;, value: 10 }]]
+                                      ]);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkJSTestswasmjsapifunctiontestsifthenelsefallthroughjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/wasm/js-api/function-tests/if-then-else-fallthrough.js (0 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/js-api/function-tests/if-then-else-fallthrough.js                                (rev 0)
+++ trunk/JSTests/wasm/js-api/function-tests/if-then-else-fallthrough.js        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -0,0 +1,25 @@
</span><ins>+import Builder from '../../Builder.js'
+
+const b = new Builder();
+b.setChecked(false);
+b.Type().End()
+    .Function().End()
+    .Code()
+    .Function({ params: [&quot;i32&quot;], ret: &quot;i32&quot; }, [])
+    .Block(&quot;i32&quot;, (b) =&gt;
+           b.GetLocal(0)
+           .I32Const(0)
+           .I32Eq()
+           .If(&quot;i32&quot;)
+               .I32Const(1)
+           .Else()
+               .I32Const(2)
+           .Br(1)
+           .End()
+          ).End()
+
+const bin = b.WebAssembly()
+bin.trim();
+testWasmModuleFunctions(bin.get(), 1, [[{type: &quot;i32&quot;, value: 1 }, [{ type: &quot;i32&quot;, value: 0 }]],
+                                       [{type: &quot;i32&quot;, value: 2 }, [{ type: &quot;i32&quot;, value: 1 }]]
+                                      ]);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkJSTestswasmjsapifunctiontestsifthenfallthroughjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/wasm/js-api/function-tests/if-then-fallthrough.js (0 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/js-api/function-tests/if-then-fallthrough.js                                (rev 0)
+++ trunk/JSTests/wasm/js-api/function-tests/if-then-fallthrough.js        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -0,0 +1,25 @@
</span><ins>+import Builder from '../../Builder.js'
+
+const b = new Builder();
+b.setChecked(false);
+b.Type().End()
+    .Function().End()
+    .Code()
+    .Function({ params: [&quot;i32&quot;], ret: &quot;i32&quot; }, [])
+    .Block(&quot;i32&quot;, (b) =&gt;
+           b.GetLocal(0)
+           .I32Const(0)
+           .I32Eq()
+           .If(&quot;i32&quot;)
+               .I32Const(1)
+           .Else()
+               .I32Const(2)
+           .Br(1)
+           .End()
+          ).End()
+
+const bin = b.WebAssembly()
+bin.trim();
+testWasmModuleFunctions(bin.get(), 1, [[{type: &quot;i32&quot;, value: 1 }, [{ type: &quot;i32&quot;, value: 0 }]],
+                                       [{type: &quot;i32&quot;, value: 2 }, [{ type: &quot;i32&quot;, value: 1 }]]
+                                      ]);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkJSTestswasmjsapifunctiontestsloopmultjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/wasm/js-api/function-tests/loop-mult.js (0 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/js-api/function-tests/loop-mult.js                                (rev 0)
+++ trunk/JSTests/wasm/js-api/function-tests/loop-mult.js        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -0,0 +1,38 @@
</span><ins>+import Builder from '../../Builder.js'
+
+const b = new Builder();
+b.setChecked(false);
+b.Type().End()
+    .Function().End()
+    .Code()
+    .Function({ params: [&quot;i32&quot;], ret: &quot;i32&quot; }, [&quot;i32&quot;])
+    .I32Const(0)
+    .SetLocal(1)
+    .Loop(&quot;void&quot;)
+    .Block(&quot;void&quot;, b =&gt;
+           b.GetLocal(0)
+           .I32Const(0)
+           .I32Eq()
+           .BrIf(0)
+           .GetLocal(0)
+           .GetLocal(1)
+           .I32Add()
+           .SetLocal(1)
+           .GetLocal(0)
+           .I32Const(1)
+           .I32Sub()
+           .SetLocal(0)
+           .Br(1)
+          )
+    .End()
+    .GetLocal(1)
+    .Return()
+    .End()
+
+const bin = b.WebAssembly()
+bin.trim();
+testWasmModuleFunctions(bin.get(), 1, [[{type: &quot;i32&quot;, value: 0 }, [{ type: &quot;i32&quot;, value: 0 }]],
+                                       [{type: &quot;i32&quot;, value: 1 }, [{ type: &quot;i32&quot;, value: 1 }]],
+                                       [{type: &quot;i32&quot;, value: 3 }, [{ type: &quot;i32&quot;, value: 2 }]],
+                                       [{type: &quot;i32&quot;, value: 5050 }, [{ type: &quot;i32&quot;, value: 100 }]]
+                                      ]);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkJSTestswasmjsapifunctiontestsloopsumjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/wasm/js-api/function-tests/loop-sum.js (0 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/js-api/function-tests/loop-sum.js                                (rev 0)
+++ trunk/JSTests/wasm/js-api/function-tests/loop-sum.js        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -0,0 +1,38 @@
</span><ins>+import Builder from '../../Builder.js'
+
+const b = new Builder();
+b.setChecked(false);
+b.Type().End()
+    .Function().End()
+    .Code()
+    .Function({ params: [&quot;i32&quot;], ret: &quot;i32&quot; }, [&quot;i32&quot;])
+    .I32Const(0)
+    .SetLocal(1)
+    .Loop(&quot;void&quot;)
+    .Block(&quot;void&quot;, b =&gt;
+           b.GetLocal(0)
+           .I32Const(0)
+           .I32Eq()
+           .BrIf(0)
+           .GetLocal(0)
+           .GetLocal(1)
+           .I32Add()
+           .SetLocal(1)
+           .GetLocal(0)
+           .I32Const(1)
+           .I32Sub()
+           .SetLocal(0)
+           .Br(1)
+          )
+    .End()
+    .GetLocal(1)
+    .Return()
+    .End()
+
+const bin = b.WebAssembly()
+bin.trim();
+testWasmModuleFunctions(bin.get(), 1, [[{type: &quot;i32&quot;, value: 0 }, [{ type: &quot;i32&quot;, value: 0 }]],
+                                       [{type: &quot;i32&quot;, value: 1 }, [{ type: &quot;i32&quot;, value: 1 }]],
+                                       [{type: &quot;i32&quot;, value: 3 }, [{ type: &quot;i32&quot;, value: 2 }]],
+                                       [{type: &quot;i32&quot;, value: 5050 }, [{ type: &quot;i32&quot;, value: 100 }]]
+                                      ]);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkJSTestswasmjsapifunctiontestsret5js"></a>
<div class="addfile"><h4>Added: trunk/JSTests/wasm/js-api/function-tests/ret5.js (0 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/js-api/function-tests/ret5.js                                (rev 0)
+++ trunk/JSTests/wasm/js-api/function-tests/ret5.js        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+import Builder from '../../Builder.js'
+
+const b = new Builder();
+b.setChecked(false);
+let code = b.Type().End()
+    .Function().End()
+    .Code();
+
+code.Function({ params: [], ret: &quot;i32&quot; })
+    .I32Const(5)
+    .Return()
+    .End()
+    .End();
+const bin = b.WebAssembly();
+bin.trim();
+testWasmModuleFunctions(bin.get(), 1, [[{type: &quot;i32&quot;, value: 5 }, []]]);
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkJSTestswasmselftesttest_LowLevelBinary_varintjs"></a>
<div class="delfile"><h4>Deleted: trunk/JSTests/wasm/self-test/test_LowLevelBinary_varint.js (208626 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/self-test/test_LowLevelBinary_varint.js        2016-11-12 00:28:29 UTC (rev 208626)
+++ trunk/JSTests/wasm/self-test/test_LowLevelBinary_varint.js        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -1,30 +0,0 @@
</span><del>-import LowLevelBinary, * as LLB from '../LowLevelBinary.js';
-import * as assert from '../assert.js';
-
-let values = [];
-for (let i = LLB.varintMin; i !== LLB.varintMin + 1024; ++i) values.push(i);
-for (let i = -2048; i !== 2048; ++i) values.push(i);
-for (let i = LLB.varintMax; i !== LLB.varintMax - 1024; --i) values.push(i);
-
-for (const i of values) {
-    let b = new LowLevelBinary();
-    b.varint(i);
-    const v = b.getVarint(0);
-    if (v.value !== i)
-        throw new Error(`Wrote &quot;${i}&quot; and read back &quot;${v}&quot;`);
-    if (v.next !== b.getSize())
-        throw new Error(`Size ${v.next}, expected ${b.getSize()}`);
-}
-
-for (let i = 0; i &lt; LLB.varBitsMax + 1; ++i) {
-    let b = new LowLevelBinary();
-    for (let j = 0; j &lt; i; ++j)
-        b.uint8(0x80);
-    assert.throws(() =&gt; b.getVarint(0), RangeError, `[${i}, ${i+1}) is out of buffer range [0, ${i})`);
-}
-
-let b = new LowLevelBinary();
-for (let i = 0; i &lt; LLB.varBitsMax; ++i)
-    b.uint8(0x80);
-b.uint8(0x00);
-assert.throws(() =&gt; b.getVarint(0), RangeError, `Shifting too much at 6`);
</del></span></pre></div>
<a id="trunkJSTestswasmselftesttest_LowLevelBinary_varint32jsfromrev208626trunkJSTestswasmselftesttest_LowLevelBinary_varintjs"></a>
<div class="copfile"><h4>Copied: trunk/JSTests/wasm/self-test/test_LowLevelBinary_varint32.js (from rev 208626, trunk/JSTests/wasm/self-test/test_LowLevelBinary_varint.js) (0 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/self-test/test_LowLevelBinary_varint32.js                                (rev 0)
+++ trunk/JSTests/wasm/self-test/test_LowLevelBinary_varint32.js        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -0,0 +1,30 @@
</span><ins>+import LowLevelBinary, * as LLB from '../LowLevelBinary.js';
+import * as assert from '../assert.js';
+
+let values = [];
+for (let i = LLB.varint32Min; i !== LLB.varint32Min + 1024; ++i) values.push(i);
+for (let i = -2048; i !== 2048; ++i) values.push(i);
+for (let i = LLB.varint32Max; i !== LLB.varint32Max - 1024; --i) values.push(i);
+
+for (const i of values) {
+    let b = new LowLevelBinary();
+    b.varint32(i);
+    const v = b.getVarint32(0);
+    if (v.value !== i)
+        throw new Error(`Wrote &quot;${i}&quot; and read back &quot;${v}&quot;`);
+    if (v.next !== b.getSize())
+        throw new Error(`Size ${v.next}, expected ${b.getSize()}`);
+}
+
+for (let i = 0; i &lt; LLB.varBitsMax + 1; ++i) {
+    let b = new LowLevelBinary();
+    for (let j = 0; j &lt; i; ++j)
+        b.uint8(0x80);
+    assert.throws(() =&gt; b.getVarint32(0), RangeError, `[${i}, ${i+1}) is out of buffer range [0, ${i})`);
+}
+
+let b = new LowLevelBinary();
+for (let i = 0; i &lt; LLB.varBitsMax; ++i)
+    b.uint8(0x80);
+b.uint8(0x00);
+assert.throws(() =&gt; b.getVarint32(0), RangeError, `Shifting too much at 6`);
</ins></span></pre></div>
<a id="trunkJSTestswasmselftesttest_LowLevelBinary_varuintjs"></a>
<div class="delfile"><h4>Deleted: trunk/JSTests/wasm/self-test/test_LowLevelBinary_varuint.js (208626 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/self-test/test_LowLevelBinary_varuint.js        2016-11-12 00:28:29 UTC (rev 208626)
+++ trunk/JSTests/wasm/self-test/test_LowLevelBinary_varuint.js        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -1,29 +0,0 @@
</span><del>-import LowLevelBinary, * as LLB from '../LowLevelBinary.js';
-import * as assert from '../assert.js';
-
-let values = [];
-for (let i = LLB.varuintMin; i !== LLB.varuintMin + 1024; ++i) values.push(i);
-for (let i = LLB.varuintMax; i !== LLB.varuintMax - 1024; --i) values.push(i);
-
-for (const i of values) {
-    let b = new LowLevelBinary();
-    b.varuint(i);
-    const v = b.getVaruint(0);
-    if (v.value !== i)
-        throw new Error(`Wrote &quot;${i}&quot; and read back &quot;${v}&quot;`);
-    if (v.next !== b.getSize())
-        throw new Error(`Size ${v.next}, expected ${b.getSize()}`);
-}
-
-for (let i = 0; i &lt; LLB.varBitsMax + 1; ++i) {
-    let b = new LowLevelBinary();
-    for (let j = 0; j &lt; i; ++j)
-        b.uint8(0x80);
-    assert.throws(() =&gt; b.getVarint(0), RangeError, `[${i}, ${i+1}) is out of buffer range [0, ${i})`);
-}
-
-let b = new LowLevelBinary();
-for (let i = 0; i &lt; LLB.varBitsMax; ++i)
-    b.uint8(0x80);
-b.uint8(0x00);
-assert.throws(() =&gt; b.getVarint(0), RangeError, `Shifting too much at 6`);
</del></span></pre></div>
<a id="trunkJSTestswasmselftesttest_LowLevelBinary_varuint32jsfromrev208626trunkJSTestswasmselftesttest_LowLevelBinary_varuintjs"></a>
<div class="copfile"><h4>Copied: trunk/JSTests/wasm/self-test/test_LowLevelBinary_varuint32.js (from rev 208626, trunk/JSTests/wasm/self-test/test_LowLevelBinary_varuint.js) (0 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/self-test/test_LowLevelBinary_varuint32.js                                (rev 0)
+++ trunk/JSTests/wasm/self-test/test_LowLevelBinary_varuint32.js        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -0,0 +1,29 @@
</span><ins>+import LowLevelBinary, * as LLB from '../LowLevelBinary.js';
+import * as assert from '../assert.js';
+
+let values = [];
+for (let i = LLB.varuint32Min; i !== LLB.varuint32Min + 1024; ++i) values.push(i);
+for (let i = LLB.varuint32Max; i !== LLB.varuint32Max - 1024; --i) values.push(i);
+
+for (const i of values) {
+    let b = new LowLevelBinary();
+    b.varuint32(i);
+    const v = b.getVaruint32(0);
+    if (v.value !== i)
+        throw new Error(`Wrote &quot;${i}&quot; and read back &quot;${v}&quot;`);
+    if (v.next !== b.getSize())
+        throw new Error(`Size ${v.next}, expected ${b.getSize()}`);
+}
+
+for (let i = 0; i &lt; LLB.varBitsMax + 1; ++i) {
+    let b = new LowLevelBinary();
+    for (let j = 0; j &lt; i; ++j)
+        b.uint8(0x80);
+    assert.throws(() =&gt; b.getVarint32(0), RangeError, `[${i}, ${i+1}) is out of buffer range [0, ${i})`);
+}
+
+let b = new LowLevelBinary();
+for (let i = 0; i &lt; LLB.varBitsMax; ++i)
+    b.uint8(0x80);
+b.uint8(0x00);
+assert.throws(() =&gt; b.getVarint32(0), RangeError, `Shifting too much at 6`);
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (208626 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2016-11-12 00:28:29 UTC (rev 208626)
+++ trunk/Source/JavaScriptCore/ChangeLog        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -1,3 +1,68 @@
</span><ins>+2016-11-11  Keith Miller  &lt;keith_miller@apple.com&gt;
+
+        Move Wasm tests to JS
+        https://bugs.webkit.org/show_bug.cgi?id=164611
+
+        Reviewed by Geoffrey Garen.
+
+        This patch translates most of the tests from testWasm.cpp to the JS testing api. Most of the
+        ommited tests were earliest tests, which tested trivial things, like adding two
+        constants. Some tests are ommited for other reasons, however. These are:
+
+        1) Tests using I64 since the testing api does not yet know how to handle 64-bit numbers.  2)
+        Tests that would validate the memory of the module once wasm was done with it since that's
+        not really possible in JS.
+
+        In order to make such a translation easier this patch also adds some features to the JS
+        testing api:
+
+        1) Blocks can now be done lexically by adding a lambda as the last argument of the block
+        opcode. For example one can do:
+            ...
+            .Block(&quot;i32&quot;, b =&gt; b.I32Const(1) )
+
+        and the nested lambda will automatically have an end attached.
+
+        2) The JS testing api can now handle inline signature types.
+
+        3) Relocate some code to make it easier to follow and prevent 44 space indentation.
+
+        4) Rename varuint/varint to varuint32/varint32, this lets them be directly called from the
+        wasm.json without being remapped.
+
+        5) Add support for Memory and Function sections to the Builder.
+
+        6) Add support for local variables.
+
+        On the JSC side, we needed to expose a new function to validate the compiled wasm code
+        behaves the way we expect. At least until the JS Wasm API is finished. The new validation
+        function, testWasmModuleFunctions, takes an array buffer containing the wasm binary, the
+        number of functions in the blob and tests for each of those functions.
+
+        * jsc.cpp:
+        (GlobalObject::finishCreation):
+        (box):
+        (callWasmFunction):
+        (functionTestWasmModuleFunctions):
+        * testWasm.cpp:
+        (checkPlan):
+        (runWasmTests):
+        * wasm/WasmB3IRGenerator.cpp:
+        (JSC::Wasm::parseAndCompile):
+        * wasm/WasmFunctionParser.h:
+        (JSC::Wasm::FunctionParser&lt;Context&gt;::parse):
+        (JSC::Wasm::FunctionParser&lt;Context&gt;::parseBody):
+        (JSC::Wasm::FunctionParser&lt;Context&gt;::parseBlock): Deleted.
+        * wasm/WasmModuleParser.cpp:
+        (JSC::Wasm::ModuleParser::parseMemory):
+        (JSC::Wasm::ModuleParser::parseExport):
+        * wasm/WasmPlan.cpp:
+        (JSC::Wasm::Plan::Plan):
+        (JSC::Wasm::Plan::run):
+        * wasm/WasmPlan.h:
+        * wasm/js/WebAssemblyModuleConstructor.cpp:
+        (JSC::constructJSWebAssemblyModule):
+
</ins><span class="cx"> 2016-11-11  Saam Barati  &lt;sbarati@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed try to fix windows build after https://bugs.webkit.org/show_bug.cgi?id=164650
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejsccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jsc.cpp (208626 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jsc.cpp        2016-11-12 00:28:29 UTC (rev 208626)
+++ trunk/Source/JavaScriptCore/jsc.cpp        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -54,9 +54,11 @@
</span><span class="cx"> #include &quot;JSString.h&quot;
</span><span class="cx"> #include &quot;JSTypedArrays.h&quot;
</span><span class="cx"> #include &quot;LLIntData.h&quot;
</span><ins>+#include &quot;LLIntThunks.h&quot;
</ins><span class="cx"> #include &quot;ObjectConstructor.h&quot;
</span><span class="cx"> #include &quot;ParserError.h&quot;
</span><span class="cx"> #include &quot;ProfilerDatabase.h&quot;
</span><ins>+#include &quot;ProtoCallFrame.h&quot;
</ins><span class="cx"> #include &quot;SamplingProfiler.h&quot;
</span><span class="cx"> #include &quot;ShadowChicken.h&quot;
</span><span class="cx"> #include &quot;StackVisitor.h&quot;
</span><span class="lines">@@ -65,6 +67,7 @@
</span><span class="cx"> #include &quot;SuperSampler.h&quot;
</span><span class="cx"> #include &quot;TestRunnerUtils.h&quot;
</span><span class="cx"> #include &quot;TypeProfilerLog.h&quot;
</span><ins>+#include &quot;WasmPlan.h&quot;
</ins><span class="cx"> #include &lt;locale.h&gt;
</span><span class="cx"> #include &lt;math.h&gt;
</span><span class="cx"> #include &lt;stdio.h&gt;
</span><span class="lines">@@ -905,6 +908,10 @@
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionSamplingProfilerStackTraces(ExecState*);
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if ENABLE(WEBASSEMBLY)
+static EncodedJSValue JSC_HOST_CALL functionTestWasmModuleFunctions(ExecState*);
+#endif
+
</ins><span class="cx"> #if ENABLE(SAMPLING_FLAGS)
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionSetSamplingFlags(ExecState*);
</span><span class="cx"> static EncodedJSValue JSC_HOST_CALL functionClearSamplingFlags(ExecState*);
</span><span class="lines">@@ -1152,6 +1159,10 @@
</span><span class="cx">         addFunction(vm, &quot;samplingProfilerStackTraces&quot;, functionSamplingProfilerStackTraces, 0);
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#if ENABLE(WEBASSEMBLY)
+        addFunction(vm, &quot;testWasmModuleFunctions&quot;, functionTestWasmModuleFunctions, 0);
+#endif
+
</ins><span class="cx">         if (!arguments.isEmpty()) {
</span><span class="cx">             JSArray* array = constructEmptyArray(globalExec(), 0);
</span><span class="cx">             for (size_t i = 0; i &lt; arguments.size(); ++i)
</span><span class="lines">@@ -2352,6 +2363,104 @@
</span><span class="cx"> }
</span><span class="cx"> #endif // ENABLE(SAMPLING_PROFILER)
</span><span class="cx"> 
</span><ins>+#if ENABLE(WEBASSEMBLY)
+
+static JSValue box(ExecState* exec, VM&amp; vm, JSValue wasmValue)
+{
+    JSString* type = jsCast&lt;JSString*&gt;(wasmValue.get(exec, makeIdentifier(vm, &quot;type&quot;)));
+    JSValue value = wasmValue.get(exec, makeIdentifier(vm, &quot;value&quot;));
+
+    const String&amp; typeString = type-&gt;value(exec);
+    if (typeString == &quot;i64&quot;) {
+        RELEASE_ASSERT(value.isString());
+        int64_t result;
+        RELEASE_ASSERT(sscanf(bitwise_cast&lt;const char*&gt;(jsCast&lt;JSString*&gt;(value)-&gt;value(exec).characters8()), &quot;%lld&quot;, &amp;result) != EOF);
+        return JSValue::decode(result);
+    }
+    RELEASE_ASSERT(value.isNumber());
+
+    if (typeString == &quot;i32&quot;) {
+        RELEASE_ASSERT(value.isInt32());
+        return JSValue::decode(value.asInt32());
+    }
+
+    if (typeString == &quot;f32&quot;)
+        return JSValue::decode(bitwise_cast&lt;uint32_t&gt;(value.toFloat(exec)));
+
+    RELEASE_ASSERT(typeString == &quot;f64&quot;);
+    return value;
+}
+
+static JSValue callWasmFunction(VM* vm, const B3::Compilation&amp; code, Vector&lt;JSValue&gt;&amp; boxedArgs)
+{
+    JSValue firstArgument;
+    int argCount = 1;
+    JSValue* remainingArgs = nullptr;
+    if (boxedArgs.size()) {
+        remainingArgs = boxedArgs.data();
+        firstArgument = *remainingArgs;
+        remainingArgs++;
+        argCount = boxedArgs.size();
+    }
+
+    ProtoCallFrame protoCallFrame;
+    protoCallFrame.init(nullptr, nullptr, firstArgument, argCount, remainingArgs);
+
+    return JSValue::decode(vmEntryToWasm(code.code().executableAddress(), vm, &amp;protoCallFrame));
+}
+
+// testWasmModule(JSArrayBufferView source, number functionCount, ...[[WasmValue, [WasmValue]]]) where the ith copy of [[result, [args]]] is a list
+// of arguments to be passed to the ith wasm function as well as the expected result. WasmValue is an object with &quot;type&quot; and &quot;value&quot; properties.
+static EncodedJSValue JSC_HOST_CALL functionTestWasmModuleFunctions(ExecState* exec)
+{
+    VM&amp; vm = exec-&gt;vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
+    if (!Options::useWebAssembly())
+        return throwVMTypeError(exec, scope, ASCIILiteral(&quot;testWasmModule should only be called if the useWebAssembly option is set&quot;));
+
+    JSArrayBufferView* source = jsCast&lt;JSArrayBufferView*&gt;(exec-&gt;argument(0));
+    uint32_t functionCount = exec-&gt;argument(1).toUInt32(exec);
+
+    if (exec-&gt;argumentCount() != functionCount + 2)
+        CRASH();
+
+    Wasm::Plan plan(&amp;vm, static_cast&lt;uint8_t*&gt;(source-&gt;vector()), source-&gt;length());
+    plan.run();
+    if (plan.failed())
+        CRASH();
+
+    if (plan.compiledFunctionCount() != functionCount)
+        CRASH();
+
+    for (uint32_t i = 0; i &lt; functionCount; ++i) {
+        if (!plan.compiledFunction(i))
+            dataLogLn(&quot;failed to compile function at index&quot;, i);
+
+        JSArray* testCases = jsCast&lt;JSArray*&gt;(exec-&gt;argument(i + 2));
+        for (unsigned testIndex = 0; testIndex &lt; testCases-&gt;length(); ++testIndex) {
+            JSArray* test = jsCast&lt;JSArray*&gt;(testCases-&gt;getIndexQuickly(testIndex));
+            JSObject* result = jsCast&lt;JSObject*&gt;(test-&gt;getIndexQuickly(0));
+            JSArray* arguments = jsCast&lt;JSArray*&gt;(test-&gt;getIndexQuickly(1));
+
+            Vector&lt;JSValue&gt; boxedArgs;
+            for (unsigned argIndex = 0; argIndex &lt; arguments-&gt;length(); ++argIndex)
+                boxedArgs.append(box(exec, vm, arguments-&gt;getIndexQuickly(argIndex)));
+
+            JSValue callResult = callWasmFunction(&amp;vm, *plan.compiledFunction(i)-&gt;jsEntryPoint, boxedArgs);
+            JSValue expected = box(exec, vm, result);
+            if (callResult != expected) {
+                WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, toCString(&quot; (callResult == &quot;, RawPointer(bitwise_cast&lt;void*&gt;(callResult)), &quot;, expected == &quot;, RawPointer(bitwise_cast&lt;void*&gt;(expected)), &quot;)&quot;).data());
+                CRASH();
+            }
+        }
+    }
+
+    return encodedJSUndefined();
+}
+
+#endif // ENABLE(WEBASSEBLY)
+
</ins><span class="cx"> // Use SEH for Release builds only to get rid of the crash report dialog
</span><span class="cx"> // (luckily the same tests fail in Release and Debug builds so far). Need to
</span><span class="cx"> // be in a separate main function because the jscmain function requires object
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestWasmcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/testWasm.cpp (208626 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/testWasm.cpp        2016-11-12 00:28:29 UTC (rev 208626)
+++ trunk/Source/JavaScriptCore/testWasm.cpp        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -279,6 +279,7 @@
</span><span class="cx"> 
</span><span class="cx"> static void checkPlan(Plan&amp; plan, unsigned expectedNumberOfFunctions)
</span><span class="cx"> {
</span><ins>+    plan.run();
</ins><span class="cx">     if (plan.failed()) {
</span><span class="cx">         dataLogLn(&quot;Module failed to compile with error: &quot;, plan.errorMessage());
</span><span class="cx">         CRASH();
</span><span class="lines">@@ -327,7 +328,7 @@
</span><span class="cx">             0x0f, 0x14, 0x01, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 1);
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><span class="lines">@@ -373,7 +374,7 @@
</span><span class="cx">             0x10, 0x0d, 0x40, 0x09, 0x0f, 0x15, 0x01, 0x14, 0x01, 0x10, 0x0e, 0x40, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 1);
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><span class="lines">@@ -411,7 +412,7 @@
</span><span class="cx">             0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 1);
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><span class="lines">@@ -444,7 +445,7 @@
</span><span class="cx">             0x10, 0x00, 0x4d, 0x03, 0x01, 0x10, 0x01, 0x04, 0x10, 0x02, 0x06, 0x01, 0x0f, 0x0f, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 1);
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><span class="lines">@@ -471,7 +472,7 @@
</span><span class="cx">             0x4d, 0x03, 0x01, 0x10, 0x01, 0x04, 0x10, 0x02, 0x0f, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 1);
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><span class="lines">@@ -509,7 +510,7 @@
</span><span class="cx">             0x0f, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 1);
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><span class="lines">@@ -539,7 +540,7 @@
</span><span class="cx">             0x16, 0x00, 0x09, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 2);
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><span class="lines">@@ -565,7 +566,7 @@
</span><span class="cx">             0x16, 0x00, 0x09, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 2);
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><span class="lines">@@ -596,7 +597,7 @@
</span><span class="cx">             0x14, 0x00, 0x14, 0x00, 0x14, 0x00, 0x16, 0x00, 0x09, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 2);
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><span class="lines">@@ -627,7 +628,7 @@
</span><span class="cx">             0x5c, 0x16, 0x00, 0x5d, 0x09, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 1);
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><span class="lines">@@ -653,11 +654,8 @@
</span><span class="cx">             0x0f, 0x88, 0x80, 0x80, 0x80, 0x00, 0x00, 0x14, 0x00, 0x14, 0x01, 0x5b, 0x09, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
-        if (plan.compiledFunctionCount() != 2 || !plan.compiledFunction(0) || !plan.compiledFunction(1)) {
-            dataLogLn(&quot;Module failed to compile correctly.&quot;);
-            CRASH();
-        }
</del><ins>+        Plan plan(vm, vector);
+        checkPlan(plan, 2);
</ins><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><span class="cx">         CHECK_EQ(invoke&lt;int&gt;(*plan.compiledFunction(1)-&gt;jsEntryPoint, { box(0), box(0) }), 0);
</span><span class="lines">@@ -684,7 +682,7 @@
</span><span class="cx">             0x16, 0x00, 0x09, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 2);
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><span class="lines">@@ -713,7 +711,7 @@
</span><span class="cx">             0x14, 0x01, 0x14, 0x00, 0x34, 0x03, 0x00, 0x14, 0x01, 0x2b, 0x03, 0x00, 0x09, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 1);
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><span class="lines">@@ -740,7 +738,7 @@
</span><span class="cx">             0x01, 0x2a, 0x02, 0x00, 0x09, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 1);
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><span class="lines">@@ -777,7 +775,7 @@
</span><span class="cx">             0x0f, 0x09, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 1);
</span><span class="cx">         ASSERT(plan.memory()-&gt;size());
</span><span class="cx"> 
</span><span class="lines">@@ -829,7 +827,7 @@
</span><span class="cx">             0x2e, 0x00, 0x00, 0x10, 0x01, 0x14, 0x03, 0x40, 0x15, 0x03, 0x06, 0x00, 0x0f, 0x0f, 0x09, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 1);
</span><span class="cx">         ASSERT(plan.memory()-&gt;size());
</span><span class="cx"> 
</span><span class="lines">@@ -870,7 +868,7 @@
</span><span class="cx">             0x01, 0x20, 0x00, 0x00, 0x09, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 1);
</span><span class="cx">         ASSERT(plan.memory()-&gt;size());
</span><span class="cx"> 
</span><span class="lines">@@ -898,7 +896,7 @@
</span><span class="cx">             0x20, 0x00, 0x00, 0x09, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 1);
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><span class="lines">@@ -925,7 +923,7 @@
</span><span class="cx">             0x01, 0x2b, 0x03, 0x00, 0x09, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 1);
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><span class="lines">@@ -953,7 +951,7 @@
</span><span class="cx">             0x01, 0x2a, 0x02, 0x00, 0x09, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 1);
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><span class="lines">@@ -990,7 +988,7 @@
</span><span class="cx">             0x0f, 0x09, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 1);
</span><span class="cx">         ASSERT(plan.memory()-&gt;size());
</span><span class="cx"> 
</span><span class="lines">@@ -1042,7 +1040,7 @@
</span><span class="cx">             0x2e, 0x00, 0x00, 0x10, 0x01, 0x14, 0x03, 0x40, 0x15, 0x03, 0x06, 0x00, 0x0f, 0x0f, 0x09, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 1);
</span><span class="cx">         ASSERT(plan.memory()-&gt;size());
</span><span class="cx"> 
</span><span class="lines">@@ -1083,7 +1081,7 @@
</span><span class="cx">             0x01, 0x20, 0x00, 0x00, 0x09, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 1);
</span><span class="cx">         ASSERT(plan.memory()-&gt;size());
</span><span class="cx"> 
</span><span class="lines">@@ -1111,7 +1109,7 @@
</span><span class="cx">             0x20, 0x00, 0x00, 0x09, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 1);
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><span class="lines">@@ -1138,7 +1136,7 @@
</span><span class="cx">             0x03, 0x00, 0x06, 0x00, 0x04, 0x10, 0x01, 0x09, 0x0f, 0x10, 0x00, 0x09, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 1);
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><span class="lines">@@ -1176,7 +1174,7 @@
</span><span class="cx">             0x15, 0x00, 0x06, 0x00, 0x0f, 0x00, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 1);
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><span class="lines">@@ -1200,7 +1198,7 @@
</span><span class="cx">             0x8b, 0x80, 0x80, 0x80, 0x00, 0x01, 0x85, 0x80, 0x80, 0x80, 0x00, 0x00, 0x10, 0x05, 0x09, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 1);
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><span class="lines">@@ -1218,7 +1216,7 @@
</span><span class="cx">             0x40, 0x09, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 1);
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><span class="lines">@@ -1235,7 +1233,7 @@
</span><span class="cx">             0x40, 0x10, 0x03, 0x40, 0x09, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 1);
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><span class="lines">@@ -1252,7 +1250,7 @@
</span><span class="cx">             0x10, 0x03, 0x40, 0x10, 0x03, 0x40, 0x09, 0x0f, 0x00, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 1);
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><span class="lines">@@ -1268,7 +1266,7 @@
</span><span class="cx">             0x01, 0x88, 0x80, 0x80, 0x80, 0x00, 0x00, 0x14, 0x00, 0x14, 0x01, 0x40, 0x09, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 1);
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><span class="lines">@@ -1294,7 +1292,7 @@
</span><span class="cx">             0x01, 0x09, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 1);
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><span class="lines">@@ -1327,7 +1325,7 @@
</span><span class="cx">             0x10, 0x01, 0x41, 0x15, 0x00, 0x06, 0x01, 0x0f, 0x0f, 0x14, 0x01, 0x09, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 1);
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><span class="lines">@@ -1368,7 +1366,7 @@
</span><span class="cx">             0x01, 0x40, 0x15, 0x04, 0x06, 0x00, 0x0f, 0x0f, 0x0f, 0x14, 0x02, 0x09, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 1);
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span><span class="lines">@@ -1418,7 +1416,7 @@
</span><span class="cx">             0x00, 0x0f, 0x00, 0x0f
</span><span class="cx">         };
</span><span class="cx"> 
</span><del>-        Plan plan(*vm, vector);
</del><ins>+        Plan plan(vm, vector);
</ins><span class="cx">         checkPlan(plan, 1);
</span><span class="cx"> 
</span><span class="cx">         // Test this doesn't crash.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmB3IRGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp (208626 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp        2016-11-12 00:28:29 UTC (rev 208626)
+++ trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -760,6 +760,8 @@
</span><span class="cx">     procedure.resetReachability();
</span><span class="cx">     validate(procedure, &quot;After parsing:\n&quot;);
</span><span class="cx"> 
</span><ins>+    if (verbose)
+        dataLog(&quot;Pre SSA: &quot;, procedure);
</ins><span class="cx">     fixSSA(procedure);
</span><span class="cx">     if (verbose)
</span><span class="cx">         dataLog(&quot;Post SSA: &quot;, procedure);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmFunctionParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmFunctionParser.h (208626 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmFunctionParser.h        2016-11-12 00:28:29 UTC (rev 208626)
+++ trunk/Source/JavaScriptCore/wasm/WasmFunctionParser.h        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -57,7 +57,7 @@
</span><span class="cx"> private:
</span><span class="cx">     static const bool verbose = false;
</span><span class="cx"> 
</span><del>-    bool WARN_UNUSED_RETURN parseBlock();
</del><ins>+    bool WARN_UNUSED_RETURN parseBody();
</ins><span class="cx">     bool WARN_UNUSED_RETURN parseExpression(OpType);
</span><span class="cx">     bool WARN_UNUSED_RETURN parseUnreachableExpression(OpType);
</span><span class="cx">     bool WARN_UNUSED_RETURN addReturn();
</span><span class="lines">@@ -109,11 +109,11 @@
</span><span class="cx">             return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    return parseBlock();
</del><ins>+    return parseBody();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename Context&gt;
</span><del>-bool FunctionParser&lt;Context&gt;::parseBlock()
</del><ins>+bool FunctionParser&lt;Context&gt;::parseBody()
</ins><span class="cx"> {
</span><span class="cx">     while (true) {
</span><span class="cx">         uint8_t op;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmModuleParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmModuleParser.cpp (208626 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmModuleParser.cpp        2016-11-12 00:28:29 UTC (rev 208626)
+++ trunk/Source/JavaScriptCore/wasm/WasmModuleParser.cpp        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -291,6 +291,13 @@
</span><span class="cx"> 
</span><span class="cx"> bool ModuleParser::parseMemory()
</span><span class="cx"> {
</span><ins>+    uint8_t count;
+    if (!parseVarUInt1(count))
+        return false;
+
+    if (!count)
+        return true;
+
</ins><span class="cx">     uint8_t flags;
</span><span class="cx">     if (!parseVarUInt1(flags))
</span><span class="cx">         return false;
</span><span class="lines">@@ -345,7 +352,7 @@
</span><span class="cx">             uint32_t functionSignatureIndex;
</span><span class="cx">             if (!parseVarUInt32(functionSignatureIndex))
</span><span class="cx">                 return false;
</span><del>-            if (functionSignatureIndex &gt; m_module-&gt;signatures.size())
</del><ins>+            if (functionSignatureIndex &gt;= m_module-&gt;signatures.size())
</ins><span class="cx">                 return false;
</span><span class="cx">             e.functionSignature = &amp;m_module-&gt;signatures[functionSignatureIndex];
</span><span class="cx">         } break;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmPlancpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmPlan.cpp (208626 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmPlan.cpp        2016-11-12 00:28:29 UTC (rev 208626)
+++ trunk/Source/JavaScriptCore/wasm/WasmPlan.cpp        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -41,17 +41,24 @@
</span><span class="cx"> 
</span><span class="cx"> static const bool verbose = false;
</span><span class="cx">     
</span><del>-Plan::Plan(VM&amp; vm, Vector&lt;uint8_t&gt; source)
</del><ins>+Plan::Plan(VM* vm, Vector&lt;uint8_t&gt; source)
</ins><span class="cx">     : Plan(vm, source.data(), source.size())
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Plan::Plan(VM&amp; vm, const uint8_t* source, size_t sourceLength)
</del><ins>+Plan::Plan(VM* vm, const uint8_t* source, size_t sourceLength)
+    : m_vm(vm)
+    , m_source(source)
+    , m_sourceLength(sourceLength)
</ins><span class="cx"> {
</span><ins>+}
+
+void Plan::run()
+{
</ins><span class="cx">     if (verbose)
</span><span class="cx">         dataLogLn(&quot;Starting plan.&quot;);
</span><span class="cx">     {
</span><del>-        ModuleParser moduleParser(source, sourceLength);
</del><ins>+        ModuleParser moduleParser(m_source, m_sourceLength);
</ins><span class="cx">         if (!moduleParser.parse()) {
</span><span class="cx">             if (verbose)
</span><span class="cx">                 dataLogLn(&quot;Parsing module failed: &quot;, moduleParser.errorMessage());
</span><span class="lines">@@ -75,17 +82,22 @@
</span><span class="cx">     for (const FunctionInformation&amp; info : m_moduleInformation-&gt;functions) {
</span><span class="cx">         if (verbose)
</span><span class="cx">             dataLogLn(&quot;Processing function starting at: &quot;, info.start, &quot; and ending at: &quot;, info.end);
</span><del>-        const uint8_t* functionStart = source + info.start;
</del><ins>+        const uint8_t* functionStart = m_source + info.start;
</ins><span class="cx">         size_t functionLength = info.end - info.start;
</span><del>-        ASSERT(functionLength &lt;= sourceLength);
</del><ins>+        ASSERT(functionLength &lt;= m_sourceLength);
</ins><span class="cx"> 
</span><span class="cx">         String error = validateFunction(functionStart, functionLength, info.signature, m_moduleInformation-&gt;functions);
</span><span class="cx">         if (!error.isNull()) {
</span><ins>+            if (verbose) {
+                for (unsigned i = 0; i &lt; functionLength; ++i)
+                    dataLog(RawPointer(reinterpret_cast&lt;void*&gt;(functionStart[i])), &quot;, &quot;);
+                dataLogLn();
+            }
</ins><span class="cx">             m_errorMessage = error;
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        m_compiledFunctions.uncheckedAppend(parseAndCompile(vm, functionStart, functionLength, m_moduleInformation-&gt;memory.get(), info.signature, m_moduleInformation-&gt;functions));
</del><ins>+        m_compiledFunctions.uncheckedAppend(parseAndCompile(*m_vm, functionStart, functionLength, m_moduleInformation-&gt;memory.get(), info.signature, m_moduleInformation-&gt;functions));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Patch the call sites for each function.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmPlanh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmPlan.h (208626 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmPlan.h        2016-11-12 00:28:29 UTC (rev 208626)
+++ trunk/Source/JavaScriptCore/wasm/WasmPlan.h        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -38,10 +38,12 @@
</span><span class="cx"> 
</span><span class="cx"> class Plan {
</span><span class="cx"> public:
</span><del>-    JS_EXPORT_PRIVATE Plan(VM&amp;, Vector&lt;uint8_t&gt;);
-    JS_EXPORT_PRIVATE Plan(VM&amp;, const uint8_t*, size_t);
</del><ins>+    JS_EXPORT_PRIVATE Plan(VM*, Vector&lt;uint8_t&gt;);
+    JS_EXPORT_PRIVATE Plan(VM*, const uint8_t*, size_t);
</ins><span class="cx">     JS_EXPORT_PRIVATE ~Plan();
</span><span class="cx"> 
</span><ins>+    JS_EXPORT_PRIVATE void run();
+
</ins><span class="cx">     bool WARN_UNUSED_RETURN failed() const { return m_failed; }
</span><span class="cx">     const String&amp; errorMessage() const
</span><span class="cx">     {
</span><span class="lines">@@ -79,6 +81,9 @@
</span><span class="cx">     std::unique_ptr&lt;ModuleInformation&gt; m_moduleInformation;
</span><span class="cx">     CompiledFunctions m_compiledFunctions;
</span><span class="cx"> 
</span><ins>+    VM* m_vm;
+    const uint8_t* m_source;
+    const size_t m_sourceLength;
</ins><span class="cx">     bool m_failed { true };
</span><span class="cx">     String m_errorMessage;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsWebAssemblyModuleConstructorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleConstructor.cpp (208626 => 208627)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleConstructor.cpp        2016-11-12 00:28:29 UTC (rev 208626)
+++ trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleConstructor.cpp        2016-11-12 00:29:36 UTC (rev 208627)
</span><span class="lines">@@ -68,8 +68,9 @@
</span><span class="cx">     size_t byteSize = arrayBufferView ? arrayBufferView-&gt;length() : arrayBuffer-&gt;impl()-&gt;byteLength();
</span><span class="cx">     const auto* base = arrayBufferView ? static_cast&lt;uint8_t*&gt;(arrayBufferView-&gt;vector()) : static_cast&lt;uint8_t*&gt;(arrayBuffer-&gt;impl()-&gt;data());
</span><span class="cx"> 
</span><del>-    Wasm::Plan plan(vm, base + byteOffset, byteSize);
</del><ins>+    Wasm::Plan plan(&amp;vm, base + byteOffset, byteSize);
</ins><span class="cx">     // On failure, a new WebAssembly.CompileError is thrown.
</span><ins>+    plan.run();
</ins><span class="cx">     if (plan.failed())
</span><span class="cx">         return JSValue::encode(throwException(state, scope, createWebAssemblyCompileError(state, plan.errorMessage())));
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>