@@ -112,11 +112,14 @@ public struct ClosureCodegen {
112112
113113 let helperEnumDecl : DeclSyntax = " \( raw: helperEnumDeclPrinter. lines. joined ( separator: " \n " ) ) "
114114
115- let initAccessModifier = accessLevel. modifierKeyword. map { " \( $0) " } ?? " "
115+ let accessModifier = accessLevel. modifierKeyword. map { " \( $0) " } ?? " "
116+ let declaration = signature. sendingParameters ? " static func sending " : " init "
117+ let returnClause = signature. sendingParameters ? " -> Self " : " "
118+ let initializer = signature. sendingParameters ? " Self " : " self.init "
116119 let typedClosureExtension : DeclSyntax = """
117120 extension JSTypedClosure where Signature == \( raw: swiftClosureType) {
118- \( raw: initAccessModifier ) init( fileID: StaticString = #fileID, line: UInt32 = #line, _ body: @escaping \( raw: swiftClosureType) ) {
119- self.init (
121+ \( raw: accessModifier ) \( raw : declaration ) ( fileID: StaticString = #fileID, line: UInt32 = #line, _ body: @escaping \( raw: swiftClosureType) ) \( raw : returnClause ) {
122+ \( raw : initializer ) (
120123 makeClosure: \( raw: externABIName) ,
121124 body: body,
122125 fileID: fileID,
@@ -135,149 +138,22 @@ public struct ClosureCodegen {
135138 let swiftClosureType = swiftClosureType ( for: signature)
136139 let boxType = " _BridgeJSTypedClosureBox< \( swiftClosureType) > "
137140 let abiName = " invoke_swift_closure_ \( signature. moduleName) _ \( signature. mangleName) "
138-
139- // Build ABI parameters directly with WasmCoreType (no string conversion needed)
140- var abiParams : [ ( name: String , type: WasmCoreType ) ] = [ ( " boxPtr " , . pointer) ]
141- var liftedParams : [ String ] = [ ]
142-
143- for (index, paramType) in signature. parameters. enumerated ( ) {
144- let paramName = " param \( index) "
145- let liftInfo = try paramType. liftParameterInfo ( )
146-
147- for (argName, wasmType) in liftInfo. parameters {
148- let fullName =
149- liftInfo. parameters. count > 1 ? " \( paramName) \( argName. capitalizedFirstLetter) " : paramName
150- abiParams. append ( ( fullName, wasmType) )
151- }
152-
153- let argNames = liftInfo. parameters. map { ( argName, _) in
154- liftInfo. parameters. count > 1 ? " \( paramName) \( argName. capitalizedFirstLetter) " : paramName
155- }
156- liftedParams. append (
157- " \( paramType. swiftType) .bridgeJSLiftParameter( \( argNames. joined ( separator: " , " ) ) ) "
158- )
159- }
160-
161- let tryPrefix = signature. isThrows ? " try " : " "
162- let closureCallExpr = ExprSyntax ( " \( raw: tryPrefix) closure( \( raw: liftedParams. joined ( separator: " , " ) ) ) " )
163- let asyncTryPrefix = ( signature. isThrows ? " try " : " " ) + " await "
164- let asyncClosureCallExpr = ExprSyntax (
165- " \( raw: asyncTryPrefix) closure( \( raw: liftedParams. joined ( separator: " , " ) ) ) "
141+ let builder = try ExportSwift . ExportedThunkBuilder (
142+ effects: Effects ( isAsync: signature. isAsync, isThrows: signature. isThrows) ,
143+ returnType: signature. returnType
166144 )
167-
168- let abiReturnWasmType =
169- signature. isAsync
170- ? try BridgeType . jsObject ( nil ) . loweringReturnInfo ( ) . returnType
171- : try signature. returnType. loweringReturnInfo ( ) . returnType
172-
173- // Build signature using SwiftSignatureBuilder
174- let funcSignature = SwiftSignatureBuilder . buildABIFunctionSignature (
175- abiParameters: abiParams,
176- returnType: abiReturnWasmType
145+ builder. abiParameterSignatures. append ( ( " boxPtr " , . pointer) )
146+ builder. parameterBindings. append (
147+ " let closure = Unmanaged< \( raw: boxType) >.fromOpaque(boxPtr).takeUnretainedValue().closure "
177148 )
178-
179- let emitCallAndLower : ( CodeFragmentPrinter ) -> Void = { printer in
180- if signature. returnType == . void {
181- printer. write ( closureCallExpr. description)
182- } else {
183- printer. write ( " let result = \( closureCallExpr) " )
184- switch signature. returnType {
185- case . swiftProtocol( let protocolName) :
186- printer. write (
187- " return _bridgeJSUnwrapProtocolExportable(result, \" \( protocolName) \" ).bridgeJSLowerAsProtocolReturn() "
188- )
189- case . nullable( . swiftProtocol( let protocolName) , _) :
190- printer. write ( " if let result { " )
191- printer. indent {
192- printer. write (
193- " _swift_js_return_optional_object(1, _bridgeJSUnwrapProtocolExportable(result, \" \( protocolName) \" ).bridgeJSLowerAsProtocolReturn()) "
194- )
195- }
196- printer. write ( " } else { " )
197- printer. indent {
198- printer. write ( " _swift_js_return_optional_object(0, 0) " )
199- }
200- printer. write ( " } " )
201- default :
202- printer. write ( " return result.bridgeJSLowerReturn() " )
203- }
204- }
205- }
206-
207- let emitAsyncCallAndLower : ( CodeFragmentPrinter ) -> Void = { printer in
208- printer. write ( " let closure = Unmanaged< \( boxType) >.fromOpaque(boxPtr).takeUnretainedValue().closure " )
209- let resolveType = signature. returnType
210- let resolveName = " Promise_resolve_ \( resolveType. mangleTypeName) "
211- let rejectName = " Promise_reject "
212- let closureHead : String
213- if signature. isThrows {
214- let returnSpelling = resolveType == . void ? " " : " -> \( resolveType. closureSwiftType) "
215- closureHead = " () async throws(JSException) \( returnSpelling) in "
216- } else {
217- closureHead = " "
218- }
219- printer. write ( " return _bjs_makePromise(resolve: \( resolveName) , reject: \( rejectName) ) { \( closureHead) " )
220- printer. indent {
221- if resolveType == . void {
222- printer. write ( asyncClosureCallExpr. description)
223- } else {
224- printer. write ( " return \( asyncClosureCallExpr) " )
225- }
226- }
227- printer. write ( " } " )
228- }
229-
230- let catchPlaceholderStmt = abiReturnWasmType? . swiftReturnPlaceholderStmt
231-
232- // Build function declaration using helper
233- let funcDecl = SwiftCodePattern . buildExposedFunctionDecl (
234- abiName: abiName,
235- signature: funcSignature
236- ) { printer in
237- if signature. isAsync {
238- emitAsyncCallAndLower ( printer)
239- } else if signature. isThrows {
240- printer. write (
241- " let closure = Unmanaged< \( boxType) >.fromOpaque(boxPtr).takeUnretainedValue().closure "
242- )
243- printer. write ( " do { " )
244- printer. indent {
245- emitCallAndLower ( printer)
246- }
247- printer. write ( " } catch let error { " )
248- printer. indent {
249- printer. write ( " if let error = error.thrownValue.object { " )
250- printer. indent {
251- printer. write ( " withExtendedLifetime(error) { " )
252- printer. indent {
253- printer. write ( " _swift_js_throw(Int32(bitPattern: $0.id)) " )
254- }
255- printer. write ( " } " )
256- }
257- printer. write ( " } else { " )
258- printer. indent {
259- printer. write ( " let jsError = JSError(message: error.description) " )
260- printer. write ( " withExtendedLifetime(jsError.jsObject) { " )
261- printer. indent {
262- printer. write ( " _swift_js_throw(Int32(bitPattern: $0.id)) " )
263- }
264- printer. write ( " } " )
265- }
266- printer. write ( " } " )
267- if let catchPlaceholderStmt {
268- printer. write ( catchPlaceholderStmt)
269- }
270- }
271- printer. write ( " } " )
272- } else {
273- printer. write (
274- " let closure = Unmanaged< \( boxType) >.fromOpaque(boxPtr).takeUnretainedValue().closure "
275- )
276- emitCallAndLower ( printer)
277- }
149+ for (index, paramType) in signature. parameters. enumerated ( ) {
150+ try builder. liftParameter (
151+ param: Parameter ( label: nil , name: " param \( index) " , type: paramType)
152+ )
278153 }
279-
280- return DeclSyntax ( funcDecl)
154+ builder. call ( name: " closure " , returnType: signature. returnType)
155+ try builder. lowerReturnValue ( returnType: signature. returnType)
156+ return builder. render ( abiName: abiName)
281157 }
282158
283159 public func renderSupport( for skeleton: BridgeJSSkeleton ) throws -> String ? {
0 commit comments