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

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

<h3>Log Message</h3>
<pre>[WASM-Function-References] Add call_ref instruction
https://bugs.webkit.org/show_bug.cgi?id=222903

Patch by Dmitry Bezhetskov <dbezhetskov@igalia.com> on 2021-05-03
Reviewed by Yusuke Suzuki.

JSTests:

Add basic tests for new call_ref instruction:
https://github.com/WebAssembly/function-references/blob/master/proposals/function-references/Overview.md.
Add tests for calling same-instance wasm function, foreign-instance
wasm function and for calling imported js function.

* wasm.yaml:
* wasm/function-references/call_ref.js: Added.
(module):
(async basics):
(async indirectCall):
(async importHostCall):
* wasm/wasm.json:

Source/JavaScriptCore:

Add support for call_ref instruction from the typed function
references proposal: https://github.com/WebAssembly/function-references/blob/master/proposals/function-references/Overview.md.
call_ref calls the given function references from the stack
and it does almost the same stuff as call_indirect but
it doesn't check signatures because wasm types system guaranties
correctness.

* bytecode/BytecodeList.rb:
* dfg/DFGCapabilities.cpp:
(JSC::DFG::capabilityLevel):
* llint/LowLevelInterpreter.asm:
* llint/WebAssembly.asm:
* runtime/Gate.h:
* wasm/WasmAirIRGenerator.cpp:
(JSC::Wasm::AirIRGenerator::addCallIndirect):
(JSC::Wasm::AirIRGenerator::addCallRef):
(JSC::Wasm::AirIRGenerator::emitIndirectCall):
* wasm/WasmB3IRGenerator.cpp:
(JSC::Wasm::B3IRGenerator::emitIndirectCall):
(JSC::Wasm::B3IRGenerator::addCallIndirect):
(JSC::Wasm::B3IRGenerator::addCallRef):
* wasm/WasmFunctionParser.h:
(JSC::Wasm::FunctionParser<Context>::parseExpression):
(JSC::Wasm::FunctionParser<Context>::parseUnreachableExpression):
* wasm/WasmLLIntGenerator.cpp:
(JSC::Wasm::LLIntGenerator::addCallRef):
* wasm/WasmSlowPaths.cpp:
(JSC::LLInt::doWasmCallRef):
(JSC::LLInt::WASM_SLOW_PATH_DECL):
* wasm/WasmSlowPaths.h:
* wasm/js/JSWebAssemblyTable.cpp:
* wasm/js/WebAssemblyFunction.cpp:
(JSC::WebAssemblyFunction::WebAssemblyFunction):
* wasm/js/WebAssemblyFunction.h:
* wasm/js/WebAssemblyFunctionBase.cpp:
(JSC::WebAssemblyFunctionBase::WebAssemblyFunctionBase):
* wasm/js/WebAssemblyFunctionBase.h:
(JSC::WebAssemblyFunctionBase::offsetOfEntrypointLoadLocation):
* wasm/js/WebAssemblyWrapperFunction.cpp:
(JSC::WebAssemblyWrapperFunction::WebAssemblyWrapperFunction):
* wasm/js/WebAssemblyWrapperFunction.h:
* wasm/wasm.json:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkJSTestsChangeLog">trunk/JSTests/ChangeLog</a></li>
<li><a href="#trunkJSTestswasmwasmjson">trunk/JSTests/wasm/wasm.json</a></li>
<li><a href="#trunkJSTestswasmyaml">trunk/JSTests/wasm.yaml</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeBytecodeListrb">trunk/Source/JavaScriptCore/bytecode/BytecodeList.rb</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGCapabilitiescpp">trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorellintLowLevelInterpreterasm">trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm</a></li>
<li><a href="#trunkSourceJavaScriptCorellintWebAssemblyasm">trunk/Source/JavaScriptCore/llint/WebAssembly.asm</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeGateh">trunk/Source/JavaScriptCore/runtime/Gate.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmAirIRGeneratorcpp">trunk/Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmB3IRGeneratorcpp">trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmFunctionParserh">trunk/Source/JavaScriptCore/wasm/WasmFunctionParser.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmLLIntGeneratorcpp">trunk/Source/JavaScriptCore/wasm/WasmLLIntGenerator.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmSlowPathscpp">trunk/Source/JavaScriptCore/wasm/WasmSlowPaths.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmWasmSlowPathsh">trunk/Source/JavaScriptCore/wasm/WasmSlowPaths.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsJSWebAssemblyTablecpp">trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsJSWebAssemblyTableh">trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsWebAssemblyFunctioncpp">trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsWebAssemblyFunctionh">trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsWebAssemblyFunctionBasecpp">trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunctionBase.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsWebAssemblyFunctionBaseh">trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunctionBase.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsWebAssemblyWrapperFunctioncpp">trunk/Source/JavaScriptCore/wasm/js/WebAssemblyWrapperFunction.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmjsWebAssemblyWrapperFunctionh">trunk/Source/JavaScriptCore/wasm/js/WebAssemblyWrapperFunction.h</a></li>
<li><a href="#trunkSourceJavaScriptCorewasmwasmjson">trunk/Source/JavaScriptCore/wasm/wasm.json</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li>trunk/JSTests/wasm/function-references/</li>
<li><a href="#trunkJSTestswasmfunctionreferencescall_refjs">trunk/JSTests/wasm/function-references/call_ref.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkJSTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/ChangeLog (276895 => 276896)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/ChangeLog  2021-05-03 09:29:48 UTC (rev 276895)
+++ trunk/JSTests/ChangeLog     2021-05-03 11:00:43 UTC (rev 276896)
</span><span class="lines">@@ -1,3 +1,23 @@
</span><ins>+2021-05-03  Dmitry Bezhetskov  <dbezhetskov@igalia.com>
+
+        [WASM-Function-References] Add call_ref instruction
+        https://bugs.webkit.org/show_bug.cgi?id=222903
+
+        Reviewed by Yusuke Suzuki.
+
+        Add basic tests for new call_ref instruction:
+        https://github.com/WebAssembly/function-references/blob/master/proposals/function-references/Overview.md.
+        Add tests for calling same-instance wasm function, foreign-instance
+        wasm function and for calling imported js function.
+
+        * wasm.yaml:
+        * wasm/function-references/call_ref.js: Added.
+        (module):
+        (async basics):
+        (async indirectCall):
+        (async importHostCall):
+        * wasm/wasm.json:
+
</ins><span class="cx"> 2021-04-28  Mark Lam  <mark.lam@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Fix exception assertions in light of the TerminationException.
</span></span></pre></div>
<a id="trunkJSTestswasmfunctionreferencescall_refjs"></a>
<div class="addfile"><h4>Added: trunk/JSTests/wasm/function-references/call_ref.js (0 => 276896)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/function-references/call_ref.js                               (rev 0)
+++ trunk/JSTests/wasm/function-references/call_ref.js  2021-05-03 11:00:43 UTC (rev 276896)
</span><span class="lines">@@ -0,0 +1,75 @@
</span><ins>+//@ runWebAssemblySuite("--useWebAssemblyTypedFunctionReferences=true")
+import * as assert from '../assert.js';
+import { instantiate } from "../wabt-wrapper.js";
+
+function module(bytes, valid = true) {
+  let buffer = new ArrayBuffer(bytes.length);
+  let view = new Uint8Array(buffer);
+  for (let i = 0; i < bytes.length; ++i) {
+    view[i] = bytes.charCodeAt(i);
+  }
+  return new WebAssembly.Module(buffer);
+}
+
+async function callFunctionFromTheSameInstance() {
+  /*
+  (module
+    (elem declare funcref (ref.func $foo))
+    (func $foo (param $x i32) (result i32)
+      (i32.add (local.get $x)
+               (i32.const 19)
+      )
+    )
+    (func (export "main") (result i32)
+      (call_ref (i32.const 10) (ref.func $foo))
+    )
+  )
+  */
+  let instance = new WebAssembly.Instance(module("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x0a\x02\x60\x01\x7f\x01\x7f\x60\x00\x01\x7f\x03\x03\x02\x00\x01\x07\x08\x01\x04\x6d\x61\x69\x6e\x00\x01\x09\x05\x01\x03\x00\x01\x00\x0a\x11\x02\x07\x00\x20\x00\x41\x13\x6a\x0b\x07\x00\x41\x0a\xd2\x00\x14\x0b"));
+  assert.eq(instance.exports.main(), 29);
+}
+
+async function callFunctionFromTheDifferentInstance() {
+  let wat = `
+  (module
+    (func (export "bar") (param $x i32) (result i32)
+      (i32.add (local.get $x)
+               (i32.const 19))
+    )
+  )`;
+  const barProvider = await instantiate(wat, {}, {reference_types: true});
+
+  /*
+  (module
+    (import "exports" "bar" (func $bar (param i32) (result i32)))
+    (elem declare funcref (ref.func $bar))
+    (func (export "main") (result i32)
+      (call_ref (i32.const 10) (ref.func $bar))
+    )
+  )
+  */
+  let instance = new WebAssembly.Instance(
+    module("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x0a\x02\x60\x01\x7f\x01\x7f\x60\x00\x01\x7f\x02\x0f\x01\x07\x65\x78\x70\x6f\x72\x74\x73\x03\x62\x61\x72\x00\x00\x03\x02\x01\x01\x07\x08\x01\x04\x6d\x61\x69\x6e\x00\x01\x09\x05\x01\x03\x00\x01\x00\x0a\x09\x01\x07\x00\x41\x0a\xd2\x00\x14\x0b"),
+    barProvider);
+  assert.eq(instance.exports.main(), 29);
+}
+
+async function callFunctionFromJS() {
+  /*
+  (module
+    (import "exports" "bar" (func $bar (param i32) (result i32)))
+    (elem declare funcref (ref.func $bar))
+    (func (export "main") (result i32)
+      (call_ref (i32.const 10) (ref.func $bar))
+    )
+  )
+  */
+  let instance = new WebAssembly.Instance(
+    module("\x00\x61\x73\x6d\x01\x00\x00\x00\x01\x0a\x02\x60\x01\x7f\x01\x7f\x60\x00\x01\x7f\x02\x0f\x01\x07\x65\x78\x70\x6f\x72\x74\x73\x03\x62\x61\x72\x00\x00\x03\x02\x01\x01\x07\x08\x01\x04\x6d\x61\x69\x6e\x00\x01\x09\x05\x01\x03\x00\x01\x00\x0a\x09\x01\x07\x00\x41\x0a\xd2\x00\x14\x0b"),
+    {exports: {bar : x => x + 19}});
+  assert.eq(instance.exports.main(), 29);
+}
+
+assert.asyncTest(callFunctionFromTheSameInstance());
+assert.asyncTest(callFunctionFromTheDifferentInstance());
+assert.asyncTest(callFunctionFromJS());
</ins></span></pre></div>
<a id="trunkJSTestswasmwasmjson"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/wasm/wasm.json (276895 => 276896)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm/wasm.json     2021-05-03 09:29:48 UTC (rev 276895)
+++ trunk/JSTests/wasm/wasm.json        2021-05-03 11:00:43 UTC (rev 276896)
</span><span class="lines">@@ -85,6 +85,7 @@
</span><span class="cx">         "data.drop":           { "category": "exttable",   "value":  252, "return": [],                              "parameter": [],                             "immediate": [{"name": "segment_index",  "type": "varuint32"}],                                             "description": "shrinks the size of the segment to zero", "extendedOp": 9 },
</span><span class="cx">         "call":                { "category": "call",       "value":  16, "return": ["call"],                         "parameter": ["call"],                       "immediate": [{"name": "function_index", "type": "varuint32"}],                                             "description": "call a function by its index" },
</span><span class="cx">         "call_indirect":       { "category": "call",       "value":  17, "return": ["call"],                         "parameter": ["call"],                       "immediate": [{"name": "type_index",     "type": "varuint32"}, {"name": "table_index","type": "varuint32"}],"description": "call a function indirect with an expected signature" },
</span><ins>+        "call_ref":            { "category": "call",       "value":  20, "return": ["call"],                         "parameter": ["call"],                       "immediate": [],                                                                                            "description": "call a function reference" },
</ins><span class="cx">         "i32.load8_s":         { "category": "memory",     "value":  44, "return": ["i32"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
</span><span class="cx">         "i32.load8_u":         { "category": "memory",     "value":  45, "return": ["i32"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
</span><span class="cx">         "i32.load16_s":        { "category": "memory",     "value":  46, "return": ["i32"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
</span></span></pre></div>
<a id="trunkJSTestswasmyaml"></a>
<div class="modfile"><h4>Modified: trunk/JSTests/wasm.yaml (276895 => 276896)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/JSTests/wasm.yaml  2021-05-03 09:29:48 UTC (rev 276895)
+++ trunk/JSTests/wasm.yaml     2021-05-03 11:00:43 UTC (rev 276896)
</span><span class="lines">@@ -33,6 +33,8 @@
</span><span class="cx">   cmd: runWebAssemblySuite unless parseRunCommands
</span><span class="cx"> - path: wasm/references
</span><span class="cx">   cmd: runWebAssemblySuite unless parseRunCommands
</span><ins>+- path: wasm/function-references
+  cmd: runWebAssemblySuite unless parseRunCommands
</ins><span class="cx"> - path: wasm/fuzz
</span><span class="cx">   cmd: runWebAssemblySuite unless parseRunCommands
</span><span class="cx"> - path: wasm/lowExecutableMemory
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (276895 => 276896)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog    2021-05-03 09:29:48 UTC (rev 276895)
+++ trunk/Source/JavaScriptCore/ChangeLog       2021-05-03 11:00:43 UTC (rev 276896)
</span><span class="lines">@@ -1,3 +1,53 @@
</span><ins>+2021-05-03  Dmitry Bezhetskov  <dbezhetskov@igalia.com>
+
+        [WASM-Function-References] Add call_ref instruction
+        https://bugs.webkit.org/show_bug.cgi?id=222903
+
+        Reviewed by Yusuke Suzuki.
+
+        Add support for call_ref instruction from the typed function
+        references proposal: https://github.com/WebAssembly/function-references/blob/master/proposals/function-references/Overview.md.
+        call_ref calls the given function references from the stack 
+        and it does almost the same stuff as call_indirect but
+        it doesn't check signatures because wasm types system guaranties
+        correctness.
+
+        * bytecode/BytecodeList.rb:
+        * dfg/DFGCapabilities.cpp:
+        (JSC::DFG::capabilityLevel):
+        * llint/LowLevelInterpreter.asm:
+        * llint/WebAssembly.asm:
+        * runtime/Gate.h:
+        * wasm/WasmAirIRGenerator.cpp:
+        (JSC::Wasm::AirIRGenerator::addCallIndirect):
+        (JSC::Wasm::AirIRGenerator::addCallRef):
+        (JSC::Wasm::AirIRGenerator::emitIndirectCall):
+        * wasm/WasmB3IRGenerator.cpp:
+        (JSC::Wasm::B3IRGenerator::emitIndirectCall):
+        (JSC::Wasm::B3IRGenerator::addCallIndirect):
+        (JSC::Wasm::B3IRGenerator::addCallRef):
+        * wasm/WasmFunctionParser.h:
+        (JSC::Wasm::FunctionParser<Context>::parseExpression):
+        (JSC::Wasm::FunctionParser<Context>::parseUnreachableExpression):
+        * wasm/WasmLLIntGenerator.cpp:
+        (JSC::Wasm::LLIntGenerator::addCallRef):
+        * wasm/WasmSlowPaths.cpp:
+        (JSC::LLInt::doWasmCallRef):
+        (JSC::LLInt::WASM_SLOW_PATH_DECL):
+        * wasm/WasmSlowPaths.h:
+        * wasm/js/JSWebAssemblyTable.cpp:
+        * wasm/js/WebAssemblyFunction.cpp:
+        (JSC::WebAssemblyFunction::WebAssemblyFunction):
+        * wasm/js/WebAssemblyFunction.h:
+        * wasm/js/WebAssemblyFunctionBase.cpp:
+        (JSC::WebAssemblyFunctionBase::WebAssemblyFunctionBase):
+        * wasm/js/WebAssemblyFunctionBase.h:
+        (JSC::WebAssemblyFunctionBase::offsetOfEntrypointLoadLocation):
+        * wasm/js/WebAssemblyWrapperFunction.cpp:
+        (JSC::WebAssemblyWrapperFunction::WebAssemblyWrapperFunction):
+        * wasm/js/WebAssemblyWrapperFunction.h:
+        * wasm/wasm.json:
+
</ins><span class="cx"> 2021-05-01  Chris Dumez  <cdumez@apple.com>
</span><span class="cx"> 
</span><span class="cx">         Start leveraging std::filesystem in WTF::FileSystem
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeBytecodeListrb"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/BytecodeList.rb (276895 => 276896)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/BytecodeList.rb     2021-05-03 09:29:48 UTC (rev 276895)
+++ trunk/Source/JavaScriptCore/bytecode/BytecodeList.rb        2021-05-03 11:00:43 UTC (rev 276896)
</span><span class="lines">@@ -1474,6 +1474,8 @@
</span><span class="cx"> op :wasm_trampoline_wasm_call_no_tls
</span><span class="cx"> op :wasm_trampoline_wasm_call_indirect
</span><span class="cx"> op :wasm_trampoline_wasm_call_indirect_no_tls
</span><ins>+op :wasm_trampoline_wasm_call_ref
+op :wasm_trampoline_wasm_call_ref_no_tls
</ins><span class="cx"> 
</span><span class="cx"> end_section :NativeHelpers
</span><span class="cx"> 
</span><span class="lines">@@ -1495,6 +1497,8 @@
</span><span class="cx"> op :call_no_tls_return_location
</span><span class="cx"> op :call_indirect_return_location
</span><span class="cx"> op :call_indirect_no_tls_return_location
</span><ins>+op :call_ref_return_location
+op :call_ref_no_tls_return_location
</ins><span class="cx"> 
</span><span class="cx"> # FIXME: Wasm and JS LLInt should share common opcodes
</span><span class="cx"> # https://bugs.webkit.org/show_bug.cgi?id=203656
</span><span class="lines">@@ -1686,6 +1690,22 @@
</span><span class="cx">         tableIndex: unsigned,
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+op :call_ref,
+    args: {
+        functionReference: VirtualRegister,
+        signatureIndex: unsigned,
+        stackOffset: unsigned,
+        numberOfStackArgs: unsigned,
+    }
+
+op :call_ref_no_tls,
+    args: {
+        functionReference: VirtualRegister,
+        signatureIndex: unsigned,
+        stackOffset: unsigned,
+        numberOfStackArgs: unsigned,
+    }
+
</ins><span class="cx"> op :current_memory,
</span><span class="cx">     args: {
</span><span class="cx">         dst: VirtualRegister,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGCapabilitiescpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp (276895 => 276896)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp      2021-05-03 09:29:48 UTC (rev 276895)
+++ trunk/Source/JavaScriptCore/dfg/DFGCapabilities.cpp 2021-05-03 11:00:43 UTC (rev 276896)
</span><span class="lines">@@ -368,6 +368,8 @@
</span><span class="cx">     case wasm_trampoline_wasm_call_no_tls:
</span><span class="cx">     case wasm_trampoline_wasm_call_indirect:
</span><span class="cx">     case wasm_trampoline_wasm_call_indirect_no_tls:
</span><ins>+    case wasm_trampoline_wasm_call_ref:
+    case wasm_trampoline_wasm_call_ref_no_tls:
</ins><span class="cx">         return CannotCompile;
</span><span class="cx">     }
</span><span class="cx">     return CannotCompile;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintLowLevelInterpreterasm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm (276895 => 276896)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm        2021-05-03 09:29:48 UTC (rev 276895)
+++ trunk/Source/JavaScriptCore/llint/LowLevelInterpreter.asm   2021-05-03 11:00:43 UTC (rev 276896)
</span><span class="lines">@@ -2530,14 +2530,20 @@
</span><span class="cx"> _wasm_trampoline_wasm_call_no_tls:
</span><span class="cx"> _wasm_trampoline_wasm_call_indirect:
</span><span class="cx"> _wasm_trampoline_wasm_call_indirect_no_tls:
</span><ins>+_wasm_trampoline_wasm_call_ref:
+_wasm_trampoline_wasm_call_ref_no_tls:
</ins><span class="cx"> _wasm_trampoline_wasm_call_wide16:
</span><span class="cx"> _wasm_trampoline_wasm_call_no_tls_wide16:
</span><span class="cx"> _wasm_trampoline_wasm_call_indirect_wide16:
</span><span class="cx"> _wasm_trampoline_wasm_call_indirect_no_tls_wide16:
</span><ins>+_wasm_trampoline_wasm_call_ref_wide16:
+_wasm_trampoline_wasm_call_ref_no_tls_wide16:
</ins><span class="cx"> _wasm_trampoline_wasm_call_wide32:
</span><span class="cx"> _wasm_trampoline_wasm_call_no_tls_wide32:
</span><span class="cx"> _wasm_trampoline_wasm_call_indirect_wide32:
</span><span class="cx"> _wasm_trampoline_wasm_call_indirect_no_tls_wide32:
</span><ins>+_wasm_trampoline_wasm_call_ref_wide32:
+_wasm_trampoline_wasm_call_ref_no_tls_wide32:
</ins><span class="cx">     crash()
</span><span class="cx"> 
</span><span class="cx"> end
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorellintWebAssemblyasm"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/llint/WebAssembly.asm (276895 => 276896)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/llint/WebAssembly.asm        2021-05-03 09:29:48 UTC (rev 276895)
+++ trunk/Source/JavaScriptCore/llint/WebAssembly.asm   2021-05-03 11:00:43 UTC (rev 276896)
</span><span class="lines">@@ -877,6 +877,14 @@
</span><span class="cx">     slowPathForWasmCall(ctx, _slow_path_wasm_call_indirect_no_tls, macro(targetInstance) move targetInstance, wasmInstance end)
</span><span class="cx"> end)
</span><span class="cx"> 
</span><ins>+wasmOp(call_ref, WasmCallRef, macro(ctx)
+    slowPathForWasmCall(ctx, _slow_path_wasm_call_ref, storeWasmInstanceToTLS)
+end)
+
+wasmOp(call_ref_no_tls, WasmCallRefNoTls, macro(ctx)
+    slowPathForWasmCall(ctx, _slow_path_wasm_call_ref_no_tls, macro(targetInstance) move targetInstance, wasmInstance end)
+end)
+
</ins><span class="cx"> wasmOp(current_memory, WasmCurrentMemory, macro(ctx)
</span><span class="cx">     loadp Wasm::Instance::m_memory[wasmInstance], t0
</span><span class="cx">     loadp Wasm::Memory::m_handle[t0], t0
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeGateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Gate.h (276895 => 276896)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Gate.h       2021-05-03 09:29:48 UTC (rev 276895)
+++ trunk/Source/JavaScriptCore/runtime/Gate.h  2021-05-03 11:00:43 UTC (rev 276896)
</span><span class="lines">@@ -68,6 +68,8 @@
</span><span class="cx">     v(wasm_call_no_tls, JSEntrySlowPathPtrTag) \
</span><span class="cx">     v(wasm_call_indirect, JSEntrySlowPathPtrTag) \
</span><span class="cx">     v(wasm_call_indirect_no_tls, JSEntrySlowPathPtrTag) \
</span><ins>+    v(wasm_call_ref, JSEntrySlowPathPtrTag) \
+    v(wasm_call_ref_no_tls, JSEntrySlowPathPtrTag) \
</ins><span class="cx"> 
</span><span class="cx"> #else
</span><span class="cx"> #define JSC_WASM_GATE_OPCODES(v)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmAirIRGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp (276895 => 276896)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp  2021-05-03 09:29:48 UTC (rev 276895)
+++ trunk/Source/JavaScriptCore/wasm/WasmAirIRGenerator.cpp     2021-05-03 11:00:43 UTC (rev 276896)
</span><span class="lines">@@ -325,7 +325,9 @@
</span><span class="cx">     // Calls
</span><span class="cx">     PartialResult WARN_UNUSED_RETURN addCall(uint32_t calleeIndex, const Signature&, Vector<ExpressionType>& args, ResultList& results);
</span><span class="cx">     PartialResult WARN_UNUSED_RETURN addCallIndirect(unsigned tableIndex, const Signature&, Vector<ExpressionType>& args, ResultList& results);
</span><ins>+    PartialResult WARN_UNUSED_RETURN addCallRef(const Signature&, Vector<ExpressionType>& args, ResultList& results);
</ins><span class="cx">     PartialResult WARN_UNUSED_RETURN addUnreachable();
</span><ins>+    PartialResult WARN_UNUSED_RETURN emitIndirectCall(TypedTmp calleeInstance, ExpressionType calleeCode, const Signature&, const Vector<ExpressionType>& args, ResultList&);
</ins><span class="cx">     B3::PatchpointValue* WARN_UNUSED_RETURN emitCallPatchpoint(BasicBlock*, const Signature&, const ResultList& results, const Vector<TypedTmp>& args, Vector<ConstrainedTmp>&& extraArgs = { });
</span><span class="cx"> 
</span><span class="cx">     PartialResult addShift(Type, B3::Air::Opcode, ExpressionType value, ExpressionType shift, ExpressionType& result);
</span><span class="lines">@@ -3273,9 +3275,6 @@
</span><span class="cx">     // can be to the embedder for our stack check calculation.
</span><span class="cx">     m_maxNumJSCallArguments = std::max(m_maxNumJSCallArguments, static_cast<uint32_t>(args.size()));
</span><span class="cx"> 
</span><del>-    auto currentInstance = g64();
-    append(Move, instanceValue(), currentInstance);
-
</del><span class="cx">     ExpressionType callableFunctionBuffer = g64();
</span><span class="cx">     ExpressionType instancesBuffer = g64();
</span><span class="cx">     ExpressionType callableFunctionBufferLength = g64();
</span><span class="lines">@@ -3340,15 +3339,42 @@
</span><span class="cx">         });
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    auto calleeInstance = g64();
+    append(Move, Arg::index(instancesBuffer, calleeIndex, 8, 0), calleeInstance);
+
+    return emitIndirectCall(calleeInstance, calleeCode, signature, args, results);
+}
+
+auto AirIRGenerator::addCallRef(const Signature& signature, Vector<ExpressionType>& args, ResultList& results) -> PartialResult
+{
+    m_makesCalls = true;
+    // Note: call ref can call either WebAssemblyFunction or WebAssemblyWrapperFunction. Because
+    // WebAssemblyWrapperFunction is like calling into the embedder, we conservatively assume all call indirects
+    // can be to the embedder for our stack check calculation.
+    ExpressionType calleeFunction = args.takeLast();
+    m_maxNumJSCallArguments = std::max(m_maxNumJSCallArguments, static_cast<uint32_t>(args.size()));
+
+    ExpressionType calleeCode = g64();
+    append(Move, Arg::addr(calleeFunction, WebAssemblyFunctionBase::offsetOfEntrypointLoadLocation()), calleeCode); // Pointer to callee code.
+
+    auto calleeInstance = g64();
+    append(Move, Arg::addr(calleeFunction, WebAssemblyFunctionBase::offsetOfInstance()), calleeInstance);
+    append(Move, Arg::addr(calleeInstance, JSWebAssemblyInstance::offsetOfInstance()), calleeInstance);
+
+    return emitIndirectCall(calleeInstance, calleeCode, signature, args, results);
+}
+
+auto AirIRGenerator::emitIndirectCall(TypedTmp calleeInstance, ExpressionType calleeCode, const Signature& signature, const Vector<ExpressionType>& args, ResultList& results) -> PartialResult
+{
+    auto currentInstance = g64();
+    append(Move, instanceValue(), currentInstance);
+
</ins><span class="cx">     // Do a context switch if needed.
</span><span class="cx">     {
</span><del>-        auto newContextInstance = g64();
-        append(Move, Arg::index(instancesBuffer, calleeIndex, 8, 0), newContextInstance);
-
</del><span class="cx">         BasicBlock* doContextSwitch = m_code.addBlock();
</span><span class="cx">         BasicBlock* continuation = m_code.addBlock();
</span><span class="cx"> 
</span><del>-        append(Branch64, Arg::relCond(MacroAssembler::Equal), newContextInstance, instanceValue());
</del><ins>+        append(Branch64, Arg::relCond(MacroAssembler::Equal), calleeInstance, currentInstance);
</ins><span class="cx">         m_currentBlock->setSuccessors(continuation, doContextSwitch);
</span><span class="cx"> 
</span><span class="cx">         auto* patchpoint = addPatchpoint(B3::Void);
</span><span class="lines">@@ -3361,26 +3387,26 @@
</span><span class="cx"> 
</span><span class="cx">         patchpoint->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) {
</span><span class="cx">             AllowMacroScratchRegisterUsage allowScratch(jit);
</span><del>-            GPRReg newContextInstance = params[0].gpr();
</del><ins>+            GPRReg calleeInstance = params[0].gpr();
</ins><span class="cx">             GPRReg oldContextInstance = params[1].gpr();
</span><span class="cx">             const PinnedRegisterInfo& pinnedRegs = PinnedRegisterInfo::get();
</span><span class="cx">             GPRReg baseMemory = pinnedRegs.baseMemoryPointer;
</span><del>-            ASSERT(newContextInstance != baseMemory);
</del><ins>+            ASSERT(calleeInstance != baseMemory);
</ins><span class="cx">             jit.loadPtr(CCallHelpers::Address(oldContextInstance, Instance::offsetOfCachedStackLimit()), baseMemory);
</span><del>-            jit.storePtr(baseMemory, CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedStackLimit()));
-            jit.storeWasmContextInstance(newContextInstance);
</del><ins>+            jit.storePtr(baseMemory, CCallHelpers::Address(calleeInstance, Instance::offsetOfCachedStackLimit()));
+            jit.storeWasmContextInstance(calleeInstance);
</ins><span class="cx">             // FIXME: We should support more than one memory size register
</span><span class="cx">             //   see: https://bugs.webkit.org/show_bug.cgi?id=162952
</span><del>-            ASSERT(pinnedRegs.boundsCheckingSizeRegister != newContextInstance);
</del><ins>+            ASSERT(pinnedRegs.boundsCheckingSizeRegister != calleeInstance);
</ins><span class="cx">             GPRReg scratch = params.gpScratch(0);
</span><span class="cx"> 
</span><del>-            jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedBoundsCheckingSize()), pinnedRegs.boundsCheckingSizeRegister); // Bound checking size.
-            jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedMemory()), baseMemory); // Memory::void*.
</del><ins>+            jit.loadPtr(CCallHelpers::Address(calleeInstance, Instance::offsetOfCachedBoundsCheckingSize()), pinnedRegs.boundsCheckingSizeRegister); // Bound checking size.
+            jit.loadPtr(CCallHelpers::Address(calleeInstance, Instance::offsetOfCachedMemory()), baseMemory); // Memory::void*.
</ins><span class="cx"> 
</span><span class="cx">             jit.cageConditionallyAndUntag(Gigacage::Primitive, baseMemory, pinnedRegs.boundsCheckingSizeRegister, scratch);
</span><span class="cx">         });
</span><span class="cx"> 
</span><del>-        emitPatchpoint(doContextSwitch, patchpoint, Tmp(), newContextInstance, instanceValue());
</del><ins>+        emitPatchpoint(doContextSwitch, patchpoint, Tmp(), calleeInstance, currentInstance);
</ins><span class="cx">         append(doContextSwitch, Jump);
</span><span class="cx">         doContextSwitch->setSuccessors(continuation);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmB3IRGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp (276895 => 276896)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp   2021-05-03 09:29:48 UTC (rev 276895)
+++ trunk/Source/JavaScriptCore/wasm/WasmB3IRGenerator.cpp      2021-05-03 11:00:43 UTC (rev 276896)
</span><span class="lines">@@ -285,7 +285,9 @@
</span><span class="cx">     // Calls
</span><span class="cx">     PartialResult WARN_UNUSED_RETURN addCall(uint32_t calleeIndex, const Signature&, Vector<ExpressionType>& args, ResultList& results);
</span><span class="cx">     PartialResult WARN_UNUSED_RETURN addCallIndirect(unsigned tableIndex, const Signature&, Vector<ExpressionType>& args, ResultList& results);
</span><ins>+    PartialResult WARN_UNUSED_RETURN addCallRef(const Signature&, Vector<ExpressionType>& args, ResultList& results);
</ins><span class="cx">     PartialResult WARN_UNUSED_RETURN addUnreachable();
</span><ins>+    PartialResult WARN_UNUSED_RETURN emitIndirectCall(Value* calleeInstance, ExpressionType calleeCode, const Signature&, Vector<ExpressionType>& args, ResultList&);
</ins><span class="cx">     B3::Value* createCallPatchpoint(BasicBlock*, Origin, const Signature&, Vector<ExpressionType>& args, const ScopedLambda<void(PatchpointValue*)>& patchpointFunctor);
</span><span class="cx"> 
</span><span class="cx">     void dump(const ControlStack&, const Stack* expressionStack);
</span><span class="lines">@@ -866,6 +868,95 @@
</span><span class="cx">     return { };
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+auto B3IRGenerator::emitIndirectCall(Value* calleeInstance, ExpressionType calleeCode, const Signature& signature, Vector<ExpressionType>& args, ResultList& results) -> PartialResult
+{
+    // Do a context switch if needed.
+    {
+        BasicBlock* continuation = m_proc.addBlock();
+        BasicBlock* doContextSwitch = m_proc.addBlock();
+
+        Value* isSameContextInstance = m_currentBlock->appendNew<Value>(m_proc, Equal, origin(),
+            calleeInstance, instanceValue());
+        m_currentBlock->appendNewControlValue(m_proc, B3::Branch, origin(),
+            isSameContextInstance, FrequentedBlock(continuation), FrequentedBlock(doContextSwitch));
+
+        PatchpointValue* patchpoint = doContextSwitch->appendNew<PatchpointValue>(m_proc, B3::Void, origin());
+        patchpoint->effects.writesPinned = true;
+        // We pessimistically assume we're calling something with BoundsChecking memory.
+        // FIXME: We shouldn't have to do this: https://bugs.webkit.org/show_bug.cgi?id=172181
+        patchpoint->clobber(PinnedRegisterInfo::get().toSave(MemoryMode::BoundsChecking));
+        patchpoint->clobber(RegisterSet::macroScratchRegisters());
+        patchpoint->append(calleeInstance, ValueRep::SomeRegister);
+        patchpoint->append(instanceValue(), ValueRep::SomeRegister);
+        patchpoint->numGPScratchRegisters = 1;
+
+        patchpoint->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) {
+            AllowMacroScratchRegisterUsage allowScratch(jit);
+            GPRReg calleeInstance = params[0].gpr();
+            GPRReg oldContextInstance = params[1].gpr();
+            const PinnedRegisterInfo& pinnedRegs = PinnedRegisterInfo::get();
+            GPRReg baseMemory = pinnedRegs.baseMemoryPointer;
+            ASSERT(calleeInstance != baseMemory);
+            jit.loadPtr(CCallHelpers::Address(oldContextInstance, Instance::offsetOfCachedStackLimit()), baseMemory);
+            jit.storePtr(baseMemory, CCallHelpers::Address(calleeInstance, Instance::offsetOfCachedStackLimit()));
+            jit.storeWasmContextInstance(calleeInstance);
+            ASSERT(pinnedRegs.boundsCheckingSizeRegister != baseMemory);
+            // FIXME: We should support more than one memory size register
+            //   see: https://bugs.webkit.org/show_bug.cgi?id=162952
+            ASSERT(pinnedRegs.boundsCheckingSizeRegister != calleeInstance);
+            GPRReg scratch = params.gpScratch(0);
+
+            jit.loadPtr(CCallHelpers::Address(calleeInstance, Instance::offsetOfCachedBoundsCheckingSize()), pinnedRegs.boundsCheckingSizeRegister); // Memory size.
+            jit.loadPtr(CCallHelpers::Address(calleeInstance, Instance::offsetOfCachedMemory()), baseMemory); // Memory::void*.
+
+            jit.cageConditionallyAndUntag(Gigacage::Primitive, baseMemory, pinnedRegs.boundsCheckingSizeRegister, scratch);
+        });
+        doContextSwitch->appendNewControlValue(m_proc, Jump, origin(), continuation);
+
+        m_currentBlock = continuation;
+    }
+
+    B3::Type returnType = toB3ResultType(&signature);
+    ExpressionType callResult = createCallPatchpoint(m_currentBlock, origin(), signature, args,
+        scopedLambdaRef<void(PatchpointValue*)>([=] (PatchpointValue* patchpoint) -> void {
+            patchpoint->effects.writesPinned = true;
+            patchpoint->effects.readsPinned = true;
+            // We need to clobber all potential pinned registers since we might be leaving the instance.
+            // We pessimistically assume we're always calling something that is bounds checking so
+            // because the wasm->wasm thunk unconditionally overrides the size registers.
+            // FIXME: We should not have to do this, but the wasm->wasm stub assumes it can
+            // use all the pinned registers as scratch: https://bugs.webkit.org/show_bug.cgi?id=172181
+            patchpoint->clobberLate(PinnedRegisterInfo::get().toSave(MemoryMode::BoundsChecking));
+
+            patchpoint->append(calleeCode, ValueRep::SomeRegister);
+            patchpoint->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) {
+                AllowMacroScratchRegisterUsage allowScratch(jit);
+                jit.call(params[params.proc().resultCount(returnType)].gpr(), WasmEntryPtrTag);
+            });
+        }));
+
+    switch (returnType.kind()) {
+    case B3::Void: {
+        break;
+    }
+    case B3::Tuple: {
+        const Vector<B3::Type>& tuple = m_proc.tupleForType(returnType);
+        for (unsigned i = 0; i < signature.returnCount(); ++i)
+            results.append(m_currentBlock->appendNew<ExtractValue>(m_proc, origin(), tuple[i], callResult, i));
+        break;
+    }
+    default: {
+        results.append(callResult);
+        break;
+    }
+    }
+
+    // The call could have been to another WebAssembly instance, and / or could have modified our Memory.
+    restoreWebAssemblyGlobalState(RestoreCachedStackLimit::Yes, m_info.memory, instanceValue(), m_proc, m_currentBlock);
+
+    return { };
+}
+
</ins><span class="cx"> auto B3IRGenerator::addGrowMemory(ExpressionType delta, ExpressionType& result) -> PartialResult
</span><span class="cx"> {
</span><span class="cx">     result = m_currentBlock->appendNew<CCallValue>(m_proc, Int32, origin(),
</span><span class="lines">@@ -2521,100 +2612,41 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    // Do a context switch if needed.
-    {
-        Value* offset = m_currentBlock->appendNew<Value>(m_proc, Mul, origin(),
-            calleeIndex, constant(pointerType(), sizeof(Instance*)));
-        Value* newContextInstance = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(),
-            m_currentBlock->appendNew<Value>(m_proc, Add, origin(), instancesBuffer, offset));
</del><ins>+    Value* offset = m_currentBlock->appendNew<Value>(m_proc, Mul, origin(),
+        calleeIndex, constant(pointerType(), sizeof(Instance*)));
+    Value* calleeInstance = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(),
+        m_currentBlock->appendNew<Value>(m_proc, Add, origin(), instancesBuffer, offset));
+    ExpressionType calleeCode = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(),
+        m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(), callableFunction,
+            safeCast<int32_t>(WasmToWasmImportableFunction::offsetOfEntrypointLoadLocation())));
</ins><span class="cx"> 
</span><del>-        BasicBlock* continuation = m_proc.addBlock();
-        BasicBlock* doContextSwitch = m_proc.addBlock();
</del><ins>+    return emitIndirectCall(calleeInstance, calleeCode, signature, args, results);
+}
</ins><span class="cx"> 
</span><del>-        Value* isSameContextInstance = m_currentBlock->appendNew<Value>(m_proc, Equal, origin(),
-            newContextInstance, instanceValue());
-        m_currentBlock->appendNewControlValue(m_proc, B3::Branch, origin(),
-            isSameContextInstance, FrequentedBlock(continuation), FrequentedBlock(doContextSwitch));
</del><ins>+auto B3IRGenerator::addCallRef(const Signature& signature, Vector<ExpressionType>& args, ResultList& results) -> PartialResult
+{
+    ExpressionType callee = args.takeLast();
+    ASSERT(signature.argumentCount() == args.size());
+    m_makesCalls = true;
</ins><span class="cx"> 
</span><del>-        PatchpointValue* patchpoint = doContextSwitch->appendNew<PatchpointValue>(m_proc, B3::Void, origin());
-        patchpoint->effects.writesPinned = true;
-        // We pessimistically assume we're calling something with BoundsChecking memory.
-        // FIXME: We shouldn't have to do this: https://bugs.webkit.org/show_bug.cgi?id=172181
-        patchpoint->clobber(PinnedRegisterInfo::get().toSave(MemoryMode::BoundsChecking));
-        patchpoint->clobber(RegisterSet::macroScratchRegisters());
-        patchpoint->append(newContextInstance, ValueRep::SomeRegister);
-        patchpoint->append(instanceValue(), ValueRep::SomeRegister);
-        patchpoint->numGPScratchRegisters = 1;
</del><ins>+    // Note: call ref can call either WebAssemblyFunction or WebAssemblyWrapperFunction. Because
+    // WebAssemblyWrapperFunction is like calling into the embedder, we conservatively assume all call indirects
+    // can be to the embedder for our stack check calculation.
+    m_maxNumJSCallArguments = std::max(m_maxNumJSCallArguments, static_cast<uint32_t>(args.size()));
</ins><span class="cx"> 
</span><del>-        patchpoint->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) {
-            AllowMacroScratchRegisterUsage allowScratch(jit);
-            GPRReg newContextInstance = params[0].gpr();
-            GPRReg oldContextInstance = params[1].gpr();
-            const PinnedRegisterInfo& pinnedRegs = PinnedRegisterInfo::get();
-            GPRReg baseMemory = pinnedRegs.baseMemoryPointer;
-            ASSERT(newContextInstance != baseMemory);
-            jit.loadPtr(CCallHelpers::Address(oldContextInstance, Instance::offsetOfCachedStackLimit()), baseMemory);
-            jit.storePtr(baseMemory, CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedStackLimit()));
-            jit.storeWasmContextInstance(newContextInstance);
-            ASSERT(pinnedRegs.boundsCheckingSizeRegister != baseMemory);
-            // FIXME: We should support more than one memory size register
-            //   see: https://bugs.webkit.org/show_bug.cgi?id=162952
-            ASSERT(pinnedRegs.boundsCheckingSizeRegister != newContextInstance);
-            GPRReg scratch = params.gpScratch(0);
</del><ins>+    Value* jsInstanceOffset = constant(pointerType(), safeCast<int32_t>(WebAssemblyFunctionBase::offsetOfInstance()));
+    Value* jsCalleeInstance = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(),
+        m_currentBlock->appendNew<Value>(m_proc, Add, origin(), callee, jsInstanceOffset));
</ins><span class="cx"> 
</span><del>-            jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedBoundsCheckingSize()), pinnedRegs.boundsCheckingSizeRegister); // Memory size.
-            jit.loadPtr(CCallHelpers::Address(newContextInstance, Instance::offsetOfCachedMemory()), baseMemory); // Memory::void*.
</del><ins>+    Value* instanceOffset = constant(pointerType(), safeCast<int32_t>(JSWebAssemblyInstance::offsetOfInstance()));
+    Value* calleeInstance = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(),
+        m_currentBlock->appendNew<Value>(m_proc, Add, origin(), jsCalleeInstance, instanceOffset));
</ins><span class="cx"> 
</span><del>-            jit.cageConditionallyAndUntag(Gigacage::Primitive, baseMemory, pinnedRegs.boundsCheckingSizeRegister, scratch);
-        });
-        doContextSwitch->appendNewControlValue(m_proc, Jump, origin(), continuation);
-
-        m_currentBlock = continuation;
-    }
-
</del><span class="cx">     ExpressionType calleeCode = m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(),
</span><del>-        m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(), callableFunction,
-            safeCast<int32_t>(WasmToWasmImportableFunction::offsetOfEntrypointLoadLocation())));
</del><ins>+        m_currentBlock->appendNew<MemoryValue>(m_proc, Load, pointerType(), origin(), callee,
+            safeCast<int32_t>(WebAssemblyFunctionBase::offsetOfEntrypointLoadLocation())));
</ins><span class="cx"> 
</span><del>-    B3::Type returnType = toB3ResultType(&signature);
-    ExpressionType callResult = createCallPatchpoint(m_currentBlock, origin(), signature, args,
-        scopedLambdaRef<void(PatchpointValue*)>([=] (PatchpointValue* patchpoint) -> void {
-            patchpoint->effects.writesPinned = true;
-            patchpoint->effects.readsPinned = true;
-            // We need to clobber all potential pinned registers since we might be leaving the instance.
-            // We pessimistically assume we're always calling something that is bounds checking so
-            // because the wasm->wasm thunk unconditionally overrides the size registers.
-            // FIXME: We should not have to do this, but the wasm->wasm stub assumes it can
-            // use all the pinned registers as scratch: https://bugs.webkit.org/show_bug.cgi?id=172181
-            patchpoint->clobberLate(PinnedRegisterInfo::get().toSave(MemoryMode::BoundsChecking));
-
-            patchpoint->append(calleeCode, ValueRep::SomeRegister);
-            patchpoint->setGenerator([=] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) {
-                AllowMacroScratchRegisterUsage allowScratch(jit);
-                jit.call(params[params.proc().resultCount(returnType)].gpr(), WasmEntryPtrTag);
-            });
-        }));
-
-    switch (returnType.kind()) {
-    case B3::Void: {
-        break;
-    }
-    case B3::Tuple: {
-        const Vector<B3::Type>& tuple = m_proc.tupleForType(returnType);
-        for (unsigned i = 0; i < signature.returnCount(); ++i)
-            results.append(m_currentBlock->appendNew<ExtractValue>(m_proc, origin(), tuple[i], callResult, i));
-        break;
-    }
-    default: {
-        results.append(callResult);
-        break;
-    }
-    }
-
-    // The call could have been to another WebAssembly instance, and / or could have modified our Memory.
-    restoreWebAssemblyGlobalState(RestoreCachedStackLimit::Yes, m_info.memory, instanceValue(), m_proc, m_currentBlock);
-
-    return { };
</del><ins>+    return emitIndirectCall(calleeInstance, calleeCode, signature, args, results);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void B3IRGenerator::unify(const ExpressionType phi, const ExpressionType source)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmFunctionParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmFunctionParser.h (276895 => 276896)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmFunctionParser.h    2021-05-03 09:29:48 UTC (rev 276895)
+++ trunk/Source/JavaScriptCore/wasm/WasmFunctionParser.h       2021-05-03 11:00:43 UTC (rev 276896)
</span><span class="lines">@@ -1248,6 +1248,37 @@
</span><span class="cx"> 
</span><span class="cx">         return { };
</span><span class="cx">     }
</span><ins>+
+    case CallRef: {
+        WASM_PARSER_FAIL_IF(!Options::useWebAssemblyTypedFunctionReferences(), "function references are not enabled");
+        WASM_VALIDATOR_FAIL_IF(!m_expressionStack.last().type().isTypeIdx(), "non-funcref call_ref value ", m_expressionStack.last().type().kind);
+
+        const SignatureIndex calleeSignatureIndex = m_expressionStack.last().type().index;
+        const Signature& calleeSignature = SignatureInformation::get(calleeSignatureIndex);
+        size_t argumentCount = calleeSignature.argumentCount() + 1; // Add the callee's value.
+        WASM_PARSER_FAIL_IF(argumentCount > m_expressionStack.size(), "call_ref expects ", argumentCount, " arguments, but the expression stack currently holds ", m_expressionStack.size(), " values");
+
+        Vector<ExpressionType> args;
+        WASM_PARSER_FAIL_IF(!args.tryReserveCapacity(argumentCount + 1), "can't allocate enough memory for ", argumentCount, " call_indirect arguments");
+        size_t firstArgumentIndex = m_expressionStack.size() - argumentCount;
+        for (size_t i = firstArgumentIndex; i < m_expressionStack.size(); ++i) {
+            TypedExpression arg = m_expressionStack.at(i);
+            if (i < m_expressionStack.size() - 1)
+                WASM_VALIDATOR_FAIL_IF(arg.type() != calleeSignature.argument(i - firstArgumentIndex), "argument type mismatch in call_indirect, got ", arg.type().kind, ", expected ", calleeSignature.argument(i - firstArgumentIndex).kind);
+            args.uncheckedAppend(arg);
+            m_context.didPopValueFromStack();
+        }
+        m_expressionStack.shrink(firstArgumentIndex);
+
+        ResultList results;
+        WASM_TRY_ADD_TO_CONTEXT(addCallRef(calleeSignature, args, results));
+
+        for (unsigned i = 0; i < calleeSignature.returnCount(); ++i)
+            m_expressionStack.constructAndAppend(calleeSignature.returnType(i), results[i]);
+
+        return { };
+    }
+
</ins><span class="cx">     case Block: {
</span><span class="cx">         BlockSignature inlineSignature;
</span><span class="cx">         WASM_PARSER_FAIL_IF(!parseBlockSignature(m_info, inlineSignature), "can't get block's signature");
</span><span class="lines">@@ -1739,6 +1770,7 @@
</span><span class="cx">     // no immediate cases
</span><span class="cx">     FOR_EACH_WASM_BINARY_OP(CREATE_CASE)
</span><span class="cx">     FOR_EACH_WASM_UNARY_OP(CREATE_CASE)
</span><ins>+    case CallRef:
</ins><span class="cx">     case Unreachable:
</span><span class="cx">     case Nop:
</span><span class="cx">     case Return:
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmLLIntGeneratorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmLLIntGenerator.cpp (276895 => 276896)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmLLIntGenerator.cpp  2021-05-03 09:29:48 UTC (rev 276895)
+++ trunk/Source/JavaScriptCore/wasm/WasmLLIntGenerator.cpp     2021-05-03 11:00:43 UTC (rev 276896)
</span><span class="lines">@@ -253,6 +253,7 @@
</span><span class="cx">     // Calls
</span><span class="cx">     PartialResult WARN_UNUSED_RETURN addCall(uint32_t calleeIndex, const Signature&, Vector<ExpressionType>& args, ResultList& results);
</span><span class="cx">     PartialResult WARN_UNUSED_RETURN addCallIndirect(unsigned tableIndex, const Signature&, Vector<ExpressionType>& args, ResultList& results);
</span><ins>+    PartialResult WARN_UNUSED_RETURN addCallRef(const Signature&, Vector<ExpressionType>& args, ResultList& results);
</ins><span class="cx">     PartialResult WARN_UNUSED_RETURN addUnreachable();
</span><span class="cx"> 
</span><span class="cx">     void didFinishParsingLocals();
</span><span class="lines">@@ -1104,6 +1105,21 @@
</span><span class="cx">     return { };
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+auto LLIntGenerator::addCallRef(const Signature& signature, Vector<ExpressionType>& args, ResultList& results) -> PartialResult
+{
+    ExpressionType callee = args.takeLast();
+
+    LLIntCallInformation info = callInformationForCaller(signature);
+    unifyValuesWithBlock(info.arguments, args);
+    if (Context::useFastTLS())
+        WasmCallRef::emit(this, callee, m_codeBlock->addSignature(signature), info.stackOffset, info.numberOfStackArguments);
+    else
+        WasmCallRefNoTls::emit(this, callee, m_codeBlock->addSignature(signature), info.stackOffset, info.numberOfStackArguments);
+    info.commitResults(results);
+
+    return { };
+}
+
</ins><span class="cx"> auto LLIntGenerator::addRefIsNull(ExpressionType value, ExpressionType& result) -> PartialResult
</span><span class="cx"> {
</span><span class="cx">     result = push();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmSlowPathscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmSlowPaths.cpp (276895 => 276896)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmSlowPaths.cpp       2021-05-03 09:29:48 UTC (rev 276895)
+++ trunk/Source/JavaScriptCore/wasm/WasmSlowPaths.cpp  2021-05-03 11:00:43 UTC (rev 276896)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> #if ENABLE(WEBASSEMBLY)
</span><span class="cx"> 
</span><span class="cx"> #include "BytecodeStructs.h"
</span><ins>+#include "JSWebAssemblyInstance.h"
</ins><span class="cx"> #include "LLIntData.h"
</span><span class="cx"> #include "WasmBBQPlan.h"
</span><span class="cx"> #include "WasmCallee.h"
</span><span class="lines">@@ -40,6 +41,7 @@
</span><span class="cx"> #include "WasmOperations.h"
</span><span class="cx"> #include "WasmSignatureInlines.h"
</span><span class="cx"> #include "WasmWorklist.h"
</span><ins>+#include "WebAssemblyFunction.h"
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace LLInt {
</span><span class="cx"> 
</span><span class="lines">@@ -498,6 +500,40 @@
</span><span class="cx">     return doWasmCallIndirect(callFrame, instance, functionIndex, instruction.m_tableIndex, instruction.m_signatureIndex);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline SlowPathReturnType doWasmCallRef(CallFrame* callFrame, Wasm::Instance* callerInstance, JSValue targetReference, unsigned signatureIndex)
+{
+    UNUSED_PARAM(callFrame);
+
+    ASSERT(targetReference.isObject());
+    JSObject* referenceAsObject = jsCast<JSObject*>(targetReference);
+
+    ASSERT(referenceAsObject->inherits<WebAssemblyFunctionBase>(callerInstance->owner<JSObject>()->vm()));
+    auto* wasmFunction = jsCast<WebAssemblyFunctionBase*>(referenceAsObject);
+    Wasm::WasmToWasmImportableFunction function = wasmFunction->importableFunction();
+    Wasm::Instance* calleeInstance = &wasmFunction->instance()->instance();
+
+    if (calleeInstance != callerInstance)
+        calleeInstance->setCachedStackLimit(callerInstance->cachedStackLimit());
+
+    ASSERT(function.signatureIndex == Wasm::SignatureInformation::get(CODE_BLOCK()->signature(signatureIndex)));
+    UNUSED_PARAM(signatureIndex);
+    WASM_CALL_RETURN(calleeInstance, function.entrypointLoadLocation->executableAddress(), WasmEntryPtrTag);
+}
+
+WASM_SLOW_PATH_DECL(call_ref)
+{
+    auto instruction = pc->as<WasmCallRef, WasmOpcodeTraits>();
+    JSValue reference = JSValue::decode(READ(instruction.m_functionReference).encodedJSValue());
+    return doWasmCallRef(callFrame, instance, reference, instruction.m_signatureIndex);
+}
+
+WASM_SLOW_PATH_DECL(call_ref_no_tls)
+{
+    auto instruction = pc->as<WasmCallRefNoTls, WasmOpcodeTraits>();
+    JSValue reference = JSValue::decode(READ(instruction.m_functionReference).encodedJSValue());
+    return doWasmCallRef(callFrame, instance, reference, instruction.m_signatureIndex);
+}
+
</ins><span class="cx"> WASM_SLOW_PATH_DECL(set_global_ref)
</span><span class="cx"> {
</span><span class="cx">     auto instruction = pc->as<WasmSetGlobalRef, WasmOpcodeTraits>();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmWasmSlowPathsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/WasmSlowPaths.h (276895 => 276896)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/WasmSlowPaths.h 2021-05-03 09:29:48 UTC (rev 276895)
+++ trunk/Source/JavaScriptCore/wasm/WasmSlowPaths.h    2021-05-03 11:00:43 UTC (rev 276896)
</span><span class="lines">@@ -76,6 +76,8 @@
</span><span class="cx"> WASM_SLOW_PATH_HIDDEN_DECL(call_no_tls);
</span><span class="cx"> WASM_SLOW_PATH_HIDDEN_DECL(call_indirect);
</span><span class="cx"> WASM_SLOW_PATH_HIDDEN_DECL(call_indirect_no_tls);
</span><ins>+WASM_SLOW_PATH_HIDDEN_DECL(call_ref);
+WASM_SLOW_PATH_HIDDEN_DECL(call_ref_no_tls);
</ins><span class="cx"> WASM_SLOW_PATH_HIDDEN_DECL(set_global_ref);
</span><span class="cx"> WASM_SLOW_PATH_HIDDEN_DECL(set_global_ref_portable_binding);
</span><span class="cx"> WASM_SLOW_PATH_HIDDEN_DECL(memory_atomic_wait32);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsJSWebAssemblyTablecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.cpp (276895 => 276896)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.cpp       2021-05-03 09:29:48 UTC (rev 276895)
+++ trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.cpp  2021-05-03 11:00:43 UTC (rev 276896)
</span><span class="lines">@@ -105,7 +105,7 @@
</span><span class="cx">     m_table->set(index, value);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void JSWebAssemblyTable::set(uint32_t index, WebAssemblyFunction* function)
</del><ins>+void JSWebAssemblyTable::set(uint32_t index, WebAssemblyFunctionBase* function)
</ins><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT(index < length());
</span><span class="cx">     RELEASE_ASSERT(m_table->asFuncrefTable());
</span><span class="lines">@@ -113,14 +113,6 @@
</span><span class="cx">     subThis.setFunction(index, function, function->importableFunction(), &function->instance()->instance());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void JSWebAssemblyTable::set(uint32_t index, WebAssemblyWrapperFunction* function)
-{
-    RELEASE_ASSERT(index < length());
-    RELEASE_ASSERT(m_table->asFuncrefTable());
-    auto& subThis = *static_cast<Wasm::FuncRefTable*>(&m_table.get());
-    subThis.setFunction(index, function, function->importableFunction(), &function->instance()->instance());
-}
-
</del><span class="cx"> void JSWebAssemblyTable::clear(uint32_t index)
</span><span class="cx"> {
</span><span class="cx">     RELEASE_ASSERT(index < length());
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsJSWebAssemblyTableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.h (276895 => 276896)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.h 2021-05-03 09:29:48 UTC (rev 276895)
+++ trunk/Source/JavaScriptCore/wasm/js/JSWebAssemblyTable.h    2021-05-03 11:00:43 UTC (rev 276896)
</span><span class="lines">@@ -60,8 +60,7 @@
</span><span class="cx">     uint32_t allocatedLength() const { return m_table->allocatedLength(length()); }
</span><span class="cx">     bool grow(uint32_t delta, JSValue defaultValue) WARN_UNUSED_RETURN;
</span><span class="cx">     JSValue get(uint32_t);
</span><del>-    void set(uint32_t, WebAssemblyFunction*);
-    void set(uint32_t, WebAssemblyWrapperFunction*);
</del><ins>+    void set(uint32_t, WebAssemblyFunctionBase*);
</ins><span class="cx">     void set(uint32_t, JSValue);
</span><span class="cx">     void clear(uint32_t);
</span><span class="cx">     JSObject* type(JSGlobalObject*);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsWebAssemblyFunctioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp (276895 => 276896)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp      2021-05-03 09:29:48 UTC (rev 276895)
+++ trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp 2021-05-03 11:00:43 UTC (rev 276896)
</span><span class="lines">@@ -454,9 +454,8 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> WebAssemblyFunction::WebAssemblyFunction(VM& vm, NativeExecutable* executable, JSGlobalObject* globalObject, Structure* structure, Wasm::Callee& jsEntrypoint, Wasm::WasmToWasmImportableFunction::LoadLocation wasmToWasmEntrypointLoadLocation, Wasm::SignatureIndex signatureIndex)
</span><del>-    : Base { vm, executable, globalObject, structure }
</del><ins>+    : Base { vm, executable, globalObject, structure, Wasm::WasmToWasmImportableFunction { signatureIndex, wasmToWasmEntrypointLoadLocation } }
</ins><span class="cx">     , m_jsEntrypoint { jsEntrypoint.entrypoint() }
</span><del>-    , m_importableFunction { signatureIndex, wasmToWasmEntrypointLoadLocation }
</del><span class="cx"> { }
</span><span class="cx"> 
</span><span class="cx"> template<typename Visitor>
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsWebAssemblyFunctionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.h (276895 => 276896)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.h        2021-05-03 09:29:48 UTC (rev 276895)
+++ trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunction.h   2021-05-03 11:00:43 UTC (rev 276896)
</span><span class="lines">@@ -39,7 +39,6 @@
</span><span class="cx"> class JSGlobalObject;
</span><span class="cx"> struct ProtoCallFrame;
</span><span class="cx"> class WebAssemblyInstance;
</span><del>-using Wasm::WasmToWasmImportableFunction;
</del><span class="cx"> 
</span><span class="cx"> class WebAssemblyFunction final : public WebAssemblyFunctionBase {
</span><span class="cx"> public:
</span><span class="lines">@@ -61,10 +60,6 @@
</span><span class="cx">     JS_EXPORT_PRIVATE static WebAssemblyFunction* create(VM&, JSGlobalObject*, Structure*, unsigned, const String&, JSWebAssemblyInstance*, Wasm::Callee& jsEntrypoint, WasmToWasmImportableFunction::LoadLocation, Wasm::SignatureIndex);
</span><span class="cx">     static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
</span><span class="cx"> 
</span><del>-    Wasm::SignatureIndex signatureIndex() const { return m_importableFunction.signatureIndex; }
-    WasmToWasmImportableFunction::LoadLocation entrypointLoadLocation() const { return m_importableFunction.entrypointLoadLocation; }
-    WasmToWasmImportableFunction importableFunction() const { return m_importableFunction; }
-
</del><span class="cx">     MacroAssemblerCodePtr<WasmEntryPtrTag> jsEntrypoint(ArityCheckMode arity)
</span><span class="cx">     {
</span><span class="cx">         if (arity == ArityCheckNotRequired)
</span><span class="lines">@@ -73,8 +68,6 @@
</span><span class="cx">         return m_jsEntrypoint;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    static ptrdiff_t offsetOfEntrypointLoadLocation() { return OBJECT_OFFSETOF(WebAssemblyFunction, m_importableFunction) + WasmToWasmImportableFunction::offsetOfEntrypointLoadLocation(); }
-
</del><span class="cx">     MacroAssemblerCodePtr<JSEntryPtrTag> jsCallEntrypoint()
</span><span class="cx">     {
</span><span class="cx">         if (m_jsCallEntrypoint)
</span><span class="lines">@@ -95,11 +88,10 @@
</span><span class="cx"> 
</span><span class="cx">     RegisterSet calleeSaves() const;
</span><span class="cx"> 
</span><del>-    // It's safe to just hold the raw WasmToWasmImportableFunction/jsEntrypoint because we have a reference
</del><ins>+    // It's safe to just hold the raw jsEntrypoint because we have a reference
</ins><span class="cx">     // to our Instance, which points to the Module that exported us, which
</span><span class="cx">     // ensures that the actual Signature/code doesn't get deallocated.
</span><span class="cx">     MacroAssemblerCodePtr<WasmEntryPtrTag> m_jsEntrypoint;
</span><del>-    WasmToWasmImportableFunction m_importableFunction;
</del><span class="cx">     WriteBarrier<JSToWasmICCallee> m_jsToWasmICCallee;
</span><span class="cx">     // Used for JS calling into Wasm.
</span><span class="cx">     MacroAssemblerCodeRef<JSEntryPtrTag> m_jsCallEntrypoint;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsWebAssemblyFunctionBasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunctionBase.cpp (276895 => 276896)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunctionBase.cpp  2021-05-03 09:29:48 UTC (rev 276895)
+++ trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunctionBase.cpp     2021-05-03 11:00:43 UTC (rev 276896)
</span><span class="lines">@@ -37,8 +37,9 @@
</span><span class="cx"> 
</span><span class="cx"> const ClassInfo WebAssemblyFunctionBase::s_info = { "WebAssemblyFunctionBase", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(WebAssemblyFunctionBase) };
</span><span class="cx"> 
</span><del>-WebAssemblyFunctionBase::WebAssemblyFunctionBase(VM& vm, NativeExecutable* executable, JSGlobalObject* globalObject, Structure* structure)
</del><ins>+WebAssemblyFunctionBase::WebAssemblyFunctionBase(VM& vm, NativeExecutable* executable, JSGlobalObject* globalObject, Structure* structure, WasmToWasmImportableFunction importableFunction)
</ins><span class="cx">     : Base(vm, executable, globalObject, structure)
</span><ins>+    , m_importableFunction(importableFunction)
</ins><span class="cx"> { }
</span><span class="cx"> 
</span><span class="cx"> template<typename Visitor>
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsWebAssemblyFunctionBaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunctionBase.h (276895 => 276896)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunctionBase.h    2021-05-03 09:29:48 UTC (rev 276895)
+++ trunk/Source/JavaScriptCore/wasm/js/WebAssemblyFunctionBase.h       2021-05-03 11:00:43 UTC (rev 276896)
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> 
</span><span class="cx"> class JSGlobalObject;
</span><span class="cx"> class JSWebAssemblyInstance;
</span><ins>+using Wasm::WasmToWasmImportableFunction;
</ins><span class="cx"> 
</span><span class="cx"> class WebAssemblyFunctionBase : public JSFunction {
</span><span class="cx"> public:
</span><span class="lines">@@ -43,14 +44,26 @@
</span><span class="cx">     DECLARE_INFO;
</span><span class="cx"> 
</span><span class="cx">     JSWebAssemblyInstance* instance() const { return m_instance.get(); }
</span><ins>+
+    Wasm::SignatureIndex signatureIndex() const { return m_importableFunction.signatureIndex; }
+    WasmToWasmImportableFunction::LoadLocation entrypointLoadLocation() const { return m_importableFunction.entrypointLoadLocation; }
+    WasmToWasmImportableFunction importableFunction() const { return m_importableFunction; }
+
</ins><span class="cx">     static ptrdiff_t offsetOfInstance() { return OBJECT_OFFSETOF(WebAssemblyFunctionBase, m_instance); }
</span><span class="cx"> 
</span><ins>+    static ptrdiff_t offsetOfEntrypointLoadLocation() { return OBJECT_OFFSETOF(WebAssemblyFunctionBase, m_importableFunction) + WasmToWasmImportableFunction::offsetOfEntrypointLoadLocation(); }
+
</ins><span class="cx"> protected:
</span><span class="cx">     DECLARE_VISIT_CHILDREN;
</span><span class="cx">     void finishCreation(VM&, NativeExecutable*, unsigned length, const String& name, JSWebAssemblyInstance*);
</span><del>-    WebAssemblyFunctionBase(VM&, NativeExecutable*, JSGlobalObject*, Structure*);
</del><ins>+    WebAssemblyFunctionBase(VM&, NativeExecutable*, JSGlobalObject*, Structure*, WasmToWasmImportableFunction);
</ins><span class="cx"> 
</span><span class="cx">     WriteBarrier<JSWebAssemblyInstance> m_instance;
</span><ins>+
+    // It's safe to just hold the raw WasmToWasmImportableFunction because we have a reference
+    // to our Instance, which points to the CodeBlock, which points to the Module
+    // that exported us, which ensures that the actual Signature/code doesn't get deallocated.
+    WasmToWasmImportableFunction m_importableFunction;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsWebAssemblyWrapperFunctioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/WebAssemblyWrapperFunction.cpp (276895 => 276896)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/WebAssemblyWrapperFunction.cpp       2021-05-03 09:29:48 UTC (rev 276895)
+++ trunk/Source/JavaScriptCore/wasm/js/WebAssemblyWrapperFunction.cpp  2021-05-03 11:00:43 UTC (rev 276896)
</span><span class="lines">@@ -39,8 +39,7 @@
</span><span class="cx"> static JSC_DECLARE_HOST_FUNCTION(callWebAssemblyWrapperFunction);
</span><span class="cx"> 
</span><span class="cx"> WebAssemblyWrapperFunction::WebAssemblyWrapperFunction(VM& vm, NativeExecutable* executable, JSGlobalObject* globalObject, Structure* structure, Wasm::WasmToWasmImportableFunction importableFunction)
</span><del>-    : Base(vm, executable, globalObject, structure)
-    , m_importableFunction(importableFunction)
</del><ins>+    : Base(vm, executable, globalObject, structure, importableFunction)
</ins><span class="cx"> { }
</span><span class="cx"> 
</span><span class="cx"> WebAssemblyWrapperFunction* WebAssemblyWrapperFunction::create(VM& vm, JSGlobalObject* globalObject, Structure* structure, JSObject* function, unsigned importIndex, JSWebAssemblyInstance* instance, Wasm::SignatureIndex signatureIndex)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmjsWebAssemblyWrapperFunctionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/js/WebAssemblyWrapperFunction.h (276895 => 276896)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/js/WebAssemblyWrapperFunction.h 2021-05-03 09:29:48 UTC (rev 276895)
+++ trunk/Source/JavaScriptCore/wasm/js/WebAssemblyWrapperFunction.h    2021-05-03 11:00:43 UTC (rev 276896)
</span><span class="lines">@@ -32,8 +32,6 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><del>-using Wasm::WasmToWasmImportableFunction;
-
</del><span class="cx"> class WebAssemblyWrapperFunction final : public WebAssemblyFunctionBase {
</span><span class="cx"> public:
</span><span class="cx">     using Base = WebAssemblyFunctionBase;
</span><span class="lines">@@ -51,9 +49,6 @@
</span><span class="cx">     static WebAssemblyWrapperFunction* create(VM&, JSGlobalObject*, Structure*, JSObject*, unsigned importIndex, JSWebAssemblyInstance*, Wasm::SignatureIndex);
</span><span class="cx">     static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
</span><span class="cx"> 
</span><del>-    Wasm::SignatureIndex signatureIndex() const { return m_importableFunction.signatureIndex; }
-    WasmToWasmImportableFunction::LoadLocation  entrypointLoadLocation() const { return m_importableFunction.entrypointLoadLocation; }
-    WasmToWasmImportableFunction importableFunction() const { return m_importableFunction; }
</del><span class="cx">     JSObject* function() { return m_function.get(); }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="lines">@@ -62,10 +57,6 @@
</span><span class="cx">     DECLARE_VISIT_CHILDREN;
</span><span class="cx"> 
</span><span class="cx">     WriteBarrier<JSObject> m_function;
</span><del>-    // It's safe to just hold the raw WasmToWasmImportableFunction because we have a reference
-    // to our Instance, which points to the CodeBlock, which points to the Module
-    // that exported us, which ensures that the actual Signature/code doesn't get deallocated.
-    WasmToWasmImportableFunction m_importableFunction;
</del><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorewasmwasmjson"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/wasm/wasm.json (276895 => 276896)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/wasm/wasm.json       2021-05-03 09:29:48 UTC (rev 276895)
+++ trunk/Source/JavaScriptCore/wasm/wasm.json  2021-05-03 11:00:43 UTC (rev 276896)
</span><span class="lines">@@ -85,6 +85,7 @@
</span><span class="cx">         "data.drop":           { "category": "exttable",   "value":  252, "return": [],                              "parameter": [],                             "immediate": [{"name": "segment_index",  "type": "varuint32"}],                                             "description": "shrinks the size of the segment to zero", "extendedOp": 9 },
</span><span class="cx">         "call":                { "category": "call",       "value":  16, "return": ["call"],                         "parameter": ["call"],                       "immediate": [{"name": "function_index", "type": "varuint32"}],                                             "description": "call a function by its index" },
</span><span class="cx">         "call_indirect":       { "category": "call",       "value":  17, "return": ["call"],                         "parameter": ["call"],                       "immediate": [{"name": "type_index",     "type": "varuint32"}, {"name": "table_index","type": "varuint32"}],"description": "call a function indirect with an expected signature" },
</span><ins>+        "call_ref":            { "category": "call",       "value":  20, "return": ["call"],                         "parameter": ["call"],                       "immediate": [],                                                                                            "description": "call a function reference" },
</ins><span class="cx">         "i32.load8_s":         { "category": "memory",     "value":  44, "return": ["i32"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
</span><span class="cx">         "i32.load8_u":         { "category": "memory",     "value":  45, "return": ["i32"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
</span><span class="cx">         "i32.load16_s":        { "category": "memory",     "value":  46, "return": ["i32"],                          "parameter": ["addr"],                       "immediate": [{"name": "flags",          "type": "varuint32"}, {"name": "offset",   "type": "varuint32"}], "description": "load from memory" },
</span></span></pre>
</div>
</div>

</body>
</html>