Title: [284702] trunk
Revision
284702
Author
[email protected]
Date
2021-10-22 11:35:42 -0700 (Fri, 22 Oct 2021)

Log Message

Change WebAssembly module import linking time to evaluate step.
https://bugs.webkit.org/show_bug.cgi?id=231114

Patch by Asumu Takikawa <[email protected]> on 2021-10-22
Reviewed by Yusuke Suzuki.

JSTests:

Added test cases based on Wasm/ESM proposal examples from:

  https://github.com/WebAssembly/esm-integration/blob/main/proposals/esm-integration/EXAMPLES.md

The new tests cases cover the bindings made for both JS<->Wasm
and Wasm<->JS cyclic module cases, and importing values from JS
into Wasm modules. The tests do not cover importing memory values
as this does not work yet.

* wasm/modules/wasm-js-cycle.js:
* wasm/modules/wasm-js-cycle/entry-global.wasm:
* wasm/modules/wasm-js-cycle/entry-global.wat:
* wasm/modules/wasm-js-cycle/entry-table.wasm:
* wasm/modules/wasm-js-cycle/entry-table.wat:
* wasm/modules/wasm-js-cycle/global.js:
(from.string_appeared_here.export.incrementGlobal): Deleted.
* wasm/modules/wasm-js-cycle/table.js:
(from.string_appeared_here.export.setTable): Deleted.

* wasm/modules/js-wasm-cycle.js:
(then):
* wasm/modules/js-wasm-cycle/entry-function.js: Added.
(f):
* wasm/modules/js-wasm-cycle/entry-i32-global.js: Added.
* wasm/modules/js-wasm-cycle/entry-i32-value.js: Added.
* wasm/modules/js-wasm-cycle/entry-memory.js: Added.
* wasm/modules/js-wasm-cycle/entry-table.js: Added.
* wasm/modules/js-wasm-cycle/entry-wasm-global.js: Added.
(f):
* wasm/modules/js-wasm-cycle/entry-wasm-memory.js: Added.
(f):
* wasm/modules/js-wasm-cycle/entry-wasm-table.js: Added.
(f):
* wasm/modules/js-wasm-cycle/function.wasm: Added.
* wasm/modules/js-wasm-cycle/function.wat: Added.
* wasm/modules/js-wasm-cycle/i32-global.wasm: Added.
* wasm/modules/js-wasm-cycle/i32-global.wat: Added.
* wasm/modules/js-wasm-cycle/i32-value.wasm: Added.
* wasm/modules/js-wasm-cycle/i32-value.wat: Added.
* wasm/modules/js-wasm-cycle/memory.wasm: Added.
* wasm/modules/js-wasm-cycle/memory.wat: Added.
* wasm/modules/js-wasm-cycle/table.wasm: Added.
* wasm/modules/js-wasm-cycle/table.wat: Added.
* wasm/modules/js-wasm-cycle/wasm-global.wasm: Added.
* wasm/modules/js-wasm-cycle/wasm-global.wat: Added.
* wasm/modules/js-wasm-cycle/wasm-memory.wasm: Added.
* wasm/modules/js-wasm-cycle/wasm-memory.wat: Added.
* wasm/modules/js-wasm-cycle/wasm-table.wasm: Added.
* wasm/modules/js-wasm-cycle/wasm-table.wat: Added.
* wasm/modules/wasm-imports-js-exports.js:
* wasm/modules/wasm-imports-js-exports/global.js: Added.
* wasm/modules/wasm-imports-js-exports/global.wasm: Added.
* wasm/modules/wasm-imports-js-exports/global.wat: Added.
* wasm/modules/wasm-imports-js-exports/table.js: Added.
* wasm/modules/wasm-imports-js-exports/table.wasm: Added.
* wasm/modules/wasm-imports-js-exports/table.wat: Added.
* wasm/modules/wasm-js-cycle.js:
* wasm/modules/wasm-js-cycle/entry-global.wasm: Added.
* wasm/modules/wasm-js-cycle/entry-global.wat: Added.
* wasm/modules/wasm-js-cycle/entry-memory.wasm: Added.
* wasm/modules/wasm-js-cycle/entry-memory.wat: Added.
* wasm/modules/wasm-js-cycle/entry-table.wasm: Added.
* wasm/modules/wasm-js-cycle/entry-table.wat: Added.
* wasm/modules/wasm-js-cycle/global.js: Added.
(export.incrementGlobal):
* wasm/modules/wasm-js-cycle/memory.js: Added.
(from.string_appeared_here.export.setMemory):
* wasm/modules/wasm-js-cycle/table.js: Added.
(export.setTable):

Source/_javascript_Core:

Moves the Wasm module import linking code to execute in the
module evaluation step, which is the behavior specified in the
Wasm/ESM-integration proposal:

  https://github.com/WebAssembly/esm-integration/tree/main/proposals/esm-integration#evaluate

* runtime/AbstractModuleRecord.cpp:
(JSC::AbstractModuleRecord::link):
(JSC::AbstractModuleRecord::evaluate):
* wasm/js/JSWebAssemblyInstance.cpp:
(JSC::JSWebAssemblyInstance::finalizeCreation):
* wasm/js/WebAssemblyModuleRecord.cpp:
(JSC::WebAssemblyModuleRecord::link):
(JSC::WebAssemblyModuleRecord::initializeImportsAndExports):
(JSC::WebAssemblyModuleRecord::linkImpl): Deleted.
* wasm/js/WebAssemblyModuleRecord.h:

Modified Paths

Added Paths

Diff

Modified: trunk/JSTests/ChangeLog (284701 => 284702)


--- trunk/JSTests/ChangeLog	2021-10-22 18:35:08 UTC (rev 284701)
+++ trunk/JSTests/ChangeLog	2021-10-22 18:35:42 UTC (rev 284702)
@@ -1,3 +1,80 @@
+2021-10-22  Asumu Takikawa  <[email protected]>
+
+        Change WebAssembly module import linking time to evaluate step.
+        https://bugs.webkit.org/show_bug.cgi?id=231114
+
+        Reviewed by Yusuke Suzuki.
+
+        Added test cases based on Wasm/ESM proposal examples from:
+
+          https://github.com/WebAssembly/esm-integration/blob/main/proposals/esm-integration/EXAMPLES.md
+
+        The new tests cases cover the bindings made for both JS<->Wasm
+        and Wasm<->JS cyclic module cases, and importing values from JS
+        into Wasm modules. The tests do not cover importing memory values
+        as this does not work yet.
+
+        * wasm/modules/wasm-js-cycle.js:
+        * wasm/modules/wasm-js-cycle/entry-global.wasm:
+        * wasm/modules/wasm-js-cycle/entry-global.wat:
+        * wasm/modules/wasm-js-cycle/entry-table.wasm:
+        * wasm/modules/wasm-js-cycle/entry-table.wat:
+        * wasm/modules/wasm-js-cycle/global.js:
+        (from.string_appeared_here.export.incrementGlobal): Deleted.
+        * wasm/modules/wasm-js-cycle/table.js:
+        (from.string_appeared_here.export.setTable): Deleted.
+
+        * wasm/modules/js-wasm-cycle.js:
+        (then):
+        * wasm/modules/js-wasm-cycle/entry-function.js: Added.
+        (f):
+        * wasm/modules/js-wasm-cycle/entry-i32-global.js: Added.
+        * wasm/modules/js-wasm-cycle/entry-i32-value.js: Added.
+        * wasm/modules/js-wasm-cycle/entry-memory.js: Added.
+        * wasm/modules/js-wasm-cycle/entry-table.js: Added.
+        * wasm/modules/js-wasm-cycle/entry-wasm-global.js: Added.
+        (f):
+        * wasm/modules/js-wasm-cycle/entry-wasm-memory.js: Added.
+        (f):
+        * wasm/modules/js-wasm-cycle/entry-wasm-table.js: Added.
+        (f):
+        * wasm/modules/js-wasm-cycle/function.wasm: Added.
+        * wasm/modules/js-wasm-cycle/function.wat: Added.
+        * wasm/modules/js-wasm-cycle/i32-global.wasm: Added.
+        * wasm/modules/js-wasm-cycle/i32-global.wat: Added.
+        * wasm/modules/js-wasm-cycle/i32-value.wasm: Added.
+        * wasm/modules/js-wasm-cycle/i32-value.wat: Added.
+        * wasm/modules/js-wasm-cycle/memory.wasm: Added.
+        * wasm/modules/js-wasm-cycle/memory.wat: Added.
+        * wasm/modules/js-wasm-cycle/table.wasm: Added.
+        * wasm/modules/js-wasm-cycle/table.wat: Added.
+        * wasm/modules/js-wasm-cycle/wasm-global.wasm: Added.
+        * wasm/modules/js-wasm-cycle/wasm-global.wat: Added.
+        * wasm/modules/js-wasm-cycle/wasm-memory.wasm: Added.
+        * wasm/modules/js-wasm-cycle/wasm-memory.wat: Added.
+        * wasm/modules/js-wasm-cycle/wasm-table.wasm: Added.
+        * wasm/modules/js-wasm-cycle/wasm-table.wat: Added.
+        * wasm/modules/wasm-imports-js-exports.js:
+        * wasm/modules/wasm-imports-js-exports/global.js: Added.
+        * wasm/modules/wasm-imports-js-exports/global.wasm: Added.
+        * wasm/modules/wasm-imports-js-exports/global.wat: Added.
+        * wasm/modules/wasm-imports-js-exports/table.js: Added.
+        * wasm/modules/wasm-imports-js-exports/table.wasm: Added.
+        * wasm/modules/wasm-imports-js-exports/table.wat: Added.
+        * wasm/modules/wasm-js-cycle.js:
+        * wasm/modules/wasm-js-cycle/entry-global.wasm: Added.
+        * wasm/modules/wasm-js-cycle/entry-global.wat: Added.
+        * wasm/modules/wasm-js-cycle/entry-memory.wasm: Added.
+        * wasm/modules/wasm-js-cycle/entry-memory.wat: Added.
+        * wasm/modules/wasm-js-cycle/entry-table.wasm: Added.
+        * wasm/modules/wasm-js-cycle/entry-table.wat: Added.
+        * wasm/modules/wasm-js-cycle/global.js: Added.
+        (export.incrementGlobal):
+        * wasm/modules/wasm-js-cycle/memory.js: Added.
+        (from.string_appeared_here.export.setMemory):
+        * wasm/modules/wasm-js-cycle/table.js: Added.
+        (export.setTable):
+
 2021-10-21  Yusuke Suzuki  <[email protected]>
 
         [JSC] Inserted GetTypedArrayLengthAsInt52 for PutByVal should have NodeResultInt52

Added: trunk/JSTests/wasm/modules/js-wasm-cycle/entry-function.js (0 => 284702)


--- trunk/JSTests/wasm/modules/js-wasm-cycle/entry-function.js	                        (rev 0)
+++ trunk/JSTests/wasm/modules/js-wasm-cycle/entry-function.js	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,4 @@
+import { f2 } from "./function.wasm"
+export { f, f2 };
+
+function f(x) { return x + 1 }

Added: trunk/JSTests/wasm/modules/js-wasm-cycle/entry-i32-global.js (0 => 284702)


--- trunk/JSTests/wasm/modules/js-wasm-cycle/entry-i32-global.js	                        (rev 0)
+++ trunk/JSTests/wasm/modules/js-wasm-cycle/entry-i32-global.js	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,2 @@
+import { glob2 } from "./i32-global.wasm"
+export const glob = new WebAssembly.Global({ value: "i32" }, 0);

Added: trunk/JSTests/wasm/modules/js-wasm-cycle/entry-i32-value.js (0 => 284702)


--- trunk/JSTests/wasm/modules/js-wasm-cycle/entry-i32-value.js	                        (rev 0)
+++ trunk/JSTests/wasm/modules/js-wasm-cycle/entry-i32-value.js	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,2 @@
+import { getGlob } from "./i32-value.wasm"
+export const glob = 84;

Added: trunk/JSTests/wasm/modules/js-wasm-cycle/entry-memory.js (0 => 284702)


--- trunk/JSTests/wasm/modules/js-wasm-cycle/entry-memory.js	                        (rev 0)
+++ trunk/JSTests/wasm/modules/js-wasm-cycle/entry-memory.js	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,3 @@
+import { f } from "./memory.wasm"
+
+export const m = new WebAssembly.Memory({ initial: 10 });

Added: trunk/JSTests/wasm/modules/js-wasm-cycle/entry-table.js (0 => 284702)


--- trunk/JSTests/wasm/modules/js-wasm-cycle/entry-table.js	                        (rev 0)
+++ trunk/JSTests/wasm/modules/js-wasm-cycle/entry-table.js	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,3 @@
+import { f } from "./table.wasm"
+
+export const t = new WebAssembly.Table({ element: "anyfunc" });

Added: trunk/JSTests/wasm/modules/js-wasm-cycle/entry-wasm-global.js (0 => 284702)


--- trunk/JSTests/wasm/modules/js-wasm-cycle/entry-wasm-global.js	                        (rev 0)
+++ trunk/JSTests/wasm/modules/js-wasm-cycle/entry-wasm-global.js	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,4 @@
+import { g } from "./wasm-global.wasm"
+
+export { f, g };
+function f(x) { return x + 1; }

Added: trunk/JSTests/wasm/modules/js-wasm-cycle/entry-wasm-memory.js (0 => 284702)


--- trunk/JSTests/wasm/modules/js-wasm-cycle/entry-wasm-memory.js	                        (rev 0)
+++ trunk/JSTests/wasm/modules/js-wasm-cycle/entry-wasm-memory.js	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,4 @@
+import { m } from "./wasm-memory.wasm"
+
+export { f, m };
+function f(x) { return x + 1; }

Added: trunk/JSTests/wasm/modules/js-wasm-cycle/entry-wasm-table.js (0 => 284702)


--- trunk/JSTests/wasm/modules/js-wasm-cycle/entry-wasm-table.js	                        (rev 0)
+++ trunk/JSTests/wasm/modules/js-wasm-cycle/entry-wasm-table.js	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,4 @@
+import { t } from "./wasm-table.wasm"
+
+export { f, t };
+function f(x) { return x + 1; }

Added: trunk/JSTests/wasm/modules/js-wasm-cycle/function.wasm (0 => 284702)


--- trunk/JSTests/wasm/modules/js-wasm-cycle/function.wasm	                        (rev 0)
+++ trunk/JSTests/wasm/modules/js-wasm-cycle/function.wasm	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,2 @@
+��asm������`./entry-function.jsf������f2��
+��A*��
\ No newline at end of file

Added: trunk/JSTests/wasm/modules/js-wasm-cycle/function.wat (0 => 284702)


--- trunk/JSTests/wasm/modules/js-wasm-cycle/function.wat	                        (rev 0)
+++ trunk/JSTests/wasm/modules/js-wasm-cycle/function.wat	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,5 @@
+(module
+    (import "./entry-function.js" "f" (func $f (param i32) (result i32)))
+    (func (export "f2") (param i32) (result i32)
+        (i32.const 42)
+        (call $f)))

Added: trunk/JSTests/wasm/modules/js-wasm-cycle/i32-global.wasm (0 => 284702)


--- trunk/JSTests/wasm/modules/js-wasm-cycle/i32-global.wasm	                        (rev 0)
+++ trunk/JSTests/wasm/modules/js-wasm-cycle/i32-global.wasm	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1 @@
+��asm������./entry-i32-global.jsglob����A*	glob2
\ No newline at end of file

Added: trunk/JSTests/wasm/modules/js-wasm-cycle/i32-global.wat (0 => 284702)


--- trunk/JSTests/wasm/modules/js-wasm-cycle/i32-global.wat	                        (rev 0)
+++ trunk/JSTests/wasm/modules/js-wasm-cycle/i32-global.wat	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,3 @@
+(module
+    (import "./entry-i32-global.js" "glob" (global i32))
+    (global (export "glob2") i32 (i32.const 42)))

Added: trunk/JSTests/wasm/modules/js-wasm-cycle/i32-value.wasm (0 => 284702)


--- trunk/JSTests/wasm/modules/js-wasm-cycle/i32-value.wasm	                        (rev 0)
+++ trunk/JSTests/wasm/modules/js-wasm-cycle/i32-value.wasm	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,2 @@
+��asm������`��./entry-i32-value.jsglob����getGlob����
+��#��
\ No newline at end of file

Added: trunk/JSTests/wasm/modules/js-wasm-cycle/i32-value.wat (0 => 284702)


--- trunk/JSTests/wasm/modules/js-wasm-cycle/i32-value.wat	                        (rev 0)
+++ trunk/JSTests/wasm/modules/js-wasm-cycle/i32-value.wat	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,4 @@
+(module
+    (import "./entry-i32-value.js" "glob" (global $glob i32))
+    (func (export "getGlob") (result i32)
+        (global.get $glob)))

Added: trunk/JSTests/wasm/modules/js-wasm-cycle/memory.wasm (0 => 284702)


--- trunk/JSTests/wasm/modules/js-wasm-cycle/memory.wasm	                        (rev 0)
+++ trunk/JSTests/wasm/modules/js-wasm-cycle/memory.wasm	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,3 @@
+��asm������`��./entry-memory.jsm��
+��f����
+��?��
\ No newline at end of file

Added: trunk/JSTests/wasm/modules/js-wasm-cycle/memory.wat (0 => 284702)


--- trunk/JSTests/wasm/modules/js-wasm-cycle/memory.wat	                        (rev 0)
+++ trunk/JSTests/wasm/modules/js-wasm-cycle/memory.wat	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,4 @@
+(module
+    (import "./entry-memory.js" "m" (memory $m 10))
+    (func (export "f") (result i32)
+        (memory.size)))

Added: trunk/JSTests/wasm/modules/js-wasm-cycle/table.wasm (0 => 284702)


--- trunk/JSTests/wasm/modules/js-wasm-cycle/table.wasm	                        (rev 0)
+++ trunk/JSTests/wasm/modules/js-wasm-cycle/table.wasm	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,2 @@
+��asm������`��./entry-table.jstp����f����
+	��A��%��\xD1
\ No newline at end of file

Added: trunk/JSTests/wasm/modules/js-wasm-cycle/table.wat (0 => 284702)


--- trunk/JSTests/wasm/modules/js-wasm-cycle/table.wat	                        (rev 0)
+++ trunk/JSTests/wasm/modules/js-wasm-cycle/table.wat	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,5 @@
+(module
+    (import "./entry-table.js" "t" (table $t 5 funcref))
+    (func (export "f") (result i32)
+        (table.get $t (i32.const 0))
+        (ref.is_null)))

Added: trunk/JSTests/wasm/modules/js-wasm-cycle/wasm-global.wasm (0 => 284702)


--- trunk/JSTests/wasm/modules/js-wasm-cycle/wasm-global.wasm	                        (rev 0)
+++ trunk/JSTests/wasm/modules/js-wasm-cycle/wasm-global.wasm	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1 @@
+��asm������`./entry-wasm-global.jsf������A*g��
\ No newline at end of file

Added: trunk/JSTests/wasm/modules/js-wasm-cycle/wasm-global.wat (0 => 284702)


--- trunk/JSTests/wasm/modules/js-wasm-cycle/wasm-global.wat	                        (rev 0)
+++ trunk/JSTests/wasm/modules/js-wasm-cycle/wasm-global.wat	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,3 @@
+(module
+    (import "./entry-wasm-global.js" "f" (func $f (param i32) (result i32)))
+    (global (export "g") i32 (i32.const 42)))

Added: trunk/JSTests/wasm/modules/js-wasm-cycle/wasm-memory.wasm (0 => 284702)


--- trunk/JSTests/wasm/modules/js-wasm-cycle/wasm-memory.wasm	                        (rev 0)
+++ trunk/JSTests/wasm/modules/js-wasm-cycle/wasm-memory.wasm	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,2 @@
+��asm������`./entry-wasm-memory.jsf������
+m��
\ No newline at end of file

Added: trunk/JSTests/wasm/modules/js-wasm-cycle/wasm-memory.wat (0 => 284702)


--- trunk/JSTests/wasm/modules/js-wasm-cycle/wasm-memory.wat	                        (rev 0)
+++ trunk/JSTests/wasm/modules/js-wasm-cycle/wasm-memory.wat	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,3 @@
+(module
+    (import "./entry-wasm-memory.js" "f" (func $f (param i32) (result i32)))
+    (memory (export "m") 10))

Added: trunk/JSTests/wasm/modules/js-wasm-cycle/wasm-table.wasm (0 => 284702)


--- trunk/JSTests/wasm/modules/js-wasm-cycle/wasm-table.wasm	                        (rev 0)
+++ trunk/JSTests/wasm/modules/js-wasm-cycle/wasm-table.wasm	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,2 @@
+��asm������`./entry-wasm-table.jsf����p��
+t��
\ No newline at end of file

Added: trunk/JSTests/wasm/modules/js-wasm-cycle/wasm-table.wat (0 => 284702)


--- trunk/JSTests/wasm/modules/js-wasm-cycle/wasm-table.wat	                        (rev 0)
+++ trunk/JSTests/wasm/modules/js-wasm-cycle/wasm-table.wat	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,3 @@
+(module
+    (import "./entry-wasm-table.js" "f" (func $f (param i32) (result i32)))
+    (table (export "t") 10 funcref))

Modified: trunk/JSTests/wasm/modules/js-wasm-cycle.js (284701 => 284702)


--- trunk/JSTests/wasm/modules/js-wasm-cycle.js	2021-10-22 18:35:08 UTC (rev 284701)
+++ trunk/JSTests/wasm/modules/js-wasm-cycle.js	2021-10-22 18:35:42 UTC (rev 284702)
@@ -1,4 +1,40 @@
 import * as assert from '../assert.js';
-import("./js-wasm-cycle/entry.js").then($vm.abort, function (error) {
-    assert.eq(String(error), `LinkError: import function ./entry.js:return42 must be callable`);
+import { return42 } from "./js-wasm-cycle/entry.js";
+
+assert.eq(return42(), 42);
+
+// Test the state of bindings with JS<->Wasm module cycles.
+// https://github.com/WebAssembly/esm-integration/blob/main/proposals/esm-integration/EXAMPLES.md#js---wasm-cycle-where-js-is-higher-in-the-module-graph
+
+// Testing JS exports.
+import("./js-wasm-cycle/entry-i32-global.js").then($vm.abort, function (error) {
+    assert.eq(String(error), `LinkError: imported global ./entry-i32-global.js:glob must be a number`);
 }).then(function () { }, $vm.abort);
+
+import("./js-wasm-cycle/entry-i32-value.js").then($vm.abort, function (error) {
+    assert.eq(String(error), `LinkError: imported global ./entry-i32-value.js:glob must be a number`);
+}).then(function () { }, $vm.abort);
+
+import("./js-wasm-cycle/entry-table.js").then($vm.abort, function (error) {
+    assert.eq(String(error), `LinkError: Table import ./entry-table.js:t is not an instance of WebAssembly.Table`);
+}).then(function () { }, $vm.abort);
+
+import("./js-wasm-cycle/entry-memory.js").then($vm.abort, function (error) {
+    assert.eq(String(error), `LinkError: Memory import ./entry-memory.js:m is not an instance of WebAssembly.Memory`);
+}).then(function () { }, $vm.abort);
+
+// Test Wasm exports.
+import { g } from "./js-wasm-cycle/entry-wasm-global.js";
+assert.instanceof(g, WebAssembly.Global);
+assert.eq(g.valueOf(), 42);
+
+import { m } from "./js-wasm-cycle/entry-wasm-memory.js";
+assert.instanceof(m, WebAssembly.Memory);
+
+import { t } from "./js-wasm-cycle/entry-wasm-table.js";
+assert.instanceof(t, WebAssembly.Table);
+
+// This case tests both Wasm and JS export.
+import { f2 } from "./js-wasm-cycle/entry-function.js";
+assert.isFunction(f2);
+assert.eq(f2(), 43);

Added: trunk/JSTests/wasm/modules/wasm-imports-js-exports/global.js (0 => 284702)


--- trunk/JSTests/wasm/modules/wasm-imports-js-exports/global.js	                        (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-exports/global.js	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,4 @@
+export const count = new WebAssembly.Global({
+    value: 'i32',
+    mutable: true,
+}, 42);

Added: trunk/JSTests/wasm/modules/wasm-imports-js-exports/global.wasm (0 => 284702)


--- trunk/JSTests/wasm/modules/wasm-imports-js-exports/global.wasm	                        (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-exports/global.wasm	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,2 @@
+��asm������`����./global.jscount��incrementCount����
+	��#��Aj$��
\ No newline at end of file

Added: trunk/JSTests/wasm/modules/wasm-imports-js-exports/global.wat (0 => 284702)


--- trunk/JSTests/wasm/modules/wasm-imports-js-exports/global.wat	                        (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-exports/global.wat	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,7 @@
+(module
+    (import "./global.js" "count" (global (mut i32)))
+    (func (export "incrementCount")
+        (global.set 0
+            (i32.add
+                (global.get 0)
+                (i32.const 1)))))

Added: trunk/JSTests/wasm/modules/wasm-imports-js-exports/table.js (0 => 284702)


--- trunk/JSTests/wasm/modules/wasm-imports-js-exports/table.js	                        (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-exports/table.js	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,6 @@
+export const table = new WebAssembly.Table({
+    element: "externref",
+    initial: 10,
+});
+
+table.set(0, "foo");

Added: trunk/JSTests/wasm/modules/wasm-imports-js-exports/table.wasm (0 => 284702)


--- trunk/JSTests/wasm/modules/wasm-imports-js-exports/table.wasm	                        (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-exports/table.wasm	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,4 @@
+��asm������`��o
+./table.jstableo��
+��getElem����
+��A��%��
\ No newline at end of file

Added: trunk/JSTests/wasm/modules/wasm-imports-js-exports/table.wat (0 => 284702)


--- trunk/JSTests/wasm/modules/wasm-imports-js-exports/table.wat	                        (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-exports/table.wat	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,4 @@
+(module
+    (import "./table.js" "table" (table $t 10 externref))
+    (func (export "getElem") (result externref)
+        (table.get $t (i32.const 0))))

Modified: trunk/JSTests/wasm/modules/wasm-imports-js-exports.js (284701 => 284702)


--- trunk/JSTests/wasm/modules/wasm-imports-js-exports.js	2021-10-22 18:35:08 UTC (rev 284701)
+++ trunk/JSTests/wasm/modules/wasm-imports-js-exports.js	2021-10-22 18:35:42 UTC (rev 284702)
@@ -5,3 +5,16 @@
 assert.eq(addOne(32), 33);
 assert.eq(addOne(-2), -1);
 assert.eq(addOne(0x7fffffff), -2147483648);
+
+import { incrementCount } from "./wasm-imports-js-exports/global.wasm";
+import { count } from "./wasm-imports-js-exports/global.js";
+
+assert.isFunction(incrementCount);
+assert.eq(count.valueOf(), 42);
+incrementCount();
+assert.eq(count.valueOf(), 43);
+
+import { getElem } from "./wasm-imports-js-exports/table.wasm";
+
+assert.isFunction(getElem);
+assert.eq(getElem(), "foo");

Added: trunk/JSTests/wasm/modules/wasm-js-cycle/entry-global.wasm (0 => 284702)


--- trunk/JSTests/wasm/modules/wasm-js-cycle/entry-global.wasm	                        (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-js-cycle/entry-global.wasm	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,2 @@
+��asm������`����`��;./global.jsincrementGlobal����./global.jsglobalFromJSA*getFromJSGlobal��g
+��#��
\ No newline at end of file

Added: trunk/JSTests/wasm/modules/wasm-js-cycle/entry-global.wat (0 => 284702)


--- trunk/JSTests/wasm/modules/wasm-js-cycle/entry-global.wat	                        (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-js-cycle/entry-global.wat	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,6 @@
+(module
+    (import "./global.js" "incrementGlobal" (func))
+    (import "./global.js" "globalFromJS" (global $fromJS (mut i32)))
+    (func (export "getFromJSGlobal") (result i32)
+        (global.get $fromJS))
+    (global (export "g") (mut i32) (i32.const 42)))

Added: trunk/JSTests/wasm/modules/wasm-js-cycle/entry-memory.wasm (0 => 284702)


--- trunk/JSTests/wasm/modules/wasm-js-cycle/entry-memory.wasm	                        (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-js-cycle/entry-memory.wasm	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,2 @@
+��asm������`��./memory.js	setMemory������
+m��
\ No newline at end of file

Added: trunk/JSTests/wasm/modules/wasm-js-cycle/entry-memory.wat (0 => 284702)


--- trunk/JSTests/wasm/modules/wasm-js-cycle/entry-memory.wat	                        (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-js-cycle/entry-memory.wat	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,3 @@
+(module
+    (import "./memory.js" "setMemory" (func (param i32 i32)))
+    (memory (export "m") 10))

Added: trunk/JSTests/wasm/modules/wasm-js-cycle/entry-table.wasm (0 => 284702)


--- trunk/JSTests/wasm/modules/wasm-js-cycle/entry-table.wasm	                        (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-js-cycle/entry-table.wasm	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,7 @@
+��asm������
+`o��`��o2
+./table.jssetTable����
+./table.jstableFromJSo��
+o��
+getFromJSTable��t
+��A��%��
\ No newline at end of file

Added: trunk/JSTests/wasm/modules/wasm-js-cycle/entry-table.wat (0 => 284702)


--- trunk/JSTests/wasm/modules/wasm-js-cycle/entry-table.wat	                        (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-js-cycle/entry-table.wat	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,6 @@
+(module
+    (import "./table.js" "setTable" (func (param i32) (param externref)))
+    (import "./table.js" "tableFromJS" (table $fromJS 10 externref))
+    (func (export "getFromJSTable") (result externref)
+        (table.get $fromJS (i32.const 0)))
+    (table (export "t") 10 externref))

Added: trunk/JSTests/wasm/modules/wasm-js-cycle/global.js (0 => 284702)


--- trunk/JSTests/wasm/modules/wasm-js-cycle/global.js	                        (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-js-cycle/global.js	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,8 @@
+import { g } from "./entry-global.wasm"
+export const globalFromJS = new WebAssembly.Global(
+    { value: "i32", mutable: true },
+    42
+);
+export function incrementGlobal() {
+    g.value = g.value + 1;
+}

Added: trunk/JSTests/wasm/modules/wasm-js-cycle/memory.js (0 => 284702)


--- trunk/JSTests/wasm/modules/wasm-js-cycle/memory.js	                        (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-js-cycle/memory.js	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,5 @@
+import { m } from "./entry-memory.wasm"
+export function setMemory(index, val) {
+    const view = new Int32Array(m.buffer);
+    view[index] = val;
+}

Added: trunk/JSTests/wasm/modules/wasm-js-cycle/table.js (0 => 284702)


--- trunk/JSTests/wasm/modules/wasm-js-cycle/table.js	                        (rev 0)
+++ trunk/JSTests/wasm/modules/wasm-js-cycle/table.js	2021-10-22 18:35:42 UTC (rev 284702)
@@ -0,0 +1,7 @@
+import { t } from "./entry-table.wasm"
+export const tableFromJS = new WebAssembly.Table(
+    { element: "externref", initial: 10 }
+);
+export function setTable(index, val) {
+    t.set(index, val);
+}

Modified: trunk/JSTests/wasm/modules/wasm-js-cycle.js (284701 => 284702)


--- trunk/JSTests/wasm/modules/wasm-js-cycle.js	2021-10-22 18:35:08 UTC (rev 284701)
+++ trunk/JSTests/wasm/modules/wasm-js-cycle.js	2021-10-22 18:35:42 UTC (rev 284702)
@@ -2,3 +2,38 @@
 import { return42 } from "./wasm-js-cycle/entry.wasm"
 
 assert.eq(return42(), 42);
+
+import { getFromJSGlobal, g } from "./wasm-js-cycle/entry-global.wasm"
+import { globalFromJS, incrementGlobal } from "./wasm-js-cycle/global.js"
+
+assert.instanceof(g, WebAssembly.Global);
+assert.eq(g.valueOf(), 42);
+incrementGlobal();
+assert.eq(g.valueOf(), 43);
+
+assert.isFunction(getFromJSGlobal);
+assert.eq(getFromJSGlobal(), globalFromJS.valueOf());
+globalFromJS.value = 84;
+assert.eq(getFromJSGlobal(), globalFromJS.valueOf());
+
+import { getFromJSTable, t } from "./wasm-js-cycle/entry-table.wasm"
+import { tableFromJS, setTable } from "./wasm-js-cycle/table.js"
+
+assert.instanceof(t, WebAssembly.Table);
+assert.eq(t.get(0), null);
+setTable(0, "foo");
+assert.eq(t.get(0), "foo");
+
+assert.isFunction(getFromJSTable);
+assert.eq(getFromJSTable(), tableFromJS.get(0));
+tableFromJS.set(0, "foo");
+assert.eq(getFromJSTable(), tableFromJS.get(0));
+
+import { m } from "./wasm-js-cycle/entry-memory.wasm"
+import { setMemory } from "./wasm-js-cycle/memory.js"
+
+assert.instanceof(m, WebAssembly.Memory);
+const view = new Int32Array(m.buffer);
+assert.eq(view[0], 0);
+setMemory(0, 42);
+assert.eq(view[0], 42);

Modified: trunk/Source/_javascript_Core/ChangeLog (284701 => 284702)


--- trunk/Source/_javascript_Core/ChangeLog	2021-10-22 18:35:08 UTC (rev 284701)
+++ trunk/Source/_javascript_Core/ChangeLog	2021-10-22 18:35:42 UTC (rev 284702)
@@ -1,3 +1,27 @@
+2021-10-22  Asumu Takikawa  <[email protected]>
+
+        Change WebAssembly module import linking time to evaluate step.
+        https://bugs.webkit.org/show_bug.cgi?id=231114
+
+        Reviewed by Yusuke Suzuki.
+
+        Moves the Wasm module import linking code to execute in the
+        module evaluation step, which is the behavior specified in the
+        Wasm/ESM-integration proposal:
+
+          https://github.com/WebAssembly/esm-integration/tree/main/proposals/esm-integration#evaluate
+
+        * runtime/AbstractModuleRecord.cpp:
+        (JSC::AbstractModuleRecord::link):
+        (JSC::AbstractModuleRecord::evaluate):
+        * wasm/js/JSWebAssemblyInstance.cpp:
+        (JSC::JSWebAssemblyInstance::finalizeCreation):
+        * wasm/js/WebAssemblyModuleRecord.cpp:
+        (JSC::WebAssemblyModuleRecord::link):
+        (JSC::WebAssemblyModuleRecord::initializeImportsAndExports):
+        (JSC::WebAssemblyModuleRecord::linkImpl): Deleted.
+        * wasm/js/WebAssemblyModuleRecord.h:
+
 2021-10-22  Mikhail R. Gadelha  <[email protected]>
 
         [JSC][32bit] Re-enable compileEnumeratorGetByVal fast path

Modified: trunk/Source/_javascript_Core/runtime/AbstractModuleRecord.cpp (284701 => 284702)


--- trunk/Source/_javascript_Core/runtime/AbstractModuleRecord.cpp	2021-10-22 18:35:08 UTC (rev 284701)
+++ trunk/Source/_javascript_Core/runtime/AbstractModuleRecord.cpp	2021-10-22 18:35:42 UTC (rev 284702)
@@ -822,8 +822,10 @@
     if (auto* jsModuleRecord = jsDynamicCast<JSModuleRecord*>(vm, this))
         return jsModuleRecord->link(globalObject, scriptFetcher);
 #if ENABLE(WEBASSEMBLY)
+    // WebAssembly module imports and exports are set up in the module record's
+    // evaluate() step. At this point, imports are just initialized as TDZ.
     if (auto* wasmModuleRecord = jsDynamicCast<WebAssemblyModuleRecord*>(vm, this))
-        return wasmModuleRecord->link(globalObject, scriptFetcher, nullptr, Wasm::CreationMode::FromModuleLoader);
+        return wasmModuleRecord->link(globalObject, scriptFetcher);
 #endif
     RELEASE_ASSERT_NOT_REACHED();
     return Synchronousness::Sync;
@@ -832,11 +834,19 @@
 JS_EXPORT_PRIVATE JSValue AbstractModuleRecord::evaluate(JSGlobalObject* globalObject, JSValue sentValue, JSValue resumeMode)
 {
     VM& vm = globalObject->vm();
+    auto scope = DECLARE_THROW_SCOPE(vm);
+
     if (auto* jsModuleRecord = jsDynamicCast<JSModuleRecord*>(vm, this))
-        return jsModuleRecord->evaluate(globalObject, sentValue, resumeMode);
+        RELEASE_AND_RETURN(scope, jsModuleRecord->evaluate(globalObject, sentValue, resumeMode));
 #if ENABLE(WEBASSEMBLY)
-    if (auto* wasmModuleRecord = jsDynamicCast<WebAssemblyModuleRecord*>(vm, this))
-        return wasmModuleRecord->evaluate(globalObject);
+    if (auto* wasmModuleRecord = jsDynamicCast<WebAssemblyModuleRecord*>(vm, this)) {
+        // WebAssembly imports need to be supplied during evaluation so that, e.g.,
+        // JS module exports are actually available to be read and installed as import
+        // bindings.
+        wasmModuleRecord->initializeImportsAndExports(globalObject, nullptr, Wasm::CreationMode::FromModuleLoader);
+        RETURN_IF_EXCEPTION(scope, jsUndefined());
+        RELEASE_AND_RETURN(scope, wasmModuleRecord->evaluate(globalObject));
+    }
 #endif
     RELEASE_ASSERT_NOT_REACHED();
     return jsUndefined();

Modified: trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyInstance.cpp (284701 => 284702)


--- trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyInstance.cpp	2021-10-22 18:35:08 UTC (rev 284701)
+++ trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyInstance.cpp	2021-10-22 18:35:42 UTC (rev 284702)
@@ -143,8 +143,10 @@
     m_moduleRecord->prepareLink(vm, this);
 
     if (creationMode == Wasm::CreationMode::FromJS) {
-        m_moduleRecord->link(globalObject, jsNull(), importObject, creationMode);
+        m_moduleRecord->link(globalObject, jsNull());
         RETURN_IF_EXCEPTION(scope, void());
+        m_moduleRecord->initializeImportsAndExports(globalObject, importObject, creationMode);
+        RETURN_IF_EXCEPTION(scope, void());
 
         JSValue startResult = m_moduleRecord->evaluate(globalObject);
         UNUSED_PARAM(startResult);

Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.cpp (284701 => 284702)


--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.cpp	2021-10-22 18:35:08 UTC (rev 284701)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.cpp	2021-10-22 18:35:42 UTC (rev 284702)
@@ -98,13 +98,22 @@
     m_instance.set(vm, this, instance);
 }
 
-Synchronousness WebAssemblyModuleRecord::link(JSGlobalObject* globalObject, JSValue, JSObject* importObject, Wasm::CreationMode creationMode)
+Synchronousness WebAssemblyModuleRecord::link(JSGlobalObject* globalObject, JSValue)
 {
-    linkImpl(globalObject, importObject, creationMode);
+    VM& vm = globalObject->vm();
+
+    RELEASE_ASSERT(m_instance);
+
+    JSWebAssemblyModule* module = m_instance->module();
+    SymbolTable* exportSymbolTable = module->exportSymbolTable();
+
+    JSModuleEnvironment* moduleEnvironment = JSModuleEnvironment::create(vm, globalObject, nullptr, exportSymbolTable, jsTDZValue(), this);
+    setModuleEnvironment(globalObject, moduleEnvironment);
+
     return Synchronousness::Sync;
 }
 
-void WebAssemblyModuleRecord::linkImpl(JSGlobalObject* globalObject, JSObject* importObject, Wasm::CreationMode creationMode)
+void WebAssemblyModuleRecord::initializeImportsAndExports(JSGlobalObject* globalObject, JSObject* importObject, Wasm::CreationMode creationMode)
 {
     VM& vm = globalObject->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
@@ -515,12 +524,10 @@
         }
     }
 
-    SymbolTable* exportSymbolTable = module->exportSymbolTable();
-
     // Let exports be a list of (string, JS value) pairs that is mapped from each external value e in instance.exports as follows:
     // https://webassembly.github.io/spec/js-api/index.html#create-an-exports-object
     JSObject* exportsObject = constructEmptyObject(vm, globalObject->nullPrototypeObjectStructure());
-    JSModuleEnvironment* moduleEnvironment = JSModuleEnvironment::create(vm, globalObject, nullptr, exportSymbolTable, JSValue(), this);
+    JSModuleEnvironment* moduleEnvironment = this->moduleEnvironment();
     for (const auto& exp : moduleInformation.exports) {
         JSValue exportedValue;
         switch (exp.kind) {
@@ -620,9 +627,6 @@
             m_startFunction.set(vm, this, function);
         }
     }
-
-    scope.release();
-    setModuleEnvironment(globalObject, moduleEnvironment);
 }
 
 template <typename Scope, typename M, typename N, typename ...Args>

Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.h (284701 => 284702)


--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.h	2021-10-22 18:35:08 UTC (rev 284701)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyModuleRecord.h	2021-10-22 18:35:42 UTC (rev 284702)
@@ -59,13 +59,13 @@
     static WebAssemblyModuleRecord* create(JSGlobalObject*, VM&, Structure*, const Identifier&, const Wasm::ModuleInformation&);
 
     void prepareLink(VM&, JSWebAssemblyInstance*);
-    Synchronousness link(JSGlobalObject*, JSValue scriptFetcher, JSObject* importObject, Wasm::CreationMode);
+    Synchronousness link(JSGlobalObject*, JSValue scriptFetcher);
+    void initializeImportsAndExports(JSGlobalObject*, JSObject* importObject, Wasm::CreationMode);
     JS_EXPORT_PRIVATE JSValue evaluate(JSGlobalObject*);
 
     JSObject* exportsObject() const { return m_exportsObject.get(); }
 
 private:
-    void linkImpl(JSGlobalObject*, JSObject* importObject, Wasm::CreationMode);
     WebAssemblyModuleRecord(VM&, Structure*, const Identifier&);
 
     void finishCreation(JSGlobalObject*, VM&, const Wasm::ModuleInformation&);
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to