From 4059df56ea53f1933ad3a9bed41f5256640ffa13 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Sun, 27 Oct 2024 11:00:20 +0100 Subject: [PATCH 01/10] Improved TS type generation from WASM --- crates/cli-support/src/wasm2es6js.rs | 141 ++++++++++++++------------- 1 file changed, 75 insertions(+), 66 deletions(-) diff --git a/crates/cli-support/src/wasm2es6js.rs b/crates/cli-support/src/wasm2es6js.rs index 36298fdd54e..c48a456454e 100644 --- a/crates/cli-support/src/wasm2es6js.rs +++ b/crates/cli-support/src/wasm2es6js.rs @@ -62,16 +62,38 @@ fn args_are_optional(name: &str) -> bool { pub fn interface(module: &Module) -> Result { let mut exports = String::new(); + module_export_types(module, |name, ty| { + exports.push_str(" readonly "); + exports.push_str(name); + exports.push_str(": "); + exports.push_str(ty); + exports.push_str(";\n"); + }); + Ok(exports) +} +pub fn typescript(module: &Module) -> Result { + let mut exports = "/* tslint:disable */\n/* eslint-disable */\n".to_string(); + module_export_types(module, |name, ty| { + exports.push_str("export const "); + exports.push_str(name); + exports.push_str(": "); + exports.push_str(ty); + exports.push_str(";\n"); + }); + Ok(exports) +} + +fn module_export_types(module: &Module, mut export: impl FnMut(&str, &str)) { for entry in module.exports.iter() { let id = match entry.item { walrus::ExportItem::Function(i) => i, walrus::ExportItem::Memory(_) => { - exports.push_str(&format!(" readonly {}: WebAssembly.Memory;\n", entry.name,)); + export(&entry.name, "WebAssembly.Memory"); continue; } walrus::ExportItem::Table(_) => { - exports.push_str(&format!(" readonly {}: WebAssembly.Table;\n", entry.name,)); + export(&entry.name, "WebAssembly.Table"); continue; } walrus::ExportItem::Global(_) => continue, @@ -79,80 +101,67 @@ pub fn interface(module: &Module) -> Result { let func = module.funcs.get(id); let ty = module.types.get(func.ty()); - let mut args = String::new(); - for (i, _) in ty.params().iter().enumerate() { - if i > 0 { - args.push_str(", "); - } + let ts_type = get_ts_function_type(ty, args_are_optional(&entry.name)); + export(&entry.name, &ts_type); + } +} +fn val_type_to_ts(ty: walrus::ValType) -> &'static str { + // see https://webassembly.github.io/spec/js-api/index.html#towebassemblyvalue + // and https://webassembly.github.io/spec/js-api/index.html#tojsvalue + match ty { + walrus::ValType::I32 | walrus::ValType::F32 | walrus::ValType::F64 => "number", + walrus::ValType::I64 => "bigint", + // there could be anything behind a reference + walrus::ValType::Ref(_) => "any", + // V128 currently isn't supported in JS and therefore doesn't have a + // specific type in the spec. When it does get support, this type will + // still be technically correct, but should be updated to something more + // specific. + walrus::ValType::V128 => "any", + } +} +fn get_ts_function_type(function: &walrus::Type, all_args_optional: bool) -> String { + let mut out = String::new(); - push_index_identifier(i, &mut args); - if args_are_optional(&entry.name) { - args.push('?'); - } - args.push_str(": number"); + // parameters + out.push('('); + for (i, arg_type) in function.params().iter().enumerate() { + if i > 0 { + out.push_str(", "); } - exports.push_str(&format!( - " readonly {name}: ({args}) => {ret};\n", - name = entry.name, - args = args, - ret = match ty.results().len() { - 0 => "void", - 1 => "number", - _ => "Array", - }, - )); + push_index_identifier(i, &mut out); + if all_args_optional { + out.push('?'); + } + out.push_str(": "); + out.push_str(val_type_to_ts(*arg_type)); } + out.push(')'); - Ok(exports) -} - -pub fn typescript(module: &Module) -> Result { - let mut exports = "/* tslint:disable */\n/* eslint-disable */\n".to_string(); - for entry in module.exports.iter() { - let id = match entry.item { - walrus::ExportItem::Function(i) => i, - walrus::ExportItem::Memory(_) => { - exports.push_str(&format!( - "export const {}: WebAssembly.Memory;\n", - entry.name, - )); - continue; - } - walrus::ExportItem::Table(_) => { - exports.push_str(&format!( - "export const {}: WebAssembly.Table;\n", - entry.name, - )); - continue; - } - walrus::ExportItem::Global(_) => continue, - }; + // arrow + out.push_str(" => "); - let func = module.funcs.get(id); - let ty = module.types.get(func.ty()); - let mut args = String::new(); - for (i, _) in ty.params().iter().enumerate() { - if i > 0 { - args.push_str(", "); + // results + let results = function.results(); + // this match follows the spec: + // https://webassembly.github.io/spec/js-api/index.html#exported-function-exotic-objects + match results.len() { + 0 => out.push_str("void"), + 1 => out.push_str(val_type_to_ts(results[0])), + _ => { + out.push('['); + for (i, result) in results.iter().enumerate() { + if i > 0 { + out.push_str(", "); + } + out.push_str(val_type_to_ts(*result)); } - push_index_identifier(i, &mut args); - args.push_str(": number"); + out.push(']'); } - - exports.push_str(&format!( - "export function {name}({args}): {ret};\n", - name = entry.name, - args = args, - ret = match ty.results().len() { - 0 => "void", - 1 => "number", - _ => "Array", - }, - )); } - Ok(exports) + out } impl Output { From 35c8f5890bc9ceab15156868343af2e2ab4a32cc Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Sun, 27 Oct 2024 11:51:57 +0100 Subject: [PATCH 02/10] Some code restructuring --- crates/cli-support/src/wasm2es6js.rs | 28 +++++++++------------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/crates/cli-support/src/wasm2es6js.rs b/crates/cli-support/src/wasm2es6js.rs index c48a456454e..0827519bf5d 100644 --- a/crates/cli-support/src/wasm2es6js.rs +++ b/crates/cli-support/src/wasm2es6js.rs @@ -63,11 +63,7 @@ fn args_are_optional(name: &str) -> bool { pub fn interface(module: &Module) -> Result { let mut exports = String::new(); module_export_types(module, |name, ty| { - exports.push_str(" readonly "); - exports.push_str(name); - exports.push_str(": "); - exports.push_str(ty); - exports.push_str(";\n"); + writeln!(exports, " readonly {}: {};", name, ty).unwrap(); }); Ok(exports) } @@ -75,34 +71,28 @@ pub fn interface(module: &Module) -> Result { pub fn typescript(module: &Module) -> Result { let mut exports = "/* tslint:disable */\n/* eslint-disable */\n".to_string(); module_export_types(module, |name, ty| { - exports.push_str("export const "); - exports.push_str(name); - exports.push_str(": "); - exports.push_str(ty); - exports.push_str(";\n"); + writeln!(exports, "export const {}: {};", name, ty).unwrap(); }); Ok(exports) } fn module_export_types(module: &Module, mut export: impl FnMut(&str, &str)) { for entry in module.exports.iter() { - let id = match entry.item { - walrus::ExportItem::Function(i) => i, + match entry.item { + walrus::ExportItem::Function(id) => { + let func = module.funcs.get(id); + let ty = module.types.get(func.ty()); + let ts_type = get_ts_function_type(ty, args_are_optional(&entry.name)); + export(&entry.name, &ts_type); + } walrus::ExportItem::Memory(_) => { export(&entry.name, "WebAssembly.Memory"); - continue; } walrus::ExportItem::Table(_) => { export(&entry.name, "WebAssembly.Table"); - continue; } walrus::ExportItem::Global(_) => continue, }; - - let func = module.funcs.get(id); - let ty = module.types.get(func.ty()); - let ts_type = get_ts_function_type(ty, args_are_optional(&entry.name)); - export(&entry.name, &ts_type); } } fn val_type_to_ts(ty: walrus::ValType) -> &'static str { From 60d5e17cff5ce84e3e8daf0ece13e06fbdee767b Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Mon, 28 Oct 2024 19:11:05 +0100 Subject: [PATCH 03/10] Minor improvements --- crates/cli-support/src/wasm2es6js.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/crates/cli-support/src/wasm2es6js.rs b/crates/cli-support/src/wasm2es6js.rs index 0827519bf5d..75dea5d0a83 100644 --- a/crates/cli-support/src/wasm2es6js.rs +++ b/crates/cli-support/src/wasm2es6js.rs @@ -76,13 +76,15 @@ pub fn typescript(module: &Module) -> Result { Ok(exports) } +/// Iterates over all the exports in a module and generates TypeScript types. All +/// name-type pairs are passed to the `export` function. fn module_export_types(module: &Module, mut export: impl FnMut(&str, &str)) { for entry in module.exports.iter() { match entry.item { walrus::ExportItem::Function(id) => { let func = module.funcs.get(id); let ty = module.types.get(func.ty()); - let ts_type = get_ts_function_type(ty, args_are_optional(&entry.name)); + let ts_type = function_type_to_ts(ty, args_are_optional(&entry.name)); export(&entry.name, &ts_type); } walrus::ExportItem::Memory(_) => { @@ -110,7 +112,7 @@ fn val_type_to_ts(ty: walrus::ValType) -> &'static str { walrus::ValType::V128 => "any", } } -fn get_ts_function_type(function: &walrus::Type, all_args_optional: bool) -> String { +fn function_type_to_ts(function: &walrus::Type, all_args_optional: bool) -> String { let mut out = String::new(); // parameters From 3f649b0b84d15a81a5bef391aee7f1cb5d931fa5 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Tue, 29 Oct 2024 00:15:17 +0100 Subject: [PATCH 04/10] golf --- crates/cli-support/src/wasm2es6js.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/crates/cli-support/src/wasm2es6js.rs b/crates/cli-support/src/wasm2es6js.rs index 75dea5d0a83..c16eb0a4504 100644 --- a/crates/cli-support/src/wasm2es6js.rs +++ b/crates/cli-support/src/wasm2es6js.rs @@ -87,12 +87,8 @@ fn module_export_types(module: &Module, mut export: impl FnMut(&str, &str)) { let ts_type = function_type_to_ts(ty, args_are_optional(&entry.name)); export(&entry.name, &ts_type); } - walrus::ExportItem::Memory(_) => { - export(&entry.name, "WebAssembly.Memory"); - } - walrus::ExportItem::Table(_) => { - export(&entry.name, "WebAssembly.Table"); - } + walrus::ExportItem::Memory(_) => export(&entry.name, "WebAssembly.Memory"), + walrus::ExportItem::Table(_) => export(&entry.name, "WebAssembly.Table"), walrus::ExportItem::Global(_) => continue, }; } From bf7becc55b228de737403ca4f8f37730c64e56a5 Mon Sep 17 00:00:00 2001 From: Michael Schmidt Date: Sat, 2 Nov 2024 19:27:41 +0100 Subject: [PATCH 05/10] Trigger CI From af0950b604497437ab98e46a418657f6fdc171c7 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Wed, 13 Nov 2024 01:30:22 +0100 Subject: [PATCH 06/10] Add type-only testing --- crates/cli/tests/reference.rs | 13 ++++++++++++- crates/cli/tests/reference/async-number.rs | 2 ++ crates/cli/tests/reference/async-void.rs | 2 ++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/crates/cli/tests/reference.rs b/crates/cli/tests/reference.rs index 190df67b541..55697231071 100644 --- a/crates/cli/tests/reference.rs +++ b/crates/cli/tests/reference.rs @@ -52,6 +52,15 @@ //! // FLAGS: --target=web //! // FLAGS: --target=nodejs //! ``` +//! +//! ## Testing only types +//! +//! In some cases, we are only interested in testing the generated `.d.ts` file. +//! In this case, add a comment at the top of the test file: +//! +//! ```rust +//! // TYPES ONLY +//! ``` use anyhow::{bail, Result}; use assert_cmd::prelude::*; @@ -119,6 +128,8 @@ fn runtest(test: &Path) -> Result<()> { let root = repo_root(); let root = root.display(); + let types_only = contents.contains("// TYPES ONLY"); + // parse target declarations let mut all_flags: Vec<_> = contents .lines() @@ -215,7 +226,7 @@ fn runtest(test: &Path) -> Result<()> { _ => "reference_test.js", }; - if !contents.contains("async") { + if !types_only { let js = fs::read_to_string(out_dir.join(main_js_file))?; assert_same(&js, &test.with_extension("js"))?; let wat = sanitize_wasm(&out_dir.join("reference_test_bg.wasm"))?; diff --git a/crates/cli/tests/reference/async-number.rs b/crates/cli/tests/reference/async-number.rs index 2948c43667d..4654452b707 100644 --- a/crates/cli/tests/reference/async-number.rs +++ b/crates/cli/tests/reference/async-number.rs @@ -1,3 +1,5 @@ +// TYPES ONLY + use wasm_bindgen::prelude::*; #[wasm_bindgen] diff --git a/crates/cli/tests/reference/async-void.rs b/crates/cli/tests/reference/async-void.rs index 73f4a0ff586..60bfa1d1a59 100644 --- a/crates/cli/tests/reference/async-void.rs +++ b/crates/cli/tests/reference/async-void.rs @@ -1,3 +1,5 @@ +// TYPES ONLY + use wasm_bindgen::prelude::*; #[wasm_bindgen] From bbb0ec386b4948f6724f88efe268d278372ad37a Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Wed, 13 Nov 2024 01:30:51 +0100 Subject: [PATCH 07/10] Test wasm export types --- .../tests/reference/wasm-export-types.d.ts | 36 +++++++++++++++++++ .../cli/tests/reference/wasm-export-types.rs | 13 +++++++ 2 files changed, 49 insertions(+) create mode 100644 crates/cli/tests/reference/wasm-export-types.d.ts create mode 100644 crates/cli/tests/reference/wasm-export-types.rs diff --git a/crates/cli/tests/reference/wasm-export-types.d.ts b/crates/cli/tests/reference/wasm-export-types.d.ts new file mode 100644 index 00000000000..eb562cd6fb0 --- /dev/null +++ b/crates/cli/tests/reference/wasm-export-types.d.ts @@ -0,0 +1,36 @@ +/* tslint:disable */ +/* eslint-disable */ +export function example(a: number, b: bigint, c: any, d: string): string; + +export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module; + +export interface InitOutput { + readonly memory: WebAssembly.Memory; + readonly example: (a: number, b: bigint, c: any, d: number, e: number) => [number, number]; + readonly __wbindgen_export_0: WebAssembly.Table; + readonly __wbindgen_malloc: (a: number, b: number) => number; + readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number; + readonly __wbindgen_free: (a: number, b: number, c: number) => void; + readonly __wbindgen_start: () => void; +} + +export type SyncInitInput = BufferSource | WebAssembly.Module; +/** +* Instantiates the given `module`, which can either be bytes or +* a precompiled `WebAssembly.Module`. +* +* @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated. +* +* @returns {InitOutput} +*/ +export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput; + +/** +* If `module_or_path` is {RequestInfo} or {URL}, makes a request and +* for everything else, calls `WebAssembly.instantiate` directly. +* +* @param {{ module_or_path: InitInput | Promise }} module_or_path - Passing `InitInput` directly is deprecated. +* +* @returns {Promise} +*/ +export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise } | InitInput | Promise): Promise; diff --git a/crates/cli/tests/reference/wasm-export-types.rs b/crates/cli/tests/reference/wasm-export-types.rs new file mode 100644 index 00000000000..12382c8b413 --- /dev/null +++ b/crates/cli/tests/reference/wasm-export-types.rs @@ -0,0 +1,13 @@ +// FLAGS: --target=web +// TYPES ONLY + +use wasm_bindgen::prelude::*; + +// This is for testing the type generation of the wasm-exported functions. +// Here, example should be exported as `(arg0: number, arg1: bigint, arg2: any, arg3: number, arg4: number) => [number, number]`. +// Notes: `arg2: any` is an external reference to a JS value, and the ABI of strings is `number, number` (pointer, length). + +#[wasm_bindgen] +pub fn example(a: u32, b: u64, c: JsValue, d: &str) -> String { + todo!() +} From 305b3946b6d32e1bd8473865a900ccfb363561c2 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Wed, 13 Nov 2024 01:36:05 +0100 Subject: [PATCH 08/10] Revert "Add type-only testing" This reverts commit af0950b604497437ab98e46a418657f6fdc171c7. --- crates/cli/tests/reference.rs | 13 +------------ crates/cli/tests/reference/async-number.rs | 2 -- crates/cli/tests/reference/async-void.rs | 2 -- 3 files changed, 1 insertion(+), 16 deletions(-) diff --git a/crates/cli/tests/reference.rs b/crates/cli/tests/reference.rs index 55697231071..190df67b541 100644 --- a/crates/cli/tests/reference.rs +++ b/crates/cli/tests/reference.rs @@ -52,15 +52,6 @@ //! // FLAGS: --target=web //! // FLAGS: --target=nodejs //! ``` -//! -//! ## Testing only types -//! -//! In some cases, we are only interested in testing the generated `.d.ts` file. -//! In this case, add a comment at the top of the test file: -//! -//! ```rust -//! // TYPES ONLY -//! ``` use anyhow::{bail, Result}; use assert_cmd::prelude::*; @@ -128,8 +119,6 @@ fn runtest(test: &Path) -> Result<()> { let root = repo_root(); let root = root.display(); - let types_only = contents.contains("// TYPES ONLY"); - // parse target declarations let mut all_flags: Vec<_> = contents .lines() @@ -226,7 +215,7 @@ fn runtest(test: &Path) -> Result<()> { _ => "reference_test.js", }; - if !types_only { + if !contents.contains("async") { let js = fs::read_to_string(out_dir.join(main_js_file))?; assert_same(&js, &test.with_extension("js"))?; let wat = sanitize_wasm(&out_dir.join("reference_test_bg.wasm"))?; diff --git a/crates/cli/tests/reference/async-number.rs b/crates/cli/tests/reference/async-number.rs index 4654452b707..2948c43667d 100644 --- a/crates/cli/tests/reference/async-number.rs +++ b/crates/cli/tests/reference/async-number.rs @@ -1,5 +1,3 @@ -// TYPES ONLY - use wasm_bindgen::prelude::*; #[wasm_bindgen] diff --git a/crates/cli/tests/reference/async-void.rs b/crates/cli/tests/reference/async-void.rs index 60bfa1d1a59..73f4a0ff586 100644 --- a/crates/cli/tests/reference/async-void.rs +++ b/crates/cli/tests/reference/async-void.rs @@ -1,5 +1,3 @@ -// TYPES ONLY - use wasm_bindgen::prelude::*; #[wasm_bindgen] From 09f8f4d6fd86bb288f9aca3947642eec22352561 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Wed, 13 Nov 2024 01:37:23 +0100 Subject: [PATCH 09/10] Updated test --- .../cli/tests/reference/wasm-export-types.js | 217 ++++++++++++++++++ .../cli/tests/reference/wasm-export-types.rs | 1 - .../cli/tests/reference/wasm-export-types.wat | 23 ++ 3 files changed, 240 insertions(+), 1 deletion(-) create mode 100644 crates/cli/tests/reference/wasm-export-types.js create mode 100644 crates/cli/tests/reference/wasm-export-types.wat diff --git a/crates/cli/tests/reference/wasm-export-types.js b/crates/cli/tests/reference/wasm-export-types.js new file mode 100644 index 00000000000..fc6b51ee861 --- /dev/null +++ b/crates/cli/tests/reference/wasm-export-types.js @@ -0,0 +1,217 @@ +let wasm; + +const cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } ); + +if (typeof TextDecoder !== 'undefined') { cachedTextDecoder.decode(); }; + +let cachedUint8ArrayMemory0 = null; + +function getUint8ArrayMemory0() { + if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) { + cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer); + } + return cachedUint8ArrayMemory0; +} + +function getStringFromWasm0(ptr, len) { + ptr = ptr >>> 0; + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + +let WASM_VECTOR_LEN = 0; + +const cachedTextEncoder = (typeof TextEncoder !== 'undefined' ? new TextEncoder('utf-8') : { encode: () => { throw Error('TextEncoder not available') } } ); + +const encodeString = (typeof cachedTextEncoder.encodeInto === 'function' + ? function (arg, view) { + return cachedTextEncoder.encodeInto(arg, view); +} + : function (arg, view) { + const buf = cachedTextEncoder.encode(arg); + view.set(buf); + return { + read: arg.length, + written: buf.length + }; +}); + +function passStringToWasm0(arg, malloc, realloc) { + + if (realloc === undefined) { + const buf = cachedTextEncoder.encode(arg); + const ptr = malloc(buf.length, 1) >>> 0; + getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf); + WASM_VECTOR_LEN = buf.length; + return ptr; + } + + let len = arg.length; + let ptr = malloc(len, 1) >>> 0; + + const mem = getUint8ArrayMemory0(); + + let offset = 0; + + for (; offset < len; offset++) { + const code = arg.charCodeAt(offset); + if (code > 0x7F) break; + mem[ptr + offset] = code; + } + + if (offset !== len) { + if (offset !== 0) { + arg = arg.slice(offset); + } + ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0; + const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len); + const ret = encodeString(arg, view); + + offset += ret.written; + ptr = realloc(ptr, len, offset, 1) >>> 0; + } + + WASM_VECTOR_LEN = offset; + return ptr; +} +/** + * @param {number} a + * @param {bigint} b + * @param {any} c + * @param {string} d + * @returns {string} + */ +export function example(a, b, c, d) { + let deferred2_0; + let deferred2_1; + try { + const ptr0 = passStringToWasm0(d, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.example(a, b, c, ptr0, len0); + deferred2_0 = ret[0]; + deferred2_1 = ret[1]; + return getStringFromWasm0(ret[0], ret[1]); + } finally { + wasm.__wbindgen_free(deferred2_0, deferred2_1, 1); + } +} + +async function __wbg_load(module, imports) { + if (typeof Response === 'function' && module instanceof Response) { + if (typeof WebAssembly.instantiateStreaming === 'function') { + try { + return await WebAssembly.instantiateStreaming(module, imports); + + } catch (e) { + if (module.headers.get('Content-Type') != 'application/wasm') { + console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e); + + } else { + throw e; + } + } + } + + const bytes = await module.arrayBuffer(); + return await WebAssembly.instantiate(bytes, imports); + + } else { + const instance = await WebAssembly.instantiate(module, imports); + + if (instance instanceof WebAssembly.Instance) { + return { instance, module }; + + } else { + return instance; + } + } +} + +function __wbg_get_imports() { + const imports = {}; + imports.wbg = {}; + imports.wbg.__wbindgen_init_externref_table = function() { + const table = wasm.__wbindgen_export_0; + const offset = table.grow(4); + table.set(0, undefined); + table.set(offset + 0, undefined); + table.set(offset + 1, null); + table.set(offset + 2, true); + table.set(offset + 3, false); + ; + }; + imports.wbg.__wbindgen_throw = function(arg0, arg1) { + throw new Error(getStringFromWasm0(arg0, arg1)); + }; + + return imports; +} + +function __wbg_init_memory(imports, memory) { + +} + +function __wbg_finalize_init(instance, module) { + wasm = instance.exports; + __wbg_init.__wbindgen_wasm_module = module; + cachedUint8ArrayMemory0 = null; + + + wasm.__wbindgen_start(); + return wasm; +} + +function initSync(module) { + if (wasm !== undefined) return wasm; + + + if (typeof module !== 'undefined') { + if (Object.getPrototypeOf(module) === Object.prototype) { + ({module} = module) + } else { + console.warn('using deprecated parameters for `initSync()`; pass a single object instead') + } + } + + const imports = __wbg_get_imports(); + + __wbg_init_memory(imports); + + if (!(module instanceof WebAssembly.Module)) { + module = new WebAssembly.Module(module); + } + + const instance = new WebAssembly.Instance(module, imports); + + return __wbg_finalize_init(instance, module); +} + +async function __wbg_init(module_or_path) { + if (wasm !== undefined) return wasm; + + + if (typeof module_or_path !== 'undefined') { + if (Object.getPrototypeOf(module_or_path) === Object.prototype) { + ({module_or_path} = module_or_path) + } else { + console.warn('using deprecated parameters for the initialization function; pass a single object instead') + } + } + + if (typeof module_or_path === 'undefined') { + module_or_path = new URL('reference_test_bg.wasm', import.meta.url); + } + const imports = __wbg_get_imports(); + + if (typeof module_or_path === 'string' || (typeof Request === 'function' && module_or_path instanceof Request) || (typeof URL === 'function' && module_or_path instanceof URL)) { + module_or_path = fetch(module_or_path); + } + + __wbg_init_memory(imports); + + const { instance, module } = await __wbg_load(await module_or_path, imports); + + return __wbg_finalize_init(instance, module); +} + +export { initSync }; +export default __wbg_init; diff --git a/crates/cli/tests/reference/wasm-export-types.rs b/crates/cli/tests/reference/wasm-export-types.rs index 12382c8b413..2911442e640 100644 --- a/crates/cli/tests/reference/wasm-export-types.rs +++ b/crates/cli/tests/reference/wasm-export-types.rs @@ -1,5 +1,4 @@ // FLAGS: --target=web -// TYPES ONLY use wasm_bindgen::prelude::*; diff --git a/crates/cli/tests/reference/wasm-export-types.wat b/crates/cli/tests/reference/wasm-export-types.wat new file mode 100644 index 00000000000..dcb407e93b8 --- /dev/null +++ b/crates/cli/tests/reference/wasm-export-types.wat @@ -0,0 +1,23 @@ +(module $reference_test.wasm + (type (;0;) (func)) + (type (;1;) (func (param i32 i32) (result i32))) + (type (;2;) (func (param i32 i32 i32))) + (type (;3;) (func (param i32 i32 i32 i32) (result i32))) + (type (;4;) (func (param i32 i64 externref i32 i32) (result i32 i32))) + (import "wbg" "__wbindgen_init_externref_table" (func (;0;) (type 0))) + (func $__wbindgen_realloc (;1;) (type 3) (param i32 i32 i32 i32) (result i32)) + (func $__wbindgen_malloc (;2;) (type 1) (param i32 i32) (result i32)) + (func $__wbindgen_free (;3;) (type 2) (param i32 i32 i32)) + (func $"example externref shim multivalue shim" (;4;) (type 4) (param i32 i64 externref i32 i32) (result i32 i32)) + (table (;0;) 128 externref) + (memory (;0;) 17) + (export "memory" (memory 0)) + (export "example" (func $"example externref shim multivalue shim")) + (export "__wbindgen_export_0" (table 0)) + (export "__wbindgen_malloc" (func $__wbindgen_malloc)) + (export "__wbindgen_realloc" (func $__wbindgen_realloc)) + (export "__wbindgen_free" (func $__wbindgen_free)) + (export "__wbindgen_start" (func 0)) + (@custom "target_features" (after code) "\04+\0amultivalue+\0fmutable-globals+\0freference-types+\08sign-ext") +) + From 0da750e08cf41a9e249ea06c589ecf0f79bba34d Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Wed, 13 Nov 2024 12:31:29 +0100 Subject: [PATCH 10/10] Add u128 test --- crates/cli/tests/reference/wasm-export-types.d.ts | 2 ++ crates/cli/tests/reference/wasm-export-types.js | 9 +++++++++ crates/cli/tests/reference/wasm-export-types.rs | 5 +++++ crates/cli/tests/reference/wasm-export-types.wat | 3 +++ 4 files changed, 19 insertions(+) diff --git a/crates/cli/tests/reference/wasm-export-types.d.ts b/crates/cli/tests/reference/wasm-export-types.d.ts index eb562cd6fb0..a5f399db59d 100644 --- a/crates/cli/tests/reference/wasm-export-types.d.ts +++ b/crates/cli/tests/reference/wasm-export-types.d.ts @@ -1,12 +1,14 @@ /* tslint:disable */ /* eslint-disable */ export function example(a: number, b: bigint, c: any, d: string): string; +export function example_128(a: bigint): bigint | undefined; export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module; export interface InitOutput { readonly memory: WebAssembly.Memory; readonly example: (a: number, b: bigint, c: any, d: number, e: number) => [number, number]; + readonly example_128: (a: bigint, b: bigint) => [number, bigint, bigint]; readonly __wbindgen_export_0: WebAssembly.Table; readonly __wbindgen_malloc: (a: number, b: number) => number; readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number; diff --git a/crates/cli/tests/reference/wasm-export-types.js b/crates/cli/tests/reference/wasm-export-types.js index fc6b51ee861..de290e90502 100644 --- a/crates/cli/tests/reference/wasm-export-types.js +++ b/crates/cli/tests/reference/wasm-export-types.js @@ -95,6 +95,15 @@ export function example(a, b, c, d) { } } +/** + * @param {bigint} a + * @returns {bigint | undefined} + */ +export function example_128(a) { + const ret = wasm.example_128(a, a >> BigInt(64)); + return ret[0] === 0 ? undefined : (BigInt.asUintN(64, ret[1]) | (BigInt.asUintN(64, ret[2]) << BigInt(64))); +} + async function __wbg_load(module, imports) { if (typeof Response === 'function' && module instanceof Response) { if (typeof WebAssembly.instantiateStreaming === 'function') { diff --git a/crates/cli/tests/reference/wasm-export-types.rs b/crates/cli/tests/reference/wasm-export-types.rs index 2911442e640..06f89d912e0 100644 --- a/crates/cli/tests/reference/wasm-export-types.rs +++ b/crates/cli/tests/reference/wasm-export-types.rs @@ -10,3 +10,8 @@ use wasm_bindgen::prelude::*; pub fn example(a: u32, b: u64, c: JsValue, d: &str) -> String { todo!() } + +#[wasm_bindgen] +pub fn example_128(a: u128) -> Option { + None +} diff --git a/crates/cli/tests/reference/wasm-export-types.wat b/crates/cli/tests/reference/wasm-export-types.wat index dcb407e93b8..195c25a5723 100644 --- a/crates/cli/tests/reference/wasm-export-types.wat +++ b/crates/cli/tests/reference/wasm-export-types.wat @@ -4,15 +4,18 @@ (type (;2;) (func (param i32 i32 i32))) (type (;3;) (func (param i32 i32 i32 i32) (result i32))) (type (;4;) (func (param i32 i64 externref i32 i32) (result i32 i32))) + (type (;5;) (func (param i64 i64) (result i32 i64 i64))) (import "wbg" "__wbindgen_init_externref_table" (func (;0;) (type 0))) (func $__wbindgen_realloc (;1;) (type 3) (param i32 i32 i32 i32) (result i32)) (func $__wbindgen_malloc (;2;) (type 1) (param i32 i32) (result i32)) (func $__wbindgen_free (;3;) (type 2) (param i32 i32 i32)) (func $"example externref shim multivalue shim" (;4;) (type 4) (param i32 i64 externref i32 i32) (result i32 i32)) + (func $"example_128 multivalue shim" (;5;) (type 5) (param i64 i64) (result i32 i64 i64)) (table (;0;) 128 externref) (memory (;0;) 17) (export "memory" (memory 0)) (export "example" (func $"example externref shim multivalue shim")) + (export "example_128" (func $"example_128 multivalue shim")) (export "__wbindgen_export_0" (table 0)) (export "__wbindgen_malloc" (func $__wbindgen_malloc)) (export "__wbindgen_realloc" (func $__wbindgen_realloc))