@@ -348,8 +348,6 @@ public struct BridgeJSLink {
348348 declarations. append ( " return; " )
349349 declarations. append ( " } " )
350350 declarations. append ( " __bjs_typeHandlesRegistered = true; " )
351- // The core (primitive) handles live in the JavaScriptKit library, so
352- // they are registered once here rather than by every module.
353351 declarations. append (
354352 " \( JSGlueVariableScope . reservedInstance) .exports[ \" \( ABINameGenerator . coreTypeRegistrationFunctionName) \" ](); "
355353 )
@@ -403,7 +401,6 @@ public struct BridgeJSLink {
403401 printer. write ( lines: lines)
404402 }
405403
406- /// A print context detached from any thunk, used for codec literal emission.
407404 private func makeCodecPrintContext( printer: CodeFragmentPrinter ) -> IntrinsicJSFragment . PrintCodeContext {
408405 IntrinsicJSFragment . PrintCodeContext (
409406 scope: JSGlueVariableScope ( intrinsicRegistry: intrinsicRegistry) ,
@@ -413,16 +410,10 @@ public struct BridgeJSLink {
413410 )
414411 }
415412
416- /// Returns the module-scope codec helper for one bridgeable type, declaring
417- /// it if this is the first reference.
418- ///
419- /// The registration table and the container combinators' element positions
420- /// go through the same helper, so a type's stack ABI is described once.
421413 private func genericCodecReference( type: BridgeType , into printer: CodeFragmentPrinter ) throws -> String {
422414 try ContainerCodecJS . codecExpression ( for: type, context: makeCodecPrintContext ( printer: printer) )
423415 }
424416
425- /// Pairs the type IDs Swift pushed with codecs in the matching skeleton order.
426417 private func writeTypeHandleRegistrationBody( into printer: CodeFragmentPrinter ) {
427418 printer. write (
428419 " const typeIds = new Int32Array( \( JSGlueVariableScope . reservedMemory) .buffer, base >>> 0, count >>> 0); "
@@ -434,11 +425,6 @@ public struct BridgeJSLink {
434425 printer. write ( " } " )
435426 }
436427
437- /// Installs the `bjs_core_register_type_handles` hook. The core handles are
438- /// owned by the JavaScriptKit library rather than by generated code, so the
439- /// wasm import exists in every binary that links JavaScriptKit and the hook
440- /// is always installed; without generics anywhere in the build it is a no-op
441- /// and the registration export is never called.
442428 private func generateCoreTypeRegistrationHook( into printer: CodeFragmentPrinter ) throws {
443429 let hookName = ABINameGenerator . coreTypeRegistrationFunctionName
444430 guard hasGenerics else {
@@ -448,8 +434,6 @@ public struct BridgeJSLink {
448434 try ContainerCodecJS . registerPrimitiveCodecs ( context: makeCodecPrintContext ( printer: printer) )
449435 printer. write ( " bjs[ \" \( hookName) \" ] = function(base, count) { " )
450436 printer. indent {
451- // Same canonical order as `_bjs_core_register_type_handles` in the
452- // JavaScriptKit library.
453437 printer. write ( " const codecs = [ " )
454438 printer. indent {
455439 for primitive in BridgeType . genericBridgeablePrimitives {
@@ -462,10 +446,6 @@ public struct BridgeJSLink {
462446 printer. write ( " } " )
463447 }
464448
465- /// Installs the per-module `bjs_<Module>_register_type_handles` import
466- /// hooks. A module with a registration function always carries the wasm
467- /// import, so a hook is always installed; without generics anywhere in the
468- /// build it is a no-op and the registration export is never called.
469449 private func generateTypeRegistrationHooks( into printer: CodeFragmentPrinter ) throws {
470450 try generateCoreTypeRegistrationHook ( into: printer)
471451 for skeleton in skeletons {
@@ -477,7 +457,6 @@ public struct BridgeJSLink {
477457 }
478458 printer. write ( " bjs[ \" \( hookName) \" ] = function(base, count) { " )
479459 try printer. indent {
480- // Same order as the module's Swift registration function.
481460 let codecNames = try moduleEntries. map {
482461 try genericCodecReference ( type: $0. bridgeType, into: printer)
483462 }
@@ -496,7 +475,9 @@ public struct BridgeJSLink {
496475
497476 private func generateAddImports( needsImportsObject: Bool ) throws -> CodeFragmentPrinter {
498477 let printer = CodeFragmentPrinter ( )
499- let allStructs = skeletons. compactMap { $0. exported? . structs } . flatMap { $0 }
478+ let allStructs = skeletons. flatMap { unified in
479+ ( unified. exported? . structs ?? [ ] ) . map { ( moduleName: unified. moduleName, structDef: $0) }
480+ }
500481 printer. write ( " return { " )
501482 try printer. indent {
502483 printer. write ( lines: [
@@ -644,19 +625,20 @@ public struct BridgeJSLink {
644625 }
645626 printer. write ( " } " )
646627 if !allStructs. isEmpty {
647- for structDef in allStructs {
628+ for (moduleName, structDef) in allStructs {
629+ let key = HelperNaming . type ( module: moduleName, swiftName: structDef. swiftCallName)
648630 printer. write ( " bjs[ \" swift_js_struct_lower_ \( structDef. abiName) \" ] = function(objectId) { " )
649631 printer. indent {
650632 printer. write (
651- " \( JSGlueVariableScope . reservedStructHelpers) . \( structDef . abiName ) .lower( \( JSGlueVariableScope . reservedSwift) .memory.getObject(objectId)); "
633+ " \( JSGlueVariableScope . reservedStructHelpers) . \( key ) .lower( \( JSGlueVariableScope . reservedSwift) .memory.getObject(objectId)); "
652634 )
653635 }
654636 printer. write ( " } " )
655637
656638 printer. write ( " bjs[ \" swift_js_struct_lift_ \( structDef. abiName) \" ] = function() { " )
657639 printer. indent {
658640 printer. write (
659- " const value = \( JSGlueVariableScope . reservedStructHelpers) . \( structDef . abiName ) .lift(); "
641+ " const value = \( JSGlueVariableScope . reservedStructHelpers) . \( key ) .lift(); "
660642 )
661643 printer. write ( " return \( JSGlueVariableScope . reservedSwift) .memory.retain(value); " )
662644 }
@@ -1229,12 +1211,18 @@ public struct BridgeJSLink {
12291211
12301212 let bodyPrinter = CodeFragmentPrinter ( )
12311213 let allStructs = exportedSkeletons. flatMap { $0. structs }
1232- for structDef in allStructs {
1214+ for (moduleName, structDef) in skeletons. flatMap ( { unified in
1215+ ( unified. exported? . structs ?? [ ] ) . map { ( unified. moduleName, $0) }
1216+ } ) {
12331217 let structPrinter = CodeFragmentPrinter ( )
12341218 let structScope = JSGlueVariableScope ( intrinsicRegistry: intrinsicRegistry)
1235- let fragment = IntrinsicJSFragment . structHelper ( structDefinition: structDef, allStructs: allStructs)
1219+ let fragment = IntrinsicJSFragment . structHelper (
1220+ structDefinition: structDef,
1221+ allStructs: allStructs,
1222+ moduleName: moduleName
1223+ )
12361224 _ = try fragment. printCode (
1237- [ structDef . abiName ] ,
1225+ [ ] ,
12381226 IntrinsicJSFragment . PrintCodeContext (
12391227 scope: structScope,
12401228 printer: structPrinter,
@@ -1245,13 +1233,16 @@ public struct BridgeJSLink {
12451233 bodyPrinter. write ( lines: structPrinter. lines)
12461234 }
12471235
1248- let allAssocEnums = exportedSkeletons . flatMap {
1249- $0 . enums. filter { $0. enumType == . associatedValue }
1250- }
1251- for enumDef in allAssocEnums {
1236+ for (moduleName , enumDef ) in skeletons . flatMap ( { unified in
1237+ ( unified . exported ? . enums ?? [ ] ) . filter { $0. enumType == . associatedValue }
1238+ . map { ( unified . moduleName , $0 ) }
1239+ } ) {
12521240 let enumPrinter = CodeFragmentPrinter ( )
12531241 let enumScope = JSGlueVariableScope ( intrinsicRegistry: intrinsicRegistry)
1254- let fragment = IntrinsicJSFragment . associatedValueEnumHelperFactory ( enumDefinition: enumDef)
1242+ let fragment = IntrinsicJSFragment . associatedValueEnumHelperFactory (
1243+ enumDefinition: enumDef,
1244+ moduleName: moduleName
1245+ )
12551246 _ = try fragment. printCode (
12561247 [ enumDef. valuesName] ,
12571248 IntrinsicJSFragment . PrintCodeContext (
@@ -1271,13 +1262,6 @@ public struct BridgeJSLink {
12711262 printer. nextLine ( )
12721263 }
12731264
1274- // The named codec helpers come after the intrinsics because they are
1275- // built out of the combinators and the primitive codec table, and
1276- // before everything that uses them: they are hoisted here so that no
1277- // call site ever composes a codec. Helpers that delegate to the
1278- // `structHelpers` / `enumHelpers` tables only read those tables when
1279- // called, so declaring them ahead of the tables being populated is
1280- // fine.
12811265 if intrinsicRegistry. hasNamedCodecs {
12821266 printer. write ( lines: intrinsicRegistry. emitNamedCodecLines ( ) )
12831267 printer. nextLine ( )
@@ -1380,12 +1364,6 @@ public struct BridgeJSLink {
13801364 return ( outputJs, outputDts)
13811365 }
13821366
1383- /// Maps every type name a `BridgeType` can carry to the module that declares
1384- /// it, so identifiers minted from type names can be module-qualified.
1385- ///
1386- /// A name declared by two modules is a pre-existing ambiguity in the
1387- /// skeleton format (`BridgeType` carries only the name), so the first
1388- /// declaration wins, which keeps the output deterministic.
13891367 private func collectTypeOwnerModules( ) -> [ String : String ] {
13901368 var result : [ String : String ] = [ : ]
13911369 func record( _ name: String , _ moduleName: String ) {
@@ -1399,6 +1377,7 @@ public struct BridgeJSLink {
13991377 for structDef in skeleton. structs {
14001378 record ( structDef. name, moduleName)
14011379 record ( structDef. abiName, moduleName)
1380+ record ( structDef. swiftCallName, moduleName)
14021381 }
14031382 for klass in skeleton. classes {
14041383 record ( klass. name, moduleName)
@@ -1407,29 +1386,26 @@ public struct BridgeJSLink {
14071386 for enumDef in skeleton. enums {
14081387 record ( enumDef. name, moduleName)
14091388 record ( enumDef. abiName, moduleName)
1389+ record ( enumDef. swiftCallName, moduleName)
14101390 }
14111391 for protocolDef in skeleton. protocols {
14121392 record ( protocolDef. name, moduleName)
14131393 }
14141394 }
1415- for file in unified. imported? . children ?? [ ] {
1416- for type in file. types {
1417- record ( type. name, moduleName)
1418- }
1419- }
14201395 }
14211396 return result
14221397 }
14231398
14241399 private func enumHelperAssignments( ) -> CodeFragmentPrinter {
14251400 let printer = CodeFragmentPrinter ( )
14261401
1427- for skeleton in skeletons. compactMap ( \. exported) {
1402+ for unified in skeletons {
1403+ guard let skeleton = unified. exported else { continue }
14281404 for enumDef in skeleton. enums where enumDef. enumType == . associatedValue {
1429- printer . write (
1430- " const \( enumDef . name ) Helpers = __bjs_create \( enumDef . valuesName ) Helpers(); "
1431- )
1432- printer. write ( " \( JSGlueVariableScope . reservedEnumHelpers) . \( enumDef . name ) = \( enumDef . name ) Helpers ;" )
1405+ let key = HelperNaming . type ( module : unified . moduleName , swiftName : enumDef . swiftCallName )
1406+ let local = HelperNaming . helperConstant ( key )
1407+ printer . write ( " const \( local ) = \( HelperNaming . enumHelperFactory ( key ) ) (); " )
1408+ printer. write ( " \( JSGlueVariableScope . reservedEnumHelpers) . \( key ) = \( local ) ; " )
14331409 printer. nextLine ( )
14341410 }
14351411 }
@@ -1440,14 +1416,13 @@ public struct BridgeJSLink {
14401416 private func structHelperAssignments( ) -> CodeFragmentPrinter {
14411417 let printer = CodeFragmentPrinter ( )
14421418
1443- for skeleton in skeletons. compactMap ( \. exported) {
1419+ for unified in skeletons {
1420+ guard let skeleton = unified. exported else { continue }
14441421 for structDef in skeleton. structs {
1445- printer. write (
1446- " const \( structDef. abiName) Helpers = __bjs_create \( structDef. abiName) Helpers(); "
1447- )
1448- printer. write (
1449- " \( JSGlueVariableScope . reservedStructHelpers) . \( structDef. abiName) = \( structDef. abiName) Helpers; "
1450- )
1422+ let key = HelperNaming . type ( module: unified. moduleName, swiftName: structDef. swiftCallName)
1423+ let local = HelperNaming . helperConstant ( key)
1424+ printer. write ( " const \( local) = \( HelperNaming . structHelperFactory ( key) ) (); " )
1425+ printer. write ( " \( JSGlueVariableScope . reservedStructHelpers) . \( key) = \( local) ; " )
14511426 printer. nextLine ( )
14521427 }
14531428 }
@@ -2593,8 +2568,6 @@ extension BridgeJSLink {
25932568
25942569 func declareGenericCodecs( genericParameters: [ String ] ) {
25952570 if !genericParameters. isEmpty {
2596- // Generic call sites instantiate the shared container codec
2597- // combinators with the codecs resolved from type IDs.
25982571 ContainerCodecJS . registerCombinators ( scope: scope)
25992572 }
26002573 for genericParam in genericParameters {
0 commit comments