Diff
Modified: trunk/JSTests/ChangeLog (286702 => 286703)
--- trunk/JSTests/ChangeLog 2021-12-08 20:27:32 UTC (rev 286702)
+++ trunk/JSTests/ChangeLog 2021-12-08 20:27:51 UTC (rev 286703)
@@ -1,3 +1,41 @@
+2021-12-08 Asumu Takikawa <[email protected]>
+
+ Support WebAssembly.Memory imports in Wasm/ESM modules.
+ https://bugs.webkit.org/show_bug.cgi?id=184745
+
+ Reviewed by Yusuke Suzuki.
+
+ * wasm/modules/wasm-imports-js-exports.js:
+ (then):
+ * wasm/modules/wasm-imports-js-exports/memory-fail-1.js: Added.
+ * wasm/modules/wasm-imports-js-exports/memory-fail-1.wasm: Added.
+ * wasm/modules/wasm-imports-js-exports/memory-fail-1.wat: Added.
+ * wasm/modules/wasm-imports-js-exports/memory-fail-2.js: Added.
+ * wasm/modules/wasm-imports-js-exports/memory-fail-2.wasm: Added.
+ * wasm/modules/wasm-imports-js-exports/memory-fail-2.wat: Added.
+ * wasm/modules/wasm-imports-js-exports/memory-fail-3.js: Added.
+ * wasm/modules/wasm-imports-js-exports/memory-fail-3.wasm: Added.
+ * wasm/modules/wasm-imports-js-exports/memory-fail-3.wat: Added.
+ * wasm/modules/wasm-imports-js-exports/memory-fail-4.js: Added.
+ * wasm/modules/wasm-imports-js-exports/memory-fail-4.wasm: Added.
+ * wasm/modules/wasm-imports-js-exports/memory-fail-4.wat: Added.
+ * wasm/modules/wasm-imports-js-exports/memory-fail-5.js: Added.
+ * wasm/modules/wasm-imports-js-exports/memory-fail-5.wasm: Added.
+ * wasm/modules/wasm-imports-js-exports/memory-fail-5.wat: Added.
+ * wasm/modules/wasm-imports-js-exports/memory.js: Added.
+ (export.setMemory):
+ * wasm/modules/wasm-imports-js-exports/memory.wasm: Added.
+ * wasm/modules/wasm-imports-js-exports/memory.wat: Added.
+ * wasm/modules/wasm-imports-js-exports/shared-memory.js: Added.
+ * wasm/modules/wasm-imports-js-exports/shared-memory.wasm: Added.
+ * wasm/modules/wasm-imports-js-exports/shared-memory.wat: Added.
+ * wasm/modules/wasm-imports-js-re-exports-wasm-exports.js:
+ * wasm/modules/wasm-imports-js-re-exports-wasm-exports/imports.wasm:
+ * wasm/modules/wasm-imports-js-re-exports-wasm-exports/imports.wat:
+ * wasm/modules/wasm-imports-js-re-exports-wasm-exports/re-export.js:
+ * wasm/modules/wasm-imports-js-re-exports-wasm-exports/sum.wasm:
+ * wasm/modules/wasm-imports-js-re-exports-wasm-exports/sum.wat:
+
2021-12-07 Saam Barati <[email protected]>
TypedArray prototype set should go down the fast path when using non clamped integer types of the same byte size
Added: trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-1.js (0 => 286703)
--- trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-1.js (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-1.js 2021-12-08 20:27:51 UTC (rev 286703)
@@ -0,0 +1 @@
+export let memory = 3;
Added: trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-1.wasm (0 => 286703)
--- trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-1.wasm (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-1.wasm 2021-12-08 20:27:51 UTC (rev 286703)
@@ -0,0 +1 @@
+��asm������./memory-fail-1.jsmemory��
\ No newline at end of file
Added: trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-1.wat (0 => 286703)
--- trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-1.wat (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-1.wat 2021-12-08 20:27:51 UTC (rev 286703)
@@ -0,0 +1,2 @@
+(module
+ (import "./memory-fail-1.js" "memory" (memory $m 1)))
Added: trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-2.js (0 => 286703)
--- trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-2.js (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-2.js 2021-12-08 20:27:51 UTC (rev 286703)
@@ -0,0 +1,3 @@
+export let memory = new WebAssembly.Memory({
+ initial: 1,
+});
Added: trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-2.wasm (0 => 286703)
--- trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-2.wasm (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-2.wasm 2021-12-08 20:27:51 UTC (rev 286703)
@@ -0,0 +1 @@
+��asm������./memory-fail-2.jsmemory��
\ No newline at end of file
Added: trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-2.wat (0 => 286703)
--- trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-2.wat (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-2.wat 2021-12-08 20:27:51 UTC (rev 286703)
@@ -0,0 +1,2 @@
+(module
+ (import "./memory-fail-2.js" "memory" (memory $m 4)))
Added: trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-3.js (0 => 286703)
--- trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-3.js (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-3.js 2021-12-08 20:27:51 UTC (rev 286703)
@@ -0,0 +1,3 @@
+export let memory = new WebAssembly.Memory({
+ initial: 1,
+});
Added: trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-3.wasm (0 => 286703)
--- trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-3.wasm (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-3.wasm 2021-12-08 20:27:51 UTC (rev 286703)
@@ -0,0 +1 @@
+��asm������./memory-fail-3.jsmemory
Added: trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-3.wat (0 => 286703)
--- trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-3.wat (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-3.wat 2021-12-08 20:27:51 UTC (rev 286703)
@@ -0,0 +1,2 @@
+(module
+ (import "./memory-fail-3.js" "memory" (memory $m 1 10)))
Added: trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-4.js (0 => 286703)
--- trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-4.js (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-4.js 2021-12-08 20:27:51 UTC (rev 286703)
@@ -0,0 +1,4 @@
+export let memory = new WebAssembly.Memory({
+ initial: 1,
+ maximum: 11
+});
Added: trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-4.wasm (0 => 286703)
--- trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-4.wasm (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-4.wasm 2021-12-08 20:27:51 UTC (rev 286703)
@@ -0,0 +1 @@
+��asm������./memory-fail-4.jsmemory
Added: trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-4.wat (0 => 286703)
--- trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-4.wat (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-4.wat 2021-12-08 20:27:51 UTC (rev 286703)
@@ -0,0 +1,2 @@
+(module
+ (import "./memory-fail-4.js" "memory" (memory $m 1 10)))
Added: trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-5.js (0 => 286703)
--- trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-5.js (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-5.js 2021-12-08 20:27:51 UTC (rev 286703)
@@ -0,0 +1,5 @@
+export let memory = new WebAssembly.Memory({
+ initial: 1,
+ maximum: 10,
+ shared: false,
+});
Added: trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-5.wasm (0 => 286703)
--- trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-5.wasm (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-5.wasm 2021-12-08 20:27:51 UTC (rev 286703)
@@ -0,0 +1 @@
+��asm������./memory-fail-5.jsmemory
Added: trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-5.wat (0 => 286703)
--- trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-5.wat (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory-fail-5.wat 2021-12-08 20:27:51 UTC (rev 286703)
@@ -0,0 +1,2 @@
+(module
+ (import "./memory-fail-5.js" "memory" (memory $m 1 10 shared)))
Added: trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory.js (0 => 286703)
--- trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory.js (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory.js 2021-12-08 20:27:51 UTC (rev 286703)
@@ -0,0 +1,10 @@
+export let memory = new WebAssembly.Memory({
+ initial: 1,
+});
+
+export function setMemory(mem) {
+ memory = mem;
+}
+
+const b = new Int8Array(memory.buffer);
+b[0] = 42;
Added: trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory.wasm (0 => 286703)
--- trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory.wasm (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory.wasm 2021-12-08 20:27:51 UTC (rev 286703)
@@ -0,0 +1,3 @@
+��asm������`./memory.jsmemory����
+getMem����
+ �� ��-����
\ No newline at end of file
Added: trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory.wat (0 => 286703)
--- trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory.wat (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-exports/memory.wat 2021-12-08 20:27:51 UTC (rev 286703)
@@ -0,0 +1,4 @@
+(module
+ (import "./memory.js" "memory" (memory $m 1))
+ (func (export "getMem") (param i32) (result i32)
+ (i32.load8_u (local.get 0))))
Added: trunk/JSTests/wasm/modules/wasm-imports-js-exports/shared-memory.js (0 => 286703)
--- trunk/JSTests/wasm/modules/wasm-imports-js-exports/shared-memory.js (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-exports/shared-memory.js 2021-12-08 20:27:51 UTC (rev 286703)
@@ -0,0 +1,8 @@
+export const memory = new WebAssembly.Memory({
+ initial: 1,
+ maximum: 10,
+ shared: true
+});
+
+const b = new Int8Array(memory.buffer);
+b[0] = 42;
Added: trunk/JSTests/wasm/modules/wasm-imports-js-exports/shared-memory.wasm (0 => 286703)
--- trunk/JSTests/wasm/modules/wasm-imports-js-exports/shared-memory.wasm (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-exports/shared-memory.wasm 2021-12-08 20:27:51 UTC (rev 286703)
@@ -0,0 +1,4 @@
+��asm������`./shared-memory.jsmemory
+��
+getMem����
+ �� ��-����
\ No newline at end of file
Added: trunk/JSTests/wasm/modules/wasm-imports-js-exports/shared-memory.wat (0 => 286703)
--- trunk/JSTests/wasm/modules/wasm-imports-js-exports/shared-memory.wat (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-exports/shared-memory.wat 2021-12-08 20:27:51 UTC (rev 286703)
@@ -0,0 +1,4 @@
+(module
+ (import "./shared-memory.js" "memory" (memory $m 1 10 shared))
+ (func (export "getMem") (param i32) (result i32)
+ (i32.load8_u (local.get 0))))
Modified: trunk/JSTests/wasm/modules/wasm-imports-js-exports.js (286702 => 286703)
--- trunk/JSTests/wasm/modules/wasm-imports-js-exports.js 2021-12-08 20:27:32 UTC (rev 286702)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-exports.js 2021-12-08 20:27:51 UTC (rev 286703)
@@ -18,3 +18,37 @@
assert.isFunction(getElem);
assert.eq(getElem(), "foo");
+
+import { getMem } from "./wasm-imports-js-exports/memory.wasm";
+
+assert.isFunction(getMem);
+assert.eq(getMem(0), 42);
+assert.eq(getMem(65535), 0);
+assert.throws(() => getMem(65536), WebAssembly.RuntimeError, "Out of bounds memory access");
+
+import { getMem as sharedGetMem } from "./wasm-imports-js-exports/shared-memory.wasm";
+
+assert.isFunction(sharedGetMem);
+assert.eq(sharedGetMem(0), 42);
+assert.eq(sharedGetMem(65535), 0);
+assert.throws(() => sharedGetMem(65536), WebAssembly.RuntimeError, "Out of bounds memory access");
+
+import("./wasm-imports-js-exports/memory-fail-1.wasm").then($vm.abort, function (error) {
+ assert.eq(String(error), `LinkError: Memory import ./memory-fail-1.js:memory is not an instance of WebAssembly.Memory`);
+}).then(function () { }, $vm.abort);
+
+import("./wasm-imports-js-exports/memory-fail-2.wasm").then($vm.abort, function (error) {
+ assert.eq(String(error), `LinkError: Memory import ./memory-fail-2.js:memory provided an 'initial' that is smaller than the module's declared 'initial' import memory size`);
+}).then(function () { }, $vm.abort);
+
+import("./wasm-imports-js-exports/memory-fail-3.wasm").then($vm.abort, function (error) {
+ assert.eq(String(error), `LinkError: Memory import ./memory-fail-3.js:memory did not have a 'maximum' but the module requires that it does`);
+}).then(function () { }, $vm.abort);
+
+import("./wasm-imports-js-exports/memory-fail-4.wasm").then($vm.abort, function (error) {
+ assert.eq(String(error), `LinkError: Memory import ./memory-fail-4.js:memory provided a 'maximum' that is larger than the module's declared 'maximum' import memory size`);
+}).then(function () { }, $vm.abort);
+
+import("./wasm-imports-js-exports/memory-fail-5.wasm").then($vm.abort, function (error) {
+ assert.eq(String(error), `LinkError: Memory import ./memory-fail-5.js:memory provided a 'shared' that is different from the module's declared 'shared' import memory attribute`);
+}).then(function () { }, $vm.abort);
Modified: trunk/JSTests/wasm/modules/wasm-imports-js-re-exports-wasm-exports/imports.wasm (286702 => 286703)
--- trunk/JSTests/wasm/modules/wasm-imports-js-re-exports-wasm-exports/imports.wasm 2021-12-08 20:27:32 UTC (rev 286702)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-re-exports-wasm-exports/imports.wasm 2021-12-08 20:27:51 UTC (rev 286703)
@@ -1,2 +1,2 @@
-��asm������``��`H./re-export.jssum��./re-export.jsanswer��./re-export.jstablep����table��addOne�� getAnswer�� ��A
+��asm������``��`b./re-export.jssum��./re-export.jsanswer��./re-export.jstablep��./re-export.jsmemory��'table��memory��addOne�� getAnswer�� ��A
��A ������#��
\ No newline at end of file
Modified: trunk/JSTests/wasm/modules/wasm-imports-js-re-exports-wasm-exports/imports.wat (286702 => 286703)
--- trunk/JSTests/wasm/modules/wasm-imports-js-re-exports-wasm-exports/imports.wat 2021-12-08 20:27:32 UTC (rev 286702)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-re-exports-wasm-exports/imports.wat 2021-12-08 20:27:51 UTC (rev 286703)
@@ -2,7 +2,9 @@
(import "./re-export.js" "sum" (func $sum (param i32 i32) (result i32)))
(import "./re-export.js" "answer" (global i32))
(import "./re-export.js" "table" (table $table 4 funcref))
+ (import "./re-export.js" "memory" (memory $memory 1 1))
(export "table" (table $table))
+ (export "memory" (memory $memory))
(type $t0 (func (param i32) (result i32)))
(func $addOne (export "addOne") (type $t0) (param $p0 i32) (result i32)
i32.const 1
Modified: trunk/JSTests/wasm/modules/wasm-imports-js-re-exports-wasm-exports/re-export.js (286702 => 286703)
--- trunk/JSTests/wasm/modules/wasm-imports-js-re-exports-wasm-exports/re-export.js 2021-12-08 20:27:32 UTC (rev 286702)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-re-exports-wasm-exports/re-export.js 2021-12-08 20:27:51 UTC (rev 286703)
@@ -1 +1 @@
-export { sum, answer, table } from "./sum.wasm"
+export { sum, answer, table, memory } from "./sum.wasm"
Modified: trunk/JSTests/wasm/modules/wasm-imports-js-re-exports-wasm-exports/sum.wasm (286702 => 286703)
--- trunk/JSTests/wasm/modules/wasm-imports-js-re-exports-wasm-exports/sum.wasm 2021-12-08 20:27:32 UTC (rev 286702)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-re-exports-wasm-exports/sum.wasm 2021-12-08 20:27:51 UTC (rev 286703)
@@ -1,2 +1,3 @@
-��asm������`��p����A*sum����answer��table�� ��A����
- �� ��j
\ No newline at end of file
+��asm������`��p����A*!sum����answer��table��memory�� ��A����
+ �� ��j
+��A����
\ No newline at end of file
Modified: trunk/JSTests/wasm/modules/wasm-imports-js-re-exports-wasm-exports/sum.wat (286702 => 286703)
--- trunk/JSTests/wasm/modules/wasm-imports-js-re-exports-wasm-exports/sum.wat 2021-12-08 20:27:32 UTC (rev 286702)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-re-exports-wasm-exports/sum.wat 2021-12-08 20:27:51 UTC (rev 286703)
@@ -6,4 +6,6 @@
i32.add)
(global (export "answer") i32 i32.const 42)
(table $table (export "table") 4 funcref)
+ (memory $memory (export "memory") 1 1)
+ (data (i32.const 4) "\10\00\10\00")
(elem (i32.const 0) $sum))
Modified: trunk/JSTests/wasm/modules/wasm-imports-js-re-exports-wasm-exports.js (286702 => 286703)
--- trunk/JSTests/wasm/modules/wasm-imports-js-re-exports-wasm-exports.js 2021-12-08 20:27:32 UTC (rev 286702)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-re-exports-wasm-exports.js 2021-12-08 20:27:51 UTC (rev 286703)
@@ -1,4 +1,4 @@
-import { addOne, getAnswer, table } from "./wasm-imports-js-re-exports-wasm-exports/imports.wasm"
+import { addOne, getAnswer, table, memory } from "./wasm-imports-js-re-exports-wasm-exports/imports.wasm"
import * as assert from '../assert.js';
assert.isFunction(addOne);
@@ -13,3 +13,13 @@
assert.eq(table.get(1)(-1), 0);
assert.eq(table.get(2), null);
assert.eq(table.get(3), null);
+
+assert.eq(memory.buffer.byteLength, 65536);
+const buf = new Uint8Array(memory.buffer);
+assert.eq(buf[4], 0x10);
+assert.eq(buf[5], 0x00);
+assert.eq(buf[6], 0x10);
+assert.eq(buf[7], 0x00);
+buf[0] = 0x42;
+assert.eq(buf[0], 0x42);
+assert.eq(buf[65536], undefined);
Modified: trunk/Source/_javascript_Core/ChangeLog (286702 => 286703)
--- trunk/Source/_javascript_Core/ChangeLog 2021-12-08 20:27:32 UTC (rev 286702)
+++ trunk/Source/_javascript_Core/ChangeLog 2021-12-08 20:27:51 UTC (rev 286703)
@@ -1,3 +1,42 @@
+2021-12-08 Asumu Takikawa <[email protected]>
+
+ Support WebAssembly.Memory imports in Wasm/ESM modules.
+ https://bugs.webkit.org/show_bug.cgi?id=184745
+
+ Reviewed by Yusuke Suzuki.
+
+ Changes how Wasm code is initialized for modules that are loaded
+ by the module loader and have memory imports. The initial code for
+ the LLInt tier is copied to all memory modes, so that the memory
+ import can be initialized after compilation. When LLInt is turned
+ off, the compilation of B3/Air code is delayed until the memory is
+ initialized.
+
+ * wasm/WasmCodeBlock.cpp:
+ (JSC::Wasm::CodeBlock::createFromExisting):
+ (JSC::Wasm::CodeBlock::CodeBlock):
+ * wasm/WasmCodeBlock.h:
+ * wasm/WasmInstance.h:
+ (JSC::Wasm::Instance::finalizeCreation):
+ (JSC::Wasm::Instance::module const):
+ (JSC::Wasm::Instance::codeBlock const):
+ (JSC::Wasm::Instance::memory const):
+ (JSC::Wasm::Instance::isImportFunction const):
+ (JSC::Wasm::Instance::module): Deleted.
+ (JSC::Wasm::Instance::codeBlock): Deleted.
+ (JSC::Wasm::Instance::memory): Deleted.
+ * wasm/WasmModule.cpp:
+ (JSC::Wasm::Module::copyInitialCodeBlockToAllMemoryModes):
+ * wasm/WasmModule.h:
+ * wasm/js/JSWebAssembly.cpp:
+ (JSC::instantiate):
+ * wasm/js/JSWebAssemblyInstance.cpp:
+ (JSC::JSWebAssemblyInstance::finalizeCreation):
+ (JSC::JSWebAssemblyInstance::tryCreate):
+ * wasm/js/JSWebAssemblyInstance.h:
+ * wasm/js/WebAssemblyModuleRecord.cpp:
+ (JSC::WebAssemblyModuleRecord::initializeImportsAndExports):
+
2021-12-08 Yusuke Suzuki <[email protected]>
[JSC] Introduce WriteBarrierStructureID
Modified: trunk/Source/_javascript_Core/wasm/WasmCodeBlock.cpp (286702 => 286703)
--- trunk/Source/_javascript_Core/wasm/WasmCodeBlock.cpp 2021-12-08 20:27:32 UTC (rev 286702)
+++ trunk/Source/_javascript_Core/wasm/WasmCodeBlock.cpp 2021-12-08 20:27:51 UTC (rev 286703)
@@ -37,10 +37,30 @@
Ref<CodeBlock> CodeBlock::create(Context* context, MemoryMode mode, ModuleInformation& moduleInformation, RefPtr<LLIntCallees> llintCallees)
{
- auto* result = new (NotNull, fastMalloc(sizeof(CodeBlock))) CodeBlock(context, mode, moduleInformation, llintCallees);
- return adoptRef(*result);
+ return adoptRef(*new CodeBlock(context, mode, moduleInformation, llintCallees));
}
+Ref<CodeBlock> CodeBlock::createFromExisting(MemoryMode mode, const CodeBlock& other)
+{
+ return adoptRef(*new CodeBlock(mode, other));
+}
+
+CodeBlock::CodeBlock(MemoryMode mode, const CodeBlock& other)
+ : m_calleeCount(other.m_calleeCount)
+ , m_mode(mode)
+ , m_llintCallees(other.m_llintCallees)
+ , m_embedderCallees(other.m_embedderCallees)
+ , m_wasmIndirectCallEntryPoints(other.m_wasmIndirectCallEntryPoints)
+ , m_wasmToWasmCallsites(other.m_wasmToWasmCallsites)
+ , m_wasmToWasmExitStubs(other.m_wasmToWasmExitStubs)
+{
+#if ENABLE(WEBASSEMBLY_B3JIT)
+ m_bbqCallees.resize(m_calleeCount);
+ m_omgCallees.resize(m_calleeCount);
+#endif
+ setCompilationFinished();
+}
+
CodeBlock::CodeBlock(Context* context, MemoryMode mode, ModuleInformation& moduleInformation, RefPtr<LLIntCallees> llintCallees)
: m_calleeCount(moduleInformation.internalFunctionCount())
, m_mode(mode)
Modified: trunk/Source/_javascript_Core/wasm/WasmCodeBlock.h (286702 => 286703)
--- trunk/Source/_javascript_Core/wasm/WasmCodeBlock.h 2021-12-08 20:27:32 UTC (rev 286702)
+++ trunk/Source/_javascript_Core/wasm/WasmCodeBlock.h 2021-12-08 20:27:51 UTC (rev 286703)
@@ -54,6 +54,7 @@
typedef void CallbackType(Ref<CodeBlock>&&);
using AsyncCompilationCallback = RefPtr<WTF::SharedTask<CallbackType>>;
static Ref<CodeBlock> create(Context*, MemoryMode, ModuleInformation&, RefPtr<LLIntCallees>);
+ static Ref<CodeBlock> createFromExisting(MemoryMode, const CodeBlock&);
void waitUntilFinished();
void compileAsync(Context*, AsyncCompilationCallback&&);
@@ -137,6 +138,7 @@
#endif
CodeBlock(Context*, MemoryMode, ModuleInformation&, RefPtr<LLIntCallees>);
+ CodeBlock(MemoryMode, const CodeBlock&);
void setCompilationFinished();
unsigned m_calleeCount;
MemoryMode m_mode;
Modified: trunk/Source/_javascript_Core/wasm/WasmInstance.h (286702 => 286703)
--- trunk/Source/_javascript_Core/wasm/WasmInstance.h 2021-12-08 20:27:32 UTC (rev 286702)
+++ trunk/Source/_javascript_Core/wasm/WasmInstance.h 2021-12-08 20:27:51 UTC (rev 286703)
@@ -56,10 +56,9 @@
static Ref<Instance> create(Context*, Ref<Module>&&, EntryFrame** pointerToTopEntryFrame, void** pointerToActualStackLimit, StoreTopCallFrameCallback&&);
- void finalizeCreation(void* owner, Ref<CodeBlock>&& codeBlock)
+ void finalizeCreation(void* owner)
{
m_owner = owner;
- m_codeBlock = WTFMove(codeBlock);
}
JS_EXPORT_PRIVATE ~Instance();
@@ -71,9 +70,9 @@
Wasm::Context* context() const { return m_context; }
- Module& module() { return m_module.get(); }
- CodeBlock* codeBlock() { return m_codeBlock.get(); }
- Memory* memory() { return m_memory.get(); }
+ Module& module() const { return m_module.get(); }
+ CodeBlock* codeBlock() const { return module().codeBlockFor(memory()->mode()); }
+ Memory* memory() const { return m_memory.get(); }
Table* table(unsigned);
void setTable(unsigned, Ref<Table>&&);
const Element* elementAt(unsigned) const;
@@ -82,7 +81,7 @@
bool isImportFunction(uint32_t functionIndex) const
{
- return functionIndex < m_codeBlock->functionImportCount();
+ return functionIndex < codeBlock()->functionImportCount();
}
void tableInit(uint32_t dstOffset, uint32_t srcOffset, uint32_t length, uint32_t elementIndex, uint32_t tableIndex);
@@ -226,7 +225,6 @@
CagedPtr<Gigacage::Primitive, void, tagCagedPtr> m_cachedMemory;
size_t m_cachedBoundsCheckingSize { 0 };
Ref<Module> m_module;
- RefPtr<CodeBlock> m_codeBlock;
RefPtr<Memory> m_memory;
MallocPtr<Global::Value, VMMalloc> m_globals;
Modified: trunk/Source/_javascript_Core/wasm/WasmModule.cpp (286702 => 286703)
--- trunk/Source/_javascript_Core/wasm/WasmModule.cpp 2021-12-08 20:27:32 UTC (rev 286702)
+++ trunk/Source/_javascript_Core/wasm/WasmModule.cpp 2021-12-08 20:27:51 UTC (rev 286703)
@@ -111,6 +111,18 @@
codeBlock->compileAsync(context, WTFMove(task));
}
+void Module::copyInitialCodeBlockToAllMemoryModes(MemoryMode initialMode)
+{
+ ASSERT(m_codeBlocks[static_cast<uint8_t>(initialMode)]);
+ const CodeBlock& initialBlock = *m_codeBlocks[static_cast<uint8_t>(initialMode)];
+ for (unsigned i = 0; i < Wasm::NumberOfMemoryModes; i++) {
+ if (i == static_cast<uint8_t>(initialMode))
+ continue;
+ Ref<CodeBlock> newBlock = CodeBlock::createFromExisting(static_cast<MemoryMode>(i), initialBlock);
+ m_codeBlocks[i] = WTFMove(newBlock);
+ }
+}
+
} } // namespace JSC::Wasm
#endif // ENABLE(WEBASSEMBLY)
Modified: trunk/Source/_javascript_Core/wasm/WasmModule.h (286702 => 286703)
--- trunk/Source/_javascript_Core/wasm/WasmModule.h 2021-12-08 20:27:32 UTC (rev 286702)
+++ trunk/Source/_javascript_Core/wasm/WasmModule.h 2021-12-08 20:27:51 UTC (rev 286703)
@@ -65,6 +65,9 @@
JS_EXPORT_PRIVATE ~Module();
CodeBlock* codeBlockFor(MemoryMode mode) { return m_codeBlocks[static_cast<uint8_t>(mode)].get(); }
+
+ void copyInitialCodeBlockToAllMemoryModes(MemoryMode);
+
private:
Ref<CodeBlock> getOrCreateCodeBlock(Context*, MemoryMode);
Modified: trunk/Source/_javascript_Core/wasm/js/JSWebAssembly.cpp (286702 => 286703)
--- trunk/Source/_javascript_Core/wasm/js/JSWebAssembly.cpp 2021-12-08 20:27:32 UTC (rev 286702)
+++ trunk/Source/_javascript_Core/wasm/js/JSWebAssembly.cpp 2021-12-08 20:27:51 UTC (rev 286703)
@@ -190,6 +190,7 @@
{
auto scope = DECLARE_THROW_SCOPE(vm);
// In order to avoid potentially recompiling a module. We first gather all the import/memory information prior to compiling code.
+ // When called via the module loader, the memory is not available yet at this step, so we skip initializing the memory here.
JSWebAssemblyInstance* instance = JSWebAssemblyInstance::tryCreate(vm, globalObject, moduleKey, module, importObject, globalObject->webAssemblyInstanceStructure(), Ref<Wasm::Module>(module->module()), creationMode);
if (UNLIKELY(scope.exception())) {
promise->rejectWithCaughtException(globalObject, scope);
Modified: trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyInstance.cpp (286702 => 286703)
--- trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyInstance.cpp 2021-12-08 20:27:32 UTC (rev 286702)
+++ trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyInstance.cpp 2021-12-08 20:27:51 UTC (rev 286703)
@@ -107,7 +107,7 @@
void JSWebAssemblyInstance::finalizeCreation(VM& vm, JSGlobalObject* globalObject, Ref<Wasm::CodeBlock>&& wasmCodeBlock, JSObject* importObject, Wasm::CreationMode creationMode)
{
- m_instance->finalizeCreation(this, wasmCodeBlock.copyRef());
+ m_instance->finalizeCreation(this);
auto scope = DECLARE_THROW_SCOPE(vm);
@@ -135,6 +135,29 @@
m_module->setCodeBlock(vm, memoryMode(), jsCodeBlock);
}
+ // In the module loader case, we will initialize all memory modes with the initial LLInt compilation
+ // results, so that later when memory imports become available, the appropriate CodeBlock can be used.
+ // If LLInt is disabled, we instead defer compilation to module evaluation.
+ bool hasMemoryImport = module()->moduleInformation().memory.isImport();
+ if (creationMode == Wasm::CreationMode::FromModuleLoader && Options::useWasmLLInt() && hasMemoryImport) {
+ Wasm::MemoryMode initialMode = Wasm::MemoryMode::BoundsChecking;
+ ASSERT(memoryMode() == initialMode);
+ module()->module().copyInitialCodeBlockToAllMemoryModes(initialMode);
+
+ for (unsigned i = 0; i < Wasm::NumberOfMemoryModes; i++) {
+ if (i == static_cast<uint8_t>(initialMode))
+ continue;
+ Wasm::MemoryMode memoryMode = static_cast<Wasm::MemoryMode>(i);
+ RefPtr<Wasm::CodeBlock> codeBlock = module()->module().codeBlockFor(memoryMode);
+ jsCodeBlock = JSWebAssemblyCodeBlock::create(vm, codeBlock.releaseNonNull(), module()->module().moduleInformation());
+ if (UNLIKELY(!jsCodeBlock->runnable())) {
+ throwException(globalObject, scope, createJSWebAssemblyLinkError(globalObject, vm, jsCodeBlock->errorMessage()));
+ return;
+ }
+ m_module->setCodeBlock(vm, memoryMode, jsCodeBlock);
+ }
+ }
+
for (unsigned importFunctionNum = 0; importFunctionNum < instance().numImportFunctions(); ++importFunctionNum) {
auto* info = instance().importFunctionInfo(importFunctionNum);
info->wasmToEmbedderStub = m_codeBlock->wasmToEmbedderStub(importFunctionNum);
@@ -212,8 +235,8 @@
Identifier::fromUid(PrivateName(PrivateName::Description, "WebAssemblyImportName")),
});
- // Skip Wasm::ExternalKind::Function validation here. It will be done in WebAssemblyModuleRecord::link.
- // Eventually we will move all the linking code here to WebAssemblyModuleRecord::link.
+ // Validation for most types are done in WebAssemblyModuleRecord::initializeImportsAndExports and skipped here.
+ // Eventually we will move all the linking code here to WebAssemblyModuleRecord::initializeImportsAndExports.
switch (import.kind) {
case Wasm::ExternalKind::Function:
case Wasm::ExternalKind::Global:
@@ -253,6 +276,10 @@
RELEASE_ASSERT(!hasMemoryImport); // This should be guaranteed by a validation failure.
RELEASE_ASSERT(moduleInformation.memory);
hasMemoryImport = true;
+ // For the module loader, we cannot initialize the memory here so we delay this
+ // until WebAssemblyModuleRecord's initialization operation.
+ if (creationMode == Wasm::CreationMode::FromModuleLoader)
+ break;
JSWebAssemblyMemory* memory = jsDynamicCast<JSWebAssemblyMemory*>(vm, value);
// i. If v is not a WebAssembly.Memory object, throw a WebAssembly.LinkError.
if (!memory)
Modified: trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyInstance.h (286702 => 286703)
--- trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyInstance.h 2021-12-08 20:27:32 UTC (rev 286702)
+++ trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyInstance.h 2021-12-08 20:27:51 UTC (rev 286703)
@@ -75,7 +75,6 @@
JSWebAssemblyMemory* memory() { return m_memory.get(); }
void setMemory(VM& vm, JSWebAssemblyMemory* value) {
- ASSERT(!memory());
m_memory.set(vm, this, value);
instance().setMemory(memory()->memory());
}
Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.cpp (286702 => 286703)
--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.cpp 2021-12-08 20:27:32 UTC (rev 286702)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.cpp 2021-12-08 20:27:51 UTC (rev 286703)
@@ -121,7 +121,6 @@
RELEASE_ASSERT(m_instance);
- Wasm::CodeBlock* codeBlock = m_instance->instance().codeBlock();
JSWebAssemblyModule* module = m_instance->module();
const Wasm::ModuleInformation& moduleInformation = module->moduleInformation();
@@ -143,7 +142,9 @@
case Wasm::ExternalKind::Exception:
break;
case Wasm::ExternalKind::Memory:
- continue;
+ if (creationMode == Wasm::CreationMode::FromJS)
+ continue;
+ break;
}
Identifier moduleName = Identifier::fromString(vm, String::fromUTF8(import.module));
@@ -408,7 +409,46 @@
break;
}
+ // Memory initialization will only occur here if the creation mode was through the module loader.
case Wasm::ExternalKind::Memory:
+ JSWebAssemblyMemory* memory = jsDynamicCast<JSWebAssemblyMemory*>(vm, value);
+ // i. If v is not a WebAssembly.Memory object, throw a WebAssembly.LinkError.
+ if (!memory)
+ return exception(createJSWebAssemblyLinkError(globalObject, vm, importFailMessage(import, "Memory import", "is not an instance of WebAssembly.Memory")));
+
+ Wasm::PageCount declaredInitial = moduleInformation.memory.initial();
+ Wasm::PageCount importedInitial = memory->memory().initial();
+ if (importedInitial < declaredInitial)
+ return exception(createJSWebAssemblyLinkError(globalObject, vm, importFailMessage(import, "Memory import", "provided an 'initial' that is smaller than the module's declared 'initial' import memory size")));
+
+ if (Wasm::PageCount declaredMaximum = moduleInformation.memory.maximum()) {
+ Wasm::PageCount importedMaximum = memory->memory().maximum();
+ if (!importedMaximum)
+ return exception(createJSWebAssemblyLinkError(globalObject, vm, importFailMessage(import, "Memory import", "did not have a 'maximum' but the module requires that it does")));
+
+ if (importedMaximum > declaredMaximum)
+ return exception(createJSWebAssemblyLinkError(globalObject, vm, importFailMessage(import, "Memory import", "provided a 'maximum' that is larger than the module's declared 'maximum' import memory size")));
+ }
+
+ if ((memory->memory().sharingMode() == Wasm::MemorySharingMode::Shared) != moduleInformation.memory.isShared())
+ return exception(createJSWebAssemblyLinkError(globalObject, vm, importFailMessage(import, "Memory import", "provided a 'shared' that is different from the module's declared 'shared' import memory attribute")));
+
+ // ii. Append v to memories.
+ // iii. Append v.[[Memory]] to imports.
+ m_instance->setMemory(vm, memory);
+ RETURN_IF_EXCEPTION(scope, void());
+
+ // Usually at this point the module's code block in any memory mode should be
+ // runnable due to the LLint tier code being shared among all modes. However,
+ // if LLInt is disabled, it is possible that the code needs to be compiled at
+ // this point when we know which memory mode to use.
+ Wasm::CodeBlock* codeBlock = m_instance->instance().codeBlock();
+ if (!codeBlock || !codeBlock->runnable()) {
+ codeBlock = m_instance->module()->module().compileSync(&vm.wasmContext, memory->memory().mode()).ptr();
+ if (!codeBlock->runnable())
+ return exception(createJSWebAssemblyLinkError(globalObject, vm, codeBlock->errorMessage()));
+ }
+ RELEASE_ASSERT(codeBlock->isSafeToRun(memory->memory().mode()));
break;
}
}
@@ -435,6 +475,9 @@
}
}
+ // This needs to be looked up after the memory is initialized, as the codeBlock depends on the memory mode.
+ Wasm::CodeBlock* codeBlock = m_instance->instance().codeBlock();
+
for (Wasm::SignatureIndex signatureIndex : moduleInformation.internalExceptionSignatureIndices)
m_instance->instance().addTag(Wasm::Tag::create(Wasm::SignatureInformation::get(signatureIndex)));