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