<!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>[210402] 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/210402">210402</a></dd>
<dt>Author</dt> <dd>matthew_hanson@apple.com</dd>
<dt>Date</dt> <dd>2017-01-05 17:47:27 -0800 (Thu, 05 Jan 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/210026">r210026</a>. rdar://problem/29735737</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchessafari603branchJSTestsChangeLog">branches/safari-603-branch/JSTests/ChangeLog</a></li>
<li><a href="#branchessafari603branchJSTestswasmfunctionteststablebasicjs">branches/safari-603-branch/JSTests/wasm/function-tests/table-basic.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="#branchessafari603branchSourceJavaScriptCoreruntimeVMh">branches/safari-603-branch/Source/JavaScriptCore/runtime/VM.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmWasmB3IRGeneratorcpp">branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp</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="#branchessafari603branchSourceJavaScriptCorewasmWasmCallingConventionh">branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmCallingConvention.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmWasmFormatcpp">branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmFormat.cpp</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="#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="#branchessafari603branchSourceJavaScriptCorewasmWasmParserh">branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmParser.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmWasmPlancpp">branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmPlan.cpp</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="#branchessafari603branchSourceJavaScriptCorewasmjsJSWebAssemblyInstancecpp">branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmjsJSWebAssemblyModuleh">branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.h</a></li>
<li><a href="#branchessafari603branchSourceJavaScriptCorewasmjsJSWebAssemblyTablecpp">branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.cpp</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="#branchessafari603branchSourceJavaScriptCorewasmjsWebAssemblyModuleRecordcpp">branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#branchessafari603branchJSTestswasmjsapiuniquesignaturejs">branches/safari-603-branch/JSTests/wasm/js-api/unique-signature.js</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>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchessafari603branchJSTestsChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/JSTests/ChangeLog (210401 => 210402)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/JSTests/ChangeLog        2017-01-06 01:47:16 UTC (rev 210401)
+++ branches/safari-603-branch/JSTests/ChangeLog        2017-01-06 01:47:27 UTC (rev 210402)
</span><span class="lines">@@ -1,5 +1,24 @@
</span><span class="cx"> 2017-01-05  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Merge r210026. rdar://problem/29735737
+
+    2016-12-20  JF Bastien  &lt;jfbastien@apple.com&gt;
+
+            WebAssembly: unique function signatures
+            https://bugs.webkit.org/show_bug.cgi?id=165957
+            &lt;rdar://problem/29735737&gt;
+
+            Reviewed by Saam Barati.
+
+            * wasm/function-tests/table-basic.js: FIXME is now addressed,
+            though instance to instance calls still need work which bug
+            #165282 will address
+            (i.assert.eq.foo):
+            * wasm/js-api/unique-signature.js: Added.
+            (CallIndirectWithDuplicateSignatures):
+
+2017-01-05  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
+
</ins><span class="cx">         Merge r209979. rdar://problem/29735737
</span><span class="cx"> 
</span><span class="cx">     2016-12-18  Saam Barati  &lt;sbarati@apple.com&gt;
</span></span></pre></div>
<a id="branchessafari603branchJSTestswasmfunctionteststablebasicjs"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/JSTests/wasm/function-tests/table-basic.js (210401 => 210402)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/JSTests/wasm/function-tests/table-basic.js        2017-01-06 01:47:16 UTC (rev 210401)
+++ branches/safari-603-branch/JSTests/wasm/function-tests/table-basic.js        2017-01-06 01:47:27 UTC (rev 210402)
</span><span class="lines">@@ -44,21 +44,15 @@
</span><span class="cx">     table.set(0, exports.bar);
</span><span class="cx">     assert.eq(table.get(0), exports.bar);
</span><span class="cx"> 
</span><del>-    for (let i = 0; i &lt; 1000; i++) {
-        if (foo(0, i) !== i + 42)
-            throw new Error(&quot;Bad call indirect&quot;);
-    }
</del><ins>+    for (let i = 0; i &lt; 1000; i++)
+        assert.eq(foo(0, i), i + 42, &quot;call_indirect&quot;);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-// FIXME: make this work cross module. The reason it doesn't
-// now is that we don't unique Signature*.
-// https://bugs.webkit.org/show_bug.cgi?id=165511
</del><span class="cx"> {
</span><span class="cx">     const {instance, table} = makeInstance();
</span><span class="cx">     const foo = instance.exports.foo;
</span><span class="cx">     table.set(0, makeInstance().instance.exports.bar); // Cross instance function.
</span><span class="cx"> 
</span><del>-    for (let i = 0; i &lt; 1000; i++) {
-        assert.throws(() =&gt; foo(0, i), WebAssembly.RuntimeError, &quot;call_indirect to a signature that does not match&quot;);
-    }
</del><ins>+    for (let i = 0; i &lt; 1000; i++)
+        assert.eq(foo(0, i), i + 42, &quot;call_indirect&quot;);
</ins><span class="cx"> }
</span></span></pre></div>
<a id="branchessafari603branchJSTestswasmjsapiuniquesignaturejs"></a>
<div class="addfile"><h4>Added: branches/safari-603-branch/JSTests/wasm/js-api/unique-signature.js (0 => 210402)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/JSTests/wasm/js-api/unique-signature.js                                (rev 0)
+++ branches/safari-603-branch/JSTests/wasm/js-api/unique-signature.js        2017-01-06 01:47:27 UTC (rev 210402)
</span><span class="lines">@@ -0,0 +1,49 @@
</span><ins>+import * as assert from '../assert.js';
+import Builder from '../Builder.js';
+
+(function CallIndirectWithDuplicateSignatures() {
+    const builder = (new Builder())
+        .Type()
+            .Func([&quot;i32&quot;], &quot;i32&quot;)         // 0
+            .Func([&quot;i32&quot;], &quot;i32&quot;)         // 1
+            .Func([&quot;i32&quot;, &quot;i32&quot;], &quot;i32&quot;)  // 2
+            .Func([&quot;i32&quot;], &quot;i32&quot;)         // 3
+            .Func([&quot;i32&quot;], &quot;i32&quot;)         // 4
+            .Func([&quot;i32&quot;, &quot;i32&quot;], &quot;i32&quot;)  // 5
+            .Func([&quot;f64&quot;, &quot;f64&quot;], &quot;f64&quot;)  // 6
+            .Func([&quot;i32&quot;], &quot;f64&quot;)         // 7
+            .Func([&quot;i32&quot;], &quot;f64&quot;)         // 8
+        .End()
+        .Function().End()
+        .Table()
+            .Table({initial: 4, maximum: 4, element: &quot;anyfunc&quot;})
+        .End()
+        .Export()
+            .Function(&quot;entry&quot;)
+            .Table(&quot;table&quot;, 0)
+            .Function(&quot;callMe&quot;)
+        .End()
+        .Code()
+            .Function(&quot;entry&quot;, 1)
+                .I32Const(42)
+                .GetLocal(0)
+                .I32Add()
+                .I32Const(0) // Function index 0.
+                .CallIndirect(4, 0) // Different signature index, but same signature.
+                .Return()
+            .End()
+            .Function(&quot;callMe&quot;, 3)
+                .I32Const(3)
+                .GetLocal(0)
+                .I32Add()
+                .Return()
+            .End()
+        .End();
+    const bin = builder.WebAssembly().get();
+    const module = new WebAssembly.Module(bin);
+    let value0 = undefined;
+    const instance = new WebAssembly.Instance(module);
+    let table = instance.exports.table;
+    table.set(0, instance.exports.callMe);
+    assert.eq(instance.exports.entry(5), 5 + 42 + 3);
+}());
</ins></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/CMakeLists.txt (210401 => 210402)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/CMakeLists.txt        2017-01-06 01:47:16 UTC (rev 210401)
+++ branches/safari-603-branch/Source/JavaScriptCore/CMakeLists.txt        2017-01-06 01:47:27 UTC (rev 210402)
</span><span class="lines">@@ -907,6 +907,7 @@
</span><span class="cx">     wasm/WasmMemoryInformation.cpp
</span><span class="cx">     wasm/WasmModuleParser.cpp
</span><span class="cx">     wasm/WasmPlan.cpp
</span><ins>+    wasm/WasmSignature.cpp
</ins><span class="cx">     wasm/WasmValidate.cpp
</span><span class="cx"> 
</span><span class="cx">     wasm/js/JSWebAssemblyCallee.cpp
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/ChangeLog (210401 => 210402)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/ChangeLog        2017-01-06 01:47:16 UTC (rev 210401)
+++ branches/safari-603-branch/Source/JavaScriptCore/ChangeLog        2017-01-06 01:47:27 UTC (rev 210402)
</span><span class="lines">@@ -1,5 +1,124 @@
</span><span class="cx"> 2017-01-05  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Merge r210026. rdar://problem/29735737
+
+    2016-12-20  JF Bastien  &lt;jfbastien@apple.com&gt;
+
+            WebAssembly: unique function signatures
+            https://bugs.webkit.org/show_bug.cgi?id=165957
+            &lt;rdar://problem/29735737&gt;
+
+            Reviewed by Saam Barati.
+
+            Signatures in a Module's Type section can be duplicated, we
+            therefore need to unique them so that call_indirect only needs to
+            do a single integer compare to check that a callee's Signature is
+            the same as the Signature declared at the call site. Without
+            uniquing we'd either trap when duplicate Signatures are used, or
+            we'd need to do multiple comparisons. This patch makes that narrow
+            usecase function correctly.
+
+            There's further complication when calling from wasm to
+            wasm, in which case the Signatures must also match. Such
+            cross-instance calls will be improved in bug #165282, but this
+            patch sets the groundwork for it:
+
+            - Signatures are now owned by SignatureInformation which lives on
+              VM, and is shared by all Modules.
+            - When parsing a Module, a Signature is created for every Type
+              entry, and then uniqued by SignatureInformation's adopt
+              method. Duplicate Signatures are dropped and the previous
+              SignatureIndex is returned, new Signatures are adopted and a new
+              SignatureIndex is created.
+            - The SignatureIndex values are monotonic. 0 is used to represent
+              invalid indices, which trap. This can only occur through Table.
+            - SignatureInformation is used while generating code to map a
+              SignatureIndex back to the Signature* when return / argument
+              information is needed. This is a simple lookup into a Vector. It
+              isn't used at runtime.
+            - These Signatures live forever on VM because the bookkeeping
+              likely isn't worth it. We may want to empty things out if all
+              Modules die, this is tracked in bug #166037.
+            - We can further improve things by bit-packing SignatureIndex with
+              Code*, which is tracked by bug #165511.
+
+            * CMakeLists.txt:
+            * JavaScriptCore.xcodeproj/project.pbxproj:
+            * runtime/VM.h: wasm signatures are uniqued here, but aren't accessed frequently (only during parsing) so indirection is fine
+            * wasm/WasmB3IRGenerator.cpp: use SignatureIndex instead of Signature* when appropriate, and when still using Signature* do so with its new API
+            (JSC::Wasm::createJSToWasmWrapper):
+            (JSC::Wasm::parseAndCompile):
+            * wasm/WasmBinding.cpp:
+            (JSC::Wasm::importStubGenerator): use SignatureIndex
+            * wasm/WasmBinding.h:
+            * wasm/WasmCallingConvention.h:
+            (JSC::Wasm::CallingConvention::loadArguments):
+            * wasm/WasmFormat.cpp: drive-by move of alloc/free functions to the implementation file, allows the .h file to drop an FastMalloc.h
+            (JSC::Wasm::Segment::create):
+            (JSC::Wasm::Segment::destroy):
+            (JSC::Wasm::Segment::createPtr):
+            * wasm/WasmFormat.h: move Signature to its own file
+            (JSC::Wasm::CallableFunction::CallableFunction):
+            * wasm/WasmFunctionParser.h:
+            (JSC::Wasm::FunctionParser&lt;Context&gt;::FunctionParser):
+            * wasm/WasmModuleParser.cpp:
+            * wasm/WasmModuleParser.h:
+            (JSC::Wasm::ModuleParser::ModuleParser):
+            * wasm/WasmParser.h:
+            (JSC::Wasm::Parser&lt;SuccessType&gt;::Parser):
+            * wasm/WasmPlan.cpp:
+            (JSC::Wasm::Plan::parseAndValidateModule):
+            (JSC::Wasm::Plan::run):
+            * wasm/WasmSignature.cpp: Added.
+            (JSC::Wasm::Signature::dump):
+            (JSC::Wasm::Signature::hash):
+            (JSC::Wasm::Signature::create):
+            (JSC::Wasm::Signature::createInvalid):
+            (JSC::Wasm::Signature::destroy):
+            (JSC::Wasm::SignatureInformation::~SignatureInformation):
+            (JSC::Wasm::SignatureInformation::adopt):
+            (JSC::Wasm::SignatureInformation::get):
+            * wasm/WasmSignature.h: Added.
+            (JSC::Wasm::Signature::Signature):
+            (JSC::Wasm::Signature::storage):
+            (JSC::Wasm::Signature::allocatedSize):
+            (JSC::Wasm::Signature::returnType):
+            (JSC::Wasm::Signature::returnCount):
+            (JSC::Wasm::Signature::argumentCount):
+            (JSC::Wasm::Signature::argument):
+            (JSC::Wasm::Signature::operator==):
+            (JSC::Wasm::SignatureHash::empty):
+            (JSC::Wasm::SignatureHash::deleted):
+            (JSC::Wasm::SignatureHash::SignatureHash):
+            (JSC::Wasm::SignatureHash::operator==):
+            (JSC::Wasm::SignatureHash::equal):
+            (JSC::Wasm::SignatureHash::hash):
+            (JSC::Wasm::SignatureHash::isHashTableDeletedValue):
+            * wasm/WasmValidate.cpp:
+            (JSC::Wasm::validateFunction):
+            * wasm/WasmValidate.h:
+            * wasm/js/JSWebAssemblyInstance.cpp:
+            (JSC::JSWebAssemblyInstance::create):
+            * wasm/js/JSWebAssemblyModule.h:
+            (JSC::JSWebAssemblyModule::signatureForFunctionIndexSpace):
+            * wasm/js/JSWebAssemblyTable.cpp:
+            (JSC::JSWebAssemblyTable::JSWebAssemblyTable):
+            (JSC::JSWebAssemblyTable::clearFunction):
+            (JSC::JSWebAssemblyTable::setFunction):
+            * wasm/js/WebAssemblyFunction.cpp:
+            (JSC::callWebAssemblyFunction):
+            (JSC::WebAssemblyFunction::call):
+            (JSC::WebAssemblyFunction::create):
+            (JSC::WebAssemblyFunction::WebAssemblyFunction):
+            (JSC::WebAssemblyFunction::finishCreation):
+            * wasm/js/WebAssemblyFunction.h:
+            (JSC::WebAssemblyFunction::signatureIndex):
+            * wasm/js/WebAssemblyModuleRecord.cpp:
+            (JSC::WebAssemblyModuleRecord::link):
+            (JSC::WebAssemblyModuleRecord::evaluate):
+
+2017-01-05  Matthew Hanson  &lt;matthew_hanson@apple.com&gt;
+
</ins><span class="cx">         Merge r209979. rdar://problem/29735737
</span><span class="cx"> 
</span><span class="cx">     2016-12-18  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 (210401 => 210402)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2017-01-06 01:47:16 UTC (rev 210401)
+++ branches/safari-603-branch/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2017-01-06 01:47:27 UTC (rev 210402)
</span><span class="lines">@@ -2022,6 +2022,8 @@
</span><span class="cx">                 AD4937D41DDD27DE0077C807 /* WebAssemblyFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = AD4937CA1DDD27340077C807 /* WebAssemblyFunction.h */; };
</span><span class="cx">                 AD4B1DF91DF244E20071AE32 /* WasmBinding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD4B1DF71DF244D70071AE32 /* WasmBinding.cpp */; };
</span><span class="cx">                 AD4B1DFA1DF244E20071AE32 /* WasmBinding.h in Headers */ = {isa = PBXBuildFile; fileRef = AD4B1DF81DF244D70071AE32 /* WasmBinding.h */; };
</span><ins>+                AD7438C01E0457A400FD0C2A /* WasmSignature.h in Headers */ = {isa = PBXBuildFile; fileRef = AD7438BF1E04579200FD0C2A /* WasmSignature.h */; settings = {ATTRIBUTES = (Private, ); }; };
+                AD7438C11E0457AA00FD0C2A /* WasmSignature.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD7438BE1E04579200FD0C2A /* WasmSignature.cpp */; };
</ins><span class="cx">                 AD86A93E1AA4D88D002FE77F /* WeakGCMapInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = AD86A93D1AA4D87C002FE77F /* WeakGCMapInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><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="lines">@@ -4504,6 +4506,8 @@
</span><span class="cx">                 AD4937CA1DDD27340077C807 /* WebAssemblyFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebAssemblyFunction.h; path = js/WebAssemblyFunction.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 AD4B1DF71DF244D70071AE32 /* WasmBinding.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmBinding.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 AD4B1DF81DF244D70071AE32 /* WasmBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmBinding.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                AD7438BE1E04579200FD0C2A /* WasmSignature.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmSignature.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                AD7438BF1E04579200FD0C2A /* WasmSignature.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmSignature.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 AD86A93D1AA4D87C002FE77F /* WeakGCMapInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WeakGCMapInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><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="lines">@@ -6046,6 +6050,8 @@
</span><span class="cx">                                 531374BE1D5CE95000AF7A0B /* WasmPlan.cpp */,
</span><span class="cx">                                 531374BC1D5CE67600AF7A0B /* WasmPlan.h */,
</span><span class="cx">                                 53F40E841D58F9770099A1B6 /* WasmSections.h */,
</span><ins>+                                AD7438BE1E04579200FD0C2A /* WasmSignature.cpp */,
+                                AD7438BF1E04579200FD0C2A /* WasmSignature.h */,
</ins><span class="cx">                                 53FF7F9A1DBFD2B900A26CCC /* WasmValidate.cpp */,
</span><span class="cx">                                 53FF7F981DBFCD9000A26CCC /* WasmValidate.h */,
</span><span class="cx">                         );
</span><span class="lines">@@ -8070,6 +8076,7 @@
</span><span class="cx">                                 0F3B3A281544C997003ED0FF /* DFGCFGSimplificationPhase.h in Headers */,
</span><span class="cx">                                 0F9D36951AE9CC33000D4DFB /* DFGCleanUpPhase.h in Headers */,
</span><span class="cx">                                 A77A424017A0BBFD00A8DB81 /* DFGClobberize.h in Headers */,
</span><ins>+                                AD7438C01E0457A400FD0C2A /* WasmSignature.h in Headers */,
</ins><span class="cx">                                 A77A424217A0BBFD00A8DB81 /* DFGClobberSet.h in Headers */,
</span><span class="cx">                                 0F3C1F1B1B868E7900ABB08B /* DFGClobbersExitState.h in Headers */,
</span><span class="cx">                                 0F04396E1B03DC0B009598B7 /* DFGCombinedLiveness.h in Headers */,
</span><span class="lines">@@ -10417,6 +10424,7 @@
</span><span class="cx">                                 FED94F2E171E3E2300BE77A4 /* Watchdog.cpp in Sources */,
</span><span class="cx">                                 0F919D2515853CE0004A4E7D /* Watchpoint.cpp in Sources */,
</span><span class="cx">                                 1ACF7377171CA6FB00C9BB1E /* Weak.cpp in Sources */,
</span><ins>+                                AD7438C11E0457AA00FD0C2A /* WasmSignature.cpp in Sources */,
</ins><span class="cx">                                 14E84F9E14EE1ACC00D6D5D4 /* WeakBlock.cpp in Sources */,
</span><span class="cx">                                 14F7256514EE265E00B1652B /* WeakHandleOwner.cpp in Sources */,
</span><span class="cx">                                 A7CA3AE317DA41AE006538AF /* WeakMapConstructor.cpp in Sources */,
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCoreruntimeVMh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/runtime/VM.h (210401 => 210402)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/runtime/VM.h        2017-01-06 01:47:16 UTC (rev 210401)
+++ branches/safari-603-branch/Source/JavaScriptCore/runtime/VM.h        2017-01-06 01:47:27 UTC (rev 210402)
</span><span class="lines">@@ -147,6 +147,11 @@
</span><span class="cx"> namespace DOMJIT {
</span><span class="cx"> class Signature;
</span><span class="cx"> }
</span><ins>+#if ENABLE(WEBASSEMBLY)
+namespace Wasm {
+class SignatureInformation;
+}
+#endif
</ins><span class="cx"> 
</span><span class="cx"> struct HashTable;
</span><span class="cx"> struct Instruction;
</span><span class="lines">@@ -354,6 +359,11 @@
</span><span class="cx">     Strong&lt;JSCell&gt; iterationTerminator;
</span><span class="cx">     Strong&lt;JSCell&gt; emptyPropertyNameEnumerator;
</span><span class="cx"> 
</span><ins>+#if ENABLE(WEBASSEMBLY)
+    std::once_flag m_wasmSignatureInformationOnceFlag;
+    std::unique_ptr&lt;Wasm::SignatureInformation&gt; m_wasmSignatureInformation;
+#endif
+
</ins><span class="cx">     AtomicStringTable* m_atomicStringTable;
</span><span class="cx">     WTF::SymbolRegistry m_symbolRegistry;
</span><span class="cx">     TemplateRegistryKeyTable m_templateRegistryKeytable;
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmWasmB3IRGeneratorcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp (210401 => 210402)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp        2017-01-06 01:47:16 UTC (rev 210401)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp        2017-01-06 01:47:27 UTC (rev 210402)
</span><span class="lines">@@ -154,7 +154,7 @@
</span><span class="cx"> 
</span><span class="cx">     B3IRGenerator(VM&amp;, const ModuleInformation&amp;, Procedure&amp;, WasmInternalFunction*, Vector&lt;UnlinkedWasmToWasmCall&gt;&amp;, const ImmutableFunctionIndexSpace&amp;);
</span><span class="cx"> 
</span><del>-    PartialResult WARN_UNUSED_RETURN addArguments(const Vector&lt;Type&gt;&amp;);
</del><ins>+    PartialResult WARN_UNUSED_RETURN addArguments(const Signature*);
</ins><span class="cx">     PartialResult WARN_UNUSED_RETURN addLocal(Type, uint32_t);
</span><span class="cx">     ExpressionType addConstant(Type, uint64_t);
</span><span class="cx"> 
</span><span class="lines">@@ -192,7 +192,7 @@
</span><span class="cx"> 
</span><span class="cx">     // Calls
</span><span class="cx">     PartialResult WARN_UNUSED_RETURN addCall(uint32_t calleeIndex, const Signature*, Vector&lt;ExpressionType&gt;&amp; args, ExpressionType&amp; result);
</span><del>-    PartialResult WARN_UNUSED_RETURN addCallIndirect(const Signature*, Vector&lt;ExpressionType&gt;&amp; args, ExpressionType&amp; result);
</del><ins>+    PartialResult WARN_UNUSED_RETURN addCallIndirect(const Signature*, SignatureIndex, Vector&lt;ExpressionType&gt;&amp; args, ExpressionType&amp; result);
</ins><span class="cx">     PartialResult WARN_UNUSED_RETURN addUnreachable();
</span><span class="cx"> 
</span><span class="cx">     void dump(const Vector&lt;ControlEntry&gt;&amp; controlStack, const ExpressionList&amp; expressionStack);
</span><span class="lines">@@ -302,13 +302,13 @@
</span><span class="cx">     return { };
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-auto B3IRGenerator::addArguments(const Vector&lt;Type&gt;&amp; types) -&gt; PartialResult
</del><ins>+auto B3IRGenerator::addArguments(const Signature* signature) -&gt; PartialResult
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(!m_locals.size());
</span><del>-    WASM_COMPILE_FAIL_IF(!m_locals.tryReserveCapacity(types.size()), &quot;can't allocate memory for &quot;, types.size(), &quot; arguments&quot;);
</del><ins>+    WASM_COMPILE_FAIL_IF(!m_locals.tryReserveCapacity(signature-&gt;argumentCount()), &quot;can't allocate memory for &quot;, signature-&gt;argumentCount(), &quot; arguments&quot;);
</ins><span class="cx"> 
</span><del>-    m_locals.grow(types.size());
-    wasmCallingConvention().loadArguments(types, m_proc, m_currentBlock, Origin(),
</del><ins>+    m_locals.grow(signature-&gt;argumentCount());
+    wasmCallingConvention().loadArguments(signature, m_proc, m_currentBlock, Origin(),
</ins><span class="cx">         [&amp;] (ExpressionType argument, unsigned i) {
</span><span class="cx">             Variable* argumentVariable = m_proc.addVariable(argument-&gt;type());
</span><span class="cx">             m_locals[i] = argumentVariable;
</span><span class="lines">@@ -682,9 +682,9 @@
</span><span class="cx"> 
</span><span class="cx"> auto B3IRGenerator::addCall(uint32_t functionIndex, const Signature* signature, Vector&lt;ExpressionType&gt;&amp; args, ExpressionType&amp; result) -&gt; PartialResult
</span><span class="cx"> {
</span><del>-    ASSERT(signature-&gt;arguments.size() == args.size());
</del><ins>+    ASSERT(signature-&gt;argumentCount() == args.size());
</ins><span class="cx"> 
</span><del>-    Type returnType = signature-&gt;returnType;
</del><ins>+    Type returnType = signature-&gt;returnType();
</ins><span class="cx"> 
</span><span class="cx">     result = wasmCallingConvention().setupCall(m_proc, m_currentBlock, Origin(), args, toB3Type(returnType),
</span><span class="cx">         [&amp;] (PatchpointValue* patchpoint) {
</span><span class="lines">@@ -704,10 +704,11 @@
</span><span class="cx">     return { };
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-auto B3IRGenerator::addCallIndirect(const Signature* signature, Vector&lt;ExpressionType&gt;&amp; args, ExpressionType&amp; result) -&gt; PartialResult
</del><ins>+auto B3IRGenerator::addCallIndirect(const Signature* signature, SignatureIndex signatureIndex, Vector&lt;ExpressionType&gt;&amp; args, ExpressionType&amp; result) -&gt; PartialResult
</ins><span class="cx"> {
</span><ins>+    ASSERT(signatureIndex != Signature::invalidIndex);
</ins><span class="cx">     ExpressionType calleeIndex = args.takeLast();
</span><del>-    ASSERT(signature-&gt;arguments.size() == args.size());
</del><ins>+    ASSERT(signature-&gt;argumentCount() == args.size());
</ins><span class="cx"> 
</span><span class="cx">     ExpressionType callableFunctionBuffer;
</span><span class="cx">     ExpressionType callableFunctionBufferSize;
</span><span class="lines">@@ -736,13 +737,14 @@
</span><span class="cx">         m_currentBlock-&gt;appendIntConstant(m_proc, Origin(), pointerType(), sizeof(CallableFunction)));
</span><span class="cx">     ExpressionType callableFunction = m_currentBlock-&gt;appendNew&lt;Value&gt;(m_proc, Add, Origin(), callableFunctionBuffer, offset);
</span><span class="cx"> 
</span><del>-    // Check that the CallableFunction is initialized. We trap if it isn't. A null Signature* indicates it's not initialized.
-    ExpressionType calleeSignature = m_currentBlock-&gt;appendNew&lt;MemoryValue&gt;(m_proc, Load, pointerType(), Origin(), callableFunction, OBJECT_OFFSETOF(CallableFunction, signature));
</del><ins>+    // Check that the CallableFunction is initialized. We trap if it isn't. An &quot;invalid&quot; SignatureIndex indicates it's not initialized.
+    static_assert(sizeof(CallableFunction::signatureIndex) == sizeof(uint32_t), &quot;Load codegen assumes i32&quot;);
+    ExpressionType calleeSignatureIndex = m_currentBlock-&gt;appendNew&lt;MemoryValue&gt;(m_proc, Load, Int32, Origin(), callableFunction, OBJECT_OFFSETOF(CallableFunction, signatureIndex));
</ins><span class="cx">     {
</span><span class="cx">         CheckValue* check = m_currentBlock-&gt;appendNew&lt;CheckValue&gt;(m_proc, Check, Origin(),
</span><del>-            m_currentBlock-&gt;appendNew&lt;Value&gt;(m_proc, Equal, Origin(), 
-                calleeSignature, 
-                m_currentBlock-&gt;appendNew&lt;ConstPtrValue&gt;(m_proc, Origin(), 0)));
</del><ins>+            m_currentBlock-&gt;appendNew&lt;Value&gt;(m_proc, Equal, Origin(),
+                calleeSignatureIndex,
+                m_currentBlock-&gt;appendNew&lt;Const32Value&gt;(m_proc, Origin(), Signature::invalidIndex)));
</ins><span class="cx"> 
</span><span class="cx">         check-&gt;setGenerator([=] (CCallHelpers&amp; jit, const B3::StackmapGenerationParams&amp;) {
</span><span class="cx">             this-&gt;emitExceptionCheck(jit, ExceptionType::NullTableEntry);
</span><span class="lines">@@ -751,9 +753,9 @@
</span><span class="cx"> 
</span><span class="cx">     // Check the signature matches the value we expect.
</span><span class="cx">     {
</span><del>-        ExpressionType expectedSignature = m_currentBlock-&gt;appendNew&lt;ConstPtrValue&gt;(m_proc, Origin(), signature);
</del><ins>+        ExpressionType expectedSignatureIndex = m_currentBlock-&gt;appendNew&lt;Const32Value&gt;(m_proc, Origin(), signatureIndex);
</ins><span class="cx">         CheckValue* check = m_currentBlock-&gt;appendNew&lt;CheckValue&gt;(m_proc, Check, Origin(),
</span><del>-            m_currentBlock-&gt;appendNew&lt;Value&gt;(m_proc, NotEqual, Origin(), calleeSignature, expectedSignature));
</del><ins>+            m_currentBlock-&gt;appendNew&lt;Value&gt;(m_proc, NotEqual, Origin(), calleeSignatureIndex, expectedSignatureIndex));
</ins><span class="cx"> 
</span><span class="cx">         check-&gt;setGenerator([=] (CCallHelpers&amp; jit, const B3::StackmapGenerationParams&amp;) {
</span><span class="cx">             this-&gt;emitExceptionCheck(jit, ExceptionType::BadSignature);
</span><span class="lines">@@ -762,7 +764,7 @@
</span><span class="cx"> 
</span><span class="cx">     ExpressionType calleeCode = m_currentBlock-&gt;appendNew&lt;MemoryValue&gt;(m_proc, Load, pointerType(), Origin(), callableFunction, OBJECT_OFFSETOF(CallableFunction, code));
</span><span class="cx"> 
</span><del>-    Type returnType = signature-&gt;returnType;
</del><ins>+    Type returnType = signature-&gt;returnType();
</ins><span class="cx">     result = wasmCallingConvention().setupCall(m_proc, m_currentBlock, Origin(), args, toB3Type(returnType),
</span><span class="cx">         [&amp;] (PatchpointValue* patchpoint) {
</span><span class="cx">             patchpoint-&gt;effects.writesPinned = true;
</span><span class="lines">@@ -834,7 +836,7 @@
</span><span class="cx">         Value* argumentCount = block-&gt;appendNew&lt;MemoryValue&gt;(proc, Load, Int32, origin,
</span><span class="cx">             block-&gt;appendNew&lt;Value&gt;(proc, Add, origin, framePointer, offSetOfArgumentCount));
</span><span class="cx"> 
</span><del>-        Value* expectedArgumentCount = block-&gt;appendNew&lt;Const32Value&gt;(proc, origin, signature-&gt;arguments.size());
</del><ins>+        Value* expectedArgumentCount = block-&gt;appendNew&lt;Const32Value&gt;(proc, origin, signature-&gt;argumentCount());
</ins><span class="cx"> 
</span><span class="cx">         CheckValue* argumentCountCheck = block-&gt;appendNew&lt;CheckValue&gt;(proc, Check, origin,
</span><span class="cx">             block-&gt;appendNew&lt;Value&gt;(proc, Above, origin, expectedArgumentCount, argumentCount));
</span><span class="lines">@@ -861,12 +863,12 @@
</span><span class="cx"> 
</span><span class="cx">     // Get our arguments.
</span><span class="cx">     Vector&lt;Value*&gt; arguments;
</span><del>-    jscCallingConvention().loadArguments(signature-&gt;arguments, proc, block, origin, [&amp;] (Value* argument, unsigned) {
</del><ins>+    jscCallingConvention().loadArguments(signature, proc, block, origin, [&amp;] (Value* argument, unsigned) {
</ins><span class="cx">         arguments.append(argument);
</span><span class="cx">     });
</span><span class="cx"> 
</span><span class="cx">     // Move the arguments into place.
</span><del>-    Value* result = wasmCallingConvention().setupCall(proc, block, origin, arguments, toB3Type(signature-&gt;returnType), [&amp;] (PatchpointValue* patchpoint) {
</del><ins>+    Value* result = wasmCallingConvention().setupCall(proc, block, origin, arguments, toB3Type(signature-&gt;returnType()), [&amp;] (PatchpointValue* patchpoint) {
</ins><span class="cx">         if (!!memory) {
</span><span class="cx">             ASSERT(sizes.size() == memory.pinnedRegisters().sizeRegisters.size());
</span><span class="cx">             patchpoint-&gt;append(ConstrainedValue(baseMemory, ValueRep::reg(memory.pinnedRegisters().baseMemoryPointer)));
</span><span class="lines">@@ -885,7 +887,7 @@
</span><span class="cx">     });
</span><span class="cx"> 
</span><span class="cx">     // Return the result, if needed.
</span><del>-    switch (signature-&gt;returnType) {
</del><ins>+    switch (signature-&gt;returnType()) {
</ins><span class="cx">     case Wasm::Void:
</span><span class="cx">         block-&gt;appendNewControlValue(proc, B3::Return, origin);
</span><span class="cx">         break;
</span><span class="lines">@@ -913,7 +915,7 @@
</span><span class="cx"> 
</span><span class="cx">     Procedure procedure;
</span><span class="cx">     B3IRGenerator context(vm, info, procedure, result.get(), unlinkedWasmToWasmCalls, functionIndexSpace);
</span><del>-    FunctionParser&lt;B3IRGenerator&gt; parser(context, functionStart, functionLength, signature, functionIndexSpace, info);
</del><ins>+    FunctionParser&lt;B3IRGenerator&gt; parser(&amp;vm, context, functionStart, functionLength, signature, functionIndexSpace, info);
</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="branchessafari603branchSourceJavaScriptCorewasmWasmBindingcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmBinding.cpp (210401 => 210402)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmBinding.cpp        2017-01-06 01:47:16 UTC (rev 210401)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmBinding.cpp        2017-01-06 01:47:27 UTC (rev 210402)
</span><span class="lines">@@ -36,11 +36,12 @@
</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, Signature* signature, unsigned importIndex)
</del><ins>+WasmToJSStub importStubGenerator(VM* vm, Bag&lt;CallLinkInfo&gt;&amp; callLinkInfos, SignatureIndex signatureIndex, unsigned importIndex)
</ins><span class="cx"> {
</span><span class="cx">     const WasmCallingConvention&amp; wasmCC = wasmCallingConvention();
</span><span class="cx">     const JSCCallingConvention&amp; jsCC = jscCallingConvention();
</span><del>-    unsigned argCount = signature-&gt;arguments.size();
</del><ins>+    const Signature* signature = SignatureInformation::get(vm, signatureIndex);
+    unsigned argCount = signature-&gt;argumentCount();
</ins><span class="cx">     typedef AssemblyHelpers JIT;
</span><span class="cx">     JIT jit(vm, nullptr);
</span><span class="cx"> 
</span><span class="lines">@@ -72,7 +73,7 @@
</span><span class="cx">     unsigned calleeFrameOffset = CallFrameSlot::firstArgument * static_cast&lt;int&gt;(sizeof(Register));
</span><span class="cx">     unsigned frOffset = CallFrameSlot::firstArgument * static_cast&lt;int&gt;(sizeof(Register));
</span><span class="cx">     for (unsigned argNum = 0; argNum &lt; argCount; ++argNum) {
</span><del>-        Type argType = signature-&gt;arguments[argNum];
</del><ins>+        Type argType = signature-&gt;argument(argNum);
</ins><span class="cx">         switch (argType) {
</span><span class="cx">         case Void:
</span><span class="cx">         case Func:
</span><span class="lines">@@ -161,7 +162,7 @@
</span><span class="cx">     JIT::Call slowCall = jit.nearCall();
</span><span class="cx">     done.link(&amp;jit);
</span><span class="cx"> 
</span><del>-    switch (signature-&gt;returnType) {
</del><ins>+    switch (signature-&gt;returnType()) {
</ins><span class="cx">     case Void:
</span><span class="cx">         // Discard.
</span><span class="cx">         break;
</span><span class="lines">@@ -230,7 +231,7 @@
</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 %p&quot;, importIndex, signature));
</del><ins>+    return FINALIZE_CODE(patchBuffer, (&quot;WebAssembly import[%i] stub for signature %i&quot;, importIndex, signatureIndex));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::Wasm
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmWasmBindingh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmBinding.h (210401 => 210402)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmBinding.h        2017-01-06 01:47:16 UTC (rev 210401)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmBinding.h        2017-01-06 01:47:27 UTC (rev 210402)
</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;, Signature*, unsigned);
</del><ins>+WasmToJSStub importStubGenerator(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="branchessafari603branchSourceJavaScriptCorewasmWasmCallingConventionh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmCallingConvention.h (210401 => 210402)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmCallingConvention.h        2017-01-06 01:47:16 UTC (rev 210401)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmCallingConvention.h        2017-01-06 01:47:27 UTC (rev 210402)
</span><span class="lines">@@ -118,7 +118,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     template&lt;typename Functor&gt;
</span><del>-    void loadArguments(const Vector&lt;Type&gt;&amp; argumentTypes, B3::Procedure&amp; proc, B3::BasicBlock* block, B3::Origin origin, const Functor&amp; functor) const
</del><ins>+    void loadArguments(const Signature* signature, B3::Procedure&amp; proc, B3::BasicBlock* block, B3::Origin origin, const Functor&amp; functor) const
</ins><span class="cx">     {
</span><span class="cx">         B3::Value* framePointer = block-&gt;appendNew&lt;B3::Value&gt;(proc, B3::FramePointer, origin);
</span><span class="cx"> 
</span><span class="lines">@@ -126,8 +126,8 @@
</span><span class="cx">         size_t fpArgumentCount = 0;
</span><span class="cx">         size_t stackOffset = headerSize;
</span><span class="cx"> 
</span><del>-        for (size_t i = 0; i &lt; argumentTypes.size(); ++i) {
-            B3::Type type = toB3Type(argumentTypes[i]);
</del><ins>+        for (size_t i = 0; i &lt; signature-&gt;argumentCount(); ++i) {
+            B3::Type type = toB3Type(signature-&gt;argument(i));
</ins><span class="cx">             B3::Value* argument;
</span><span class="cx">             B3::ValueRep rep = marshallArgument(type, gpArgumentCount, fpArgumentCount, stackOffset);
</span><span class="cx">             if (rep.isReg()) {
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmWasmFormatcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmFormat.cpp (210401 => 210402)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmFormat.cpp        2017-01-06 01:47:16 UTC (rev 210401)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmFormat.cpp        2017-01-06 01:47:27 UTC (rev 210402)
</span><span class="lines">@@ -30,9 +30,31 @@
</span><span class="cx"> #if ENABLE(WEBASSEMBLY)
</span><span class="cx"> 
</span><span class="cx"> #include &quot;WasmMemory.h&quot;
</span><ins>+#include &lt;wtf/FastMalloc.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace Wasm {
</span><span class="cx"> 
</span><ins>+Segment* Segment::create(uint32_t offset, uint32_t sizeInBytes)
+{
+    auto allocated = tryFastCalloc(sizeof(Segment) + sizeInBytes, 1);
+    Segment* segment;
+    if (!allocated.getValue(segment))
+        return nullptr;
+    segment-&gt;offset = offset;
+    segment-&gt;sizeInBytes = sizeInBytes;
+    return segment;
+}
+
+void Segment::destroy(Segment *segment)
+{
+    fastFree(segment);
+}
+
+Segment::Ptr Segment::adoptPtr(Segment* segment)
+{
+    return Ptr(segment, &amp;Segment::destroy);
+}
+
</ins><span class="cx"> JS_EXPORT_PRIVATE ModuleInformation::~ModuleInformation() { }
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::Wasm
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmWasmFormath"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmFormat.h (210401 => 210402)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmFormat.h        2017-01-06 01:47:16 UTC (rev 210401)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmFormat.h        2017-01-06 01:47:27 UTC (rev 210402)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -36,8 +36,9 @@
</span><span class="cx"> #include &quot;WasmMemoryInformation.h&quot;
</span><span class="cx"> #include &quot;WasmOps.h&quot;
</span><span class="cx"> #include &quot;WasmPageCount.h&quot;
</span><ins>+#include &quot;WasmSignature.h&quot;
+#include &lt;limits&gt;
</ins><span class="cx"> #include &lt;memory&gt;
</span><del>-#include &lt;wtf/FastMalloc.h&gt;
</del><span class="cx"> #include &lt;wtf/Optional.h&gt;
</span><span class="cx"> #include &lt;wtf/Vector.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -100,11 +101,6 @@
</span><span class="cx">     return &quot;?&quot;;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-struct Signature {
-    Type returnType;
-    Vector&lt;Type&gt; arguments;
-};
-
</del><span class="cx"> struct Import {
</span><span class="cx">     Identifier module;
</span><span class="cx">     Identifier field;
</span><span class="lines">@@ -146,30 +142,15 @@
</span><span class="cx">     uint32_t offset;
</span><span class="cx">     uint32_t sizeInBytes;
</span><span class="cx">     // Bytes are allocated at the end.
</span><del>-    static Segment* make(uint32_t offset, uint32_t sizeInBytes)
-    {
-        auto allocated = tryFastCalloc(sizeof(Segment) + sizeInBytes, 1);
-        Segment* segment;
-        if (!allocated.getValue(segment))
-            return nullptr;
-        segment-&gt;offset = offset;
-        segment-&gt;sizeInBytes = sizeInBytes;
-        return segment;
-    }
-    static void destroy(Segment *segment)
-    {
-        fastFree(segment);
-    }
</del><span class="cx">     uint8_t&amp; byte(uint32_t pos)
</span><span class="cx">     {
</span><span class="cx">         ASSERT(pos &lt; sizeInBytes);
</span><span class="cx">         return *reinterpret_cast&lt;uint8_t*&gt;(reinterpret_cast&lt;char*&gt;(this) + sizeof(offset) + sizeof(sizeInBytes) + pos);
</span><span class="cx">     }
</span><ins>+    static Segment* create(uint32_t, uint32_t);
+    static void destroy(Segment*);
</ins><span class="cx">     typedef std::unique_ptr&lt;Segment, decltype(&amp;Segment::destroy)&gt; Ptr;
</span><del>-    static Ptr makePtr(Segment* segment)
-    {
-        return Ptr(segment, &amp;Segment::destroy);
-    }
</del><ins>+    static Ptr adoptPtr(Segment*);
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> struct Element {
</span><span class="lines">@@ -206,10 +187,10 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> struct ModuleInformation {
</span><del>-    Vector&lt;Signature&gt; signatures;
</del><ins>+    Vector&lt;SignatureIndex&gt; signatureIndices;
</ins><span class="cx">     Vector&lt;Import&gt; imports;
</span><del>-    Vector&lt;Signature*&gt; importFunctions;
-    Vector&lt;Signature*&gt; internalFunctionSignatures;
</del><ins>+    Vector&lt;SignatureIndex&gt; importFunctionSignatureIndices;
+    Vector&lt;SignatureIndex&gt; internalFunctionSignatureIndices;
</ins><span class="cx">     MemoryInformation memory;
</span><span class="cx">     Vector&lt;Export&gt; exports;
</span><span class="cx">     std::optional&lt;uint32_t&gt; startFunctionIndexSpace;
</span><span class="lines">@@ -247,15 +228,14 @@
</span><span class="cx"> struct CallableFunction {
</span><span class="cx">     CallableFunction() = default;
</span><span class="cx"> 
</span><del>-    CallableFunction(Signature* signature, void* code = nullptr)
-        : signature(signature)
</del><ins>+    CallableFunction(SignatureIndex signatureIndex, void* code = nullptr)
+        : signatureIndex(signatureIndex)
</ins><span class="cx">         , code(code)
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // FIXME pack this inside a (uniqued) integer (for correctness the parser should unique Signatures),
-    // and then pack that integer into the code pointer. https://bugs.webkit.org/show_bug.cgi?id=165511
-    Signature* signature { nullptr }; 
</del><ins>+    // FIXME pack the SignatureIndex and the code pointer into one 64-bit value. https://bugs.webkit.org/show_bug.cgi?id=165511
+    SignatureIndex signatureIndex { Signature::invalidIndex };
</ins><span class="cx">     void* code { nullptr };
</span><span class="cx"> };
</span><span class="cx"> typedef Vector&lt;CallableFunction&gt; FunctionIndexSpace;
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmWasmFunctionParserh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmFunctionParser.h (210401 => 210402)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmFunctionParser.h        2017-01-06 01:47:16 UTC (rev 210401)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmFunctionParser.h        2017-01-06 01:47:27 UTC (rev 210402)
</span><span class="lines">@@ -45,7 +45,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(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 ImmutableFunctionIndexSpace&amp;, const ModuleInformation&amp;);
</ins><span class="cx"> 
</span><span class="cx">     Result WARN_UNUSED_RETURN parse();
</span><span class="cx"> 
</span><span class="lines">@@ -88,8 +88,8 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename Context&gt;
</span><del>-FunctionParser&lt;Context&gt;::FunctionParser(Context&amp; context, const uint8_t* functionStart, size_t functionLength, const Signature* signature, const ImmutableFunctionIndexSpace&amp; functionIndexSpace, const ModuleInformation&amp; info)
-    : Parser(functionStart, functionLength)
</del><ins>+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)
+    : Parser(vm, functionStart, functionLength)
</ins><span class="cx">     , m_context(context)
</span><span class="cx">     , m_signature(signature)
</span><span class="cx">     , m_functionIndexSpace(functionIndexSpace)
</span><span class="lines">@@ -104,7 +104,7 @@
</span><span class="cx"> {
</span><span class="cx">     uint32_t localCount;
</span><span class="cx"> 
</span><del>-    WASM_PARSER_FAIL_IF(!m_context.addArguments(m_signature-&gt;arguments), &quot;can't add &quot;, m_signature-&gt;arguments.size(), &quot; arguments to Function&quot;);
</del><ins>+    WASM_PARSER_FAIL_IF(!m_context.addArguments(m_signature), &quot;can't add &quot;, m_signature-&gt;argumentCount(), &quot; arguments to Function&quot;);
</ins><span class="cx">     WASM_PARSER_FAIL_IF(!parseVarUInt32(localCount), &quot;can't get local count&quot;);
</span><span class="cx">     WASM_PARSER_FAIL_IF(localCount == std::numeric_limits&lt;uint32_t&gt;::max(), &quot;Function section's local count is too big &quot;, localCount);
</span><span class="cx"> 
</span><span class="lines">@@ -155,7 +155,7 @@
</span><span class="cx"> auto FunctionParser&lt;Context&gt;::addReturn() -&gt; PartialResult
</span><span class="cx"> {
</span><span class="cx">     ExpressionList returnValues;
</span><del>-    if (m_signature-&gt;returnType != Void) {
</del><ins>+    if (m_signature-&gt;returnType() != Void) {
</ins><span class="cx">         ExpressionType returnValue;
</span><span class="cx">         WASM_TRY_POP_EXPRESSION_STACK_INTO(returnValue, &quot;return&quot;);
</span><span class="cx">         returnValues.append(returnValue);
</span><span class="lines">@@ -329,12 +329,13 @@
</span><span class="cx">         WASM_PARSER_FAIL_IF(!parseVarUInt32(functionIndex), &quot;can't parse call's function index&quot;);
</span><span class="cx">         WASM_PARSER_FAIL_IF(functionIndex &gt;= m_functionIndexSpace.size, &quot;call function index &quot;, functionIndex, &quot; exceeds function index space &quot;, m_functionIndexSpace.size);
</span><span class="cx"> 
</span><del>-        const Signature* calleeSignature = m_functionIndexSpace.buffer.get()[functionIndex].signature;
-        WASM_PARSER_FAIL_IF(calleeSignature-&gt;arguments.size() &gt; m_expressionStack.size(), &quot;call function index &quot;, functionIndex, &quot; has &quot;, calleeSignature-&gt;arguments.size(), &quot; arguments, but the expression stack currently holds &quot;, m_expressionStack.size(), &quot; values&quot;);
</del><ins>+        SignatureIndex calleeSignatureIndex = m_functionIndexSpace.buffer.get()[functionIndex].signatureIndex;
+        const Signature* calleeSignature = SignatureInformation::get(m_vm, calleeSignatureIndex);
+        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;);
</ins><span class="cx"> 
</span><del>-        size_t firstArgumentIndex = m_expressionStack.size() - calleeSignature-&gt;arguments.size();
</del><ins>+        size_t firstArgumentIndex = m_expressionStack.size() - calleeSignature-&gt;argumentCount();
</ins><span class="cx">         Vector&lt;ExpressionType&gt; args;
</span><del>-        WASM_PARSER_FAIL_IF(!args.tryReserveCapacity(calleeSignature-&gt;arguments.size()), &quot;can't allocate enough memory for call's &quot;, calleeSignature-&gt;arguments.size(), &quot; arguments&quot;);
</del><ins>+        WASM_PARSER_FAIL_IF(!args.tryReserveCapacity(calleeSignature-&gt;argumentCount()), &quot;can't allocate enough memory for call's &quot;, calleeSignature-&gt;argumentCount(), &quot; arguments&quot;);
</ins><span class="cx">         for (size_t i = firstArgumentIndex; i &lt; m_expressionStack.size(); ++i)
</span><span class="cx">             args.uncheckedAppend(m_expressionStack[i]);
</span><span class="cx">         m_expressionStack.shrink(firstArgumentIndex);
</span><span class="lines">@@ -355,10 +356,11 @@
</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.signatures.size() &lt;= signatureIndex, &quot;call_indirect's signature index &quot;, signatureIndex, &quot; exceeds known signatures &quot;, m_info.signatures.size());
</del><ins>+        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());
</ins><span class="cx"> 
</span><del>-        const Signature* calleeSignature = &amp;m_info.signatures[signatureIndex];
-        size_t argumentCount = calleeSignature-&gt;arguments.size() + 1; // Add the callee's index.
</del><ins>+        SignatureIndex calleeSignatureIndex = m_info.signatureIndices[signatureIndex];
+        const Signature* calleeSignature = SignatureInformation::get(m_vm, calleeSignatureIndex);
+        size_t argumentCount = calleeSignature-&gt;argumentCount() + 1; // Add the callee's index.
</ins><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 class="cx"> 
</span><span class="cx">         Vector&lt;ExpressionType&gt; args;
</span><span class="lines">@@ -369,7 +371,7 @@
</span><span class="cx">         m_expressionStack.shrink(firstArgumentIndex);
</span><span class="cx"> 
</span><span class="cx">         ExpressionType result = Context::emptyExpression;
</span><del>-        WASM_TRY_ADD_TO_CONTEXT(addCallIndirect(calleeSignature, args, result));
</del><ins>+        WASM_TRY_ADD_TO_CONTEXT(addCallIndirect(calleeSignature, calleeSignatureIndex, args, result));
</ins><span class="cx"> 
</span><span class="cx">         if (result != Context::emptyExpression)
</span><span class="cx">             m_expressionStack.append(result);
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmWasmModuleParsercpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmModuleParser.cpp (210401 => 210402)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmModuleParser.cpp        2017-01-06 01:47:16 UTC (rev 210401)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmModuleParser.cpp        2017-01-06 01:47:27 UTC (rev 210402)
</span><span class="lines">@@ -99,7 +99,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;signatures.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.module-&gt;signatureIndices.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">@@ -110,18 +110,18 @@
</span><span class="cx">         WASM_PARSER_FAIL_IF(type != Func, i, &quot;th Type is non-Func &quot;, type);
</span><span class="cx">         WASM_PARSER_FAIL_IF(!parseVarUInt32(argumentCount), &quot;can't get &quot;, i, &quot;th Type's argument count&quot;);
</span><span class="cx">         WASM_PARSER_FAIL_IF(argumentCount == std::numeric_limits&lt;uint32_t&gt;::max(), i, &quot;th argument count is too big &quot;, argumentCount);
</span><del>-        WASM_PARSER_FAIL_IF(!argumentTypes.tryReserveCapacity(argumentCount), &quot;can't allocate enough memory for Type section's &quot;, i, &quot;th &quot;, argumentCount, &quot; arguments&quot;);
</del><ins>+        std::unique_ptr&lt;Signature, void (*)(Signature*)&gt; signature(Signature::create(argumentCount), &amp;Signature::destroy);
+        WASM_PARSER_FAIL_IF(!signature, &quot;can't allocate enough memory for Type section's &quot;, i, &quot;th signature&quot;);
</ins><span class="cx"> 
</span><span class="cx">         for (unsigned i = 0; i &lt; argumentCount; ++i) {
</span><span class="cx">             Type argumentType;
</span><span class="cx">             WASM_PARSER_FAIL_IF(!parseResultType(argumentType), &quot;can't get &quot;, i, &quot;th argument Type&quot;);
</span><del>-            argumentTypes.uncheckedAppend(argumentType);
</del><ins>+            signature-&gt;argument(i) = argumentType;
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         uint8_t returnCount;
</span><span class="cx">         WASM_PARSER_FAIL_IF(!parseVarUInt1(returnCount), &quot;can't get &quot;, i, &quot;th Type's return count&quot;);
</span><span class="cx">         Type returnType;
</span><del>-
</del><span class="cx">         if (returnCount) {
</span><span class="cx">             Type value;
</span><span class="cx">             WASM_PARSER_FAIL_IF(!parseValueType(value), &quot;can't get &quot;, i, &quot;th Type's return value&quot;);
</span><span class="lines">@@ -128,8 +128,10 @@
</span><span class="cx">             returnType = static_cast&lt;Type&gt;(value);
</span><span class="cx">         } else
</span><span class="cx">             returnType = Type::Void;
</span><ins>+        signature-&gt;returnType() = returnType;
</ins><span class="cx"> 
</span><del>-        m_result.module-&gt;signatures.uncheckedAppend({ returnType, WTFMove(argumentTypes) });
</del><ins>+        SignatureIndex signatureIndex = SignatureInformation::adopt(m_vm, signature.release());
+        m_result.module-&gt;signatureIndices.uncheckedAppend(signatureIndex);
</ins><span class="cx">     }
</span><span class="cx">     return { };
</span><span class="cx"> }
</span><span class="lines">@@ -141,7 +143,7 @@
</span><span class="cx">     WASM_PARSER_FAIL_IF(importCount == std::numeric_limits&lt;uint32_t&gt;::max(), &quot;Import section's count is too big &quot;, importCount);
</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><del>-    WASM_PARSER_FAIL_IF(!m_result.module-&gt;importFunctions.tryReserveCapacity(importCount), &quot;can't allocate enough memory for &quot;, importCount, &quot; import functions&quot;); // FIXME this over-allocates when we fix the FIXMEs below.
</del><ins>+    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.
</ins><span class="cx">     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.
</span><span class="cx"> 
</span><span class="cx">     for (uint32_t importNumber = 0; importNumber &lt; importCount; ++importNumber) {
</span><span class="lines">@@ -164,11 +166,11 @@
</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;signatures.size(), &quot;invalid function signature for &quot;, importNumber, &quot;th Import, &quot;, functionSignatureIndex, &quot; is out of range of &quot;, m_result.module-&gt;signatures.size(), &quot; in module '&quot;, moduleString, &quot;' field '&quot;, fieldString, &quot;'&quot;);
-            imp.kindIndex = m_result.module-&gt;importFunctions.size();
-            Signature* signature = &amp;m_result.module-&gt;signatures[functionSignatureIndex];
-            m_result.module-&gt;importFunctions.uncheckedAppend(signature);
-            m_result.functionIndexSpace.uncheckedAppend(signature);
</del><ins>+            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;);
+            imp.kindIndex = m_result.module-&gt;importFunctionSignatureIndices.size();
+            SignatureIndex signatureIndex = m_result.module-&gt;signatureIndices[functionSignatureIndex];
+            m_result.module-&gt;importFunctionSignatureIndices.uncheckedAppend(signatureIndex);
+            m_result.functionIndexSpace.uncheckedAppend(signatureIndex);
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx">         case ExternalKind::Table: {
</span><span class="lines">@@ -208,7 +210,7 @@
</span><span class="cx">     uint32_t count;
</span><span class="cx">     WASM_PARSER_FAIL_IF(!parseVarUInt32(count), &quot;can't get Function section's count&quot;);
</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><del>-    WASM_PARSER_FAIL_IF(!m_result.module-&gt;internalFunctionSignatures.tryReserveCapacity(count), &quot;can't allocate enough memory for &quot;, count, &quot; Function signatures&quot;);
</del><ins>+    WASM_PARSER_FAIL_IF(!m_result.module-&gt;internalFunctionSignatureIndices.tryReserveCapacity(count), &quot;can't allocate enough memory for &quot;, count, &quot; Function signatures&quot;);
</ins><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><span class="cx">     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;);
</span><span class="cx"> 
</span><span class="lines">@@ -215,15 +217,15 @@
</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;signatures.size(), i, &quot;th Function type number is invalid &quot;, typeNumber);
</del><ins>+        WASM_PARSER_FAIL_IF(typeNumber &gt;= m_result.module-&gt;signatureIndices.size(), i, &quot;th Function type number is invalid &quot;, typeNumber);
</ins><span class="cx"> 
</span><del>-        Signature* signature = &amp;m_result.module-&gt;signatures[typeNumber];
</del><ins>+        SignatureIndex signatureIndex = m_result.module-&gt;signatureIndices[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><del>-        m_result.module-&gt;internalFunctionSignatures.uncheckedAppend(signature);
</del><ins>+        m_result.module-&gt;internalFunctionSignatureIndices.uncheckedAppend(signatureIndex);
</ins><span class="cx">         m_result.functionLocationInBinary.uncheckedAppend({ start, end });
</span><del>-        m_result.functionIndexSpace.uncheckedAppend(signature);
</del><ins>+        m_result.functionIndexSpace.uncheckedAppend(signatureIndex);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return { };
</span><span class="lines">@@ -425,9 +427,10 @@
</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><span class="cx">     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());
</span><del>-    Signature* signature = m_result.functionIndexSpace[startFunctionIndex].signature;
-    WASM_PARSER_FAIL_IF(!signature-&gt;arguments.isEmpty(), &quot;Start function can't have arguments&quot;);
-    WASM_PARSER_FAIL_IF(signature-&gt;returnType != Void, &quot;Start function can't return a value&quot;);
</del><ins>+    SignatureIndex signatureIndex = m_result.functionIndexSpace[startFunctionIndex].signatureIndex;
+    const Signature* signature = SignatureInformation::get(m_vm, signatureIndex);
+    WASM_PARSER_FAIL_IF(signature-&gt;argumentCount(), &quot;Start function can't have arguments&quot;);
+    WASM_PARSER_FAIL_IF(signature-&gt;returnType() != Void, &quot;Start function can't return a value&quot;);
</ins><span class="cx">     m_result.module-&gt;startFunctionIndexSpace = startFunctionIndex;
</span><span class="cx">     return { };
</span><span class="cx"> }
</span><span class="lines">@@ -594,9 +597,9 @@
</span><span class="cx">         WASM_PARSER_FAIL_IF(!parseVarUInt32(dataByteLength), &quot;can't get &quot;, segmentNumber, &quot;th Data segment's data byte length&quot;);
</span><span class="cx">         WASM_PARSER_FAIL_IF(dataByteLength == std::numeric_limits&lt;uint32_t&gt;::max(), segmentNumber, &quot;th Data segment's data byte length is too big &quot;, dataByteLength);
</span><span class="cx"> 
</span><del>-        Segment* segment = Segment::make(offset, dataByteLength);
</del><ins>+        Segment* segment = Segment::create(offset, dataByteLength);
</ins><span class="cx">         WASM_PARSER_FAIL_IF(!segment, &quot;can't allocate enough memory for &quot;, segmentNumber, &quot;th Data segment of size &quot;, dataByteLength);
</span><del>-        m_result.module-&gt;data.uncheckedAppend(Segment::makePtr(segment));
</del><ins>+        m_result.module-&gt;data.uncheckedAppend(Segment::adoptPtr(segment));
</ins><span class="cx">         for (uint32_t dataByte = 0; dataByte &lt; dataByteLength; ++dataByte) {
</span><span class="cx">             uint8_t byte;
</span><span class="cx">             WASM_PARSER_FAIL_IF(!parseUInt8(byte), &quot;can't get &quot;, dataByte, &quot;th data byte from &quot;, segmentNumber, &quot;th Data segment&quot;);
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmWasmModuleParserh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmModuleParser.h (210401 => 210402)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmModuleParser.h        2017-01-06 01:47:16 UTC (rev 210401)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmModuleParser.h        2017-01-06 01:47:27 UTC (rev 210402)
</span><span class="lines">@@ -44,8 +44,7 @@
</span><span class="cx"> public:
</span><span class="cx"> 
</span><span class="cx">     ModuleParser(VM* vm, const uint8_t* sourceBuffer, size_t sourceLength)
</span><del>-        : Parser(sourceBuffer, sourceLength)
-        , m_vm(vm)
</del><ins>+        : Parser(vm, sourceBuffer, sourceLength)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     ModuleParser(VM* vm, const Vector&lt;uint8_t&gt;&amp; sourceBuffer)
</span><span class="lines">@@ -67,7 +66,6 @@
</span><span class="cx">     PartialResult WARN_UNUSED_RETURN parseResizableLimits(uint32_t&amp; initial, std::optional&lt;uint32_t&gt;&amp; maximum);
</span><span class="cx">     PartialResult WARN_UNUSED_RETURN parseInitExpr(uint8_t&amp;, uint64_t&amp;);
</span><span class="cx"> 
</span><del>-    VM* m_vm;
</del><span class="cx">     ModuleParserResult m_result;
</span><span class="cx">     bool m_hasTable { false };
</span><span class="cx"> };
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmWasmParserh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmParser.h (210401 => 210402)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmParser.h        2017-01-06 01:47:16 UTC (rev 210401)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmParser.h        2017-01-06 01:47:27 UTC (rev 210402)
</span><span class="lines">@@ -56,7 +56,7 @@
</span><span class="cx">     typedef Expected&lt;SuccessType, ErrorType&gt; Result;
</span><span class="cx"> 
</span><span class="cx"> protected:
</span><del>-    Parser(const uint8_t*, size_t);
</del><ins>+    Parser(VM*, const uint8_t*, size_t);
</ins><span class="cx"> 
</span><span class="cx">     bool WARN_UNUSED_RETURN consumeCharacter(char);
</span><span class="cx">     bool WARN_UNUSED_RETURN consumeString(const char*);
</span><span class="lines">@@ -81,6 +81,7 @@
</span><span class="cx">     const uint8_t* source() const { return m_source; }
</span><span class="cx">     size_t length() const { return m_sourceLength; }
</span><span class="cx"> 
</span><ins>+    VM* m_vm;
</ins><span class="cx">     size_t m_offset = 0;
</span><span class="cx"> 
</span><span class="cx">     template &lt;typename ...Args&gt;
</span><span class="lines">@@ -106,8 +107,9 @@
</span><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> template&lt;typename SuccessType&gt;
</span><del>-ALWAYS_INLINE Parser&lt;SuccessType&gt;::Parser(const uint8_t* sourceBuffer, size_t sourceLength)
-    : m_source(sourceBuffer)
</del><ins>+ALWAYS_INLINE Parser&lt;SuccessType&gt;::Parser(VM* vm, const uint8_t* sourceBuffer, size_t sourceLength)
+    : m_vm(vm)
+    , m_source(sourceBuffer)
</ins><span class="cx">     , m_sourceLength(sourceLength)
</span><span class="cx"> {
</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 (210401 => 210402)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmPlan.cpp        2017-01-06 01:47:16 UTC (rev 210401)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmPlan.cpp        2017-01-06 01:47:27 UTC (rev 210402)
</span><span class="lines">@@ -79,9 +79,10 @@
</span><span class="cx">         const uint8_t* functionStart = m_source + m_functionLocationInBinary[functionIndex].start;
</span><span class="cx">         size_t functionLength = m_functionLocationInBinary[functionIndex].end - m_functionLocationInBinary[functionIndex].start;
</span><span class="cx">         ASSERT(Checked&lt;uintptr_t&gt;(bitwise_cast&lt;uintptr_t&gt;(functionStart)) + functionLength &lt;= Checked&lt;uintptr_t&gt;(bitwise_cast&lt;uintptr_t&gt;(m_source)) + m_sourceLength);
</span><del>-        Signature* signature = m_moduleInformation-&gt;internalFunctionSignatures[functionIndex];
</del><ins>+        SignatureIndex signatureIndex = m_moduleInformation-&gt;internalFunctionSignatureIndices[functionIndex];
+        const Signature* signature = SignatureInformation::get(m_vm, signatureIndex);
</ins><span class="cx"> 
</span><del>-        auto validationResult = validateFunction(functionStart, functionLength, signature, m_functionIndexSpace, *m_moduleInformation);
</del><ins>+        auto validationResult = validateFunction(m_vm, functionStart, functionLength, signature, m_functionIndexSpace, *m_moduleInformation);
</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">@@ -114,7 +115,7 @@
</span><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     Vector&lt;Vector&lt;UnlinkedWasmToWasmCall&gt;&gt; unlinkedWasmToWasmCalls;
</span><del>-    if (!tryReserveCapacity(m_wasmToJSStubs, m_moduleInformation-&gt;importFunctions.size(), &quot; WebAssembly to JavaScript stubs&quot;)
</del><ins>+    if (!tryReserveCapacity(m_wasmToJSStubs, m_moduleInformation-&gt;importFunctionSignatureIndices.size(), &quot; WebAssembly to JavaScript stubs&quot;)
</ins><span class="cx">         || !tryReserveCapacity(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">         return;
</span><span class="lines">@@ -126,8 +127,8 @@
</span><span class="cx">         unsigned importFunctionIndex = m_wasmToJSStubs.size();
</span><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><del>-        Signature* signature = m_moduleInformation-&gt;importFunctions.at(import-&gt;kindIndex);
-        m_wasmToJSStubs.uncheckedAppend(importStubGenerator(m_vm, m_callLinkInfos, signature, importFunctionIndex));
</del><ins>+        SignatureIndex signatureIndex = m_moduleInformation-&gt;importFunctionSignatureIndices.at(import-&gt;kindIndex);
+        m_wasmToJSStubs.uncheckedAppend(importStubGenerator(m_vm, m_callLinkInfos, signatureIndex, importFunctionIndex));
</ins><span class="cx">         m_functionIndexSpace.buffer.get()[importFunctionIndex].code = m_wasmToJSStubs[importFunctionIndex].code().executableAddress();
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -137,11 +138,12 @@
</span><span class="cx">         const uint8_t* functionStart = m_source + m_functionLocationInBinary[functionIndex].start;
</span><span class="cx">         size_t functionLength = m_functionLocationInBinary[functionIndex].end - m_functionLocationInBinary[functionIndex].start;
</span><span class="cx">         ASSERT(functionLength &lt;= m_sourceLength);
</span><del>-        Signature* signature = m_moduleInformation-&gt;internalFunctionSignatures[functionIndex];
</del><ins>+        SignatureIndex signatureIndex = m_moduleInformation-&gt;internalFunctionSignatureIndices[functionIndex];
+        const Signature* signature = SignatureInformation::get(m_vm, signatureIndex);
</ins><span class="cx">         unsigned functionIndexSpace = m_wasmToJSStubs.size() + functionIndex;
</span><del>-        ASSERT(m_functionIndexSpace.buffer.get()[functionIndexSpace].signature == signature);
</del><ins>+        ASSERT(m_functionIndexSpace.buffer.get()[functionIndexSpace].signatureIndex == signatureIndex);
</ins><span class="cx"> 
</span><del>-        ASSERT(validateFunction(functionStart, functionLength, signature, m_functionIndexSpace, *m_moduleInformation));
</del><ins>+        ASSERT(validateFunction(m_vm, functionStart, functionLength, signature, m_functionIndexSpace, *m_moduleInformation));
</ins><span class="cx"> 
</span><span class="cx">         unlinkedWasmToWasmCalls.uncheckedAppend(Vector&lt;UnlinkedWasmToWasmCall&gt;());
</span><span class="cx">         auto parseAndCompileResult = parseAndCompile(*m_vm, functionStart, functionLength, signature, unlinkedWasmToWasmCalls.at(functionIndex), m_functionIndexSpace, *m_moduleInformation);
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmWasmSignaturecpp"></a>
<div class="addfile"><h4>Added: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmSignature.cpp (0 => 210402)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmSignature.cpp                                (rev 0)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmSignature.cpp        2017-01-06 01:47:27 UTC (rev 210402)
</span><span class="lines">@@ -0,0 +1,147 @@
</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;WasmSignature.h&quot;
+
+#if ENABLE(WEBASSEMBLY)
+
+#include &quot;VM.h&quot;
+#include &lt;wtf/FastMalloc.h&gt;
+#include &lt;wtf/HashFunctions.h&gt;
+#include &lt;wtf/PrintStream.h&gt;
+
+namespace JSC { namespace Wasm {
+
+namespace {
+const bool verbose = false;
+}
+
+const constexpr SignatureIndex Signature::invalidIndex;
+
+void Signature::dump(PrintStream&amp; out) const
+{
+    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;);
+}
+
+unsigned Signature::hash() const
+{
+    uint32_t sizeToHash = allocatedSize(argumentCount()) / sizeof(allocationSizeRoundsUpTo);
+    // Assumes over-allocated memory was zero-initialized, and rounded-up to allocationSizeRoundsUpTo so that a wider hash can be performed.
+    ASSERT(sizeToHash * sizeof(allocationSizeRoundsUpTo) == allocatedSize(argumentCount()));
+    unsigned accumulator = 0xa1bcedd8u;
+    const auto* pos = reinterpret_cast&lt;const allocationSizeRoundsUpTo*&gt;(this);
+    for (uint32_t i = 0; i &lt; sizeToHash; ++i)
+        accumulator = WTF::pairIntHash(accumulator, WTF::IntHash&lt;allocationSizeRoundsUpTo&gt;::hash(*pos));
+    return accumulator;
+}
+
+Signature* Signature::create(SignatureArgCount argumentCount)
+{
+    // Hashing relies on allocation zero-initializing trailing elements.
+    auto allocated = tryFastCalloc(allocatedSize(argumentCount), 1);
+    Signature* signature;
+    if (!allocated.getValue(signature))
+        return nullptr;
+    new (signature) Signature(argumentCount);
+    return signature;
+}
+
+Signature* Signature::createInvalid()
+{
+    Signature* signature = create(0);
+    RELEASE_ASSERT(signature);
+    new (signature) Signature(std::numeric_limits&lt;SignatureArgCount&gt;::max());
+    return signature;
+}
+
+void Signature::destroy(Signature* signature)
+{
+    fastFree(signature);
+}
+
+SignatureInformation::~SignatureInformation()
+{
+    for (size_t i = 0; i &lt; m_signatures.size(); ++i)
+        Signature::destroy(m_signatures[i]);
+}
+
+SignatureInformation::SignatureInformation()
+{
+    // The zeroth entry is an invalid signature, to match invalidIndex.
+    ASSERT(!Signature::invalidIndex);
+    Signature* invalidSignature = Signature::createInvalid();
+    auto addResult = m_signatureMap.add(SignatureHash { invalidSignature }, Signature::invalidIndex);
+    RELEASE_ASSERT(addResult.isNewEntry);
+    ASSERT(Signature::invalidIndex == addResult.iterator-&gt;value);
+    m_signatures.append(invalidSignature);
+}
+
+SignatureInformation* SignatureInformation::get(VM* vm)
+{
+    std::call_once(vm-&gt;m_wasmSignatureInformationOnceFlag, [vm] {
+        vm-&gt;m_wasmSignatureInformation = std::unique_ptr&lt;SignatureInformation&gt;(new SignatureInformation());
+    });
+    return vm-&gt;m_wasmSignatureInformation.get();
+}
+
+SignatureIndex SignatureInformation::adopt(VM* vm, Signature* signature)
+{
+    SignatureInformation* info = get(vm);
+    LockHolder lock(info-&gt;m_lock);
+
+    SignatureIndex nextValue = info-&gt;m_signatures.size();
+    auto addResult = info-&gt;m_signatureMap.add(SignatureHash { signature }, nextValue);
+    if (addResult.isNewEntry) {
+        ASSERT(nextValue == addResult.iterator-&gt;value);
+        if (verbose)
+            dataLogLn(&quot;Adopt new signature &quot;, *signature, &quot; with index &quot;, addResult.iterator-&gt;value, &quot; hash: &quot;, signature-&gt;hash());
+        info-&gt;m_signatures.append(signature);
+        return nextValue;
+    }
+    if (verbose)
+        dataLogLn(&quot;Existing signature &quot;, *signature, &quot; with index &quot;, addResult.iterator-&gt;value, &quot; hash: &quot;, signature-&gt;hash());
+    Signature::destroy(signature);
+    ASSERT(addResult.iterator-&gt;value != Signature::invalidIndex);
+    return addResult.iterator-&gt;value;
+}
+
+const Signature* SignatureInformation::get(VM* vm, SignatureIndex index)
+{
+    ASSERT(index != Signature::invalidIndex);
+    SignatureInformation* info = get(vm);
+    LockHolder lock(info-&gt;m_lock);
+
+    if (verbose)
+        dataLogLn(&quot;Got signature &quot;, *info-&gt;m_signatures.at(index), &quot; at index &quot;, index);
+    return info-&gt;m_signatures.at(index);
+}
+
+} } // namespace JSC::Wasm
+
+#endif // ENABLE(WEBASSEMBLY)
</ins></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmWasmSignatureh"></a>
<div class="addfile"><h4>Added: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmSignature.h (0 => 210402)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmSignature.h                                (rev 0)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmSignature.h        2017-01-06 01:47:27 UTC (rev 210402)
</span><span class="lines">@@ -0,0 +1,168 @@
</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.
+ */
+
+#pragma once
+
+#if ENABLE(WEBASSEMBLY)
+
+#include &quot;B3Type.h&quot;
+#include &quot;WasmOps.h&quot;
+#include &lt;cstdint&gt;
+#include &lt;cstring&gt;
+#include &lt;wtf/HashMap.h&gt;
+#include &lt;wtf/HashTraits.h&gt;
+#include &lt;wtf/StdLibExtras.h&gt;
+#include &lt;wtf/Vector.h&gt;
+
+namespace WTF {
+class PrintStream;
+}
+
+namespace JSC {
+
+class VM;
+
+namespace Wasm {
+
+typedef uint32_t SignatureArgCount;
+typedef uint32_t SignatureIndex;
+
+class Signature {
+    static const constexpr SignatureArgCount s_retCount = 1;
+    typedef uint64_t allocationSizeRoundsUpTo;
+
+    Signature() = delete;
+    Signature(const Signature&amp;) = delete;
+    Signature(SignatureArgCount argCount)
+        : m_argCount(argCount)
+    {
+    }
+
+    Type* storage(SignatureArgCount i)
+    {
+        return i + reinterpret_cast&lt;Type*&gt;(reinterpret_cast&lt;char*&gt;(this) + sizeof(Signature));
+    }
+    Type* storage(SignatureArgCount i) const { return const_cast&lt;Signature*&gt;(this)-&gt;storage(i); }
+    static uint32_t allocatedSize(SignatureArgCount argCount)
+    {
+        return WTF::roundUpToMultipleOf&lt;sizeof(allocationSizeRoundsUpTo)&gt;(sizeof(Signature) + (s_retCount + argCount) * sizeof(Type));
+    }
+
+public:
+    Type&amp; returnType() { return *storage(0); }
+    Type returnType() const { return *storage(0); }
+    SignatureArgCount returnCount() const { return s_retCount; }
+    SignatureArgCount argumentCount() const { return m_argCount; }
+    Type&amp; argument(SignatureArgCount i)
+    {
+        ASSERT(i &lt; argumentCount());
+        return *storage(returnCount() + i);
+    }
+    Type argument(SignatureArgCount i) const { return const_cast&lt;Signature*&gt;(this)-&gt;argument(i); }
+
+    void dump(WTF::PrintStream&amp; out) const;
+    bool operator==(const Signature&amp; rhs) const
+    {
+        return allocatedSize(argumentCount()) == allocatedSize(rhs.argumentCount()) &amp;&amp; !memcmp(this, &amp;rhs, allocatedSize(argumentCount()));
+    }
+    unsigned hash() const;
+
+    static Signature* create(SignatureArgCount);
+    static void destroy(Signature*);
+
+    // Signatures are uniqued and, for call_indirect, validated at runtime. Tables can create invalid SignatureIndex values which cause call_indirect to fail. We use 0 as the invalidIndex so that the codegen can easily test for it and trap, and we add a token invalid entry in SignatureInformation.
+    static const constexpr SignatureIndex invalidIndex = 0;
+
+private:
+    friend class SignatureInformation;
+    static Signature* createInvalid();
+    SignatureArgCount m_argCount;
+    // Return Type and arguments are stored here.
+};
+
+struct SignatureHash {
+    const Signature* key;
+    static const Signature* empty() { return nullptr; }
+    static const Signature* deleted() { return reinterpret_cast&lt;const Signature*&gt;(1); }
+    SignatureHash()
+        : key(empty())
+    {
+    }
+    explicit SignatureHash(const Signature* key)
+        : key(key)
+    {
+        ASSERT(key != empty());
+        ASSERT(key != deleted());
+    }
+    explicit SignatureHash(WTF::HashTableDeletedValueType)
+        : key(deleted())
+    {
+    }
+    bool operator==(const SignatureHash&amp; rhs) const { return equal(*this, rhs); }
+    static bool equal(const SignatureHash&amp; lhs, const SignatureHash&amp; rhs) { return lhs.key == rhs.key || (lhs.key &amp;&amp; rhs.key &amp;&amp; *lhs.key == *rhs.key); }
+    static unsigned hash(const SignatureHash&amp; signature) { return signature.key-&gt;hash(); }
+    static const bool safeToCompareToEmptyOrDeleted = false;
+    bool isHashTableDeletedValue() const { return key == deleted(); }
+};
+
+} } // namespace JSC::Wasm
+
+
+namespace WTF {
+
+template&lt;typename T&gt; struct DefaultHash;
+template&lt;&gt; struct DefaultHash&lt;JSC::Wasm::SignatureHash&gt; {
+    typedef JSC::Wasm::SignatureHash Hash;
+};
+
+template&lt;typename T&gt; struct HashTraits;
+template&lt;&gt; struct HashTraits&lt;JSC::Wasm::SignatureHash&gt; : SimpleClassHashTraits&lt;JSC::Wasm::SignatureHash&gt; {
+    static const bool emptyValueIsZero = true;
+};
+
+} // namespace WTF
+
+
+namespace JSC { namespace Wasm {
+
+// Signature information is held globally on VM to allow all signatures to be unique. This is required when wasm calls another wasm instance.
+// Note: signatures are never removed from VM because that would require accounting for all WebAssembly.Module and which signatures they use. The maximum number of signatures is bounded, and isn't worth the counting overhead. We could clear everything when we reach zero outstanding WebAssembly.Module. https://bugs.webkit.org/show_bug.cgi?id=166037
+class SignatureInformation {
+    HashMap&lt;Wasm::SignatureHash, Wasm::SignatureIndex&gt; m_signatureMap;
+    Vector&lt;Signature*&gt; m_signatures;
+    Lock m_lock;
+    static SignatureInformation* get(VM*);
+    SignatureInformation();
+    SignatureInformation(const SignatureInformation&amp;) = delete;
+
+public:
+    ~SignatureInformation();
+    static SignatureIndex WARN_UNUSED_RETURN adopt(VM*, Signature*);
+    static const Signature* WARN_UNUSED_RETURN get(VM*, SignatureIndex);
+};
+
+} } // namespace JSC::Wasm
+
+#endif // ENABLE(WEBASSEMBLY)
</ins></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmWasmValidatecpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmValidate.cpp (210401 => 210402)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmValidate.cpp        2017-01-06 01:47:16 UTC (rev 210401)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmValidate.cpp        2017-01-06 01:47:27 UTC (rev 210402)
</span><span class="lines">@@ -92,7 +92,7 @@
</span><span class="cx">         return fail(__VA_ARGS__);                   \
</span><span class="cx">     } while (0)
</span><span class="cx"> 
</span><del>-    Result WARN_UNUSED_RETURN addArguments(const Vector&lt;Type&gt;&amp;);
</del><ins>+    Result WARN_UNUSED_RETURN addArguments(const Signature*);
</ins><span class="cx">     Result WARN_UNUSED_RETURN addLocal(Type, uint32_t);
</span><span class="cx">     ExpressionType addConstant(Type type, uint64_t) { return type; }
</span><span class="cx"> 
</span><span class="lines">@@ -132,7 +132,7 @@
</span><span class="cx"> 
</span><span class="cx">     // Calls
</span><span class="cx">     Result WARN_UNUSED_RETURN addCall(unsigned calleeIndex, const Signature*, const Vector&lt;ExpressionType&gt;&amp; args, ExpressionType&amp; result);
</span><del>-    Result WARN_UNUSED_RETURN addCallIndirect(const Signature*, const Vector&lt;ExpressionType&gt;&amp; args, ExpressionType&amp; result);
</del><ins>+    Result WARN_UNUSED_RETURN addCallIndirect(const Signature*, SignatureIndex, const Vector&lt;ExpressionType&gt;&amp; args, ExpressionType&amp; result);
</ins><span class="cx"> 
</span><span class="cx">     bool hasMemory() const { return !!m_module.memory; }
</span><span class="cx"> 
</span><span class="lines">@@ -155,10 +155,10 @@
</span><span class="cx">     const ModuleInformation&amp; m_module;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-auto Validate::addArguments(const Vector&lt;Type&gt;&amp; args) -&gt; Result
</del><ins>+auto Validate::addArguments(const Signature* signature) -&gt; Result
</ins><span class="cx"> {
</span><del>-    for (Type arg : args)
-        WASM_FAIL_IF_HELPER_FAILS(addLocal(arg, 1));
</del><ins>+    for (size_t i = 0; i &lt; signature-&gt;argumentCount(); ++i)
+        WASM_FAIL_IF_HELPER_FAILS(addLocal(signature-&gt;argument(i), 1));
</ins><span class="cx">     return { };
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -310,26 +310,28 @@
</span><span class="cx"> 
</span><span class="cx"> auto Validate::addCall(unsigned, const Signature* signature, const Vector&lt;ExpressionType&gt;&amp; args, ExpressionType&amp; result) -&gt; Result
</span><span class="cx"> {
</span><del>-    WASM_VALIDATOR_FAIL_IF(signature-&gt;arguments.size() != args.size(), &quot;arity mismatch in call, got &quot;, args.size(), &quot; arguments, expected &quot;, signature-&gt;arguments.size());
</del><ins>+    WASM_VALIDATOR_FAIL_IF(signature-&gt;argumentCount() != args.size(), &quot;arity mismatch in call, got &quot;, args.size(), &quot; arguments, expected &quot;, signature-&gt;argumentCount());
</ins><span class="cx"> 
</span><span class="cx">     for (unsigned i = 0; i &lt; args.size(); ++i)
</span><del>-        WASM_VALIDATOR_FAIL_IF(args[i] != signature-&gt;arguments[i], &quot;argument type mismatch in call, got &quot;, args[i], &quot;, expected &quot;, signature-&gt;arguments[i]);
</del><ins>+        WASM_VALIDATOR_FAIL_IF(args[i] != signature-&gt;argument(i), &quot;argument type mismatch in call, got &quot;, args[i], &quot;, expected &quot;, signature-&gt;argument(i));
</ins><span class="cx"> 
</span><del>-    result = signature-&gt;returnType;
</del><ins>+    result = signature-&gt;returnType();
</ins><span class="cx">     return { };
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-auto Validate::addCallIndirect(const Signature* signature, const Vector&lt;ExpressionType&gt;&amp; args, ExpressionType&amp; result) -&gt; Result
</del><ins>+auto Validate::addCallIndirect(const Signature* signature, SignatureIndex signatureIndex, const Vector&lt;ExpressionType&gt;&amp; args, ExpressionType&amp; result) -&gt; Result
</ins><span class="cx"> {
</span><del>-    const auto argumentCount = signature-&gt;arguments.size();
</del><ins>+    UNUSED_PARAM(signatureIndex);
+    ASSERT(signatureIndex != Signature::invalidIndex);
+    const auto argumentCount = signature-&gt;argumentCount();
</ins><span class="cx">     WASM_VALIDATOR_FAIL_IF(argumentCount != args.size() - 1, &quot;arity mismatch in call_indirect, got &quot;, args.size() - 1, &quot; arguments, expected &quot;, argumentCount);
</span><span class="cx"> 
</span><span class="cx">     for (unsigned i = 0; i &lt; argumentCount; ++i)
</span><del>-        WASM_VALIDATOR_FAIL_IF(args[i] != signature-&gt;arguments[i], &quot;argument type mismatch in call_indirect, got &quot;, args[i], &quot;, expected &quot;, signature-&gt;arguments[i]);
</del><ins>+        WASM_VALIDATOR_FAIL_IF(args[i] != signature-&gt;argument(i), &quot;argument type mismatch in call_indirect, got &quot;, args[i], &quot;, expected &quot;, signature-&gt;argument(i));
</ins><span class="cx"> 
</span><span class="cx">     WASM_VALIDATOR_FAIL_IF(args.last() != I32, &quot;non-i32 call_indirect index &quot;, args.last());
</span><span class="cx"> 
</span><del>-    result = signature-&gt;returnType;
</del><ins>+    result = signature-&gt;returnType();
</ins><span class="cx">     return { };
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -351,10 +353,10 @@
</span><span class="cx">     // Think of this as penance for the sin of bad error messages.
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Expected&lt;void, String&gt; validateFunction(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 ImmutableFunctionIndexSpace&amp; functionIndexSpace, const ModuleInformation&amp; module)
</ins><span class="cx"> {
</span><del>-    Validate context(signature-&gt;returnType, module);
-    FunctionParser&lt;Validate&gt; validator(context, source, length, signature, functionIndexSpace, module);
</del><ins>+    Validate context(signature-&gt;returnType(), module);
+    FunctionParser&lt;Validate&gt; validator(vm, context, source, length, signature, functionIndexSpace, module);
</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 (210401 => 210402)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmValidate.h        2017-01-06 01:47:16 UTC (rev 210401)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/WasmValidate.h        2017-01-06 01:47:27 UTC (rev 210402)
</span><span class="lines">@@ -30,10 +30,14 @@
</span><span class="cx"> #include &quot;WasmFormat.h&quot;
</span><span class="cx"> #include &lt;wtf/Expected.h&gt;
</span><span class="cx"> 
</span><del>-namespace JSC { namespace Wasm {
</del><ins>+namespace JSC {
</ins><span class="cx"> 
</span><del>-Expected&lt;void, String&gt; validateFunction(const uint8_t*, size_t, const Signature*, const ImmutableFunctionIndexSpace&amp;, const ModuleInformation&amp;);
</del><ins>+class VM;
</ins><span class="cx"> 
</span><ins>+namespace Wasm {
+
+Expected&lt;void, String&gt; validateFunction(VM*, const uint8_t*, size_t, const Signature*, const ImmutableFunctionIndexSpace&amp;, const ModuleInformation&amp;);
+
</ins><span class="cx"> } } // namespace JSC::Wasm
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(WEBASSEMBLY)
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmjsJSWebAssemblyInstancecpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp (210401 => 210402)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp        2017-01-06 01:47:16 UTC (rev 210401)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp        2017-01-06 01:47:27 UTC (rev 210402)
</span><span class="lines">@@ -41,7 +41,7 @@
</span><span class="cx"> JSWebAssemblyInstance* JSWebAssemblyInstance::create(VM&amp; vm, Structure* structure, JSWebAssemblyModule* module, JSModuleNamespaceObject* moduleNamespaceObject)
</span><span class="cx"> {
</span><span class="cx">     // FIXME: These objects could be pretty big we should try to throw OOM here.
</span><del>-    auto* instance = new (NotNull, allocateCell&lt;JSWebAssemblyInstance&gt;(vm.heap, allocationSize(module-&gt;moduleInformation().importFunctions.size()))) JSWebAssemblyInstance(vm, structure, module-&gt;moduleInformation().importFunctions.size());
</del><ins>+    auto* instance = new (NotNull, allocateCell&lt;JSWebAssemblyInstance&gt;(vm.heap, allocationSize(module-&gt;moduleInformation().importFunctionSignatureIndices.size()))) JSWebAssemblyInstance(vm, structure, module-&gt;moduleInformation().importFunctionSignatureIndices.size());
</ins><span class="cx">     instance-&gt;finishCreation(vm, module, moduleNamespaceObject);
</span><span class="cx">     return instance;
</span><span class="cx"> }
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmjsJSWebAssemblyModuleh"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.h (210401 => 210402)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.h        2017-01-06 01:47:16 UTC (rev 210401)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyModule.h        2017-01-06 01:47:27 UTC (rev 210402)
</span><span class="lines">@@ -50,7 +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::Signature* signatureForFunctionIndexSpace(unsigned functionIndexSpace) const { ASSERT(functionIndexSpace &lt; m_functionIndexSpace.size); return m_functionIndexSpace.buffer.get()[functionIndexSpace].signature; }
</del><ins>+    Wasm::SignatureIndex signatureForFunctionIndexSpace(unsigned functionIndexSpace) const
+    {
+        ASSERT(functionIndexSpace &lt; m_functionIndexSpace.size);
+        return m_functionIndexSpace.buffer.get()[functionIndexSpace].signatureIndex;
+    }
</ins><span class="cx">     unsigned importCount() const { return m_wasmToJSStubs.size(); }
</span><span class="cx"> 
</span><span class="cx">     JSWebAssemblyCallee* jsEntrypointCalleeFromFunctionIndexSpace(unsigned functionIndexSpace)
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmjsJSWebAssemblyTablecpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.cpp (210401 => 210402)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.cpp        2017-01-06 01:47:16 UTC (rev 210401)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.cpp        2017-01-06 01:47:27 UTC (rev 210402)
</span><span class="lines">@@ -67,7 +67,7 @@
</span><span class="cx">     m_jsFunctions = MallocPtr&lt;WriteBarrier&lt;WebAssemblyFunction&gt;&gt;::malloc(sizeof(WriteBarrier&lt;WebAssemblyFunction&gt;) * static_cast&lt;size_t&gt;(m_size));
</span><span class="cx">     for (uint32_t i = 0; i &lt; m_size; ++i) {
</span><span class="cx">         new (&amp;m_functions.get()[i]) Wasm::CallableFunction();
</span><del>-        ASSERT(!m_functions.get()[i].signature); // We rely on this in compiled code.
</del><ins>+        ASSERT(m_functions.get()[i].signatureIndex == Wasm::Signature::invalidIndex); // We rely on this in compiled code.
</ins><span class="cx">         new (&amp;m_jsFunctions.get()[i]) WriteBarrier&lt;WebAssemblyFunction&gt;();
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="lines">@@ -121,7 +121,7 @@
</span><span class="cx">     RELEASE_ASSERT(index &lt; m_size);
</span><span class="cx">     m_jsFunctions.get()[index] = WriteBarrier&lt;WebAssemblyFunction&gt;();
</span><span class="cx">     m_functions.get()[index] = Wasm::CallableFunction();
</span><del>-    ASSERT(!m_functions.get()[index].signature); // We rely on this in compiled code.
</del><ins>+    ASSERT(m_functions.get()[index].signatureIndex == Wasm::Signature::invalidIndex); // We rely on this in compiled code.
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void JSWebAssemblyTable::setFunction(VM&amp; vm, uint32_t index, WebAssemblyFunction* function)
</span><span class="lines">@@ -128,7 +128,7 @@
</span><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT(index &lt; m_size);
</span><span class="cx">     m_jsFunctions.get()[index].set(vm, this, function);
</span><del>-    m_functions.get()[index] = Wasm::CallableFunction(function-&gt;signature(), function-&gt;wasmEntrypoint());
</del><ins>+    m_functions.get()[index] = Wasm::CallableFunction(function-&gt;signatureIndex(), function-&gt;wasmEntrypoint());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmjsWebAssemblyFunctioncpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp (210401 => 210402)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp        2017-01-06 01:47:16 UTC (rev 210401)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp        2017-01-06 01:47:27 UTC (rev 210402)
</span><span class="lines">@@ -52,10 +52,11 @@
</span><span class="cx">     WebAssemblyFunction* wasmFunction = jsDynamicCast&lt;WebAssemblyFunction*&gt;(exec-&gt;jsCallee());
</span><span class="cx">     if (!wasmFunction)
</span><span class="cx">         return JSValue::encode(throwException(exec, scope, createTypeError(exec, &quot;expected a WebAssembly function&quot;, defaultSourceAppender, runtimeTypeForValue(exec-&gt;jsCallee()))));
</span><del>-    const Wasm::Signature* signature = wasmFunction-&gt;signature();
</del><ins>+    Wasm::SignatureIndex signatureIndex = wasmFunction-&gt;signatureIndex();
+    const Wasm::Signature* signature = Wasm::SignatureInformation::get(&amp;vm, signatureIndex);
</ins><span class="cx"> 
</span><span class="cx">     // FIXME is this the right behavior? https://bugs.webkit.org/show_bug.cgi?id=164876
</span><del>-    if (exec-&gt;argumentCount() != signature-&gt;arguments.size())
</del><ins>+    if (exec-&gt;argumentCount() != signature-&gt;argumentCount())
</ins><span class="cx">         return JSValue::encode(throwException(exec, scope, createNotEnoughArgumentsError(exec, defaultSourceAppender)));
</span><span class="cx"> 
</span><span class="cx">     // FIXME is this boxing correct? https://bugs.webkit.org/show_bug.cgi?id=164876
</span><span class="lines">@@ -62,7 +63,7 @@
</span><span class="cx">     Vector&lt;JSValue&gt; boxedArgs;
</span><span class="cx">     for (unsigned argIndex = 0; argIndex &lt; exec-&gt;argumentCount(); ++argIndex) {
</span><span class="cx">         JSValue arg = exec-&gt;uncheckedArgument(argIndex);
</span><del>-        switch (signature-&gt;arguments[argIndex]) {
</del><ins>+        switch (signature-&gt;argument(argIndex)) {
</ins><span class="cx">         case Wasm::I32:
</span><span class="cx">             arg = JSValue::decode(arg.toInt32(exec));
</span><span class="cx">             break;
</span><span class="lines">@@ -121,7 +122,7 @@
</span><span class="cx">     vm.topJSWebAssemblyInstance = prevJSWebAssemblyInstance;
</span><span class="cx"> 
</span><span class="cx">     // FIXME is this correct? https://bugs.webkit.org/show_bug.cgi?id=164876
</span><del>-    switch (signature()-&gt;returnType) {
</del><ins>+    switch (m_returnType) {
</ins><span class="cx">     case Wasm::Void:
</span><span class="cx">         return JSValue::encode(jsUndefined());
</span><span class="cx">     case Wasm::I32:
</span><span class="lines">@@ -140,12 +141,12 @@
</span><span class="cx">     return EncodedJSValue();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-WebAssemblyFunction* WebAssemblyFunction::create(VM&amp; vm, JSGlobalObject* globalObject, unsigned length, const String&amp; name, JSWebAssemblyInstance* instance, JSWebAssemblyCallee* jsEntrypoint, JSWebAssemblyCallee* wasmEntrypoint, Wasm::Signature* signature)
</del><ins>+WebAssemblyFunction* WebAssemblyFunction::create(VM&amp; vm, JSGlobalObject* globalObject, unsigned length, const String&amp; name, JSWebAssemblyInstance* instance, JSWebAssemblyCallee* jsEntrypoint, JSWebAssemblyCallee* wasmEntrypoint, Wasm::SignatureIndex signatureIndex)
</ins><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);
-    function-&gt;finishCreation(vm, executable, length, name, instance, jsEntrypoint, wasmEntrypoint, signature);
</del><ins>+    WebAssemblyFunction* function = new (NotNull, allocateCell&lt;WebAssemblyFunction&gt;(vm.heap)) WebAssemblyFunction(vm, globalObject, structure, signatureIndex);
+    function-&gt;finishCreation(vm, executable, length, name, instance, jsEntrypoint, wasmEntrypoint);
</ins><span class="cx">     return function;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -155,9 +156,13 @@
</span><span class="cx">     return Structure::create(vm, globalObject, prototype, TypeInfo(JSFunctionType, StructureFlags), info());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-WebAssemblyFunction::WebAssemblyFunction(VM&amp; vm, JSGlobalObject* globalObject, Structure* structure)
</del><ins>+WebAssemblyFunction::WebAssemblyFunction(VM&amp; vm, JSGlobalObject* globalObject, Structure* structure, Wasm::SignatureIndex signatureIndex)
</ins><span class="cx">     : Base(vm, globalObject, structure)
</span><ins>+    , m_signatureIndex(signatureIndex)
</ins><span class="cx"> {
</span><ins>+    // Don't cache the signature pointer: it's a global on VM and can change as new WebAssembly.Module are created.
+    const Wasm::Signature* signature = Wasm::SignatureInformation::get(&amp;vm, m_signatureIndex);
+    m_returnType = signature-&gt;returnType();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebAssemblyFunction::visitChildren(JSCell* cell, SlotVisitor&amp; visitor)
</span><span class="lines">@@ -170,7 +175,7 @@
</span><span class="cx">     visitor.append(thisObject-&gt;m_wasmEntrypoint);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebAssemblyFunction::finishCreation(VM&amp; vm, NativeExecutable* executable, unsigned length, const String&amp; name, JSWebAssemblyInstance* instance, JSWebAssemblyCallee* jsEntrypoint, JSWebAssemblyCallee* wasmEntrypoint, Wasm::Signature* signature)
</del><ins>+void WebAssemblyFunction::finishCreation(VM&amp; vm, NativeExecutable* executable, unsigned length, const String&amp; name, JSWebAssemblyInstance* instance, JSWebAssemblyCallee* jsEntrypoint, JSWebAssemblyCallee* wasmEntrypoint)
</ins><span class="cx"> {
</span><span class="cx">     Base::finishCreation(vm, executable, length, name);
</span><span class="cx">     ASSERT(inherits(info()));
</span><span class="lines">@@ -178,7 +183,6 @@
</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><del>-    m_signature = signature;
</del><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 (210401 => 210402)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.h        2017-01-06 01:47:16 UTC (rev 210401)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.h        2017-01-06 01:47:27 UTC (rev 210402)
</span><span class="lines">@@ -41,10 +41,6 @@
</span><span class="cx"> class Compilation;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-namespace Wasm {
-struct Signature;
-}
-
</del><span class="cx"> class WebAssemblyFunction : public JSFunction {
</span><span class="cx"> public:
</span><span class="cx">     typedef JSFunction Base;
</span><span class="lines">@@ -53,15 +49,11 @@
</span><span class="cx"> 
</span><span class="cx">     DECLARE_EXPORT_INFO;
</span><span class="cx"> 
</span><del>-    JS_EXPORT_PRIVATE static WebAssemblyFunction* create(VM&amp;, JSGlobalObject*, unsigned, const String&amp;, JSWebAssemblyInstance*, JSWebAssemblyCallee* jsEntrypoint, JSWebAssemblyCallee* wasmEntrypoint, Wasm::Signature*);
</del><ins>+    JS_EXPORT_PRIVATE static WebAssemblyFunction* create(VM&amp;, JSGlobalObject*, unsigned, const String&amp;, JSWebAssemblyInstance*, JSWebAssemblyCallee* jsEntrypoint, JSWebAssemblyCallee* wasmEntrypoint, Wasm::SignatureIndex);
</ins><span class="cx">     static Structure* createStructure(VM&amp;, JSGlobalObject*, JSValue);
</span><span class="cx"> 
</span><span class="cx">     JSWebAssemblyInstance* instance() const { return m_instance.get(); }
</span><del>-    Wasm::Signature* signature()
-    { 
-        ASSERT(m_signature);
-        return m_signature;
-    }
</del><ins>+    Wasm::SignatureIndex signatureIndex() const { return m_signatureIndex; }
</ins><span class="cx">     EncodedJSValue call(VM&amp;, ProtoCallFrame*);
</span><span class="cx">     void* wasmEntrypoint() { return m_wasmEntrypoint-&gt;entrypoint(); }
</span><span class="cx"> 
</span><span class="lines">@@ -68,15 +60,16 @@
</span><span class="cx"> protected:
</span><span class="cx">     static void visitChildren(JSCell*, SlotVisitor&amp;);
</span><span class="cx"> 
</span><del>-    void finishCreation(VM&amp;, NativeExecutable*, unsigned length, const String&amp; name, JSWebAssemblyInstance*, JSWebAssemblyCallee* jsEntrypoint, JSWebAssemblyCallee* wasmEntrypoint, Wasm::Signature*);
</del><ins>+    void finishCreation(VM&amp;, NativeExecutable*, unsigned length, const String&amp; name, JSWebAssemblyInstance*, JSWebAssemblyCallee* jsEntrypoint, JSWebAssemblyCallee* wasmEntrypoint);
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    WebAssemblyFunction(VM&amp;, JSGlobalObject*, Structure*);
</del><ins>+    WebAssemblyFunction(VM&amp;, JSGlobalObject*, Structure*, Wasm::SignatureIndex);
</ins><span class="cx"> 
</span><span class="cx">     WriteBarrier&lt;JSWebAssemblyInstance&gt; m_instance;
</span><span class="cx">     WriteBarrier&lt;JSWebAssemblyCallee&gt; m_jsEntrypoint;
</span><span class="cx">     WriteBarrier&lt;JSWebAssemblyCallee&gt; m_wasmEntrypoint;
</span><del>-    Wasm::Signature* m_signature;
</del><ins>+    Wasm::SignatureIndex m_signatureIndex;
+    Wasm::Type m_returnType;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="branchessafari603branchSourceJavaScriptCorewasmjsWebAssemblyModuleRecordcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp (210401 => 210402)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp        2017-01-06 01:47:16 UTC (rev 210401)
+++ branches/safari-603-branch/Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp        2017-01-06 01:47:27 UTC (rev 210402)
</span><span class="lines">@@ -37,6 +37,7 @@
</span><span class="cx"> #include &quot;JSWebAssemblyModule.h&quot;
</span><span class="cx"> #include &quot;ProtoCallFrame.h&quot;
</span><span class="cx"> #include &quot;WasmFormat.h&quot;
</span><ins>+#include &quot;WasmSignature.h&quot;
</ins><span class="cx"> #include &quot;WebAssemblyFunction.h&quot;
</span><span class="cx"> #include &lt;limits&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -120,8 +121,9 @@
</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::Signature* signature = module-&gt;signatureForFunctionIndexSpace(exp.kindIndex);
-            WebAssemblyFunction* function = WebAssemblyFunction::create(vm, globalObject, signature-&gt;arguments.size(), exp.field.string(), instance, jsEntrypointCallee, wasmEntrypointCallee, signature);
</del><ins>+            Wasm::SignatureIndex signatureIndex = module-&gt;signatureForFunctionIndexSpace(exp.kindIndex);
+            const Wasm::Signature* signature = Wasm::SignatureInformation::get(&amp;vm, signatureIndex);
+            WebAssemblyFunction* function = WebAssemblyFunction::create(vm, globalObject, signature-&gt;argumentCount(), exp.field.string(), instance, jsEntrypointCallee, wasmEntrypointCallee, signatureIndex);
</ins><span class="cx">             exportedValue = function;
</span><span class="cx">             if (hasStart &amp;&amp; startFunctionIndexSpace == exp.kindIndex)
</span><span class="cx">                 m_startFunction.set(vm, this, function);
</span><span class="lines">@@ -176,16 +178,17 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (hasStart) {
</span><del>-        Wasm::Signature* signature = module-&gt;signatureForFunctionIndexSpace(startFunctionIndexSpace);
</del><ins>+        Wasm::SignatureIndex signatureIndex = module-&gt;signatureForFunctionIndexSpace(startFunctionIndexSpace);
+        const Wasm::Signature* signature = Wasm::SignatureInformation::get(&amp;vm, signatureIndex);
</ins><span class="cx">         // The start function must not take any arguments or return anything. This is enforced by the parser.
</span><del>-        ASSERT(!signature-&gt;arguments.size());
-        ASSERT(signature-&gt;returnType == Wasm::Void);
</del><ins>+        ASSERT(!signature-&gt;argumentCount());
+        ASSERT(signature-&gt;returnType() == Wasm::Void);
</ins><span class="cx">         // FIXME can start call imports / tables? This assumes not. https://github.com/WebAssembly/design/issues/896
</span><span class="cx">         if (!m_startFunction.get()) {
</span><span class="cx">             // The start function wasn't added above. It must be a purely internal function.
</span><span class="cx">             JSWebAssemblyCallee* jsEntrypointCallee = module-&gt;jsEntrypointCalleeFromFunctionIndexSpace(startFunctionIndexSpace);
</span><span class="cx">             JSWebAssemblyCallee* wasmEntrypointCallee = module-&gt;wasmEntrypointCalleeFromFunctionIndexSpace(startFunctionIndexSpace);
</span><del>-            WebAssemblyFunction* function = WebAssemblyFunction::create(vm, globalObject, signature-&gt;arguments.size(), &quot;start&quot;, instance, jsEntrypointCallee, wasmEntrypointCallee, signature);
</del><ins>+            WebAssemblyFunction* function = WebAssemblyFunction::create(vm, globalObject, signature-&gt;argumentCount(), &quot;start&quot;, instance, jsEntrypointCallee, wasmEntrypointCallee, signatureIndex);
</ins><span class="cx">             m_startFunction.set(vm, this, function);
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -237,13 +240,14 @@
</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::Signature* signature = module-&gt;signatureForFunctionIndexSpace(functionIndex);
</del><ins>+                Wasm::SignatureIndex signatureIndex = module-&gt;signatureForFunctionIndexSpace(functionIndex);
+                const Wasm::Signature* signature = Wasm::SignatureInformation::get(&amp;vm, signatureIndex);
</ins><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="cx">                 // Does (new Instance(...)).exports.foo === table.get(0)?
</span><span class="cx">                 // https://bugs.webkit.org/show_bug.cgi?id=165825
</span><span class="cx">                 WebAssemblyFunction* function = WebAssemblyFunction::create(
</span><del>-                    vm, m_instance-&gt;globalObject(), signature-&gt;arguments.size(), String(), m_instance.get(), jsEntrypointCallee, wasmEntrypointCallee, signature);
</del><ins>+                    vm, m_instance-&gt;globalObject(), signature-&gt;argumentCount(), String(), m_instance.get(), jsEntrypointCallee, wasmEntrypointCallee, signatureIndex);
</ins><span class="cx"> 
</span><span class="cx">                 table-&gt;setFunction(vm, tableIndex, function);
</span><span class="cx">                 ++tableIndex;
</span></span></pre>
</div>
</div>

</body>
</html>