-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[JSC] Supports Type Reflection for
WebAssembly.Module.imports
and `…
…WebAssembly.Module.exports` https://bugs.webkit.org/show_bug.cgi?id=277608 Reviewed by Yusuke Suzuki. The current JSC implements part of the WebAssembly Type Reflection proposal[1]. It allows to get type informations through methods like `WebAssembly.Memory.prototype.type()` and `WebAssembly.Table.prototype.type()`. The Type Reflection API should also add a new `type` field to the elements of the arrays returned by `WebAssembly.Module.imports` and `WebAssembly.Module.exports`[2]. However, this feature is not currently implemented in JSC. This feature has been implemented to V8[3] and SpiderMonkey[4]. This patch implements Type Reflection for `WebAssembly.Module.imports` and `WebAssembly.Module.exports`. [1]: https://github.com/WebAssembly/js-types [2]: https://webassembly.github.io/js-types/js-api/#modules [3]: https://chromium-review.googlesource.com/c/v8/v8/+/1763527 [4]: https://hg.mozilla.org/mozilla-central/rev/91e0c6d26de8ba365ec3d462f98d28c75055a89b * JSTests/wasm/js-api/Module.exports.js: (assert.truthy): * JSTests/wasm/js-api/Module.imports.js: (assert.truthy): * JSTests/wasm/js-api/type-reflection-concrete-types.js: Added. (import.as.assert.from.string_appeared_here.assert.throws): (WebAssembly.Module.exports): (assert.throws): * JSTests/wasm/js-api/type-reflection-exports.js: Added. (import.as.assert.from.string_appeared_here.sameValue): (async test): * JSTests/wasm/js-api/type-reflection-imports.js: Added. (import.as.assert.from.string_appeared_here.sameValue): * Source/JavaScriptCore/wasm/WasmModuleInformation.h: (JSC::Wasm::ModuleInformation::global const): * Source/JavaScriptCore/wasm/js/WebAssemblyModuleConstructor.cpp: (JSC::createTypeReflectionObject): (JSC::JSC_DEFINE_HOST_FUNCTION): Canonical link: https://commits.webkit.org/281974@main
- Loading branch information
1 parent
1e5569c
commit 6880a8b
Showing
7 changed files
with
333 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// @requireOptions("--useWasmTypedFunctionReferences=true") | ||
|
||
import * as assert from "../assert.js" | ||
|
||
// https://github.com/WebAssembly/function-references/blob/main/proposals/function-references/Overview.md#type-reflection | ||
|
||
{ | ||
// (module | ||
// (table (export "t") 10 (ref func) (ref.func 0)) | ||
// (func) | ||
// ) | ||
const bytes = new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,4,10,1,64,0,100,112,0,10,210,0,11,7,5,1,1,116,1,0,10,4,1,2,0,11]); | ||
const module = new WebAssembly.Module(bytes); | ||
assert.throws(function () { | ||
WebAssembly.Module.exports(module); | ||
}, TypeError, "WebAssembly.Module.exports unable to produce export descriptors for the given module"); | ||
} | ||
|
||
{ | ||
// (module | ||
// (global (export "g") (ref func) (ref.func 0)) | ||
// (func) | ||
// ) | ||
const bytes = new Uint8Array([0,97,115,109,1,0,0,0,1,4,1,96,0,0,3,2,1,0,6,7,1,100,112,0,210,0,11,7,5,1,1,103,3,0,10,4,1,2,0,11]); | ||
const module = new WebAssembly.Module(bytes); | ||
assert.throws(function () { | ||
WebAssembly.Module.exports(module); | ||
}, TypeError, "WebAssembly.Module.exports unable to produce export descriptors for the given module"); | ||
} | ||
|
||
{ | ||
// (module | ||
// (func (export "f") (param (ref func))) | ||
// (func) | ||
// ) | ||
const bytes = new Uint8Array([0,97,115,109,1,0,0,0,1,9,2,96,1,100,112,0,96,0,0,3,3,2,0,1,7,5,1,1,102,0,0,10,7,2,2,0,11,2,0,11]); | ||
const module = new WebAssembly.Module(bytes); | ||
assert.throws(function () { | ||
WebAssembly.Module.exports(module); | ||
}, TypeError, "WebAssembly.Module.exports unable to produce export descriptors for the given module"); | ||
} | ||
|
||
{ | ||
// (module | ||
// (import "m" "g" (global (ref func))) | ||
// ) | ||
const bytes = new Uint8Array([0,97,115,109,1,0,0,0,2,9,1,1,109,1,103,3,100,112,0]); | ||
const module = new WebAssembly.Module(bytes); | ||
assert.throws(function () { | ||
WebAssembly.Module.imports(module); | ||
}, TypeError, "WebAssembly.Module.imports unable to produce import descriptors for the given module"); | ||
} | ||
|
||
{ | ||
// (module | ||
// (import "m" "g" (func (param (ref func)))) | ||
// ) | ||
const bytes = new Uint8Array([0,97,115,109,1,0,0,0,1,6,1,96,1,100,112,0,2,7,1,1,109,1,103,0,0]); | ||
const module = new WebAssembly.Module(bytes); | ||
assert.throws(function () { | ||
WebAssembly.Module.imports(module); | ||
}, TypeError, "WebAssembly.Module.imports unable to produce import descriptors for the given module"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import { compile } from "../wabt-wrapper.js"; | ||
import * as assert from "../assert.js" | ||
|
||
function sameValue(a, b) { | ||
if (JSON.stringify(a) !== JSON.stringify(b)) | ||
throw new Error(`Expected ${JSON.stringify(b)} but got ${JSON.stringify(a)}`); | ||
} | ||
|
||
const wat = ` | ||
(module | ||
(func $log1 (export "fn1") (param i64) (param i32) (result i32) | ||
(i32.const 0)) | ||
(func $log2 (export "fn2") (param i32) | ||
(drop (local.get 0))) | ||
(func $log3 (export "fn3") (param i32) (param i64) (result i64) | ||
(local.get 1)) | ||
(func $log4 (export "fn4") (param f32) (param f64) (result f64) | ||
(local.get 1)) | ||
(func $log5 (export "fn5") (param i32) (param i32) (param i32) (result i32) | ||
(local.get 0)) | ||
(func $log6 (export "fn6") (param f32) (param f32) (result f32) | ||
(local.get 0)) | ||
(func $log7 (export "fn7") (param i32) (result i32) | ||
(local.get 0)) | ||
(func $log8 (export "fn8") (param f64) (result f64) | ||
(local.get 0)) | ||
(memory (export "memory") 1 8) | ||
(table (export "table_funcref") 1 2 funcref) | ||
(table (export "table_externref") 1 2 externref) | ||
(global $global_i32_mut (export "global_i32_mut") (mut i32) (i32.const 0)) | ||
(global $global_i32_imut (export "global_i32_imut") i32 (i32.const 0)) | ||
(global $global_f32_mut (export "global_f32_mut") (mut f32) (f32.const 0.0)) | ||
(global $global_f64_imut (export "global_f64_imut") f64 (f64.const 0.0)) | ||
(global $global_i64_mut (export "global_i64_mut") (mut i64) (i64.const 0)) | ||
(global $global_i64_imut (export "global_i64_imut") i64 (i64.const 0)) | ||
(global $global_f64_mut (export "global_f64_mut") (mut f64) (f64.const 0.0)) | ||
(global $global_f32_imut (export "global_f32_imut") f32 (f32.const 0.0)) | ||
) | ||
`; | ||
|
||
async function test() { | ||
const module = await compile(wat); | ||
const expected = [ | ||
{ parameters: ["i64", "i32"], results: ["i32"] }, | ||
{ parameters: ["i32"], results: [] }, | ||
{ parameters: ["i32", "i64"], results: ["i64"] }, | ||
{ parameters: ["f32", "f64"], results: ["f64"] }, | ||
{ parameters: ["i32", "i32", "i32"], results: ["i32"] }, | ||
{ parameters: ["f32", "f32"], results: ["f32"] }, | ||
{ parameters: ["i32"], results: ["i32"] }, | ||
{ parameters: ["f64"], results: ["f64"] }, | ||
{ maximum: 8, minimum: 1, shared: false }, | ||
{ maximum: 2, minimum: 1, element: "funcref" }, | ||
{ maximum: 2, minimum: 1, element: "externref" }, | ||
{ mutable: true, value: "i32" }, | ||
{ mutable: false, value: "i32" }, | ||
{ mutable: true, value: "f32" }, | ||
{ mutable: false, value: "f64" }, | ||
{ mutable: true, value: "i64" }, | ||
{ mutable: false, value: "i64" }, | ||
{ mutable: true, value: "f64" }, | ||
{ mutable: false, value: "f32" } | ||
]; | ||
const result = WebAssembly.Module.exports(module).map(({ type }) => type); | ||
for (let i = 0; i < expected.length; ++i) { | ||
sameValue(result[i], expected[i]); | ||
} | ||
} | ||
|
||
await assert.asyncTest(test()); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import { compile } from "../wabt-wrapper.js"; | ||
import * as assert from "../assert.js" | ||
|
||
function sameValue(a, b) { | ||
if (JSON.stringify(a) !== JSON.stringify(b)) | ||
throw new Error(`Expected ${JSON.stringify(b)} but got ${JSON.stringify(a)}`); | ||
} | ||
|
||
const wat = ` | ||
(module | ||
(import "mod" "fn1" (func $log1 (param i64) (param i32) (result i32))) | ||
(import "mod" "fn2" (func $log2 (param i32))) | ||
(import "mod" "fn3" (func $log3 (param i32) (param i64) (result i64))) | ||
(import "mod" "fn4" (func $log4 (param f32) (param f64) (result f64))) | ||
(import "mod" "fn5" (func $log5 (param i32) (param i32) (param i32) (result i32))) | ||
(import "mod" "fn6" (func $log6 (param f32) (param f32) (result f32))) | ||
(import "mod" "fn7" (func $log7 (param i32) (result i32))) | ||
(import "mod" "fn8" (func $log8 (param f64) (result f64))) | ||
(import "mod" "memory" (memory 1 8)) | ||
(import "mod" "table_funcref" (table 1 2 funcref)) | ||
(import "mod" "table_externref" (table 1 2 externref)) | ||
(import "mod" "global_i32_mut" (global $global_i32_mut (mut i32))) | ||
(import "mod" "global_i32_imut" (global $global_i32_imut i32)) | ||
(import "mod" "global_f32_mut" (global $global_f32_mut (mut f32))) | ||
(import "mod" "global_f64_imut" (global $global_f64_imut f64)) | ||
(import "mod" "global_i64_mut" (global $global_i64_mut (mut i64))) | ||
(import "mod" "global_i64_imut" (global $global_i64_imut i64)) | ||
(import "mod" "global_f64_mut" (global $global_f64_mut (mut f64))) | ||
(import "mod" "global_f32_imut" (global $global_f32_imut f32)) | ||
) | ||
` | ||
async function test() { | ||
const module = await compile(wat); | ||
const expected = [ | ||
{ parameters: ["i64", "i32"], results: ["i32"] }, | ||
{ parameters: ["i32"], results: [] }, | ||
{ parameters: ["i32", "i64"], results: ["i64"] }, | ||
{ parameters: ["f32", "f64"], results: ["f64"] }, | ||
{ parameters: ["i32", "i32", "i32"], results: ["i32"] }, | ||
{ parameters: ["f32", "f32"], results: ["f32"] }, | ||
{ parameters: ["i32"], results: ["i32"] }, | ||
{ parameters: ["f64"], results: ["f64"] }, | ||
{ maximum: 8, minimum: 1, shared: false }, | ||
{ maximum: 2, minimum: 1, element: "funcref" }, | ||
{ maximum: 2, minimum: 1, element: "externref" }, | ||
{ mutable: true, value: "i32" }, | ||
{ mutable: false, value: "i32" }, | ||
{ mutable: true, value: "f32" }, | ||
{ mutable: false, value: "f64" }, | ||
{ mutable: true, value: "i64" }, | ||
{ mutable: false, value: "i64" }, | ||
{ mutable: true, value: "f64" }, | ||
{ mutable: false, value: "f32" } | ||
]; | ||
const result = WebAssembly.Module.imports(module).map(({ type }) => type); | ||
for (let i = 0; i < expected.length; ++i) { | ||
sameValue(result[i], expected[i]); | ||
} | ||
} | ||
|
||
await assert.asyncTest(test()); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.