Skip to content

BridgeJS: Use a BigInt zero placeholder for Wasm i64 in generated JS#757

Merged
krodak merged 1 commit into
swiftwasm:mainfrom
PassiveLogic:kr/optional-scalar-zero-literal
Jun 8, 2026
Merged

BridgeJS: Use a BigInt zero placeholder for Wasm i64 in generated JS#757
krodak merged 1 commit into
swiftwasm:mainfrom
PassiveLogic:kr/optional-scalar-zero-literal

Conversation

@krodak
Copy link
Copy Markdown
Member

@krodak krodak commented Jun 8, 2026

Overview

A Wasm i64 parameter or return value is represented as a JavaScript BigInt. The generated JS, however, used a plain 0 as the placeholder for two cases:

  1. The absent value of an optional i64 parameter when lowering a call into a Wasm export (isSome ? v : 0).
  2. The error-path return of an imported thunk (the value returned from the catch block after an exception is recorded).

Passing a plain number 0 where the Wasm boundary expects an i64 raises TypeError: Cannot convert 0 to a BigInt. So calling an export with an optional Int64/UInt64 argument of null, or having an imported i64-returning function throw, crashed:

// before
instance.exports.bjs_roundTripOptionalInt64RawValueEnum(+isSome, isSome ? v : 0)   // 0 -> TypeError
// after
instance.exports.bjs_roundTripOptionalInt64RawValueEnum(+isSome, isSome ? v : 0n)

The fix emits 0n for i64 in both placeholder paths (the optional-parameter zero literal and the imported-thunk return placeholder); other core types are unchanged.

This was latent because the optional Int64/UInt64 round-trip tests only ever exercised the present case. The PR adds the none assertions that reproduce and lock down the fix.

This is the last in a short series of small, focused ABI fixes (optional @JS struct imports, case-enum imports, and now the i64 BigInt placeholder) that together unblock complete async support for non-ConvertibleToJSValue return types across all bridged stack types.

@krodak krodak requested a review from kateinoigakukun June 8, 2026 15:51
@krodak krodak self-assigned this Jun 8, 2026
A Wasm i64 parameter or return value is represented as a JavaScript BigInt.
The generated JS used a plain 0 as the placeholder for the absent case of an
optional i64 parameter (isSome ? v : 0) and for the error-path return of an
imported thunk, so calling such an export with null (or an imported i64
function throwing) raised "TypeError: Cannot convert 0 to a BigInt".

Emit 0n for i64 in both placeholders (jsZeroLiteral and the imported-thunk
return placeholder). This was latent because the optional Int64/UInt64
round-trip tests never exercised the none case; add those assertions.
@krodak krodak force-pushed the kr/optional-scalar-zero-literal branch from bbd2500 to 7aef830 Compare June 8, 2026 16:16
@krodak krodak merged commit be3b300 into swiftwasm:main Jun 8, 2026
13 checks passed
@krodak krodak deleted the kr/optional-scalar-zero-literal branch June 8, 2026 18:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants