Skip to content

BridgeJS: Consolidate optional and pointer runtime intrinsics#626

Merged
krodak merged 1 commit intoswiftwasm:mainfrom
PassiveLogic:kr/runtime-intrinsics-generic
Feb 12, 2026
Merged

BridgeJS: Consolidate optional and pointer runtime intrinsics#626
krodak merged 1 commit intoswiftwasm:mainfrom
PassiveLogic:kr/runtime-intrinsics-generic

Conversation

@krodak
Copy link
Member

@krodak krodak commented Feb 12, 2026

Overview

  • Refactor pointer-family runtime bridging by introducing _BridgedSwiftUnsafePointerLike and sharing the common lift/lower stack behavior in one protocol extension.
  • Add reusable optional helpers and scalar optional bridge protocols (_BridgedSwiftOptionalScalarBridge, _BridgedSwiftOptionalScalarSideChannelBridge) to remove duplicated Optional<Bool/Int/UInt/Float/Double> implementations.
  • Consolidate _BridgedAsOptional forwarding for scalar optionals into generic protocol-based extensions while preserving Bool-specific sentinel return lifting.
  • Apply helper-based lifting/lowering to additional optional paths (String, JSObject, protocol wrappers, heap objects, case enums) to reduce boilerplate without changing ABI behavior.

@krodak krodak self-assigned this Feb 12, 2026
_bridgeJSLowerReturn(
noneValue: 0,
lowerWrapped: { $0.bridgeJSLowerReturn() },
write: _swift_js_return_optional_int
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been thinking even more about replacing the optional side channel return with StackABI. Would you mind taking a benchmark if you have a moment?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll try to have look at it tomorrow 👍🏻

Copy link
Member Author

@krodak krodak Feb 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried benchmarking sideChannelReturn vs stackABI for optional scalar returns. Results suggest the side-channel approach is faster.

I used the existing OptionalReturnRoundtrip benchmarks on upstream/main (a98e49d8). Each benchmark calls the method (the default --iterations).

Baseline: 100,000 times per sample, 50 adaptive samples, main.

StackABI variant: modified bridgeJSLowerReturn() on all Optional<T> extensions in BridgeJSIntrinsics.swift to use _swift_js_push_* / i32Stack.pop() instead of _swift_js_return_optional_* / tmpRetOptional*. For example, Optional<Int>:

Full changes and raw JSON results on branch kr/stackabi-optional-benchmark:

Test sideChannel stackABI Change
Int? (some) 2.58 3.11 +20.5%
Int? (none) 2.51 2.49 -0.8%
Bool? (some) 2.44 3.09 +26.6%
Bool? (none) 2.45 2.45 +0.0%
Double? (some) 2.74 3.41 +24.5%
Double? (none) 2.39 2.45 +2.5%
String? (some) 10.50 14.45 +37.6%
String? (none) 2.44 2.56 +4.9%

Maybe we should stick with current side-channel approach where we can for now?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the data point! In that case, let's stick with the non-stack storage.

@krodak krodak merged commit 56933d2 into swiftwasm:main Feb 12, 2026
11 checks passed
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