Skip to content

Commit 6bb09b6

Browse files
Merge pull request #659 from swiftwasm/yt/workaround-extern-inlining
[NFC] BridgeJS: Work around extern inlining by adding an extra non-inlined layer of indirection
2 parents 8bbf832 + aa961dc commit 6bb09b6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+3021
-1117
lines changed

Benchmarks/Sources/Generated/BridgeJS.swift

Lines changed: 110 additions & 44 deletions
Large diffs are not rendered by default.

Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/BridgeJS.swift

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -37,21 +37,27 @@ extension PlayBridgeJSOutput: _BridgedSwiftStruct {
3737

3838
#if arch(wasm32)
3939
@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_PlayBridgeJSOutput")
40-
fileprivate func _bjs_struct_lower_PlayBridgeJSOutput(_ objectId: Int32) -> Void
40+
fileprivate func _bjs_struct_lower_PlayBridgeJSOutput_extern(_ objectId: Int32) -> Void
4141
#else
42-
fileprivate func _bjs_struct_lower_PlayBridgeJSOutput(_ objectId: Int32) -> Void {
42+
fileprivate func _bjs_struct_lower_PlayBridgeJSOutput_extern(_ objectId: Int32) -> Void {
4343
fatalError("Only available on WebAssembly")
4444
}
4545
#endif
46+
@inline(never) fileprivate func _bjs_struct_lower_PlayBridgeJSOutput(_ objectId: Int32) -> Void {
47+
return _bjs_struct_lower_PlayBridgeJSOutput_extern(objectId)
48+
}
4649

4750
#if arch(wasm32)
4851
@_extern(wasm, module: "bjs", name: "swift_js_struct_lift_PlayBridgeJSOutput")
49-
fileprivate func _bjs_struct_lift_PlayBridgeJSOutput() -> Int32
52+
fileprivate func _bjs_struct_lift_PlayBridgeJSOutput_extern() -> Int32
5053
#else
51-
fileprivate func _bjs_struct_lift_PlayBridgeJSOutput() -> Int32 {
54+
fileprivate func _bjs_struct_lift_PlayBridgeJSOutput_extern() -> Int32 {
5255
fatalError("Only available on WebAssembly")
5356
}
5457
#endif
58+
@inline(never) fileprivate func _bjs_struct_lift_PlayBridgeJSOutput() -> Int32 {
59+
return _bjs_struct_lift_PlayBridgeJSOutput_extern()
60+
}
5561

5662
extension PlayBridgeJSDiagnostic: _BridgedSwiftStruct {
5763
@_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> PlayBridgeJSDiagnostic {
@@ -87,21 +93,27 @@ extension PlayBridgeJSDiagnostic: _BridgedSwiftStruct {
8793

8894
#if arch(wasm32)
8995
@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_PlayBridgeJSDiagnostic")
90-
fileprivate func _bjs_struct_lower_PlayBridgeJSDiagnostic(_ objectId: Int32) -> Void
96+
fileprivate func _bjs_struct_lower_PlayBridgeJSDiagnostic_extern(_ objectId: Int32) -> Void
9197
#else
92-
fileprivate func _bjs_struct_lower_PlayBridgeJSDiagnostic(_ objectId: Int32) -> Void {
98+
fileprivate func _bjs_struct_lower_PlayBridgeJSDiagnostic_extern(_ objectId: Int32) -> Void {
9399
fatalError("Only available on WebAssembly")
94100
}
95101
#endif
102+
@inline(never) fileprivate func _bjs_struct_lower_PlayBridgeJSDiagnostic(_ objectId: Int32) -> Void {
103+
return _bjs_struct_lower_PlayBridgeJSDiagnostic_extern(objectId)
104+
}
96105

97106
#if arch(wasm32)
98107
@_extern(wasm, module: "bjs", name: "swift_js_struct_lift_PlayBridgeJSDiagnostic")
99-
fileprivate func _bjs_struct_lift_PlayBridgeJSDiagnostic() -> Int32
108+
fileprivate func _bjs_struct_lift_PlayBridgeJSDiagnostic_extern() -> Int32
100109
#else
101-
fileprivate func _bjs_struct_lift_PlayBridgeJSDiagnostic() -> Int32 {
110+
fileprivate func _bjs_struct_lift_PlayBridgeJSDiagnostic_extern() -> Int32 {
102111
fatalError("Only available on WebAssembly")
103112
}
104113
#endif
114+
@inline(never) fileprivate func _bjs_struct_lift_PlayBridgeJSDiagnostic() -> Int32 {
115+
return _bjs_struct_lift_PlayBridgeJSDiagnostic_extern()
116+
}
105117

106118
extension PlayBridgeJSResult: _BridgedSwiftStruct {
107119
@_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> PlayBridgeJSResult {
@@ -129,21 +141,27 @@ extension PlayBridgeJSResult: _BridgedSwiftStruct {
129141

130142
#if arch(wasm32)
131143
@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_PlayBridgeJSResult")
132-
fileprivate func _bjs_struct_lower_PlayBridgeJSResult(_ objectId: Int32) -> Void
144+
fileprivate func _bjs_struct_lower_PlayBridgeJSResult_extern(_ objectId: Int32) -> Void
133145
#else
134-
fileprivate func _bjs_struct_lower_PlayBridgeJSResult(_ objectId: Int32) -> Void {
146+
fileprivate func _bjs_struct_lower_PlayBridgeJSResult_extern(_ objectId: Int32) -> Void {
135147
fatalError("Only available on WebAssembly")
136148
}
137149
#endif
150+
@inline(never) fileprivate func _bjs_struct_lower_PlayBridgeJSResult(_ objectId: Int32) -> Void {
151+
return _bjs_struct_lower_PlayBridgeJSResult_extern(objectId)
152+
}
138153

139154
#if arch(wasm32)
140155
@_extern(wasm, module: "bjs", name: "swift_js_struct_lift_PlayBridgeJSResult")
141-
fileprivate func _bjs_struct_lift_PlayBridgeJSResult() -> Int32
156+
fileprivate func _bjs_struct_lift_PlayBridgeJSResult_extern() -> Int32
142157
#else
143-
fileprivate func _bjs_struct_lift_PlayBridgeJSResult() -> Int32 {
158+
fileprivate func _bjs_struct_lift_PlayBridgeJSResult_extern() -> Int32 {
144159
fatalError("Only available on WebAssembly")
145160
}
146161
#endif
162+
@inline(never) fileprivate func _bjs_struct_lift_PlayBridgeJSResult() -> Int32 {
163+
return _bjs_struct_lift_PlayBridgeJSResult_extern()
164+
}
147165

148166
@_expose(wasm, "bjs_PlayBridgeJS_init")
149167
@_cdecl("bjs_PlayBridgeJS_init")
@@ -199,21 +217,27 @@ extension PlayBridgeJS: ConvertibleToJSValue, _BridgedSwiftHeapObject {
199217

200218
#if arch(wasm32)
201219
@_extern(wasm, module: "PlayBridgeJS", name: "bjs_PlayBridgeJS_wrap")
202-
fileprivate func _bjs_PlayBridgeJS_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32
220+
fileprivate func _bjs_PlayBridgeJS_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32
203221
#else
204-
fileprivate func _bjs_PlayBridgeJS_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 {
222+
fileprivate func _bjs_PlayBridgeJS_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 {
205223
fatalError("Only available on WebAssembly")
206224
}
207225
#endif
226+
@inline(never) fileprivate func _bjs_PlayBridgeJS_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 {
227+
return _bjs_PlayBridgeJS_wrap_extern(pointer)
228+
}
208229

209230
#if arch(wasm32)
210231
@_extern(wasm, module: "PlayBridgeJS", name: "bjs_createTS2Swift")
211-
fileprivate func bjs_createTS2Swift() -> Int32
232+
fileprivate func bjs_createTS2Swift_extern() -> Int32
212233
#else
213-
fileprivate func bjs_createTS2Swift() -> Int32 {
234+
fileprivate func bjs_createTS2Swift_extern() -> Int32 {
214235
fatalError("Only available on WebAssembly")
215236
}
216237
#endif
238+
@inline(never) fileprivate func bjs_createTS2Swift() -> Int32 {
239+
return bjs_createTS2Swift_extern()
240+
}
217241

218242
func _$createTS2Swift() throws(JSException) -> TS2Swift {
219243
let ret = bjs_createTS2Swift()
@@ -225,12 +249,15 @@ func _$createTS2Swift() throws(JSException) -> TS2Swift {
225249

226250
#if arch(wasm32)
227251
@_extern(wasm, module: "PlayBridgeJS", name: "bjs_TS2Swift_convert")
228-
fileprivate func bjs_TS2Swift_convert(_ self: Int32, _ ts: Int32) -> Int32
252+
fileprivate func bjs_TS2Swift_convert_extern(_ self: Int32, _ ts: Int32) -> Int32
229253
#else
230-
fileprivate func bjs_TS2Swift_convert(_ self: Int32, _ ts: Int32) -> Int32 {
254+
fileprivate func bjs_TS2Swift_convert_extern(_ self: Int32, _ ts: Int32) -> Int32 {
231255
fatalError("Only available on WebAssembly")
232256
}
233257
#endif
258+
@inline(never) fileprivate func bjs_TS2Swift_convert(_ self: Int32, _ ts: Int32) -> Int32 {
259+
return bjs_TS2Swift_convert_extern(self, ts)
260+
}
234261

235262
func _$TS2Swift_convert(_ self: JSObject, _ ts: String) throws(JSException) -> String {
236263
let selfValue = self.bridgeJSLowerParameter()

Plugins/BridgeJS/Sources/BridgeJSCore/ClosureCodegen.swift

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,17 +46,17 @@ public struct ClosureCodegen {
4646

4747
// Generate extern declaration using CallJSEmission
4848
let externDecl = builder.renderImportDecl()
49-
50-
let makeClosureExternDecl: DeclSyntax = """
51-
#if arch(wasm32)
52-
@_extern(wasm, module: "bjs", name: "make_swift_closure_\(raw: signature.moduleName)_\(raw: signature.mangleName)")
53-
fileprivate func make_swift_closure_\(raw: signature.moduleName)_\(raw: signature.mangleName)(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer<UInt8>, _ line: UInt32) -> Int32
54-
#else
55-
fileprivate func make_swift_closure_\(raw: signature.moduleName)_\(raw: signature.mangleName)(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer<UInt8>, _ line: UInt32) -> Int32 {
56-
fatalError("Only available on WebAssembly")
57-
}
58-
#endif
59-
"""
49+
let externABIName = "make_swift_closure_\(signature.moduleName)_\(signature.mangleName)"
50+
let externDeclPrinter = CodeFragmentPrinter()
51+
SwiftCodePattern.buildExternFunctionDecl(
52+
printer: externDeclPrinter,
53+
moduleName: "bjs",
54+
abiName: externABIName,
55+
functionName: externABIName,
56+
signature: "(_ boxPtr: UnsafeMutableRawPointer, _ file: UnsafePointer<UInt8>, _ line: UInt32) -> Int32",
57+
parameterNames: ["boxPtr", "file", "line"]
58+
)
59+
let makeClosureExternDecl: DeclSyntax = "\(raw: externDeclPrinter.lines.joined(separator: "\n"))"
6060

6161
let helperEnumDeclPrinter = CodeFragmentPrinter()
6262
helperEnumDeclPrinter.write("private enum \(helperName) {")
@@ -98,7 +98,7 @@ public struct ClosureCodegen {
9898
extension JSTypedClosure where Signature == \(raw: swiftClosureType) {
9999
init(fileID: StaticString = #fileID, line: UInt32 = #line, _ body: @escaping \(raw: swiftClosureType)) {
100100
self.init(
101-
makeClosure: make_swift_closure_\(raw: signature.moduleName)_\(raw: signature.mangleName),
101+
makeClosure: \(raw: externABIName),
102102
body: body,
103103
fileID: fileID,
104104
line: line

Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift

Lines changed: 22 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -695,32 +695,14 @@ public class ExportSwift {
695695
}
696696
"""
697697
// Build common function signature
698-
let funcSignature = SwiftSignatureBuilder.buildABIFunctionSignature(
699-
abiParameters: [("pointer", .pointer)],
700-
returnType: .i32
701-
)
702-
703698
let externDeclPrinter = CodeFragmentPrinter()
704-
SwiftCodePattern.buildWasmConditionalCompilationDecls(
699+
SwiftCodePattern.buildExternFunctionDecl(
705700
printer: externDeclPrinter,
706-
wasmDecl: { printer in
707-
SwiftCodePattern.buildExternFunctionDecl(
708-
printer: printer,
709-
moduleName: moduleName,
710-
abiName: externFunctionName,
711-
functionName: wrapFunctionName,
712-
signature: funcSignature
713-
)
714-
},
715-
elseDecl: { printer in
716-
printer.write(
717-
multilineString: """
718-
fileprivate func \(wrapFunctionName)\(funcSignature) {
719-
fatalError("Only available on WebAssembly")
720-
}
721-
"""
722-
)
723-
}
701+
moduleName: moduleName,
702+
abiName: externFunctionName,
703+
functionName: wrapFunctionName,
704+
abiParameters: [("pointer", .pointer)],
705+
returnType: .i32
724706
)
725707
let externDecl: DeclSyntax = "\(raw: externDeclPrinter.lines.joined(separator: "\n"))"
726708
return [extensionDecl, externDecl]
@@ -1265,24 +1247,22 @@ struct StructCodegen {
12651247
let bridgedStructExtension: DeclSyntax = "\(raw: printer.lines.joined(separator: "\n"))"
12661248

12671249
let lowerExternDeclPrinter = CodeFragmentPrinter()
1268-
Self.renderStructExtern(
1250+
SwiftCodePattern.buildExternFunctionDecl(
12691251
printer: lowerExternDeclPrinter,
1270-
externName: lowerExternName,
1252+
moduleName: "bjs",
1253+
abiName: lowerExternName,
12711254
functionName: lowerFunctionName,
1272-
signature: SwiftSignatureBuilder.buildABIFunctionSignature(
1273-
abiParameters: [("objectId", .i32)],
1274-
returnType: nil
1275-
)
1255+
abiParameters: [("objectId", .i32)],
1256+
returnType: nil
12761257
)
12771258
let liftExternDeclPrinter = CodeFragmentPrinter()
1278-
Self.renderStructExtern(
1259+
SwiftCodePattern.buildExternFunctionDecl(
12791260
printer: liftExternDeclPrinter,
1280-
externName: liftExternName,
1261+
moduleName: "bjs",
1262+
abiName: liftExternName,
12811263
functionName: liftFunctionName,
1282-
signature: SwiftSignatureBuilder.buildABIFunctionSignature(
1283-
abiParameters: [],
1284-
returnType: .i32
1285-
)
1264+
abiParameters: [],
1265+
returnType: .i32
12861266
)
12871267

12881268
return [
@@ -1291,35 +1271,6 @@ struct StructCodegen {
12911271
]
12921272
}
12931273

1294-
private static func renderStructExtern(
1295-
printer: CodeFragmentPrinter,
1296-
externName: String,
1297-
functionName: String,
1298-
signature: String
1299-
) {
1300-
SwiftCodePattern.buildWasmConditionalCompilationDecls(
1301-
printer: printer,
1302-
wasmDecl: { printer in
1303-
SwiftCodePattern.buildExternFunctionDecl(
1304-
printer: printer,
1305-
moduleName: "bjs",
1306-
abiName: externName,
1307-
functionName: functionName,
1308-
signature: signature
1309-
)
1310-
},
1311-
elseDecl: { printer in
1312-
printer.write(
1313-
multilineString: """
1314-
fileprivate func \(functionName)\(signature) {
1315-
fatalError("Only available on WebAssembly")
1316-
}
1317-
"""
1318-
)
1319-
}
1320-
)
1321-
}
1322-
13231274
private func generateStructLiftCode(structDef: ExportedStruct) -> [String] {
13241275
var lines: [String] = []
13251276
let instanceProps = structDef.properties.filter { !$0.isStatic }
@@ -1385,17 +1336,14 @@ struct ProtocolCodegen {
13851336
)
13861337

13871338
// Build extern declaration using helper function
1388-
let externSignature = SwiftSignatureBuilder.buildABIFunctionSignature(
1389-
abiParameters: builder.abiParameterSignatures,
1390-
returnType: builder.abiReturnType
1391-
)
13921339
let externDeclPrinter = CodeFragmentPrinter()
13931340
SwiftCodePattern.buildExternFunctionDecl(
13941341
printer: externDeclPrinter,
13951342
moduleName: moduleName,
13961343
abiName: method.abiName,
13971344
functionName: "_extern_\(method.name)",
1398-
signature: externSignature
1345+
abiParameters: builder.abiParameterSignatures,
1346+
returnType: builder.abiReturnType
13991347
)
14001348
externDecls.append(DeclSyntax("\(raw: externDeclPrinter.lines.joined(separator: "\n"))"))
14011349
let methodImplPrinter = CodeFragmentPrinter()
@@ -1476,17 +1424,14 @@ struct ProtocolCodegen {
14761424
try getterBuilder.liftReturnValue(returnType: property.type)
14771425

14781426
// Build getter extern declaration using helper function
1479-
let getterExternSignature = SwiftSignatureBuilder.buildABIFunctionSignature(
1480-
abiParameters: getterBuilder.abiParameterSignatures,
1481-
returnType: getterBuilder.abiReturnType
1482-
)
14831427
let getterExternDeclPrinter = CodeFragmentPrinter()
14841428
SwiftCodePattern.buildExternFunctionDecl(
14851429
printer: getterExternDeclPrinter,
14861430
moduleName: moduleName,
14871431
abiName: getterAbiName,
14881432
functionName: getterAbiName,
1489-
signature: getterExternSignature
1433+
abiParameters: getterBuilder.abiParameterSignatures,
1434+
returnType: getterBuilder.abiReturnType
14901435
)
14911436
let getterExternDecl = DeclSyntax("\(raw: getterExternDeclPrinter.lines.joined(separator: "\n"))")
14921437
var externDecls: [DeclSyntax] = [getterExternDecl]
@@ -1511,17 +1456,14 @@ struct ProtocolCodegen {
15111456
try setterBuilder.call(returnType: .void)
15121457

15131458
// Build setter extern declaration using helper function
1514-
let setterExternSignature = SwiftSignatureBuilder.buildABIFunctionSignature(
1515-
abiParameters: setterBuilder.abiParameterSignatures,
1516-
returnType: setterBuilder.abiReturnType
1517-
)
15181459
let setterExternDeclPrinter = CodeFragmentPrinter()
15191460
SwiftCodePattern.buildExternFunctionDecl(
15201461
printer: setterExternDeclPrinter,
15211462
moduleName: moduleName,
15221463
abiName: setterAbiName,
15231464
functionName: setterAbiName,
1524-
signature: setterExternSignature
1465+
abiParameters: setterBuilder.abiParameterSignatures,
1466+
returnType: setterBuilder.abiReturnType
15251467
)
15261468
let setterExternDecl = DeclSyntax("\(raw: setterExternDeclPrinter.lines.joined(separator: "\n"))")
15271469
externDecls.append(setterExternDecl)

0 commit comments

Comments
 (0)