<!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>[189822] 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/189822">189822</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2015-09-15 13:00:23 -0700 (Tue, 15 Sep 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Implement calls to JavaScript functions in WebAssembly
https://bugs.webkit.org/show_bug.cgi?id=149093

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

This patch implements calls to JavaScript functions in WebAssembly.
WebAssembly functions can only call JavaScript functions that are
imported to their module via an object that is passed into
loadWebAssembly(). References to JavaScript functions are resolved at
the module's load time, just like asm.js.

* jsc.cpp:
(GlobalObject::finishCreation):
(functionLoadWebAssembly):
* tests/stress/wasm-calls.js:
* tests/stress/wasm/calls.wasm:
* wasm/JSWASMModule.cpp:
(JSC::JSWASMModule::visitChildren):
* wasm/JSWASMModule.h:
(JSC::JSWASMModule::importedFunctions):
* wasm/WASMFunctionCompiler.h:
(JSC::WASMFunctionCompiler::buildCallImport):
* wasm/WASMFunctionParser.cpp:
(JSC::WASMFunctionParser::parseExpressionI32):
(JSC::WASMFunctionParser::parseExpressionF64):
(JSC::WASMFunctionParser::parseCallImport):
* wasm/WASMFunctionParser.h:
* wasm/WASMFunctionSyntaxChecker.h:
(JSC::WASMFunctionSyntaxChecker::buildCallInternal):
(JSC::WASMFunctionSyntaxChecker::buildCallImport):
(JSC::WASMFunctionSyntaxChecker::updateTempStackHeightForCall):
* wasm/WASMModuleParser.cpp:
(JSC::WASMModuleParser::WASMModuleParser):
(JSC::WASMModuleParser::parse):
(JSC::WASMModuleParser::parseModule):
(JSC::WASMModuleParser::parseFunctionImportSection):
(JSC::WASMModuleParser::getImportedValue):
(JSC::parseWebAssembly):
* wasm/WASMModuleParser.h:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCorejsccpp">trunk/Source/JavaScriptCore/jsc.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstresswasmcallswasm">trunk/Source/JavaScriptCore/tests/stress/wasm/calls.wasm</a></li>
<li><a href="#trunkSourceJavaScriptCoretestsstresswasmcallsjs">trunk/Source/JavaScriptCore/tests/stress/wasm-calls.js</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmJSWASMModulecpp">trunk/Source/JavaScriptCore/wasm/JSWASMModule.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmJSWASMModuleh">trunk/Source/JavaScriptCore/wasm/JSWASMModule.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWASMFunctionCompilerh">trunk/Source/JavaScriptCore/wasm/WASMFunctionCompiler.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>
<li><a href="#trunkSourceJavaScriptCorewasmWASMModuleParserh">trunk/Source/JavaScriptCore/wasm/WASMModuleParser.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (189821 => 189822)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-09-15 19:56:34 UTC (rev 189821)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-09-15 20:00:23 UTC (rev 189822)
</span><span class="lines">@@ -1,3 +1,45 @@
</span><ins>+2015-09-15  Sukolsak Sakshuwong  &lt;sukolsak@gmail.com&gt;
+
+        Implement calls to JavaScript functions in WebAssembly
+        https://bugs.webkit.org/show_bug.cgi?id=149093
+
+        Reviewed by Filip Pizlo.
+
+        This patch implements calls to JavaScript functions in WebAssembly.
+        WebAssembly functions can only call JavaScript functions that are
+        imported to their module via an object that is passed into
+        loadWebAssembly(). References to JavaScript functions are resolved at
+        the module's load time, just like asm.js.
+
+        * jsc.cpp:
+        (GlobalObject::finishCreation):
+        (functionLoadWebAssembly):
+        * tests/stress/wasm-calls.js:
+        * tests/stress/wasm/calls.wasm:
+        * wasm/JSWASMModule.cpp:
+        (JSC::JSWASMModule::visitChildren):
+        * wasm/JSWASMModule.h:
+        (JSC::JSWASMModule::importedFunctions):
+        * wasm/WASMFunctionCompiler.h:
+        (JSC::WASMFunctionCompiler::buildCallImport):
+        * wasm/WASMFunctionParser.cpp:
+        (JSC::WASMFunctionParser::parseExpressionI32):
+        (JSC::WASMFunctionParser::parseExpressionF64):
+        (JSC::WASMFunctionParser::parseCallImport):
+        * wasm/WASMFunctionParser.h:
+        * wasm/WASMFunctionSyntaxChecker.h:
+        (JSC::WASMFunctionSyntaxChecker::buildCallInternal):
+        (JSC::WASMFunctionSyntaxChecker::buildCallImport):
+        (JSC::WASMFunctionSyntaxChecker::updateTempStackHeightForCall):
+        * wasm/WASMModuleParser.cpp:
+        (JSC::WASMModuleParser::WASMModuleParser):
+        (JSC::WASMModuleParser::parse):
+        (JSC::WASMModuleParser::parseModule):
+        (JSC::WASMModuleParser::parseFunctionImportSection):
+        (JSC::WASMModuleParser::getImportedValue):
+        (JSC::parseWebAssembly):
+        * wasm/WASMModuleParser.h:
+
</ins><span class="cx"> 2015-09-15  Csaba Osztrogonác  &lt;ossy@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Fix the !ENABLE(DFG_JIT) build after r188696
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejsccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jsc.cpp (189821 => 189822)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jsc.cpp        2015-09-15 19:56:34 UTC (rev 189821)
+++ trunk/Source/JavaScriptCore/jsc.cpp        2015-09-15 20:00:23 UTC (rev 189822)
</span><span class="lines">@@ -679,7 +679,7 @@
</span><span class="cx">         addFunction(vm, &quot;drainMicrotasks&quot;, functionDrainMicrotasks, 0);
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(WEBASSEMBLY)
</span><del>-        addFunction(vm, &quot;loadWebAssembly&quot;, functionLoadWebAssembly, 1);
</del><ins>+        addFunction(vm, &quot;loadWebAssembly&quot;, functionLoadWebAssembly, 2);
</ins><span class="cx"> #endif
</span><span class="cx">         addFunction(vm, &quot;loadModule&quot;, functionLoadModule, 1);
</span><span class="cx">         addFunction(vm, &quot;checkModuleSyntax&quot;, functionCheckModuleSyntax, 1);
</span><span class="lines">@@ -1458,8 +1458,10 @@
</span><span class="cx">         return JSValue::encode(exec-&gt;vm().throwException(exec, createError(exec, ASCIILiteral(&quot;Could not open file.&quot;))));
</span><span class="cx">     RefPtr&lt;WebAssemblySourceProvider&gt; sourceProvider = WebAssemblySourceProvider::create(reinterpret_cast&lt;Vector&lt;uint8_t&gt;&amp;&gt;(buffer), fileName);
</span><span class="cx">     SourceCode source(sourceProvider);
</span><ins>+    JSObject* imports = exec-&gt;argument(1).getObject();
+
</ins><span class="cx">     String errorMessage;
</span><del>-    JSWASMModule* module = parseWebAssembly(exec, source, errorMessage);
</del><ins>+    JSWASMModule* module = parseWebAssembly(exec, source, imports, errorMessage);
</ins><span class="cx">     if (!module)
</span><span class="cx">         return JSValue::encode(exec-&gt;vm().throwException(exec, createSyntaxError(exec, errorMessage)));
</span><span class="cx">     return JSValue::encode(module);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstresswasmcallswasm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tests/stress/wasm/calls.wasm (189821 => 189822)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/wasm/calls.wasm        2015-09-15 19:56:34 UTC (rev 189821)
+++ trunk/Source/JavaScriptCore/tests/stress/wasm/calls.wasm        2015-09-15 20:00:23 UTC (rev 189822)
</span><span class="lines">@@ -1 +1 @@
</span><del>-wasm\xDC\x808\xC0\xA1\xA1\xC0\xA1\xC0\xA2\x80.\xC1\xA0\xC0\xC1#\xC0\xC1\x80! \xC0\xC1\xC0\xC1fibonaccigcdlcm
</del><span class="cx">\ No newline at end of file
</span><ins>+wasm\x82summax\x808\xC0\xA1\xA1\xC0\xA1\xC0\xA2\x80.\xC1\xA0\xC0\xC1#\xC0\xC1\x80! \xC0\xC1\xC0\xC1\x80\xC0\xC1\x80\xC0\xC1fibonaccigcdlcmcallSumcallMax
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoretestsstresswasmcallsjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/tests/stress/wasm-calls.js (189821 => 189822)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/tests/stress/wasm-calls.js        2015-09-15 19:56:34 UTC (rev 189821)
+++ trunk/Source/JavaScriptCore/tests/stress/wasm-calls.js        2015-09-15 20:00:23 UTC (rev 189822)
</span><span class="lines">@@ -8,9 +8,12 @@
</span><span class="cx"> /*
</span><span class="cx"> wasm/calls.wasm is generated by pack-asmjs &lt;https://github.com/WebAssembly/polyfill-prototype-1&gt; from the following script:
</span><span class="cx"> 
</span><del>-function asmModule(global, env, buffer) {
</del><ins>+function asmModule(global, imports, buffer) {
</ins><span class="cx">     &quot;use asm&quot;;
</span><span class="cx"> 
</span><ins>+    var sum = imports.sum;
+    var max = imports.max;
+
</ins><span class="cx">     function fibonacci(x) {
</span><span class="cx">         x = x | 0;
</span><span class="cx">         if ((x | 0) &lt;= 1)
</span><span class="lines">@@ -32,16 +35,37 @@
</span><span class="cx">         return (((x * y) | 0) / (gcd(x, y) | 0)) | 0;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    function callSum(x, y) {
+        x = x | 0;
+        y = y | 0;
+        return sum(x, y) | 0;
+    }
+
+    function callMax(x, y) {
+        x = x | 0;
+        y = y | 0;
+        return max(x, y) | 0;
+    }
+
</ins><span class="cx">     return {
</span><span class="cx">         fibonacci: fibonacci,
</span><span class="cx">         gcd: gcd,
</span><span class="cx">         lcm: lcm,
</span><ins>+        callSum: callSum,
+        callMax: callMax,
</ins><span class="cx">     };
</span><span class="cx"> }
</span><span class="cx"> */
</span><span class="cx"> 
</span><del>-var module = loadWebAssembly(&quot;wasm/calls.wasm&quot;);
</del><ins>+var imports = {
+    sum: (x, y) =&gt; x + y,
+    max: Math.max,
+};
+var module = loadWebAssembly(&quot;wasm/calls.wasm&quot;, imports);
</ins><span class="cx"> 
</span><span class="cx"> shouldBe(module.fibonacci(10), 89);
</span><span class="cx"> shouldBe(module.gcd(15, 25), 5);
</span><span class="cx"> shouldBe(module.lcm(15, 25), 75);
</span><ins>+
+shouldBe(module.callSum(1, 2), 3);
+shouldBe(module.callMax(1, 2), 2);
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmJSWASMModulecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/JSWASMModule.cpp (189821 => 189822)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/JSWASMModule.cpp        2015-09-15 19:56:34 UTC (rev 189821)
+++ trunk/Source/JavaScriptCore/wasm/JSWASMModule.cpp        2015-09-15 20:00:23 UTC (rev 189822)
</span><span class="lines">@@ -48,6 +48,8 @@
</span><span class="cx">     Base::visitChildren(thisObject, visitor);
</span><span class="cx">     for (auto function : thisObject-&gt;m_functions)
</span><span class="cx">         visitor.append(&amp;function);
</span><ins>+    for (auto importedFunction : thisObject-&gt;m_importedFunctions)
+        visitor.append(&amp;importedFunction);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmJSWASMModuleh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/JSWASMModule.h (189821 => 189822)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/JSWASMModule.h        2015-09-15 19:56:34 UTC (rev 189821)
+++ trunk/Source/JavaScriptCore/wasm/JSWASMModule.h        2015-09-15 20:00:23 UTC (rev 189822)
</span><span class="lines">@@ -87,6 +87,7 @@
</span><span class="cx">     Vector&lt;unsigned&gt;&amp; functionStartOffsetsInSource() { return m_functionStartOffsetsInSource; }
</span><span class="cx">     Vector&lt;unsigned&gt;&amp; functionStackHeights() { return m_functionStackHeights; }
</span><span class="cx">     Vector&lt;GlobalVariable&gt;&amp; globalVariables() { return m_globalVariables; }
</span><ins>+    Vector&lt;WriteBarrier&lt;JSFunction&gt;&gt;&amp; importedFunctions() { return m_importedFunctions; }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     JSWASMModule(VM&amp; vm, Structure* structure)
</span><span class="lines">@@ -108,6 +109,7 @@
</span><span class="cx">     Vector&lt;unsigned&gt; m_functionStartOffsetsInSource;
</span><span class="cx">     Vector&lt;unsigned&gt; m_functionStackHeights;
</span><span class="cx">     Vector&lt;GlobalVariable&gt; m_globalVariables;
</span><ins>+    Vector&lt;WriteBarrier&lt;JSFunction&gt;&gt; m_importedFunctions;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWASMFunctionCompilerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h (189821 => 189822)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h        2015-09-15 19:56:34 UTC (rev 189821)
+++ trunk/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h        2015-09-15 20:00:23 UTC (rev 189822)
</span><span class="lines">@@ -654,6 +654,17 @@
</span><span class="cx">         return UNUSED;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    int buildCallImport(uint32_t functionImportIndex, int, const WASMSignature&amp; signature, WASMExpressionType returnType)
+    {
+        boxArgumentsAndAdjustStackPointer(signature.arguments);
+
+        JSFunction* function = m_module-&gt;importedFunctions()[functionImportIndex].get();
+        move(TrustedImmPtr(function), GPRInfo::regT0);
+
+        callAndUnboxResult(returnType);
+        return UNUSED;
+    }
+
</ins><span class="cx">     void appendExpressionList(int&amp;, int) { }
</span><span class="cx"> 
</span><span class="cx">     void linkTarget(JumpTarget&amp; target)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWASMFunctionParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.cpp (189821 => 189822)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.cpp        2015-09-15 19:56:34 UTC (rev 189821)
+++ trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.cpp        2015-09-15 20:00:23 UTC (rev 189822)
</span><span class="lines">@@ -530,6 +530,8 @@
</span><span class="cx">             return parseGetGlobalExpressionI32(context);
</span><span class="cx">         case WASMOpExpressionI32::CallInternal:
</span><span class="cx">             return parseCallInternalExpressionI32(context);
</span><ins>+        case WASMOpExpressionI32::CallImport:
+            return parseCallImport(context, WASMExpressionType::I32);
</ins><span class="cx">         case WASMOpExpressionI32::Negate:
</span><span class="cx">         case WASMOpExpressionI32::BitNot:
</span><span class="cx">         case WASMOpExpressionI32::CountLeadingZeros:
</span><span class="lines">@@ -594,7 +596,6 @@
</span><span class="cx">         case WASMOpExpressionI32::Store32:
</span><span class="cx">         case WASMOpExpressionI32::StoreWithOffset32:
</span><span class="cx">         case WASMOpExpressionI32::CallIndirect:
</span><del>-        case WASMOpExpressionI32::CallImport:
</del><span class="cx">         case WASMOpExpressionI32::Conditional:
</span><span class="cx">         case WASMOpExpressionI32::Comma:
</span><span class="cx">         case WASMOpExpressionI32::FromF32:
</span><span class="lines">@@ -877,6 +878,8 @@
</span><span class="cx">             return parseGetLocalExpressionF64(context);
</span><span class="cx">         case WASMOpExpressionF64::GetGlobal:
</span><span class="cx">             return parseGetGlobalExpressionF64(context);
</span><ins>+        case WASMOpExpressionF64::CallImport:
+            return parseCallImport(context, WASMExpressionType::F64);
</ins><span class="cx">         case WASMOpExpressionF64::SetLocal:
</span><span class="cx">         case WASMOpExpressionF64::SetGlobal:
</span><span class="cx">         case WASMOpExpressionF64::Load:
</span><span class="lines">@@ -885,7 +888,6 @@
</span><span class="cx">         case WASMOpExpressionF64::StoreWithOffset:
</span><span class="cx">         case WASMOpExpressionF64::CallInternal:
</span><span class="cx">         case WASMOpExpressionF64::CallIndirect:
</span><del>-        case WASMOpExpressionF64::CallImport:
</del><span class="cx">         case WASMOpExpressionF64::Conditional:
</span><span class="cx">         case WASMOpExpressionF64::Comma:
</span><span class="cx">         case WASMOpExpressionF64::FromS32:
</span><span class="lines">@@ -1006,6 +1008,21 @@
</span><span class="cx">     return context.buildCallInternal(functionIndex, argumentList, signature, returnType);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+template &lt;class Context&gt;
+ContextExpression WASMFunctionParser::parseCallImport(Context&amp; context, WASMExpressionType returnType)
+{
+    uint32_t functionImportSignatureIndex;
+    READ_COMPACT_UINT32_OR_FAIL(functionImportSignatureIndex, &quot;Cannot read the function import signature index.&quot;);
+    FAIL_IF_FALSE(functionImportSignatureIndex &lt; m_module-&gt;functionImportSignatures().size(), &quot;The function import signature index is incorrect.&quot;);
+    const WASMFunctionImportSignature&amp; functionImportSignature = m_module-&gt;functionImportSignatures()[functionImportSignatureIndex];
+    const WASMSignature&amp; signature = m_module-&gt;signatures()[functionImportSignature.signatureIndex];
+    FAIL_IF_FALSE(signature.returnType == returnType, &quot;Wrong return type.&quot;);
+
+    ContextExpressionList argumentList = parseCallArguments(context, signature.arguments);
+    PROPAGATE_ERROR();
+    return context.buildCallImport(functionImportSignature.functionImportIndex, argumentList, signature, returnType);
+}
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(WEBASSEMBLY)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWASMFunctionParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.h (189821 => 189822)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.h        2015-09-15 19:56:34 UTC (rev 189821)
+++ trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.h        2015-09-15 20:00:23 UTC (rev 189822)
</span><span class="lines">@@ -116,6 +116,7 @@
</span><span class="cx"> 
</span><span class="cx">     template &lt;class Context&gt; ContextExpressionList parseCallArguments(Context&amp;, const Vector&lt;WASMType&gt;&amp; arguments);
</span><span class="cx">     template &lt;class Context&gt; ContextExpression parseCallInternal(Context&amp;, WASMExpressionType returnType);
</span><ins>+    template &lt;class Context&gt; ContextExpression parseCallImport(Context&amp;, WASMExpressionType returnType);
</ins><span class="cx"> 
</span><span class="cx">     JSWASMModule* m_module;
</span><span class="cx">     WASMReader m_reader;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWASMFunctionSyntaxCheckerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WASMFunctionSyntaxChecker.h (189821 => 189822)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WASMFunctionSyntaxChecker.h        2015-09-15 19:56:34 UTC (rev 189821)
+++ trunk/Source/JavaScriptCore/wasm/WASMFunctionSyntaxChecker.h        2015-09-15 20:00:23 UTC (rev 189822)
</span><span class="lines">@@ -144,12 +144,19 @@
</span><span class="cx">     int buildCallInternal(uint32_t, int, const WASMSignature&amp; signature, WASMExpressionType returnType)
</span><span class="cx">     {
</span><span class="cx">         size_t argumentCount = signature.arguments.size();
</span><ins>+        updateTempStackHeightForCall(argumentCount);
+        m_tempStackTop -= argumentCount;
+        if (returnType != WASMExpressionType::Void) {
+            m_tempStackTop++;
+            updateTempStackHeight();
+        }
+        return UNUSED;
+    }
</ins><span class="cx"> 
</span><del>-        // Boxed arguments + this argument + call frame header + padding.
-        m_tempStackTop += argumentCount + 1 + JSStack::CallFrameHeaderSize + 1;
-        updateTempStackHeight();
-        m_tempStackTop -= argumentCount + 1 + JSStack::CallFrameHeaderSize + 1;
-
</del><ins>+    int buildCallImport(uint32_t, int, const WASMSignature&amp; signature, WASMExpressionType returnType)
+    {
+        size_t argumentCount = signature.arguments.size();
+        updateTempStackHeightForCall(argumentCount);
</ins><span class="cx">         m_tempStackTop -= argumentCount;
</span><span class="cx">         if (returnType != WASMExpressionType::Void) {
</span><span class="cx">             m_tempStackTop++;
</span><span class="lines">@@ -196,6 +203,14 @@
</span><span class="cx">             m_tempStackHeight = m_tempStackTop;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void updateTempStackHeightForCall(size_t argumentCount)
+    {
+        // Boxed arguments + this argument + call frame header + maximum padding.
+        m_tempStackTop += argumentCount + 1 + JSStack::CallFrameHeaderSize + 1;
+        updateTempStackHeight();
+        m_tempStackTop -= argumentCount + 1 + JSStack::CallFrameHeaderSize + 1;
+    }
+
</ins><span class="cx">     unsigned m_numberOfLocals;
</span><span class="cx">     unsigned m_tempStackTop { 0 };
</span><span class="cx">     unsigned m_tempStackHeight { 0 };
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWASMModuleParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WASMModuleParser.cpp (189821 => 189822)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WASMModuleParser.cpp        2015-09-15 19:56:34 UTC (rev 189821)
+++ trunk/Source/JavaScriptCore/wasm/WASMModuleParser.cpp        2015-09-15 20:00:23 UTC (rev 189822)
</span><span class="lines">@@ -49,18 +49,19 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><del>-WASMModuleParser::WASMModuleParser(VM&amp; vm, JSGlobalObject* globalObject, const SourceCode&amp; source)
</del><ins>+WASMModuleParser::WASMModuleParser(VM&amp; vm, JSGlobalObject* globalObject, const SourceCode&amp; source, JSObject* imports)
</ins><span class="cx">     : m_vm(vm)
</span><span class="cx">     , m_globalObject(vm, globalObject)
</span><span class="cx">     , m_source(source)
</span><ins>+    , m_imports(vm, imports)
</ins><span class="cx">     , m_reader(static_cast&lt;WebAssemblySourceProvider*&gt;(source.provider())-&gt;data())
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-JSWASMModule* WASMModuleParser::parse(String&amp; errorMessage)
</del><ins>+JSWASMModule* WASMModuleParser::parse(ExecState* exec, String&amp; errorMessage)
</ins><span class="cx"> {
</span><span class="cx">     m_module.set(m_vm, JSWASMModule::create(m_vm, m_globalObject-&gt;wasmModuleStructure()));
</span><del>-    parseModule();
</del><ins>+    parseModule(exec);
</ins><span class="cx">     if (!m_errorMessage.isNull()) {
</span><span class="cx">         errorMessage = m_errorMessage;
</span><span class="cx">         return nullptr;
</span><span class="lines">@@ -68,7 +69,7 @@
</span><span class="cx">     return m_module.get();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WASMModuleParser::parseModule()
</del><ins>+void WASMModuleParser::parseModule(ExecState* exec)
</ins><span class="cx"> {
</span><span class="cx">     uint32_t magicNumber;
</span><span class="cx">     READ_UINT32_OR_FAIL(magicNumber, &quot;Cannot read the magic number.&quot;);
</span><span class="lines">@@ -81,7 +82,7 @@
</span><span class="cx">     PROPAGATE_ERROR();
</span><span class="cx">     parseSignatureSection();
</span><span class="cx">     PROPAGATE_ERROR();
</span><del>-    parseFunctionImportSection();
</del><ins>+    parseFunctionImportSection(exec);
</ins><span class="cx">     PROPAGATE_ERROR();
</span><span class="cx">     parseGlobalSection();
</span><span class="cx">     PROPAGATE_ERROR();
</span><span class="lines">@@ -143,7 +144,7 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WASMModuleParser::parseFunctionImportSection()
</del><ins>+void WASMModuleParser::parseFunctionImportSection(ExecState* exec)
</ins><span class="cx"> {
</span><span class="cx">     uint32_t numberOfFunctionImports;
</span><span class="cx">     uint32_t numberOfFunctionImportSignatures;
</span><span class="lines">@@ -151,6 +152,7 @@
</span><span class="cx">     READ_COMPACT_UINT32_OR_FAIL(numberOfFunctionImportSignatures, &quot;Cannot read the number of function import signatures.&quot;);
</span><span class="cx">     m_module-&gt;functionImports().reserveInitialCapacity(numberOfFunctionImports);
</span><span class="cx">     m_module-&gt;functionImportSignatures().reserveInitialCapacity(numberOfFunctionImportSignatures);
</span><ins>+    m_module-&gt;importedFunctions().reserveInitialCapacity(numberOfFunctionImports);
</ins><span class="cx"> 
</span><span class="cx">     for (uint32_t functionImportIndex = 0; functionImportIndex &lt; numberOfFunctionImports; ++functionImportIndex) {
</span><span class="cx">         WASMFunctionImport functionImport;
</span><span class="lines">@@ -168,6 +170,13 @@
</span><span class="cx">             functionImportSignature.functionImportIndex = functionImportIndex;
</span><span class="cx">             m_module-&gt;functionImportSignatures().uncheckedAppend(functionImportSignature);
</span><span class="cx">         }
</span><ins>+
+        JSValue value;
+        getImportedValue(exec, functionImport.functionName, value);
+        PROPAGATE_ERROR();
+        FAIL_IF_FALSE(value.isFunction(), &quot;\&quot;&quot; + functionImport.functionName + &quot;\&quot; is not a function.&quot;);
+        JSFunction* function = jsCast&lt;JSFunction*&gt;(value.asCell());
+        m_module-&gt;importedFunctions().uncheckedAppend(WriteBarrier&lt;JSFunction&gt;(m_vm, m_module.get(), function));
</ins><span class="cx">     }
</span><span class="cx">     FAIL_IF_FALSE(m_module-&gt;functionImportSignatures().size() == numberOfFunctionImportSignatures, &quot;The number of function import signatures is incorrect.&quot;);
</span><span class="cx"> }
</span><span class="lines">@@ -321,12 +330,24 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-JSWASMModule* parseWebAssembly(ExecState* exec, const SourceCode&amp; source, String&amp; errorMessage)
</del><ins>+void WASMModuleParser::getImportedValue(ExecState* exec, const String&amp; importName, JSValue&amp; value)
</ins><span class="cx"> {
</span><del>-    WASMModuleParser moduleParser(exec-&gt;vm(), exec-&gt;lexicalGlobalObject(), source);
-    return moduleParser.parse(errorMessage);
</del><ins>+    FAIL_IF_FALSE(m_imports, &quot;Accessing property of non-object.&quot;);
+    Identifier identifier = Identifier::fromString(&amp;m_vm, importName);
+    PropertySlot slot(m_imports.get());
+    if (!m_imports-&gt;getPropertySlot(exec, identifier, slot))
+        FAIL_WITH_MESSAGE(&quot;Can't find a property named \&quot;&quot; + importName + '&quot;');
+    FAIL_IF_FALSE(slot.isValue(), &quot;\&quot;&quot; + importName + &quot;\&quot; is not a data property.&quot;);
+    // We only retrieve data properties. So, this does not cause any user-observable effect.
+    value = slot.getValue(exec, identifier);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+JSWASMModule* parseWebAssembly(ExecState* exec, const SourceCode&amp; source, JSObject* imports, String&amp; errorMessage)
+{
+    WASMModuleParser moduleParser(exec-&gt;vm(), exec-&gt;lexicalGlobalObject(), source, imports);
+    return moduleParser.parse(exec, errorMessage);
+}
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(WEBASSEMBLY)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWASMModuleParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WASMModuleParser.h (189821 => 189822)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WASMModuleParser.h        2015-09-15 19:56:34 UTC (rev 189821)
+++ trunk/Source/JavaScriptCore/wasm/WASMModuleParser.h        2015-09-15 20:00:23 UTC (rev 189822)
</span><span class="lines">@@ -42,30 +42,32 @@
</span><span class="cx"> 
</span><span class="cx"> class WASMModuleParser {
</span><span class="cx"> public:
</span><del>-    WASMModuleParser(VM&amp;, JSGlobalObject*, const SourceCode&amp;);
-    JSWASMModule* parse(String&amp; errorMessage);
</del><ins>+    WASMModuleParser(VM&amp;, JSGlobalObject*, const SourceCode&amp;, JSObject* imports);
+    JSWASMModule* parse(ExecState*, String&amp; errorMessage);
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    void parseModule();
</del><ins>+    void parseModule(ExecState*);
</ins><span class="cx">     void parseConstantPoolSection();
</span><span class="cx">     void parseSignatureSection();
</span><del>-    void parseFunctionImportSection();
</del><ins>+    void parseFunctionImportSection(ExecState*);
</ins><span class="cx">     void parseGlobalSection();
</span><span class="cx">     void parseFunctionDeclarationSection();
</span><span class="cx">     void parseFunctionPointerTableSection();
</span><span class="cx">     void parseFunctionDefinitionSection();
</span><span class="cx">     void parseFunctionDefinition(size_t functionIndex);
</span><span class="cx">     void parseExportSection();
</span><ins>+    void getImportedValue(ExecState*, const String&amp; importName, JSValue&amp;);
</ins><span class="cx"> 
</span><span class="cx">     VM&amp; m_vm;
</span><span class="cx">     Strong&lt;JSGlobalObject&gt; m_globalObject;
</span><span class="cx">     const SourceCode&amp; m_source;
</span><ins>+    Strong&lt;JSObject&gt; m_imports;
</ins><span class="cx">     WASMReader m_reader;
</span><span class="cx">     Strong&lt;JSWASMModule&gt; m_module;
</span><span class="cx">     String m_errorMessage;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-JS_EXPORT_PRIVATE JSWASMModule* parseWebAssembly(ExecState*, const SourceCode&amp;, String&amp; errorMessage);
</del><ins>+JS_EXPORT_PRIVATE JSWASMModule* parseWebAssembly(ExecState*, const SourceCode&amp;, JSObject* imports, String&amp; errorMessage);
</ins><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>