From c1d8bc653a55c898098f3b67f8e4fa3d61955da5 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Sat, 12 Oct 2024 17:37:22 +0200 Subject: [PATCH 01/14] Add `null` to argument types of optional parameters --- crates/cli-support/src/js/binding.rs | 35 +- crates/cli/tests/reference/echo.d.ts | 185 +++++++ crates/cli/tests/reference/echo.js | 757 ++++++++++++++++++++++++++ crates/cli/tests/reference/echo.rs | 56 ++ crates/cli/tests/reference/echo.wat | 99 ++++ crates/cli/tests/reference/enums.d.ts | 8 +- crates/cli/tests/reference/enums.js | 4 +- 7 files changed, 1130 insertions(+), 14 deletions(-) create mode 100644 crates/cli/tests/reference/echo.d.ts create mode 100644 crates/cli/tests/reference/echo.js create mode 100644 crates/cli/tests/reference/echo.rs create mode 100644 crates/cli/tests/reference/echo.wat diff --git a/crates/cli-support/src/js/binding.rs b/crates/cli-support/src/js/binding.rs index 27d58549ba6..0cca7389c4c 100644 --- a/crates/cli-support/src/js/binding.rs +++ b/crates/cli-support/src/js/binding.rs @@ -300,13 +300,15 @@ impl<'a, 'b> Builder<'a, 'b> { let mut ts = String::new(); match ty { AdapterType::Option(ty) if omittable => { + // e.g. `foo?: string | null` arg.push_str("?: "); - adapter2ts(ty, &mut ts); + adapter2ts(ty, &mut ts, NoneType::Both); + ts.push_str(" | null"); } ty => { omittable = false; arg.push_str(": "); - adapter2ts(ty, &mut ts); + adapter2ts(ty, &mut ts, NoneType::Both); } } arg.push_str(&ts); @@ -342,7 +344,7 @@ impl<'a, 'b> Builder<'a, 'b> { let mut ret = String::new(); match result_tys.len() { 0 => ret.push_str("void"), - 1 => adapter2ts(&result_tys[0], &mut ret), + 1 => adapter2ts(&result_tys[0], &mut ret, NoneType::Undefined), _ => ret.push_str("[any]"), } if asyncness { @@ -374,7 +376,7 @@ impl<'a, 'b> Builder<'a, 'b> { for (name, ty) in fn_arg_names.iter().zip(arg_tys).rev() { let mut arg = "@param {".to_string(); - adapter2ts(ty, &mut arg); + adapter2ts(ty, &mut arg, NoneType::Both); arg.push_str("} "); match ty { AdapterType::Option(..) if omittable => { @@ -395,7 +397,7 @@ impl<'a, 'b> Builder<'a, 'b> { if let (Some(name), Some(ty)) = (variadic_arg, arg_tys.last()) { ret.push_str("@param {..."); - adapter2ts(ty, &mut ret); + adapter2ts(ty, &mut ret, NoneType::Both); ret.push_str("} "); ret.push_str(name); ret.push('\n'); @@ -1417,7 +1419,23 @@ impl Invocation { } } -fn adapter2ts(ty: &AdapterType, dst: &mut String) { +#[derive(Debug, Clone, Copy)] +enum NoneType { + Undefined, + Null, + Both, +} +impl NoneType { + fn js_ty(&self) -> &str { + match self { + NoneType::Undefined => "undefined", + NoneType::Null => "null", + NoneType::Both => "undefined | null", + } + } +} + +fn adapter2ts(ty: &AdapterType, dst: &mut String, none_type: NoneType) { match ty { AdapterType::I32 | AdapterType::S8 @@ -1435,8 +1453,9 @@ fn adapter2ts(ty: &AdapterType, dst: &mut String) { AdapterType::Bool => dst.push_str("boolean"), AdapterType::Vector(kind) => dst.push_str(&kind.js_ty()), AdapterType::Option(ty) => { - adapter2ts(ty, dst); - dst.push_str(" | undefined"); + adapter2ts(ty, dst, none_type); + dst.push_str(" | "); + dst.push_str(none_type.js_ty()); } AdapterType::NamedExternref(name) => dst.push_str(name), AdapterType::Struct(name) => dst.push_str(name), diff --git a/crates/cli/tests/reference/echo.d.ts b/crates/cli/tests/reference/echo.d.ts new file mode 100644 index 00000000000..c141784c69b --- /dev/null +++ b/crates/cli/tests/reference/echo.d.ts @@ -0,0 +1,185 @@ +/* tslint:disable */ +/* eslint-disable */ +/** + * @param {number} a + * @returns {number} + */ +export function echo_u8(a: number): number; +/** + * @param {number} a + * @returns {number} + */ +export function echo_i8(a: number): number; +/** + * @param {number} a + * @returns {number} + */ +export function echo_u16(a: number): number; +/** + * @param {number} a + * @returns {number} + */ +export function echo_i16(a: number): number; +/** + * @param {number} a + * @returns {number} + */ +export function echo_u32(a: number): number; +/** + * @param {number} a + * @returns {number} + */ +export function echo_i32(a: number): number; +/** + * @param {bigint} a + * @returns {bigint} + */ +export function echo_u64(a: bigint): bigint; +/** + * @param {bigint} a + * @returns {bigint} + */ +export function echo_i64(a: bigint): bigint; +/** + * @param {number} a + * @returns {number} + */ +export function echo_usize(a: number): number; +/** + * @param {number} a + * @returns {number} + */ +export function echo_isize(a: number): number; +/** + * @param {number} a + * @returns {number} + */ +export function echo_f32(a: number): number; +/** + * @param {number} a + * @returns {number} + */ +export function echo_f64(a: number): number; +/** + * @param {boolean} a + * @returns {boolean} + */ +export function echo_bool(a: boolean): boolean; +/** + * @param {string} a + * @returns {string} + */ +export function echo_char(a: string): string; +/** + * @param {string} a + * @returns {string} + */ +export function echo_string(a: string): string; +/** + * @param {Uint8Array} a + * @returns {Uint8Array} + */ +export function echo_vec_u8(a: Uint8Array): Uint8Array; +/** + * @param {Foo} a + * @returns {Foo} + */ +export function echo_struct(a: Foo): Foo; +/** + * @param {(Foo)[]} a + * @returns {(Foo)[]} + */ +export function echo_vec_struct(a: (Foo)[]): (Foo)[]; +/** + * @param {number | undefined | null} [a] + * @returns {number | undefined} + */ +export function echo_option_u8(a?: number | null): number | undefined; +/** + * @param {number | undefined | null} [a] + * @returns {number | undefined} + */ +export function echo_option_i8(a?: number | null): number | undefined; +/** + * @param {number | undefined | null} [a] + * @returns {number | undefined} + */ +export function echo_option_u16(a?: number | null): number | undefined; +/** + * @param {number | undefined | null} [a] + * @returns {number | undefined} + */ +export function echo_option_i16(a?: number | null): number | undefined; +/** + * @param {number | undefined | null} [a] + * @returns {number | undefined} + */ +export function echo_option_u32(a?: number | null): number | undefined; +/** + * @param {number | undefined | null} [a] + * @returns {number | undefined} + */ +export function echo_option_i32(a?: number | null): number | undefined; +/** + * @param {bigint | undefined | null} [a] + * @returns {bigint | undefined} + */ +export function echo_option_u64(a?: bigint | null): bigint | undefined; +/** + * @param {bigint | undefined | null} [a] + * @returns {bigint | undefined} + */ +export function echo_option_i64(a?: bigint | null): bigint | undefined; +/** + * @param {number | undefined | null} [a] + * @returns {number | undefined} + */ +export function echo_option_usize(a?: number | null): number | undefined; +/** + * @param {number | undefined | null} [a] + * @returns {number | undefined} + */ +export function echo_option_isize(a?: number | null): number | undefined; +/** + * @param {number | undefined | null} [a] + * @returns {number | undefined} + */ +export function echo_option_f32(a?: number | null): number | undefined; +/** + * @param {number | undefined | null} [a] + * @returns {number | undefined} + */ +export function echo_option_f64(a?: number | null): number | undefined; +/** + * @param {boolean | undefined | null} [a] + * @returns {boolean | undefined} + */ +export function echo_option_bool(a?: boolean | null): boolean | undefined; +/** + * @param {string | undefined | null} [a] + * @returns {string | undefined} + */ +export function echo_option_char(a?: string | null): string | undefined; +/** + * @param {string | undefined | null} [a] + * @returns {string | undefined} + */ +export function echo_option_string(a?: string | null): string | undefined; +/** + * @param {Uint8Array | undefined | null} [a] + * @returns {Uint8Array | undefined} + */ +export function echo_option_vec_u8(a?: Uint8Array | null): Uint8Array | undefined; +/** + * @param {Foo | undefined | null} [a] + * @returns {Foo | undefined} + */ +export function echo_option_struct(a?: Foo | null): Foo | undefined; +/** + * @param {(Foo)[] | undefined | null} [a] + * @returns {(Foo)[] | undefined} + */ +export function echo_option_vec_struct(a?: (Foo)[] | null): (Foo)[] | undefined; +export class Foo { + free(): void; +} diff --git a/crates/cli/tests/reference/echo.js b/crates/cli/tests/reference/echo.js new file mode 100644 index 00000000000..83842c9cd3a --- /dev/null +++ b/crates/cli/tests/reference/echo.js @@ -0,0 +1,757 @@ +let wasm; +export function __wbg_set_wasm(val) { + wasm = val; +} + + +const heap = new Array(128).fill(undefined); + +heap.push(undefined, null, true, false); + +function getObject(idx) { return heap[idx]; } + +let heap_next = heap.length; + +function dropObject(idx) { + if (idx < 132) return; + heap[idx] = heap_next; + heap_next = idx; +} + +function takeObject(idx) { + const ret = getObject(idx); + dropObject(idx); + return ret; +} + +function debugString(val) { + // primitive types + const type = typeof val; + if (type == 'number' || type == 'boolean' || val == null) { + return `${val}`; + } + if (type == 'string') { + return `"${val}"`; + } + if (type == 'symbol') { + const description = val.description; + if (description == null) { + return 'Symbol'; + } else { + return `Symbol(${description})`; + } + } + if (type == 'function') { + const name = val.name; + if (typeof name == 'string' && name.length > 0) { + return `Function(${name})`; + } else { + return 'Function'; + } + } + // objects + if (Array.isArray(val)) { + const length = val.length; + let debug = '['; + if (length > 0) { + debug += debugString(val[0]); + } + for(let i = 1; i < length; i++) { + debug += ', ' + debugString(val[i]); + } + debug += ']'; + return debug; + } + // Test for built-in + const builtInMatches = /\[object ([^\]]+)\]/.exec(toString.call(val)); + let className; + if (builtInMatches.length > 1) { + className = builtInMatches[1]; + } else { + // Failed to match the standard '[object ClassName]' + return toString.call(val); + } + if (className == 'Object') { + // we're a user defined class or Object + // JSON.stringify avoids problems with cycles, and is generally much + // easier than looping through ownProperties of `val`. + try { + return 'Object(' + JSON.stringify(val) + ')'; + } catch (_) { + return 'Object'; + } + } + // errors + if (val instanceof Error) { + return `${val.name}: ${val.message}\n${val.stack}`; + } + // TODO we could test for more things here, like `Set`s and `Map`s. + return className; +} + +let WASM_VECTOR_LEN = 0; + +let cachedUint8ArrayMemory0 = null; + +function getUint8ArrayMemory0() { + if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) { + cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer); + } + return cachedUint8ArrayMemory0; +} + +const lTextEncoder = typeof TextEncoder === 'undefined' ? (0, module.require)('util').TextEncoder : TextEncoder; + +let cachedTextEncoder = new lTextEncoder('utf-8'); + +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; +} + +let cachedDataViewMemory0 = null; + +function getDataViewMemory0() { + if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) { + cachedDataViewMemory0 = new DataView(wasm.memory.buffer); + } + return cachedDataViewMemory0; +} + +const lTextDecoder = typeof TextDecoder === 'undefined' ? (0, module.require)('util').TextDecoder : TextDecoder; + +let cachedTextDecoder = new lTextDecoder('utf-8', { ignoreBOM: true, fatal: true }); + +cachedTextDecoder.decode(); + +function getStringFromWasm0(ptr, len) { + ptr = ptr >>> 0; + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + +function addHeapObject(obj) { + if (heap_next === heap.length) heap.push(heap.length + 1); + const idx = heap_next; + heap_next = heap[idx]; + + heap[idx] = obj; + return idx; +} +/** + * @param {number} a + * @returns {number} + */ +export function echo_u8(a) { + const ret = wasm.echo_u8(a); + return ret; +} + +/** + * @param {number} a + * @returns {number} + */ +export function echo_i8(a) { + const ret = wasm.echo_i8(a); + return ret; +} + +/** + * @param {number} a + * @returns {number} + */ +export function echo_u16(a) { + const ret = wasm.echo_u16(a); + return ret; +} + +/** + * @param {number} a + * @returns {number} + */ +export function echo_i16(a) { + const ret = wasm.echo_i16(a); + return ret; +} + +/** + * @param {number} a + * @returns {number} + */ +export function echo_u32(a) { + const ret = wasm.echo_u32(a); + return ret >>> 0; +} + +/** + * @param {number} a + * @returns {number} + */ +export function echo_i32(a) { + const ret = wasm.echo_i32(a); + return ret; +} + +/** + * @param {bigint} a + * @returns {bigint} + */ +export function echo_u64(a) { + const ret = wasm.echo_u64(a); + return BigInt.asUintN(64, ret); +} + +/** + * @param {bigint} a + * @returns {bigint} + */ +export function echo_i64(a) { + const ret = wasm.echo_i64(a); + return ret; +} + +/** + * @param {number} a + * @returns {number} + */ +export function echo_usize(a) { + const ret = wasm.echo_usize(a); + return ret >>> 0; +} + +/** + * @param {number} a + * @returns {number} + */ +export function echo_isize(a) { + const ret = wasm.echo_isize(a); + return ret; +} + +/** + * @param {number} a + * @returns {number} + */ +export function echo_f32(a) { + const ret = wasm.echo_f32(a); + return ret; +} + +/** + * @param {number} a + * @returns {number} + */ +export function echo_f64(a) { + const ret = wasm.echo_f64(a); + return ret; +} + +/** + * @param {boolean} a + * @returns {boolean} + */ +export function echo_bool(a) { + const ret = wasm.echo_bool(a); + return ret !== 0; +} + +function _assertChar(c) { + if (typeof(c) === 'number' && (c >= 0x110000 || (c >= 0xD800 && c < 0xE000))) throw new Error(`expected a valid Unicode scalar value, found ${c}`); +} +/** + * @param {string} a + * @returns {string} + */ +export function echo_char(a) { + const char0 = a.codePointAt(0); + _assertChar(char0); + const ret = wasm.echo_char(char0); + return String.fromCodePoint(ret); +} + +/** + * @param {string} a + * @returns {string} + */ +export function echo_string(a) { + let deferred2_0; + let deferred2_1; + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(a, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + wasm.echo_string(retptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + deferred2_0 = r0; + deferred2_1 = r1; + return getStringFromWasm0(r0, r1); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_free(deferred2_0, deferred2_1, 1); + } +} + +function passArray8ToWasm0(arg, malloc) { + const ptr = malloc(arg.length * 1, 1) >>> 0; + getUint8ArrayMemory0().set(arg, ptr / 1); + WASM_VECTOR_LEN = arg.length; + return ptr; +} + +function getArrayU8FromWasm0(ptr, len) { + ptr = ptr >>> 0; + return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len); +} +/** + * @param {Uint8Array} a + * @returns {Uint8Array} + */ +export function echo_vec_u8(a) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArray8ToWasm0(a, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + wasm.echo_vec_u8(retptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var v2 = getArrayU8FromWasm0(r0, r1).slice(); + wasm.__wbindgen_free(r0, r1 * 1, 1); + return v2; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } +} + +function _assertClass(instance, klass) { + if (!(instance instanceof klass)) { + throw new Error(`expected instance of ${klass.name}`); + } + return instance.ptr; +} +/** + * @param {Foo} a + * @returns {Foo} + */ +export function echo_struct(a) { + _assertClass(a, Foo); + var ptr0 = a.__destroy_into_raw(); + const ret = wasm.echo_struct(ptr0); + return Foo.__wrap(ret); +} + +function passArrayJsValueToWasm0(array, malloc) { + const ptr = malloc(array.length * 4, 4) >>> 0; + const mem = getDataViewMemory0(); + for (let i = 0; i < array.length; i++) { + mem.setUint32(ptr + 4 * i, addHeapObject(array[i]), true); + } + WASM_VECTOR_LEN = array.length; + return ptr; +} + +function getArrayJsValueFromWasm0(ptr, len) { + ptr = ptr >>> 0; + const mem = getDataViewMemory0(); + const result = []; + for (let i = ptr; i < ptr + 4 * len; i += 4) { + result.push(takeObject(mem.getUint32(i, true))); + } + return result; +} +/** + * @param {(Foo)[]} a + * @returns {(Foo)[]} + */ +export function echo_vec_struct(a) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passArrayJsValueToWasm0(a, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + wasm.echo_vec_struct(retptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var v2 = getArrayJsValueFromWasm0(r0, r1).slice(); + wasm.__wbindgen_free(r0, r1 * 4, 4); + return v2; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } +} + +function isLikeNone(x) { + return x === undefined || x === null; +} +/** + * @param {number | undefined | null} [a] + * @returns {number | undefined} + */ +export function echo_option_u8(a) { + const ret = wasm.echo_option_u8(isLikeNone(a) ? 0xFFFFFF : a); + return ret === 0xFFFFFF ? undefined : ret; +} + +/** + * @param {number | undefined | null} [a] + * @returns {number | undefined} + */ +export function echo_option_i8(a) { + const ret = wasm.echo_option_i8(isLikeNone(a) ? 0xFFFFFF : a); + return ret === 0xFFFFFF ? undefined : ret; +} + +/** + * @param {number | undefined | null} [a] + * @returns {number | undefined} + */ +export function echo_option_u16(a) { + const ret = wasm.echo_option_u16(isLikeNone(a) ? 0xFFFFFF : a); + return ret === 0xFFFFFF ? undefined : ret; +} + +/** + * @param {number | undefined | null} [a] + * @returns {number | undefined} + */ +export function echo_option_i16(a) { + const ret = wasm.echo_option_i16(isLikeNone(a) ? 0xFFFFFF : a); + return ret === 0xFFFFFF ? undefined : ret; +} + +/** + * @param {number | undefined | null} [a] + * @returns {number | undefined} + */ +export function echo_option_u32(a) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.echo_option_u32(retptr, !isLikeNone(a), isLikeNone(a) ? 0 : a); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + return r0 === 0 ? undefined : r1 >>> 0; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } +} + +/** + * @param {number | undefined | null} [a] + * @returns {number | undefined} + */ +export function echo_option_i32(a) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.echo_option_i32(retptr, !isLikeNone(a), isLikeNone(a) ? 0 : a); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + return r0 === 0 ? undefined : r1; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } +} + +/** + * @param {bigint | undefined | null} [a] + * @returns {bigint | undefined} + */ +export function echo_option_u64(a) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.echo_option_u64(retptr, !isLikeNone(a), isLikeNone(a) ? BigInt(0) : a); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r2 = getDataViewMemory0().getBigInt64(retptr + 8 * 1, true); + return r0 === 0 ? undefined : BigInt.asUintN(64, r2); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } +} + +/** + * @param {bigint | undefined | null} [a] + * @returns {bigint | undefined} + */ +export function echo_option_i64(a) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.echo_option_i64(retptr, !isLikeNone(a), isLikeNone(a) ? BigInt(0) : a); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r2 = getDataViewMemory0().getBigInt64(retptr + 8 * 1, true); + return r0 === 0 ? undefined : r2; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } +} + +/** + * @param {number | undefined | null} [a] + * @returns {number | undefined} + */ +export function echo_option_usize(a) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.echo_option_usize(retptr, !isLikeNone(a), isLikeNone(a) ? 0 : a); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + return r0 === 0 ? undefined : r1 >>> 0; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } +} + +/** + * @param {number | undefined | null} [a] + * @returns {number | undefined} + */ +export function echo_option_isize(a) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.echo_option_isize(retptr, !isLikeNone(a), isLikeNone(a) ? 0 : a); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + return r0 === 0 ? undefined : r1; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } +} + +/** + * @param {number | undefined | null} [a] + * @returns {number | undefined} + */ +export function echo_option_f32(a) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.echo_option_f32(retptr, !isLikeNone(a), isLikeNone(a) ? 0 : a); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getFloat32(retptr + 4 * 1, true); + return r0 === 0 ? undefined : r1; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } +} + +/** + * @param {number | undefined | null} [a] + * @returns {number | undefined} + */ +export function echo_option_f64(a) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + wasm.echo_option_f64(retptr, !isLikeNone(a), isLikeNone(a) ? 0 : a); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r2 = getDataViewMemory0().getFloat64(retptr + 8 * 1, true); + return r0 === 0 ? undefined : r2; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } +} + +/** + * @param {boolean | undefined | null} [a] + * @returns {boolean | undefined} + */ +export function echo_option_bool(a) { + const ret = wasm.echo_option_bool(isLikeNone(a) ? 0xFFFFFF : a ? 1 : 0); + return ret === 0xFFFFFF ? undefined : ret !== 0; +} + +/** + * @param {string | undefined | null} [a] + * @returns {string | undefined} + */ +export function echo_option_char(a) { + const char0 = isLikeNone(a) ? 0xFFFFFF : a.codePointAt(0); +if (char0 !== 0xFFFFFF) { _assertChar(char0); } +const ret = wasm.echo_option_char(char0); +return ret === 0xFFFFFF ? undefined : String.fromCodePoint(ret); +} + +/** + * @param {string | undefined | null} [a] + * @returns {string | undefined} + */ +export function echo_option_string(a) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + var ptr0 = isLikeNone(a) ? 0 : passStringToWasm0(a, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + var len0 = WASM_VECTOR_LEN; + wasm.echo_option_string(retptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + let v2; + if (r0 !== 0) { + v2 = getStringFromWasm0(r0, r1).slice(); + wasm.__wbindgen_free(r0, r1 * 1, 1); + } + return v2; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } +} + +/** + * @param {Uint8Array | undefined | null} [a] + * @returns {Uint8Array | undefined} + */ +export function echo_option_vec_u8(a) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + var ptr0 = isLikeNone(a) ? 0 : passArray8ToWasm0(a, wasm.__wbindgen_malloc); + var len0 = WASM_VECTOR_LEN; + wasm.echo_option_vec_u8(retptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + let v2; + if (r0 !== 0) { + v2 = getArrayU8FromWasm0(r0, r1).slice(); + wasm.__wbindgen_free(r0, r1 * 1, 1); + } + return v2; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } +} + +/** + * @param {Foo | undefined | null} [a] + * @returns {Foo | undefined} + */ +export function echo_option_struct(a) { + let ptr0 = 0; + if (!isLikeNone(a)) { + _assertClass(a, Foo); + ptr0 = a.__destroy_into_raw(); + } + const ret = wasm.echo_option_struct(ptr0); + return ret === 0 ? undefined : Foo.__wrap(ret); +} + +/** + * @param {(Foo)[] | undefined | null} [a] + * @returns {(Foo)[] | undefined} + */ +export function echo_option_vec_struct(a) { + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + var ptr0 = isLikeNone(a) ? 0 : passArrayJsValueToWasm0(a, wasm.__wbindgen_malloc); + var len0 = WASM_VECTOR_LEN; + wasm.echo_option_vec_struct(retptr, ptr0, len0); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + let v2; + if (r0 !== 0) { + v2 = getArrayJsValueFromWasm0(r0, r1).slice(); + wasm.__wbindgen_free(r0, r1 * 4, 4); + } + return v2; + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + } +} + +const FooFinalization = (typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_foo_free(ptr >>> 0, 1)); + +export class Foo { + + static __wrap(ptr) { + ptr = ptr >>> 0; + const obj = Object.create(Foo.prototype); + obj.__wbg_ptr = ptr; + FooFinalization.register(obj, obj.__wbg_ptr, obj); + return obj; + } + + static __unwrap(jsValue) { + if (!(jsValue instanceof Foo)) { + return 0; + } + return jsValue.__destroy_into_raw(); + } + + __destroy_into_raw() { + const ptr = this.__wbg_ptr; + this.__wbg_ptr = 0; + FooFinalization.unregister(this); + return ptr; + } + + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_foo_free(ptr, 0); + } +} + +export function __wbg_foo_unwrap(arg0) { + const ret = Foo.__unwrap(takeObject(arg0)); + return ret; +}; + +export function __wbg_foo_new(arg0) { + const ret = Foo.__wrap(arg0); + return addHeapObject(ret); +}; + +export function __wbindgen_object_drop_ref(arg0) { + takeObject(arg0); +}; + +export function __wbindgen_debug_string(arg0, arg1) { + const ret = debugString(getObject(arg1)); + const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); +}; + +export function __wbindgen_throw(arg0, arg1) { + throw new Error(getStringFromWasm0(arg0, arg1)); +}; + diff --git a/crates/cli/tests/reference/echo.rs b/crates/cli/tests/reference/echo.rs new file mode 100644 index 00000000000..e87719dd570 --- /dev/null +++ b/crates/cli/tests/reference/echo.rs @@ -0,0 +1,56 @@ +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +pub struct Foo { + x: u32, +} + +macro_rules! echo { + ($(($n:ident, $t:ty)),*) => { + $( + #[wasm_bindgen] + pub fn $n(a: $t) -> $t { + a + } + )* + } +} + +echo!( + (echo_u8, u8), + (echo_i8, i8), + (echo_u16, u16), + (echo_i16, i16), + (echo_u32, u32), + (echo_i32, i32), + (echo_u64, u64), + (echo_i64, i64), + (echo_usize, usize), + (echo_isize, isize), + (echo_f32, f32), + (echo_f64, f64), + (echo_bool, bool), + (echo_char, char), + (echo_string, String), + (echo_vec_u8, Vec), + (echo_struct, Foo), + (echo_vec_struct, Vec), + (echo_option_u8, Option), + (echo_option_i8, Option), + (echo_option_u16, Option), + (echo_option_i16, Option), + (echo_option_u32, Option), + (echo_option_i32, Option), + (echo_option_u64, Option), + (echo_option_i64, Option), + (echo_option_usize, Option), + (echo_option_isize, Option), + (echo_option_f32, Option), + (echo_option_f64, Option), + (echo_option_bool, Option), + (echo_option_char, Option), + (echo_option_string, Option), + (echo_option_vec_u8, Option>), + (echo_option_struct, Option), + (echo_option_vec_struct, Option>) +); diff --git a/crates/cli/tests/reference/echo.wat b/crates/cli/tests/reference/echo.wat new file mode 100644 index 00000000000..ee89000c6af --- /dev/null +++ b/crates/cli/tests/reference/echo.wat @@ -0,0 +1,99 @@ +(module $reference_test.wasm + (type (;0;) (func (param i32) (result i32))) + (type (;1;) (func (param i32 i32))) + (type (;2;) (func (param i32 i32) (result i32))) + (type (;3;) (func (param i32 i32 i32))) + (type (;4;) (func (param i32 i32 i32 i32) (result i32))) + (type (;5;) (func (param i32 i32 i64))) + (type (;6;) (func (param i32 i32 f32))) + (type (;7;) (func (param i32 i32 f64))) + (type (;8;) (func (param i64) (result i64))) + (type (;9;) (func (param f32) (result f32))) + (type (;10;) (func (param f64) (result f64))) + (func $__wbindgen_realloc (;0;) (type 4) (param i32 i32 i32 i32) (result i32)) + (func $__wbindgen_malloc (;1;) (type 2) (param i32 i32) (result i32)) + (func $echo_option_u32 (;2;) (type 3) (param i32 i32 i32)) + (func $echo_option_i32 (;3;) (type 3) (param i32 i32 i32)) + (func $echo_option_u64 (;4;) (type 5) (param i32 i32 i64)) + (func $echo_option_i64 (;5;) (type 5) (param i32 i32 i64)) + (func $echo_option_usize (;6;) (type 3) (param i32 i32 i32)) + (func $echo_option_isize (;7;) (type 3) (param i32 i32 i32)) + (func $echo_option_f32 (;8;) (type 6) (param i32 i32 f32)) + (func $echo_option_f64 (;9;) (type 7) (param i32 i32 f64)) + (func $echo_string (;10;) (type 3) (param i32 i32 i32)) + (func $echo_vec_u8 (;11;) (type 3) (param i32 i32 i32)) + (func $echo_vec_struct (;12;) (type 3) (param i32 i32 i32)) + (func $echo_option_string (;13;) (type 3) (param i32 i32 i32)) + (func $echo_option_vec_u8 (;14;) (type 3) (param i32 i32 i32)) + (func $echo_option_vec_struct (;15;) (type 3) (param i32 i32 i32)) + (func $echo_option_u8 (;16;) (type 0) (param i32) (result i32)) + (func $echo_option_i8 (;17;) (type 0) (param i32) (result i32)) + (func $echo_option_u16 (;18;) (type 0) (param i32) (result i32)) + (func $echo_option_i16 (;19;) (type 0) (param i32) (result i32)) + (func $echo_option_struct (;20;) (type 0) (param i32) (result i32)) + (func $echo_u8 (;21;) (type 0) (param i32) (result i32)) + (func $echo_i8 (;22;) (type 0) (param i32) (result i32)) + (func $echo_u16 (;23;) (type 0) (param i32) (result i32)) + (func $echo_i16 (;24;) (type 0) (param i32) (result i32)) + (func $echo_u32 (;25;) (type 0) (param i32) (result i32)) + (func $echo_i32 (;26;) (type 0) (param i32) (result i32)) + (func $echo_usize (;27;) (type 0) (param i32) (result i32)) + (func $echo_isize (;28;) (type 0) (param i32) (result i32)) + (func $echo_f32 (;29;) (type 9) (param f32) (result f32)) + (func $echo_bool (;30;) (type 0) (param i32) (result i32)) + (func $echo_char (;31;) (type 0) (param i32) (result i32)) + (func $echo_struct (;32;) (type 0) (param i32) (result i32)) + (func $echo_option_bool (;33;) (type 0) (param i32) (result i32)) + (func $echo_option_char (;34;) (type 0) (param i32) (result i32)) + (func $echo_u64 (;35;) (type 8) (param i64) (result i64)) + (func $echo_i64 (;36;) (type 8) (param i64) (result i64)) + (func $echo_f64 (;37;) (type 10) (param f64) (result f64)) + (func $__wbindgen_free (;38;) (type 3) (param i32 i32 i32)) + (func $__wbg_foo_free (;39;) (type 1) (param i32 i32)) + (func $__wbindgen_add_to_stack_pointer (;40;) (type 0) (param i32) (result i32)) + (memory (;0;) 17) + (export "memory" (memory 0)) + (export "__wbg_foo_free" (func $__wbg_foo_free)) + (export "echo_u8" (func $echo_u8)) + (export "echo_i8" (func $echo_i8)) + (export "echo_u16" (func $echo_u16)) + (export "echo_i16" (func $echo_i16)) + (export "echo_u32" (func $echo_u32)) + (export "echo_i32" (func $echo_i32)) + (export "echo_u64" (func $echo_u64)) + (export "echo_i64" (func $echo_i64)) + (export "echo_usize" (func $echo_usize)) + (export "echo_isize" (func $echo_isize)) + (export "echo_f32" (func $echo_f32)) + (export "echo_f64" (func $echo_f64)) + (export "echo_bool" (func $echo_bool)) + (export "echo_char" (func $echo_char)) + (export "echo_string" (func $echo_string)) + (export "echo_vec_u8" (func $echo_vec_u8)) + (export "echo_struct" (func $echo_struct)) + (export "echo_vec_struct" (func $echo_vec_struct)) + (export "echo_option_u8" (func $echo_option_u8)) + (export "echo_option_i8" (func $echo_option_i8)) + (export "echo_option_u16" (func $echo_option_u16)) + (export "echo_option_i16" (func $echo_option_i16)) + (export "echo_option_u32" (func $echo_option_u32)) + (export "echo_option_i32" (func $echo_option_i32)) + (export "echo_option_u64" (func $echo_option_u64)) + (export "echo_option_i64" (func $echo_option_i64)) + (export "echo_option_usize" (func $echo_option_usize)) + (export "echo_option_isize" (func $echo_option_isize)) + (export "echo_option_f32" (func $echo_option_f32)) + (export "echo_option_f64" (func $echo_option_f64)) + (export "echo_option_bool" (func $echo_option_bool)) + (export "echo_option_char" (func $echo_option_char)) + (export "echo_option_string" (func $echo_option_string)) + (export "echo_option_vec_u8" (func $echo_option_vec_u8)) + (export "echo_option_struct" (func $echo_option_struct)) + (export "echo_option_vec_struct" (func $echo_option_vec_struct)) + (export "__wbindgen_malloc" (func $__wbindgen_malloc)) + (export "__wbindgen_realloc" (func $__wbindgen_realloc)) + (export "__wbindgen_add_to_stack_pointer" (func $__wbindgen_add_to_stack_pointer)) + (export "__wbindgen_free" (func $__wbindgen_free)) + (@custom "target_features" (after code) "\02+\0fmutable-globals+\08sign-ext") +) + diff --git a/crates/cli/tests/reference/enums.d.ts b/crates/cli/tests/reference/enums.d.ts index 86e3e28d560..dc8c4b7c97e 100644 --- a/crates/cli/tests/reference/enums.d.ts +++ b/crates/cli/tests/reference/enums.d.ts @@ -6,20 +6,20 @@ */ export function enum_echo(color: Color): Color; /** - * @param {Color | undefined} [color] + * @param {Color | undefined | null} [color] * @returns {Color | undefined} */ -export function option_enum_echo(color?: Color): Color | undefined; +export function option_enum_echo(color?: Color | null): Color | undefined; /** * @param {Color} color * @returns {any} */ export function get_name(color: Color): any; /** - * @param {any | undefined} [color] + * @param {any | undefined | null} [color] * @returns {any | undefined} */ -export function option_string_enum_echo(color?: any): any | undefined; +export function option_string_enum_echo(color?: any | null): any | undefined; /** * A color. */ diff --git a/crates/cli/tests/reference/enums.js b/crates/cli/tests/reference/enums.js index e69baa01e95..7662a40c01c 100644 --- a/crates/cli/tests/reference/enums.js +++ b/crates/cli/tests/reference/enums.js @@ -36,7 +36,7 @@ function isLikeNone(x) { return x === undefined || x === null; } /** - * @param {Color | undefined} [color] + * @param {Color | undefined | null} [color] * @returns {Color | undefined} */ export function option_enum_echo(color) { @@ -54,7 +54,7 @@ export function get_name(color) { } /** - * @param {any | undefined} [color] + * @param {any | undefined | null} [color] * @returns {any | undefined} */ export function option_string_enum_echo(color) { From 0fe90f93775b8c4d5d8b72c51b885bd0e9406e8e Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Sat, 12 Oct 2024 19:09:55 +0200 Subject: [PATCH 02/14] Update echo.js --- crates/cli/tests/reference/echo.js | 42 +++++++++++++++--------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/crates/cli/tests/reference/echo.js b/crates/cli/tests/reference/echo.js index 83842c9cd3a..f12c6d807d6 100644 --- a/crates/cli/tests/reference/echo.js +++ b/crates/cli/tests/reference/echo.js @@ -10,20 +10,6 @@ heap.push(undefined, null, true, false); function getObject(idx) { return heap[idx]; } -let heap_next = heap.length; - -function dropObject(idx) { - if (idx < 132) return; - heap[idx] = heap_next; - heap_next = idx; -} - -function takeObject(idx) { - const ret = getObject(idx); - dropObject(idx); - return ret; -} - function debugString(val) { // primitive types const type = typeof val; @@ -176,6 +162,20 @@ function getStringFromWasm0(ptr, len) { return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); } +let heap_next = heap.length; + +function dropObject(idx) { + if (idx < 132) return; + heap[idx] = heap_next; + heap_next = idx; +} + +function takeObject(idx) { + const ret = getObject(idx); + dropObject(idx); + return ret; +} + function addHeapObject(obj) { if (heap_next === heap.length) heap.push(heap.length + 1); const idx = heap_next; @@ -729,18 +729,14 @@ export class Foo { } } -export function __wbg_foo_unwrap(arg0) { - const ret = Foo.__unwrap(takeObject(arg0)); - return ret; -}; - export function __wbg_foo_new(arg0) { const ret = Foo.__wrap(arg0); return addHeapObject(ret); }; -export function __wbindgen_object_drop_ref(arg0) { - takeObject(arg0); +export function __wbg_foo_unwrap(arg0) { + const ret = Foo.__unwrap(takeObject(arg0)); + return ret; }; export function __wbindgen_debug_string(arg0, arg1) { @@ -755,3 +751,7 @@ export function __wbindgen_throw(arg0, arg1) { throw new Error(getStringFromWasm0(arg0, arg1)); }; +export function __wbindgen_object_drop_ref(arg0) { + takeObject(arg0); +}; + From ff5dd9d24f5805d7c6731e83210a93b0f09045e8 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Sat, 12 Oct 2024 23:53:12 +0200 Subject: [PATCH 03/14] Updated refs and changelog --- CHANGELOG.md | 3 +++ crates/cli/tests/reference/echo.d.ts | 36 +++++++++++++-------------- crates/cli/tests/reference/enums.d.ts | 8 +++--- crates/cli/tests/reference/enums.js | 4 +-- 4 files changed, 27 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 745e56ecbab..2de77bc54c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ * String enums now generate private TypeScript types but only if used. [#4174](https://github.com/rustwasm/wasm-bindgen/pull/4174) +* Optional parameters are now typed as `T | undefined | null` to reflect the JS behavior. + [#4188](https://github.com/rustwasm/wasm-bindgen/pull/4188) + ### Fixed * Fixed methods with `self: &Self` consuming the object. diff --git a/crates/cli/tests/reference/echo.d.ts b/crates/cli/tests/reference/echo.d.ts index c141784c69b..2b3f6f162c8 100644 --- a/crates/cli/tests/reference/echo.d.ts +++ b/crates/cli/tests/reference/echo.d.ts @@ -94,92 +94,92 @@ export function echo_vec_struct(a: (Foo)[]): (Foo)[]; * @param {number | undefined | null} [a] * @returns {number | undefined} */ -export function echo_option_u8(a?: number | null): number | undefined; +export function echo_option_u8(a?: number): number | undefined; /** * @param {number | undefined | null} [a] * @returns {number | undefined} */ -export function echo_option_i8(a?: number | null): number | undefined; +export function echo_option_i8(a?: number): number | undefined; /** * @param {number | undefined | null} [a] * @returns {number | undefined} */ -export function echo_option_u16(a?: number | null): number | undefined; +export function echo_option_u16(a?: number): number | undefined; /** * @param {number | undefined | null} [a] * @returns {number | undefined} */ -export function echo_option_i16(a?: number | null): number | undefined; +export function echo_option_i16(a?: number): number | undefined; /** * @param {number | undefined | null} [a] * @returns {number | undefined} */ -export function echo_option_u32(a?: number | null): number | undefined; +export function echo_option_u32(a?: number): number | undefined; /** * @param {number | undefined | null} [a] * @returns {number | undefined} */ -export function echo_option_i32(a?: number | null): number | undefined; +export function echo_option_i32(a?: number): number | undefined; /** * @param {bigint | undefined | null} [a] * @returns {bigint | undefined} */ -export function echo_option_u64(a?: bigint | null): bigint | undefined; +export function echo_option_u64(a?: bigint): bigint | undefined; /** * @param {bigint | undefined | null} [a] * @returns {bigint | undefined} */ -export function echo_option_i64(a?: bigint | null): bigint | undefined; +export function echo_option_i64(a?: bigint): bigint | undefined; /** * @param {number | undefined | null} [a] * @returns {number | undefined} */ -export function echo_option_usize(a?: number | null): number | undefined; +export function echo_option_usize(a?: number): number | undefined; /** * @param {number | undefined | null} [a] * @returns {number | undefined} */ -export function echo_option_isize(a?: number | null): number | undefined; +export function echo_option_isize(a?: number): number | undefined; /** * @param {number | undefined | null} [a] * @returns {number | undefined} */ -export function echo_option_f32(a?: number | null): number | undefined; +export function echo_option_f32(a?: number): number | undefined; /** * @param {number | undefined | null} [a] * @returns {number | undefined} */ -export function echo_option_f64(a?: number | null): number | undefined; +export function echo_option_f64(a?: number): number | undefined; /** * @param {boolean | undefined | null} [a] * @returns {boolean | undefined} */ -export function echo_option_bool(a?: boolean | null): boolean | undefined; +export function echo_option_bool(a?: boolean): boolean | undefined; /** * @param {string | undefined | null} [a] * @returns {string | undefined} */ -export function echo_option_char(a?: string | null): string | undefined; +export function echo_option_char(a?: string): string | undefined; /** * @param {string | undefined | null} [a] * @returns {string | undefined} */ -export function echo_option_string(a?: string | null): string | undefined; +export function echo_option_string(a?: string): string | undefined; /** * @param {Uint8Array | undefined | null} [a] * @returns {Uint8Array | undefined} */ -export function echo_option_vec_u8(a?: Uint8Array | null): Uint8Array | undefined; +export function echo_option_vec_u8(a?: Uint8Array): Uint8Array | undefined; /** * @param {Foo | undefined | null} [a] * @returns {Foo | undefined} */ -export function echo_option_struct(a?: Foo | null): Foo | undefined; +export function echo_option_struct(a?: Foo): Foo | undefined; /** * @param {(Foo)[] | undefined | null} [a] * @returns {(Foo)[] | undefined} */ -export function echo_option_vec_struct(a?: (Foo)[] | null): (Foo)[] | undefined; +export function echo_option_vec_struct(a?: (Foo)[]): (Foo)[] | undefined; export class Foo { free(): void; } diff --git a/crates/cli/tests/reference/enums.d.ts b/crates/cli/tests/reference/enums.d.ts index 930414ae49c..fcd2a2bdcb2 100644 --- a/crates/cli/tests/reference/enums.d.ts +++ b/crates/cli/tests/reference/enums.d.ts @@ -9,17 +9,17 @@ export function enum_echo(color: Color): Color; * @param {Color | undefined | null} [color] * @returns {Color | undefined} */ -export function option_enum_echo(color?: Color | null): Color | undefined; +export function option_enum_echo(color?: Color): Color | undefined; /** * @param {Color} color * @returns {ColorName} */ export function get_name(color: Color): ColorName; /** - * @param {any | undefined | null} [color] - * @returns {any | undefined} + * @param {ColorName | undefined | null} [color] + * @returns {ColorName | undefined} */ -export function option_string_enum_echo(color?: any | null): any | undefined; +export function option_string_enum_echo(color?: ColorName): ColorName | undefined; /** * A color. */ diff --git a/crates/cli/tests/reference/enums.js b/crates/cli/tests/reference/enums.js index 7987f27eebe..f3fcd999437 100644 --- a/crates/cli/tests/reference/enums.js +++ b/crates/cli/tests/reference/enums.js @@ -54,8 +54,8 @@ export function get_name(color) { } /** - * @param {any | undefined | null} [color] - * @returns {any | undefined} + * @param {ColorName | undefined | null} [color] + * @returns {ColorName | undefined} */ export function option_string_enum_echo(color) { const ret = wasm.option_string_enum_echo(isLikeNone(color) ? 4 : ((__wbindgen_enum_ColorName.indexOf(color) + 1 || 4) - 1)); From 914222d754b11a0d75733021d1bb91308b785c0c Mon Sep 17 00:00:00 2001 From: daxpedda Date: Sat, 12 Oct 2024 23:55:12 +0200 Subject: [PATCH 04/14] Adjust changelog entry --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2de77bc54c5..3bb5c498ab5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ * String enums now generate private TypeScript types but only if used. [#4174](https://github.com/rustwasm/wasm-bindgen/pull/4174) -* Optional parameters are now typed as `T | undefined | null` to reflect the JS behavior. +* Optional parameters are now typed as `T | undefined | null` to reflect the actual JS behavior. [#4188](https://github.com/rustwasm/wasm-bindgen/pull/4188) ### Fixed From 3febb5e4b154a8d6e324cfff750e5523705a42f1 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Sun, 13 Oct 2024 00:28:24 +0200 Subject: [PATCH 05/14] Fixed missing null in TS optional args --- crates/cli-support/src/js/binding.rs | 1 + crates/cli/tests/reference/echo.d.ts | 180 +++----------------------- crates/cli/tests/reference/enums.d.ts | 10 +- 3 files changed, 22 insertions(+), 169 deletions(-) diff --git a/crates/cli-support/src/js/binding.rs b/crates/cli-support/src/js/binding.rs index 6b1e41eb6f1..9b1df3e2025 100644 --- a/crates/cli-support/src/js/binding.rs +++ b/crates/cli-support/src/js/binding.rs @@ -315,6 +315,7 @@ impl<'a, 'b> Builder<'a, 'b> { // e.g. `foo?: string | null` arg.push_str("?: "); adapter2ts(ty, TypePosition::Argument, &mut ts, Some(&mut ts_refs)); + ts.push_str(" | null"); } ty => { omittable = false; diff --git a/crates/cli/tests/reference/echo.d.ts b/crates/cli/tests/reference/echo.d.ts index 2b3f6f162c8..2bb0d480770 100644 --- a/crates/cli/tests/reference/echo.d.ts +++ b/crates/cli/tests/reference/echo.d.ts @@ -1,185 +1,41 @@ /* tslint:disable */ /* eslint-disable */ -/** - * @param {number} a - * @returns {number} - */ export function echo_u8(a: number): number; -/** - * @param {number} a - * @returns {number} - */ export function echo_i8(a: number): number; -/** - * @param {number} a - * @returns {number} - */ export function echo_u16(a: number): number; -/** - * @param {number} a - * @returns {number} - */ export function echo_i16(a: number): number; -/** - * @param {number} a - * @returns {number} - */ export function echo_u32(a: number): number; -/** - * @param {number} a - * @returns {number} - */ export function echo_i32(a: number): number; -/** - * @param {bigint} a - * @returns {bigint} - */ export function echo_u64(a: bigint): bigint; -/** - * @param {bigint} a - * @returns {bigint} - */ export function echo_i64(a: bigint): bigint; -/** - * @param {number} a - * @returns {number} - */ export function echo_usize(a: number): number; -/** - * @param {number} a - * @returns {number} - */ export function echo_isize(a: number): number; -/** - * @param {number} a - * @returns {number} - */ export function echo_f32(a: number): number; -/** - * @param {number} a - * @returns {number} - */ export function echo_f64(a: number): number; -/** - * @param {boolean} a - * @returns {boolean} - */ export function echo_bool(a: boolean): boolean; -/** - * @param {string} a - * @returns {string} - */ export function echo_char(a: string): string; -/** - * @param {string} a - * @returns {string} - */ export function echo_string(a: string): string; -/** - * @param {Uint8Array} a - * @returns {Uint8Array} - */ export function echo_vec_u8(a: Uint8Array): Uint8Array; -/** - * @param {Foo} a - * @returns {Foo} - */ export function echo_struct(a: Foo): Foo; -/** - * @param {(Foo)[]} a - * @returns {(Foo)[]} - */ export function echo_vec_struct(a: (Foo)[]): (Foo)[]; -/** - * @param {number | undefined | null} [a] - * @returns {number | undefined} - */ -export function echo_option_u8(a?: number): number | undefined; -/** - * @param {number | undefined | null} [a] - * @returns {number | undefined} - */ -export function echo_option_i8(a?: number): number | undefined; -/** - * @param {number | undefined | null} [a] - * @returns {number | undefined} - */ -export function echo_option_u16(a?: number): number | undefined; -/** - * @param {number | undefined | null} [a] - * @returns {number | undefined} - */ -export function echo_option_i16(a?: number): number | undefined; -/** - * @param {number | undefined | null} [a] - * @returns {number | undefined} - */ -export function echo_option_u32(a?: number): number | undefined; -/** - * @param {number | undefined | null} [a] - * @returns {number | undefined} - */ -export function echo_option_i32(a?: number): number | undefined; -/** - * @param {bigint | undefined | null} [a] - * @returns {bigint | undefined} - */ -export function echo_option_u64(a?: bigint): bigint | undefined; -/** - * @param {bigint | undefined | null} [a] - * @returns {bigint | undefined} - */ -export function echo_option_i64(a?: bigint): bigint | undefined; -/** - * @param {number | undefined | null} [a] - * @returns {number | undefined} - */ -export function echo_option_usize(a?: number): number | undefined; -/** - * @param {number | undefined | null} [a] - * @returns {number | undefined} - */ -export function echo_option_isize(a?: number): number | undefined; -/** - * @param {number | undefined | null} [a] - * @returns {number | undefined} - */ -export function echo_option_f32(a?: number): number | undefined; -/** - * @param {number | undefined | null} [a] - * @returns {number | undefined} - */ -export function echo_option_f64(a?: number): number | undefined; -/** - * @param {boolean | undefined | null} [a] - * @returns {boolean | undefined} - */ -export function echo_option_bool(a?: boolean): boolean | undefined; -/** - * @param {string | undefined | null} [a] - * @returns {string | undefined} - */ -export function echo_option_char(a?: string): string | undefined; -/** - * @param {string | undefined | null} [a] - * @returns {string | undefined} - */ -export function echo_option_string(a?: string): string | undefined; -/** - * @param {Uint8Array | undefined | null} [a] - * @returns {Uint8Array | undefined} - */ -export function echo_option_vec_u8(a?: Uint8Array): Uint8Array | undefined; -/** - * @param {Foo | undefined | null} [a] - * @returns {Foo | undefined} - */ -export function echo_option_struct(a?: Foo): Foo | undefined; -/** - * @param {(Foo)[] | undefined | null} [a] - * @returns {(Foo)[] | undefined} - */ -export function echo_option_vec_struct(a?: (Foo)[]): (Foo)[] | undefined; +export function echo_option_u8(a?: number | null): number | undefined; +export function echo_option_i8(a?: number | null): number | undefined; +export function echo_option_u16(a?: number | null): number | undefined; +export function echo_option_i16(a?: number | null): number | undefined; +export function echo_option_u32(a?: number | null): number | undefined; +export function echo_option_i32(a?: number | null): number | undefined; +export function echo_option_u64(a?: bigint | null): bigint | undefined; +export function echo_option_i64(a?: bigint | null): bigint | undefined; +export function echo_option_usize(a?: number | null): number | undefined; +export function echo_option_isize(a?: number | null): number | undefined; +export function echo_option_f32(a?: number | null): number | undefined; +export function echo_option_f64(a?: number | null): number | undefined; +export function echo_option_bool(a?: boolean | null): boolean | undefined; +export function echo_option_char(a?: string | null): string | undefined; +export function echo_option_string(a?: string | null): string | undefined; +export function echo_option_vec_u8(a?: Uint8Array | null): Uint8Array | undefined; +export function echo_option_struct(a?: Foo | null): Foo | undefined; +export function echo_option_vec_struct(a?: (Foo)[] | null): (Foo)[] | undefined; export class Foo { free(): void; } diff --git a/crates/cli/tests/reference/enums.d.ts b/crates/cli/tests/reference/enums.d.ts index 50e7c2d1270..d79b062fd73 100644 --- a/crates/cli/tests/reference/enums.d.ts +++ b/crates/cli/tests/reference/enums.d.ts @@ -1,16 +1,12 @@ /* tslint:disable */ /* eslint-disable */ export function enum_echo(color: Color): Color; -/** - * @param {Color | undefined | null} [color] - * @returns {Color | undefined} - */ -export function option_enum_echo(color?: Color): Color | undefined; +export function option_enum_echo(color?: Color | null): Color | undefined; export function get_name(color: Color): ColorName; +export function option_string_enum_echo(color?: ColorName | null): ColorName | undefined; /** - * @param {ColorName | undefined | null} [color] + * A color. */ -export function option_string_enum_echo(color?: ColorName): ColorName | undefined; export enum Color { /** * Green as a leaf. From 841f802449bc3cc9fabb99d9565cbccd38d92a47 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Sun, 13 Oct 2024 22:41:17 +0200 Subject: [PATCH 06/14] Remove `| undefined` from JSDoc types --- crates/cli-support/src/js/binding.rs | 8 ++++--- crates/cli/tests/reference/echo.js | 36 ++++++++++++++-------------- crates/cli/tests/reference/enums.js | 4 ++-- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/crates/cli-support/src/js/binding.rs b/crates/cli-support/src/js/binding.rs index 9b1df3e2025..d3b50b7d4d5 100644 --- a/crates/cli-support/src/js/binding.rs +++ b/crates/cli-support/src/js/binding.rs @@ -393,16 +393,18 @@ impl<'a, 'b> Builder<'a, 'b> { for (name, ty) in fn_arg_names.iter().zip(arg_tys).rev() { let mut arg = "@param {".to_string(); - adapter2ts(ty, TypePosition::Argument, &mut arg, None); - arg.push_str("} "); match ty { - AdapterType::Option(..) if omittable => { + AdapterType::Option(ty) if omittable => { + adapter2ts(ty, TypePosition::Argument, &mut arg, None); + arg.push_str(" | null} "); arg.push('['); arg.push_str(name); arg.push(']'); } _ => { omittable = false; + adapter2ts(ty, TypePosition::Argument, &mut arg, None); + arg.push_str("} "); arg.push_str(name); } } diff --git a/crates/cli/tests/reference/echo.js b/crates/cli/tests/reference/echo.js index f12c6d807d6..f2761d935a4 100644 --- a/crates/cli/tests/reference/echo.js +++ b/crates/cli/tests/reference/echo.js @@ -429,7 +429,7 @@ function isLikeNone(x) { return x === undefined || x === null; } /** - * @param {number | undefined | null} [a] + * @param {number | null} [a] * @returns {number | undefined} */ export function echo_option_u8(a) { @@ -438,7 +438,7 @@ export function echo_option_u8(a) { } /** - * @param {number | undefined | null} [a] + * @param {number | null} [a] * @returns {number | undefined} */ export function echo_option_i8(a) { @@ -447,7 +447,7 @@ export function echo_option_i8(a) { } /** - * @param {number | undefined | null} [a] + * @param {number | null} [a] * @returns {number | undefined} */ export function echo_option_u16(a) { @@ -456,7 +456,7 @@ export function echo_option_u16(a) { } /** - * @param {number | undefined | null} [a] + * @param {number | null} [a] * @returns {number | undefined} */ export function echo_option_i16(a) { @@ -465,7 +465,7 @@ export function echo_option_i16(a) { } /** - * @param {number | undefined | null} [a] + * @param {number | null} [a] * @returns {number | undefined} */ export function echo_option_u32(a) { @@ -481,7 +481,7 @@ export function echo_option_u32(a) { } /** - * @param {number | undefined | null} [a] + * @param {number | null} [a] * @returns {number | undefined} */ export function echo_option_i32(a) { @@ -497,7 +497,7 @@ export function echo_option_i32(a) { } /** - * @param {bigint | undefined | null} [a] + * @param {bigint | null} [a] * @returns {bigint | undefined} */ export function echo_option_u64(a) { @@ -513,7 +513,7 @@ export function echo_option_u64(a) { } /** - * @param {bigint | undefined | null} [a] + * @param {bigint | null} [a] * @returns {bigint | undefined} */ export function echo_option_i64(a) { @@ -529,7 +529,7 @@ export function echo_option_i64(a) { } /** - * @param {number | undefined | null} [a] + * @param {number | null} [a] * @returns {number | undefined} */ export function echo_option_usize(a) { @@ -545,7 +545,7 @@ export function echo_option_usize(a) { } /** - * @param {number | undefined | null} [a] + * @param {number | null} [a] * @returns {number | undefined} */ export function echo_option_isize(a) { @@ -561,7 +561,7 @@ export function echo_option_isize(a) { } /** - * @param {number | undefined | null} [a] + * @param {number | null} [a] * @returns {number | undefined} */ export function echo_option_f32(a) { @@ -577,7 +577,7 @@ export function echo_option_f32(a) { } /** - * @param {number | undefined | null} [a] + * @param {number | null} [a] * @returns {number | undefined} */ export function echo_option_f64(a) { @@ -593,7 +593,7 @@ export function echo_option_f64(a) { } /** - * @param {boolean | undefined | null} [a] + * @param {boolean | null} [a] * @returns {boolean | undefined} */ export function echo_option_bool(a) { @@ -602,7 +602,7 @@ export function echo_option_bool(a) { } /** - * @param {string | undefined | null} [a] + * @param {string | null} [a] * @returns {string | undefined} */ export function echo_option_char(a) { @@ -613,7 +613,7 @@ return ret === 0xFFFFFF ? undefined : String.fromCodePoint(ret); } /** - * @param {string | undefined | null} [a] + * @param {string | null} [a] * @returns {string | undefined} */ export function echo_option_string(a) { @@ -636,7 +636,7 @@ export function echo_option_string(a) { } /** - * @param {Uint8Array | undefined | null} [a] + * @param {Uint8Array | null} [a] * @returns {Uint8Array | undefined} */ export function echo_option_vec_u8(a) { @@ -659,7 +659,7 @@ export function echo_option_vec_u8(a) { } /** - * @param {Foo | undefined | null} [a] + * @param {Foo | null} [a] * @returns {Foo | undefined} */ export function echo_option_struct(a) { @@ -673,7 +673,7 @@ export function echo_option_struct(a) { } /** - * @param {(Foo)[] | undefined | null} [a] + * @param {(Foo)[] | null} [a] * @returns {(Foo)[] | undefined} */ export function echo_option_vec_struct(a) { diff --git a/crates/cli/tests/reference/enums.js b/crates/cli/tests/reference/enums.js index f3fcd999437..beb1aa91457 100644 --- a/crates/cli/tests/reference/enums.js +++ b/crates/cli/tests/reference/enums.js @@ -36,7 +36,7 @@ function isLikeNone(x) { return x === undefined || x === null; } /** - * @param {Color | undefined | null} [color] + * @param {Color | null} [color] * @returns {Color | undefined} */ export function option_enum_echo(color) { @@ -54,7 +54,7 @@ export function get_name(color) { } /** - * @param {ColorName | undefined | null} [color] + * @param {ColorName | null} [color] * @returns {ColorName | undefined} */ export function option_string_enum_echo(color) { From 90f1efb3a5304db55219baa3ffb49d5b7bcdfb12 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Tue, 15 Oct 2024 15:23:08 +0200 Subject: [PATCH 07/14] Update ref --- crates/cli/tests/reference/echo.js | 57 +++++++++++++++--------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/crates/cli/tests/reference/echo.js b/crates/cli/tests/reference/echo.js index f2761d935a4..59a98bcc323 100644 --- a/crates/cli/tests/reference/echo.js +++ b/crates/cli/tests/reference/echo.js @@ -8,8 +8,31 @@ const heap = new Array(128).fill(undefined); heap.push(undefined, null, true, false); +let heap_next = heap.length; + +function addHeapObject(obj) { + if (heap_next === heap.length) heap.push(heap.length + 1); + const idx = heap_next; + heap_next = heap[idx]; + + heap[idx] = obj; + return idx; +} + function getObject(idx) { return heap[idx]; } +function dropObject(idx) { + if (idx < 132) return; + heap[idx] = heap_next; + heap_next = idx; +} + +function takeObject(idx) { + const ret = getObject(idx); + dropObject(idx); + return ret; +} + function debugString(val) { // primitive types const type = typeof val; @@ -51,7 +74,7 @@ function debugString(val) { // Test for built-in const builtInMatches = /\[object ([^\]]+)\]/.exec(toString.call(val)); let className; - if (builtInMatches.length > 1) { + if (builtInMatches && builtInMatches.length > 1) { className = builtInMatches[1]; } else { // Failed to match the standard '[object ClassName]' @@ -161,29 +184,6 @@ function getStringFromWasm0(ptr, len) { ptr = ptr >>> 0; return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); } - -let heap_next = heap.length; - -function dropObject(idx) { - if (idx < 132) return; - heap[idx] = heap_next; - heap_next = idx; -} - -function takeObject(idx) { - const ret = getObject(idx); - dropObject(idx); - return ret; -} - -function addHeapObject(obj) { - if (heap_next === heap.length) heap.push(heap.length + 1); - const idx = heap_next; - heap_next = heap[idx]; - - heap[idx] = obj; - return idx; -} /** * @param {number} a * @returns {number} @@ -373,7 +373,6 @@ function _assertClass(instance, klass) { if (!(instance instanceof klass)) { throw new Error(`expected instance of ${klass.name}`); } - return instance.ptr; } /** * @param {Foo} a @@ -747,11 +746,11 @@ export function __wbindgen_debug_string(arg0, arg1) { getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); }; -export function __wbindgen_throw(arg0, arg1) { - throw new Error(getStringFromWasm0(arg0, arg1)); -}; - export function __wbindgen_object_drop_ref(arg0) { takeObject(arg0); }; +export function __wbindgen_throw(arg0, arg1) { + throw new Error(getStringFromWasm0(arg0, arg1)); +}; + From b712add1d6c68b462460862d884209c0e3859041 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Wed, 16 Oct 2024 21:55:47 +0200 Subject: [PATCH 08/14] Updated refs --- crates/cli/tests/reference/echo.js | 55 ++++++----------------------- crates/cli/tests/reference/echo.wat | 55 ++++++++++++++--------------- 2 files changed, 37 insertions(+), 73 deletions(-) diff --git a/crates/cli/tests/reference/echo.js b/crates/cli/tests/reference/echo.js index 59a98bcc323..eee82f7dc9b 100644 --- a/crates/cli/tests/reference/echo.js +++ b/crates/cli/tests/reference/echo.js @@ -468,15 +468,8 @@ export function echo_option_i16(a) { * @returns {number | undefined} */ export function echo_option_u32(a) { - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - wasm.echo_option_u32(retptr, !isLikeNone(a), isLikeNone(a) ? 0 : a); - var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); - var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); - return r0 === 0 ? undefined : r1 >>> 0; - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); - } + const ret = wasm.echo_option_u32(isLikeNone(a) ? 0x100000001 : (a) >>> 0); + return ret === 0x100000001 ? undefined : ret; } /** @@ -484,15 +477,8 @@ export function echo_option_u32(a) { * @returns {number | undefined} */ export function echo_option_i32(a) { - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - wasm.echo_option_i32(retptr, !isLikeNone(a), isLikeNone(a) ? 0 : a); - var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); - var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); - return r0 === 0 ? undefined : r1; - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); - } + const ret = wasm.echo_option_i32(isLikeNone(a) ? 0x100000001 : (a) >> 0); + return ret === 0x100000001 ? undefined : ret; } /** @@ -532,15 +518,8 @@ export function echo_option_i64(a) { * @returns {number | undefined} */ export function echo_option_usize(a) { - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - wasm.echo_option_usize(retptr, !isLikeNone(a), isLikeNone(a) ? 0 : a); - var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); - var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); - return r0 === 0 ? undefined : r1 >>> 0; - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); - } + const ret = wasm.echo_option_usize(isLikeNone(a) ? 0x100000001 : (a) >>> 0); + return ret === 0x100000001 ? undefined : ret; } /** @@ -548,15 +527,8 @@ export function echo_option_usize(a) { * @returns {number | undefined} */ export function echo_option_isize(a) { - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - wasm.echo_option_isize(retptr, !isLikeNone(a), isLikeNone(a) ? 0 : a); - var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); - var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); - return r0 === 0 ? undefined : r1; - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); - } + const ret = wasm.echo_option_isize(isLikeNone(a) ? 0x100000001 : (a) >> 0); + return ret === 0x100000001 ? undefined : ret; } /** @@ -564,15 +536,8 @@ export function echo_option_isize(a) { * @returns {number | undefined} */ export function echo_option_f32(a) { - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - wasm.echo_option_f32(retptr, !isLikeNone(a), isLikeNone(a) ? 0 : a); - var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); - var r1 = getDataViewMemory0().getFloat32(retptr + 4 * 1, true); - return r0 === 0 ? undefined : r1; - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); - } + const ret = wasm.echo_option_f32(isLikeNone(a) ? 0x100000001 : Math.fround(a)); + return ret === 0x100000001 ? undefined : ret; } /** diff --git a/crates/cli/tests/reference/echo.wat b/crates/cli/tests/reference/echo.wat index ee89000c6af..d5d4addeb39 100644 --- a/crates/cli/tests/reference/echo.wat +++ b/crates/cli/tests/reference/echo.wat @@ -5,32 +5,31 @@ (type (;3;) (func (param i32 i32 i32))) (type (;4;) (func (param i32 i32 i32 i32) (result i32))) (type (;5;) (func (param i32 i32 i64))) - (type (;6;) (func (param i32 i32 f32))) - (type (;7;) (func (param i32 i32 f64))) - (type (;8;) (func (param i64) (result i64))) - (type (;9;) (func (param f32) (result f32))) - (type (;10;) (func (param f64) (result f64))) + (type (;6;) (func (param i32 i32 f64))) + (type (;7;) (func (param i64) (result i64))) + (type (;8;) (func (param f32) (result f32))) + (type (;9;) (func (param f64) (result f64))) (func $__wbindgen_realloc (;0;) (type 4) (param i32 i32 i32 i32) (result i32)) (func $__wbindgen_malloc (;1;) (type 2) (param i32 i32) (result i32)) - (func $echo_option_u32 (;2;) (type 3) (param i32 i32 i32)) - (func $echo_option_i32 (;3;) (type 3) (param i32 i32 i32)) - (func $echo_option_u64 (;4;) (type 5) (param i32 i32 i64)) - (func $echo_option_i64 (;5;) (type 5) (param i32 i32 i64)) - (func $echo_option_usize (;6;) (type 3) (param i32 i32 i32)) - (func $echo_option_isize (;7;) (type 3) (param i32 i32 i32)) - (func $echo_option_f32 (;8;) (type 6) (param i32 i32 f32)) - (func $echo_option_f64 (;9;) (type 7) (param i32 i32 f64)) - (func $echo_string (;10;) (type 3) (param i32 i32 i32)) - (func $echo_vec_u8 (;11;) (type 3) (param i32 i32 i32)) - (func $echo_vec_struct (;12;) (type 3) (param i32 i32 i32)) - (func $echo_option_string (;13;) (type 3) (param i32 i32 i32)) - (func $echo_option_vec_u8 (;14;) (type 3) (param i32 i32 i32)) - (func $echo_option_vec_struct (;15;) (type 3) (param i32 i32 i32)) - (func $echo_option_u8 (;16;) (type 0) (param i32) (result i32)) - (func $echo_option_i8 (;17;) (type 0) (param i32) (result i32)) - (func $echo_option_u16 (;18;) (type 0) (param i32) (result i32)) - (func $echo_option_i16 (;19;) (type 0) (param i32) (result i32)) - (func $echo_option_struct (;20;) (type 0) (param i32) (result i32)) + (func $echo_option_u64 (;2;) (type 5) (param i32 i32 i64)) + (func $echo_option_i64 (;3;) (type 5) (param i32 i32 i64)) + (func $echo_option_f64 (;4;) (type 6) (param i32 i32 f64)) + (func $echo_string (;5;) (type 3) (param i32 i32 i32)) + (func $echo_vec_u8 (;6;) (type 3) (param i32 i32 i32)) + (func $echo_vec_struct (;7;) (type 3) (param i32 i32 i32)) + (func $echo_option_string (;8;) (type 3) (param i32 i32 i32)) + (func $echo_option_vec_u8 (;9;) (type 3) (param i32 i32 i32)) + (func $echo_option_vec_struct (;10;) (type 3) (param i32 i32 i32)) + (func $echo_option_u8 (;11;) (type 0) (param i32) (result i32)) + (func $echo_option_i8 (;12;) (type 0) (param i32) (result i32)) + (func $echo_option_u16 (;13;) (type 0) (param i32) (result i32)) + (func $echo_option_i16 (;14;) (type 0) (param i32) (result i32)) + (func $echo_option_struct (;15;) (type 0) (param i32) (result i32)) + (func $echo_option_u32 (;16;) (type 9) (param f64) (result f64)) + (func $echo_option_i32 (;17;) (type 9) (param f64) (result f64)) + (func $echo_option_usize (;18;) (type 9) (param f64) (result f64)) + (func $echo_option_isize (;19;) (type 9) (param f64) (result f64)) + (func $echo_option_f32 (;20;) (type 9) (param f64) (result f64)) (func $echo_u8 (;21;) (type 0) (param i32) (result i32)) (func $echo_i8 (;22;) (type 0) (param i32) (result i32)) (func $echo_u16 (;23;) (type 0) (param i32) (result i32)) @@ -39,15 +38,15 @@ (func $echo_i32 (;26;) (type 0) (param i32) (result i32)) (func $echo_usize (;27;) (type 0) (param i32) (result i32)) (func $echo_isize (;28;) (type 0) (param i32) (result i32)) - (func $echo_f32 (;29;) (type 9) (param f32) (result f32)) + (func $echo_f32 (;29;) (type 8) (param f32) (result f32)) (func $echo_bool (;30;) (type 0) (param i32) (result i32)) (func $echo_char (;31;) (type 0) (param i32) (result i32)) (func $echo_struct (;32;) (type 0) (param i32) (result i32)) (func $echo_option_bool (;33;) (type 0) (param i32) (result i32)) (func $echo_option_char (;34;) (type 0) (param i32) (result i32)) - (func $echo_u64 (;35;) (type 8) (param i64) (result i64)) - (func $echo_i64 (;36;) (type 8) (param i64) (result i64)) - (func $echo_f64 (;37;) (type 10) (param f64) (result f64)) + (func $echo_u64 (;35;) (type 7) (param i64) (result i64)) + (func $echo_i64 (;36;) (type 7) (param i64) (result i64)) + (func $echo_f64 (;37;) (type 9) (param f64) (result f64)) (func $__wbindgen_free (;38;) (type 3) (param i32 i32 i32)) (func $__wbg_foo_free (;39;) (type 1) (param i32 i32)) (func $__wbindgen_add_to_stack_pointer (;40;) (type 0) (param i32) (result i32)) From e9cedd490f2b469b86d669fa3a3c8bce13cdc3e0 Mon Sep 17 00:00:00 2001 From: Michael Schmidt Date: Thu, 17 Oct 2024 10:41:55 +0200 Subject: [PATCH 09/14] Update crates/cli-support/src/js/binding.rs Co-authored-by: daxpedda --- crates/cli-support/src/js/binding.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/cli-support/src/js/binding.rs b/crates/cli-support/src/js/binding.rs index f4df0119788..95775ee8d05 100644 --- a/crates/cli-support/src/js/binding.rs +++ b/crates/cli-support/src/js/binding.rs @@ -1528,7 +1528,7 @@ fn adapter2ts( AdapterType::Option(ty) => { adapter2ts(ty, position, dst, refs); dst.push_str(match position { - TypePosition::Argument => " | undefined | null", + TypePosition::Argument => unreachable!(), TypePosition::Return => " | undefined", }); } From fd337f21a897c78c03a22327c5016e9bf9ccf040 Mon Sep 17 00:00:00 2001 From: RunDevelopment Date: Tue, 29 Oct 2024 11:34:40 +0100 Subject: [PATCH 10/14] Updated refs --- crates/cli/tests/reference/getter-setter.d.ts | 13 +++-- crates/cli/tests/reference/getter-setter.js | 58 +++++-------------- crates/cli/tests/reference/getter-setter.wat | 36 ++++++------ 3 files changed, 40 insertions(+), 67 deletions(-) diff --git a/crates/cli/tests/reference/getter-setter.d.ts b/crates/cli/tests/reference/getter-setter.d.ts index 4c207c3c7e6..9719e772da8 100644 --- a/crates/cli/tests/reference/getter-setter.d.ts +++ b/crates/cli/tests/reference/getter-setter.d.ts @@ -3,10 +3,12 @@ export class Foo { free(): void; x: number; - y?: number; - z?: number; + get y(): number | undefined; + set y(value: number | null | undefined); + get z(): number | undefined; + set z(value: number | null | undefined); readonly lone_getter: number | undefined; - set lone_setter(value: number | undefined); + set lone_setter(value: number | null | undefined); /** * You will only read numbers. */ @@ -16,10 +18,11 @@ export class Foo { * * Yes, this is totally fine in JS. */ - set weird(value: string | undefined); + set weird(value: string | null | undefined); /** * There can be static getters and setters too, and they can even have the * same name as instance getters and setters. */ - static x?: boolean; + static get x(): boolean | undefined; + static set x(value: boolean | null | undefined); } diff --git a/crates/cli/tests/reference/getter-setter.js b/crates/cli/tests/reference/getter-setter.js index 789dfb2787e..32fa6c4cb97 100644 --- a/crates/cli/tests/reference/getter-setter.js +++ b/crates/cli/tests/reference/getter-setter.js @@ -24,15 +24,6 @@ function getStringFromWasm0(ptr, len) { return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); } -let cachedDataViewMemory0 = null; - -function getDataViewMemory0() { - if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) { - cachedDataViewMemory0 = new DataView(wasm.memory.buffer); - } - return cachedDataViewMemory0; -} - function isLikeNone(x) { return x === undefined || x === null; } @@ -129,61 +120,40 @@ export class Foo { * @returns {number | undefined} */ get y() { - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - wasm.__wbg_get_foo_y(retptr, this.__wbg_ptr); - var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); - var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); - return r0 === 0 ? undefined : r1 >>> 0; - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); - } + const ret = wasm.__wbg_get_foo_y(this.__wbg_ptr); + return ret === 0x100000001 ? undefined : ret; } /** - * @param {number | undefined} [arg0] + * @param {number | null} [arg0] */ set y(arg0) { - wasm.__wbg_set_foo_y(this.__wbg_ptr, !isLikeNone(arg0), isLikeNone(arg0) ? 0 : arg0); + wasm.__wbg_set_foo_y(this.__wbg_ptr, isLikeNone(arg0) ? 0x100000001 : (arg0) >>> 0); } /** * @returns {number | undefined} */ get z() { - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - wasm.foo_z(retptr, this.__wbg_ptr); - var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); - var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); - return r0 === 0 ? undefined : r1 >>> 0; - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); - } + const ret = wasm.foo_z(this.__wbg_ptr); + return ret === 0x100000001 ? undefined : ret; } /** - * @param {number | undefined} [z] + * @param {number | null} [z] */ set z(z) { - wasm.foo_set_z(this.__wbg_ptr, !isLikeNone(z), isLikeNone(z) ? 0 : z); + wasm.foo_set_z(this.__wbg_ptr, isLikeNone(z) ? 0x100000001 : (z) >>> 0); } /** * @returns {number | undefined} */ get lone_getter() { - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - wasm.foo_lone_getter(retptr, this.__wbg_ptr); - var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); - var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); - return r0 === 0 ? undefined : r1 >>> 0; - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); - } + const ret = wasm.foo_lone_getter(this.__wbg_ptr); + return ret === 0x100000001 ? undefined : ret; } /** - * @param {number | undefined} [value] + * @param {number | null} [value] */ set lone_setter(value) { - wasm.foo_set_lone_setter(this.__wbg_ptr, !isLikeNone(value), isLikeNone(value) ? 0 : value); + wasm.foo_set_lone_setter(this.__wbg_ptr, isLikeNone(value) ? 0x100000001 : (value) >>> 0); } /** * You will only read numbers. @@ -197,7 +167,7 @@ export class Foo { * But you must write strings. * * Yes, this is totally fine in JS. - * @param {string | undefined} [value] + * @param {string | null} [value] */ set weird(value) { var ptr0 = isLikeNone(value) ? 0 : passStringToWasm0(value, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); @@ -214,7 +184,7 @@ export class Foo { return ret === 0xFFFFFF ? undefined : ret !== 0; } /** - * @param {boolean | undefined} [value] + * @param {boolean | null} [value] */ static set x(value) { wasm.foo_set_x_static(isLikeNone(value) ? 0xFFFFFF : value ? 1 : 0); diff --git a/crates/cli/tests/reference/getter-setter.wat b/crates/cli/tests/reference/getter-setter.wat index 9688f99b7f2..6deffc9b7df 100644 --- a/crates/cli/tests/reference/getter-setter.wat +++ b/crates/cli/tests/reference/getter-setter.wat @@ -2,26 +2,27 @@ (type (;0;) (func (result i32))) (type (;1;) (func (param i32))) (type (;2;) (func (param i32) (result i32))) - (type (;3;) (func (param i32 i32))) - (type (;4;) (func (param i32 i32) (result i32))) - (type (;5;) (func (param i32 i32 i32))) - (type (;6;) (func (param i32 i32 i32 i32) (result i32))) - (func $__wbindgen_realloc (;0;) (type 6) (param i32 i32 i32 i32) (result i32)) - (func $__wbindgen_malloc (;1;) (type 4) (param i32 i32) (result i32)) - (func $__wbg_set_foo_y (;2;) (type 5) (param i32 i32 i32)) - (func $__wbg_get_foo_y (;3;) (type 3) (param i32 i32)) - (func $foo_z (;4;) (type 3) (param i32 i32)) - (func $foo_lone_getter (;5;) (type 3) (param i32 i32)) - (func $foo_set_weird (;6;) (type 5) (param i32 i32 i32)) - (func $foo_set_z (;7;) (type 5) (param i32 i32 i32)) - (func $foo_set_lone_setter (;8;) (type 5) (param i32 i32 i32)) - (func $__wbg_get_foo_x (;9;) (type 2) (param i32) (result i32)) - (func $__wbg_set_foo_x (;10;) (type 3) (param i32 i32)) + (type (;3;) (func (param i32) (result f64))) + (type (;4;) (func (param i32 i32))) + (type (;5;) (func (param i32 i32) (result i32))) + (type (;6;) (func (param i32 i32 i32))) + (type (;7;) (func (param i32 i32 i32 i32) (result i32))) + (type (;8;) (func (param i32 f64))) + (func $__wbindgen_realloc (;0;) (type 7) (param i32 i32 i32 i32) (result i32)) + (func $__wbindgen_malloc (;1;) (type 5) (param i32 i32) (result i32)) + (func $foo_set_weird (;2;) (type 6) (param i32 i32 i32)) + (func $__wbg_set_foo_y (;3;) (type 8) (param i32 f64)) + (func $__wbg_get_foo_y (;4;) (type 3) (param i32) (result f64)) + (func $__wbg_get_foo_x (;5;) (type 2) (param i32) (result i32)) + (func $foo_set_z (;6;) (type 8) (param i32 f64)) + (func $foo_set_lone_setter (;7;) (type 8) (param i32 f64)) + (func $foo_z (;8;) (type 3) (param i32) (result f64)) + (func $foo_lone_getter (;9;) (type 3) (param i32) (result f64)) + (func $__wbg_set_foo_x (;10;) (type 4) (param i32 i32)) (func $foo_weird (;11;) (type 2) (param i32) (result i32)) (func $foo_x_static (;12;) (type 0) (result i32)) - (func $__wbg_foo_free (;13;) (type 3) (param i32 i32)) + (func $__wbg_foo_free (;13;) (type 4) (param i32 i32)) (func $foo_set_x_static (;14;) (type 1) (param i32)) - (func $__wbindgen_add_to_stack_pointer (;15;) (type 2) (param i32) (result i32)) (memory (;0;) 17) (export "memory" (memory 0)) (export "__wbg_foo_free" (func $__wbg_foo_free)) @@ -37,7 +38,6 @@ (export "foo_set_weird" (func $foo_set_weird)) (export "foo_x_static" (func $foo_x_static)) (export "foo_set_x_static" (func $foo_set_x_static)) - (export "__wbindgen_add_to_stack_pointer" (func $__wbindgen_add_to_stack_pointer)) (export "__wbindgen_malloc" (func $__wbindgen_malloc)) (export "__wbindgen_realloc" (func $__wbindgen_realloc)) (@custom "target_features" (after code) "\02+\0fmutable-globals+\08sign-ext") From d4ff7fa36a01475575931deedd117f5c53112570 Mon Sep 17 00:00:00 2001 From: Michael Schmidt Date: Thu, 31 Oct 2024 20:51:16 +0100 Subject: [PATCH 11/14] Updated refs --- crates/cli/tests/reference/echo.js | 158 +++++++++------------------- crates/cli/tests/reference/echo.wat | 115 ++++++++++---------- 2 files changed, 106 insertions(+), 167 deletions(-) diff --git a/crates/cli/tests/reference/echo.js b/crates/cli/tests/reference/echo.js index eee82f7dc9b..fc384b416b5 100644 --- a/crates/cli/tests/reference/echo.js +++ b/crates/cli/tests/reference/echo.js @@ -323,17 +323,13 @@ export function echo_string(a) { let deferred2_0; let deferred2_1; try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); const ptr0 = passStringToWasm0(a, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); const len0 = WASM_VECTOR_LEN; - wasm.echo_string(retptr, ptr0, len0); - var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); - var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); - deferred2_0 = r0; - deferred2_1 = r1; - return getStringFromWasm0(r0, r1); + const ret = wasm.echo_string(ptr0, len0); + deferred2_0 = ret[0]; + deferred2_1 = ret[1]; + return getStringFromWasm0(ret[0], ret[1]); } finally { - wasm.__wbindgen_add_to_stack_pointer(16); wasm.__wbindgen_free(deferred2_0, deferred2_1, 1); } } @@ -354,19 +350,12 @@ function getArrayU8FromWasm0(ptr, len) { * @returns {Uint8Array} */ export function echo_vec_u8(a) { - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - const ptr0 = passArray8ToWasm0(a, wasm.__wbindgen_malloc); - const len0 = WASM_VECTOR_LEN; - wasm.echo_vec_u8(retptr, ptr0, len0); - var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); - var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); - var v2 = getArrayU8FromWasm0(r0, r1).slice(); - wasm.__wbindgen_free(r0, r1 * 1, 1); - return v2; - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); - } + const ptr0 = passArray8ToWasm0(a, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.echo_vec_u8(ptr0, len0); + var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); + return v2; } function _assertClass(instance, klass) { @@ -409,19 +398,12 @@ function getArrayJsValueFromWasm0(ptr, len) { * @returns {(Foo)[]} */ export function echo_vec_struct(a) { - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - const ptr0 = passArrayJsValueToWasm0(a, wasm.__wbindgen_malloc); - const len0 = WASM_VECTOR_LEN; - wasm.echo_vec_struct(retptr, ptr0, len0); - var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); - var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); - var v2 = getArrayJsValueFromWasm0(r0, r1).slice(); - wasm.__wbindgen_free(r0, r1 * 4, 4); - return v2; - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); - } + const ptr0 = passArrayJsValueToWasm0(a, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.echo_vec_struct(ptr0, len0); + var v2 = getArrayJsValueFromWasm0(ret[0], ret[1]).slice(); + wasm.__wbindgen_free(ret[0], ret[1] * 4, 4); + return v2; } function isLikeNone(x) { @@ -486,15 +468,8 @@ export function echo_option_i32(a) { * @returns {bigint | undefined} */ export function echo_option_u64(a) { - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - wasm.echo_option_u64(retptr, !isLikeNone(a), isLikeNone(a) ? BigInt(0) : a); - var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); - var r2 = getDataViewMemory0().getBigInt64(retptr + 8 * 1, true); - return r0 === 0 ? undefined : BigInt.asUintN(64, r2); - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); - } + const ret = wasm.echo_option_u64(!isLikeNone(a), isLikeNone(a) ? BigInt(0) : a); + return ret[0] === 0 ? undefined : BigInt.asUintN(64, ret[1]); } /** @@ -502,15 +477,8 @@ export function echo_option_u64(a) { * @returns {bigint | undefined} */ export function echo_option_i64(a) { - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - wasm.echo_option_i64(retptr, !isLikeNone(a), isLikeNone(a) ? BigInt(0) : a); - var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); - var r2 = getDataViewMemory0().getBigInt64(retptr + 8 * 1, true); - return r0 === 0 ? undefined : r2; - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); - } + const ret = wasm.echo_option_i64(!isLikeNone(a), isLikeNone(a) ? BigInt(0) : a); + return ret[0] === 0 ? undefined : ret[1]; } /** @@ -545,15 +513,8 @@ export function echo_option_f32(a) { * @returns {number | undefined} */ export function echo_option_f64(a) { - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - wasm.echo_option_f64(retptr, !isLikeNone(a), isLikeNone(a) ? 0 : a); - var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); - var r2 = getDataViewMemory0().getFloat64(retptr + 8 * 1, true); - return r0 === 0 ? undefined : r2; - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); - } + const ret = wasm.echo_option_f64(!isLikeNone(a), isLikeNone(a) ? 0 : a); + return ret[0] === 0 ? undefined : ret[1]; } /** @@ -571,9 +532,9 @@ export function echo_option_bool(a) { */ export function echo_option_char(a) { const char0 = isLikeNone(a) ? 0xFFFFFF : a.codePointAt(0); -if (char0 !== 0xFFFFFF) { _assertChar(char0); } -const ret = wasm.echo_option_char(char0); -return ret === 0xFFFFFF ? undefined : String.fromCodePoint(ret); + if (char0 !== 0xFFFFFF) { _assertChar(char0); } + const ret = wasm.echo_option_char(char0); + return ret === 0xFFFFFF ? undefined : String.fromCodePoint(ret); } /** @@ -581,22 +542,15 @@ return ret === 0xFFFFFF ? undefined : String.fromCodePoint(ret); * @returns {string | undefined} */ export function echo_option_string(a) { - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - var ptr0 = isLikeNone(a) ? 0 : passStringToWasm0(a, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); - var len0 = WASM_VECTOR_LEN; - wasm.echo_option_string(retptr, ptr0, len0); - var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); - var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); - let v2; - if (r0 !== 0) { - v2 = getStringFromWasm0(r0, r1).slice(); - wasm.__wbindgen_free(r0, r1 * 1, 1); - } - return v2; - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); + var ptr0 = isLikeNone(a) ? 0 : passStringToWasm0(a, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + var len0 = WASM_VECTOR_LEN; + const ret = wasm.echo_option_string(ptr0, len0); + let v2; + if (ret[0] !== 0) { + v2 = getStringFromWasm0(ret[0], ret[1]).slice(); + wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); } + return v2; } /** @@ -604,22 +558,15 @@ export function echo_option_string(a) { * @returns {Uint8Array | undefined} */ export function echo_option_vec_u8(a) { - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - var ptr0 = isLikeNone(a) ? 0 : passArray8ToWasm0(a, wasm.__wbindgen_malloc); - var len0 = WASM_VECTOR_LEN; - wasm.echo_option_vec_u8(retptr, ptr0, len0); - var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); - var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); - let v2; - if (r0 !== 0) { - v2 = getArrayU8FromWasm0(r0, r1).slice(); - wasm.__wbindgen_free(r0, r1 * 1, 1); - } - return v2; - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); + var ptr0 = isLikeNone(a) ? 0 : passArray8ToWasm0(a, wasm.__wbindgen_malloc); + var len0 = WASM_VECTOR_LEN; + const ret = wasm.echo_option_vec_u8(ptr0, len0); + let v2; + if (ret[0] !== 0) { + v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice(); + wasm.__wbindgen_free(ret[0], ret[1] * 1, 1); } + return v2; } /** @@ -641,22 +588,15 @@ export function echo_option_struct(a) { * @returns {(Foo)[] | undefined} */ export function echo_option_vec_struct(a) { - try { - const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); - var ptr0 = isLikeNone(a) ? 0 : passArrayJsValueToWasm0(a, wasm.__wbindgen_malloc); - var len0 = WASM_VECTOR_LEN; - wasm.echo_option_vec_struct(retptr, ptr0, len0); - var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); - var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); - let v2; - if (r0 !== 0) { - v2 = getArrayJsValueFromWasm0(r0, r1).slice(); - wasm.__wbindgen_free(r0, r1 * 4, 4); - } - return v2; - } finally { - wasm.__wbindgen_add_to_stack_pointer(16); + var ptr0 = isLikeNone(a) ? 0 : passArrayJsValueToWasm0(a, wasm.__wbindgen_malloc); + var len0 = WASM_VECTOR_LEN; + const ret = wasm.echo_option_vec_struct(ptr0, len0); + let v2; + if (ret[0] !== 0) { + v2 = getArrayJsValueFromWasm0(ret[0], ret[1]).slice(); + wasm.__wbindgen_free(ret[0], ret[1] * 4, 4); } + return v2; } const FooFinalization = (typeof FinalizationRegistry === 'undefined') diff --git a/crates/cli/tests/reference/echo.wat b/crates/cli/tests/reference/echo.wat index d5d4addeb39..9ebe444d049 100644 --- a/crates/cli/tests/reference/echo.wat +++ b/crates/cli/tests/reference/echo.wat @@ -2,54 +2,54 @@ (type (;0;) (func (param i32) (result i32))) (type (;1;) (func (param i32 i32))) (type (;2;) (func (param i32 i32) (result i32))) - (type (;3;) (func (param i32 i32 i32))) - (type (;4;) (func (param i32 i32 i32 i32) (result i32))) - (type (;5;) (func (param i32 i32 i64))) - (type (;6;) (func (param i32 i32 f64))) - (type (;7;) (func (param i64) (result i64))) - (type (;8;) (func (param f32) (result f32))) - (type (;9;) (func (param f64) (result f64))) - (func $__wbindgen_realloc (;0;) (type 4) (param i32 i32 i32 i32) (result i32)) + (type (;3;) (func (param i32 i32) (result i32 i32))) + (type (;4;) (func (param i32 i32 i32))) + (type (;5;) (func (param i32 i32 i32 i32) (result i32))) + (type (;6;) (func (param i32 i64) (result i32 i64))) + (type (;7;) (func (param i32 f64) (result i32 f64))) + (type (;8;) (func (param i64) (result i64))) + (type (;9;) (func (param f32) (result f32))) + (type (;10;) (func (param f64) (result f64))) + (func $__wbindgen_realloc (;0;) (type 5) (param i32 i32 i32 i32) (result i32)) (func $__wbindgen_malloc (;1;) (type 2) (param i32 i32) (result i32)) - (func $echo_option_u64 (;2;) (type 5) (param i32 i32 i64)) - (func $echo_option_i64 (;3;) (type 5) (param i32 i32 i64)) - (func $echo_option_f64 (;4;) (type 6) (param i32 i32 f64)) - (func $echo_string (;5;) (type 3) (param i32 i32 i32)) - (func $echo_vec_u8 (;6;) (type 3) (param i32 i32 i32)) - (func $echo_vec_struct (;7;) (type 3) (param i32 i32 i32)) - (func $echo_option_string (;8;) (type 3) (param i32 i32 i32)) - (func $echo_option_vec_u8 (;9;) (type 3) (param i32 i32 i32)) - (func $echo_option_vec_struct (;10;) (type 3) (param i32 i32 i32)) - (func $echo_option_u8 (;11;) (type 0) (param i32) (result i32)) - (func $echo_option_i8 (;12;) (type 0) (param i32) (result i32)) - (func $echo_option_u16 (;13;) (type 0) (param i32) (result i32)) - (func $echo_option_i16 (;14;) (type 0) (param i32) (result i32)) - (func $echo_option_struct (;15;) (type 0) (param i32) (result i32)) - (func $echo_option_u32 (;16;) (type 9) (param f64) (result f64)) - (func $echo_option_i32 (;17;) (type 9) (param f64) (result f64)) - (func $echo_option_usize (;18;) (type 9) (param f64) (result f64)) - (func $echo_option_isize (;19;) (type 9) (param f64) (result f64)) - (func $echo_option_f32 (;20;) (type 9) (param f64) (result f64)) - (func $echo_u8 (;21;) (type 0) (param i32) (result i32)) - (func $echo_i8 (;22;) (type 0) (param i32) (result i32)) - (func $echo_u16 (;23;) (type 0) (param i32) (result i32)) - (func $echo_i16 (;24;) (type 0) (param i32) (result i32)) - (func $echo_u32 (;25;) (type 0) (param i32) (result i32)) - (func $echo_i32 (;26;) (type 0) (param i32) (result i32)) - (func $echo_usize (;27;) (type 0) (param i32) (result i32)) - (func $echo_isize (;28;) (type 0) (param i32) (result i32)) - (func $echo_f32 (;29;) (type 8) (param f32) (result f32)) - (func $echo_bool (;30;) (type 0) (param i32) (result i32)) - (func $echo_char (;31;) (type 0) (param i32) (result i32)) - (func $echo_struct (;32;) (type 0) (param i32) (result i32)) - (func $echo_option_bool (;33;) (type 0) (param i32) (result i32)) - (func $echo_option_char (;34;) (type 0) (param i32) (result i32)) - (func $echo_u64 (;35;) (type 7) (param i64) (result i64)) - (func $echo_i64 (;36;) (type 7) (param i64) (result i64)) - (func $echo_f64 (;37;) (type 9) (param f64) (result f64)) - (func $__wbindgen_free (;38;) (type 3) (param i32 i32 i32)) - (func $__wbg_foo_free (;39;) (type 1) (param i32 i32)) - (func $__wbindgen_add_to_stack_pointer (;40;) (type 0) (param i32) (result i32)) + (func $echo_option_u8 (;2;) (type 0) (param i32) (result i32)) + (func $echo_option_i8 (;3;) (type 0) (param i32) (result i32)) + (func $echo_option_u16 (;4;) (type 0) (param i32) (result i32)) + (func $echo_option_i16 (;5;) (type 0) (param i32) (result i32)) + (func $echo_option_struct (;6;) (type 0) (param i32) (result i32)) + (func $echo_option_u32 (;7;) (type 10) (param f64) (result f64)) + (func $echo_option_i32 (;8;) (type 10) (param f64) (result f64)) + (func $echo_option_usize (;9;) (type 10) (param f64) (result f64)) + (func $echo_option_isize (;10;) (type 10) (param f64) (result f64)) + (func $echo_option_f32 (;11;) (type 10) (param f64) (result f64)) + (func $echo_u8 (;12;) (type 0) (param i32) (result i32)) + (func $echo_i8 (;13;) (type 0) (param i32) (result i32)) + (func $echo_u16 (;14;) (type 0) (param i32) (result i32)) + (func $echo_i16 (;15;) (type 0) (param i32) (result i32)) + (func $echo_u32 (;16;) (type 0) (param i32) (result i32)) + (func $echo_i32 (;17;) (type 0) (param i32) (result i32)) + (func $echo_usize (;18;) (type 0) (param i32) (result i32)) + (func $echo_isize (;19;) (type 0) (param i32) (result i32)) + (func $echo_f32 (;20;) (type 9) (param f32) (result f32)) + (func $echo_bool (;21;) (type 0) (param i32) (result i32)) + (func $echo_char (;22;) (type 0) (param i32) (result i32)) + (func $echo_struct (;23;) (type 0) (param i32) (result i32)) + (func $echo_option_bool (;24;) (type 0) (param i32) (result i32)) + (func $echo_option_char (;25;) (type 0) (param i32) (result i32)) + (func $echo_u64 (;26;) (type 8) (param i64) (result i64)) + (func $echo_i64 (;27;) (type 8) (param i64) (result i64)) + (func $echo_f64 (;28;) (type 10) (param f64) (result f64)) + (func $__wbindgen_free (;29;) (type 4) (param i32 i32 i32)) + (func $__wbg_foo_free (;30;) (type 1) (param i32 i32)) + (func $"echo_string multivalue shim" (;31;) (type 3) (param i32 i32) (result i32 i32)) + (func $"echo_vec_u8 multivalue shim" (;32;) (type 3) (param i32 i32) (result i32 i32)) + (func $"echo_vec_struct multivalue shim" (;33;) (type 3) (param i32 i32) (result i32 i32)) + (func $"echo_option_u64 multivalue shim" (;34;) (type 6) (param i32 i64) (result i32 i64)) + (func $"echo_option_i64 multivalue shim" (;35;) (type 6) (param i32 i64) (result i32 i64)) + (func $"echo_option_f64 multivalue shim" (;36;) (type 7) (param i32 f64) (result i32 f64)) + (func $"echo_option_string multivalue shim" (;37;) (type 3) (param i32 i32) (result i32 i32)) + (func $"echo_option_vec_u8 multivalue shim" (;38;) (type 3) (param i32 i32) (result i32 i32)) + (func $"echo_option_vec_struct multivalue shim" (;39;) (type 3) (param i32 i32) (result i32 i32)) (memory (;0;) 17) (export "memory" (memory 0)) (export "__wbg_foo_free" (func $__wbg_foo_free)) @@ -67,32 +67,31 @@ (export "echo_f64" (func $echo_f64)) (export "echo_bool" (func $echo_bool)) (export "echo_char" (func $echo_char)) - (export "echo_string" (func $echo_string)) - (export "echo_vec_u8" (func $echo_vec_u8)) + (export "echo_string" (func $"echo_string multivalue shim")) + (export "echo_vec_u8" (func $"echo_vec_u8 multivalue shim")) (export "echo_struct" (func $echo_struct)) - (export "echo_vec_struct" (func $echo_vec_struct)) + (export "echo_vec_struct" (func $"echo_vec_struct multivalue shim")) (export "echo_option_u8" (func $echo_option_u8)) (export "echo_option_i8" (func $echo_option_i8)) (export "echo_option_u16" (func $echo_option_u16)) (export "echo_option_i16" (func $echo_option_i16)) (export "echo_option_u32" (func $echo_option_u32)) (export "echo_option_i32" (func $echo_option_i32)) - (export "echo_option_u64" (func $echo_option_u64)) - (export "echo_option_i64" (func $echo_option_i64)) + (export "echo_option_u64" (func $"echo_option_u64 multivalue shim")) + (export "echo_option_i64" (func $"echo_option_i64 multivalue shim")) (export "echo_option_usize" (func $echo_option_usize)) (export "echo_option_isize" (func $echo_option_isize)) (export "echo_option_f32" (func $echo_option_f32)) - (export "echo_option_f64" (func $echo_option_f64)) + (export "echo_option_f64" (func $"echo_option_f64 multivalue shim")) (export "echo_option_bool" (func $echo_option_bool)) (export "echo_option_char" (func $echo_option_char)) - (export "echo_option_string" (func $echo_option_string)) - (export "echo_option_vec_u8" (func $echo_option_vec_u8)) + (export "echo_option_string" (func $"echo_option_string multivalue shim")) + (export "echo_option_vec_u8" (func $"echo_option_vec_u8 multivalue shim")) (export "echo_option_struct" (func $echo_option_struct)) - (export "echo_option_vec_struct" (func $echo_option_vec_struct)) + (export "echo_option_vec_struct" (func $"echo_option_vec_struct multivalue shim")) (export "__wbindgen_malloc" (func $__wbindgen_malloc)) (export "__wbindgen_realloc" (func $__wbindgen_realloc)) - (export "__wbindgen_add_to_stack_pointer" (func $__wbindgen_add_to_stack_pointer)) (export "__wbindgen_free" (func $__wbindgen_free)) - (@custom "target_features" (after code) "\02+\0fmutable-globals+\08sign-ext") + (@custom "target_features" (after code) "\04+\0amultivalue+\0fmutable-globals+\0freference-types+\08sign-ext") ) From b45cfb6ced0f591acdeb9578edc993cc13a09b57 Mon Sep 17 00:00:00 2001 From: Michael Schmidt Date: Thu, 31 Oct 2024 21:12:57 +0100 Subject: [PATCH 12/14] Unreachable has been reached --- crates/cli-support/src/js/binding.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/cli-support/src/js/binding.rs b/crates/cli-support/src/js/binding.rs index 95775ee8d05..83994981f41 100644 --- a/crates/cli-support/src/js/binding.rs +++ b/crates/cli-support/src/js/binding.rs @@ -1528,7 +1528,7 @@ fn adapter2ts( AdapterType::Option(ty) => { adapter2ts(ty, position, dst, refs); dst.push_str(match position { - TypePosition::Argument => unreachable!(), + TypePosition::Argument => " | null | undefined", TypePosition::Return => " | undefined", }); } From dd79ed464c87209ed4919b8f6a615e78b27e6105 Mon Sep 17 00:00:00 2001 From: Michael Schmidt Date: Thu, 31 Oct 2024 21:32:10 +0100 Subject: [PATCH 13/14] Fixed TS test --- crates/typescript-tests/src/optional_fields.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/crates/typescript-tests/src/optional_fields.ts b/crates/typescript-tests/src/optional_fields.ts index 61e1fc05b1b..8d1cf90c64c 100644 --- a/crates/typescript-tests/src/optional_fields.ts +++ b/crates/typescript-tests/src/optional_fields.ts @@ -1,3 +1,10 @@ import * as wbg from '../pkg/typescript_tests'; -const fields: wbg.Fields = { spaceboy: true, free: () => { } }; +const fields: wbg.Fields = null as unknown as wbg.Fields; + +// optional fields read T | undefined +const _hallo: boolean | undefined = fields.hallo; + +// and allow writing T | null | undefined +fields.hallo = undefined; +fields.hallo = null; From 54b685249b82a7370cf13201326f5fde8ee2b9b6 Mon Sep 17 00:00:00 2001 From: Michael Schmidt Date: Thu, 31 Oct 2024 21:37:00 +0100 Subject: [PATCH 14/14] Added test for optional args --- crates/cli/tests/reference/optional-args.d.ts | 4 +++ crates/cli/tests/reference/optional-args.js | 27 +++++++++++++++++++ crates/cli/tests/reference/optional-args.rs | 7 +++++ crates/cli/tests/reference/optional-args.wat | 12 +++++++++ 4 files changed, 50 insertions(+) create mode 100644 crates/cli/tests/reference/optional-args.d.ts create mode 100644 crates/cli/tests/reference/optional-args.js create mode 100644 crates/cli/tests/reference/optional-args.rs create mode 100644 crates/cli/tests/reference/optional-args.wat diff --git a/crates/cli/tests/reference/optional-args.d.ts b/crates/cli/tests/reference/optional-args.d.ts new file mode 100644 index 00000000000..4f156949356 --- /dev/null +++ b/crates/cli/tests/reference/optional-args.d.ts @@ -0,0 +1,4 @@ +/* tslint:disable */ +/* eslint-disable */ +export function all_optional(a?: number | null, b?: number | null, c?: number | null): void; +export function some_optional(a: number | null | undefined, b: number, c?: number | null): void; diff --git a/crates/cli/tests/reference/optional-args.js b/crates/cli/tests/reference/optional-args.js new file mode 100644 index 00000000000..b73d6117030 --- /dev/null +++ b/crates/cli/tests/reference/optional-args.js @@ -0,0 +1,27 @@ +let wasm; +export function __wbg_set_wasm(val) { + wasm = val; +} + + +function isLikeNone(x) { + return x === undefined || x === null; +} +/** + * @param {number | null} [a] + * @param {number | null} [b] + * @param {number | null} [c] + */ +export function all_optional(a, b, c) { + wasm.all_optional(isLikeNone(a) ? 0x100000001 : (a) >>> 0, isLikeNone(b) ? 0x100000001 : (b) >>> 0, isLikeNone(c) ? 0x100000001 : (c) >>> 0); +} + +/** + * @param {number | null | undefined} a + * @param {number} b + * @param {number | null} [c] + */ +export function some_optional(a, b, c) { + wasm.some_optional(isLikeNone(a) ? 0x100000001 : (a) >>> 0, b, isLikeNone(c) ? 0x100000001 : (c) >>> 0); +} + diff --git a/crates/cli/tests/reference/optional-args.rs b/crates/cli/tests/reference/optional-args.rs new file mode 100644 index 00000000000..bbc0fa81e39 --- /dev/null +++ b/crates/cli/tests/reference/optional-args.rs @@ -0,0 +1,7 @@ +use wasm_bindgen::prelude::*; + +#[wasm_bindgen] +pub fn all_optional(a: Option, b: Option, c: Option) {} + +#[wasm_bindgen] +pub fn some_optional(a: Option, b: u32, c: Option) {} diff --git a/crates/cli/tests/reference/optional-args.wat b/crates/cli/tests/reference/optional-args.wat new file mode 100644 index 00000000000..a18f4bc575c --- /dev/null +++ b/crates/cli/tests/reference/optional-args.wat @@ -0,0 +1,12 @@ +(module $reference_test.wasm + (type (;0;) (func (param f64 i32 f64))) + (type (;1;) (func (param f64 f64 f64))) + (func $all_optional (;0;) (type 1) (param f64 f64 f64)) + (func $some_optional (;1;) (type 0) (param f64 i32 f64)) + (memory (;0;) 17) + (export "memory" (memory 0)) + (export "all_optional" (func $all_optional)) + (export "some_optional" (func $some_optional)) + (@custom "target_features" (after code) "\04+\0amultivalue+\0fmutable-globals+\0freference-types+\08sign-ext") +) +