NFC: BridgeJS: Refactor JSGlueGen with compositional optional handling and helper consolidation#656
Open
krodak wants to merge 1 commit intoswiftwasm:mainfrom
Open
NFC: BridgeJS: Refactor JSGlueGen with compositional optional handling and helper consolidation#656krodak wants to merge 1 commit intoswiftwasm:mainfrom
krodak wants to merge 1 commit intoswiftwasm:mainfrom
Conversation
0126fea to
9cd388d
Compare
…g and helper consolidation
9cd388d to
1ad419b
Compare
kateinoigakukun
approved these changes
Feb 19, 2026
| return IntrinsicJSFragment( | ||
| parameters: ["value"], | ||
| printCode: { arguments, context in | ||
| let (scope, printer) = (context.scope, context.printer) | ||
| let value = arguments[0] | ||
| scope.reserveNames(arguments) |
Member
There was a problem hiding this comment.
arguments given to IntrinsicJSFragment are not guaranteed to be a variable name but it can be an arbitrary expression, so we can't register them into the scope.
Instead, what we really need to do here seems like registering parameter names into the scope?
class ExportedThunkBuilder {
func lowerParameter(param: Parameter) throws {
let loweringFragment = try IntrinsicJSFragment.lowerParameter(type: param.type)
assert(
loweringFragment.parameters.count == 1,
"Lowering fragment should have exactly one parameter to lower"
)
let paramName = scope.variable(param.name)
self.parameterNames.append(paramName)
let loweredValues = try loweringFragment.printCode([paramName], context)
parameterForwardings.append(contentsOf: loweredValues)
}
}| ) | ||
| } | ||
|
|
||
| static func optionalLowerParameter(wrappedType: BridgeType) throws -> IntrinsicJSFragment { | ||
| private static func compositeOptionalLowerParameter( |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Mix of concrete simplifications and structural refactoring in JSGlueGen.swift. Happy to split this into a smaller PR with just the simplification items if the refactoring part is too much for one review.
Simplifications
() => { return () => ({...}); }to() => ({...})- the double-invocation wrapper was left over from PR NFC: BridgeJS: Remove dead cleanup infrastructure #655simpleEnumHelper/rawValueEnumHelperunified intocaseEnumHelper- they had identical logicemitPushI32Return,emitPushF64Return,emitPushPointerReturnwere copies of their parameter counterparts; several fragment aliases that just forwarded to another fragmentemitRetainCasehelper extracted to deduplicate 5 identical JSValue retain-and-break casesjsZeroLiteralscoped down from publicWasmCoreTypeAPI in BridgeJSSkeleton to fileprivate in JSGlueGen - nobody else uses it(ret | 0)coercion dropped from optional case enum returns - the non-optional path never applied it, and the value is already an integer from the enum helper so| 0was a no-opStructural refactoring
IntrinsicJSFragmentdefinitions for everyoptional(X)combination, generic fragments wrap the inner type's fragments. Adding a newBridgeTypeno longer requires writing dedicated optional fragment variants - you set a few properties and optional support composes from the base fragments. The stack ABI optional path is fully generic, which should help with planned external class support.wasmParams,optionalConvention,nilSentinel,isSingleParamScalar,lowerCoerce, etc. moved from free functions and static methods into aprivate extension BridgeTypein JSGlueGen.swift. Reads astype.wasmParamsinstead ofwasmParams(for: type).reserveNamesscope change to fileprivate, moved to bottom ofJSGlueVariableScopeTrade-offs
The composite optional wrapper produces slightly more verbose JS than the old per-type fragments (
resultintermediary vars and if/else vs inline ternaries). The codegen is easier to extend and engines optimize both patterns the same way.