<!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>[189284] trunk/Source/JavaScriptCore</title>
</head>
<body>

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

<h3>Log Message</h3>
<pre>Initial implementation of WebAssembly function compiler
https://bugs.webkit.org/show_bug.cgi?id=148734

Patch by Sukolsak Sakshuwong &lt;sukolsak@gmail.com&gt; on 2015-09-03
Reviewed by Filip Pizlo.

This patch introduces WASMFunctionCompiler, a class for generating
baseline JIT code for WebAssembly functions. The source for each
WebAssembly function is parsed in two passes.
- The first pass is done by WASMFunctionSyntaxChecker when the
  WebAssembly module is initialized. It validates the syntax,
  determines the start and the end offsets in the source, and
  calculates the stack height of the function.
- The second pass is done by WASMFunctionCompiler when the function
  is about to be executed.
This patch doesn't calculate the correct stack height nor generate
the correct code. That will be done in a subsequent patch.

* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
* JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
* JavaScriptCore.xcodeproj/project.pbxproj:
* wasm/JSWASMModule.h:
(JSC::JSWASMModule::functionStartOffsetsInSource):
(JSC::JSWASMModule::functionStackHeights):
* wasm/WASMFunctionCompiler.h: Added.
(JSC::WASMFunctionCompiler::WASMFunctionCompiler):
(JSC::WASMFunctionCompiler::startFunction):
(JSC::WASMFunctionCompiler::endFunction):
(JSC::WASMFunctionCompiler::throwStackOverflowError):
(JSC::WASMFunctionCompiler::localAddress):
* wasm/WASMFunctionParser.cpp:
(JSC::WASMFunctionParser::checkSyntax):
(JSC::WASMFunctionParser::compile):
(JSC::WASMFunctionParser::parseFunction):
* wasm/WASMFunctionParser.h:
* wasm/WASMFunctionSyntaxChecker.h:
(JSC::WASMFunctionSyntaxChecker::startFunction):
(JSC::WASMFunctionSyntaxChecker::endFunction):
(JSC::WASMFunctionSyntaxChecker::stackHeight):
* wasm/WASMModuleParser.cpp:
(JSC::WASMModuleParser::parseFunctionDeclarationSection):
(JSC::WASMModuleParser::parseFunctionDefinition):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj">trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxprojfilters">trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmJSWASMModuleh">trunk/Source/JavaScriptCore/wasm/JSWASMModule.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWASMFunctionParsercpp">trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWASMFunctionParserh">trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWASMFunctionSyntaxCheckerh">trunk/Source/JavaScriptCore/wasm/WASMFunctionSyntaxChecker.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWASMModuleParsercpp">trunk/Source/JavaScriptCore/wasm/WASMModuleParser.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCorewasmWASMFunctionCompilerh">trunk/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (189283 => 189284)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-09-03 20:15:07 UTC (rev 189283)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-09-03 20:32:35 UTC (rev 189284)
</span><span class="lines">@@ -1,3 +1,47 @@
</span><ins>+2015-09-03  Sukolsak Sakshuwong  &lt;sukolsak@gmail.com&gt;
+
+        Initial implementation of WebAssembly function compiler
+        https://bugs.webkit.org/show_bug.cgi?id=148734
+
+        Reviewed by Filip Pizlo.
+
+        This patch introduces WASMFunctionCompiler, a class for generating
+        baseline JIT code for WebAssembly functions. The source for each
+        WebAssembly function is parsed in two passes.
+        - The first pass is done by WASMFunctionSyntaxChecker when the
+          WebAssembly module is initialized. It validates the syntax,
+          determines the start and the end offsets in the source, and
+          calculates the stack height of the function.
+        - The second pass is done by WASMFunctionCompiler when the function
+          is about to be executed.
+        This patch doesn't calculate the correct stack height nor generate
+        the correct code. That will be done in a subsequent patch.
+
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj:
+        * JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * wasm/JSWASMModule.h:
+        (JSC::JSWASMModule::functionStartOffsetsInSource):
+        (JSC::JSWASMModule::functionStackHeights):
+        * wasm/WASMFunctionCompiler.h: Added.
+        (JSC::WASMFunctionCompiler::WASMFunctionCompiler):
+        (JSC::WASMFunctionCompiler::startFunction):
+        (JSC::WASMFunctionCompiler::endFunction):
+        (JSC::WASMFunctionCompiler::throwStackOverflowError):
+        (JSC::WASMFunctionCompiler::localAddress):
+        * wasm/WASMFunctionParser.cpp:
+        (JSC::WASMFunctionParser::checkSyntax):
+        (JSC::WASMFunctionParser::compile):
+        (JSC::WASMFunctionParser::parseFunction):
+        * wasm/WASMFunctionParser.h:
+        * wasm/WASMFunctionSyntaxChecker.h:
+        (JSC::WASMFunctionSyntaxChecker::startFunction):
+        (JSC::WASMFunctionSyntaxChecker::endFunction):
+        (JSC::WASMFunctionSyntaxChecker::stackHeight):
+        * wasm/WASMModuleParser.cpp:
+        (JSC::WASMModuleParser::parseFunctionDeclarationSection):
+        (JSC::WASMModuleParser::parseFunctionDefinition):
+
</ins><span class="cx"> 2015-09-03  Saam barati  &lt;sbarati@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Block scoped variables should be visible across scripts
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj (189283 => 189284)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2015-09-03 20:15:07 UTC (rev 189283)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj        2015-09-03 20:32:35 UTC (rev 189284)
</span><span class="lines">@@ -1801,6 +1801,7 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\wasm\JSWASMModule.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\wasm\WASMConstants.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\wasm\WASMFormat.h&quot; /&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\wasm\WASMFunctionCompiler.h&quot; /&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\wasm\WASMFunctionParser.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\wasm\WASMFunctionSyntaxChecker.h&quot; /&gt;
</span><span class="cx">     &lt;ClInclude Include=&quot;..\wasm\WASMModuleParser.h&quot; /&gt;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorevcxprojJavaScriptCorevcxprojfilters"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters (189283 => 189284)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters        2015-09-03 20:15:07 UTC (rev 189283)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.vcxproj/JavaScriptCore.vcxproj.filters        2015-09-03 20:32:35 UTC (rev 189284)
</span><span class="lines">@@ -4457,6 +4457,9 @@
</span><span class="cx">     &lt;ClInclude Include=&quot;..\wasm\WASMFormat.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;wasm&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span><ins>+    &lt;ClInclude Include=&quot;..\wasm\WASMFunctionCompiler.h&quot;&gt;
+      &lt;Filter&gt;wasm&lt;/Filter&gt;
+    &lt;/ClInclude&gt;
</ins><span class="cx">     &lt;ClInclude Include=&quot;..\wasm\WASMFunctionParser.h&quot;&gt;
</span><span class="cx">       &lt;Filter&gt;wasm&lt;/Filter&gt;
</span><span class="cx">     &lt;/ClInclude&gt;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (189283 => 189284)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-09-03 20:15:07 UTC (rev 189283)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2015-09-03 20:32:35 UTC (rev 189284)
</span><span class="lines">@@ -1042,6 +1042,7 @@
</span><span class="cx">                 7B0247561B8682E100542440 /* WASMFunctionParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7B0247531B8682D500542440 /* WASMFunctionParser.cpp */; };
</span><span class="cx">                 7B0247571B8682E400542440 /* WASMFunctionParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B0247541B8682D500542440 /* WASMFunctionParser.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 7B0247591B868EB700542440 /* WASMFunctionSyntaxChecker.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B0247581B868EAE00542440 /* WASMFunctionSyntaxChecker.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                7B2E010E1B97AA6900EF5D5C /* WASMFunctionCompiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B2E010D1B97AA5800EF5D5C /* WASMFunctionCompiler.h */; };
</ins><span class="cx">                 7B39F76D1B62DE2E00360FB4 /* WASMModuleParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7B39F7691B62DE2200360FB4 /* WASMModuleParser.cpp */; };
</span><span class="cx">                 7B39F76E1B62DE3200360FB4 /* WASMModuleParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B39F76A1B62DE2200360FB4 /* WASMModuleParser.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 7B39F7701B62DE3200360FB4 /* WASMReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B39F76C1B62DE2200360FB4 /* WASMReader.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -2867,6 +2868,7 @@
</span><span class="cx">                 7B0247531B8682D500542440 /* WASMFunctionParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WASMFunctionParser.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7B0247541B8682D500542440 /* WASMFunctionParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WASMFunctionParser.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7B0247581B868EAE00542440 /* WASMFunctionSyntaxChecker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WASMFunctionSyntaxChecker.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                7B2E010D1B97AA5800EF5D5C /* WASMFunctionCompiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WASMFunctionCompiler.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 7B39F7691B62DE2200360FB4 /* WASMModuleParser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WASMModuleParser.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7B39F76A1B62DE2200360FB4 /* WASMModuleParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WASMModuleParser.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7B39F76C1B62DE2200360FB4 /* WASMReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WASMReader.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -4477,6 +4479,7 @@
</span><span class="cx">                                 7B98D1351B60CD5A0023B1A4 /* JSWASMModule.h */,
</span><span class="cx">                                 7B0247521B8682D500542440 /* WASMConstants.h */,
</span><span class="cx">                                 7BC547D21B69599B00959B58 /* WASMFormat.h */,
</span><ins>+                                7B2E010D1B97AA5800EF5D5C /* WASMFunctionCompiler.h */,
</ins><span class="cx">                                 7B0247531B8682D500542440 /* WASMFunctionParser.cpp */,
</span><span class="cx">                                 7B0247541B8682D500542440 /* WASMFunctionParser.h */,
</span><span class="cx">                                 7B0247581B868EAE00542440 /* WASMFunctionSyntaxChecker.h */,
</span><span class="lines">@@ -6870,6 +6873,7 @@
</span><span class="cx">                                 0F3A1BFA1A9ECB7D000DE01A /* DFGPutStackSinkingPhase.h in Headers */,
</span><span class="cx">                                 451539B912DC994500EF7AC4 /* Yarr.h in Headers */,
</span><span class="cx">                                 86704B8512DBA33700A9FE7B /* YarrInterpreter.h in Headers */,
</span><ins>+                                7B2E010E1B97AA6900EF5D5C /* WASMFunctionCompiler.h in Headers */,
</ins><span class="cx">                                 86704B8712DBA33700A9FE7B /* YarrJIT.h in Headers */,
</span><span class="cx">                                 86704B8812DBA33700A9FE7B /* YarrParser.h in Headers */,
</span><span class="cx">                                 86704B8A12DBA33700A9FE7B /* YarrPattern.h in Headers */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmJSWASMModuleh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/JSWASMModule.h (189283 => 189284)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/JSWASMModule.h        2015-09-03 20:15:07 UTC (rev 189283)
+++ trunk/Source/JavaScriptCore/wasm/JSWASMModule.h        2015-09-03 20:32:35 UTC (rev 189284)
</span><span class="lines">@@ -65,6 +65,8 @@
</span><span class="cx">     Vector&lt;WASMFunctionPointerTable&gt;&amp; functionPointerTables() { return m_functionPointerTables; }
</span><span class="cx"> 
</span><span class="cx">     Vector&lt;WriteBarrier&lt;JSFunction&gt;&gt;&amp; functions() { return m_functions; }
</span><ins>+    Vector&lt;unsigned&gt;&amp; functionStartOffsetsInSource() { return m_functionStartOffsetsInSource; }
+    Vector&lt;unsigned&gt;&amp; functionStackHeights() { return m_functionStackHeights; }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     JSWASMModule(VM&amp; vm, Structure* structure)
</span><span class="lines">@@ -83,6 +85,8 @@
</span><span class="cx">     Vector&lt;WASMFunctionPointerTable&gt; m_functionPointerTables;
</span><span class="cx"> 
</span><span class="cx">     Vector&lt;WriteBarrier&lt;JSFunction&gt;&gt; m_functions;
</span><ins>+    Vector&lt;unsigned&gt; m_functionStartOffsetsInSource;
+    Vector&lt;unsigned&gt; m_functionStackHeights;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWASMFunctionCompilerh"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h (0 => 189284)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h        2015-09-03 20:32:35 UTC (rev 189284)
</span><span class="lines">@@ -0,0 +1,170 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WASMFunctionCompiler_h
+#define WASMFunctionCompiler_h
+
+#if ENABLE(WEBASSEMBLY)
+
+#include &quot;CCallHelpers.h&quot;
+#include &quot;JITOperations.h&quot;
+#include &quot;LinkBuffer.h&quot;
+#include &quot;MaxFrameExtentForSlowPathCall.h&quot;
+
+namespace JSC {
+
+class WASMFunctionCompiler : private CCallHelpers {
+public:
+    typedef int Expression;
+    typedef int Statement;
+
+    union StackSlot {
+        int32_t intValue;
+        float floatValue;
+        double doubleValue;
+    };
+
+    WASMFunctionCompiler(VM&amp; vm, CodeBlock* codeBlock, unsigned stackHeight)
+        : CCallHelpers(&amp;vm, codeBlock)
+        , m_stackHeight(stackHeight)
+    {
+    }
+
+    void startFunction(const Vector&lt;WASMType&gt;&amp; arguments, uint32_t numberOfI32LocalVariables, uint32_t numberOfF32LocalVariables, uint32_t numberOfF64LocalVariables)
+    {
+        emitFunctionPrologue();
+        emitPutImmediateToCallFrameHeader(m_codeBlock, JSStack::CodeBlock);
+
+        m_beginLabel = label();
+
+        addPtr(TrustedImm32(-WTF::roundUpToMultipleOf(stackAlignmentRegisters(), m_stackHeight) * sizeof(StackSlot)), GPRInfo::callFrameRegister, GPRInfo::regT1);
+        m_stackOverflow = branchPtr(Above, AbsoluteAddress(m_vm-&gt;addressOfStackLimit()), GPRInfo::regT1);
+
+        move(GPRInfo::regT1, stackPointerRegister);
+        checkStackPointerAlignment();
+
+        m_numberOfLocals = arguments.size() + numberOfI32LocalVariables + numberOfF32LocalVariables + numberOfF64LocalVariables;
+
+        unsigned localIndex = 0;
+        for (size_t i = 0; i &lt; arguments.size(); ++i) {
+            Address address(GPRInfo::callFrameRegister, CallFrame::argumentOffset(i) * sizeof(Register));
+            switch (arguments[i]) {
+            case WASMType::I32:
+                load32(address, GPRInfo::regT0);
+                store32(GPRInfo::regT0, localAddress(localIndex++));
+                break;
+            case WASMType::F32:
+                load64(address, GPRInfo::regT0);
+                unboxDoubleWithoutAssertions(GPRInfo::regT0, FPRInfo::fpRegT0);
+                convertDoubleToFloat(FPRInfo::fpRegT0, FPRInfo::fpRegT0);
+                storeDouble(FPRInfo::fpRegT0, localAddress(localIndex++));
+                break;
+            case WASMType::F64:
+                load64(address, GPRInfo::regT0);
+                unboxDoubleWithoutAssertions(GPRInfo::regT0, FPRInfo::fpRegT0);
+                storeDouble(FPRInfo::fpRegT0, localAddress(localIndex++));
+                break;
+            default:
+                ASSERT_NOT_REACHED();
+            }
+        }
+        for (uint32_t i = 0; i &lt; numberOfI32LocalVariables; ++i)
+            store32(TrustedImm32(0), localAddress(localIndex++));
+        for (uint32_t i = 0; i &lt; numberOfF32LocalVariables; ++i)
+            store32(TrustedImm32(0), localAddress(localIndex++));
+        for (uint32_t i = 0; i &lt; numberOfF64LocalVariables; ++i)
+            store64(TrustedImm64(0), localAddress(localIndex++));
+
+        m_codeBlock-&gt;setNumParameters(1 + arguments.size());
+    }
+
+    void endFunction()
+    {
+        // FIXME: Remove these if the last statement is a return statement.
+        move(TrustedImm64(JSValue::encode(jsUndefined())), GPRInfo::returnValueGPR);
+        emitFunctionEpilogue();
+        ret();
+
+        m_stackOverflow.link(this);
+        if (maxFrameExtentForSlowPathCall)
+            addPtr(TrustedImm32(-maxFrameExtentForSlowPathCall), stackPointerRegister);
+        throwStackOverflowError();
+
+        // FIXME: Implement arity check.
+        Label arityCheck = label();
+        emitFunctionPrologue();
+        emitPutImmediateToCallFrameHeader(m_codeBlock, JSStack::CodeBlock);
+        jump(m_beginLabel);
+
+        LinkBuffer patchBuffer(*m_vm, *this, m_codeBlock, JITCompilationMustSucceed);
+
+        for (auto iterator : m_calls)
+            patchBuffer.link(iterator.first, FunctionPtr(iterator.second));
+
+        MacroAssemblerCodePtr withArityCheck = patchBuffer.locationOf(arityCheck);
+        CodeRef result = FINALIZE_CODE(patchBuffer, (&quot;Baseline JIT code for WebAssembly&quot;));
+        m_codeBlock-&gt;setJITCode(adoptRef(new DirectJITCode(result, withArityCheck, JITCode::BaselineJIT)));
+        m_codeBlock-&gt;capabilityLevel();
+    }
+
+private:
+    Address localAddress(unsigned localIndex) const
+    {
+        ASSERT(localIndex &lt; m_numberOfLocals);
+        return Address(GPRInfo::callFrameRegister, -(localIndex + 1) * sizeof(StackSlot));
+    }
+
+    void throwStackOverflowError()
+    {
+        setupArgumentsWithExecState(TrustedImmPtr(m_codeBlock));
+
+        m_calls.append(std::make_pair(call(), FunctionPtr(operationThrowStackOverflowError).value()));
+
+        // lookupExceptionHandlerFromCallerFrame is passed two arguments, the VM and the exec (the CallFrame*).
+        move(TrustedImmPtr(m_vm), GPRInfo::argumentGPR0);
+        move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR1);
+#if CPU(X86)
+        // FIXME: should use the call abstraction, but this is currently in the SpeculativeJIT layer!
+        poke(GPRInfo::argumentGPR0);
+        poke(GPRInfo::argumentGPR1, 1);
+#endif
+        m_calls.append(std::make_pair(call(), FunctionPtr(lookupExceptionHandlerFromCallerFrame).value()));
+        jumpToExceptionHandler();
+    }
+
+    unsigned m_stackHeight;
+    unsigned m_numberOfLocals;
+
+    Label m_beginLabel;
+    Jump m_stackOverflow;
+
+    Vector&lt;std::pair&lt;Call, void*&gt;&gt; m_calls;
+};
+
+} // namespace JSC
+
+#endif // ENABLE(WEBASSEMBLY)
+
+#endif // WASMFunctionCompiler_h
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWASMFunctionParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.cpp (189283 => 189284)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.cpp        2015-09-03 20:15:07 UTC (rev 189283)
+++ trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.cpp        2015-09-03 20:32:35 UTC (rev 189284)
</span><span class="lines">@@ -28,9 +28,8 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(WEBASSEMBLY)
</span><span class="cx"> 
</span><del>-#include &quot;CCallHelpers.h&quot;
</del><span class="cx"> #include &quot;JSWASMModule.h&quot;
</span><del>-#include &quot;LinkBuffer.h&quot;
</del><ins>+#include &quot;WASMFunctionCompiler.h&quot;
</ins><span class="cx"> #include &quot;WASMFunctionSyntaxChecker.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #define PROPAGATE_ERROR() do { if (!m_errorMessage.isNull()) return 0; } while (0)
</span><span class="lines">@@ -47,7 +46,7 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><del>-bool WASMFunctionParser::checkSyntax(JSWASMModule* module, const SourceCode&amp; source, size_t functionIndex, unsigned startOffsetInSource, unsigned&amp; endOffsetInSource, String&amp; errorMessage)
</del><ins>+bool WASMFunctionParser::checkSyntax(JSWASMModule* module, const SourceCode&amp; source, size_t functionIndex, unsigned startOffsetInSource, unsigned&amp; endOffsetInSource, unsigned&amp; stackHeight, String&amp; errorMessage)
</ins><span class="cx"> {
</span><span class="cx">     WASMFunctionParser parser(module, source, functionIndex);
</span><span class="cx">     WASMFunctionSyntaxChecker syntaxChecker;
</span><span class="lines">@@ -58,28 +57,17 @@
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="cx">     endOffsetInSource = parser.m_reader.offset();
</span><ins>+    stackHeight = syntaxChecker.stackHeight();
</ins><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WASMFunctionParser::compile(VM&amp; vm, CodeBlock* codeBlock, JSWASMModule* module, const SourceCode&amp;, size_t functionIndex)
</del><ins>+void WASMFunctionParser::compile(VM&amp; vm, CodeBlock* codeBlock, JSWASMModule* module, const SourceCode&amp; source, size_t functionIndex)
</ins><span class="cx"> {
</span><del>-    // FIXME: Actually compile the code.
-    CCallHelpers jit(&amp;vm, codeBlock);
-    MacroAssembler::Label beginLabel = jit.label();
-    jit.move(MacroAssembler::TrustedImm64(JSValue::encode(jsNumber(0))), GPRInfo::returnValueGPR);
-    jit.ret();
-    MacroAssembler::Label arityCheck = jit.label();
-    jit.jump(beginLabel);
-
-    LinkBuffer patchBuffer(vm, jit, codeBlock, JITCompilationMustSucceed);
-    MacroAssemblerCodePtr withArityCheck = patchBuffer.locationOf(arityCheck);
-    MacroAssembler::CodeRef result = FINALIZE_CODE(patchBuffer, (&quot;Baseline JIT code for WebAssembly&quot;));
-    codeBlock-&gt;setJITCode(adoptRef(new DirectJITCode(result, withArityCheck, JITCode::BaselineJIT)));
-    codeBlock-&gt;capabilityLevel();
-
-    uint32_t signatureIndex = module-&gt;functionDeclarations()[functionIndex].signatureIndex;
-    const WASMSignature&amp; signature = module-&gt;signatures()[signatureIndex];
-    codeBlock-&gt;setNumParameters(1 + signature.arguments.size());
</del><ins>+    WASMFunctionParser parser(module, source, functionIndex);
+    WASMFunctionCompiler compiler(vm, codeBlock, module-&gt;functionStackHeights()[functionIndex]);
+    parser.m_reader.setOffset(module-&gt;functionStartOffsetsInSource()[functionIndex]);
+    parser.parseFunction(compiler);
+    ASSERT(parser.m_errorMessage.isNull());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> template &lt;class Context&gt;
</span><span class="lines">@@ -102,7 +90,12 @@
</span><span class="cx">     for (uint32_t i = 0; i &lt; m_numberOfF64LocalVariables; ++i)
</span><span class="cx">         m_localTypes.append(WASMType::F64);
</span><span class="cx"> 
</span><ins>+    context.startFunction(arguments, m_numberOfI32LocalVariables, m_numberOfF32LocalVariables, m_numberOfF64LocalVariables);
+
</ins><span class="cx">     parseBlockStatement(context);
</span><ins>+    PROPAGATE_ERROR();
+
+    context.endFunction();
</ins><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWASMFunctionParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.h (189283 => 189284)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.h        2015-09-03 20:15:07 UTC (rev 189283)
+++ trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.h        2015-09-03 20:32:35 UTC (rev 189284)
</span><span class="lines">@@ -42,7 +42,7 @@
</span><span class="cx"> 
</span><span class="cx"> class WASMFunctionParser {
</span><span class="cx"> public:
</span><del>-    static bool checkSyntax(JSWASMModule*, const SourceCode&amp;, size_t functionIndex, unsigned startOffsetInSource, unsigned&amp; endOffsetInSource, String&amp; errorMessage);
</del><ins>+    static bool checkSyntax(JSWASMModule*, const SourceCode&amp;, size_t functionIndex, unsigned startOffsetInSource, unsigned&amp; endOffsetInSource, unsigned&amp; stackHeight, String&amp; errorMessage);
</ins><span class="cx">     static void compile(VM&amp;, CodeBlock*, JSWASMModule*, const SourceCode&amp;, size_t functionIndex);
</span><span class="cx"> 
</span><span class="cx"> private:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWASMFunctionSyntaxCheckerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WASMFunctionSyntaxChecker.h (189283 => 189284)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WASMFunctionSyntaxChecker.h        2015-09-03 20:15:07 UTC (rev 189283)
+++ trunk/Source/JavaScriptCore/wasm/WASMFunctionSyntaxChecker.h        2015-09-03 20:32:35 UTC (rev 189284)
</span><span class="lines">@@ -34,6 +34,19 @@
</span><span class="cx"> public:
</span><span class="cx">     typedef int Expression;
</span><span class="cx">     typedef int Statement;
</span><ins>+
+    void startFunction(const Vector&lt;WASMType&gt;&amp; arguments, uint32_t numberOfI32LocalVariables, uint32_t numberOfF32LocalVariables, uint32_t numberOfF64LocalVariables)
+    {
+        // FIXME: Need to include the number of temporaries used.
+        m_stackHeight = arguments.size() + numberOfI32LocalVariables + numberOfF32LocalVariables + numberOfF64LocalVariables;
+    }
+
+    void endFunction() { }
+
+    unsigned stackHeight() { return m_stackHeight; }
+
+private:
+    unsigned m_stackHeight;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWASMModuleParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WASMModuleParser.cpp (189283 => 189284)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WASMModuleParser.cpp        2015-09-03 20:15:07 UTC (rev 189283)
+++ trunk/Source/JavaScriptCore/wasm/WASMModuleParser.cpp        2015-09-03 20:32:35 UTC (rev 189284)
</span><span class="lines">@@ -220,6 +220,8 @@
</span><span class="cx">     READ_COMPACT_UINT32_OR_FAIL(numberOfFunctionDeclarations, &quot;Cannot read the number of function declarations.&quot;);
</span><span class="cx">     m_module-&gt;functionDeclarations().reserveInitialCapacity(numberOfFunctionDeclarations);
</span><span class="cx">     m_module-&gt;functions().reserveInitialCapacity(numberOfFunctionDeclarations);
</span><ins>+    m_module-&gt;functionStartOffsetsInSource().reserveInitialCapacity(numberOfFunctionDeclarations);
+    m_module-&gt;functionStackHeights().reserveInitialCapacity(numberOfFunctionDeclarations);
</ins><span class="cx">     for (uint32_t i = 0; i &lt; numberOfFunctionDeclarations; ++i) {
</span><span class="cx">         WASMFunctionDeclaration functionDeclaration;
</span><span class="cx">         READ_COMPACT_UINT32_OR_FAIL(functionDeclaration.signatureIndex, &quot;Cannot read the signature index.&quot;);
</span><span class="lines">@@ -262,8 +264,9 @@
</span><span class="cx"> {
</span><span class="cx">     unsigned startOffsetInSource = m_reader.offset();
</span><span class="cx">     unsigned endOffsetInSource;
</span><ins>+    unsigned stackHeight;
</ins><span class="cx">     String errorMessage;
</span><del>-    if (!WASMFunctionParser::checkSyntax(m_module.get(), m_source, functionIndex, startOffsetInSource, endOffsetInSource, errorMessage)) {
</del><ins>+    if (!WASMFunctionParser::checkSyntax(m_module.get(), m_source, functionIndex, startOffsetInSource, endOffsetInSource, stackHeight, errorMessage)) {
</ins><span class="cx">         m_errorMessage = errorMessage;
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="lines">@@ -272,6 +275,8 @@
</span><span class="cx">     WebAssemblyExecutable* webAssemblyExecutable = WebAssemblyExecutable::create(m_vm, m_source, m_module.get(), functionIndex);
</span><span class="cx">     JSFunction* function = JSFunction::create(m_vm, webAssemblyExecutable, m_globalObject.get());
</span><span class="cx">     m_module-&gt;functions().uncheckedAppend(WriteBarrier&lt;JSFunction&gt;(m_vm, m_module.get(), function));
</span><ins>+    m_module-&gt;functionStartOffsetsInSource().uncheckedAppend(startOffsetInSource);
+    m_module-&gt;functionStackHeights().uncheckedAppend(stackHeight);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WASMModuleParser::parseExportSection()
</span></span></pre>
</div>
</div>

</body>
</html>