Skip to content

BridgeJS: Unify optional stack encoding to presence-flag form#16

Closed
krodak wants to merge 1 commit into
mainfrom
kr/unify-optional-stack-encoding
Closed

BridgeJS: Unify optional stack encoding to presence-flag form#16
krodak wants to merge 1 commit into
mainfrom
kr/unify-optional-stack-encoding

Conversation

@krodak

@krodak krodak commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Overview

Unifies the stack encoding of Optional values to a single presence-flag form. Previously, associated-value enums were the one type with a specialized optional stack encoding: the presence signal was merged into the case-ID slot, with -1 meaning nil. Every other type uses a 0/1 presence flag followed by the value. After this change, associated-value enums use the same flag form as everything else when crossing in stack positions (array elements, struct fields, dictionary values, nested enum payloads).

before:  caseId | -1            (one i32, meaning depends on the wrapped type)
after:   flag, then caseId      (flag is 0/1 for every type)

1. Swift runtime. The bridgeJSStackPop/PushAsOptional override on _BridgedSwiftAssociatedValueEnum is removed; the protocol defaults now serve every type. The direct return slot keeps the merged caseId/-1 convention (it is a separate ABI position, shared with other enum returns); the previous implementation delegated to the stack helper, so the merged form is now inlined there with a comment.

2. JS glue. The associated-value enum special cases in optionalElementRaiseFragment / optionalElementLowerFragment are removed; associated-value enums flow through the same general path as all other wrapped types, which composes the existing per-type element fragments behind a presence flag.

Cost

Optional associated-value enums in stack positions carry one extra i32 (the flag) per crossing. Direct parameter and return conventions are unchanged.

Motivation

This removes the only optional stack encoding that cannot be decoded without knowing the wrapped type: a popped 0 meant nil for most types but "case 0, payload follows" for associated-value enums. A type-agnostic consumer of the stack encoding needs one uniform optional form; this prepares for generic function support (swiftwasm#398), where a runtime codec decodes optionals without static knowledge of T. A follow-up PR adds that support.

Test plan

  • Host snapshot tests and npm run check:bridgejs-dts pass; only two .js snapshots change, showing the flag-form encoding.
  • WebAssembly runtime tests pass, including testRoundTripOptionalAssociatedValueEnum and asyncRoundTripOptionalAssociatedValueEnum, which exercise the changed encoding end to end.

@krodak krodak force-pushed the kr/unify-optional-stack-encoding branch from 292c088 to bc356b5 Compare July 8, 2026 17:35
@krodak krodak closed this Jul 8, 2026
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.

1 participant