@@ -1751,13 +1751,13 @@ public class ExportSwift {
17511751 return bridgeJSRawValue
17521752 }
17531753 @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Int32) -> \( raw : typeName ) {
1754- return \( raw : typeName ) (bridgeJSRawValue: value)!
1754+ return bridgeJSLiftParameter( value)
17551755 }
17561756 @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Int32) -> \( raw : typeName ) {
17571757 return \( raw : typeName ) (bridgeJSRawValue: value)!
17581758 }
17591759 @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Int32 {
1760- return bridgeJSRawValue
1760+ return bridgeJSLowerParameter()
17611761 }
17621762
17631763 private init?(bridgeJSRawValue: Int32) {
@@ -1774,13 +1774,32 @@ public class ExportSwift {
17741774 func renderAssociatedValueEnumHelpers ( _ enumDef : ExportedEnum ) -> DeclSyntax {
17751775 let typeName = enumDef . swiftCallName
17761776 return """
1777- extension \( raw : typeName ) : _BridgedSwiftAssociatedValueEnum {
1778- @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter (_ caseId: Int32) -> \( raw : typeName ) {
1777+ extension \( raw : typeName ) : _BridgedSwiftAssociatedValueEnum {
1778+ private static func _bridgeJSLiftFromCaseId (_ caseId: Int32) -> \( raw : typeName ) {
17791779 switch caseId {
17801780 \( raw : generateStackLiftSwitchCases ( enumDef : enumDef ) . joined ( separator : " \n " ) )
17811781 default: fatalError( " Unknown \( raw : typeName ) case ID: \\ (caseId) " )
17821782 }
17831783 }
1784+
1785+ // MARK: Protocol Export
1786+
1787+ @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 {
1788+ switch self {
1789+ \( raw : generateLowerParameterSwitchCases ( enumDef : enumDef ) . joined ( separator : " \n " ) )
1790+ }
1791+ }
1792+
1793+ @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn() -> \( raw : typeName ) {
1794+ let caseId = _swift_js_pop_param_int32()
1795+ return _bridgeJSLiftFromCaseId(caseId)
1796+ }
1797+
1798+ // MARK: ExportSwift
1799+
1800+ @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ caseId: Int32) -> \( raw : typeName ) {
1801+ return _bridgeJSLiftFromCaseId(caseId)
1802+ }
17841803
17851804 @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() {
17861805 switch self {
@@ -1849,66 +1868,94 @@ public class ExportSwift {
18491868 return cases
18501869 }
18511870
1871+ /// Generates code to push associated value payloads to side channels
1872+ /// This helper is reused by both lowerParameter and lowerReturn to avoid duplication
1873+ private func generatePayloadPushingCode (
1874+ associatedValues : [ AssociatedValue ]
1875+ ) -> [ String ] {
1876+ var bodyLines : [ String ] = [ ]
1877+ for ( index , associatedValue ) in associatedValues . enumerated ( ) {
1878+ let paramName = associatedValue . label ?? " param \( index ) "
1879+ switch associatedValue . type {
1880+ case . string :
1881+ bodyLines . append ( " var __bjs_ \( paramName ) = \( paramName ) " )
1882+ bodyLines . append ( " __bjs_ \( paramName ) .withUTF8 { ptr in " )
1883+ bodyLines . append ( " _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) " )
1884+ bodyLines . append ( " } " )
1885+ case . int :
1886+ bodyLines . append ( " _swift_js_push_int(Int32( \( paramName ) )) " )
1887+ case . bool :
1888+ bodyLines . append ( " _swift_js_push_int( \( paramName ) ? 1 : 0) " )
1889+ case . float :
1890+ bodyLines . append ( " _swift_js_push_f32( \( paramName ) ) " )
1891+ case . double :
1892+ bodyLines . append ( " _swift_js_push_f64( \( paramName ) ) " )
1893+ case . optional ( let wrappedType ) :
1894+ bodyLines . append ( " let __bjs_isSome_ \( paramName ) = \( paramName ) != nil " )
1895+ bodyLines . append ( " if let __bjs_unwrapped_ \( paramName ) = \( paramName ) { " )
1896+ switch wrappedType {
1897+ case . string :
1898+ bodyLines . append ( " var __bjs_str_ \( paramName ) = __bjs_unwrapped_ \( paramName ) " )
1899+ bodyLines . append ( " __bjs_str_ \( paramName ) .withUTF8 { ptr in " )
1900+ bodyLines . append ( " _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) " )
1901+ bodyLines . append ( " } " )
1902+ case . int :
1903+ bodyLines . append ( " _swift_js_push_int(Int32(__bjs_unwrapped_ \( paramName ) )) " )
1904+ case . bool :
1905+ bodyLines . append ( " _swift_js_push_int(__bjs_unwrapped_ \( paramName ) ? 1 : 0) " )
1906+ case . float :
1907+ bodyLines . append ( " _swift_js_push_f32(__bjs_unwrapped_ \( paramName ) ) " )
1908+ case . double :
1909+ bodyLines . append ( " _swift_js_push_f64(__bjs_unwrapped_ \( paramName ) ) " )
1910+ default :
1911+ bodyLines . append (
1912+ " preconditionFailure( \" BridgeJS: unsupported optional wrapped type in generated code \" ) "
1913+ )
1914+ }
1915+ bodyLines . append ( " } " )
1916+ bodyLines . append ( " _swift_js_push_int(__bjs_isSome_ \( paramName ) ? 1 : 0) " )
1917+ default :
1918+ bodyLines . append (
1919+ " preconditionFailure( \" BridgeJS: unsupported associated value type in generated code \" ) "
1920+ )
1921+ }
1922+ }
1923+ return bodyLines
1924+ }
1925+
1926+ private func generateLowerParameterSwitchCases ( enumDef : ExportedEnum ) -> [ String ] {
1927+ var cases : [ String ] = [ ]
1928+ for ( caseIndex , enumCase ) in enumDef . cases . enumerated ( ) {
1929+ if enumCase . associatedValues . isEmpty {
1930+ cases . append ( " case . \( enumCase . name ) : " )
1931+ cases . append ( " return Int32( \( caseIndex ) ) " )
1932+ } else {
1933+ let payloadCode = generatePayloadPushingCode ( associatedValues : enumCase . associatedValues )
1934+ let pattern = enumCase . associatedValues . enumerated ( )
1935+ . map { index , associatedValue in " let \( associatedValue . label ?? " param \( index ) " ) " }
1936+ . joined ( separator : " , " )
1937+ cases . append ( " case . \( enumCase . name ) ( \( pattern ) ): " )
1938+ cases . append ( contentsOf : payloadCode )
1939+ cases . append ( " return Int32( \( caseIndex ) ) " )
1940+ }
1941+ }
1942+ return cases
1943+ }
1944+
18521945 private func generateReturnSwitchCases ( enumDef : ExportedEnum ) -> [ String ] {
18531946 var cases : [ String ] = [ ]
18541947 for ( caseIndex , enumCase ) in enumDef . cases . enumerated ( ) {
18551948 if enumCase . associatedValues . isEmpty {
18561949 cases . append ( " case . \( enumCase . name ) : " )
18571950 cases . append ( " _swift_js_push_tag(Int32( \( caseIndex ) )) " )
18581951 } else {
1859- var bodyLines : [ String ] = [ ]
1860- bodyLines . append ( " _swift_js_push_tag(Int32( \( caseIndex ) )) " )
1861- for ( index , associatedValue ) in enumCase . associatedValues . enumerated ( ) {
1862- let paramName = associatedValue . label ?? " param \( index ) "
1863- switch associatedValue . type {
1864- case . string :
1865- bodyLines . append ( " var __bjs_ \( paramName ) = \( paramName ) " )
1866- bodyLines . append ( " __bjs_ \( paramName ) .withUTF8 { ptr in " )
1867- bodyLines . append ( " _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) " )
1868- bodyLines . append ( " } " )
1869- case . int :
1870- bodyLines . append ( " _swift_js_push_int(Int32( \( paramName ) )) " )
1871- case . bool :
1872- bodyLines . append ( " _swift_js_push_int( \( paramName ) ? 1 : 0) " )
1873- case . float :
1874- bodyLines . append ( " _swift_js_push_f32( \( paramName ) ) " )
1875- case . double :
1876- bodyLines . append ( " _swift_js_push_f64( \( paramName ) ) " )
1877- case . optional ( let wrappedType ) :
1878- bodyLines . append ( " let __bjs_isSome_ \( paramName ) = \( paramName ) != nil " )
1879- bodyLines . append ( " if let __bjs_unwrapped_ \( paramName ) = \( paramName ) { " )
1880- switch wrappedType {
1881- case . string :
1882- bodyLines . append ( " var __bjs_str_ \( paramName ) = __bjs_unwrapped_ \( paramName ) " )
1883- bodyLines . append ( " __bjs_str_ \( paramName ) .withUTF8 { ptr in " )
1884- bodyLines . append ( " _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) " )
1885- bodyLines . append ( " } " )
1886- case . int :
1887- bodyLines . append ( " _swift_js_push_int(Int32(__bjs_unwrapped_ \( paramName ) )) " )
1888- case . bool :
1889- bodyLines . append ( " _swift_js_push_int(__bjs_unwrapped_ \( paramName ) ? 1 : 0) " )
1890- case . float :
1891- bodyLines . append ( " _swift_js_push_f32(__bjs_unwrapped_ \( paramName ) ) " )
1892- case . double :
1893- bodyLines . append ( " _swift_js_push_f64(__bjs_unwrapped_ \( paramName ) ) " )
1894- default :
1895- bodyLines . append (
1896- " preconditionFailure( \" BridgeJS: unsupported optional wrapped type in generated code \" ) "
1897- )
1898- }
1899- bodyLines . append ( " } " )
1900- bodyLines . append ( " _swift_js_push_int(__bjs_isSome_ \( paramName ) ? 1 : 0) " )
1901- default :
1902- bodyLines . append (
1903- " preconditionFailure( \" BridgeJS: unsupported associated value type in generated code \" ) "
1904- )
1905- }
1906- }
19071952 let pattern = enumCase . associatedValues . enumerated ( )
19081953 . map { index , associatedValue in " let \( associatedValue . label ?? " param \( index ) " ) " }
19091954 . joined ( separator : " , " )
19101955 cases . append ( " case . \( enumCase . name ) ( \( pattern ) ): " )
1911- cases . append ( contentsOf : bodyLines )
1956+ cases . append ( " _swift_js_push_tag(Int32( \( caseIndex ) )) " )
1957+ let payloadCode = generatePayloadPushingCode ( associatedValues : enumCase . associatedValues )
1958+ cases . append ( contentsOf : payloadCode )
19121959 }
19131960 }
19141961 return cases
0 commit comments