<!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>[213745] 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/213745">213745</a></dd>
<dt>Author</dt> <dd>sbarati@apple.com</dd>
<dt>Date</dt> <dd>2017-03-10 18:04:37 -0800 (Fri, 10 Mar 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>WebAssembly: Make more demos run
https://bugs.webkit.org/show_bug.cgi?id=165510
&lt;rdar://problem/29760310&gt;

Reviewed by Keith Miller.

JSTests:

* wasm/Builder.js:
(export.default.Builder.prototype._registerSectionBuilders.const.section.in.WASM.description.section.switch.section.case.string_appeared_here.this.section):
* wasm/js-api/wrapper-function.js: Added.
(exportImport):
(return.new.WebAssembly.Module):
(assert.throws.makeInstance):
(assert.throws.Bar):
(assert.throws):

Source/JavaScriptCore:

This patch makes another Wasm demo run:
https://kripken.github.io/BananaBread/cube2/bb.html

This patch fixes two bugs:
1. When WebAssemblyFunctionType was added, we did not properly
update the last JS type value.
2. Our code for our JS -&gt; Wasm entrypoint was wrong. It lead to bad
code generation where we would emit B3 that would write over <a href="http://trac.webkit.org/projects/webkit/changeset/12">r12</a>
and rbx (on x86) which is invalid since those are our pinned registers.
This patch just rewrites the entrypoint to use hand written assembler
code. I was planning on doing this anyways because it's a compile
time speed boost.

Also, this patch adds support for some new API features:
We can now export an import, either via a direct export, or via a Table and the
Element section. I've added a new class called WebAssemblyWrapperFunction that
just wraps over a JSObject that is a function. Wrapper functions have types
associated with them, so if they're re-imported, or called via call_indirect,
they can be type checked.

* CMakeLists.txt:
* JavaScriptCore.xcodeproj/project.pbxproj:
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildren):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::webAssemblyWrapperFunctionStructure):
* runtime/JSType.h:
* wasm/JSWebAssemblyCodeBlock.h:
(JSC::JSWebAssemblyCodeBlock::wasmToJsCallStubForImport):
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::createJSToWasmWrapper):
* wasm/WasmCallingConvention.h:
(JSC::Wasm::CallingConvention::headerSizeInBytes):
* wasm/js/JSWebAssemblyHelpers.h:
(JSC::isWebAssemblyHostFunction):
* wasm/js/JSWebAssemblyInstance.cpp:
(JSC::JSWebAssemblyInstance::JSWebAssemblyInstance):
* wasm/js/JSWebAssemblyInstance.h:
(JSC::JSWebAssemblyInstance::importFunction):
(JSC::JSWebAssemblyInstance::importFunctions):
(JSC::JSWebAssemblyInstance::setImportFunction):
* wasm/js/JSWebAssemblyTable.cpp:
(JSC::JSWebAssemblyTable::JSWebAssemblyTable):
(JSC::JSWebAssemblyTable::grow):
(JSC::JSWebAssemblyTable::clearFunction):
(JSC::JSWebAssemblyTable::setFunction):
* wasm/js/JSWebAssemblyTable.h:
(JSC::JSWebAssemblyTable::getFunction):
* wasm/js/WebAssemblyFunction.cpp:
(JSC::callWebAssemblyFunction):
* wasm/js/WebAssemblyInstanceConstructor.cpp:
(JSC::WebAssemblyInstanceConstructor::createInstance):
* wasm/js/WebAssemblyModuleRecord.cpp:
(JSC::WebAssemblyModuleRecord::link):
(JSC::WebAssemblyModuleRecord::evaluate):
* wasm/js/WebAssemblyModuleRecord.h:
* wasm/js/WebAssemblyTablePrototype.cpp:
(JSC::webAssemblyTableProtoFuncGet):
(JSC::webAssemblyTableProtoFuncSet):
* wasm/js/WebAssemblyWrapperFunction.cpp: Added.
(JSC::callWebAssemblyWrapperFunction):
(JSC::WebAssemblyWrapperFunction::WebAssemblyWrapperFunction):
(JSC::WebAssemblyWrapperFunction::create):
(JSC::WebAssemblyWrapperFunction::finishCreation):
(JSC::WebAssemblyWrapperFunction::createStructure):
(JSC::WebAssemblyWrapperFunction::visitChildren):
* wasm/js/WebAssemblyWrapperFunction.h: Added.
(JSC::WebAssemblyWrapperFunction::signatureIndex):
(JSC::WebAssemblyWrapperFunction::wasmEntrypoint):
(JSC::WebAssemblyWrapperFunction::function):</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="#trunkSourceJavaScriptCoreCMakeListstxt">trunk/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjectcpp">trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSGlobalObjecth">trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSTypeh">trunk/Source/JavaScriptCore/runtime/JSType.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmJSWebAssemblyCodeBlockh">trunk/Source/JavaScriptCore/wasm/JSWebAssemblyCodeBlock.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmB3IRGeneratorcpp">trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmCallingConventionh">trunk/Source/JavaScriptCore/wasm/WasmCallingConvention.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsJSWebAssemblyHelpersh">trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyHelpers.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsJSWebAssemblyInstancecpp">trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsJSWebAssemblyInstanceh">trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsJSWebAssemblyTablecpp">trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsJSWebAssemblyTableh">trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsWebAssemblyInstanceConstructorcpp">trunk/Source/JavaScriptCore/wasm/js/WebAssemblyInstanceConstructor.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsWebAssemblyModuleRecordcpp">trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsWebAssemblyModuleRecordh">trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsWebAssemblyTablePrototypecpp">trunk/Source/JavaScriptCore/wasm/js/WebAssemblyTablePrototype.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkJSTestswasmjsapiwrapperfunctionjs">trunk/JSTests/wasm/js-api/wrapper-function.js</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsWebAssemblyWrapperFunctioncpp">trunk/Source/JavaScriptCore/wasm/js/WebAssemblyWrapperFunction.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsWebAssemblyWrapperFunctionh">trunk/Source/JavaScriptCore/wasm/js/WebAssemblyWrapperFunction.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkJSTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/ChangeLog (213744 => 213745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/ChangeLog        2017-03-11 01:56:08 UTC (rev 213744)
+++ trunk/JSTests/ChangeLog        2017-03-11 02:04:37 UTC (rev 213745)
</span><span class="lines">@@ -1,3 +1,20 @@
</span><ins>+2017-03-10  Saam Barati  &lt;sbarati@apple.com&gt;
+
+        WebAssembly: Make more demos run
+        https://bugs.webkit.org/show_bug.cgi?id=165510
+        &lt;rdar://problem/29760310&gt;
+
+        Reviewed by Keith Miller.
+
+        * wasm/Builder.js:
+        (export.default.Builder.prototype._registerSectionBuilders.const.section.in.WASM.description.section.switch.section.case.string_appeared_here.this.section):
+        * wasm/js-api/wrapper-function.js: Added.
+        (exportImport):
+        (return.new.WebAssembly.Module):
+        (assert.throws.makeInstance):
+        (assert.throws.Bar):
+        (assert.throws):
+
</ins><span class="cx"> 2017-03-10  Mark Lam  &lt;mark.lam@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         JSC: BindingNode::bindValue doesn't increase the scope's reference count.
</span></span></pre></div>
<a id="trunkJSTestswasmBuilderjs"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/wasm/Builder.js (213744 => 213745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/Builder.js        2017-03-11 01:56:08 UTC (rev 213744)
+++ trunk/JSTests/wasm/Builder.js        2017-03-11 02:04:37 UTC (rev 213745)
</span><span class="lines">@@ -579,7 +579,10 @@
</span><span class="cx">                 break;
</span><span class="cx"> 
</span><span class="cx">             case &quot;Element&quot;:
</span><del>-                this[section] = function() {
</del><ins>+                this[section] = function(...args) {
+                    if (args.length !== 0)
+                        throw new Error(&quot;You're doing it wrong. This element does not take arguments. You must chain the call with another Element()&quot;);
+
</ins><span class="cx">                     const s = this._addSection(section);
</span><span class="cx">                     const elementBuilder = {
</span><span class="cx">                         End: () =&gt; this,
</span></span></pre></div>
<a id="trunkJSTestswasmjsapiwrapperfunctionjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/wasm/js-api/wrapper-function.js (0 => 213745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/js-api/wrapper-function.js                                (rev 0)
+++ trunk/JSTests/wasm/js-api/wrapper-function.js        2017-03-11 02:04:37 UTC (rev 213745)
</span><span class="lines">@@ -0,0 +1,146 @@
</span><ins>+import Builder from '../Builder.js';
+import * as assert from '../assert.js';
+
+
+function exportImport(type) {
+    let builder = (new Builder())
+        .Type().End()
+        .Import()
+            .Function(&quot;imp&quot;, &quot;f&quot;, type)
+        .End()
+        .Function().End()
+        .Export()
+            .Function(&quot;func&quot;, {module: &quot;imp&quot;, field: &quot;f&quot;})
+        .End()
+        .Code().End();
+    return new WebAssembly.Module(builder.WebAssembly().get());
+}
+
+{
+    let type = { params: [&quot;i32&quot;], ret: &quot;i32&quot; };
+    let module = exportImport(type);
+    let called = false;
+    let foo = (i) =&gt; {
+        called = true;
+        return i + 42;
+    };
+    let instance = new WebAssembly.Instance(module, {imp: {f: foo}});
+    assert.truthy(instance.exports.func !== foo);
+    for (let i = 0; i &lt; 100; i++) {
+        let r1 = instance.exports.func(i);
+        assert.truthy(called);
+        called = false;
+        let r2 = foo(i);
+        called = false;
+        assert.eq(r1, r2);
+    }
+
+    {
+        let builder = (new Builder())
+            .Type().End()
+            .Import()
+                .Function(&quot;imp&quot;, &quot;f&quot;, {params: []})
+            .End()
+            .Function().End()
+            .Code().End();
+        let module = new WebAssembly.Module(builder.WebAssembly().get());
+        // This should not type check.
+        assert.throws(() =&gt; new WebAssembly.Instance(module, {imp: {f: instance.exports.func}}), WebAssembly.LinkError, &quot;imported function's signature doesn't match the provided WebAssembly function's signature&quot;);
+    }
+
+}
+
+{
+    const tableDescription = {element: &quot;anyfunc&quot;, initial: 2};
+    function makeInstance(type, imp) {
+        const builder = new Builder()
+            .Type()
+                .Func([&quot;i32&quot;], &quot;i32&quot;)
+                .Func([&quot;i32&quot;, &quot;i32&quot;], &quot;i32&quot;)
+            .End()
+            .Import()
+                .Table(&quot;imp&quot;, &quot;table&quot;, tableDescription)
+                .Function(&quot;imp&quot;, &quot;f1&quot;, {params: [&quot;i32&quot;], ret:&quot;i32&quot;})
+                .Function(&quot;imp&quot;, &quot;f2&quot;, {params: [&quot;i32&quot;, &quot;i32&quot;], ret:&quot;i32&quot;})
+            .End()
+            .Function().End()
+            .Export()
+                .Function(&quot;foo&quot;)
+            .End()
+            .Element()
+                .Element({offset: 0, functionIndices: [0, 1]})
+            .End()
+            .Code()
+                .Function(&quot;foo&quot;, 1)
+                    .GetLocal(1) // parameter to call
+                    .GetLocal(0) // call index
+                    .CallIndirect(0, 0) // calling function of type ['i32'] =&gt; 'i32'
+                    .Return()
+                .End()
+            .End();
+        let module = new WebAssembly.Module(builder.WebAssembly().get());
+        return new WebAssembly.Instance(module, imp);
+    }
+
+    function Bar(){};
+    noInline(Bar);
+    let called = false;
+    let foo = (i) =&gt; {
+        called = true;
+        new Bar;
+        return i*42;
+    }
+    let table = new WebAssembly.Table(tableDescription);
+    let inst = makeInstance({params:['i32'], ret:&quot;i32&quot;}, {imp: {f1: foo, f2:foo, table}});
+    for (let i = 0; i &lt; 1000; i++) {
+        let r1 = inst.exports.foo(0, i);
+        assert.truthy(called);
+        called = false;
+        let r2 = foo(i);
+        assert.truthy(called);
+        called = false;
+        assert.eq(r1, r2);
+    }
+    for (let i = 0; i &lt; 1000; i++) {
+        assert.throws(() =&gt; inst.exports.foo(1, i), WebAssembly.RuntimeError, &quot;call_indirect to a signature that does not match&quot;);
+        assert.truthy(!called);
+    }
+    for (let i = 0; i &lt; 1000; i++) {
+        let r1 = table.get(0)(i);
+        table.set(0, table.get(0)); // just make sure setting a wrapper function works.
+        assert.truthy(called);
+        called = false;
+        let r2 = table.get(1)(i);
+        assert.truthy(called);
+        called = false;
+        assert.eq(r1, r2);
+    }
+
+    {
+        let nextInst = makeInstance({params:['i32'], ret:&quot;i32&quot;}, {imp: {f1: table.get(0), f2:inst.exports.foo, table}});
+        for (let i = 0; i &lt; 1000; i++) {
+            let r1 = nextInst.exports.foo(0, i);
+            assert.truthy(called);
+            called = false;
+            let r2 = foo(i);
+            assert.truthy(called);
+            called = false;
+            assert.eq(r1, r2);
+        }
+
+        for (let i = 0; i &lt; 1000; i++) {
+            assert.throws(() =&gt; nextInst.exports.foo(1, i), WebAssembly.RuntimeError, &quot;call_indirect to a signature that does not match&quot;);
+            assert.truthy(!called);
+        }
+
+        for (let i = 0; i &lt; 1000; i++) {
+            let r1 = table.get(1)(0, i);
+            assert.truthy(called);
+            called = false;
+            let r2 = foo(i);
+            assert.truthy(called);
+            called = false;
+            assert.eq(r1, r2);
+        }
+    }
+}
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/CMakeLists.txt (213744 => 213745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/CMakeLists.txt        2017-03-11 01:56:08 UTC (rev 213744)
+++ trunk/Source/JavaScriptCore/CMakeLists.txt        2017-03-11 02:04:37 UTC (rev 213745)
</span><span class="lines">@@ -968,6 +968,7 @@
</span><span class="cx">     wasm/js/WebAssemblyTableConstructor.cpp
</span><span class="cx">     wasm/js/WebAssemblyTablePrototype.cpp
</span><span class="cx">     wasm/js/WebAssemblyToJSCallee.cpp
</span><ins>+    wasm/js/WebAssemblyWrapperFunction.cpp
</ins><span class="cx"> 
</span><span class="cx">     yarr/RegularExpression.cpp
</span><span class="cx">     yarr/YarrCanonicalizeUCS2.cpp
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (213744 => 213745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2017-03-11 01:56:08 UTC (rev 213744)
+++ trunk/Source/JavaScriptCore/ChangeLog        2017-03-11 02:04:37 UTC (rev 213745)
</span><span class="lines">@@ -1,3 +1,83 @@
</span><ins>+2017-03-10  Saam Barati  &lt;sbarati@apple.com&gt;
+
+        WebAssembly: Make more demos run
+        https://bugs.webkit.org/show_bug.cgi?id=165510
+        &lt;rdar://problem/29760310&gt;
+
+        Reviewed by Keith Miller.
+
+        This patch makes another Wasm demo run:
+        https://kripken.github.io/BananaBread/cube2/bb.html
+        
+        This patch fixes two bugs:
+        1. When WebAssemblyFunctionType was added, we did not properly
+        update the last JS type value.
+        2. Our code for our JS -&gt; Wasm entrypoint was wrong. It lead to bad
+        code generation where we would emit B3 that would write over r12
+        and rbx (on x86) which is invalid since those are our pinned registers.
+        This patch just rewrites the entrypoint to use hand written assembler
+        code. I was planning on doing this anyways because it's a compile
+        time speed boost.
+        
+        Also, this patch adds support for some new API features:
+        We can now export an import, either via a direct export, or via a Table and the
+        Element section. I've added a new class called WebAssemblyWrapperFunction that
+        just wraps over a JSObject that is a function. Wrapper functions have types
+        associated with them, so if they're re-imported, or called via call_indirect,
+        they can be type checked.
+
+        * CMakeLists.txt:
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        (JSC::JSGlobalObject::visitChildren):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::webAssemblyWrapperFunctionStructure):
+        * runtime/JSType.h:
+        * wasm/JSWebAssemblyCodeBlock.h:
+        (JSC::JSWebAssemblyCodeBlock::wasmToJsCallStubForImport):
+        * wasm/WasmB3IRGenerator.cpp:
+        (JSC::Wasm::createJSToWasmWrapper):
+        * wasm/WasmCallingConvention.h:
+        (JSC::Wasm::CallingConvention::headerSizeInBytes):
+        * wasm/js/JSWebAssemblyHelpers.h:
+        (JSC::isWebAssemblyHostFunction):
+        * wasm/js/JSWebAssemblyInstance.cpp:
+        (JSC::JSWebAssemblyInstance::JSWebAssemblyInstance):
+        * wasm/js/JSWebAssemblyInstance.h:
+        (JSC::JSWebAssemblyInstance::importFunction):
+        (JSC::JSWebAssemblyInstance::importFunctions):
+        (JSC::JSWebAssemblyInstance::setImportFunction):
+        * wasm/js/JSWebAssemblyTable.cpp:
+        (JSC::JSWebAssemblyTable::JSWebAssemblyTable):
+        (JSC::JSWebAssemblyTable::grow):
+        (JSC::JSWebAssemblyTable::clearFunction):
+        (JSC::JSWebAssemblyTable::setFunction):
+        * wasm/js/JSWebAssemblyTable.h:
+        (JSC::JSWebAssemblyTable::getFunction):
+        * wasm/js/WebAssemblyFunction.cpp:
+        (JSC::callWebAssemblyFunction):
+        * wasm/js/WebAssemblyInstanceConstructor.cpp:
+        (JSC::WebAssemblyInstanceConstructor::createInstance):
+        * wasm/js/WebAssemblyModuleRecord.cpp:
+        (JSC::WebAssemblyModuleRecord::link):
+        (JSC::WebAssemblyModuleRecord::evaluate):
+        * wasm/js/WebAssemblyModuleRecord.h:
+        * wasm/js/WebAssemblyTablePrototype.cpp:
+        (JSC::webAssemblyTableProtoFuncGet):
+        (JSC::webAssemblyTableProtoFuncSet):
+        * wasm/js/WebAssemblyWrapperFunction.cpp: Added.
+        (JSC::callWebAssemblyWrapperFunction):
+        (JSC::WebAssemblyWrapperFunction::WebAssemblyWrapperFunction):
+        (JSC::WebAssemblyWrapperFunction::create):
+        (JSC::WebAssemblyWrapperFunction::finishCreation):
+        (JSC::WebAssemblyWrapperFunction::createStructure):
+        (JSC::WebAssemblyWrapperFunction::visitChildren):
+        * wasm/js/WebAssemblyWrapperFunction.h: Added.
+        (JSC::WebAssemblyWrapperFunction::signatureIndex):
+        (JSC::WebAssemblyWrapperFunction::wasmEntrypoint):
+        (JSC::WebAssemblyWrapperFunction::function):
+
</ins><span class="cx"> 2017-03-10  Mark Lam  &lt;mark.lam@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         JSC: BindingNode::bindValue doesn't increase the scope's reference count.
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (213744 => 213745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2017-03-11 01:56:08 UTC (rev 213744)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2017-03-11 02:04:37 UTC (rev 213745)
</span><span class="lines">@@ -1312,6 +1312,8 @@
</span><span class="cx">                 52C0611F1AA51E1C00B4ADBA /* RuntimeType.h in Headers */ = {isa = PBXBuildFile; fileRef = 52C0611D1AA51E1B00B4ADBA /* RuntimeType.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 52C952B719A289850069B386 /* TypeProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 52C952B619A289850069B386 /* TypeProfiler.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 52C952B919A28A1C0069B386 /* TypeProfiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52C952B819A28A1C0069B386 /* TypeProfiler.cpp */; };
</span><ins>+                52F6C35D1E71EB080081F4CC /* WebAssemblyWrapperFunction.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 52F6C35B1E71EB080081F4CC /* WebAssemblyWrapperFunction.cpp */; };
+                52F6C35E1E71EB080081F4CC /* WebAssemblyWrapperFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 52F6C35C1E71EB080081F4CC /* WebAssemblyWrapperFunction.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 531374BD1D5CE67600AF7A0B /* WasmPlan.h in Headers */ = {isa = PBXBuildFile; fileRef = 531374BC1D5CE67600AF7A0B /* WasmPlan.h */; };
</span><span class="cx">                 531374BF1D5CE95000AF7A0B /* WasmPlan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 531374BE1D5CE95000AF7A0B /* WasmPlan.cpp */; };
</span><span class="cx">                 533B15DF1DC7F463004D500A /* WasmOps.h in Headers */ = {isa = PBXBuildFile; fileRef = 533B15DE1DC7F463004D500A /* WasmOps.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -3789,6 +3791,8 @@
</span><span class="cx">                 52C0611D1AA51E1B00B4ADBA /* RuntimeType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RuntimeType.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 52C952B619A289850069B386 /* TypeProfiler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TypeProfiler.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 52C952B819A28A1C0069B386 /* TypeProfiler.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TypeProfiler.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                52F6C35B1E71EB080081F4CC /* WebAssemblyWrapperFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebAssemblyWrapperFunction.cpp; path = js/WebAssemblyWrapperFunction.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                52F6C35C1E71EB080081F4CC /* WebAssemblyWrapperFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebAssemblyWrapperFunction.h; path = js/WebAssemblyWrapperFunction.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 531374BC1D5CE67600AF7A0B /* WasmPlan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmPlan.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 531374BE1D5CE95000AF7A0B /* WasmPlan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmPlan.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 533B15DE1DC7F463004D500A /* WasmOps.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmOps.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -7908,6 +7912,8 @@
</span><span class="cx">                                 AD2FCBC31DB58DA400B3E736 /* WebAssemblyTablePrototype.h */,
</span><span class="cx">                                 ADBC54D21DF8EA00005BF738 /* WebAssemblyToJSCallee.cpp */,
</span><span class="cx">                                 ADBC54D31DF8EA00005BF738 /* WebAssemblyToJSCallee.h */,
</span><ins>+                                52F6C35B1E71EB080081F4CC /* WebAssemblyWrapperFunction.cpp */,
+                                52F6C35C1E71EB080081F4CC /* WebAssemblyWrapperFunction.h */,
</ins><span class="cx">                         );
</span><span class="cx">                         name = js;
</span><span class="cx">                         sourceTree = &quot;&lt;group&gt;&quot;;
</span><span class="lines">@@ -8245,6 +8251,7 @@
</span><span class="cx">                                 0F21C27D14BE727A00ADC64B /* CodeSpecializationKind.h in Headers */,
</span><span class="cx">                                 0F0B83A714BCF50700885B4F /* CodeType.h in Headers */,
</span><span class="cx">                                 0FA762051DB9242900B7A2FD /* CollectionScope.h in Headers */,
</span><ins>+                                52F6C35E1E71EB080081F4CC /* WebAssemblyWrapperFunction.h in Headers */,
</ins><span class="cx">                                 A53243981856A489002ED692 /* CombinedDomains.json in Headers */,
</span><span class="cx">                                 BC18C3F30E16F5CD00B34460 /* CommonIdentifiers.h in Headers */,
</span><span class="cx">                                 0F15F15F14B7A73E005DE37D /* CommonSlowPaths.h in Headers */,
</span><span class="lines">@@ -10358,6 +10365,7 @@
</span><span class="cx">                                 A503FA19188E0FB000110F14 /* JavaScriptCallFrame.cpp in Sources */,
</span><span class="cx">                                 1429D92F0ED22D7000B89619 /* JIT.cpp in Sources */,
</span><span class="cx">                                 FE1220281BE7F5910039E6F2 /* JITAddGenerator.cpp in Sources */,
</span><ins>+                                52F6C35D1E71EB080081F4CC /* WebAssemblyWrapperFunction.cpp in Sources */,
</ins><span class="cx">                                 86A90ED00EE7D51F00AB350D /* JITArithmetic.cpp in Sources */,
</span><span class="cx">                                 A75706DE118A2BCF0057F88F /* JITArithmetic32_64.cpp in Sources */,
</span><span class="cx">                                 FE3A06B11C10CB8400390FDD /* JITBitAndGenerator.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp (213744 => 213745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2017-03-11 01:56:08 UTC (rev 213744)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObject.cpp        2017-03-11 02:04:37 UTC (rev 213745)
</span><span class="lines">@@ -892,6 +892,7 @@
</span><span class="cx">         m_webAssemblyStructure.set(vm, this, JSWebAssembly::createStructure(vm, this, webAssemblyPrototype));
</span><span class="cx">         m_webAssemblyModuleRecordStructure.set(vm, this, WebAssemblyModuleRecord::createStructure(vm, this, m_objectPrototype.get()));
</span><span class="cx">         m_webAssemblyFunctionStructure.set(vm, this, WebAssemblyFunction::createStructure(vm, this, m_functionPrototype.get()));
</span><ins>+        m_webAssemblyWrapperFunctionStructure.set(vm, this, WebAssemblyWrapperFunction::createStructure(vm, this, m_functionPrototype.get()));
</ins><span class="cx">         auto* webAssembly = JSWebAssembly::create(vm, this, m_webAssemblyStructure.get());
</span><span class="cx">         putDirectWithoutTransition(vm, Identifier::fromString(exec, &quot;WebAssembly&quot;), webAssembly, DontEnum);
</span><span class="cx"> 
</span><span class="lines">@@ -1272,6 +1273,7 @@
</span><span class="cx">     visitor.append(thisObject-&gt;m_webAssemblyStructure);
</span><span class="cx">     visitor.append(thisObject-&gt;m_webAssemblyModuleRecordStructure);
</span><span class="cx">     visitor.append(thisObject-&gt;m_webAssemblyFunctionStructure);
</span><ins>+    visitor.append(thisObject-&gt;m_webAssemblyWrapperFunctionStructure);
</ins><span class="cx">     FOR_EACH_WEBASSEMBLY_CONSTRUCTOR_TYPE(VISIT_SIMPLE_TYPE)
</span><span class="cx"> #endif // ENABLE(WEBASSEMBLY)
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSGlobalObjecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h (213744 => 213745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h        2017-03-11 01:56:08 UTC (rev 213744)
+++ trunk/Source/JavaScriptCore/runtime/JSGlobalObject.h        2017-03-11 02:04:37 UTC (rev 213745)
</span><span class="lines">@@ -345,6 +345,7 @@
</span><span class="cx">     WriteBarrier&lt;Structure&gt; m_webAssemblyStructure;
</span><span class="cx">     WriteBarrier&lt;Structure&gt; m_webAssemblyModuleRecordStructure;
</span><span class="cx">     WriteBarrier&lt;Structure&gt; m_webAssemblyFunctionStructure;
</span><ins>+    WriteBarrier&lt;Structure&gt; m_webAssemblyWrapperFunctionStructure;
</ins><span class="cx">     FOR_EACH_WEBASSEMBLY_CONSTRUCTOR_TYPE(DEFINE_STORAGE_FOR_SIMPLE_TYPE)
</span><span class="cx"> #endif // ENABLE(WEBASSEMBLY)
</span><span class="cx"> 
</span><span class="lines">@@ -612,6 +613,7 @@
</span><span class="cx"> #if ENABLE(WEBASSEMBLY)
</span><span class="cx">     Structure* webAssemblyModuleRecordStructure() const { return m_webAssemblyModuleRecordStructure.get(); }
</span><span class="cx">     Structure* webAssemblyFunctionStructure() const { return m_webAssemblyFunctionStructure.get(); }
</span><ins>+    Structure* webAssemblyWrapperFunctionStructure() const { return m_webAssemblyWrapperFunctionStructure.get(); }
</ins><span class="cx"> #endif // ENABLE(WEBASSEMBLY)
</span><span class="cx"> 
</span><span class="cx">     JS_EXPORT_PRIVATE void setRemoteDebuggingEnabled(bool);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSTypeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSType.h (213744 => 213745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSType.h        2017-03-11 01:56:08 UTC (rev 213744)
+++ trunk/Source/JavaScriptCore/runtime/JSType.h        2017-03-11 02:04:37 UTC (rev 213745)
</span><span class="lines">@@ -97,7 +97,7 @@
</span><span class="cx"> 
</span><span class="cx">     WebAssemblyFunctionType,
</span><span class="cx"> 
</span><del>-    LastJSCObjectType = JSSetType,
</del><ins>+    LastJSCObjectType = WebAssemblyFunctionType,
</ins><span class="cx">     MaxJSType = 0b11111111,
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmJSWebAssemblyCodeBlockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/JSWebAssemblyCodeBlock.h (213744 => 213745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/JSWebAssemblyCodeBlock.h        2017-03-11 01:56:08 UTC (rev 213744)
+++ trunk/Source/JavaScriptCore/wasm/JSWebAssemblyCodeBlock.h        2017-03-11 02:04:37 UTC (rev 213745)
</span><span class="lines">@@ -94,6 +94,12 @@
</span><span class="cx">         return bitwise_cast&lt;WriteBarrier&lt;JSWebAssemblyCallee&gt;*&gt;(bitwise_cast&lt;char*&gt;(this) + offsetOfCallees());
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void* wasmToJsCallStubForImport(unsigned importIndex)
+    {
+        RELEASE_ASSERT(importIndex &lt; m_wasmExitStubs.size());
+        return m_wasmExitStubs[importIndex].wasmToJs.code().executableAddress();
+    }
+
</ins><span class="cx"> private:
</span><span class="cx">     JSWebAssemblyCodeBlock(VM&amp;, JSWebAssemblyModule*, Bag&lt;CallLinkInfo&gt;&amp;&amp;, Vector&lt;Wasm::WasmExitStubs&gt;&amp;&amp;, Wasm::Memory::Mode, unsigned calleeCount);
</span><span class="cx">     DECLARE_EXPORT_INFO;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmB3IRGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp (213744 => 213745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp        2017-03-11 01:56:08 UTC (rev 213744)
+++ trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp        2017-03-11 02:04:37 UTC (rev 213745)
</span><span class="lines">@@ -1039,85 +1039,165 @@
</span><span class="cx"> 
</span><span class="cx"> static void createJSToWasmWrapper(VM&amp; vm, CompilationContext&amp; compilationContext, WasmInternalFunction&amp; function, const Signature* signature, const ModuleInformation&amp; info)
</span><span class="cx"> {
</span><del>-    Procedure proc;
-    BasicBlock* block = proc.addBlock();
</del><ins>+    CCallHelpers&amp; jit = *compilationContext.jsEntrypointJIT;
</ins><span class="cx"> 
</span><del>-    Origin origin;
</del><ins>+    jit.emitFunctionPrologue();
</ins><span class="cx"> 
</span><del>-    jscCallingConvention().setupFrameInPrologue(&amp;function.jsToWasmCalleeMoveLocation, proc, origin, block);
</del><ins>+    // FIXME Stop using 0 as codeBlocks. https://bugs.webkit.org/show_bug.cgi?id=165321
+    jit.store64(CCallHelpers::TrustedImm64(0), CCallHelpers::Address(GPRInfo::callFrameRegister, CallFrameSlot::codeBlock * static_cast&lt;int&gt;(sizeof(Register))));
+    MacroAssembler::DataLabelPtr calleeMoveLocation = jit.moveWithPatch(MacroAssembler::TrustedImmPtr(nullptr), GPRInfo::nonPreservedNonReturnGPR);
+    jit.storePtr(GPRInfo::nonPreservedNonReturnGPR, CCallHelpers::Address(GPRInfo::callFrameRegister, CallFrameSlot::callee * static_cast&lt;int&gt;(sizeof(Register))));
+    CodeLocationDataLabelPtr* linkedCalleeMove = &amp;function.jsToWasmCalleeMoveLocation;
+    jit.addLinkTask([=] (LinkBuffer&amp; linkBuffer) {
+        *linkedCalleeMove = linkBuffer.locationOf(calleeMoveLocation);
+    });
</ins><span class="cx"> 
</span><del>-    if (!ASSERT_DISABLED) {
-        // This should be guaranteed by our JS wrapper that handles calls to us.
-        // Just prevent against crazy when ASSERT is enabled.
-        Value* framePointer = block-&gt;appendNew&lt;B3::Value&gt;(proc, B3::FramePointer, origin);
-        Value* offSetOfArgumentCount = block-&gt;appendNew&lt;Const64Value&gt;(proc, origin, CallFrameSlot::argumentCount * sizeof(Register));
-        Value* argumentCount = block-&gt;appendNew&lt;MemoryValue&gt;(proc, Load, Int32, origin,
-            block-&gt;appendNew&lt;Value&gt;(proc, Add, origin, framePointer, offSetOfArgumentCount));
</del><ins>+    RegisterSet toSave;
+    const PinnedRegisterInfo&amp; pinnedRegs = PinnedRegisterInfo::get();
+    toSave.set(pinnedRegs.baseMemoryPointer);
+    for (const PinnedSizeRegisterInfo&amp; regInfo : pinnedRegs.sizeRegisters)
+        toSave.set(regInfo.sizeRegister);
</ins><span class="cx"> 
</span><del>-        Value* expectedArgumentCount = block-&gt;appendNew&lt;Const32Value&gt;(proc, origin, signature-&gt;argumentCount());
</del><ins>+#if !ASSERT_DISABLED
+    unsigned toSaveSize = toSave.numberOfSetGPRs();
+    // They should all be callee saves.
+    toSave.filter(RegisterSet::calleeSaveRegisters());
+    ASSERT(toSave.numberOfSetGPRs() == toSaveSize);
+#endif
</ins><span class="cx"> 
</span><del>-        CheckValue* argumentCountCheck = block-&gt;appendNew&lt;CheckValue&gt;(proc, Check, origin,
-            block-&gt;appendNew&lt;Value&gt;(proc, Above, origin, expectedArgumentCount, argumentCount));
</del><ins>+    RegisterAtOffsetList registersToSpill(toSave, RegisterAtOffsetList::OffsetBaseType::FramePointerBased);
+    function.jsToWasmEntrypoint.calleeSaveRegisters = registersToSpill;
</ins><span class="cx"> 
</span><del>-        argumentCountCheck-&gt;setGenerator([] (CCallHelpers&amp; jit, const StackmapGenerationParams&amp;) {
-            jit.breakpoint();
-        });
</del><ins>+    unsigned totalFrameSize = registersToSpill.size() * sizeof(void*);
+    totalFrameSize += WasmCallingConvention::headerSizeInBytes();
+    totalFrameSize -= sizeof(CallerFrameAndPC);
+    unsigned numGPRs = 0;
+    unsigned numFPRs = 0;
+    for (unsigned i = 0; i &lt; signature-&gt;argumentCount(); i++) {
+        switch (signature-&gt;argument(i)) {
+        case Wasm::I64:
+        case Wasm::I32:
+            if (numGPRs &gt;= wasmCallingConvention().m_gprArgs.size())
+                totalFrameSize += sizeof(void*);
+            ++numGPRs;
+            break;
+        case Wasm::F32:
+        case Wasm::F64:
+            if (numFPRs &gt;= wasmCallingConvention().m_fprArgs.size())
+                totalFrameSize += sizeof(void*);
+            ++numFPRs;
+            break;
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+        }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // FIXME The instance is currently set by the C++ code in WebAssemblyFunction::call. We shouldn't go through the extra C++ hoop. https://bugs.webkit.org/show_bug.cgi?id=166486
-    Value* instance = block-&gt;appendNew&lt;MemoryValue&gt;(proc, Load, pointerType(), Origin(),
-        block-&gt;appendNew&lt;ConstPtrValue&gt;(proc, Origin(), &amp;vm.topJSWebAssemblyInstance));
-    restoreWebAssemblyGlobalState(vm, info.memory, instance, proc, block);
</del><ins>+    totalFrameSize = WTF::roundUpToMultipleOf(stackAlignmentBytes(), totalFrameSize);
+    jit.subPtr(MacroAssembler::TrustedImm32(totalFrameSize), MacroAssembler::stackPointerRegister);
</ins><span class="cx"> 
</span><del>-    // Get our arguments.
-    Vector&lt;Value*&gt; arguments;
-    jscCallingConvention().loadArguments(signature, proc, block, origin, [&amp;] (Value* argument, unsigned) {
-        arguments.append(argument);
-    });
</del><ins>+    // We save all these registers regardless of having a memory or not.
+    // The reason is that we use one of these as a scratch. That said,
+    // almost all real wasm programs use memory, so it's not really
+    // worth optimizing for the case that they don't.
+    for (const RegisterAtOffset&amp; regAtOffset : registersToSpill) {
+        GPRReg reg = regAtOffset.reg().gpr();
+        ptrdiff_t offset = regAtOffset.offset();
+        jit.storePtr(reg, CCallHelpers::Address(GPRInfo::callFrameRegister, offset));
+    }
</ins><span class="cx"> 
</span><del>-    // Move the arguments into place.
-    Value* result = wasmCallingConvention().setupCall(proc, block, origin, arguments, toB3Type(signature-&gt;returnType()), [&amp;] (PatchpointValue* patchpoint) {
-        CompilationContext* context = &amp;compilationContext;
</del><ins>+    {
+        CCallHelpers::Address calleeFrame = CCallHelpers::Address(MacroAssembler::stackPointerRegister, -static_cast&lt;ptrdiff_t&gt;(sizeof(CallerFrameAndPC)));
+        numGPRs = 0;
+        numFPRs = 0;
+        // We're going to set the pinned registers after this. So
+        // we can use this as a scratch for now since we saved it above.
+        GPRReg scratchReg = pinnedRegs.baseMemoryPointer;
</ins><span class="cx"> 
</span><del>-        // wasm -&gt; wasm calls clobber pinned registers unconditionally. This JS -&gt; wasm transition must therefore restore these pinned registers (which are usually callee-saved) to account for this.
-        const PinnedRegisterInfo* pinnedRegs = &amp;PinnedRegisterInfo::get();
-        RegisterSet clobbers;
-        clobbers.set(pinnedRegs-&gt;baseMemoryPointer);
-        for (auto info : pinnedRegs-&gt;sizeRegisters)
-            clobbers.set(info.sizeRegister);
-        patchpoint-&gt;effects.writesPinned = true;
-        patchpoint-&gt;clobber(clobbers);
</del><ins>+        ptrdiff_t jsOffset = CallFrameSlot::thisArgument * sizeof(void*);
+        ptrdiff_t wasmOffset = CallFrame::headerSizeInRegisters * sizeof(void*);
+        for (unsigned i = 0; i &lt; signature-&gt;argumentCount(); i++) {
+            switch (signature-&gt;argument(i)) {
+            case Wasm::I32:
+            case Wasm::I64:
+                if (numGPRs &gt;= wasmCallingConvention().m_gprArgs.size()) {
+                    if (signature-&gt;argument(i) == Wasm::I32) {
+                        jit.load32(CCallHelpers::Address(GPRInfo::callFrameRegister, jsOffset), scratchReg);
+                        jit.store32(scratchReg, calleeFrame.withOffset(wasmOffset));
+                    } else {
+                        jit.load64(CCallHelpers::Address(GPRInfo::callFrameRegister, jsOffset), scratchReg);
+                        jit.store64(scratchReg, calleeFrame.withOffset(wasmOffset));
+                    }
+                    wasmOffset += sizeof(void*);
+                } else {
+                    if (signature-&gt;argument(i) == Wasm::I32)
+                        jit.load32(CCallHelpers::Address(GPRInfo::callFrameRegister, jsOffset), wasmCallingConvention().m_gprArgs[numGPRs].gpr());
+                    else
+                        jit.load64(CCallHelpers::Address(GPRInfo::callFrameRegister, jsOffset), wasmCallingConvention().m_gprArgs[numGPRs].gpr());
+                }
+                ++numGPRs;
+                break;
+            case Wasm::F32:
+            case Wasm::F64:
+                if (numFPRs &gt;= wasmCallingConvention().m_fprArgs.size()) {
+                    if (signature-&gt;argument(i) == Wasm::F32) {
+                        jit.load32(CCallHelpers::Address(GPRInfo::callFrameRegister, jsOffset), scratchReg);
+                        jit.store32(scratchReg, calleeFrame.withOffset(wasmOffset));
+                    } else {
+                        jit.load64(CCallHelpers::Address(GPRInfo::callFrameRegister, jsOffset), scratchReg);
+                        jit.store64(scratchReg, calleeFrame.withOffset(wasmOffset));
+                    }
+                    wasmOffset += sizeof(void*);
+                } else {
+                    if (signature-&gt;argument(i) == Wasm::F32)
+                        jit.loadFloat(CCallHelpers::Address(GPRInfo::callFrameRegister, jsOffset), wasmCallingConvention().m_fprArgs[numFPRs].fpr());
+                    else
+                        jit.loadDouble(CCallHelpers::Address(GPRInfo::callFrameRegister, jsOffset), wasmCallingConvention().m_fprArgs[numFPRs].fpr());
+                }
+                ++numFPRs;
+                break;
+            default:
+                RELEASE_ASSERT_NOT_REACHED();
+            }
</ins><span class="cx"> 
</span><del>-        patchpoint-&gt;setGenerator([context] (CCallHelpers&amp; jit, const B3::StackmapGenerationParams&amp;) {
-            AllowMacroScratchRegisterUsage allowScratch(jit);
</del><ins>+            jsOffset += sizeof(void*);
+        }
+    }
</ins><span class="cx"> 
</span><del>-            CCallHelpers::Call call = jit.call();
-            context-&gt;jsEntrypointToWasmEntrypointCall = call;
-        });
-    });
</del><ins>+    if (!!info.memory) {
+        GPRReg baseMemory = pinnedRegs.baseMemoryPointer;
+        jit.loadPtr(&amp;vm.topJSWebAssemblyInstance, baseMemory);
+        jit.loadPtr(CCallHelpers::Address(baseMemory, JSWebAssemblyInstance::offsetOfMemory()), baseMemory);
+        const auto&amp; sizeRegs = pinnedRegs.sizeRegisters;
+        ASSERT(sizeRegs.size() &gt;= 1);
+        ASSERT(!sizeRegs[0].sizeOffset); // The following code assumes we start at 0, and calculates subsequent size registers relative to 0.
+        jit.loadPtr(CCallHelpers::Address(baseMemory, JSWebAssemblyMemory::offsetOfSize()), sizeRegs[0].sizeRegister);
+        jit.loadPtr(CCallHelpers::Address(baseMemory, JSWebAssemblyMemory::offsetOfMemory()), baseMemory);
+        for (unsigned i = 1; i &lt; sizeRegs.size(); ++i)
+            jit.add64(CCallHelpers::TrustedImm32(-sizeRegs[i].sizeOffset), sizeRegs[0].sizeRegister, sizeRegs[i].sizeRegister);
+    }
</ins><span class="cx"> 
</span><del>-    // Return the result, if needed.
</del><ins>+    compilationContext.jsEntrypointToWasmEntrypointCall = jit.call();
+
+    for (const RegisterAtOffset&amp; regAtOffset : registersToSpill) {
+        GPRReg reg = regAtOffset.reg().gpr();
+        ASSERT(reg != GPRInfo::returnValueGPR);
+        ptrdiff_t offset = regAtOffset.offset();
+        jit.loadPtr(CCallHelpers::Address(GPRInfo::callFrameRegister, offset), reg);
+    }
+
</ins><span class="cx">     switch (signature-&gt;returnType()) {
</span><del>-    case Wasm::Void:
-        block-&gt;appendNewControlValue(proc, B3::Return, origin);
</del><ins>+    case Wasm::F32:
+        jit.moveFloatTo32(FPRInfo::returnValueFPR, GPRInfo::returnValueGPR);
</ins><span class="cx">         break;
</span><del>-    case Wasm::F32:
</del><span class="cx">     case Wasm::F64:
</span><del>-        result = block-&gt;appendNew&lt;Value&gt;(proc, BitwiseCast, origin, result);
-        FALLTHROUGH;
-    case Wasm::I32:
-    case Wasm::I64:
-        block-&gt;appendNewControlValue(proc, B3::Return, origin, result);
</del><ins>+        jit.moveDoubleTo64(FPRInfo::returnValueFPR, GPRInfo::returnValueGPR);
</ins><span class="cx">         break;
</span><del>-    case Wasm::Func:
-    case Wasm::Anyfunc:
-        RELEASE_ASSERT_NOT_REACHED();
</del><ins>+    default:
+        break;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    B3::prepareForGeneration(proc);
-    B3::generate(proc, *compilationContext.jsEntrypointJIT);
-    compilationContext.jsEntrypointByproducts = proc.releaseByproducts();
-    function.jsToWasmEntrypoint.calleeSaveRegisters = proc.calleeSaveRegisters();
</del><ins>+    jit.emitFunctionEpilogue();
+    jit.ret();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> Expected&lt;std::unique_ptr&lt;WasmInternalFunction&gt;, String&gt; parseAndCompile(VM&amp; vm, CompilationContext&amp; compilationContext, const uint8_t* functionStart, size_t functionLength, const Signature* signature, Vector&lt;UnlinkedWasmToWasmCall&gt;&amp; unlinkedWasmToWasmCalls, const ModuleInformation&amp; info, const Vector&lt;SignatureIndex&gt;&amp; moduleSignatureIndicesToUniquedSignatureIndices, unsigned optLevel)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmCallingConventionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmCallingConvention.h (213744 => 213745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmCallingConvention.h        2017-03-11 01:56:08 UTC (rev 213744)
+++ trunk/Source/JavaScriptCore/wasm/WasmCallingConvention.h        2017-03-11 02:04:37 UTC (rev 213745)
</span><span class="lines">@@ -84,6 +84,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> public:
</span><ins>+    static unsigned headerSizeInBytes() { return headerSize; }
</ins><span class="cx">     void setupFrameInPrologue(CodeLocationDataLabelPtr* calleeMoveLocation, B3::Procedure&amp; proc, B3::Origin origin, B3::BasicBlock* block) const
</span><span class="cx">     {
</span><span class="cx">         static_assert(CallFrameSlot::callee * sizeof(Register) &lt; headerSize, &quot;We rely on this here for now.&quot;);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsJSWebAssemblyHelpersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyHelpers.h (213744 => 213745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyHelpers.h        2017-03-11 01:56:08 UTC (rev 213744)
+++ trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyHelpers.h        2017-03-11 02:04:37 UTC (rev 213745)
</span><span class="lines">@@ -29,6 +29,8 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;JSArrayBuffer.h&quot;
</span><span class="cx"> #include &quot;JSCJSValue.h&quot;
</span><ins>+#include &quot;WebAssemblyFunction.h&quot;
+#include &quot;WebAssemblyWrapperFunction.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="lines">@@ -71,6 +73,36 @@
</span><span class="cx">     return 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><span class="cx"> 
</span><ins>+ALWAYS_INLINE bool isWebAssemblyHostFunction(VM&amp; vm, JSObject* object, WebAssemblyFunction*&amp; wasmFunction, WebAssemblyWrapperFunction*&amp; wasmWrapperFunction)
+{
+    if (object-&gt;inherits(vm, WebAssemblyFunction::info())) {
+        wasmFunction = jsCast&lt;WebAssemblyFunction*&gt;(object);
+        wasmWrapperFunction = nullptr;
+        return true;
+    }
+    if (object-&gt;inherits(vm, WebAssemblyWrapperFunction::info())) {
+        wasmWrapperFunction = jsCast&lt;WebAssemblyWrapperFunction*&gt;(object);
+        wasmFunction = nullptr;
+        return true;
+    }
+    return false;
+}
+
+ALWAYS_INLINE bool isWebAssemblyHostFunction(VM&amp; vm, JSValue value, WebAssemblyFunction*&amp; wasmFunction, WebAssemblyWrapperFunction*&amp; wasmWrapperFunction)
+{
+    if (!value.isObject())
+        return false;
+    return isWebAssemblyHostFunction(vm, jsCast&lt;JSObject*&gt;(value), wasmFunction, wasmWrapperFunction);
+}
+
+
+ALWAYS_INLINE bool isWebAssemblyHostFunction(VM&amp; vm, JSObject* object)
+{
+    WebAssemblyFunction* unused;
+    WebAssemblyWrapperFunction* unused2;
+    return isWebAssemblyHostFunction(vm, object, unused, unused2);
+}
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(WEBASSEMBLY)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsJSWebAssemblyInstancecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp (213744 => 213745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp        2017-03-11 01:56:08 UTC (rev 213744)
+++ trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp        2017-03-11 02:04:37 UTC (rev 213745)
</span><span class="lines">@@ -67,7 +67,7 @@
</span><span class="cx">     : Base(vm, structure)
</span><span class="cx">     , m_numImportFunctions(numImportFunctions)
</span><span class="cx"> {
</span><del>-    memset(importFunctions(), 0, m_numImportFunctions * sizeof(WriteBarrier&lt;JSCell&gt;));
</del><ins>+    memset(importFunctions(), 0, m_numImportFunctions * sizeof(WriteBarrier&lt;JSObject&gt;));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void JSWebAssemblyInstance::finishCreation(VM&amp; vm, JSWebAssemblyModule* module, JSModuleNamespaceObject* moduleNamespaceObject)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsJSWebAssemblyInstanceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h (213744 => 213745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h        2017-03-11 01:56:08 UTC (rev 213744)
+++ trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h        2017-03-11 02:04:37 UTC (rev 213745)
</span><span class="lines">@@ -60,18 +60,18 @@
</span><span class="cx">         return m_codeBlock.get();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    WriteBarrier&lt;JSCell&gt;* importFunction(unsigned idx)
</del><ins>+    WriteBarrier&lt;JSObject&gt;* importFunction(unsigned idx)
</ins><span class="cx">     {
</span><span class="cx">         RELEASE_ASSERT(idx &lt; m_numImportFunctions);
</span><span class="cx">         return &amp;importFunctions()[idx];
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    WriteBarrier&lt;JSCell&gt;* importFunctions()
</del><ins>+    WriteBarrier&lt;JSObject&gt;* importFunctions()
</ins><span class="cx">     {
</span><del>-        return bitwise_cast&lt;WriteBarrier&lt;JSCell&gt;*&gt;(bitwise_cast&lt;char*&gt;(this) + offsetOfImportFunctions());
</del><ins>+        return bitwise_cast&lt;WriteBarrier&lt;JSObject&gt;*&gt;(bitwise_cast&lt;char*&gt;(this) + offsetOfImportFunctions());
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void setImportFunction(VM&amp; vm, JSCell* value, unsigned idx)
</del><ins>+    void setImportFunction(VM&amp; vm, JSObject* value, unsigned idx)
</ins><span class="cx">     {
</span><span class="cx">         importFunction(idx)-&gt;set(vm, this, value);
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsJSWebAssemblyTablecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.cpp (213744 => 213745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.cpp        2017-03-11 01:56:08 UTC (rev 213744)
+++ trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.cpp        2017-03-11 02:04:37 UTC (rev 213745)
</span><span class="lines">@@ -64,11 +64,11 @@
</span><span class="cx">     // FIXME: It might be worth trying to pre-allocate maximum here. The spec recommends doing so.
</span><span class="cx">     // But for now, we're not doing that.
</span><span class="cx">     m_functions = MallocPtr&lt;Wasm::CallableFunction&gt;::malloc(sizeof(Wasm::CallableFunction) * static_cast&lt;size_t&gt;(m_size));
</span><del>-    m_jsFunctions = MallocPtr&lt;WriteBarrier&lt;WebAssemblyFunction&gt;&gt;::malloc(sizeof(WriteBarrier&lt;WebAssemblyFunction&gt;) * static_cast&lt;size_t&gt;(m_size));
</del><ins>+    m_jsFunctions = MallocPtr&lt;WriteBarrier&lt;JSObject&gt;&gt;::malloc(sizeof(WriteBarrier&lt;JSObject&gt;) * static_cast&lt;size_t&gt;(m_size));
</ins><span class="cx">     for (uint32_t i = 0; i &lt; m_size; ++i) {
</span><span class="cx">         new (&amp;m_functions.get()[i]) Wasm::CallableFunction();
</span><span class="cx">         ASSERT(m_functions.get()[i].signatureIndex == Wasm::Signature::invalidIndex); // We rely on this in compiled code.
</span><del>-        new (&amp;m_jsFunctions.get()[i]) WriteBarrier&lt;WebAssemblyFunction&gt;();
</del><ins>+        new (&amp;m_jsFunctions.get()[i]) WriteBarrier&lt;JSObject&gt;();
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -106,11 +106,11 @@
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     m_functions.realloc(sizeof(Wasm::CallableFunction) * static_cast&lt;size_t&gt;(newSize));
</span><del>-    m_jsFunctions.realloc(sizeof(WriteBarrier&lt;WebAssemblyFunction&gt;) * static_cast&lt;size_t&gt;(newSize));
</del><ins>+    m_jsFunctions.realloc(sizeof(WriteBarrier&lt;JSObject&gt;) * static_cast&lt;size_t&gt;(newSize));
</ins><span class="cx"> 
</span><span class="cx">     for (uint32_t i = m_size; i &lt; newSize; ++i) {
</span><span class="cx">         new (&amp;m_functions.get()[i]) Wasm::CallableFunction();
</span><del>-        new (&amp;m_jsFunctions.get()[i]) WriteBarrier&lt;WebAssemblyFunction&gt;();
</del><ins>+        new (&amp;m_jsFunctions.get()[i]) WriteBarrier&lt;JSObject&gt;();
</ins><span class="cx">     }
</span><span class="cx">     m_size = newSize;
</span><span class="cx">     return true;
</span><span class="lines">@@ -119,7 +119,7 @@
</span><span class="cx"> void JSWebAssemblyTable::clearFunction(uint32_t index)
</span><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT(index &lt; m_size);
</span><del>-    m_jsFunctions.get()[index] = WriteBarrier&lt;WebAssemblyFunction&gt;();
</del><ins>+    m_jsFunctions.get()[index] = WriteBarrier&lt;JSObject&gt;();
</ins><span class="cx">     m_functions.get()[index] = Wasm::CallableFunction();
</span><span class="cx">     ASSERT(m_functions.get()[index].signatureIndex == Wasm::Signature::invalidIndex); // We rely on this in compiled code.
</span><span class="cx"> }
</span><span class="lines">@@ -131,6 +131,13 @@
</span><span class="cx">     m_functions.get()[index] = Wasm::CallableFunction(function-&gt;signatureIndex(), function-&gt;wasmEntrypoint());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void JSWebAssemblyTable::setFunction(VM&amp; vm, uint32_t index, WebAssemblyWrapperFunction* function)
+{
+    RELEASE_ASSERT(index &lt; m_size);
+    m_jsFunctions.get()[index].set(vm, this, function);
+    m_functions.get()[index] = Wasm::CallableFunction(function-&gt;signatureIndex(), function-&gt;wasmEntrypoint());
+}
+
</ins><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(WEBASSEMBLY)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsJSWebAssemblyTableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.h (213744 => 213745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.h        2017-03-11 01:56:08 UTC (rev 213744)
+++ trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.h        2017-03-11 02:04:37 UTC (rev 213745)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;JSDestructibleObject.h&quot;
</span><span class="cx"> #include &quot;JSObject.h&quot;
</span><ins>+#include &quot;WebAssemblyWrapperFunction.h&quot;
</ins><span class="cx"> #include &quot;WebAssemblyFunction.h&quot;
</span><span class="cx"> #include &lt;wtf/MallocPtr.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -50,7 +51,7 @@
</span><span class="cx">     std::optional&lt;uint32_t&gt; maximum() const { return m_maximum; }
</span><span class="cx">     uint32_t size() const { return m_size; }
</span><span class="cx">     bool grow(uint32_t newSize) WARN_UNUSED_RETURN;
</span><del>-    WebAssemblyFunction* getFunction(uint32_t index)
</del><ins>+    JSObject* getFunction(uint32_t index)
</ins><span class="cx">     {
</span><span class="cx">         RELEASE_ASSERT(index &lt; m_size);
</span><span class="cx">         return m_jsFunctions.get()[index].get();
</span><span class="lines">@@ -57,6 +58,7 @@
</span><span class="cx">     }
</span><span class="cx">     void clearFunction(uint32_t index);
</span><span class="cx">     void setFunction(VM&amp;, uint32_t index, WebAssemblyFunction*);
</span><ins>+    void setFunction(VM&amp;, uint32_t index, WebAssemblyWrapperFunction*);
</ins><span class="cx"> 
</span><span class="cx">     static ptrdiff_t offsetOfSize() { return OBJECT_OFFSETOF(JSWebAssemblyTable, m_size); }
</span><span class="cx">     static ptrdiff_t offsetOfFunctions() { return OBJECT_OFFSETOF(JSWebAssemblyTable, m_functions); }
</span><span class="lines">@@ -74,7 +76,7 @@
</span><span class="cx">     static void visitChildren(JSCell*, SlotVisitor&amp;);
</span><span class="cx"> 
</span><span class="cx">     MallocPtr&lt;Wasm::CallableFunction&gt; m_functions;
</span><del>-    MallocPtr&lt;WriteBarrier&lt;WebAssemblyFunction&gt;&gt; m_jsFunctions;
</del><ins>+    MallocPtr&lt;WriteBarrier&lt;JSObject&gt;&gt; m_jsFunctions;
</ins><span class="cx">     std::optional&lt;uint32_t&gt; m_maximum;
</span><span class="cx">     uint32_t m_size;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsWebAssemblyInstanceConstructorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/WebAssemblyInstanceConstructor.cpp (213744 => 213745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/WebAssemblyInstanceConstructor.cpp        2017-03-11 01:56:08 UTC (rev 213744)
+++ trunk/Source/JavaScriptCore/wasm/js/WebAssemblyInstanceConstructor.cpp        2017-03-11 02:04:37 UTC (rev 213745)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="cx"> #include &quot;JSModuleEnvironment.h&quot;
</span><span class="cx"> #include &quot;JSModuleNamespaceObject.h&quot;
</span><ins>+#include &quot;JSWebAssemblyHelpers.h&quot;
</ins><span class="cx"> #include &quot;JSWebAssemblyInstance.h&quot;
</span><span class="cx"> #include &quot;JSWebAssemblyLinkError.h&quot;
</span><span class="cx"> #include &quot;JSWebAssemblyMemory.h&quot;
</span><span class="lines">@@ -129,15 +130,23 @@
</span><span class="cx">             if (!value.isFunction())
</span><span class="cx">                 return exception(createJSWebAssemblyLinkError(exec, vm, ASCIILiteral(&quot;import function must be callable&quot;)));
</span><span class="cx"> 
</span><del>-            JSCell* cell = value.asCell();
</del><ins>+            JSObject* function = jsCast&lt;JSObject*&gt;(value);
</ins><span class="cx">             // ii. If v is an Exported Function Exotic Object:
</span><del>-            if (WebAssemblyFunction* importedExport = jsDynamicCast&lt;WebAssemblyFunction*&gt;(vm, cell)) {
</del><ins>+            WebAssemblyFunction* wasmFunction;
+            WebAssemblyWrapperFunction* wasmWrapperFunction;
+            if (isWebAssemblyHostFunction(vm, function, wasmFunction, wasmWrapperFunction)) {
</ins><span class="cx">                 // a. If the signature of v does not match the signature of i, throw a WebAssembly.LinkError.
</span><del>-                Wasm::SignatureIndex importedSignatureIndex = importedExport-&gt;signatureIndex();
</del><ins>+                Wasm::SignatureIndex importedSignatureIndex;
+                if (wasmFunction)
+                    importedSignatureIndex = wasmFunction-&gt;signatureIndex();
+                else {
+                    importedSignatureIndex = wasmWrapperFunction-&gt;signatureIndex();
+                    // b. Let closure be v.[[Closure]].
+                    function = wasmWrapperFunction-&gt;function();
+                }
</ins><span class="cx">                 Wasm::SignatureIndex expectedSignatureIndex = moduleInformation.importFunctionSignatureIndices[import.kindIndex];
</span><span class="cx">                 if (importedSignatureIndex != expectedSignatureIndex)
</span><span class="cx">                     return exception(createJSWebAssemblyLinkError(exec, vm, ASCIILiteral(&quot;imported function's signature doesn't match the provided WebAssembly function's signature&quot;)));
</span><del>-                // b. Let closure be v.[[Closure]].
</del><span class="cx">             }
</span><span class="cx">             // iii. Otherwise:
</span><span class="cx">             // a. Let closure be a new host function of the given signature which calls v by coercing WebAssembly arguments to JavaScript arguments via ToJSValue and returns the result, if any, by coercing via ToWebAssemblyValue.
</span><span class="lines">@@ -146,7 +155,7 @@
</span><span class="cx">             // Note: adding the JSCell to the instance list fulfills closure requirements b. above (the WebAssembly.Instance wil be kept alive) and v. below (the JSFunction).
</span><span class="cx"> 
</span><span class="cx">             ASSERT(numImportFunctions == import.kindIndex);
</span><del>-            instance-&gt;setImportFunction(vm, cell, numImportFunctions++);
</del><ins>+            instance-&gt;setImportFunction(vm, function, numImportFunctions++);
</ins><span class="cx">             // v. Append closure to imports.
</span><span class="cx">             break;
</span><span class="cx">         }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsWebAssemblyModuleRecordcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp (213744 => 213745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp        2017-03-11 01:56:08 UTC (rev 213744)
+++ trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp        2017-03-11 02:04:37 UTC (rev 213745)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> #include &quot;JSCInlines.h&quot;
</span><span class="cx"> #include &quot;JSLexicalEnvironment.h&quot;
</span><span class="cx"> #include &quot;JSModuleEnvironment.h&quot;
</span><ins>+#include &quot;JSWebAssemblyHelpers.h&quot;
</ins><span class="cx"> #include &quot;JSWebAssemblyInstance.h&quot;
</span><span class="cx"> #include &quot;JSWebAssemblyLinkError.h&quot;
</span><span class="cx"> #include &quot;JSWebAssemblyModule.h&quot;
</span><span class="lines">@@ -110,19 +111,26 @@
</span><span class="cx">             //   i. If there is an Exported Function Exotic Object func in funcs whose func.[[Closure]] equals c, then return func.
</span><span class="cx">             //   ii. (Note: At most one wrapper is created for any closure, so func is unique, even if there are multiple occurrances in the list. Moreover, if the item was an import that is already an Exported Function Exotic Object, then the original function object will be found. For imports that are regular JS functions, a new wrapper will be created.)
</span><span class="cx">             if (exp.kindIndex &lt; functionImportCount) {
</span><del>-                // FIXME Implement re-exporting an import. https://bugs.webkit.org/show_bug.cgi?id=165510
-                RELEASE_ASSERT_NOT_REACHED();
</del><ins>+                unsigned functionIndex = exp.kindIndex;
+                JSObject* functionImport = instance-&gt;importFunction(functionIndex)-&gt;get();
+                if (isWebAssemblyHostFunction(vm, functionImport))
+                    exportedValue = functionImport;
+                else {
+                    Wasm::SignatureIndex signatureIndex = module-&gt;signatureIndexFromFunctionIndexSpace(functionIndex);
+                    exportedValue = WebAssemblyWrapperFunction::create(vm, globalObject, functionImport, functionIndex, codeBlock, signatureIndex);
+                }
+            } else {
+                //   iii. Otherwise:
+                //     a. Let func be an Exported Function Exotic Object created from c.
+                //     b. Append func to funcs.
+                //     c. Return func.
+                JSWebAssemblyCallee* jsEntrypointCallee = codeBlock-&gt;jsEntrypointCalleeFromFunctionIndexSpace(exp.kindIndex);
+                JSWebAssemblyCallee* wasmEntrypointCallee = codeBlock-&gt;wasmEntrypointCalleeFromFunctionIndexSpace(exp.kindIndex);
+                Wasm::SignatureIndex signatureIndex = module-&gt;signatureIndexFromFunctionIndexSpace(exp.kindIndex);
+                const Wasm::Signature* signature = Wasm::SignatureInformation::get(&amp;vm, signatureIndex);
+                WebAssemblyFunction* function = WebAssemblyFunction::create(vm, globalObject, signature-&gt;argumentCount(), exp.field.string(), instance, jsEntrypointCallee, wasmEntrypointCallee, signatureIndex);
+                exportedValue = function;
</ins><span class="cx">             }
</span><del>-            //   iii. Otherwise:
-            //     a. Let func be an Exported Function Exotic Object created from c.
-            //     b. Append func to funcs.
-            //     c. Return func.
-            JSWebAssemblyCallee* jsEntrypointCallee = codeBlock-&gt;jsEntrypointCalleeFromFunctionIndexSpace(exp.kindIndex);
-            JSWebAssemblyCallee* wasmEntrypointCallee = codeBlock-&gt;wasmEntrypointCalleeFromFunctionIndexSpace(exp.kindIndex);
-            Wasm::SignatureIndex signatureIndex = module-&gt;signatureIndexFromFunctionIndexSpace(exp.kindIndex);
-            const Wasm::Signature* signature = Wasm::SignatureInformation::get(&amp;vm, signatureIndex);
-            WebAssemblyFunction* function = WebAssemblyFunction::create(vm, globalObject, signature-&gt;argumentCount(), exp.field.string(), instance, jsEntrypointCallee, wasmEntrypointCallee, signatureIndex);
-            exportedValue = function;
</del><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         case Wasm::ExternalKind::Table: {
</span><span class="lines">@@ -184,7 +192,7 @@
</span><span class="cx">         ASSERT(!signature-&gt;argumentCount());
</span><span class="cx">         ASSERT(signature-&gt;returnType() == Wasm::Void);
</span><span class="cx">         if (startFunctionIndexSpace &lt; codeBlock-&gt;functionImportCount()) {
</span><del>-            JSCell* startFunction = instance-&gt;importFunction(startFunctionIndexSpace)-&gt;get();
</del><ins>+            JSObject* startFunction = instance-&gt;importFunction(startFunctionIndexSpace)-&gt;get();
</ins><span class="cx">             m_startFunction.set(vm, this, startFunction);
</span><span class="cx">         } else {
</span><span class="cx">             JSWebAssemblyCallee* jsEntrypointCallee = codeBlock-&gt;jsEntrypointCalleeFromFunctionIndexSpace(startFunctionIndexSpace);
</span><span class="lines">@@ -241,14 +249,28 @@
</span><span class="cx">                 // for the import.
</span><span class="cx">                 // https://bugs.webkit.org/show_bug.cgi?id=165510
</span><span class="cx">                 uint32_t functionIndex = element.functionIndices[i];
</span><ins>+                Wasm::SignatureIndex signatureIndex = module-&gt;signatureIndexFromFunctionIndexSpace(functionIndex);
</ins><span class="cx">                 if (functionIndex &lt; codeBlock-&gt;functionImportCount()) {
</span><del>-                    return JSValue::decode(
-                        throwVMRangeError(state, scope, ASCIILiteral(&quot;Element is setting the table value with an import. This is not yet implemented. FIXME.&quot;)));
</del><ins>+                    JSObject* functionImport = jsCast&lt;JSObject*&gt;(m_instance-&gt;importFunction(functionIndex)-&gt;get());
+                    if (isWebAssemblyHostFunction(vm, functionImport)) {
+                        WebAssemblyFunction* wasmFunction = jsDynamicCast&lt;WebAssemblyFunction*&gt;(vm, functionImport);
+                        // If we ever import a WebAssemblyWrapperFunction, we set the import as the unwrapped value.
+                        // Because a WebAssemblyWrapperFunction can never wrap another WebAssemblyWrapperFunction,
+                        // the only type this could be is WebAssemblyFunction.
+                        RELEASE_ASSERT(wasmFunction);
+                        table-&gt;setFunction(vm, tableIndex, wasmFunction);
+                        ++tableIndex;
+                        continue;
+                    }
+
+                    table-&gt;setFunction(vm, tableIndex,
+                        WebAssemblyWrapperFunction::create(vm, m_instance-&gt;globalObject(), functionImport, functionIndex, codeBlock, signatureIndex));
+                    ++tableIndex;
+                    continue;
</ins><span class="cx">                 }
</span><span class="cx"> 
</span><span class="cx">                 JSWebAssemblyCallee* jsEntrypointCallee = codeBlock-&gt;jsEntrypointCalleeFromFunctionIndexSpace(functionIndex);
</span><span class="cx">                 JSWebAssemblyCallee* wasmEntrypointCallee = codeBlock-&gt;wasmEntrypointCalleeFromFunctionIndexSpace(functionIndex);
</span><del>-                Wasm::SignatureIndex signatureIndex = module-&gt;signatureIndexFromFunctionIndexSpace(functionIndex);
</del><span class="cx">                 const Wasm::Signature* signature = Wasm::SignatureInformation::get(&amp;vm, signatureIndex);
</span><span class="cx">                 // FIXME: Say we export local function &quot;foo&quot; at function index 0.
</span><span class="cx">                 // What if we also set it to the table an Element w/ index 0.
</span><span class="lines">@@ -288,7 +310,7 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (JSCell* startFunction = m_startFunction.get()) {
</del><ins>+    if (JSObject* startFunction = m_startFunction.get()) {
</ins><span class="cx">         CallData callData;
</span><span class="cx">         CallType callType = JSC::getCallData(startFunction, callData);
</span><span class="cx">         call(state, startFunction, callType, callData, jsUndefined(), state-&gt;emptyList());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsWebAssemblyModuleRecordh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.h (213744 => 213745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.h        2017-03-11 01:56:08 UTC (rev 213744)
+++ trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.h        2017-03-11 02:04:37 UTC (rev 213745)
</span><span class="lines">@@ -59,7 +59,7 @@
</span><span class="cx">     static void visitChildren(JSCell*, SlotVisitor&amp;);
</span><span class="cx"> 
</span><span class="cx">     WriteBarrier&lt;JSWebAssemblyInstance&gt; m_instance;
</span><del>-    WriteBarrier&lt;JSCell&gt; m_startFunction;
</del><ins>+    WriteBarrier&lt;JSObject&gt; m_startFunction;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsWebAssemblyTablePrototypecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/WebAssemblyTablePrototype.cpp (213744 => 213745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/WebAssemblyTablePrototype.cpp        2017-03-11 01:56:08 UTC (rev 213744)
+++ trunk/Source/JavaScriptCore/wasm/js/WebAssemblyTablePrototype.cpp        2017-03-11 02:04:37 UTC (rev 213745)
</span><span class="lines">@@ -106,7 +106,7 @@
</span><span class="cx">         return { };
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (WebAssemblyFunction* result = table-&gt;getFunction(index))
</del><ins>+    if (JSObject* result = table-&gt;getFunction(index))
</ins><span class="cx">         return JSValue::encode(result);
</span><span class="cx">     return JSValue::encode(jsNull());
</span><span class="cx"> }
</span><span class="lines">@@ -120,8 +120,9 @@
</span><span class="cx">     RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
</span><span class="cx"> 
</span><span class="cx">     JSValue value = exec-&gt;argument(1);
</span><del>-    WebAssemblyFunction* function = jsDynamicCast&lt;WebAssemblyFunction*&gt;(vm, value);
-    if (!value.isNull() &amp;&amp; !function) {
</del><ins>+    WebAssemblyFunction* wasmFunction;
+    WebAssemblyWrapperFunction* wasmWrapperFunction;
+    if (!value.isNull() &amp;&amp; !isWebAssemblyHostFunction(vm, value, wasmFunction, wasmWrapperFunction)) {
</ins><span class="cx">         throwException(exec, throwScope,
</span><span class="cx">             createTypeError(exec, ASCIILiteral(&quot;WebAssembly.Table.prototype.set expects the second argument to be null or an instance of WebAssembly.Function&quot;)));
</span><span class="cx">         return { };
</span><span class="lines">@@ -139,8 +140,12 @@
</span><span class="cx">     if (value.isNull())
</span><span class="cx">         table-&gt;clearFunction(index);
</span><span class="cx">     else {
</span><del>-        ASSERT(!!function);
-        table-&gt;setFunction(vm, index, function);
</del><ins>+        ASSERT(value.isObject() &amp;&amp; isWebAssemblyHostFunction(vm, jsCast&lt;JSObject*&gt;(value), wasmFunction, wasmWrapperFunction));
+        ASSERT(!!wasmFunction || !!wasmWrapperFunction);
+        if (wasmFunction)
+            table-&gt;setFunction(vm, index, wasmFunction);
+        else
+            table-&gt;setFunction(vm, index, wasmWrapperFunction);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     return JSValue::encode(jsUndefined());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsWebAssemblyWrapperFunctioncpp"></a>
<div class="addfile"><h4>Added: trunk/Source/JavaScriptCore/wasm/js/WebAssemblyWrapperFunction.cpp (0 => 213745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/WebAssemblyWrapperFunction.cpp                                (rev 0)
+++ trunk/Source/JavaScriptCore/wasm/js/WebAssemblyWrapperFunction.cpp        2017-03-11 02:04:37 UTC (rev 213745)
</span><span class="lines">@@ -0,0 +1,98 @@
</span><ins>+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;WebAssemblyWrapperFunction.h&quot;
+
+#if ENABLE(WEBASSEMBLY)
+
+#include &quot;Error.h&quot;
+#include &quot;FunctionPrototype.h&quot;
+#include &quot;JSCInlines.h&quot;
+
+namespace JSC {
+
+const ClassInfo WebAssemblyWrapperFunction::s_info = { &quot;WebAssemblyWrapperFunction&quot;, &amp;Base::s_info, nullptr, CREATE_METHOD_TABLE(WebAssemblyWrapperFunction) };
+
+static EncodedJSValue JSC_HOST_CALL callWebAssemblyWrapperFunction(ExecState* exec)
+{
+    VM&amp; vm = exec-&gt;vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+    WebAssemblyWrapperFunction* wasmFunction = jsDynamicCast&lt;WebAssemblyWrapperFunction*&gt;(vm, exec-&gt;jsCallee());
+    if (!wasmFunction)
+        return JSValue::encode(throwException(exec, scope, createTypeError(exec, &quot;expected a WebAssembly function&quot;)));
+
+    CallData callData;
+    JSObject* function = wasmFunction-&gt;function();
+    CallType callType = function-&gt;methodTable(vm)-&gt;getCallData(function, callData);
+    RELEASE_ASSERT(callType != CallType::None);
+    scope.release();
+    return JSValue::encode(call(exec, function, callType, callData, jsUndefined(), ArgList(exec)));
+}
+
+WebAssemblyWrapperFunction::WebAssemblyWrapperFunction(VM&amp; vm, JSGlobalObject* globalObject, Structure* structure, Wasm::SignatureIndex signatureIndex, void* wasmEntrypointCode)
+    : Base(vm, globalObject, structure)
+    , m_wasmEntrypointCode(wasmEntrypointCode)
+    , m_signatureIndex(signatureIndex)
+{ }
+
+WebAssemblyWrapperFunction* WebAssemblyWrapperFunction::create(VM&amp; vm, JSGlobalObject* globalObject, JSObject* function, unsigned importIndex, JSWebAssemblyCodeBlock* codeBlock, Wasm::SignatureIndex signatureIndex)
+{
+    ASSERT_WITH_MESSAGE(!function-&gt;inherits(vm, WebAssemblyWrapperFunction::info()), &quot;We should never double wrap a wrapper function.&quot;);
+    String name = &quot;&quot;;
+    NativeExecutable* executable = vm.getHostFunction(callWebAssemblyWrapperFunction, NoIntrinsic, callHostFunctionAsConstructor, nullptr, name);
+    WebAssemblyWrapperFunction* result = new (NotNull, allocateCell&lt;WebAssemblyWrapperFunction&gt;(vm.heap)) WebAssemblyWrapperFunction(vm, globalObject, globalObject-&gt;webAssemblyWrapperFunctionStructure(), signatureIndex, codeBlock-&gt;wasmToJsCallStubForImport(importIndex));
+    const Wasm::Signature* signature = Wasm::SignatureInformation::get(&amp;vm, signatureIndex);
+    result-&gt;finishCreation(vm, executable, signature-&gt;argumentCount(), name, function, codeBlock);
+    return result;
+}
+
+void WebAssemblyWrapperFunction::finishCreation(VM&amp; vm, NativeExecutable* executable, unsigned length, const String&amp; name, JSObject* function, JSWebAssemblyCodeBlock* codeBlock)
+{
+    Base::finishCreation(vm, executable, length, name);
+    RELEASE_ASSERT(JSValue(function).isFunction());
+    m_function.set(vm, this, function);
+    m_codeBlock.set(vm, this, codeBlock);
+}
+
+Structure* WebAssemblyWrapperFunction::createStructure(VM&amp; vm, JSGlobalObject* globalObject, JSValue prototype)
+{
+    ASSERT(globalObject);
+    return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
+}
+
+void WebAssemblyWrapperFunction::visitChildren(JSCell* cell, SlotVisitor&amp; visitor)
+{
+    WebAssemblyWrapperFunction* thisObject = jsCast&lt;WebAssemblyWrapperFunction*&gt;(cell);
+    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
+    Base::visitChildren(thisObject, visitor);
+
+    visitor.append(thisObject-&gt;m_codeBlock);
+    visitor.append(thisObject-&gt;m_function);
+}
+
+} // namespace JSC
+
+#endif // ENABLE(WEBASSEMBLY)
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsWebAssemblyWrapperFunctionhfromrev213744trunkSourceJavaScriptCorewasmjsWebAssemblyModuleRecordh"></a>
<div class="copfile"><h4>Copied: trunk/Source/JavaScriptCore/wasm/js/WebAssemblyWrapperFunction.h (from rev 213744, trunk/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.h) (0 => 213745)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/WebAssemblyWrapperFunction.h                                (rev 0)
+++ trunk/Source/JavaScriptCore/wasm/js/WebAssemblyWrapperFunction.h        2017-03-11 02:04:37 UTC (rev 213745)
</span><span class="lines">@@ -0,0 +1,68 @@
</span><ins>+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#if ENABLE(WEBASSEMBLY)
+
+#include &quot;JSFunction.h&quot;
+#include &quot;JSWebAssemblyCodeBlock.h&quot;
+
+namespace JSC {
+
+class WebAssemblyWrapperFunction : public JSFunction {
+public:
+    typedef JSFunction Base;
+
+    const static unsigned StructureFlags = Base::StructureFlags;
+
+    DECLARE_INFO;
+
+    static WebAssemblyWrapperFunction* create(VM&amp;, JSGlobalObject*, JSObject*, unsigned importIndex, JSWebAssemblyCodeBlock*, Wasm::SignatureIndex);
+    static Structure* createStructure(VM&amp;, JSGlobalObject*, JSValue);
+
+    Wasm::SignatureIndex signatureIndex() const { return m_signatureIndex; }
+    void* wasmEntrypoint() { return m_wasmEntrypointCode; }
+    JSObject* function() { return m_function.get(); }
+
+protected:
+    static void visitChildren(JSCell*, SlotVisitor&amp;);
+
+    void finishCreation(VM&amp;, NativeExecutable*, unsigned length, const String&amp; name, JSObject*, JSWebAssemblyCodeBlock*);
+
+private:
+    WebAssemblyWrapperFunction(VM&amp;, JSGlobalObject*, Structure*, Wasm::SignatureIndex, void* wasmEntrypointCode);
+
+    // We keep a reference to our CodeBlock because we have a raw
+    // pointer to asm code that it owns.
+    WriteBarrier&lt;JSWebAssemblyCodeBlock&gt; m_codeBlock;
+    WriteBarrier&lt;JSObject&gt; m_function;
+    void* m_wasmEntrypointCode;
+    Wasm::SignatureIndex m_signatureIndex;
+};
+
+} // namespace JSC
+
+#endif // ENABLE(WEBASSEMBLY)
</ins></span></pre>
</div>
</div>

</body>
</html>