<!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>[210421] branches/safari-603-branch</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/210421">210421</a></dd>
<dt>Author</dt> <dd>matthew_hanson@apple.com</dd>
<dt>Date</dt> <dd>2017-01-05 17:49:36 -0800 (Thu, 05 Jan 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/210229">r210229</a>. rdar://problem/29760322</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchessafari603branchJSTestsChangeLog">branches/safari-603-branch/JSTests/ChangeLog</a></li>
<li><a href="#branchessafari603branchJSTestswasmBuilderjs">branches/safari-603-branch/JSTests/wasm/Builder.js</a></li>
<li><a href="#branchessafari603branchJSTestswasmLowLevelBinaryjs">branches/safari-603-branch/JSTests/wasm/LowLevelBinary.js</a></li>
<li><a href="#branchessafari603branchJSTestswasmfunctiontestsexceptionsjs">branches/safari-603-branch/JSTests/wasm/function-tests/exceptions.js</a></li>
<li><a href="#branchessafari603branchJSTestswasmfunctionteststraploadjs">branches/safari-603-branch/JSTests/wasm/function-tests/trap-load.js</a></li>
<li><a href="#branchessafari603branchJSTestswasmfunctionteststrapstorejs">branches/safari-603-branch/JSTests/wasm/function-tests/trap-store.js</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreCMakeListstxt">branches/safari-603-branch/Source/JavaScriptCore/CMakeLists.txt</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreChangeLog">branches/safari-603-branch/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">branches/safari-603-branch/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorejsccpp">branches/safari-603-branch/Source/JavaScriptCore/jsc.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCoreruntimeJSTypeh">branches/safari-603-branch/Source/JavaScriptCore/runtime/JSType.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmWasmB3IRGeneratorcpp">branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmWasmB3IRGeneratorh">branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmB3IRGenerator.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmWasmBindingcpp">branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmBinding.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmWasmBindingh">branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmBinding.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmWasmFormath">branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmFormat.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmWasmFunctionParserh">branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmFunctionParser.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmWasmMemorycpp">branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmMemory.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmWasmMemoryh">branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmMemory.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmWasmMemoryInformationcpp">branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmMemoryInformation.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmWasmMemoryInformationh">branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmMemoryInformation.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmWasmModuleParsercpp">branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmModuleParser.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmWasmModuleParserh">branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmModuleParser.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmWasmPageCounth">branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmPageCount.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmWasmPlancpp">branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmPlan.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmWasmPlanh">branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmPlan.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmWasmSignaturecpp">branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmSignature.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmWasmSignatureh">branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmSignature.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmWasmValidatecpp">branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmValidate.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmWasmValidateh">branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmValidate.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmjsJSWebAssemblyInstanceh">branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmjsJSWebAssemblyMemorycpp">branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmjsJSWebAssemblyMemoryh">branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmjsJSWebAssemblyModulecpp">branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmjsJSWebAssemblyModuleh">branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmjsWebAssemblyFunctioncpp">branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmjsWebAssemblyFunctionh">branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmjsWebAssemblyInstanceConstructorcpp">branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyInstanceConstructor.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmjsWebAssemblyMemoryConstructorcpp">branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyMemoryConstructor.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmjsWebAssemblyModuleConstructorcpp">branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyModuleConstructor.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmjsWebAssemblyModuleRecordcpp">branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#branchessafari603branchJSTestswasmjsapiwasmtowasmbadsignaturejs">branches/safari-603-branch/JSTests/wasm/js-api/wasm-to-wasm-bad-signature.js</a></li>
<li><a href="#branchessafari603branchJSTestswasmjsapiwasmtowasmjs">branches/safari-603-branch/JSTests/wasm/js-api/wasm-to-wasm.js</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmWasmPageCountcpp">branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmPageCount.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchessafari603branchJSTestsChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/JSTests/ChangeLog (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/JSTests/ChangeLog        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/JSTests/ChangeLog        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -1,5 +1,44 @@
</span><span class="cx"> 2017-01-05  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Merge r210229. rdar://problem/29760322
+
+    2017-01-02  JF Bastien  &lt;jfbastien@apple.com&gt;
+
+            WebAssembly: handle and optimize wasm export → wasm import calls
+            https://bugs.webkit.org/show_bug.cgi?id=165282
+
+            Reviewed by Saam Barati.
+
+            * wasm/Builder.js: Add a Proxy to Builder.js, which intercepts
+            unknown property lookups. This creates way better error messages
+            on typos than 'undefined is not a function', which happens
+            semi-frequently as I typo opcode names (and which one is a typo is
+            hard to find because we chain builders).
+            (const._isValidValue):
+            (get target):
+            (const._importFunctionContinuation):
+            (const._importMemoryContinuation):
+            (const._importTableContinuation):
+            (const._exportFunctionContinuation):
+            (export.default.Builder.prototype._registerSectionBuilders.const.section.in.WASM.description.section.switch.section.case.string_appeared_here.this.section):
+            (export.default.Builder.prototype._registerSectionBuilders.this.Unknown):
+            * wasm/LowLevelBinary.js: Add limited support for var{u}int64 (only the 32-bit values)
+            (export.default.LowLevelBinary.prototype.varint32):
+            (export.default.LowLevelBinary.prototype.varuint64):
+            (export.default.LowLevelBinary.prototype.varint64):
+            * wasm/function-tests/exceptions.js: update error message
+            * wasm/function-tests/trap-load.js: update error message
+            * wasm/function-tests/trap-store.js: update error message
+            * wasm/js-api/wasm-to-wasm-bad-signature.js: Added. Test a bunch of bad wasm-&gt;wasm import signatures
+            (const.makeImportee.signature.switch):
+            (BadSignatureDropStartParams):
+            * wasm/js-api/wasm-to-wasm.js: Added. Test 64-bit wasm-&gt;wasm import calls
+            (const.callerModule):
+            (const.calleeModule):
+            (WasmToWasm):
+
+2017-01-05  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
+
</ins><span class="cx">         Merge r210201. rdar://problem/29803676
</span><span class="cx"> 
</span><span class="cx">     2016-12-28  Saam Barati  &lt;sbarati@apple.com&gt;
</span></span></pre></div>
<a id="branchessafari603branchJSTestswasmBuilderjs"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/JSTests/wasm/Builder.js (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/JSTests/wasm/Builder.js        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/JSTests/wasm/Builder.js        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -38,7 +38,7 @@
</span><span class="cx">     switch (type) {
</span><span class="cx">     // We allow both signed and unsigned numbers.
</span><span class="cx">     case &quot;i32&quot;: return Math.round(value) === value &amp;&amp; LLB.varint32Min &lt;= value &amp;&amp; value &lt;= LLB.varuint32Max;
</span><del>-    case &quot;i64&quot;: throw new Error(`Unimplemented: value check for ${type}`); // FIXME https://bugs.webkit.org/show_bug.cgi?id=163420 64-bit values
</del><ins>+    case &quot;i64&quot;: return true; // FIXME https://bugs.webkit.org/show_bug.cgi?id=163420 64-bit values
</ins><span class="cx">     case &quot;f32&quot;: return typeof(value) === &quot;number&quot; &amp;&amp; isFinite(value);
</span><span class="cx">     case &quot;f64&quot;: return typeof(value) === &quot;number&quot; &amp;&amp; isFinite(value);
</span><span class="cx">     default: throw new Error(`Implementation problem: unknown type ${type}`);
</span><span class="lines">@@ -57,6 +57,16 @@
</span><span class="cx">     return [params, ret];
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+const _errorHandlingProxyFor = builder =&gt; builder[&quot;__isProxy&quot;] ? builder : new Proxy(builder, {
+    get: (target, property, receiver) =&gt; {
+        if (property === &quot;__isProxy&quot;)
+            return true;
+        if (target[property] === undefined)
+            throw new Error(`WebAssembly builder received unknown property '${property}'`);
+        return target[property];
+    }
+});
+
</ins><span class="cx"> const _maybeRegisterType = (builder, type) =&gt; {
</span><span class="cx">     const typeSection = builder._getSection(&quot;Type&quot;);
</span><span class="cx">     if (typeof(type) === &quot;number&quot;) {
</span><span class="lines">@@ -100,7 +110,7 @@
</span><span class="cx">         section.data.push({ field: field, type: type, kind: &quot;Function&quot;, module: module });
</span><span class="cx">         // Imports also count in the function index space. Map them as objects to avoid clashing with Code functions' names.
</span><span class="cx">         builder._registerFunctionToIndexSpace({ module: module, field: field });
</span><del>-        return nextBuilder;
</del><ins>+        return _errorHandlingProxyFor(nextBuilder);
</ins><span class="cx">     };
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -109,7 +119,7 @@
</span><span class="cx">         assert.isString(module, `Import Memory module should be a string, got &quot;${module}&quot;`);
</span><span class="cx">         assert.isString(field, `Import Memory field should be a string, got &quot;${field}&quot;`);
</span><span class="cx">         section.data.push({module, field, kind: &quot;Memory&quot;, memoryDescription: {initial, maximum}});
</span><del>-        return nextBuilder;
</del><ins>+        return _errorHandlingProxyFor(nextBuilder);
</ins><span class="cx">     };
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -118,7 +128,7 @@
</span><span class="cx">         assert.isString(module, `Import Table module should be a string, got &quot;${module}&quot;`);
</span><span class="cx">         assert.isString(field, `Import Table field should be a string, got &quot;${field}&quot;`);
</span><span class="cx">         section.data.push({module, field, kind: &quot;Table&quot;, tableDescription: {initial, maximum, element}});
</span><del>-        return nextBuilder;
</del><ins>+        return _errorHandlingProxyFor(nextBuilder);
</ins><span class="cx">     };
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -172,7 +182,7 @@
</span><span class="cx">                 assert.eq(type, exportedImport.type, `Re-exporting import &quot;${exportedImport.field}&quot; as &quot;${field}&quot; has mismatching type`);
</span><span class="cx">         }
</span><span class="cx">         section.data.push({ field: field, type: type, kind: &quot;Function&quot;, index: index });
</span><del>-        return nextBuilder;
</del><ins>+        return _errorHandlingProxyFor(nextBuilder);
</ins><span class="cx">     };
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -189,7 +199,7 @@
</span><span class="cx">     return (field, index) =&gt; {
</span><span class="cx">         assert.isNumber(index, `Global exports only support number indices right now`);
</span><span class="cx">         section.data.push({ field, kind: &quot;Global&quot;, index });
</span><del>-        return nextBuilder;
</del><ins>+        return _errorHandlingProxyFor(nextBuilder);
</ins><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -197,7 +207,7 @@
</span><span class="cx">     return (field, index) =&gt; {
</span><span class="cx">         assert.isNumber(index, `Memory exports only support number indices`);
</span><span class="cx">         section.data.push({field, kind: &quot;Memory&quot;, index});
</span><del>-        return nextBuilder;
</del><ins>+        return _errorHandlingProxyFor(nextBuilder);
</ins><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -205,7 +215,7 @@
</span><span class="cx">     return (field, index) =&gt; {
</span><span class="cx">         assert.isNumber(index, `Table exports only support number indices`);
</span><span class="cx">         section.data.push({field, kind: &quot;Table&quot;, index});
</span><del>-        return nextBuilder;
</del><ins>+        return _errorHandlingProxyFor(nextBuilder);
</ins><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -220,10 +230,10 @@
</span><span class="cx">                 assert.isString(field, `Import global field should be a string, got &quot;${field}&quot;`);
</span><span class="cx">                 assert.isString(mutability, `Import global mutability should be a string, got &quot;${mutability}&quot;`);
</span><span class="cx">                 section.data.push({ globalDescription: { type: op, mutability: _normalizeMutability(mutability) }, module, field, kind: &quot;Global&quot; });
</span><del>-                return globalBuilder;
</del><ins>+                return _errorHandlingProxyFor(globalBuilder);
</ins><span class="cx">             };
</span><span class="cx">         }
</span><del>-        return globalBuilder;
</del><ins>+        return _errorHandlingProxyFor(globalBuilder);
</ins><span class="cx">     };
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="lines">@@ -324,11 +334,11 @@
</span><span class="cx">             default:
</span><span class="cx">                 nextBuilder = functionBuilder;
</span><span class="cx">                 break;
</span><del>-                case &quot;End&quot;:
</del><ins>+            case &quot;End&quot;:
</ins><span class="cx">                 nextBuilder = previousBuilder;
</span><del>-                    break;
</del><ins>+                break;
</ins><span class="cx">             case &quot;Block&quot;:
</span><del>-                case &quot;Loop&quot;:
</del><ins>+            case &quot;Loop&quot;:
</ins><span class="cx">             case &quot;If&quot;:
</span><span class="cx">                 nextBuilder = _createFunctionBuilder(func, builder, functionBuilder);
</span><span class="cx">                 break;
</span><span class="lines">@@ -344,11 +354,12 @@
</span><span class="cx">             const stackArgs = []; // FIXME https://bugs.webkit.org/show_bug.cgi?id=162706
</span><span class="cx">             func.code.push({ name: op, value: value, arguments: stackArgs, immediates: imms });
</span><span class="cx">             if (hasContinuation)
</span><del>-                return continuation(nextBuilder).End();
-            return nextBuilder;
</del><ins>+                return _errorHandlingProxyFor(continuation(nextBuilder).End());
+            return _errorHandlingProxyFor(nextBuilder);
</ins><span class="cx">         };
</span><del>-    }
-    return functionBuilder;
</del><ins>+    };
+
+    return _errorHandlingProxyFor(functionBuilder);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> const _createFunction = (section, builder, previousBuilder) =&gt; {
</span><span class="lines">@@ -449,10 +460,10 @@
</span><span class="cx">                         Func: (params, ret) =&gt; {
</span><span class="cx">                             [params, ret] = _normalizeFunctionSignature(params, ret);
</span><span class="cx">                             s.data.push({ params: params, ret: ret });
</span><del>-                            return typeBuilder;
</del><ins>+                            return _errorHandlingProxyFor(typeBuilder);
</ins><span class="cx">                         },
</span><span class="cx">                     };
</span><del>-                    return typeBuilder;
</del><ins>+                    return _errorHandlingProxyFor(typeBuilder);
</ins><span class="cx">                 };
</span><span class="cx">                 break;
</span><span class="cx"> 
</span><span class="lines">@@ -466,7 +477,7 @@
</span><span class="cx">                     importBuilder.Function = _importFunctionContinuation(this, s, importBuilder);
</span><span class="cx">                     importBuilder.Memory = _importMemoryContinuation(this, s, importBuilder);
</span><span class="cx">                     importBuilder.Table = _importTableContinuation(this, s, importBuilder);
</span><del>-                    return importBuilder;
</del><ins>+                    return _errorHandlingProxyFor(importBuilder);
</ins><span class="cx">                 };
</span><span class="cx">                 break;
</span><span class="cx"> 
</span><span class="lines">@@ -477,7 +488,7 @@
</span><span class="cx">                         End: () =&gt; this
</span><span class="cx">                         // FIXME: add ability to add this with whatever.
</span><span class="cx">                     };
</span><del>-                    return functionBuilder;
</del><ins>+                    return _errorHandlingProxyFor(functionBuilder);
</ins><span class="cx">                 };
</span><span class="cx">                 break;
</span><span class="cx"> 
</span><span class="lines">@@ -488,10 +499,10 @@
</span><span class="cx">                         End: () =&gt; this,
</span><span class="cx">                         Table: ({initial, maximum, element}) =&gt; {
</span><span class="cx">                             s.data.push({tableDescription: {initial, maximum, element}});
</span><del>-                            return tableBuilder;
</del><ins>+                            return _errorHandlingProxyFor(tableBuilder);
</ins><span class="cx">                         }
</span><span class="cx">                     };
</span><del>-                    return tableBuilder;
</del><ins>+                    return _errorHandlingProxyFor(tableBuilder);
</ins><span class="cx">                 };
</span><span class="cx">                 break;
</span><span class="cx"> 
</span><span class="lines">@@ -502,10 +513,10 @@
</span><span class="cx">                         End: () =&gt; this,
</span><span class="cx">                         InitialMaxPages: (initial, max) =&gt; {
</span><span class="cx">                             s.data.push({ initial, max });
</span><del>-                            return memoryBuilder;
</del><ins>+                            return _errorHandlingProxyFor(memoryBuilder);
</ins><span class="cx">                         }
</span><span class="cx">                     };
</span><del>-                    return memoryBuilder;
</del><ins>+                    return _errorHandlingProxyFor(memoryBuilder);
</ins><span class="cx">                 };
</span><span class="cx">                 break;
</span><span class="cx"> 
</span><span class="lines">@@ -516,16 +527,16 @@
</span><span class="cx">                         End: () =&gt; this,
</span><span class="cx">                         GetGlobal: (type, initValue, mutability) =&gt; {
</span><span class="cx">                             s.data.push({ type, op: &quot;get_global&quot;, mutability: _normalizeMutability(mutability), initValue });
</span><del>-                            return globalBuilder;
</del><ins>+                            return _errorHandlingProxyFor(globalBuilder);
</ins><span class="cx">                         }
</span><span class="cx">                     };
</span><span class="cx">                     for (let op of WASM.description.value_type) {
</span><span class="cx">                         globalBuilder[_toJavaScriptName(op)] = (initValue, mutability) =&gt; {
</span><span class="cx">                             s.data.push({ type: op, op: op + &quot;.const&quot;, mutability: _normalizeMutability(mutability), initValue });
</span><del>-                            return globalBuilder;
</del><ins>+                            return _errorHandlingProxyFor(globalBuilder);
</ins><span class="cx">                         };
</span><span class="cx">                     }
</span><del>-                    return globalBuilder;
</del><ins>+                    return _errorHandlingProxyFor(globalBuilder);
</ins><span class="cx">                 };
</span><span class="cx">                 break;
</span><span class="cx"> 
</span><span class="lines">@@ -539,7 +550,7 @@
</span><span class="cx">                     exportBuilder.Function = _exportFunctionContinuation(this, s, exportBuilder);
</span><span class="cx">                     exportBuilder.Memory = _exportMemoryContinuation(this, s, exportBuilder);
</span><span class="cx">                     exportBuilder.Table = _exportTableContinuation(this, s, exportBuilder);
</span><del>-                    return exportBuilder;
</del><ins>+                    return _errorHandlingProxyFor(exportBuilder);
</ins><span class="cx">                 };
</span><span class="cx">                 break;
</span><span class="cx"> 
</span><span class="lines">@@ -552,7 +563,7 @@
</span><span class="cx">                     if (typeof(functionIndexOrName) !== &quot;number&quot; &amp;&amp; typeof(functionIndexOrName) !== &quot;string&quot;)
</span><span class="cx">                         throw new Error(`Start section's function index  must either be a number or a string`);
</span><span class="cx">                     s.data.push(functionIndexOrName);
</span><del>-                    return startBuilder;
</del><ins>+                    return _errorHandlingProxyFor(startBuilder);
</ins><span class="cx">                 };
</span><span class="cx">                 break;
</span><span class="cx"> 
</span><span class="lines">@@ -563,11 +574,11 @@
</span><span class="cx">                         End: () =&gt; this,
</span><span class="cx">                         Element: ({tableIndex = 0, offset, functionIndices}) =&gt; {
</span><span class="cx">                             s.data.push({tableIndex, offset, functionIndices});
</span><del>-                            return elementBuilder;
</del><ins>+                            return _errorHandlingProxyFor(elementBuilder);
</ins><span class="cx">                         }
</span><span class="cx">                     };
</span><span class="cx"> 
</span><del>-                    return elementBuilder;
</del><ins>+                    return _errorHandlingProxyFor(elementBuilder);
</ins><span class="cx">                 };
</span><span class="cx">                 break;
</span><span class="cx"> 
</span><span class="lines">@@ -632,12 +643,12 @@
</span><span class="cx">                                     // FIXME in checked mode, test that the type is acceptable for start function. We probably want _registerFunctionToIndexSpace to also register types per index. https://bugs.webkit.org/show_bug.cgi?id=165658
</span><span class="cx">                                 }
</span><span class="cx">                             }
</span><del>-                            return builder;
</del><ins>+                            return _errorHandlingProxyFor(builder);
</ins><span class="cx">                         },
</span><span class="cx"> 
</span><span class="cx">                     };
</span><span class="cx">                     codeBuilder.Function = _createFunction(s, builder, codeBuilder);
</span><del>-                    return codeBuilder;
</del><ins>+                    return _errorHandlingProxyFor(codeBuilder);
</ins><span class="cx">                 };
</span><span class="cx">                 break;
</span><span class="cx"> 
</span><span class="lines">@@ -660,19 +671,19 @@
</span><span class="cx">                                 Index: index =&gt; {
</span><span class="cx">                                     assert.eq(index, 0); // Linear memory index must be zero in MVP.
</span><span class="cx">                                     thisSegment.index = index;
</span><del>-                                    return segmentBuilder;
</del><ins>+                                    return _errorHandlingProxyFor(segmentBuilder);
</ins><span class="cx">                                 },
</span><span class="cx">                                 Offset: offset =&gt; {
</span><span class="cx">                                     // FIXME allow complex init_expr here. https://bugs.webkit.org/show_bug.cgi?id=165700
</span><span class="cx">                                     assert.isNumber(offset);
</span><span class="cx">                                     thisSegment.offset = offset;
</span><del>-                                    return segmentBuilder;
</del><ins>+                                    return _errorHandlingProxyFor(segmentBuilder);
</ins><span class="cx">                                 },
</span><span class="cx">                             };
</span><del>-                            return segmentBuilder;
</del><ins>+                            return _errorHandlingProxyFor(segmentBuilder);
</ins><span class="cx">                         },
</span><span class="cx">                     };
</span><del>-                    return dataBuilder;
</del><ins>+                    return _errorHandlingProxyFor(dataBuilder);
</ins><span class="cx">                 };
</span><span class="cx">                 break;
</span><span class="cx"> 
</span><span class="lines">@@ -690,10 +701,10 @@
</span><span class="cx">                 Byte: b =&gt; {
</span><span class="cx">                     assert.eq(b &amp; 0xFF, b, `Unknown section expected byte, got: &quot;${b}&quot;`);
</span><span class="cx">                     s.data.push(b);
</span><del>-                    return unknownBuilder;
</del><ins>+                    return _errorHandlingProxyFor(unknownBuilder);
</ins><span class="cx">                 }
</span><span class="cx">             };
</span><del>-            return unknownBuilder;
</del><ins>+            return _errorHandlingProxyFor(unknownBuilder);
</ins><span class="cx">         };
</span><span class="cx">     }
</span><span class="cx">     _addSection(nameOrNumber, extraObject) {
</span></span></pre></div>
<a id="branchessafari603branchJSTestswasmLowLevelBinaryjs"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/JSTests/wasm/LowLevelBinary.js (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/JSTests/wasm/LowLevelBinary.js        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/JSTests/wasm/LowLevelBinary.js        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -170,6 +170,18 @@
</span><span class="cx">             this.uint8(0x80 | b);
</span><span class="cx">         } while (true);
</span><span class="cx">     }
</span><ins>+    varuint64(v) {
+        assert.isNumber(v);
+        if (v &lt; varuint32Min || varuint32Max &lt; v)
+            throw new RangeError(`unimplemented: varuint64 larger than 32-bit`);
+        this.varuint32(v); // FIXME implement 64-bit var{u}int https://bugs.webkit.org/show_bug.cgi?id=163420
+    }
+    varint64(v) {
+        assert.isNumber(v);
+        if (v &lt; varint32Min || varint32Max &lt; v)
+            throw new RangeError(`unimplemented: varint64 larger than 32-bit`);
+        this.varint32(v); // FIXME implement 64-bit var{u}int https://bugs.webkit.org/show_bug.cgi?id=163420
+    }
</ins><span class="cx">     varuint1(v) {
</span><span class="cx">         if (v !== 0 &amp;&amp; v !== 1)
</span><span class="cx">             throw new RangeError(`Invalid varuint1 ${v} range is [0, 1]`);
</span></span></pre></div>
<a id="branchessafari603branchJSTestswasmfunctiontestsexceptionsjs"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/JSTests/wasm/function-tests/exceptions.js (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/JSTests/wasm/function-tests/exceptions.js        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/JSTests/wasm/function-tests/exceptions.js        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -45,7 +45,7 @@
</span><span class="cx">     assert.eq(table.get(0), null);
</span><span class="cx"> 
</span><span class="cx">     for (let i = 0; i &lt; 1000; i++) {
</span><del>-        assert.throws(() =&gt; foo(0, i), WebAssembly.RuntimeError, &quot;call_indirect to a null table entry (evaluating 'func(...args)')&quot;);
</del><ins>+        assert.throws(() =&gt; foo(0, i), WebAssembly.RuntimeError, &quot;call_indirect to a null table entry&quot;);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     table.set(0, foo);
</span><span class="lines">@@ -52,11 +52,11 @@
</span><span class="cx">     assert.eq(table.get(0), foo);
</span><span class="cx"> 
</span><span class="cx">     for (let i = 0; i &lt; 1000; i++) {
</span><del>-        assert.throws(() =&gt; foo(1 + i, i), WebAssembly.RuntimeError, &quot;Out of bounds call_indirect (evaluating 'func(...args)')&quot;);
</del><ins>+        assert.throws(() =&gt; foo(1 + i, i), WebAssembly.RuntimeError, &quot;Out of bounds call_indirect&quot;);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     for (let i = 0; i &lt; 1000; i++) {
</span><del>-        assert.throws(() =&gt; foo(0, i), WebAssembly.RuntimeError, &quot;call_indirect to a signature that does not match (evaluating 'func(...args)')&quot;);
</del><ins>+        assert.throws(() =&gt; foo(0, i), WebAssembly.RuntimeError, &quot;call_indirect to a signature that does not match&quot;);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     table.set(0, bar);
</span></span></pre></div>
<a id="branchessafari603branchJSTestswasmfunctionteststraploadjs"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/JSTests/wasm/function-tests/trap-load.js (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/JSTests/wasm/function-tests/trap-load.js        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/JSTests/wasm/function-tests/trap-load.js        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -29,7 +29,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> for (let i = 0; i &lt; 1000; i++) {
</span><del>-    const e = assert.throws(() =&gt; foo(numPages * pageSize + 1), WebAssembly.RuntimeError, &quot;Out of bounds memory access (evaluating 'func(...args)')&quot;);
</del><ins>+    const e = assert.throws(() =&gt; foo(numPages * pageSize + 1), WebAssembly.RuntimeError, &quot;Out of bounds memory access&quot;);
</ins><span class="cx">     assert.eq(wasmFrameCountFromError(e), 2);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchJSTestswasmfunctionteststrapstorejs"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/JSTests/wasm/function-tests/trap-store.js (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/JSTests/wasm/function-tests/trap-store.js        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/JSTests/wasm/function-tests/trap-store.js        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -25,7 +25,7 @@
</span><span class="cx">     const foo = new WebAssembly.Instance(module, {a: {b: new WebAssembly.Memory({initial: numPages})}}).exports.foo;
</span><span class="cx"> 
</span><span class="cx">     for (let i = 0; i &lt; 10000; i++)
</span><del>-        assert.throws(() =&gt; foo(i, numPages * pageSize + 1), WebAssembly.RuntimeError, &quot;Out of bounds memory access (evaluating 'func(...args)')&quot;);
</del><ins>+        assert.throws(() =&gt; foo(i, numPages * pageSize + 1), WebAssembly.RuntimeError, &quot;Out of bounds memory access&quot;);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchJSTestswasmjsapiwasmtowasmbadsignaturejs"></a>
<div class="addfile"><h4>Added: branches/safari-603-branch/JSTests/wasm/js-api/wasm-to-wasm-bad-signature.js (0 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/JSTests/wasm/js-api/wasm-to-wasm-bad-signature.js                                (rev 0)
+++ branches/safari-603-branch/JSTests/wasm/js-api/wasm-to-wasm-bad-signature.js        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -0,0 +1,105 @@
</span><ins>+import * as assert from '../assert.js';
+import Builder from '../Builder.js';
+
+const importName = &quot;pierOne&quot;;
+const types = [&quot;i32&quot;, &quot;i64&quot;, &quot;f32&quot;, &quot;f64&quot;, &quot;void&quot;];
+const typesNonVoid = [&quot;i32&quot;, &quot;i64&quot;, &quot;f32&quot;, &quot;f64&quot;];
+const swapType = (type, index) =&gt; types[(types.indexOf(type) + index) % types.length];
+const swapTypeNonVoid = (type, index) =&gt; typesNonVoid[(typesNonVoid.indexOf(type) + index) % typesNonVoid.length];
+
+const signatures = [
+    { params: [&quot;i32&quot;], ret: &quot;void&quot; },
+    { params: [&quot;i64&quot;], ret: &quot;void&quot; },
+    { params: [&quot;f32&quot;], ret: &quot;void&quot; },
+    { params: [&quot;f64&quot;], ret: &quot;void&quot; },
+    { params: [&quot;i32&quot;], ret: &quot;i32&quot; },
+    { params: [&quot;i64&quot;], ret: &quot;i64&quot; },
+    { params: [&quot;f32&quot;], ret: &quot;f32&quot; },
+    { params: [&quot;f64&quot;], ret: &quot;f64&quot; },
+    { params: [&quot;i32&quot;, &quot;f32&quot;], ret: &quot;i32&quot; },
+    { params: [&quot;f32&quot;, &quot;i32&quot;], ret: &quot;i32&quot; },
+    { params: [&quot;i64&quot;, &quot;f64&quot;], ret: &quot;i64&quot; },
+    { params: [&quot;f64&quot;, &quot;i64&quot;], ret: &quot;i64&quot; },
+    { params: [&quot;i32&quot;, &quot;f32&quot;, &quot;i32&quot;], ret: &quot;i32&quot; },
+    { params: [&quot;i32&quot;, &quot;f32&quot;, &quot;i32&quot;], ret: &quot;i32&quot; },
+    { params: [&quot;i64&quot;, &quot;f64&quot;, &quot;i64&quot;], ret: &quot;i64&quot; },
+    { params: [&quot;i64&quot;, &quot;f64&quot;, &quot;i64&quot;], ret: &quot;i64&quot; },
+    { params: Array(32).fill(&quot;i32&quot;), ret: &quot;i64&quot; },
+    { params: Array(32).fill(&quot;i64&quot;), ret: &quot;i64&quot; },
+    { params: Array(32).fill(&quot;f32&quot;), ret: &quot;i64&quot; },
+    { params: Array(32).fill(&quot;f64&quot;), ret: &quot;i64&quot; },
+];
+
+const makeImporter = signature =&gt; {
+    const builder = (new Builder())
+        .Type().End()
+        .Import().Function(&quot;exports&quot;, importName, signature).End();
+    return new WebAssembly.Module(builder.WebAssembly().get());
+};
+
+const makeImportee = signature =&gt; {
+    const builder = (new Builder())
+        .Type().End()
+        .Function().End()
+        .Export()
+            .Function(importName)
+        .End()
+        .Code()
+            .Function(importName, signature);
+    switch (signature.ret) {
+    case &quot;i32&quot;: builder.I32Const(0); break;
+    case &quot;i64&quot;: builder.I64Const(0); break;
+    case &quot;f32&quot;: builder.F32Const(0); break;
+    case &quot;f64&quot;: builder.F64Const(0); break;
+    case &quot;void&quot;: break;
+    }
+    return new WebAssembly.Instance(new WebAssembly.Module(builder.Return().End().End().WebAssembly().get()));
+};
+
+(function BadSignatureDropStartParams() {
+    for (let signature of signatures) {
+        const importee = makeImportee(signature);
+        for (let i = 1; i &lt;= signature.params.length; ++i) {
+            const badParamSignature = { params: signature.params.slice(i, signature.params.length), ret: signature.ret };
+            const importer = makeImporter(badParamSignature);
+            assert.throws(() =&gt; new WebAssembly.Instance(importer, importee), WebAssembly.LinkError, `imported function's signature doesn't match the provided WebAssembly function's signature (evaluating 'new WebAssembly.Instance(importer, importee)')`);
+        }
+    }
+})();
+
+(function BadSignatureDropEndParams() {
+    for (let signature of signatures) {
+        const importee = makeImportee(signature);
+        for (let i = 1; i &lt; signature.params.length; ++i) {
+            const badParamSignature = { params: signature.params.slice(0, i), ret: signature.ret };
+            const importer = makeImporter(badParamSignature);
+            assert.throws(() =&gt; new WebAssembly.Instance(importer, importee), WebAssembly.LinkError, `imported function's signature doesn't match the provided WebAssembly function's signature (evaluating 'new WebAssembly.Instance(importer, importee)')`);
+        }
+    }
+})();
+
+(function BadSignatureSwapParam() {
+    for (let signature of signatures) {
+        const importee = makeImportee(signature);
+        for (let signatureIndex = 0; signatureIndex &lt; signature.length; ++signatureIndex) {
+            for (let typeIndex = 1; typeIndex &lt; typesNonVoid.length; ++typeIndex) {
+                let badParams = signature.params.slice();
+                badParams[signatureIndex] = swapTypeNonVoid(badParams[signatureIndex], typeIndex);
+                const badParamSignature = { params: badParams, ret: signature.ret };
+                const importer = makeImporter(badParamSignature);
+                assert.throws(() =&gt; new WebAssembly.Instance(importer, importee), WebAssembly.LinkError, `imported function's signature doesn't match the provided WebAssembly function's signature (evaluating 'new WebAssembly.Instance(importer, importee)')`);
+            }
+        }
+    }
+})();
+
+(function BadSignatureRet() {
+    for (let signature of signatures) {
+        const importee = makeImportee(signature);
+        for (let typeIndex = 1; typeIndex &lt; types.length; ++typeIndex) {
+            const badParamSignature = { params: signature.params, ret: swapType(signature.ret, typeIndex) };
+            const importer = makeImporter(badParamSignature);
+            assert.throws(() =&gt; new WebAssembly.Instance(importer, importee), WebAssembly.LinkError, `imported function's signature doesn't match the provided WebAssembly function's signature (evaluating 'new WebAssembly.Instance(importer, importee)')`);
+        }
+    }
+})();
</ins></span></pre></div>
<a id="branchessafari603branchJSTestswasmjsapiwasmtowasmjs"></a>
<div class="addfile"><h4>Added: branches/safari-603-branch/JSTests/wasm/js-api/wasm-to-wasm.js (0 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/JSTests/wasm/js-api/wasm-to-wasm.js                                (rev 0)
+++ branches/safari-603-branch/JSTests/wasm/js-api/wasm-to-wasm.js        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -0,0 +1,72 @@
</span><ins>+import * as assert from '../assert.js';
+import Builder from '../Builder.js';
+
+const callerTopBits = 0xC0FEBEEF;
+const innerReturnHi = 0xDEADFACE;
+const innerReturnLo = 0xC0FEC0FE;
+
+const callerModule = () =&gt; {
+    const builder = (new Builder())
+        .Type().End()
+        .Import()
+            .Function(&quot;exports&quot;, &quot;callMe&quot;, { params: [&quot;i64&quot;], ret: &quot;i64&quot; })
+        .End()
+        .Function().End()
+        .Export()
+            .Function(&quot;entry&quot;)
+        .End()
+        .Code()
+            .Function(&quot;entry&quot;, { params: [&quot;i32&quot;], ret: &quot;i32&quot; }, [&quot;i64&quot;])
+                .I32Const(callerTopBits).I64ExtendUI32().I32Const(32).I64ExtendUI32().I64Shl() // ((i64)callerTopBits) &lt;&lt; 32
+                .GetLocal(0).I64ExtendUI32()
+                .I64Or() // value: param | (((i64)callerTopBits &lt;&lt; 32))
+                .Call(0) // Calls exports.callMe(param | (((i64)callerTopBits) &lt;&lt; 32)).
+                .TeeLocal(1).I32WrapI64() // lo: (i32)callResult
+                .GetLocal(1).I32Const(32).I64ExtendUI32().I64ShrU().I32WrapI64() // hi: (i32)(callResult &gt;&gt; 32)
+                .I32Xor()
+                .Return()
+            .End()
+        .End();
+    return new WebAssembly.Module(builder.WebAssembly().get());
+};
+
+const calleeModule = () =&gt; {
+    const builder = (new Builder())
+        .Type().End()
+        .Import()
+            .Function(&quot;imp&quot;, &quot;func&quot;, { params: [&quot;i32&quot;, &quot;i32&quot;], ret: &quot;i32&quot; })
+        .End()
+        .Function().End()
+        .Export()
+            .Function(&quot;callMe&quot;)
+        .End()
+        .Code()
+            .Function(&quot;callMe&quot;, { params: [&quot;i64&quot;], ret: &quot;i64&quot; })
+                .GetLocal(0).I32WrapI64() // lo: (i32)param
+                .GetLocal(0).I32Const(32).I64ExtendUI32().I64ShrU().I32WrapI64() // hi: (i32)(param &gt;&gt; 32)
+                .Call(0) // Calls imp.func with the 64-bit value as i32 { hi, lo }.
+                .Drop()
+                .I32Const(innerReturnHi).I64ExtendUI32().I32Const(32).I64ExtendUI32().I64Shl().I32Const(innerReturnLo).I64ExtendUI32().I64Or() // ((i64)hi &lt;&lt; 32) | (i64)lo
+                .Return()
+            .End()
+        .End();
+    return new WebAssembly.Module(builder.WebAssembly().get());
+};
+
+(function WasmToWasm() {
+    let value;
+    const func = (hi, lo) =&gt; { value = { hi: hi, lo: lo }; return hi ^ lo; };
+    const callee = new WebAssembly.Instance(calleeModule(), { imp: { func: func } });
+    const caller = new WebAssembly.Instance(callerModule(), callee);
+    for (let i = 0; i &lt; 4096; ++i) {
+        assert.eq(caller.exports.entry(i), innerReturnHi ^ innerReturnLo);
+        assert.eq(value.lo &gt;&gt;&gt; 0, callerTopBits);
+        assert.eq(value.hi &gt;&gt;&gt; 0, i);
+    }
+})();
+
+// FIXME test the following https://bugs.webkit.org/show_bug.cgi?id=166625
+// - wasm-&gt;wasm using 32-bit things (including float), as well as 64-bit NaNs that don't get canonicalized
+// - Do a throw two-deep
+// - Check that the first wasm's instance is back in OK state (with table or global?)
+// - Test calling through a Table
</ins></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/CMakeLists.txt (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/CMakeLists.txt        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/CMakeLists.txt        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -906,6 +906,7 @@
</span><span class="cx">     wasm/WasmMemory.cpp
</span><span class="cx">     wasm/WasmMemoryInformation.cpp
</span><span class="cx">     wasm/WasmModuleParser.cpp
</span><ins>+    wasm/WasmPageCount.cpp
</ins><span class="cx">     wasm/WasmPlan.cpp
</span><span class="cx">     wasm/WasmSignature.cpp
</span><span class="cx">     wasm/WasmValidate.cpp
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/ChangeLog (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/ChangeLog        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/ChangeLog        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -1,5 +1,134 @@
</span><span class="cx"> 2017-01-05  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Merge r210229. rdar://problem/29760322
+
+    2017-01-02  JF Bastien  &lt;jfbastien@apple.com&gt;
+
+            WebAssembly: handle and optimize wasm export → wasm import calls
+            https://bugs.webkit.org/show_bug.cgi?id=165282
+
+            Reviewed by Saam Barati.
+
+              - Add a new JSType for WebAssemblyFunction, and use it when creating its
+                structure. This will is used to quickly detect from wasm whether the import
+                call is to another wasm module, or whether it's to JS.
+              - Generate two stubs from the import stub generator: one for wasm-&gt;JS and one
+                for wasm -&gt; wasm. This is done at Module time. Which is called will only be
+                known at Instance time, once we've received the import object. We want to
+                avoid codegen at Instance time, so having both around is great.
+              - Restore the WebAssembly global state (VM top Instance, and pinned registers)
+                after call / call_indirect, and in the JS-&gt;wasm entry stub.
+              - Pinned registers are now a global thing, not per-Memory, because the wasm -&gt;
+                wasm stubs are generated at Module time where we don't really have enough
+                information to do the right thing (doing so would generate too much code).
+
+            * CMakeLists.txt:
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * runtime/JSType.h: add WebAssemblyFunctionType as a JSType
+            * wasm/WasmB3IRGenerator.cpp: significantly rework how calls which
+            could be external work, and how we save / restore global state:
+            VM's top Instance, and pinned registers
+            (JSC::Wasm::B3IRGenerator::B3IRGenerator):
+            (JSC::Wasm::getMemoryBaseAndSize):
+            (JSC::Wasm::restoreWebAssemblyGlobalState):
+            (JSC::Wasm::createJSToWasmWrapper):
+            (JSC::Wasm::parseAndCompile):
+            * wasm/WasmB3IRGenerator.h:
+            * wasm/WasmBinding.cpp:
+            (JSC::Wasm::materializeImportJSCell):
+            (JSC::Wasm::wasmToJS):
+            (JSC::Wasm::wasmToWasm): the main goal of this patch was adding this function
+            (JSC::Wasm::exitStubGenerator):
+            * wasm/WasmBinding.h:
+            * wasm/WasmFormat.h: Get rid of much of the function index space:
+            we already have all of its information elsewhere, and as-is it
+            provides no extra efficiency.
+            (JSC::Wasm::ModuleInformation::functionIndexSpaceSize):
+            (JSC::Wasm::ModuleInformation::isImportedFunctionFromFunctionIndexSpace):
+            (JSC::Wasm::ModuleInformation::signatureIndexFromFunctionIndexSpace):
+            * wasm/WasmFunctionParser.h:
+            (JSC::Wasm::FunctionParser&lt;Context&gt;::FunctionParser):
+            * wasm/WasmMemory.cpp: Add some logging.
+            (JSC::Wasm::Memory::dump): this was nice when debugging
+            (JSC::Wasm::Memory::makeString):
+            (JSC::Wasm::Memory::Memory):
+            (JSC::Wasm::Memory::~Memory):
+            (JSC::Wasm::Memory::grow):
+            * wasm/WasmMemory.h: don't use extra indirection, it wasn't
+            needed. Reorder some of the fields which are looked up at runtime
+            so they're more cache-friendly.
+            (JSC::Wasm::Memory::Memory):
+            (JSC::Wasm::Memory::mode):
+            (JSC::Wasm::Memory::offsetOfSize):
+            * wasm/WasmMemoryInformation.cpp: Pinned registers are now a
+            global thing for all of JSC, not a per-Memory thing
+            anymore. wasm-&gt;wasm calls are more complex otherwise: they have to
+            figure out how to bridge between the caller and callee's
+            special-snowflake pinning.
+            (JSC::Wasm::PinnedRegisterInfo::get):
+            (JSC::Wasm::PinnedRegisterInfo::PinnedRegisterInfo):
+            (JSC::Wasm::MemoryInformation::MemoryInformation):
+            * wasm/WasmMemoryInformation.h:
+            * wasm/WasmModuleParser.cpp:
+            * wasm/WasmModuleParser.h:
+            * wasm/WasmPageCount.cpp: Copied from Source/JavaScriptCore/wasm/WasmBinding.h.
+            (JSC::Wasm::PageCount::dump): nice for debugging
+            * wasm/WasmPageCount.h:
+            * wasm/WasmPlan.cpp:
+            (JSC::Wasm::Plan::parseAndValidateModule):
+            (JSC::Wasm::Plan::run):
+            * wasm/WasmPlan.h:
+            (JSC::Wasm::Plan::takeWasmExitStubs):
+            * wasm/WasmSignature.cpp:
+            (JSC::Wasm::Signature::toString):
+            (JSC::Wasm::Signature::dump):
+            * wasm/WasmSignature.h:
+            * wasm/WasmValidate.cpp:
+            (JSC::Wasm::validateFunction):
+            * wasm/WasmValidate.h:
+            * wasm/js/JSWebAssemblyInstance.h:
+            (JSC::JSWebAssemblyInstance::offsetOfTable):
+            (JSC::JSWebAssemblyInstance::offsetOfImportFunctions):
+            (JSC::JSWebAssemblyInstance::offsetOfImportFunction):
+            * wasm/js/JSWebAssemblyMemory.cpp:
+            (JSC::JSWebAssemblyMemory::create):
+            (JSC::JSWebAssemblyMemory::JSWebAssemblyMemory):
+            (JSC::JSWebAssemblyMemory::buffer):
+            (JSC::JSWebAssemblyMemory::grow):
+            * wasm/js/JSWebAssemblyMemory.h:
+            (JSC::JSWebAssemblyMemory::memory):
+            (JSC::JSWebAssemblyMemory::offsetOfMemory):
+            (JSC::JSWebAssemblyMemory::offsetOfSize):
+            * wasm/js/JSWebAssemblyModule.cpp:
+            (JSC::JSWebAssemblyModule::create):
+            (JSC::JSWebAssemblyModule::JSWebAssemblyModule):
+            * wasm/js/JSWebAssemblyModule.h:
+            (JSC::JSWebAssemblyModule::signatureIndexFromFunctionIndexSpace):
+            (JSC::JSWebAssemblyModule::functionImportCount):
+            * wasm/js/WebAssemblyFunction.cpp:
+            (JSC::callWebAssemblyFunction):
+            (JSC::WebAssemblyFunction::create):
+            (JSC::WebAssemblyFunction::createStructure):
+            (JSC::WebAssemblyFunction::WebAssemblyFunction):
+            (JSC::WebAssemblyFunction::finishCreation):
+            * wasm/js/WebAssemblyFunction.h:
+            (JSC::WebAssemblyFunction::wasmEntrypoint):
+            (JSC::WebAssemblyFunction::offsetOfInstance):
+            (JSC::WebAssemblyFunction::offsetOfWasmEntryPointCode):
+            * wasm/js/WebAssemblyInstanceConstructor.cpp:
+            (JSC::constructJSWebAssemblyInstance): always start with a dummy
+            memory, so wasm-&gt;wasm calls don't need to null-check
+            * wasm/js/WebAssemblyMemoryConstructor.cpp:
+            (JSC::constructJSWebAssemblyMemory):
+            * wasm/js/WebAssemblyModuleConstructor.cpp:
+            (JSC::WebAssemblyModuleConstructor::createModule):
+            * wasm/js/WebAssemblyModuleRecord.cpp:
+            (JSC::WebAssemblyModuleRecord::link):
+            (JSC::WebAssemblyModuleRecord::evaluate):
+            * wasm/js/WebAssemblyModuleRecord.h:
+
+2017-01-05  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
+
</ins><span class="cx">         Merge r210202. rdar://problem/29803676
</span><span class="cx"> 
</span><span class="cx">     2016-12-28  Saam Barati  &lt;sbarati@apple.com&gt;
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -1235,6 +1235,7 @@
</span><span class="cx">                 2ADFA26318EF3540004F9FCC /* GCLogging.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2ADFA26218EF3540004F9FCC /* GCLogging.cpp */; };
</span><span class="cx">                 2AF7382C18BBBF92008A5A37 /* StructureIDTable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2AF7382A18BBBF92008A5A37 /* StructureIDTable.cpp */; };
</span><span class="cx">                 2AF7382D18BBBF92008A5A37 /* StructureIDTable.h in Headers */ = {isa = PBXBuildFile; fileRef = 2AF7382B18BBBF92008A5A37 /* StructureIDTable.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                2D342F36F7244096804ADB24 /* SourceOrigin.h in Headers */ = {isa = PBXBuildFile; fileRef = 425BA1337E4344E1B269A671 /* SourceOrigin.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 371D842D17C98B6E00ECF994 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 371D842C17C98B6E00ECF994 /* libz.dylib */; };
</span><span class="cx">                 412952771D2CF6BC00E78B89 /* builtins_generate_internals_wrapper_header.py in Headers */ = {isa = PBXBuildFile; fileRef = 412952731D2CF6AC00E78B89 /* builtins_generate_internals_wrapper_header.py */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 412952781D2CF6BC00E78B89 /* builtins_generate_internals_wrapper_implementation.py in Headers */ = {isa = PBXBuildFile; fileRef = 412952741D2CF6AC00E78B89 /* builtins_generate_internals_wrapper_implementation.py */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -2025,6 +2026,7 @@
</span><span class="cx">                 AD7438C01E0457A400FD0C2A /* WasmSignature.h in Headers */ = {isa = PBXBuildFile; fileRef = AD7438BF1E04579200FD0C2A /* WasmSignature.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 AD7438C11E0457AA00FD0C2A /* WasmSignature.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD7438BE1E04579200FD0C2A /* WasmSignature.cpp */; };
</span><span class="cx">                 AD86A93E1AA4D88D002FE77F /* WeakGCMapInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = AD86A93D1AA4D87C002FE77F /* WeakGCMapInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                ADB6F67D1E15D7600082F384 /* WasmPageCount.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ADB6F67C1E15D7500082F384 /* WasmPageCount.cpp */; };
</ins><span class="cx">                 ADBC54D41DF8EA2B005BF738 /* WebAssemblyToJSCallee.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ADBC54D21DF8EA00005BF738 /* WebAssemblyToJSCallee.cpp */; };
</span><span class="cx">                 ADBC54D51DF8EA2B005BF738 /* WebAssemblyToJSCallee.h in Headers */ = {isa = PBXBuildFile; fileRef = ADBC54D31DF8EA00005BF738 /* WebAssemblyToJSCallee.h */; };
</span><span class="cx">                 ADDB1F6318D77DBE009B58A8 /* OpaqueRootSet.h in Headers */ = {isa = PBXBuildFile; fileRef = ADDB1F6218D77DB7009B58A8 /* OpaqueRootSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -3637,6 +3639,7 @@
</span><span class="cx">                 412952751D2CF6AC00E78B89 /* builtins_generate_wrapper_header.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = builtins_generate_wrapper_header.py; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 412952761D2CF6AC00E78B89 /* builtins_generate_wrapper_implementation.py */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.python; path = builtins_generate_wrapper_implementation.py; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 41DEA1311B9F3154006D65DD /* BuiltinUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BuiltinUtils.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                425BA1337E4344E1B269A671 /* SourceOrigin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SourceOrigin.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 4319DA011C1BE3C1001D260B /* B3LowerMacrosAfterOptimizations.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = B3LowerMacrosAfterOptimizations.cpp; path = b3/B3LowerMacrosAfterOptimizations.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 4319DA021C1BE3C1001D260B /* B3LowerMacrosAfterOptimizations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = B3LowerMacrosAfterOptimizations.h; path = b3/B3LowerMacrosAfterOptimizations.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 4340A4821A9051AF00D73CCA /* MathCommon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MathCommon.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -4509,6 +4512,7 @@
</span><span class="cx">                 AD7438BE1E04579200FD0C2A /* WasmSignature.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmSignature.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 AD7438BF1E04579200FD0C2A /* WasmSignature.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmSignature.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 AD86A93D1AA4D87C002FE77F /* WeakGCMapInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakGCMapInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                ADB6F67C1E15D7500082F384 /* WasmPageCount.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmPageCount.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 ADBC54D21DF8EA00005BF738 /* WebAssemblyToJSCallee.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebAssemblyToJSCallee.cpp; path = js/WebAssemblyToJSCallee.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 ADBC54D31DF8EA00005BF738 /* WebAssemblyToJSCallee.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebAssemblyToJSCallee.h; path = js/WebAssemblyToJSCallee.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 ADDB1F6218D77DB7009B58A8 /* OpaqueRootSet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OpaqueRootSet.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -6045,6 +6049,7 @@
</span><span class="cx">                                 79B759721DFA4C600052174C /* WasmMemoryInformation.h */,
</span><span class="cx">                                 53F40E961D5A7BEC0099A1B6 /* WasmModuleParser.cpp */,
</span><span class="cx">                                 53F40E941D5A7AEF0099A1B6 /* WasmModuleParser.h */,
</span><ins>+                                ADB6F67C1E15D7500082F384 /* WasmPageCount.cpp */,
</ins><span class="cx">                                 79B759731DFA4C600052174C /* WasmPageCount.h */,
</span><span class="cx">                                 53F40E8C1D5901F20099A1B6 /* WasmParser.h */,
</span><span class="cx">                                 531374BE1D5CE95000AF7A0B /* WasmPlan.cpp */,
</span><span class="lines">@@ -9699,6 +9704,7 @@
</span><span class="cx">                                 0F64B2711A784BAF006E4E66 /* BinarySwitch.cpp in Sources */,
</span><span class="cx">                                 14280863107EC11A0013E7B2 /* BooleanConstructor.cpp in Sources */,
</span><span class="cx">                                 14280864107EC11A0013E7B2 /* BooleanObject.cpp in Sources */,
</span><ins>+                                ADB6F67D1E15D7600082F384 /* WasmPageCount.cpp in Sources */,
</ins><span class="cx">                                 14280865107EC11A0013E7B2 /* BooleanPrototype.cpp in Sources */,
</span><span class="cx">                                 DE26E9071CB5DEFB00D2BE82 /* BuiltinExecutableCreator.cpp in Sources */,
</span><span class="cx">                                 A7D801A41880D66E0026C39B /* BuiltinExecutables.cpp in Sources */,
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorejsccpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/jsc.cpp (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/jsc.cpp        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/jsc.cpp        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -2632,7 +2632,6 @@
</span><span class="cx">                 lastIndex = calleeIndex;
</span><span class="cx">             });
</span><span class="cx">     }
</span><del>-
</del><span class="cx">     std::unique_ptr&lt;Wasm::ModuleInformation&gt; moduleInformation = plan.takeModuleInformation();
</span><span class="cx">     RELEASE_ASSERT(!moduleInformation-&gt;memory);
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreruntimeJSTypeh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/runtime/JSType.h (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/runtime/JSType.h        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/runtime/JSType.h        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -93,6 +93,8 @@
</span><span class="cx">     JSMapType,
</span><span class="cx">     JSSetType,
</span><span class="cx"> 
</span><ins>+    WebAssemblyFunctionType,
+
</ins><span class="cx">     LastJSCObjectType = JSSetType,
</span><span class="cx">     MaxJSType = 0b11111111,
</span><span class="cx"> };
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmWasmB3IRGeneratorcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -155,7 +155,7 @@
</span><span class="cx">             return fail(__VA_ARGS__);             \
</span><span class="cx">     } while (0)
</span><span class="cx"> 
</span><del>-    B3IRGenerator(VM&amp;, const ModuleInformation&amp;, Procedure&amp;, WasmInternalFunction*, Vector&lt;UnlinkedWasmToWasmCall&gt;&amp;, const ImmutableFunctionIndexSpace&amp;);
</del><ins>+    B3IRGenerator(VM&amp;, const ModuleInformation&amp;, Procedure&amp;, WasmInternalFunction*, Vector&lt;UnlinkedWasmToWasmCall&gt;&amp;);
</ins><span class="cx"> 
</span><span class="cx">     PartialResult WARN_UNUSED_RETURN addArguments(const Signature*);
</span><span class="cx">     PartialResult WARN_UNUSED_RETURN addLocal(Type, uint32_t);
</span><span class="lines">@@ -205,8 +205,6 @@
</span><span class="cx"> 
</span><span class="cx">     void emitExceptionCheck(CCallHelpers&amp;, ExceptionType);
</span><span class="cx"> 
</span><del>-    void emitReloadPinnedRegisters();
-
</del><span class="cx"> private:
</span><span class="cx">     ExpressionType emitCheckAndPreparePointer(ExpressionType pointer, uint32_t offset, uint32_t sizeOfOp);
</span><span class="cx">     ExpressionType emitLoadOp(LoadOpType, Origin, ExpressionType pointer, uint32_t offset);
</span><span class="lines">@@ -219,7 +217,6 @@
</span><span class="cx">     void emitChecksForModOrDiv(B3::Opcode, ExpressionType left, ExpressionType right);
</span><span class="cx"> 
</span><span class="cx">     VM&amp; m_vm;
</span><del>-    const ImmutableFunctionIndexSpace&amp; m_functionIndexSpace;
</del><span class="cx">     const ModuleInformation&amp; m_info;
</span><span class="cx">     Procedure&amp; m_proc;
</span><span class="cx">     BasicBlock* m_currentBlock;
</span><span class="lines">@@ -231,9 +228,8 @@
</span><span class="cx">     Value* m_instanceValue;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-B3IRGenerator::B3IRGenerator(VM&amp; vm, const ModuleInformation&amp; info, Procedure&amp; procedure, WasmInternalFunction* compilation, Vector&lt;UnlinkedWasmToWasmCall&gt;&amp; unlinkedWasmToWasmCalls, const ImmutableFunctionIndexSpace&amp; functionIndexSpace)
</del><ins>+B3IRGenerator::B3IRGenerator(VM&amp; vm, const ModuleInformation&amp; info, Procedure&amp; procedure, WasmInternalFunction* compilation, Vector&lt;UnlinkedWasmToWasmCall&gt;&amp; unlinkedWasmToWasmCalls)
</ins><span class="cx">     : m_vm(vm)
</span><del>-    , m_functionIndexSpace(functionIndexSpace)
</del><span class="cx">     , m_info(info)
</span><span class="cx">     , m_proc(procedure)
</span><span class="cx">     , m_unlinkedWasmToWasmCalls(unlinkedWasmToWasmCalls)
</span><span class="lines">@@ -254,14 +250,16 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    // FIXME we don't really need to pin registers here if there's no memory. It makes wasm -&gt; wasm thunks simpler for now. https://bugs.webkit.org/show_bug.cgi?id=166623
+    const PinnedRegisterInfo&amp; pinnedRegs = PinnedRegisterInfo::get();
+    m_memoryBaseGPR = pinnedRegs.baseMemoryPointer;
+    m_proc.pinRegister(m_memoryBaseGPR);
+    ASSERT(!pinnedRegs.sizeRegisters[0].sizeOffset);
+    m_memorySizeGPR = pinnedRegs.sizeRegisters[0].sizeRegister;
+    for (const PinnedSizeRegisterInfo&amp; regInfo : pinnedRegs.sizeRegisters)
+        m_proc.pinRegister(regInfo.sizeRegister);
+
</ins><span class="cx">     if (info.hasMemory()) {
</span><del>-        m_memoryBaseGPR = info.memory.pinnedRegisters().baseMemoryPointer;
-        m_proc.pinRegister(m_memoryBaseGPR);
-        ASSERT(!info.memory.pinnedRegisters().sizeRegisters[0].sizeOffset);
-        m_memorySizeGPR = info.memory.pinnedRegisters().sizeRegisters[0].sizeRegister;
-        for (const PinnedSizeRegisterInfo&amp; regInfo : info.memory.pinnedRegisters().sizeRegisters)
-            m_proc.pinRegister(regInfo.sizeRegister);
-
</del><span class="cx">         m_proc.setWasmBoundsCheckGenerator([=] (CCallHelpers&amp; jit, GPRReg pinnedGPR, unsigned) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><span class="cx">             ASSERT_UNUSED(pinnedGPR, m_memorySizeGPR == pinnedGPR);
</span><span class="lines">@@ -275,6 +273,56 @@
</span><span class="cx">         m_currentBlock-&gt;appendNew&lt;ConstPtrValue&gt;(m_proc, Origin(), &amp;m_vm.topJSWebAssemblyInstance));
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+struct MemoryBaseAndSize {
+    Value* base;
+    Value* size;
+};
+
+static MemoryBaseAndSize getMemoryBaseAndSize(VM&amp; vm, Value* instance, Procedure&amp; proc, BasicBlock* block)
+{
+    Value* memoryObject = block-&gt;appendNew&lt;MemoryValue&gt;(proc, Load, pointerType(), Origin(), instance, JSWebAssemblyInstance::offsetOfMemory());
+
+    static_assert(sizeof(decltype(vm.topJSWebAssemblyInstance-&gt;memory()-&gt;memory()-&gt;memory())) == sizeof(void*), &quot;codegen relies on this size&quot;);
+    static_assert(sizeof(decltype(vm.topJSWebAssemblyInstance-&gt;memory()-&gt;memory()-&gt;size())) == sizeof(uint64_t), &quot;codegen relies on this size&quot;);
+    MemoryBaseAndSize result;
+    result.base = block-&gt;appendNew&lt;MemoryValue&gt;(proc, Load, pointerType(), Origin(), memoryObject, JSWebAssemblyMemory::offsetOfMemory());
+    result.size = block-&gt;appendNew&lt;MemoryValue&gt;(proc, Load, Int64, Origin(), memoryObject, JSWebAssemblyMemory::offsetOfSize());
+
+    return result;
+}
+
+static void restoreWebAssemblyGlobalState(VM&amp; vm, const MemoryInformation&amp; memory, Value* instance, Procedure&amp; proc, BasicBlock* block)
+{
+    block-&gt;appendNew&lt;MemoryValue&gt;(proc, Store, Origin(), instance, block-&gt;appendNew&lt;ConstPtrValue&gt;(proc, Origin(), &amp;vm.topJSWebAssemblyInstance));
+
+    if (!!memory) {
+        const PinnedRegisterInfo* pinnedRegs = &amp;PinnedRegisterInfo::get();
+        RegisterSet clobbers;
+        clobbers.set(pinnedRegs-&gt;baseMemoryPointer);
+        for (auto info : pinnedRegs-&gt;sizeRegisters)
+            clobbers.set(info.sizeRegister);
+
+        B3::PatchpointValue* patchpoint = block-&gt;appendNew&lt;B3::PatchpointValue&gt;(proc, B3::Void, Origin());
+        patchpoint-&gt;effects = Effects::none();
+        patchpoint-&gt;effects.writesPinned = true;
+        patchpoint-&gt;clobber(clobbers);
+
+        patchpoint-&gt;append(instance, ValueRep::SomeRegister);
+
+        patchpoint-&gt;setGenerator([pinnedRegs] (CCallHelpers&amp; jit, const B3::StackmapGenerationParams&amp; params) {
+            GPRReg baseMemory = pinnedRegs-&gt;baseMemoryPointer;
+            jit.loadPtr(CCallHelpers::Address(params[0].gpr(), JSWebAssemblyInstance::offsetOfMemory()), baseMemory);
+            const auto&amp; sizeRegs = pinnedRegs-&gt;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"> void B3IRGenerator::emitExceptionCheck(CCallHelpers&amp; jit, ExceptionType type)
</span><span class="cx"> {
</span><span class="cx">     jit.move(CCallHelpers::TrustedImm32(static_cast&lt;uint32_t&gt;(type)), GPRInfo::argumentGPR1);
</span><span class="lines">@@ -338,49 +386,6 @@
</span><span class="cx">     return { };
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void reloadPinnedRegisters(Procedure&amp; proc, BasicBlock* block, const ModuleInformation&amp; info, Value* instance)
-{
-    if (!info.hasMemory())
-        return;
-
-    const MemoryInformation* memory = &amp;info.memory;
-
-    RegisterSet clobbers;
-    clobbers.set(memory-&gt;pinnedRegisters().baseMemoryPointer);
-    for (auto info : memory-&gt;pinnedRegisters().sizeRegisters)
-        clobbers.set(info.sizeRegister);
-
-    B3::PatchpointValue* patchpoint = block-&gt;appendNew&lt;B3::PatchpointValue&gt;(proc, B3::Void, Origin());
-    patchpoint-&gt;effects = Effects::none();
-    patchpoint-&gt;effects.writesPinned = true;
-    patchpoint-&gt;clobber(clobbers);
-    patchpoint-&gt;numGPScratchRegisters = 1;
-
-    patchpoint-&gt;append(instance, ValueRep::SomeRegister);
-
-    patchpoint-&gt;setGenerator([memory] (CCallHelpers&amp; jit, const B3::StackmapGenerationParams&amp; params) {
-        AllowMacroScratchRegisterUsage allowScratch(jit);
-
-        GPRReg scratch = params.gpScratch(0);
-        jit.loadPtr(CCallHelpers::Address(params[0].gpr(), JSWebAssemblyInstance::offsetOfMemory()), scratch);
-        jit.loadPtr(CCallHelpers::Address(scratch, JSWebAssemblyMemory::offsetOfMemory()), scratch);
-        jit.loadPtr(CCallHelpers::Address(scratch, Memory::offsetOfMemory()), memory-&gt;pinnedRegisters().baseMemoryPointer);
-
-        jit.load64(CCallHelpers::Address(scratch, Memory::offsetOfSize()), scratch);
-        for (unsigned i = 0; i &lt; memory-&gt;pinnedRegisters().sizeRegisters.size(); i++) {
-            GPRReg sizeReg = memory-&gt;pinnedRegisters().sizeRegisters[i].sizeRegister;
-            jit.move(scratch, sizeReg);
-            jit.sub64(CCallHelpers::TrustedImm32(memory-&gt;pinnedRegisters().sizeRegisters[i].sizeOffset), sizeReg);
-        }
-    });
-}
-
-void B3IRGenerator::emitReloadPinnedRegisters()
-{
-    reloadPinnedRegisters(m_proc, m_currentBlock, m_info, m_instanceValue);
-}
-
-
</del><span class="cx"> auto B3IRGenerator::addGrowMemory(ExpressionType delta, ExpressionType&amp; result) -&gt; PartialResult
</span><span class="cx"> {
</span><span class="cx">     int32_t (*growMemory) (ExecState*, int32_t) = [] (ExecState* exec, int32_t delta) -&gt; int32_t {
</span><span class="lines">@@ -389,7 +394,6 @@
</span><span class="cx"> 
</span><span class="cx">         JSWebAssemblyInstance* instance = vm.topJSWebAssemblyInstance;
</span><span class="cx">         JSWebAssemblyMemory* wasmMemory = instance-&gt;memory();
</span><del>-        RELEASE_ASSERT(wasmMemory); // This would fail validation otherwise.
</del><span class="cx"> 
</span><span class="cx">         if (delta &lt; 0)
</span><span class="cx">             return -1;
</span><span class="lines">@@ -407,7 +411,7 @@
</span><span class="cx">         m_currentBlock-&gt;appendNew&lt;ConstPtrValue&gt;(m_proc, Origin(), bitwise_cast&lt;void*&gt;(growMemory)),
</span><span class="cx">         m_currentBlock-&gt;appendNew&lt;B3::Value&gt;(m_proc, B3::FramePointer, Origin()), delta);
</span><span class="cx"> 
</span><del>-    emitReloadPinnedRegisters();
</del><ins>+    restoreWebAssemblyGlobalState(m_vm, m_info.memory, m_instanceValue, m_proc, m_currentBlock);
</ins><span class="cx"> 
</span><span class="cx">     return { };
</span><span class="cx"> }
</span><span class="lines">@@ -414,14 +418,12 @@
</span><span class="cx"> 
</span><span class="cx"> auto B3IRGenerator::addCurrentMemory(ExpressionType&amp; result) -&gt; PartialResult
</span><span class="cx"> {
</span><del>-    Value* jsMemory = m_currentBlock-&gt;appendNew&lt;MemoryValue&gt;(m_proc, Load, pointerType(), Origin(), m_instanceValue, JSWebAssemblyInstance::offsetOfMemory());
-    Value* wasmMemory = m_currentBlock-&gt;appendNew&lt;MemoryValue&gt;(m_proc, Load, pointerType(), Origin(), jsMemory, JSWebAssemblyMemory::offsetOfMemory());
-    Value* size = m_currentBlock-&gt;appendNew&lt;MemoryValue&gt;(m_proc, Load, B3::Int64, Origin(), wasmMemory, Memory::offsetOfSize());
</del><ins>+    auto memoryValue = getMemoryBaseAndSize(m_vm, m_instanceValue, m_proc, m_currentBlock);
</ins><span class="cx"> 
</span><span class="cx">     constexpr uint32_t shiftValue = 16;
</span><span class="cx">     static_assert(PageCount::pageSize == 1 &lt;&lt; shiftValue, &quot;This must hold for the code below to be correct.&quot;);
</span><span class="cx">     Value* numPages = m_currentBlock-&gt;appendNew&lt;Value&gt;(m_proc, ZShr, Origin(),
</span><del>-        size, m_currentBlock-&gt;appendNew&lt;Const32Value&gt;(m_proc, Origin(), shiftValue));
</del><ins>+        memoryValue.size, m_currentBlock-&gt;appendNew&lt;Const32Value&gt;(m_proc, Origin(), shiftValue));
</ins><span class="cx"> 
</span><span class="cx">     result = m_currentBlock-&gt;appendNew&lt;Value&gt;(m_proc, Trunc, Origin(), numPages);
</span><span class="cx"> 
</span><span class="lines">@@ -832,27 +834,76 @@
</span><span class="cx">     ASSERT(signature-&gt;argumentCount() == args.size());
</span><span class="cx"> 
</span><span class="cx">     Type returnType = signature-&gt;returnType();
</span><ins>+    Vector&lt;UnlinkedWasmToWasmCall&gt;* unlinkedWasmToWasmCalls = &amp;m_unlinkedWasmToWasmCalls;
</ins><span class="cx"> 
</span><del>-    result = wasmCallingConvention().setupCall(m_proc, m_currentBlock, Origin(), args, toB3Type(returnType),
-        [&amp;] (PatchpointValue* patchpoint) {
-            patchpoint-&gt;effects.writesPinned = true;
-            patchpoint-&gt;effects.readsPinned = true;
</del><ins>+    if (m_info.isImportedFunctionFromFunctionIndexSpace(functionIndex)) {
+        // FIXME imports can be linked here, instead of generating a patchpoint, because all import stubs are generated before B3 compilation starts. https://bugs.webkit.org/show_bug.cgi?id=166462
+        Value* functionImport = m_currentBlock-&gt;appendNew&lt;MemoryValue&gt;(m_proc, Load, pointerType(), Origin(), m_instanceValue, JSWebAssemblyInstance::offsetOfImportFunction(functionIndex));
+        Value* jsTypeOfImport = m_currentBlock-&gt;appendNew&lt;MemoryValue&gt;(m_proc, Load8Z, Origin(), functionImport, JSCell::typeInfoTypeOffset());
+        Value* isWasmCall = m_currentBlock-&gt;appendNew&lt;Value&gt;(m_proc, Equal, Origin(), jsTypeOfImport, m_currentBlock-&gt;appendNew&lt;Const32Value&gt;(m_proc, Origin(), WebAssemblyFunctionType));
</ins><span class="cx"> 
</span><del>-            Vector&lt;UnlinkedWasmToWasmCall&gt;* unlinkedWasmToWasmCalls = &amp;m_unlinkedWasmToWasmCalls;
-            patchpoint-&gt;setGenerator([unlinkedWasmToWasmCalls, functionIndex] (CCallHelpers&amp; jit, const B3::StackmapGenerationParams&amp;) {
-                AllowMacroScratchRegisterUsage allowScratch(jit);
</del><ins>+        BasicBlock* isWasmBlock = m_proc.addBlock();
+        BasicBlock* isJSBlock = m_proc.addBlock();
+        BasicBlock* continuation = m_proc.addBlock();
+        m_currentBlock-&gt;appendNewControlValue(m_proc, B3::Branch, Origin(), isWasmCall, FrequentedBlock(isWasmBlock), FrequentedBlock(isJSBlock));
</ins><span class="cx"> 
</span><del>-                CCallHelpers::Call call = jit.call();
</del><ins>+        Value* wasmCallResult = wasmCallingConvention().setupCall(m_proc, isWasmBlock, Origin(), args, toB3Type(returnType),
+            [&amp;] (PatchpointValue* patchpoint) {
+                patchpoint-&gt;effects.writesPinned = true;
+                patchpoint-&gt;effects.readsPinned = true;
+                patchpoint-&gt;setGenerator([unlinkedWasmToWasmCalls, functionIndex] (CCallHelpers&amp; jit, const B3::StackmapGenerationParams&amp;) {
+                    AllowMacroScratchRegisterUsage allowScratch(jit);
+                    CCallHelpers::Call call = jit.call();
+                    jit.addLinkTask([unlinkedWasmToWasmCalls, call, functionIndex] (LinkBuffer&amp; linkBuffer) {
+                        unlinkedWasmToWasmCalls-&gt;append({ linkBuffer.locationOf(call), functionIndex, UnlinkedWasmToWasmCall::Target::ToWasm });
+                    });
+                });
+            });
+        UpsilonValue* wasmCallResultUpsilon = returnType == Void ? nullptr : isWasmBlock-&gt;appendNew&lt;UpsilonValue&gt;(m_proc, Origin(), wasmCallResult);
+        isWasmBlock-&gt;appendNewControlValue(m_proc, Jump, Origin(), continuation);
</ins><span class="cx"> 
</span><del>-                jit.addLinkTask([unlinkedWasmToWasmCalls, call, functionIndex] (LinkBuffer&amp; linkBuffer) {
-                    unlinkedWasmToWasmCalls-&gt;append({ linkBuffer.locationOf(call), functionIndex });
</del><ins>+        Value* jsCallResult = wasmCallingConvention().setupCall(m_proc, isJSBlock, Origin(), args, toB3Type(returnType),
+            [&amp;] (PatchpointValue* patchpoint) {
+                patchpoint-&gt;effects.writesPinned = true;
+                patchpoint-&gt;effects.readsPinned = true;
+                patchpoint-&gt;setGenerator([unlinkedWasmToWasmCalls, functionIndex] (CCallHelpers&amp; jit, const B3::StackmapGenerationParams&amp;) {
+                    AllowMacroScratchRegisterUsage allowScratch(jit);
+                    CCallHelpers::Call call = jit.call();
+                    jit.addLinkTask([unlinkedWasmToWasmCalls, call, functionIndex] (LinkBuffer&amp; linkBuffer) {
+                        unlinkedWasmToWasmCalls-&gt;append({ linkBuffer.locationOf(call), functionIndex, UnlinkedWasmToWasmCall::Target::ToJs });
+                    });
</ins><span class="cx">                 });
</span><span class="cx">             });
</span><del>-        });
</del><ins>+        UpsilonValue* jsCallResultUpsilon = returnType == Void ? nullptr : isJSBlock-&gt;appendNew&lt;UpsilonValue&gt;(m_proc, Origin(), jsCallResult);
+        isJSBlock-&gt;appendNewControlValue(m_proc, Jump, Origin(), continuation);
</ins><span class="cx"> 
</span><del>-    if (functionIndex &lt; m_info.importFunctionCount())
-        emitReloadPinnedRegisters();
</del><ins>+        m_currentBlock = continuation;
</ins><span class="cx"> 
</span><ins>+        if (returnType == Void)
+            result = nullptr;
+        else {
+            result = continuation-&gt;appendNew&lt;Value&gt;(m_proc, Phi, toB3Type(returnType), Origin());
+            wasmCallResultUpsilon-&gt;setPhi(result);
+            jsCallResultUpsilon-&gt;setPhi(result);
+        }
+
+        // The call could have been to another WebAssembly instance, and / or could have modified our Memory.
+        restoreWebAssemblyGlobalState(m_vm, m_info.memory, m_instanceValue, m_proc, continuation);
+    } else {
+        result = wasmCallingConvention().setupCall(m_proc, m_currentBlock, Origin(), args, toB3Type(returnType),
+            [&amp;] (PatchpointValue* patchpoint) {
+                patchpoint-&gt;effects.writesPinned = true;
+                patchpoint-&gt;effects.readsPinned = true;
+                patchpoint-&gt;setGenerator([unlinkedWasmToWasmCalls, functionIndex] (CCallHelpers&amp; jit, const B3::StackmapGenerationParams&amp;) {
+                    AllowMacroScratchRegisterUsage allowScratch(jit);
+                    CCallHelpers::Call call = jit.call();
+                    jit.addLinkTask([unlinkedWasmToWasmCalls, call, functionIndex] (LinkBuffer&amp; linkBuffer) {
+                        unlinkedWasmToWasmCalls-&gt;append({ linkBuffer.locationOf(call), functionIndex, UnlinkedWasmToWasmCall::Target::ToWasm });
+                    });
+                });
+            });
+    }
+
</ins><span class="cx">     return { };
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -929,7 +980,8 @@
</span><span class="cx">             });
</span><span class="cx">         });
</span><span class="cx"> 
</span><del>-    emitReloadPinnedRegisters();
</del><ins>+    // The call could have been to another WebAssembly instance, and / or could have modified our Memory.
+    restoreWebAssemblyGlobalState(m_vm, m_info.memory, m_instanceValue, m_proc, m_currentBlock);
</ins><span class="cx"> 
</span><span class="cx">     return { };
</span><span class="cx"> }
</span><span class="lines">@@ -998,12 +1050,10 @@
</span><span class="cx">         });
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // Move memory values to the approriate places, if needed.
-    {
-        Value* instance = block-&gt;appendNew&lt;MemoryValue&gt;(proc, Load, pointerType(), Origin(),
-            block-&gt;appendNew&lt;ConstPtrValue&gt;(proc, Origin(), &amp;vm.topJSWebAssemblyInstance));
-        reloadPinnedRegisters(proc, block, info, instance);
-    }
</del><ins>+    // 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);
</ins><span class="cx"> 
</span><span class="cx">     // Get our arguments.
</span><span class="cx">     Vector&lt;Value*&gt; arguments;
</span><span class="lines">@@ -1046,7 +1096,7 @@
</span><span class="cx">     function.jsToWasmEntrypoint.calleeSaveRegisters = proc.calleeSaveRegisters();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-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 ImmutableFunctionIndexSpace&amp; functionIndexSpace, const ModuleInformation&amp; info, unsigned optLevel)
</del><ins>+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)
</ins><span class="cx"> {
</span><span class="cx">     auto result = std::make_unique&lt;WasmInternalFunction&gt;();
</span><span class="cx"> 
</span><span class="lines">@@ -1054,8 +1104,8 @@
</span><span class="cx">     compilationContext.wasmEntrypointJIT = std::make_unique&lt;CCallHelpers&gt;(&amp;vm);
</span><span class="cx"> 
</span><span class="cx">     Procedure procedure;
</span><del>-    B3IRGenerator context(vm, info, procedure, result.get(), unlinkedWasmToWasmCalls, functionIndexSpace);
-    FunctionParser&lt;B3IRGenerator&gt; parser(&amp;vm, context, functionStart, functionLength, signature, functionIndexSpace, info);
</del><ins>+    B3IRGenerator context(vm, info, procedure, result.get(), unlinkedWasmToWasmCalls);
+    FunctionParser&lt;B3IRGenerator&gt; parser(&amp;vm, context, functionStart, functionLength, signature, info, moduleSignatureIndicesToUniquedSignatureIndices);
</ins><span class="cx">     WASM_FAIL_IF_HELPER_FAILS(parser.parse());
</span><span class="cx"> 
</span><span class="cx">     procedure.resetReachability();
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmWasmB3IRGeneratorh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmB3IRGenerator.h (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmB3IRGenerator.h        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmB3IRGenerator.h        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -47,7 +47,7 @@
</span><span class="cx">     CCallHelpers::Call jsEntrypointToWasmEntrypointCall;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-Expected&lt;std::unique_ptr&lt;WasmInternalFunction&gt;, String&gt; parseAndCompile(VM&amp;, CompilationContext&amp;, const uint8_t*, size_t, const Signature*, Vector&lt;UnlinkedWasmToWasmCall&gt;&amp;, const ImmutableFunctionIndexSpace&amp;, const ModuleInformation&amp;, unsigned optLevel = 1);
</del><ins>+Expected&lt;std::unique_ptr&lt;WasmInternalFunction&gt;, String&gt; parseAndCompile(VM&amp;, CompilationContext&amp;, const uint8_t*, size_t, const Signature*, Vector&lt;UnlinkedWasmToWasmCall&gt;&amp;, const ModuleInformation&amp;, const Vector&lt;SignatureIndex&gt;&amp;, unsigned optLevel = 1);
</ins><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::Wasm
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmWasmBindingcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmBinding.cpp (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmBinding.cpp        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmBinding.cpp        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -36,13 +36,21 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace Wasm {
</span><span class="cx"> 
</span><del>-WasmToJSStub importStubGenerator(VM* vm, Bag&lt;CallLinkInfo&gt;&amp; callLinkInfos, SignatureIndex signatureIndex, unsigned importIndex)
</del><ins>+typedef AssemblyHelpers JIT;
+
+static void materializeImportJSCell(VM* vm, JIT&amp; jit, unsigned importIndex, GPRReg result)
</ins><span class="cx"> {
</span><ins>+    // We're calling out of the current WebAssembly.Instance, which is identified on VM. That Instance has a list of all its import functions.
+    jit.loadPtr(&amp;vm-&gt;topJSWebAssemblyInstance, result);
+    jit.loadPtr(JIT::Address(result, JSWebAssemblyInstance::offsetOfImportFunction(importIndex)), result);
+}
+
+static MacroAssemblerCodeRef wasmToJs(VM* vm, Bag&lt;CallLinkInfo&gt;&amp; callLinkInfos, SignatureIndex signatureIndex, unsigned importIndex)
+{
</ins><span class="cx">     const WasmCallingConvention&amp; wasmCC = wasmCallingConvention();
</span><span class="cx">     const JSCCallingConvention&amp; jsCC = jscCallingConvention();
</span><span class="cx">     const Signature* signature = SignatureInformation::get(vm, signatureIndex);
</span><span class="cx">     unsigned argCount = signature-&gt;argumentCount();
</span><del>-    typedef AssemblyHelpers JIT;
</del><span class="cx">     JIT jit(vm, nullptr);
</span><span class="cx"> 
</span><span class="cx">     // Below, we assume that the JS calling convention is always on the stack.
</span><span class="lines">@@ -210,9 +218,7 @@
</span><span class="cx">     GPRReg importJSCellGPRReg = GPRInfo::regT0; // Callee needs to be in regT0 for slow path below.
</span><span class="cx">     ASSERT(!wasmCC.m_calleeSaveRegisters.get(importJSCellGPRReg));
</span><span class="cx"> 
</span><del>-    // Each JS -&gt; wasm entry sets the WebAssembly.Instance whose export is being called. We're calling out of this Instance, and can therefore figure out the import being called.
-    jit.loadPtr(&amp;vm-&gt;topJSWebAssemblyInstance, importJSCellGPRReg);
-    jit.loadPtr(JIT::Address(importJSCellGPRReg, JSWebAssemblyInstance::offsetOfImportFunction(importIndex)), importJSCellGPRReg);
</del><ins>+    materializeImportJSCell(vm, jit, importIndex, importJSCellGPRReg);
</ins><span class="cx"> 
</span><span class="cx">     uint64_t thisArgument = ValueUndefined; // FIXME what does the WebAssembly spec say this should be? https://bugs.webkit.org/show_bug.cgi?id=165471
</span><span class="cx">     jit.store64(importJSCellGPRReg, calleeFrame.withOffset(CallFrameSlot::callee * static_cast&lt;int&gt;(sizeof(Register))));
</span><span class="lines">@@ -303,9 +309,58 @@
</span><span class="cx">     CodeLocationLabel hotPathBegin(patchBuffer.locationOf(targetToCheck));
</span><span class="cx">     CodeLocationNearCall hotPathOther = patchBuffer.locationOfNearCall(fastCall);
</span><span class="cx">     callLinkInfo-&gt;setCallLocations(callReturnLocation, hotPathBegin, hotPathOther);
</span><del>-    return FINALIZE_CODE(patchBuffer, (&quot;WebAssembly import[%i] stub for signature %i&quot;, importIndex, signatureIndex));
</del><ins>+    String signatureDescription = SignatureInformation::get(vm, signatureIndex)-&gt;toString();
+    return FINALIZE_CODE(patchBuffer, (&quot;WebAssembly-&gt;JavaScript import[%i] %s&quot;, importIndex, signatureDescription.ascii().data()));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static MacroAssemblerCodeRef wasmToWasm(VM* vm, unsigned importIndex)
+{
+    const PinnedRegisterInfo&amp; pinnedRegs = PinnedRegisterInfo::get();
+    JIT jit(vm, nullptr);
+
+    GPRReg scratch = GPRInfo::nonPreservedNonArgumentGPR;
+
+    // B3's call codegen ensures that the JSCell is a WebAssemblyFunction.
+    materializeImportJSCell(vm, jit, importIndex, scratch);
+
+    // Get the callee's WebAssembly.Instance and set it as vm.topJSWebAssemblyInstance. The caller will take care of restoring its own Instance.
+    GPRReg baseMemory = pinnedRegs.baseMemoryPointer;
+    ASSERT(baseMemory != scratch);
+    jit.loadPtr(JIT::Address(scratch, WebAssemblyFunction::offsetOfInstance()), baseMemory); // Instance*.
+    jit.storePtr(baseMemory, &amp;vm-&gt;topJSWebAssemblyInstance);
+
+    // FIXME the following code assumes that all WebAssembly.Instance have the same pinned registers. https://bugs.webkit.org/show_bug.cgi?id=162952
+    // Set up the callee's baseMemory register as well as the memory size registers.
+    jit.loadPtr(JIT::Address(baseMemory, JSWebAssemblyInstance::offsetOfMemory()), baseMemory); // JSWebAssemblyMemory*.
+    const auto&amp; sizeRegs = pinnedRegs.sizeRegisters;
+    ASSERT(sizeRegs.size() &gt;= 1);
+    ASSERT(sizeRegs[0].sizeRegister != baseMemory);
+    ASSERT(sizeRegs[0].sizeRegister != scratch);
+    ASSERT(!sizeRegs[0].sizeOffset); // The following code assumes we start at 0, and calculates subsequent size registers relative to 0.
+    jit.loadPtr(JIT::Address(baseMemory, JSWebAssemblyMemory::offsetOfSize()), sizeRegs[0].sizeRegister); // Memory size.
+    jit.loadPtr(JIT::Address(baseMemory, JSWebAssemblyMemory::offsetOfMemory()), baseMemory); // WasmMemory::void*.
+    for (unsigned i = 1; i &lt; sizeRegs.size(); ++i) {
+        ASSERT(sizeRegs[i].sizeRegister != baseMemory);
+        ASSERT(sizeRegs[i].sizeRegister != scratch);
+        jit.add64(JIT::TrustedImm32(-sizeRegs[i].sizeOffset), sizeRegs[0].sizeRegister, sizeRegs[i].sizeRegister);
+    }
+
+    // Tail call into the callee WebAssembly function.
+    jit.loadPtr(JIT::Address(scratch, WebAssemblyFunction::offsetOfWasmEntryPointCode()), scratch);
+    jit.jump(scratch);
+
+    LinkBuffer patchBuffer(*vm, jit, GLOBAL_THUNK_ID);
+    return FINALIZE_CODE(patchBuffer, (&quot;WebAssembly-&gt;WebAssembly import[%i]&quot;, importIndex));
+}
+
+WasmExitStubs exitStubGenerator(VM* vm, Bag&lt;CallLinkInfo&gt;&amp; callLinkInfos, SignatureIndex signatureIndex, unsigned importIndex)
+{
+    WasmExitStubs stubs;
+    stubs.wasmToJs = wasmToJs(vm, callLinkInfos, signatureIndex, importIndex);
+    stubs.wasmToWasm = wasmToWasm(vm, importIndex);
+    return stubs;
+}
+
</ins><span class="cx"> } } // namespace JSC::Wasm
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(WEBASSEMBLY)
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmWasmBindingh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmBinding.h (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmBinding.h        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmBinding.h        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -38,7 +38,7 @@
</span><span class="cx"> 
</span><span class="cx"> namespace Wasm {
</span><span class="cx"> 
</span><del>-WasmToJSStub importStubGenerator(VM*, Bag&lt;CallLinkInfo&gt;&amp;, SignatureIndex, unsigned);
</del><ins>+WasmExitStubs exitStubGenerator(VM*, Bag&lt;CallLinkInfo&gt;&amp;, SignatureIndex, unsigned);
</ins><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::Wasm
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmWasmFormath"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmFormat.h (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmFormat.h        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmFormat.h        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -222,7 +222,6 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> struct ModuleInformation {
</span><del>-    Vector&lt;SignatureIndex&gt; signatureIndices;
</del><span class="cx">     Vector&lt;Import&gt; imports;
</span><span class="cx">     Vector&lt;SignatureIndex&gt; importFunctionSignatureIndices;
</span><span class="cx">     Vector&lt;SignatureIndex&gt; internalFunctionSignatureIndices;
</span><span class="lines">@@ -236,6 +235,18 @@
</span><span class="cx">     TableInformation tableInformation;
</span><span class="cx">     Vector&lt;Global&gt; globals;
</span><span class="cx">     unsigned firstInternalGlobal { 0 };
</span><ins>+    size_t functionIndexSpaceSize() const { return importFunctionSignatureIndices.size() + internalFunctionSignatureIndices.size(); }
+    bool isImportedFunctionFromFunctionIndexSpace(size_t functionIndex) const
+    {
+        ASSERT(functionIndex &lt; functionIndexSpaceSize());
+        return functionIndex &lt; importFunctionSignatureIndices.size();
+    }
+    SignatureIndex signatureIndexFromFunctionIndexSpace(size_t functionIndex) const
+    {
+        return isImportedFunctionFromFunctionIndexSpace(functionIndex)
+            ? importFunctionSignatureIndices[functionIndex]
+            : internalFunctionSignatureIndices[functionIndex - importFunctionSignatureIndices.size()];
+    }
</ins><span class="cx"> 
</span><span class="cx">     uint32_t importFunctionCount() const { return importFunctionSignatureIndices.size(); }
</span><span class="cx">     bool hasMemory() const { return !!memory; }
</span><span class="lines">@@ -246,6 +257,10 @@
</span><span class="cx"> struct UnlinkedWasmToWasmCall {
</span><span class="cx">     CodeLocationCall callLocation;
</span><span class="cx">     size_t functionIndex;
</span><ins>+    enum class Target : uint8_t {
+        ToJs,
+        ToWasm,
+    } target;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> struct Entrypoint {
</span><span class="lines">@@ -261,7 +276,10 @@
</span><span class="cx">     Entrypoint jsToWasmEntrypoint;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-typedef MacroAssemblerCodeRef WasmToJSStub;
</del><ins>+struct WasmExitStubs {
+    MacroAssemblerCodeRef wasmToJs;
+    MacroAssemblerCodeRef wasmToWasm;
+};
</ins><span class="cx"> 
</span><span class="cx"> // WebAssembly direct calls and call_indirect use indices into &quot;function index space&quot;. This space starts with all imports, and then all internal functions.
</span><span class="cx"> // CallableFunction and FunctionIndexSpace are only meant as fast lookup tables for these opcodes, and do not own code.
</span><span class="lines">@@ -280,12 +298,6 @@
</span><span class="cx"> };
</span><span class="cx"> typedef Vector&lt;CallableFunction&gt; FunctionIndexSpace;
</span><span class="cx"> 
</span><del>-
-struct ImmutableFunctionIndexSpace {
-    MallocPtr&lt;CallableFunction&gt; buffer;
-    size_t size;
-};
-
</del><span class="cx"> } } // namespace JSC::Wasm
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(WEBASSEMBLY)
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmWasmFunctionParserh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmFunctionParser.h (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmFunctionParser.h        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmFunctionParser.h        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -46,7 +46,7 @@
</span><span class="cx">     typedef typename Context::ControlType ControlType;
</span><span class="cx">     typedef typename Context::ExpressionList ExpressionList;
</span><span class="cx"> 
</span><del>-    FunctionParser(VM*, Context&amp;, const uint8_t* functionStart, size_t functionLength, const Signature*, const ImmutableFunctionIndexSpace&amp;, const ModuleInformation&amp;);
</del><ins>+    FunctionParser(VM*, Context&amp;, const uint8_t* functionStart, size_t functionLength, const Signature*, const ModuleInformation&amp;, const Vector&lt;SignatureIndex&gt;&amp;);
</ins><span class="cx"> 
</span><span class="cx">     Result WARN_UNUSED_RETURN parse();
</span><span class="cx"> 
</span><span class="lines">@@ -82,18 +82,18 @@
</span><span class="cx">     ExpressionList m_expressionStack;
</span><span class="cx">     Vector&lt;ControlEntry&gt; m_controlStack;
</span><span class="cx">     const Signature* m_signature;
</span><del>-    const ImmutableFunctionIndexSpace&amp; m_functionIndexSpace;
</del><span class="cx">     const ModuleInformation&amp; m_info;
</span><ins>+    const Vector&lt;SignatureIndex&gt;&amp; m_moduleSignatureIndicesToUniquedSignatureIndices;
</ins><span class="cx">     unsigned m_unreachableBlocks { 0 };
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename Context&gt;
</span><del>-FunctionParser&lt;Context&gt;::FunctionParser(VM* vm, Context&amp; context, const uint8_t* functionStart, size_t functionLength, const Signature* signature, const ImmutableFunctionIndexSpace&amp; functionIndexSpace, const ModuleInformation&amp; info)
</del><ins>+FunctionParser&lt;Context&gt;::FunctionParser(VM* vm, Context&amp; context, const uint8_t* functionStart, size_t functionLength, const Signature* signature, const ModuleInformation&amp; info, const Vector&lt;SignatureIndex&gt;&amp; moduleSignatureIndicesToUniquedSignatureIndices)
</ins><span class="cx">     : Parser(vm, functionStart, functionLength)
</span><span class="cx">     , m_context(context)
</span><span class="cx">     , m_signature(signature)
</span><del>-    , m_functionIndexSpace(functionIndexSpace)
</del><span class="cx">     , m_info(info)
</span><ins>+    , m_moduleSignatureIndicesToUniquedSignatureIndices(moduleSignatureIndicesToUniquedSignatureIndices)
</ins><span class="cx"> {
</span><span class="cx">     if (verbose)
</span><span class="cx">         dataLogLn(&quot;Parsing function starting at: &quot;, (uintptr_t)functionStart, &quot; of length: &quot;, functionLength);
</span><span class="lines">@@ -308,9 +308,9 @@
</span><span class="cx">     case Call: {
</span><span class="cx">         uint32_t functionIndex;
</span><span class="cx">         WASM_PARSER_FAIL_IF(!parseVarUInt32(functionIndex), &quot;can't parse call's function index&quot;);
</span><del>-        WASM_PARSER_FAIL_IF(functionIndex &gt;= m_functionIndexSpace.size, &quot;call function index &quot;, functionIndex, &quot; exceeds function index space &quot;, m_functionIndexSpace.size);
</del><ins>+        WASM_PARSER_FAIL_IF(functionIndex &gt;= m_info.functionIndexSpaceSize(), &quot;call function index &quot;, functionIndex, &quot; exceeds function index space &quot;, m_info.functionIndexSpaceSize());
</ins><span class="cx"> 
</span><del>-        SignatureIndex calleeSignatureIndex = m_functionIndexSpace.buffer.get()[functionIndex].signatureIndex;
</del><ins>+        SignatureIndex calleeSignatureIndex = m_info.signatureIndexFromFunctionIndexSpace(functionIndex);
</ins><span class="cx">         const Signature* calleeSignature = SignatureInformation::get(m_vm, calleeSignatureIndex);
</span><span class="cx">         WASM_PARSER_FAIL_IF(calleeSignature-&gt;argumentCount() &gt; m_expressionStack.size(), &quot;call function index &quot;, functionIndex, &quot; has &quot;, calleeSignature-&gt;argumentCount(), &quot; arguments, but the expression stack currently holds &quot;, m_expressionStack.size(), &quot; values&quot;);
</span><span class="cx"> 
</span><span class="lines">@@ -337,9 +337,9 @@
</span><span class="cx">         WASM_PARSER_FAIL_IF(!parseVarUInt32(signatureIndex), &quot;can't get call_indirect's signature index&quot;);
</span><span class="cx">         WASM_PARSER_FAIL_IF(!parseVarUInt1(reserved), &quot;can't get call_indirect's reserved byte&quot;);
</span><span class="cx">         WASM_PARSER_FAIL_IF(reserved, &quot;call_indirect's 'reserved' varuint1 must be 0x0&quot;);
</span><del>-        WASM_PARSER_FAIL_IF(m_info.signatureIndices.size() &lt;= signatureIndex, &quot;call_indirect's signature index &quot;, signatureIndex, &quot; exceeds known signatures &quot;, m_info.signatureIndices.size());
</del><ins>+        WASM_PARSER_FAIL_IF(m_moduleSignatureIndicesToUniquedSignatureIndices.size() &lt;= signatureIndex, &quot;call_indirect's signature index &quot;, signatureIndex, &quot; exceeds known signatures &quot;, m_moduleSignatureIndicesToUniquedSignatureIndices.size());
</ins><span class="cx"> 
</span><del>-        SignatureIndex calleeSignatureIndex = m_info.signatureIndices[signatureIndex];
</del><ins>+        SignatureIndex calleeSignatureIndex = m_moduleSignatureIndicesToUniquedSignatureIndices[signatureIndex];
</ins><span class="cx">         const Signature* calleeSignature = SignatureInformation::get(m_vm, calleeSignatureIndex);
</span><span class="cx">         size_t argumentCount = calleeSignature-&gt;argumentCount() + 1; // Add the callee's index.
</span><span class="cx">         WASM_PARSER_FAIL_IF(argumentCount &gt; m_expressionStack.size(), &quot;call_indirect expects &quot;, argumentCount, &quot; arguments, but the expression stack currently holds &quot;, m_expressionStack.size(), &quot; values&quot;);
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmWasmMemorycpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmMemory.cpp (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmMemory.cpp        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmMemory.cpp        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -28,15 +28,39 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(WEBASSEMBLY)
</span><span class="cx"> 
</span><ins>+#include &lt;wtf/HexNumber.h&gt;
+#include &lt;wtf/PrintStream.h&gt;
+#include &lt;wtf/text/WTFString.h&gt;
+
</ins><span class="cx"> namespace JSC { namespace Wasm {
</span><span class="cx"> 
</span><ins>+namespace {
+const bool verbose = false;
+}
+
+void Memory::dump(PrintStream&amp; out) const
+{
+    String memoryHex;
+    WTF::appendUnsigned64AsHex((uint64_t)(uintptr_t)m_memory, memoryHex);
+    out.print(&quot;Memory at 0x&quot;, memoryHex, &quot;, size &quot;, m_size, &quot;B capacity &quot;, m_mappedCapacity, &quot;B, initial &quot;, m_initial, &quot; maximum &quot;, m_maximum, &quot; mode &quot;, makeString(m_mode));
+}
+
+const char* Memory::makeString(Mode mode) const
+{
+    switch (mode) {
+    case Mode::BoundsChecking: return &quot;BoundsChecking&quot;;
+    }
+    RELEASE_ASSERT_NOT_REACHED();
+    return &quot;&quot;;
+}
+
</ins><span class="cx"> static_assert(sizeof(uint64_t) == sizeof(size_t), &quot;We rely on allowing the maximum size of Memory we map to be 2^32 which is larger than fits in a 32-bit integer that we'd pass to mprotect if this didn't hold.&quot;);
</span><span class="cx"> 
</span><span class="cx"> Memory::Memory(PageCount initial, PageCount maximum, bool&amp; failed)
</span><del>-    : m_mode(Mode::BoundsChecking)
</del><ins>+    : m_size(initial.bytes())
</ins><span class="cx">     , m_initial(initial)
</span><span class="cx">     , m_maximum(maximum)
</span><del>-    , m_size(initial.bytes())
</del><ins>+    , m_mode(Mode::BoundsChecking)
</ins><span class="cx">     // FIXME: If we add signal based bounds checking then we need extra space for overflow on load.
</span><span class="cx">     // see: https://bugs.webkit.org/show_bug.cgi?id=162693
</span><span class="cx"> {
</span><span class="lines">@@ -46,9 +70,11 @@
</span><span class="cx">     if (!m_mappedCapacity) {
</span><span class="cx">         // This means we specified a zero as maximum (which means we also have zero as initial size).
</span><span class="cx">         RELEASE_ASSERT(m_size == 0);
</span><ins>+        m_memory = nullptr;
</ins><span class="cx">         m_mappedCapacity = 0;
</span><del>-        m_memory = nullptr;
</del><span class="cx">         failed = false;
</span><ins>+        if (verbose)
+            dataLogLn(&quot;Memory::Memory allocating nothing &quot;, *this);
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -56,15 +82,21 @@
</span><span class="cx">     void* result = Options::simulateWebAssemblyLowMemory() ? MAP_FAILED : mmap(nullptr, m_mappedCapacity, PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0);
</span><span class="cx">     if (result == MAP_FAILED) {
</span><span class="cx">         // Try again with a different number.
</span><ins>+        if (verbose)
+            dataLogLn(&quot;Memory::Memory mmap failed once for capacity, trying again&quot;, *this);
</ins><span class="cx">         m_mappedCapacity = m_size;
</span><span class="cx">         if (!m_mappedCapacity) {
</span><span class="cx">             m_memory = nullptr;
</span><span class="cx">             failed = false;
</span><ins>+            if (verbose)
+                dataLogLn(&quot;Memory::Memory mmap not trying again because size is zero &quot;, *this);
</ins><span class="cx">             return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         result = mmap(nullptr, m_mappedCapacity, PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0);
</span><span class="cx">         if (result == MAP_FAILED) {
</span><ins>+            if (verbose)
+                dataLogLn(&quot;Memory::Memory mmap failed twice &quot;, *this);
</ins><span class="cx">             failed = true;
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="lines">@@ -78,12 +110,27 @@
</span><span class="cx"> 
</span><span class="cx">     m_memory = result;
</span><span class="cx">     failed = false;
</span><ins>+    if (verbose)
+        dataLogLn(&quot;Memory::Memory mmap succeeded &quot;, *this);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+Memory::~Memory()
+{
+    if (verbose)
+        dataLogLn(&quot;Memory::~Memory &quot;, *this);
+    if (m_memory) {
+        if (munmap(m_memory, m_mappedCapacity))
+            CRASH();
+    }
+}
+
</ins><span class="cx"> bool Memory::grow(PageCount newSize)
</span><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT(newSize &gt; PageCount::fromBytes(m_size));
</span><span class="cx"> 
</span><ins>+    if (verbose)
+        dataLogLn(&quot;Memory::grow to &quot;, newSize, &quot; from &quot;, *this);
+
</ins><span class="cx">     if (maximum() &amp;&amp; newSize &gt; maximum())
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="lines">@@ -93,6 +140,8 @@
</span><span class="cx">         bool success = !mprotect(static_cast&lt;uint8_t*&gt;(m_memory) + m_size, static_cast&lt;size_t&gt;(desiredSize - m_size), PROT_READ | PROT_WRITE);
</span><span class="cx">         RELEASE_ASSERT(success);
</span><span class="cx">         m_size = desiredSize;
</span><ins>+        if (verbose)
+            dataLogLn(&quot;Memory::grow in-place &quot;, *this);
</ins><span class="cx">         return true;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -110,6 +159,8 @@
</span><span class="cx">     m_mappedCapacity = desiredSize;
</span><span class="cx">     m_size = desiredSize;
</span><span class="cx"> 
</span><ins>+    if (verbose)
+        dataLogLn(&quot;Memory::grow &quot;, *this);
</ins><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmWasmMemoryh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmMemory.h (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmMemory.h        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmMemory.h        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -30,7 +30,9 @@
</span><span class="cx"> #include &quot;WasmCallingConvention.h&quot;
</span><span class="cx"> #include &quot;WasmPageCount.h&quot;
</span><span class="cx"> 
</span><del>-#include &lt;wtf/Vector.h&gt;
</del><ins>+namespace WTF {
+class PrintStream;
+}
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace Wasm {
</span><span class="cx"> 
</span><span class="lines">@@ -38,41 +40,50 @@
</span><span class="cx">     WTF_MAKE_NONCOPYABLE(Memory);
</span><span class="cx">     WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx"> public:
</span><ins>+    void dump(WTF::PrintStream&amp;) const;
</ins><span class="cx"> 
</span><span class="cx">     // FIXME: We should support other modes. see: https://bugs.webkit.org/show_bug.cgi?id=162693
</span><span class="cx">     enum class Mode {
</span><span class="cx">         BoundsChecking
</span><span class="cx">     };
</span><ins>+    const char* makeString(Mode) const;
</ins><span class="cx"> 
</span><ins>+    Memory() = default;
</ins><span class="cx">     JS_EXPORT_PRIVATE Memory(PageCount initial, PageCount maximum, bool&amp; failed);
</span><del>-
-    ~Memory()
</del><ins>+    Memory(Memory&amp;&amp; other)
+        : m_memory(other.m_memory)
+        , m_size(other.m_size)
+        , m_initial(other.m_initial)
+        , m_maximum(other.m_maximum)
+        , m_mappedCapacity(other.m_mappedCapacity)
+        , m_mode(other.m_mode)
</ins><span class="cx">     {
</span><del>-        if (m_memory)
-            munmap(m_memory, m_mappedCapacity);
</del><ins>+        // Moving transfers ownership of the allocated memory.
+        other.m_memory = nullptr;
</ins><span class="cx">     }
</span><ins>+    ~Memory();
</ins><span class="cx"> 
</span><span class="cx">     void* memory() const { return m_memory; }
</span><span class="cx">     uint64_t size() const { return m_size; }
</span><span class="cx">     PageCount sizeInPages() const { return PageCount::fromBytes(m_size); }
</span><span class="cx"> 
</span><del>-    Mode mode() const { return m_mode; }
-
</del><span class="cx">     PageCount initial() const { return m_initial; }
</span><span class="cx">     PageCount maximum() const { return m_maximum; }
</span><span class="cx"> 
</span><ins>+    Mode mode() const { return m_mode; }
+
</ins><span class="cx">     bool grow(PageCount);
</span><span class="cx"> 
</span><ins>+    static ptrdiff_t offsetOfMemory() { return OBJECT_OFFSETOF(Memory, m_memory); }
</ins><span class="cx">     static ptrdiff_t offsetOfSize() { return OBJECT_OFFSETOF(Memory, m_size); }
</span><del>-    static ptrdiff_t offsetOfMemory() { return OBJECT_OFFSETOF(Memory, m_memory); }
</del><span class="cx">     
</span><span class="cx"> private:
</span><span class="cx">     void* m_memory { nullptr };
</span><del>-    Mode m_mode;
</del><ins>+    uint64_t m_size { 0 };
</ins><span class="cx">     PageCount m_initial;
</span><span class="cx">     PageCount m_maximum;
</span><del>-    uint64_t m_size { 0 };
</del><span class="cx">     uint64_t m_mappedCapacity { 0 };
</span><ins>+    Mode m_mode { Mode::BoundsChecking };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::Wasm
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmWasmMemoryInformationcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmMemoryInformation.cpp (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmMemoryInformation.cpp        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmMemoryInformation.cpp        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -26,13 +26,52 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;WasmMemoryInformation.h&quot;
</span><span class="cx"> 
</span><ins>+#if ENABLE(WEBASSEMBLY)
+
</ins><span class="cx"> #include &quot;WasmCallingConvention.h&quot;
</span><ins>+#include &lt;wtf/NeverDestroyed.h&gt;
</ins><span class="cx"> 
</span><del>-#if ENABLE(WEBASSEMBLY)
-
</del><span class="cx"> namespace JSC { namespace Wasm {
</span><span class="cx"> 
</span><del>-MemoryInformation::MemoryInformation(PageCount initial, PageCount maximum,  const Vector&lt;unsigned&gt;&amp; pinnedSizeRegisters, bool isImport)
</del><ins>+const PinnedRegisterInfo&amp; PinnedRegisterInfo::get()
+{
+    static LazyNeverDestroyed&lt;PinnedRegisterInfo&gt; staticPinnedRegisterInfo;
+    static std::once_flag staticPinnedRegisterInfoFlag;
+    std::call_once(staticPinnedRegisterInfoFlag, [] () {
+        Vector&lt;PinnedSizeRegisterInfo&gt; sizeRegisters;
+        GPRReg baseMemoryPointer;
+
+        // FIXME: We should support more than one memory size register, and we should allow different
+        //        WebAssembly.Instance to have different pins. Right now we take a vector with only one entry.
+        //        If we have more than one size register, we can have one for each load size class.
+        //        see: https://bugs.webkit.org/show_bug.cgi?id=162952
+        Vector&lt;unsigned&gt; pinnedSizes = { 0 };
+        unsigned remainingPinnedRegisters = pinnedSizes.size() + 1;
+        jscCallingConvention().m_calleeSaveRegisters.forEach([&amp;] (Reg reg) {
+            GPRReg gpr = reg.gpr();
+            if (!remainingPinnedRegisters || RegisterSet::stackRegisters().get(reg))
+                return;
+            if (remainingPinnedRegisters == 1) {
+                baseMemoryPointer = gpr;
+                remainingPinnedRegisters--;
+            } else
+                sizeRegisters.append({ gpr, pinnedSizes[--remainingPinnedRegisters - 1] });
+        });
+
+        ASSERT(!remainingPinnedRegisters);
+        staticPinnedRegisterInfo.construct(WTFMove(sizeRegisters), baseMemoryPointer);
+    });
+
+    return staticPinnedRegisterInfo.get();
+}
+
+PinnedRegisterInfo::PinnedRegisterInfo(Vector&lt;PinnedSizeRegisterInfo&gt;&amp;&amp; sizeRegisters, GPRReg baseMemoryPointer)
+    : sizeRegisters(WTFMove(sizeRegisters))
+    , baseMemoryPointer(baseMemoryPointer)
+{
+}
+
+MemoryInformation::MemoryInformation(PageCount initial, PageCount maximum,  bool isImport)
</ins><span class="cx">     : m_initial(initial)
</span><span class="cx">     , m_maximum(maximum)
</span><span class="cx">     , m_isImport(isImport)
</span><span class="lines">@@ -40,20 +79,6 @@
</span><span class="cx">     RELEASE_ASSERT(!!m_initial);
</span><span class="cx">     RELEASE_ASSERT(!m_maximum || m_maximum &gt;= m_initial);
</span><span class="cx">     ASSERT(!!*this);
</span><del>-
-    unsigned remainingPinnedRegisters = pinnedSizeRegisters.size() + 1;
-    jscCallingConvention().m_calleeSaveRegisters.forEach([&amp;] (Reg reg) {
-        GPRReg gpr = reg.gpr();
-        if (!remainingPinnedRegisters || RegisterSet::stackRegisters().get(reg))
-            return;
-        if (remainingPinnedRegisters == 1) {
-            m_pinnedRegisters.baseMemoryPointer = gpr;
-            remainingPinnedRegisters--;
-        } else
-            m_pinnedRegisters.sizeRegisters.append({ gpr, pinnedSizeRegisters[--remainingPinnedRegisters - 1] });
-    });
-
-    ASSERT(!remainingPinnedRegisters);
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::Wasm
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmWasmMemoryInformationh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmMemoryInformation.h (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmMemoryInformation.h        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmMemoryInformation.h        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -38,12 +38,11 @@
</span><span class="cx">     unsigned sizeOffset;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-// FIXME: We should support more than one memory size register. Right now we take a vector with only one
-// entry. Specifically an entry where the sizeOffset == 0. If we have more than one size register,
-// we can have one for each load size class. see: https://bugs.webkit.org/show_bug.cgi?id=162952
</del><span class="cx"> struct PinnedRegisterInfo {
</span><span class="cx">     Vector&lt;PinnedSizeRegisterInfo&gt; sizeRegisters;
</span><span class="cx">     GPRReg baseMemoryPointer;
</span><ins>+    static const PinnedRegisterInfo&amp; get();
+    PinnedRegisterInfo(Vector&lt;PinnedSizeRegisterInfo&gt;&amp;&amp;, GPRReg);
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class MemoryInformation {
</span><span class="lines">@@ -53,9 +52,8 @@
</span><span class="cx">         ASSERT(!*this);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    MemoryInformation(PageCount initial, PageCount maximum, const Vector&lt;unsigned&gt;&amp; pinnedSizeRegisters, bool isImport);
</del><ins>+    MemoryInformation(PageCount initial, PageCount maximum, bool isImport);
</ins><span class="cx"> 
</span><del>-    const PinnedRegisterInfo&amp; pinnedRegisters() const { return m_pinnedRegisters; }
</del><span class="cx">     PageCount initial() const { return m_initial; }
</span><span class="cx">     PageCount maximum() const { return m_maximum; }
</span><span class="cx">     bool isImport() const { return m_isImport; }
</span><span class="lines">@@ -65,7 +63,6 @@
</span><span class="cx"> private:
</span><span class="cx">     PageCount m_initial { };
</span><span class="cx">     PageCount m_maximum { };
</span><del>-    PinnedRegisterInfo m_pinnedRegisters { };
</del><span class="cx">     bool m_isImport { false };
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmWasmModuleParsercpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmModuleParser.cpp (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmModuleParser.cpp        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmModuleParser.cpp        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -107,7 +107,7 @@
</span><span class="cx"> 
</span><span class="cx">     WASM_PARSER_FAIL_IF(!parseVarUInt32(count), &quot;can't get Type section's count&quot;);
</span><span class="cx">     WASM_PARSER_FAIL_IF(count == std::numeric_limits&lt;uint32_t&gt;::max(), &quot;Type section's count is too big &quot;, count);
</span><del>-    WASM_PARSER_FAIL_IF(!m_result.module-&gt;signatureIndices.tryReserveCapacity(count), &quot;can't allocate enough memory for Type section's &quot;, count, &quot; entries&quot;);
</del><ins>+    WASM_PARSER_FAIL_IF(!m_result.moduleSignatureIndicesToUniquedSignatureIndices.tryReserveCapacity(count), &quot;can't allocate enough memory for Type section's &quot;, count, &quot; entries&quot;);
</ins><span class="cx"> 
</span><span class="cx">     for (uint32_t i = 0; i &lt; count; ++i) {
</span><span class="cx">         int8_t type;
</span><span class="lines">@@ -139,7 +139,7 @@
</span><span class="cx">         signature-&gt;returnType() = returnType;
</span><span class="cx"> 
</span><span class="cx">         SignatureIndex signatureIndex = SignatureInformation::adopt(m_vm, signature.release());
</span><del>-        m_result.module-&gt;signatureIndices.uncheckedAppend(signatureIndex);
</del><ins>+        m_result.moduleSignatureIndicesToUniquedSignatureIndices.uncheckedAppend(signatureIndex);
</ins><span class="cx">     }
</span><span class="cx">     return { };
</span><span class="cx"> }
</span><span class="lines">@@ -152,7 +152,6 @@
</span><span class="cx">     WASM_PARSER_FAIL_IF(!m_result.module-&gt;globals.tryReserveCapacity(importCount), &quot;can't allocate enough memory for &quot;, importCount, &quot; globals&quot;); // FIXME this over-allocates when we fix the FIXMEs below.
</span><span class="cx">     WASM_PARSER_FAIL_IF(!m_result.module-&gt;imports.tryReserveCapacity(importCount), &quot;can't allocate enough memory for &quot;, importCount, &quot; imports&quot;); // FIXME this over-allocates when we fix the FIXMEs below.
</span><span class="cx">     WASM_PARSER_FAIL_IF(!m_result.module-&gt;importFunctionSignatureIndices.tryReserveCapacity(importCount), &quot;can't allocate enough memory for &quot;, importCount, &quot; import function signatures&quot;); // FIXME this over-allocates when we fix the FIXMEs below.
</span><del>-    WASM_PARSER_FAIL_IF(!m_result.functionIndexSpace.tryReserveCapacity(importCount), &quot;can't allocate enough memory for &quot;, importCount, &quot; functions in the index space&quot;); // FIXME this over-allocates when we fix the FIXMEs below. We'll allocate some more here when we know how many functions to expect.
</del><span class="cx"> 
</span><span class="cx">     for (uint32_t importNumber = 0; importNumber &lt; importCount; ++importNumber) {
</span><span class="cx">         Import imp;
</span><span class="lines">@@ -174,11 +173,10 @@
</span><span class="cx">         case ExternalKind::Function: {
</span><span class="cx">             uint32_t functionSignatureIndex;
</span><span class="cx">             WASM_PARSER_FAIL_IF(!parseVarUInt32(functionSignatureIndex), &quot;can't get &quot;, importNumber, &quot;th Import's function signature in module '&quot;, moduleString, &quot;' field '&quot;, fieldString, &quot;'&quot;);
</span><del>-            WASM_PARSER_FAIL_IF(functionSignatureIndex &gt;= m_result.module-&gt;signatureIndices.size(), &quot;invalid function signature for &quot;, importNumber, &quot;th Import, &quot;, functionSignatureIndex, &quot; is out of range of &quot;, m_result.module-&gt;signatureIndices.size(), &quot; in module '&quot;, moduleString, &quot;' field '&quot;, fieldString, &quot;'&quot;);
</del><ins>+            WASM_PARSER_FAIL_IF(functionSignatureIndex &gt;= m_result.moduleSignatureIndicesToUniquedSignatureIndices.size(), &quot;invalid function signature for &quot;, importNumber, &quot;th Import, &quot;, functionSignatureIndex, &quot; is out of range of &quot;, m_result.moduleSignatureIndicesToUniquedSignatureIndices.size(), &quot; in module '&quot;, moduleString, &quot;' field '&quot;, fieldString, &quot;'&quot;);
</ins><span class="cx">             imp.kindIndex = m_result.module-&gt;importFunctionSignatureIndices.size();
</span><del>-            SignatureIndex signatureIndex = m_result.module-&gt;signatureIndices[functionSignatureIndex];
</del><ins>+            SignatureIndex signatureIndex = m_result.moduleSignatureIndicesToUniquedSignatureIndices[functionSignatureIndex];
</ins><span class="cx">             m_result.module-&gt;importFunctionSignatureIndices.uncheckedAppend(signatureIndex);
</span><del>-            m_result.functionIndexSpace.uncheckedAppend(signatureIndex);
</del><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         case ExternalKind::Table: {
</span><span class="lines">@@ -220,20 +218,18 @@
</span><span class="cx">     WASM_PARSER_FAIL_IF(count == std::numeric_limits&lt;uint32_t&gt;::max(), &quot;Function section's count is too big &quot;, count);
</span><span class="cx">     WASM_PARSER_FAIL_IF(!m_result.module-&gt;internalFunctionSignatureIndices.tryReserveCapacity(count), &quot;can't allocate enough memory for &quot;, count, &quot; Function signatures&quot;);
</span><span class="cx">     WASM_PARSER_FAIL_IF(!m_result.functionLocationInBinary.tryReserveCapacity(count), &quot;can't allocate enough memory for &quot;, count, &quot;Function locations&quot;);
</span><del>-    WASM_PARSER_FAIL_IF(!m_result.functionIndexSpace.tryReserveCapacity(m_result.functionIndexSpace.size() + count), &quot;can't allocate enough memory for &quot;, count, &quot; more functions in the function index space&quot;);
</del><span class="cx"> 
</span><span class="cx">     for (uint32_t i = 0; i &lt; count; ++i) {
</span><span class="cx">         uint32_t typeNumber;
</span><span class="cx">         WASM_PARSER_FAIL_IF(!parseVarUInt32(typeNumber), &quot;can't get &quot;, i, &quot;th Function's type number&quot;);
</span><del>-        WASM_PARSER_FAIL_IF(typeNumber &gt;= m_result.module-&gt;signatureIndices.size(), i, &quot;th Function type number is invalid &quot;, typeNumber);
</del><ins>+        WASM_PARSER_FAIL_IF(typeNumber &gt;= m_result.moduleSignatureIndicesToUniquedSignatureIndices.size(), i, &quot;th Function type number is invalid &quot;, typeNumber);
</ins><span class="cx"> 
</span><del>-        SignatureIndex signatureIndex = m_result.module-&gt;signatureIndices[typeNumber];
</del><ins>+        SignatureIndex signatureIndex = m_result.moduleSignatureIndicesToUniquedSignatureIndices[typeNumber];
</ins><span class="cx">         // The Code section fixes up start and end.
</span><span class="cx">         size_t start = 0;
</span><span class="cx">         size_t end = 0;
</span><span class="cx">         m_result.module-&gt;internalFunctionSignatureIndices.uncheckedAppend(signatureIndex);
</span><span class="cx">         m_result.functionLocationInBinary.uncheckedAppend({ start, end });
</span><del>-        m_result.functionIndexSpace.uncheckedAppend(signatureIndex);
</del><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return { };
</span><span class="lines">@@ -320,8 +316,7 @@
</span><span class="cx">     ASSERT(initialPageCount);
</span><span class="cx">     ASSERT(!maximumPageCount || maximumPageCount &gt;= initialPageCount);
</span><span class="cx"> 
</span><del>-    Vector&lt;unsigned&gt; pinnedSizes = { 0 };
-    m_result.module-&gt;memory = MemoryInformation(initialPageCount, maximumPageCount, pinnedSizes, isImport);
</del><ins>+    m_result.module-&gt;memory = MemoryInformation(initialPageCount, maximumPageCount, isImport);
</ins><span class="cx">     return { };
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -387,7 +382,7 @@
</span><span class="cx">         WASM_PARSER_FAIL_IF(!parseVarUInt32(exp.kindIndex), &quot;can't get &quot;, exportNumber, &quot;th Export's kind index, named '&quot;, fieldString, &quot;'&quot;);
</span><span class="cx">         switch (exp.kind) {
</span><span class="cx">         case ExternalKind::Function: {
</span><del>-            WASM_PARSER_FAIL_IF(exp.kindIndex &gt;= m_result.functionIndexSpace.size(), exportNumber, &quot;th Export has invalid function number &quot;, exp.kindIndex, &quot; it exceeds the function index space &quot;, m_result.functionIndexSpace.size(), &quot;, named '&quot;, fieldString, &quot;'&quot;);
</del><ins>+            WASM_PARSER_FAIL_IF(exp.kindIndex &gt;= m_result.module-&gt;functionIndexSpaceSize(), exportNumber, &quot;th Export has invalid function number &quot;, exp.kindIndex, &quot; it exceeds the function index space &quot;, m_result.module-&gt;functionIndexSpaceSize(), &quot;, named '&quot;, fieldString, &quot;'&quot;);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         case ExternalKind::Table: {
</span><span class="lines">@@ -417,8 +412,8 @@
</span><span class="cx"> {
</span><span class="cx">     uint32_t startFunctionIndex;
</span><span class="cx">     WASM_PARSER_FAIL_IF(!parseVarUInt32(startFunctionIndex), &quot;can't get Start index&quot;);
</span><del>-    WASM_PARSER_FAIL_IF(startFunctionIndex &gt;= m_result.functionIndexSpace.size(), &quot;Start index &quot;, startFunctionIndex, &quot; exceeds function index space &quot;, m_result.functionIndexSpace.size());
-    SignatureIndex signatureIndex = m_result.functionIndexSpace[startFunctionIndex].signatureIndex;
</del><ins>+    WASM_PARSER_FAIL_IF(startFunctionIndex &gt;= m_result.module-&gt;functionIndexSpaceSize(), &quot;Start index &quot;, startFunctionIndex, &quot; exceeds function index space &quot;, m_result.module-&gt;functionIndexSpaceSize());
+    SignatureIndex signatureIndex = m_result.module-&gt;signatureIndexFromFunctionIndexSpace(startFunctionIndex);
</ins><span class="cx">     const Signature* signature = SignatureInformation::get(m_vm, signatureIndex);
</span><span class="cx">     WASM_PARSER_FAIL_IF(signature-&gt;argumentCount(), &quot;Start function can't have arguments&quot;);
</span><span class="cx">     WASM_PARSER_FAIL_IF(signature-&gt;returnType() != Void, &quot;Start function can't return a value&quot;);
</span><span class="lines">@@ -469,7 +464,7 @@
</span><span class="cx">         for (unsigned index = 0; index &lt; indexCount; ++index) {
</span><span class="cx">             uint32_t functionIndex;
</span><span class="cx">             WASM_PARSER_FAIL_IF(!parseVarUInt32(functionIndex), &quot;can't get Element section's &quot;, elementNum, &quot;th element's &quot;, index, &quot;th index&quot;);
</span><del>-            WASM_PARSER_FAIL_IF(functionIndex &gt;= m_result.functionIndexSpace.size(), &quot;Element section's &quot;, elementNum, &quot;th element's &quot;, index, &quot;th index is &quot;, functionIndex, &quot; which exceeds the function index space size of &quot;, m_result.functionIndexSpace.size());
</del><ins>+            WASM_PARSER_FAIL_IF(functionIndex &gt;= m_result.module-&gt;functionIndexSpaceSize(), &quot;Element section's &quot;, elementNum, &quot;th element's &quot;, index, &quot;th index is &quot;, functionIndex, &quot; which exceeds the function index space size of &quot;, m_result.module-&gt;functionIndexSpaceSize());
</ins><span class="cx"> 
</span><span class="cx">             element.functionIndices.uncheckedAppend(functionIndex);
</span><span class="cx">         }
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmWasmModuleParserh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmModuleParser.h (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmModuleParser.h        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmModuleParser.h        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -36,8 +36,8 @@
</span><span class="cx"> 
</span><span class="cx"> struct ModuleParserResult {
</span><span class="cx">     std::unique_ptr&lt;ModuleInformation&gt; module;
</span><del>-    FunctionIndexSpace functionIndexSpace;
</del><span class="cx">     Vector&lt;FunctionLocationInBinary&gt; functionLocationInBinary;
</span><ins>+    Vector&lt;SignatureIndex&gt; moduleSignatureIndicesToUniquedSignatureIndices;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class ModuleParser : public Parser&lt;ModuleParserResult&gt; {
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmWasmPageCountcppfromrev210420branchessafari603branchSourceJavaScriptCorewasmWasmBindingh"></a>
<div class="copfile"><h4>Copied: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmPageCount.cpp (from rev 210420, branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmBinding.h) (0 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmPageCount.cpp                                (rev 0)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmPageCount.cpp        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -0,0 +1,45 @@
</span><ins>+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;WasmPageCount.h&quot;
+
+#if ENABLE(WEBASSEMBLY)
+
+#include &lt;wtf/PrintStream.h&gt;
+#include &lt;wtf/text/WTFString.h&gt;
+
+namespace JSC { namespace Wasm {
+
+void PageCount::dump(PrintStream&amp; out) const
+{
+    out.print(String::number(bytes()), &quot;B&quot;);
+}
+
+} // namespace JSC
+
+} // namespace Wasm
+
+#endif // ENABLE(WEBASSEMBLY)
</ins></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmWasmPageCounth"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmPageCount.h (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmPageCount.h        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmPageCount.h        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -27,6 +27,10 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(WEBASSEMBLY)
</span><span class="cx"> 
</span><ins>+namespace WTF {
+class PrintStream;
+}
+
</ins><span class="cx"> namespace JSC { namespace Wasm {
</span><span class="cx"> 
</span><span class="cx"> class PageCount {
</span><span class="lines">@@ -42,6 +46,8 @@
</span><span class="cx">         : m_pageCount(pageCount)
</span><span class="cx">     { }
</span><span class="cx"> 
</span><ins>+    void dump(WTF::PrintStream&amp;) const;
+
</ins><span class="cx">     uint64_t bytes() const { return static_cast&lt;uint64_t&gt;(m_pageCount) * static_cast&lt;uint64_t&gt;(pageSize); }
</span><span class="cx">     uint32_t pageCount() const { return m_pageCount; }
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmWasmPlancpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmPlan.cpp (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmPlan.cpp        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmPlan.cpp        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -76,8 +76,7 @@
</span><span class="cx">         }
</span><span class="cx">         m_moduleInformation = WTFMove(parseResult-&gt;module);
</span><span class="cx">         m_functionLocationInBinary = WTFMove(parseResult-&gt;functionLocationInBinary);
</span><del>-        m_functionIndexSpace.size = parseResult-&gt;functionIndexSpace.size();
-        m_functionIndexSpace.buffer = parseResult-&gt;functionIndexSpace.releaseBuffer();
</del><ins>+        m_moduleSignatureIndicesToUniquedSignatureIndices = WTFMove(parseResult-&gt;moduleSignatureIndicesToUniquedSignatureIndices);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     for (unsigned functionIndex = 0; functionIndex &lt; m_functionLocationInBinary.size(); ++functionIndex) {
</span><span class="lines">@@ -89,7 +88,7 @@
</span><span class="cx">         SignatureIndex signatureIndex = m_moduleInformation-&gt;internalFunctionSignatureIndices[functionIndex];
</span><span class="cx">         const Signature* signature = SignatureInformation::get(m_vm, signatureIndex);
</span><span class="cx"> 
</span><del>-        auto validationResult = validateFunction(m_vm, functionStart, functionLength, signature, m_functionIndexSpace, *m_moduleInformation);
</del><ins>+        auto validationResult = validateFunction(m_vm, functionStart, functionLength, signature, *m_moduleInformation, m_moduleSignatureIndicesToUniquedSignatureIndices);
</ins><span class="cx">         if (!validationResult) {
</span><span class="cx">             if (verbose) {
</span><span class="cx">                 for (unsigned i = 0; i &lt; functionLength; ++i)
</span><span class="lines">@@ -127,7 +126,7 @@
</span><span class="cx">         return true;
</span><span class="cx">     };
</span><span class="cx"> 
</span><del>-    if (!tryReserveCapacity(m_wasmToJSStubs, m_moduleInformation-&gt;importFunctionSignatureIndices.size(), &quot; WebAssembly to JavaScript stubs&quot;)
</del><ins>+    if (!tryReserveCapacity(m_wasmExitStubs, m_moduleInformation-&gt;importFunctionSignatureIndices.size(), &quot; WebAssembly to JavaScript stubs&quot;)
</ins><span class="cx">         || !tryReserveCapacity(m_unlinkedWasmToWasmCalls, m_functionLocationInBinary.size(), &quot; unlinked WebAssembly to WebAssembly calls&quot;)
</span><span class="cx">         || !tryReserveCapacity(m_wasmInternalFunctions, m_functionLocationInBinary.size(), &quot; WebAssembly functions&quot;)
</span><span class="cx">         || !tryReserveCapacity(m_compilationContexts, m_functionLocationInBinary.size(), &quot; compilation contexts&quot;))
</span><span class="lines">@@ -141,12 +140,11 @@
</span><span class="cx">         Import* import = &amp;m_moduleInformation-&gt;imports[importIndex];
</span><span class="cx">         if (import-&gt;kind != ExternalKind::Function)
</span><span class="cx">             continue;
</span><del>-        unsigned importFunctionIndex = m_wasmToJSStubs.size();
</del><ins>+        unsigned importFunctionIndex = m_wasmExitStubs.size();
</ins><span class="cx">         if (verbose)
</span><span class="cx">             dataLogLn(&quot;Processing import function number &quot;, importFunctionIndex, &quot;: &quot;, import-&gt;module, &quot;: &quot;, import-&gt;field);
</span><span class="cx">         SignatureIndex signatureIndex = m_moduleInformation-&gt;importFunctionSignatureIndices.at(import-&gt;kindIndex);
</span><del>-        m_wasmToJSStubs.uncheckedAppend(importStubGenerator(m_vm, m_callLinkInfos, signatureIndex, importFunctionIndex));
-        m_functionIndexSpace.buffer.get()[importFunctionIndex].code = m_wasmToJSStubs[importFunctionIndex].code().executableAddress();
</del><ins>+        m_wasmExitStubs.uncheckedAppend(exitStubGenerator(m_vm, m_callLinkInfos, signatureIndex, importFunctionIndex));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     m_currentIndex = 0;
</span><span class="lines">@@ -167,12 +165,12 @@
</span><span class="cx">             ASSERT(functionLength &lt;= m_sourceLength);
</span><span class="cx">             SignatureIndex signatureIndex = m_moduleInformation-&gt;internalFunctionSignatureIndices[functionIndex];
</span><span class="cx">             const Signature* signature = SignatureInformation::get(m_vm, signatureIndex);
</span><del>-            unsigned functionIndexSpace = m_wasmToJSStubs.size() + functionIndex;
-            ASSERT_UNUSED(functionIndexSpace, m_functionIndexSpace.buffer.get()[functionIndexSpace].signatureIndex == signatureIndex);
-            ASSERT(validateFunction(m_vm, functionStart, functionLength, signature, m_functionIndexSpace, *m_moduleInformation));
</del><ins>+            unsigned functionIndexSpace = m_wasmExitStubs.size() + functionIndex;
+            ASSERT_UNUSED(functionIndexSpace, m_moduleInformation-&gt;signatureIndexFromFunctionIndexSpace(functionIndexSpace) == signatureIndex);
+            ASSERT(validateFunction(m_vm, functionStart, functionLength, signature, *m_moduleInformation, m_moduleSignatureIndicesToUniquedSignatureIndices));
</ins><span class="cx"> 
</span><span class="cx">             m_unlinkedWasmToWasmCalls[functionIndex] = Vector&lt;UnlinkedWasmToWasmCall&gt;();
</span><del>-            auto parseAndCompileResult = parseAndCompile(*m_vm, m_compilationContexts[functionIndex], functionStart, functionLength, signature, m_unlinkedWasmToWasmCalls[functionIndex], m_functionIndexSpace, *m_moduleInformation);
</del><ins>+            auto parseAndCompileResult = parseAndCompile(*m_vm, m_compilationContexts[functionIndex], functionStart, functionLength, signature, m_unlinkedWasmToWasmCalls[functionIndex], *m_moduleInformation, m_moduleSignatureIndicesToUniquedSignatureIndices);
</ins><span class="cx"> 
</span><span class="cx">             if (UNLIKELY(!parseAndCompileResult)) {
</span><span class="cx">                 auto locker = holdLock(m_lock);
</span><span class="lines">@@ -209,10 +207,12 @@
</span><span class="cx">     for (uint32_t functionIndex = 0; functionIndex &lt; m_functionLocationInBinary.size(); functionIndex++) {
</span><span class="cx">         {
</span><span class="cx">             CompilationContext&amp; context = m_compilationContexts[functionIndex];
</span><ins>+            SignatureIndex signatureIndex = m_moduleInformation-&gt;internalFunctionSignatureIndices[functionIndex];
+            String signatureDescription = SignatureInformation::get(m_vm, signatureIndex)-&gt;toString();
</ins><span class="cx">             {
</span><span class="cx">                 LinkBuffer linkBuffer(*m_vm, *context.wasmEntrypointJIT, nullptr);
</span><span class="cx">                 m_wasmInternalFunctions[functionIndex]-&gt;wasmEntrypoint.compilation =
</span><del>-                    std::make_unique&lt;B3::Compilation&gt;(FINALIZE_CODE(linkBuffer, (&quot;Wasm function&quot;)), WTFMove(context.wasmEntrypointByproducts));
</del><ins>+                    std::make_unique&lt;B3::Compilation&gt;(FINALIZE_CODE(linkBuffer, (&quot;WebAssembly function[%i] %s&quot;, functionIndex, signatureDescription.ascii().data())), WTFMove(context.wasmEntrypointByproducts));
</ins><span class="cx">             }
</span><span class="cx"> 
</span><span class="cx">             {
</span><span class="lines">@@ -220,12 +220,9 @@
</span><span class="cx">                 linkBuffer.link(context.jsEntrypointToWasmEntrypointCall, FunctionPtr(m_wasmInternalFunctions[functionIndex]-&gt;wasmEntrypoint.compilation-&gt;code().executableAddress()));
</span><span class="cx"> 
</span><span class="cx">                 m_wasmInternalFunctions[functionIndex]-&gt;jsToWasmEntrypoint.compilation =
</span><del>-                    std::make_unique&lt;B3::Compilation&gt;(FINALIZE_CODE(linkBuffer, (&quot;Wasm JS entrypoint&quot;)), WTFMove(context.jsEntrypointByproducts));
</del><ins>+                    std::make_unique&lt;B3::Compilation&gt;(FINALIZE_CODE(linkBuffer, (&quot;JavaScript-&gt;WebAssembly entrypoint[%i] %s&quot;, functionIndex, signatureDescription.ascii().data())), WTFMove(context.jsEntrypointByproducts));
</ins><span class="cx">             }
</span><span class="cx">         }
</span><del>-
-        unsigned functionIndexSpace = m_wasmToJSStubs.size() + functionIndex;
-        m_functionIndexSpace.buffer.get()[functionIndexSpace].code = m_wasmInternalFunctions[functionIndex]-&gt;wasmEntrypoint.compilation-&gt;code().executableAddress();
</del><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (verbose || Options::reportCompileTimes()) {
</span><span class="lines">@@ -235,8 +232,19 @@
</span><span class="cx"> 
</span><span class="cx">     // Patch the call sites for each WebAssembly function.
</span><span class="cx">     for (auto&amp; unlinked : m_unlinkedWasmToWasmCalls) {
</span><del>-        for (auto&amp; call : unlinked)
-            MacroAssembler::repatchCall(call.callLocation, CodeLocationLabel(m_functionIndexSpace.buffer.get()[call.functionIndex].code));
</del><ins>+        for (auto&amp; call : unlinked) {
+            void* executableAddress;
+            if (m_moduleInformation-&gt;isImportedFunctionFromFunctionIndexSpace(call.functionIndex)) {
+                // FIXME imports could have been linked in B3, instead of generating a patchpoint. This condition should be replaced by a RELEASE_ASSERT. https://bugs.webkit.org/show_bug.cgi?id=166462
+                executableAddress = call.target == UnlinkedWasmToWasmCall::Target::ToJs
+                    ? m_wasmExitStubs.at(call.functionIndex).wasmToJs.code().executableAddress()
+                    : m_wasmExitStubs.at(call.functionIndex).wasmToWasm.code().executableAddress();
+            } else {
+                ASSERT(call.target != UnlinkedWasmToWasmCall::Target::ToJs);
+                executableAddress = m_wasmInternalFunctions.at(call.functionIndex - m_wasmExitStubs.size())-&gt;wasmEntrypoint.compilation-&gt;code().executableAddress();
+            }
+            MacroAssembler::repatchCall(call.callLocation, CodeLocationLabel(executableAddress));
+        }
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     m_failed = false;
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmWasmPlanh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmPlan.h (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmPlan.h        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmPlan.h        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -86,26 +86,20 @@
</span><span class="cx">         return WTFMove(m_callLinkInfos);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    Vector&lt;WasmToJSStub&gt;&amp;&amp; takeWasmToJSStubs()
</del><ins>+    Vector&lt;WasmExitStubs&gt;&amp;&amp; takeWasmExitStubs()
</ins><span class="cx">     {
</span><span class="cx">         RELEASE_ASSERT(!failed());
</span><del>-        return WTFMove(m_wasmToJSStubs);
</del><ins>+        return WTFMove(m_wasmExitStubs);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    ImmutableFunctionIndexSpace&amp;&amp; takeFunctionIndexSpace()
-    {
-        RELEASE_ASSERT(!failed());
-        return WTFMove(m_functionIndexSpace);
-    }
-
</del><span class="cx"> private:
</span><span class="cx">     std::unique_ptr&lt;ModuleInformation&gt; m_moduleInformation;
</span><span class="cx">     Vector&lt;FunctionLocationInBinary&gt; m_functionLocationInBinary;
</span><ins>+    Vector&lt;SignatureIndex&gt; m_moduleSignatureIndicesToUniquedSignatureIndices;
</ins><span class="cx">     Bag&lt;CallLinkInfo&gt; m_callLinkInfos;
</span><del>-    Vector&lt;WasmToJSStub&gt; m_wasmToJSStubs;
</del><ins>+    Vector&lt;WasmExitStubs&gt; m_wasmExitStubs;
</ins><span class="cx">     Vector&lt;std::unique_ptr&lt;WasmInternalFunction&gt;&gt; m_wasmInternalFunctions;
</span><span class="cx">     Vector&lt;CompilationContext&gt; m_compilationContexts;
</span><del>-    ImmutableFunctionIndexSpace m_functionIndexSpace;
</del><span class="cx"> 
</span><span class="cx">     VM* m_vm;
</span><span class="cx">     Vector&lt;Vector&lt;UnlinkedWasmToWasmCall&gt;&gt; m_unlinkedWasmToWasmCalls;
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmWasmSignaturecpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmSignature.cpp (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmSignature.cpp        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmSignature.cpp        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -41,12 +41,22 @@
</span><span class="cx"> 
</span><span class="cx"> const constexpr SignatureIndex Signature::invalidIndex;
</span><span class="cx"> 
</span><ins>+String Signature::toString() const
+{
+    String result(makeString(returnType()));
+    result.append(&quot; (&quot;);
+    for (SignatureArgCount arg = 0; arg &lt; argumentCount(); ++arg) {
+        if (arg)
+            result.append(&quot;, &quot;);
+        result.append(makeString(argument(arg)));
+    }
+    result.append(')');
+    return result;
+}
+
</ins><span class="cx"> void Signature::dump(PrintStream&amp; out) const
</span><span class="cx"> {
</span><del>-    out.print(makeString(returnType()), &quot; (&quot;);
-    for (SignatureArgCount arg = 0; arg &lt; argumentCount(); ++arg)
-        out.print((arg ? &quot;, &quot; : &quot;&quot;), makeString(argument(arg)));
-    out.print(&quot;)&quot;);
</del><ins>+    out.print(toString());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> unsigned Signature::hash() const
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmWasmSignatureh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmSignature.h (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmSignature.h        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmSignature.h        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -82,6 +82,7 @@
</span><span class="cx">     }
</span><span class="cx">     Type argument(SignatureArgCount i) const { return const_cast&lt;Signature*&gt;(this)-&gt;argument(i); }
</span><span class="cx"> 
</span><ins>+    WTF::String toString() const;
</ins><span class="cx">     void dump(WTF::PrintStream&amp; out) const;
</span><span class="cx">     bool operator==(const Signature&amp; rhs) const
</span><span class="cx">     {
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmWasmValidatecpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmValidate.cpp (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmValidate.cpp        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmValidate.cpp        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -381,10 +381,10 @@
</span><span class="cx">     dataLogLn();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Expected&lt;void, String&gt; validateFunction(VM* vm, const uint8_t* source, size_t length, const Signature* signature, const ImmutableFunctionIndexSpace&amp; functionIndexSpace, const ModuleInformation&amp; module)
</del><ins>+Expected&lt;void, String&gt; validateFunction(VM* vm, const uint8_t* source, size_t length, const Signature* signature, const ModuleInformation&amp; module, const Vector&lt;SignatureIndex&gt;&amp; moduleSignatureIndicesToUniquedSignatureIndices)
</ins><span class="cx"> {
</span><span class="cx">     Validate context(module);
</span><del>-    FunctionParser&lt;Validate&gt; validator(vm, context, source, length, signature, functionIndexSpace, module);
</del><ins>+    FunctionParser&lt;Validate&gt; validator(vm, context, source, length, signature, module, moduleSignatureIndicesToUniquedSignatureIndices);
</ins><span class="cx">     WASM_FAIL_IF_HELPER_FAILS(validator.parse());
</span><span class="cx">     return { };
</span><span class="cx"> }
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmWasmValidateh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmValidate.h (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmValidate.h        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmValidate.h        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -36,7 +36,7 @@
</span><span class="cx"> 
</span><span class="cx"> namespace Wasm {
</span><span class="cx"> 
</span><del>-Expected&lt;void, String&gt; validateFunction(VM*, const uint8_t*, size_t, const Signature*, const ImmutableFunctionIndexSpace&amp;, const ModuleInformation&amp;);
</del><ins>+Expected&lt;void, String&gt; validateFunction(VM*, const uint8_t*, size_t, const Signature*, const ModuleInformation&amp;, const Vector&lt;SignatureIndex&gt;&amp;);
</ins><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::Wasm
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmjsJSWebAssemblyInstanceh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.h        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -86,9 +86,11 @@
</span><span class="cx">         return offsetOfImportFunctions() + sizeof(WriteBarrier&lt;JSCell&gt;) * idx;
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    static ptrdiff_t offsetOfMemory() { return OBJECT_OFFSETOF(JSWebAssemblyInstance, m_memory); }
</ins><span class="cx">     static ptrdiff_t offsetOfTable() { return OBJECT_OFFSETOF(JSWebAssemblyInstance, m_table); }
</span><del>-    static ptrdiff_t offsetOfMemory() { return OBJECT_OFFSETOF(JSWebAssemblyInstance, m_memory); }
</del><span class="cx">     static ptrdiff_t offsetOfGlobals() { return OBJECT_OFFSETOF(JSWebAssemblyInstance, m_globals); }
</span><ins>+    static size_t offsetOfImportFunctions() { return WTF::roundUpToMultipleOf&lt;sizeof(WriteBarrier&lt;JSCell&gt;)&gt;(sizeof(JSWebAssemblyInstance)); }
+    static size_t offsetOfImportFunction(size_t importFunctionNum) { return offsetOfImportFunctions() + importFunctionNum * sizeof(sizeof(WriteBarrier&lt;JSCell&gt;)); }
</ins><span class="cx"> 
</span><span class="cx"> protected:
</span><span class="cx">     JSWebAssemblyInstance(VM&amp;, Structure*, unsigned numImportFunctions);
</span><span class="lines">@@ -96,11 +98,6 @@
</span><span class="cx">     static void destroy(JSCell*);
</span><span class="cx">     static void visitChildren(JSCell*, SlotVisitor&amp;);
</span><span class="cx"> 
</span><del>-    static size_t offsetOfImportFunctions()
-    {
-        return WTF::roundUpToMultipleOf&lt;sizeof(WriteBarrier&lt;JSCell&gt;)&gt;(sizeof(JSWebAssemblyInstance));
-    }
-
</del><span class="cx">     static size_t allocationSize(unsigned numImportFunctions)
</span><span class="cx">     {
</span><span class="cx">         return offsetOfImportFunctions() + sizeof(WriteBarrier&lt;JSCell&gt;) * numImportFunctions;
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmjsJSWebAssemblyMemorycpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.cpp (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.cpp        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.cpp        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -37,9 +37,9 @@
</span><span class="cx"> 
</span><span class="cx"> const ClassInfo JSWebAssemblyMemory::s_info = { &quot;WebAssembly.Memory&quot;, &amp;Base::s_info, 0, CREATE_METHOD_TABLE(JSWebAssemblyMemory) };
</span><span class="cx"> 
</span><del>-JSWebAssemblyMemory* JSWebAssemblyMemory::create(VM&amp; vm, Structure* structure, std::unique_ptr&lt;Wasm::Memory&gt;&amp;&amp; memory)
</del><ins>+JSWebAssemblyMemory* JSWebAssemblyMemory::create(VM&amp; vm, Structure* structure, Wasm::Memory&amp;&amp; memory)
</ins><span class="cx"> {
</span><del>-    auto* instance = new (NotNull, allocateCell&lt;JSWebAssemblyMemory&gt;(vm.heap)) JSWebAssemblyMemory(vm, structure, WTFMove(memory));
</del><ins>+    auto* instance = new (NotNull, allocateCell&lt;JSWebAssemblyMemory&gt;(vm.heap)) JSWebAssemblyMemory(vm, structure, std::forward&lt;Wasm::Memory&gt;(memory));
</ins><span class="cx">     instance-&gt;finishCreation(vm);
</span><span class="cx">     return instance;
</span><span class="cx"> }
</span><span class="lines">@@ -49,7 +49,7 @@
</span><span class="cx">     return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-JSWebAssemblyMemory::JSWebAssemblyMemory(VM&amp; vm, Structure* structure, std::unique_ptr&lt;Wasm::Memory&gt;&amp;&amp; memory)
</del><ins>+JSWebAssemblyMemory::JSWebAssemblyMemory(VM&amp; vm, Structure* structure, Wasm::Memory&amp;&amp; memory)
</ins><span class="cx">     : Base(vm, structure)
</span><span class="cx">     , m_memory(WTFMove(memory))
</span><span class="cx"> {
</span><span class="lines">@@ -72,7 +72,7 @@
</span><span class="cx">     auto destructor = [] (void*) {
</span><span class="cx">         // We don't need to do anything here to destroy the memory.
</span><span class="cx">         // The ArrayBuffer backing the JSArrayBuffer is only owned by us,
</span><del>-        // so we guarantee its lifecylce.
</del><ins>+        // so we guarantee its lifecycle.
</ins><span class="cx">     };
</span><span class="cx">     m_buffer = ArrayBuffer::createFromBytes(memory()-&gt;memory(), memory()-&gt;size(), WTFMove(destructor));
</span><span class="cx">     m_bufferWrapper.set(vm, this, JSArrayBuffer::create(vm, globalObject-&gt;m_arrayBufferStructure.get(), m_buffer.get()));
</span><span class="lines">@@ -85,7 +85,7 @@
</span><span class="cx">     VM&amp; vm = exec-&gt;vm();
</span><span class="cx">     auto throwScope = DECLARE_THROW_SCOPE(vm);
</span><span class="cx"> 
</span><del>-    Wasm::PageCount oldPageCount = m_memory-&gt;sizeInPages();
</del><ins>+    Wasm::PageCount oldPageCount = memory()-&gt;sizeInPages();
</ins><span class="cx"> 
</span><span class="cx">     if (!Wasm::PageCount::isValid(delta)) {
</span><span class="cx">         if (shouldThrowExceptionsOnFailure)
</span><span class="lines">@@ -101,7 +101,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (delta) {
</span><del>-        bool success = m_memory-&gt;grow(newSize);
</del><ins>+        bool success = memory()-&gt;grow(newSize);
</ins><span class="cx">         if (!success) {
</span><span class="cx">             if (shouldThrowExceptionsOnFailure)
</span><span class="cx">                 throwException(exec, throwScope, createOutOfMemoryError(exec));
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmjsJSWebAssemblyMemoryh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.h (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.h        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyMemory.h        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -41,25 +41,26 @@
</span><span class="cx"> public:
</span><span class="cx">     typedef JSDestructibleObject Base;
</span><span class="cx"> 
</span><del>-    static JSWebAssemblyMemory* create(VM&amp;, Structure*, std::unique_ptr&lt;Wasm::Memory&gt;&amp;&amp;);
</del><ins>+    static JSWebAssemblyMemory* create(VM&amp;, Structure*, Wasm::Memory&amp;&amp;);
</ins><span class="cx">     static Structure* createStructure(VM&amp;, JSGlobalObject*, JSValue);
</span><span class="cx"> 
</span><span class="cx">     DECLARE_INFO;
</span><span class="cx"> 
</span><del>-    Wasm::Memory* memory() { return m_memory.get(); }
</del><ins>+    Wasm::Memory* memory() { return &amp;m_memory; }
</ins><span class="cx">     JSArrayBuffer* buffer(VM&amp; vm, JSGlobalObject*);
</span><span class="cx">     Wasm::PageCount grow(ExecState*, uint32_t delta, bool shouldThrowExceptionsOnFailure);
</span><span class="cx"> 
</span><del>-    static ptrdiff_t offsetOfMemory() { return OBJECT_OFFSETOF(JSWebAssemblyMemory, m_memory); }
</del><ins>+    static ptrdiff_t offsetOfMemory() { return OBJECT_OFFSETOF(JSWebAssemblyMemory, m_memory) + Wasm::Memory::offsetOfMemory(); }
+    static ptrdiff_t offsetOfSize() { return OBJECT_OFFSETOF(JSWebAssemblyMemory, m_memory) + Wasm::Memory::offsetOfSize(); }
</ins><span class="cx"> 
</span><span class="cx"> protected:
</span><del>-    JSWebAssemblyMemory(VM&amp;, Structure*, std::unique_ptr&lt;Wasm::Memory&gt;&amp;&amp;);
</del><ins>+    JSWebAssemblyMemory(VM&amp;, Structure*, Wasm::Memory&amp;&amp;);
</ins><span class="cx">     ~JSWebAssemblyMemory();
</span><span class="cx">     void finishCreation(VM&amp;);
</span><span class="cx">     static void destroy(JSCell*);
</span><span class="cx">     static void visitChildren(JSCell*, SlotVisitor&amp;);
</span><span class="cx"> 
</span><del>-    std::unique_ptr&lt;Wasm::Memory&gt; m_memory;
</del><ins>+    Wasm::Memory m_memory;
</ins><span class="cx">     WriteBarrier&lt;JSArrayBuffer&gt; m_bufferWrapper;
</span><span class="cx">     RefPtr&lt;ArrayBuffer&gt; m_buffer;
</span><span class="cx"> };
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmjsJSWebAssemblyModulecpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.cpp (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.cpp        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.cpp        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -38,9 +38,9 @@
</span><span class="cx"> 
</span><span class="cx"> const ClassInfo JSWebAssemblyModule::s_info = { &quot;WebAssembly.Module&quot;, &amp;Base::s_info, nullptr, CREATE_METHOD_TABLE(JSWebAssemblyModule) };
</span><span class="cx"> 
</span><del>-JSWebAssemblyModule* JSWebAssemblyModule::create(VM&amp; vm, Structure* structure, std::unique_ptr&lt;Wasm::ModuleInformation&gt;&amp;&amp; moduleInformation, Bag&lt;CallLinkInfo&gt;&amp;&amp; callLinkInfos, Vector&lt;Wasm::WasmToJSStub&gt;&amp;&amp; wasmToJSStubs, Wasm::ImmutableFunctionIndexSpace&amp;&amp; functionIndexSpace, SymbolTable* exportSymbolTable, unsigned calleeCount)
</del><ins>+JSWebAssemblyModule* JSWebAssemblyModule::create(VM&amp; vm, Structure* structure, std::unique_ptr&lt;Wasm::ModuleInformation&gt;&amp;&amp; moduleInformation, Bag&lt;CallLinkInfo&gt;&amp;&amp; callLinkInfos, Vector&lt;Wasm::WasmExitStubs&gt;&amp;&amp; wasmExitStubs, SymbolTable* exportSymbolTable, unsigned calleeCount)
</ins><span class="cx"> {
</span><del>-    auto* instance = new (NotNull, allocateCell&lt;JSWebAssemblyModule&gt;(vm.heap, allocationSize(calleeCount))) JSWebAssemblyModule(vm, structure, std::forward&lt;std::unique_ptr&lt;Wasm::ModuleInformation&gt;&gt;(moduleInformation), std::forward&lt;Bag&lt;CallLinkInfo&gt;&gt;(callLinkInfos), std::forward&lt;Vector&lt;Wasm::WasmToJSStub&gt;&gt;(wasmToJSStubs), std::forward&lt;Wasm::ImmutableFunctionIndexSpace&gt;(functionIndexSpace), calleeCount);
</del><ins>+    auto* instance = new (NotNull, allocateCell&lt;JSWebAssemblyModule&gt;(vm.heap, allocationSize(calleeCount))) JSWebAssemblyModule(vm, structure, std::forward&lt;std::unique_ptr&lt;Wasm::ModuleInformation&gt;&gt;(moduleInformation), std::forward&lt;Bag&lt;CallLinkInfo&gt;&gt;(callLinkInfos), std::forward&lt;Vector&lt;Wasm::WasmExitStubs&gt;&gt;(wasmExitStubs), calleeCount);
</ins><span class="cx">     instance-&gt;finishCreation(vm, exportSymbolTable);
</span><span class="cx">     return instance;
</span><span class="cx"> }
</span><span class="lines">@@ -50,12 +50,11 @@
</span><span class="cx">     return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-JSWebAssemblyModule::JSWebAssemblyModule(VM&amp; vm, Structure* structure, std::unique_ptr&lt;Wasm::ModuleInformation&gt;&amp;&amp; moduleInformation, Bag&lt;CallLinkInfo&gt;&amp;&amp; callLinkInfos, Vector&lt;Wasm::WasmToJSStub&gt;&amp;&amp; wasmToJSStubs, Wasm::ImmutableFunctionIndexSpace&amp;&amp; functionIndexSpace, unsigned calleeCount)
</del><ins>+JSWebAssemblyModule::JSWebAssemblyModule(VM&amp; vm, Structure* structure, std::unique_ptr&lt;Wasm::ModuleInformation&gt;&amp;&amp; moduleInformation, Bag&lt;CallLinkInfo&gt;&amp;&amp; callLinkInfos, Vector&lt;Wasm::WasmExitStubs&gt;&amp;&amp; wasmExitStubs, unsigned calleeCount)
</ins><span class="cx">     : Base(vm, structure)
</span><span class="cx">     , m_moduleInformation(WTFMove(moduleInformation))
</span><span class="cx">     , m_callLinkInfos(WTFMove(callLinkInfos))
</span><del>-    , m_wasmToJSStubs(WTFMove(wasmToJSStubs))
-    , m_functionIndexSpace(WTFMove(functionIndexSpace))
</del><ins>+    , m_wasmExitStubs(WTFMove(wasmExitStubs))
</ins><span class="cx">     , m_calleeCount(calleeCount)
</span><span class="cx"> {
</span><span class="cx">     memset(callees(), 0, m_calleeCount * sizeof(WriteBarrier&lt;JSWebAssemblyCallee&gt;) * 2);
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmjsJSWebAssemblyModuleh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.h (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.h        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.h        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -43,7 +43,7 @@
</span><span class="cx"> public:
</span><span class="cx">     typedef JSDestructibleObject Base;
</span><span class="cx"> 
</span><del>-    static JSWebAssemblyModule* create(VM&amp;, Structure*, std::unique_ptr&lt;Wasm::ModuleInformation&gt;&amp;&amp;, Bag&lt;CallLinkInfo&gt;&amp;&amp;, Vector&lt;Wasm::WasmToJSStub&gt;&amp;&amp;, Wasm::ImmutableFunctionIndexSpace&amp;&amp;, SymbolTable*, unsigned);
</del><ins>+    static JSWebAssemblyModule* create(VM&amp;, Structure*, std::unique_ptr&lt;Wasm::ModuleInformation&gt;&amp;&amp;, Bag&lt;CallLinkInfo&gt;&amp;&amp;, Vector&lt;Wasm::WasmExitStubs&gt;&amp;&amp;, SymbolTable*, unsigned);
</ins><span class="cx">     static Structure* createStructure(VM&amp;, JSGlobalObject*, JSValue);
</span><span class="cx"> 
</span><span class="cx">     DECLARE_INFO;
</span><span class="lines">@@ -50,12 +50,11 @@
</span><span class="cx"> 
</span><span class="cx">     const Wasm::ModuleInformation&amp; moduleInformation() const { return *m_moduleInformation.get(); }
</span><span class="cx">     SymbolTable* exportSymbolTable() const { return m_exportSymbolTable.get(); }
</span><del>-    Wasm::SignatureIndex signatureForFunctionIndexSpace(unsigned functionIndexSpace) const
</del><ins>+    Wasm::SignatureIndex signatureIndexFromFunctionIndexSpace(unsigned functionIndexSpace) const
</ins><span class="cx">     {
</span><del>-        ASSERT(functionIndexSpace &lt; m_functionIndexSpace.size);
-        return m_functionIndexSpace.buffer.get()[functionIndexSpace].signatureIndex;
</del><ins>+        return m_moduleInformation-&gt;signatureIndexFromFunctionIndexSpace(functionIndexSpace);
</ins><span class="cx">     }
</span><del>-    unsigned functionImportCount() const { return m_wasmToJSStubs.size(); }
</del><ins>+    unsigned functionImportCount() const { return m_wasmExitStubs.size(); }
</ins><span class="cx"> 
</span><span class="cx">     JSWebAssemblyCallee* jsEntrypointCalleeFromFunctionIndexSpace(unsigned functionIndexSpace)
</span><span class="cx">     {
</span><span class="lines">@@ -90,10 +89,8 @@
</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><del>-    static ptrdiff_t offsetOfFunctionIndexSpace() { return OBJECT_OFFSETOF(JSWebAssemblyModule, m_functionIndexSpace); }
-
</del><span class="cx"> protected:
</span><del>-    JSWebAssemblyModule(VM&amp;, Structure*, std::unique_ptr&lt;Wasm::ModuleInformation&gt;&amp;&amp;, Bag&lt;CallLinkInfo&gt;&amp;&amp;, Vector&lt;Wasm::WasmToJSStub&gt;&amp;&amp;, Wasm::ImmutableFunctionIndexSpace&amp;&amp;, unsigned calleeCount);
</del><ins>+    JSWebAssemblyModule(VM&amp;, Structure*, std::unique_ptr&lt;Wasm::ModuleInformation&gt;&amp;&amp;, Bag&lt;CallLinkInfo&gt;&amp;&amp;, Vector&lt;Wasm::WasmExitStubs&gt;&amp;&amp;, unsigned calleeCount);
</ins><span class="cx">     void finishCreation(VM&amp;, SymbolTable*);
</span><span class="cx">     static void destroy(JSCell*);
</span><span class="cx">     static void visitChildren(JSCell*, SlotVisitor&amp;);
</span><span class="lines">@@ -117,8 +114,7 @@
</span><span class="cx">     std::unique_ptr&lt;Wasm::ModuleInformation&gt; m_moduleInformation;
</span><span class="cx">     Bag&lt;CallLinkInfo&gt; m_callLinkInfos;
</span><span class="cx">     WriteBarrier&lt;SymbolTable&gt; m_exportSymbolTable;
</span><del>-    Vector&lt;Wasm::WasmToJSStub&gt; m_wasmToJSStubs;
-    const Wasm::ImmutableFunctionIndexSpace m_functionIndexSpace;
</del><ins>+    Vector&lt;Wasm::WasmExitStubs&gt; m_wasmExitStubs;
</ins><span class="cx">     unsigned m_calleeCount;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmjsWebAssemblyFunctioncpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -114,6 +114,7 @@
</span><span class="cx">     ProtoCallFrame protoCallFrame;
</span><span class="cx">     protoCallFrame.init(nullptr, wasmFunction, firstArgument, argCount, remainingArgs);
</span><span class="cx"> 
</span><ins>+    // FIXME Do away with this entire function, and only use the entrypoint generated by B3. https://bugs.webkit.org/show_bug.cgi?id=166486
</ins><span class="cx">     JSWebAssemblyInstance* prevJSWebAssemblyInstance = vm.topJSWebAssemblyInstance;
</span><span class="cx">     vm.topJSWebAssemblyInstance = wasmFunction-&gt;instance();
</span><span class="cx">     ASSERT(wasmFunction-&gt;instance());
</span><span class="lines">@@ -143,7 +144,7 @@
</span><span class="cx"> {
</span><span class="cx">     NativeExecutable* executable = vm.getHostFunction(callWebAssemblyFunction, NoIntrinsic, callHostFunctionAsConstructor, nullptr, name);
</span><span class="cx">     Structure* structure = globalObject-&gt;webAssemblyFunctionStructure();
</span><del>-    WebAssemblyFunction* function = new (NotNull, allocateCell&lt;WebAssemblyFunction&gt;(vm.heap)) WebAssemblyFunction(vm, globalObject, structure, signatureIndex);
</del><ins>+    WebAssemblyFunction* function = new (NotNull, allocateCell&lt;WebAssemblyFunction&gt;(vm.heap)) WebAssemblyFunction(vm, globalObject, structure, wasmEntrypoint, signatureIndex);
</ins><span class="cx">     function-&gt;finishCreation(vm, executable, length, name, instance, jsEntrypoint, wasmEntrypoint);
</span><span class="cx">     return function;
</span><span class="cx"> }
</span><span class="lines">@@ -151,11 +152,12 @@
</span><span class="cx"> Structure* WebAssemblyFunction::createStructure(VM&amp; vm, JSGlobalObject* globalObject, JSValue prototype)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(globalObject);
</span><del>-    return Structure::create(vm, globalObject, prototype, TypeInfo(JSFunctionType, StructureFlags), info());
</del><ins>+    return Structure::create(vm, globalObject, prototype, TypeInfo(WebAssemblyFunctionType, StructureFlags), info());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-WebAssemblyFunction::WebAssemblyFunction(VM&amp; vm, JSGlobalObject* globalObject, Structure* structure, Wasm::SignatureIndex signatureIndex)
</del><ins>+WebAssemblyFunction::WebAssemblyFunction(VM&amp; vm, JSGlobalObject* globalObject, Structure* structure, JSWebAssemblyCallee* wasmEntrypoint, Wasm::SignatureIndex signatureIndex)
</ins><span class="cx">     : Base(vm, globalObject, structure)
</span><ins>+    , m_wasmEntryPointCode(wasmEntrypoint-&gt;entrypoint())
</ins><span class="cx">     , m_signatureIndex(signatureIndex)
</span><span class="cx"> { }
</span><span class="cx"> 
</span><span class="lines">@@ -177,6 +179,7 @@
</span><span class="cx">     ASSERT(jsEntrypoint != wasmEntrypoint);
</span><span class="cx">     m_jsEntrypoint.set(vm, this, jsEntrypoint);
</span><span class="cx">     m_wasmEntrypoint.set(vm, this, wasmEntrypoint);
</span><ins>+    ASSERT(m_wasmEntrypoint-&gt;entrypoint() == m_wasmEntryPointCode);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmjsWebAssemblyFunctionh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.h (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.h        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.h        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -54,9 +54,12 @@
</span><span class="cx"> 
</span><span class="cx">     JSWebAssemblyInstance* instance() const { return m_instance.get(); }
</span><span class="cx">     Wasm::SignatureIndex signatureIndex() const { return m_signatureIndex; }
</span><del>-    void* wasmEntrypoint() { return m_wasmEntrypoint-&gt;entrypoint(); }
</del><ins>+    void* wasmEntrypoint() { return m_wasmEntryPointCode; }
</ins><span class="cx">     void* jsEntrypoint() { return m_jsEntrypoint-&gt;entrypoint(); }
</span><span class="cx"> 
</span><ins>+    static ptrdiff_t offsetOfInstance() { return OBJECT_OFFSETOF(WebAssemblyFunction, m_instance); }
+    static ptrdiff_t offsetOfWasmEntryPointCode() { return OBJECT_OFFSETOF(WebAssemblyFunction, m_wasmEntryPointCode); }
+
</ins><span class="cx"> protected:
</span><span class="cx">     static void visitChildren(JSCell*, SlotVisitor&amp;);
</span><span class="cx"> 
</span><span class="lines">@@ -63,9 +66,10 @@
</span><span class="cx">     void finishCreation(VM&amp;, NativeExecutable*, unsigned length, const String&amp; name, JSWebAssemblyInstance*, JSWebAssemblyCallee* jsEntrypoint, JSWebAssemblyCallee* wasmEntrypoint);
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    WebAssemblyFunction(VM&amp;, JSGlobalObject*, Structure*, Wasm::SignatureIndex);
</del><ins>+    WebAssemblyFunction(VM&amp;, JSGlobalObject*, Structure*, JSWebAssemblyCallee*, Wasm::SignatureIndex);
</ins><span class="cx"> 
</span><span class="cx">     WriteBarrier&lt;JSWebAssemblyInstance&gt; m_instance;
</span><ins>+    void* m_wasmEntryPointCode; // Cache code pointer: allows the wasm -&gt; wasm stub to do a single load and jump instead of having dependent loads.
</ins><span class="cx">     WriteBarrier&lt;JSWebAssemblyCallee&gt; m_jsEntrypoint;
</span><span class="cx">     WriteBarrier&lt;JSWebAssemblyCallee&gt; m_wasmEntrypoint;
</span><span class="cx">     Wasm::SignatureIndex m_signatureIndex;
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmjsWebAssemblyInstanceConstructorcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyInstanceConstructor.cpp (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyInstanceConstructor.cpp        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyInstanceConstructor.cpp        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -84,6 +84,11 @@
</span><span class="cx"> 
</span><span class="cx">     JSWebAssemblyInstance* instance = JSWebAssemblyInstance::create(vm, instanceStructure, jsModule, moduleRecord-&gt;getModuleNamespace(exec));
</span><span class="cx">     RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
</span><ins>+    {
+        // Always start with a dummy Memory, so that wasm -&gt; wasm thunks avoid checking for a nullptr Memory when trying to set pinned registers.
+        Wasm::Memory memory;
+        instance-&gt;setMemory(vm, JSWebAssemblyMemory::create(vm, exec-&gt;lexicalGlobalObject()-&gt;WebAssemblyMemoryStructure(), WTFMove(memory)));
+    }
</ins><span class="cx"> 
</span><span class="cx">     // Let funcs, memories and tables be initially-empty lists of callable JavaScript objects, WebAssembly.Memory objects and WebAssembly.Table objects, respectively.
</span><span class="cx">     // Let imports be an initially-empty list of external values.
</span><span class="lines">@@ -114,18 +119,19 @@
</span><span class="cx">                 return JSValue::encode(throwException(exec, throwScope, createJSWebAssemblyLinkError(exec, vm, ASCIILiteral(&quot;import function must be callable&quot;))));
</span><span class="cx">             JSCell* cell = value.asCell();
</span><span class="cx">             // ii. If v is an Exported Function Exotic Object:
</span><del>-            if (WebAssemblyFunction* importedExports = jsDynamicCast&lt;WebAssemblyFunction*&gt;(object)) {
-                // FIXME handle Function Exotic Object properly. https://bugs.webkit.org/show_bug.cgi?id=165282
-                // a. If the signature of v does not match the signature of i, throw a TypeError.
</del><ins>+            if (WebAssemblyFunction* importedExport = jsDynamicCast&lt;WebAssemblyFunction*&gt;(cell)) {
+                // a. If the signature of v does not match the signature of i, throw a WebAssembly.LinkError.
+                Wasm::SignatureIndex importedSignatureIndex = importedExport-&gt;signatureIndex();
+                Wasm::SignatureIndex expectedSignatureIndex = moduleInformation.importFunctionSignatureIndices[import.kindIndex];
+                if (importedSignatureIndex != expectedSignatureIndex)
+                    return JSValue::encode(throwException(exec, throwScope, createJSWebAssemblyLinkError(exec, vm, ASCIILiteral(&quot;imported function's signature doesn't match the provided WebAssembly function's signature&quot;))));
</ins><span class="cx">                 // b. Let closure be v.[[Closure]].
</span><del>-                RELEASE_ASSERT_NOT_REACHED();
-                UNUSED_PARAM(importedExports);
-                break;
</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="cx">             // Note: done as part of Plan compilation.
</span><span class="cx">             // iv. Append v to funcs.
</span><ins>+            // 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).
</ins><span class="cx">             instance-&gt;setImportFunction(vm, cell, numImportFunctions++);
</span><span class="cx">             // v. Append closure to imports.
</span><span class="cx">             break;
</span><span class="lines">@@ -230,7 +236,7 @@
</span><span class="cx">             RELEASE_ASSERT(!moduleInformation.memory.isImport());
</span><span class="cx">             // We create a memory when it's a memory definition.
</span><span class="cx">             bool failed;
</span><del>-            std::unique_ptr&lt;Wasm::Memory&gt; memory = std::make_unique&lt;Wasm::Memory&gt;(moduleInformation.memory.initial(), moduleInformation.memory.maximum(), failed);
</del><ins>+            Wasm::Memory memory(moduleInformation.memory.initial(), moduleInformation.memory.maximum(), failed);
</ins><span class="cx">             if (failed)
</span><span class="cx">                 return JSValue::encode(throwException(exec, throwScope, createOutOfMemoryError(exec)));
</span><span class="cx">             instance-&gt;setMemory(vm,
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmjsWebAssemblyMemoryConstructorcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyMemoryConstructor.cpp (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyMemoryConstructor.cpp        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyMemoryConstructor.cpp        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -97,7 +97,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     bool failed;
</span><del>-    std::unique_ptr&lt;Wasm::Memory&gt; memory = std::make_unique&lt;Wasm::Memory&gt;(initialPageCount, maximumPageCount, failed);
</del><ins>+    Wasm::Memory memory(initialPageCount, maximumPageCount, failed);
</ins><span class="cx">     if (failed)
</span><span class="cx">         return JSValue::encode(throwException(exec, throwScope, createOutOfMemoryError(exec)));
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmjsWebAssemblyModuleConstructorcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyModuleConstructor.cpp (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyModuleConstructor.cpp        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyModuleConstructor.cpp        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -97,7 +97,7 @@
</span><span class="cx"> 
</span><span class="cx">     // Only wasm-internal functions have a callee, stubs to JS do not.
</span><span class="cx">     unsigned calleeCount = plan.internalFunctionCount();
</span><del>-    JSWebAssemblyModule* result = JSWebAssemblyModule::create(vm, structure, plan.takeModuleInformation(), plan.takeCallLinkInfos(), plan.takeWasmToJSStubs(), plan.takeFunctionIndexSpace(), exportSymbolTable, calleeCount);
</del><ins>+    JSWebAssemblyModule* result = JSWebAssemblyModule::create(vm, structure, plan.takeModuleInformation(), plan.takeCallLinkInfos(), plan.takeWasmExitStubs(), exportSymbolTable, calleeCount);
</ins><span class="cx">     plan.initializeCallees(state-&gt;jsCallee()-&gt;globalObject(), 
</span><span class="cx">         [&amp;] (unsigned calleeIndex, JSWebAssemblyCallee* jsEntrypointCallee, JSWebAssemblyCallee* wasmEntrypointCallee) {
</span><span class="cx">             result-&gt;setJSEntrypointCallee(vm, calleeIndex, jsEntrypointCallee);
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmjsWebAssemblyModuleRecordcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp (210420 => 210421)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp        2017-01-06 01:49:23 UTC (rev 210420)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp        2017-01-06 01:49:36 UTC (rev 210421)
</span><span class="lines">@@ -118,7 +118,7 @@
</span><span class="cx">             //     c. Return func.
</span><span class="cx">             JSWebAssemblyCallee* jsEntrypointCallee = module-&gt;jsEntrypointCalleeFromFunctionIndexSpace(exp.kindIndex);
</span><span class="cx">             JSWebAssemblyCallee* wasmEntrypointCallee = module-&gt;wasmEntrypointCalleeFromFunctionIndexSpace(exp.kindIndex);
</span><del>-            Wasm::SignatureIndex signatureIndex = module-&gt;signatureForFunctionIndexSpace(exp.kindIndex);
</del><ins>+            Wasm::SignatureIndex signatureIndex = module-&gt;signatureIndexFromFunctionIndexSpace(exp.kindIndex);
</ins><span class="cx">             const Wasm::Signature* signature = Wasm::SignatureInformation::get(&amp;vm, signatureIndex);
</span><span class="cx">             WebAssemblyFunction* function = WebAssemblyFunction::create(vm, globalObject, signature-&gt;argumentCount(), exp.field.string(), instance, jsEntrypointCallee, wasmEntrypointCallee, signatureIndex);
</span><span class="cx">             exportedValue = function;
</span><span class="lines">@@ -133,8 +133,6 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         case Wasm::ExternalKind::Memory: {
</span><del>-            // This should be guaranteed by module verification.
-            RELEASE_ASSERT(instance-&gt;memory()); 
</del><span class="cx">             ASSERT(exp.kindIndex == 0);
</span><span class="cx"> 
</span><span class="cx">             exportedValue = instance-&gt;memory();
</span><span class="lines">@@ -175,7 +173,7 @@
</span><span class="cx">     bool hasStart = !!moduleInformation.startFunctionIndexSpace;
</span><span class="cx">     if (hasStart) {
</span><span class="cx">         auto startFunctionIndexSpace = moduleInformation.startFunctionIndexSpace.value_or(0);
</span><del>-        Wasm::SignatureIndex signatureIndex = module-&gt;signatureForFunctionIndexSpace(startFunctionIndexSpace);
</del><ins>+        Wasm::SignatureIndex signatureIndex = module-&gt;signatureIndexFromFunctionIndexSpace(startFunctionIndexSpace);
</ins><span class="cx">         const Wasm::Signature* signature = Wasm::SignatureInformation::get(&amp;vm, signatureIndex);
</span><span class="cx">         // The start function must not take any arguments or return anything. This is enforced by the parser.
</span><span class="cx">         ASSERT(!signature-&gt;argumentCount());
</span><span class="lines">@@ -238,7 +236,7 @@
</span><span class="cx"> 
</span><span class="cx">                 JSWebAssemblyCallee* jsEntrypointCallee = module-&gt;jsEntrypointCalleeFromFunctionIndexSpace(functionIndex);
</span><span class="cx">                 JSWebAssemblyCallee* wasmEntrypointCallee = module-&gt;wasmEntrypointCalleeFromFunctionIndexSpace(functionIndex);
</span><del>-                Wasm::SignatureIndex signatureIndex = module-&gt;signatureForFunctionIndexSpace(functionIndex);
</del><ins>+                Wasm::SignatureIndex signatureIndex = module-&gt;signatureIndexFromFunctionIndexSpace(functionIndex);
</ins><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 funciton index 0.
</span><span class="cx">                 // What if we also set it to the table an Element w/ index 0.
</span><span class="lines">@@ -257,7 +255,6 @@
</span><span class="cx">         const Vector&lt;Wasm::Segment::Ptr&gt;&amp; data = m_instance-&gt;module()-&gt;moduleInformation().data;
</span><span class="cx">         JSWebAssemblyMemory* jsMemory = m_instance-&gt;memory();
</span><span class="cx">         if (!data.isEmpty()) {
</span><del>-            RELEASE_ASSERT(jsMemory); // It is a validation error for a Data section to exist without a Memory section or import.
</del><span class="cx">             uint8_t* memory = reinterpret_cast&lt;uint8_t*&gt;(jsMemory-&gt;memory()-&gt;memory());
</span><span class="cx">             uint64_t sizeInBytes = jsMemory-&gt;memory()-&gt;size();
</span><span class="cx">             for (auto&amp; segment : data) {
</span></span></pre>
</div>
</div>

</body>
</html>