@@ -130,10 +130,43 @@ public class ExportSwift {
130130 case . swiftStruct( let structName) :
131131 typeNameForIntrinsic = structName
132132 liftingExpr = ExprSyntax ( " \( raw: structName) .bridgeJSLiftParameter() " )
133+ case . array:
134+ typeNameForIntrinsic = param. type. swiftType
135+ liftingExpr = StackCodegen ( ) . liftExpression ( for: param. type)
133136 case . optional( let wrappedType) :
134- typeNameForIntrinsic = " Optional< \( wrappedType. swiftType) > "
137+ if case . array( let elementType) = wrappedType {
138+ let arrayLift = StackCodegen ( ) . liftArrayExpression ( elementType: elementType)
139+ let isSomeParam = argumentsToLift [ 0 ]
140+ let swiftTypeName = elementType. swiftType
141+ typeNameForIntrinsic = " Optional<[ \( swiftTypeName) ]> "
142+ liftingExpr = ExprSyntax (
143+ """
144+ {
145+ if \( raw: isSomeParam) == 0 {
146+ return Optional<[ \( raw: swiftTypeName) ]>.none
147+ } else {
148+ return \( arrayLift)
149+ }
150+ }()
151+ """
152+ )
153+ } else if case . swiftProtocol( let protocolName) = wrappedType {
154+ let wrapperName = " Any \( protocolName) "
155+ typeNameForIntrinsic = " Optional< \( wrapperName) > "
156+ liftingExpr = ExprSyntax (
157+ " \( raw: typeNameForIntrinsic) .bridgeJSLiftParameter( \( raw: argumentsToLift. joined ( separator: " , " ) ) ) "
158+ )
159+ } else {
160+ typeNameForIntrinsic = " Optional< \( wrappedType. swiftType) > "
161+ liftingExpr = ExprSyntax (
162+ " \( raw: typeNameForIntrinsic) .bridgeJSLiftParameter( \( raw: argumentsToLift. joined ( separator: " , " ) ) ) "
163+ )
164+ }
165+ case . swiftProtocol( let protocolName) :
166+ let wrapperName = " Any \( protocolName) "
167+ typeNameForIntrinsic = wrapperName
135168 liftingExpr = ExprSyntax (
136- " \( raw: typeNameForIntrinsic ) .bridgeJSLiftParameter( \( raw: argumentsToLift. joined ( separator: " , " ) ) ) "
169+ " \( raw: wrapperName ) .bridgeJSLiftParameter( \( raw: argumentsToLift. joined ( separator: " , " ) ) ) "
137170 )
138171 default :
139172 typeNameForIntrinsic = param. type. swiftType
@@ -246,7 +279,8 @@ public class ExportSwift {
246279 let stackParamIndices = parameters. enumerated ( ) . compactMap { index, param -> Int ? in
247280 switch param. type {
248281 case . swiftStruct, . optional( . swiftStruct) ,
249- . associatedValueEnum, . optional( . associatedValueEnum) :
282+ . associatedValueEnum, . optional( . associatedValueEnum) ,
283+ . array:
250284 return index
251285 default :
252286 return nil
@@ -319,9 +353,15 @@ public class ExportSwift {
319353 return
320354 }
321355
322- if case . closure( let signature) = returnType {
356+ switch returnType {
357+ case . closure( let signature) :
323358 append ( " return _BJS_Closure_ \( raw: signature. mangleName) .bridgeJSLower(ret) " )
324- } else {
359+ case . array, . optional( . array) :
360+ let stackCodegen = StackCodegen ( )
361+ for stmt in stackCodegen. lowerStatements ( for: returnType, accessor: " ret " , varPrefix: " ret " ) {
362+ append ( stmt)
363+ }
364+ default :
325365 append ( " return ret.bridgeJSLowerReturn() " )
326366 }
327367 }
@@ -774,9 +814,10 @@ struct StackCodegen {
774814 return " \( raw: className) .bridgeJSLiftParameter(_swift_js_pop_param_pointer()) "
775815 case . unsafePointer:
776816 return " \( raw: type. swiftType) .bridgeJSLiftParameter(_swift_js_pop_param_pointer()) "
777- case . swiftProtocol:
778- // Protocols are handled via JSObject
779- return " JSObject.bridgeJSLiftParameter(_swift_js_pop_param_int32()) "
817+ case . swiftProtocol( let protocolName) :
818+ // Protocols use their Any wrapper type for lifting
819+ let wrapperName = " Any \( protocolName) "
820+ return " \( raw: wrapperName) .bridgeJSLiftParameter(_swift_js_pop_param_int32()) "
780821 case . caseEnum( let enumName) :
781822 return " \( raw: enumName) .bridgeJSLiftParameter(_swift_js_pop_param_int32()) "
782823 case . rawValueEnum( let enumName, let rawType) :
@@ -805,9 +846,28 @@ struct StackCodegen {
805846 return " () "
806847 case . closure:
807848 return " JSObject.bridgeJSLiftParameter(_swift_js_pop_param_int32()) "
849+ case . array( let elementType) :
850+ return liftArrayExpression ( elementType: elementType)
808851 }
809852 }
810853
854+ func liftArrayExpression( elementType: BridgeType ) -> ExprSyntax {
855+ let elementLift = liftExpression ( for: elementType)
856+ let swiftTypeName = elementType. swiftType
857+ return """
858+ {
859+ let __count = Int(_swift_js_pop_param_array_length())
860+ var __result: [ \( raw: swiftTypeName) ] = []
861+ __result.reserveCapacity(__count)
862+ for _ in 0..<__count {
863+ __result.append( \( elementLift) )
864+ }
865+ __result.reverse()
866+ return __result
867+ }()
868+ """
869+ }
870+
811871 private func liftOptionalExpression( wrappedType: BridgeType ) -> ExprSyntax {
812872 switch wrappedType {
813873 case . string:
@@ -849,6 +909,19 @@ struct StackCodegen {
849909 " Optional< \( raw: enumName) >.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32()) "
850910 case . jsObject:
851911 return " Optional<JSObject>.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32()) "
912+ case . array( let elementType) :
913+ let arrayLift = liftArrayExpression ( elementType: elementType)
914+ let swiftTypeName = elementType. swiftType
915+ return """
916+ {
917+ let __isSome = _swift_js_pop_param_int32()
918+ if __isSome == 0 {
919+ return Optional<[ \( raw: swiftTypeName) ]>.none
920+ } else {
921+ return \( arrayLift)
922+ }
923+ }()
924+ """
852925 default :
853926 // Fallback for other optional types
854927 return " Optional<Int>.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32()) "
@@ -886,8 +959,9 @@ struct StackCodegen {
886959 return [ " _swift_js_push_pointer( \( raw: accessor) .bridgeJSLowerReturn()) " ]
887960 case . unsafePointer:
888961 return [ " _swift_js_push_pointer( \( raw: accessor) .bridgeJSLowerReturn()) " ]
889- case . swiftProtocol:
890- return [ " _swift_js_push_int( \( raw: accessor) .bridgeJSLowerParameter()) " ]
962+ case . swiftProtocol( let protocolName) :
963+ let wrapperName = " Any \( protocolName) "
964+ return [ " _swift_js_push_int(( \( raw: accessor) as! \( raw: wrapperName) ).bridgeJSLowerReturn()) " ]
891965 case . caseEnum:
892966 return [ " _swift_js_push_int(Int32( \( raw: accessor) .bridgeJSLowerParameter())) " ]
893967 case . rawValueEnum( _, let rawType) :
@@ -916,9 +990,34 @@ struct StackCodegen {
916990 return [ ]
917991 case . closure:
918992 return [ " _swift_js_push_pointer( \( raw: accessor) .bridgeJSLowerReturn()) " ]
993+ case . array( let elementType) :
994+ return lowerArrayStatements ( elementType: elementType, accessor: accessor, varPrefix: varPrefix)
919995 }
920996 }
921997
998+ private func lowerArrayStatements(
999+ elementType: BridgeType ,
1000+ accessor: String ,
1001+ varPrefix: String
1002+ ) -> [ CodeBlockItemSyntax ] {
1003+ var statements : [ CodeBlockItemSyntax ] = [ ]
1004+ let elementVarName = " __bjs_elem_ \( varPrefix) "
1005+ statements. append ( " for \( raw: elementVarName) in \( raw: accessor) { " )
1006+
1007+ let elementStatements = lowerStatements (
1008+ for: elementType,
1009+ accessor: elementVarName,
1010+ varPrefix: " \( varPrefix) _elem "
1011+ )
1012+ for stmt in elementStatements {
1013+ statements. append ( stmt)
1014+ }
1015+
1016+ statements. append ( " } " )
1017+ statements. append ( " _swift_js_push_array_length(Int32( \( raw: accessor) .count)) " )
1018+ return statements
1019+ }
1020+
9221021 private func lowerOptionalStatements(
9231022 wrappedType: BridgeType ,
9241023 accessor: String ,
@@ -985,6 +1084,8 @@ struct StackCodegen {
9851084 return [ " _swift_js_push_int( \( raw: unwrappedVar) .bridgeJSLowerParameter()) " ]
9861085 case . jsObject:
9871086 return [ " _swift_js_push_int( \( raw: unwrappedVar) .bridgeJSLowerReturn()) " ]
1087+ case . array( let elementType) :
1088+ return lowerArrayStatements ( elementType: elementType, accessor: unwrappedVar, varPrefix: varPrefix)
9881089 default :
9891090 return [ " preconditionFailure( \" BridgeJS: unsupported optional wrapped type \" ) " ]
9901091 }
@@ -1552,6 +1653,7 @@ extension BridgeType {
15521653 case . swiftProtocol( let name) : return " Any \( name) "
15531654 case . void: return " Void "
15541655 case . optional( let wrappedType) : return " Optional< \( wrappedType. swiftType) > "
1656+ case . array( let elementType) : return " [ \( elementType. swiftType) ] "
15551657 case . caseEnum( let name) : return name
15561658 case . rawValueEnum( let name, _) : return name
15571659 case . associatedValueEnum( let name) : return name
@@ -1609,6 +1711,8 @@ extension BridgeType {
16091711 throw BridgeJSCoreError ( " Namespace enums are not supported to pass as parameters " )
16101712 case . closure:
16111713 return LiftingIntrinsicInfo ( parameters: [ ( " callbackId " , . i32) ] )
1714+ case . array:
1715+ return LiftingIntrinsicInfo ( parameters: [ ] )
16121716 }
16131717 }
16141718
@@ -1629,6 +1733,7 @@ extension BridgeType {
16291733 static let associatedValueEnum = LoweringIntrinsicInfo ( returnType: nil )
16301734 static let swiftStruct = LoweringIntrinsicInfo ( returnType: nil )
16311735 static let optional = LoweringIntrinsicInfo ( returnType: nil )
1736+ static let array = LoweringIntrinsicInfo ( returnType: nil )
16321737 }
16331738
16341739 func loweringReturnInfo( ) throws -> LoweringIntrinsicInfo {
@@ -1655,6 +1760,8 @@ extension BridgeType {
16551760 throw BridgeJSCoreError ( " Namespace enums are not supported to pass as parameters " )
16561761 case . closure:
16571762 return . swiftHeapObject
1763+ case . array:
1764+ return . array
16581765 }
16591766 }
16601767}
0 commit comments