Skip to content

Commit 2699257

Browse files
BridgeJS: Standardize lift/lower pattern across Swift and JavaScript
Replace global intrinsic functions with consistent extension-based system. Each bridged type now defines standardized lift/lower operations: Swift side (type extensions): - bridgeJSLowerParameter/Return: Swift -> Wasm core types - bridgeJSLiftParameter/Return: Wasm core types -> Swift JavaScript side (JSGlueGen): - Corresponding lift/lower functions for JS <-> Wasm interop Adds CodeFragmentPrinter for improved code organization. Reduces generated code complexity across both Swift and JS.
1 parent 8cedac7 commit 2699257

Some content is hidden

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

44 files changed

+1033
-994
lines changed

Benchmarks/Sources/Generated/BridgeJS.ImportTS.swift

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,7 @@ func benchmarkRunner(_ name: String, _ body: JSObject) throws(JSException) -> Vo
4545
fatalError("Only available on WebAssembly")
4646
}
4747
#endif
48-
var name = name
49-
let nameId = name.withUTF8 { b in
50-
_swift_js_make_js_string(b.baseAddress.unsafelyUnwrapped, Int32(b.count))
51-
}
52-
bjs_benchmarkRunner(nameId, Int32(bitPattern: body.id))
48+
bjs_benchmarkRunner(name.bridgeJSLowerParameter(), body.bridgeJSLowerParameter())
5349
if let error = _swift_js_take_exception() {
5450
throw error
5551
}

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

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,7 @@ public func _bjs_PlayBridgeJS_init() -> UnsafeMutableRawPointer {
2222
public func _bjs_PlayBridgeJS_update(_self: UnsafeMutableRawPointer, swiftSourceBytes: Int32, swiftSourceLen: Int32, dtsSourceBytes: Int32, dtsSourceLen: Int32) -> UnsafeMutableRawPointer {
2323
#if arch(wasm32)
2424
do {
25-
let swiftSource = String(unsafeUninitializedCapacity: Int(swiftSourceLen)) { b in
26-
_swift_js_init_memory(swiftSourceBytes, b.baseAddress.unsafelyUnwrapped)
27-
return Int(swiftSourceLen)
28-
}
29-
let dtsSource = String(unsafeUninitializedCapacity: Int(dtsSourceLen)) { b in
30-
_swift_js_init_memory(dtsSourceBytes, b.baseAddress.unsafelyUnwrapped)
31-
return Int(dtsSourceLen)
32-
}
33-
let ret = try Unmanaged<PlayBridgeJS>.fromOpaque(_self).takeUnretainedValue().update(swiftSource: swiftSource, dtsSource: dtsSource)
25+
let ret = try Unmanaged<PlayBridgeJS>.fromOpaque(_self).takeUnretainedValue().update(swiftSource: String.bridgeJSLiftParameter(swiftSourceBytes, swiftSourceLen), dtsSource: String.bridgeJSLiftParameter(dtsSourceBytes, dtsSourceLen))
3426
return Unmanaged.passRetained(ret).toOpaque()
3527
} catch let error {
3628
if let error = error.thrownValue.object {
@@ -68,10 +60,8 @@ extension PlayBridgeJS: ConvertibleToJSValue {
6860
@_cdecl("bjs_PlayBridgeJSOutput_outputJs")
6961
public func _bjs_PlayBridgeJSOutput_outputJs(_self: UnsafeMutableRawPointer) -> Void {
7062
#if arch(wasm32)
71-
var ret = Unmanaged<PlayBridgeJSOutput>.fromOpaque(_self).takeUnretainedValue().outputJs()
72-
return ret.withUTF8 { ptr in
73-
_swift_js_return_string(ptr.baseAddress, Int32(ptr.count))
74-
}
63+
let ret = Unmanaged<PlayBridgeJSOutput>.fromOpaque(_self).takeUnretainedValue().outputJs()
64+
return ret.bridgeJSLowerReturn()
7565
#else
7666
fatalError("Only available on WebAssembly")
7767
#endif
@@ -81,10 +71,8 @@ public func _bjs_PlayBridgeJSOutput_outputJs(_self: UnsafeMutableRawPointer) ->
8171
@_cdecl("bjs_PlayBridgeJSOutput_outputDts")
8272
public func _bjs_PlayBridgeJSOutput_outputDts(_self: UnsafeMutableRawPointer) -> Void {
8373
#if arch(wasm32)
84-
var ret = Unmanaged<PlayBridgeJSOutput>.fromOpaque(_self).takeUnretainedValue().outputDts()
85-
return ret.withUTF8 { ptr in
86-
_swift_js_return_string(ptr.baseAddress, Int32(ptr.count))
87-
}
74+
let ret = Unmanaged<PlayBridgeJSOutput>.fromOpaque(_self).takeUnretainedValue().outputDts()
75+
return ret.bridgeJSLowerReturn()
8876
#else
8977
fatalError("Only available on WebAssembly")
9078
#endif
@@ -94,10 +82,8 @@ public func _bjs_PlayBridgeJSOutput_outputDts(_self: UnsafeMutableRawPointer) ->
9482
@_cdecl("bjs_PlayBridgeJSOutput_importSwiftGlue")
9583
public func _bjs_PlayBridgeJSOutput_importSwiftGlue(_self: UnsafeMutableRawPointer) -> Void {
9684
#if arch(wasm32)
97-
var ret = Unmanaged<PlayBridgeJSOutput>.fromOpaque(_self).takeUnretainedValue().importSwiftGlue()
98-
return ret.withUTF8 { ptr in
99-
_swift_js_return_string(ptr.baseAddress, Int32(ptr.count))
100-
}
85+
let ret = Unmanaged<PlayBridgeJSOutput>.fromOpaque(_self).takeUnretainedValue().importSwiftGlue()
86+
return ret.bridgeJSLowerReturn()
10187
#else
10288
fatalError("Only available on WebAssembly")
10389
#endif
@@ -107,10 +93,8 @@ public func _bjs_PlayBridgeJSOutput_importSwiftGlue(_self: UnsafeMutableRawPoint
10793
@_cdecl("bjs_PlayBridgeJSOutput_exportSwiftGlue")
10894
public func _bjs_PlayBridgeJSOutput_exportSwiftGlue(_self: UnsafeMutableRawPointer) -> Void {
10995
#if arch(wasm32)
110-
var ret = Unmanaged<PlayBridgeJSOutput>.fromOpaque(_self).takeUnretainedValue().exportSwiftGlue()
111-
return ret.withUTF8 { ptr in
112-
_swift_js_return_string(ptr.baseAddress, Int32(ptr.count))
113-
}
96+
let ret = Unmanaged<PlayBridgeJSOutput>.fromOpaque(_self).takeUnretainedValue().exportSwiftGlue()
97+
return ret.bridgeJSLowerReturn()
11498
#else
11599
fatalError("Only available on WebAssembly")
116100
#endif

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

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,18 +42,11 @@ struct TS2Skeleton {
4242
fatalError("Only available on WebAssembly")
4343
}
4444
#endif
45-
var ts = ts
46-
let tsId = ts.withUTF8 { b in
47-
_swift_js_make_js_string(b.baseAddress.unsafelyUnwrapped, Int32(b.count))
48-
}
49-
let ret = bjs_TS2Skeleton_convert(Int32(bitPattern: self.this.id), tsId)
45+
let ret = bjs_TS2Skeleton_convert(self.this.bridgeJSLowerParameter(), ts.bridgeJSLowerParameter())
5046
if let error = _swift_js_take_exception() {
5147
throw error
5248
}
53-
return String(unsafeUninitializedCapacity: Int(ret)) { b in
54-
_swift_js_init_memory_with_result(b.baseAddress.unsafelyUnwrapped, Int32(ret))
55-
return Int(ret)
56-
}
49+
return String.bridgeJSLiftReturn(ret)
5750
}
5851

5952
}

Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift

Lines changed: 27 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -782,10 +782,14 @@ public class ExportSwift {
782782
parameters.append(param)
783783
switch param.type {
784784
case .bool:
785-
liftedParameterExprs.append(ExprSyntax("\(raw: param.name) == 1"))
785+
liftedParameterExprs.append(
786+
ExprSyntax("\(raw: param.type.swiftType).bridgeJSLiftParameter(\(raw: param.name))")
787+
)
786788
abiParameterSignatures.append((param.name, .i32))
787789
case .int:
788-
liftedParameterExprs.append(ExprSyntax("\(raw: param.type.swiftType)(\(raw: param.name))"))
790+
liftedParameterExprs.append(
791+
ExprSyntax("\(raw: param.type.swiftType).bridgeJSLiftParameter(\(raw: param.name))")
792+
)
789793
abiParameterSignatures.append((param.name, .i32))
790794
case .float:
791795
liftedParameterExprs.append(ExprSyntax("\(raw: param.name)"))
@@ -796,14 +800,11 @@ public class ExportSwift {
796800
case .string:
797801
let bytesLabel = "\(param.name)Bytes"
798802
let lengthLabel = "\(param.name)Len"
799-
let prepare: CodeBlockItemSyntax = """
800-
let \(raw: param.name) = String(unsafeUninitializedCapacity: Int(\(raw: lengthLabel))) { b in
801-
_swift_js_init_memory(\(raw: bytesLabel), b.baseAddress.unsafelyUnwrapped)
802-
return Int(\(raw: lengthLabel))
803-
}
804-
"""
805-
append(prepare)
806-
liftedParameterExprs.append(ExprSyntax("\(raw: param.name)"))
803+
liftedParameterExprs.append(
804+
ExprSyntax(
805+
"\(raw: param.type.swiftType).bridgeJSLiftParameter(\(raw: bytesLabel), \(raw: lengthLabel))"
806+
)
807+
)
807808
abiParameterSignatures.append((bytesLabel, .i32))
808809
abiParameterSignatures.append((lengthLabel, .i32))
809810
case .caseEnum(let enumName):
@@ -813,21 +814,19 @@ public class ExportSwift {
813814
if rawType == .string {
814815
let bytesLabel = "\(param.name)Bytes"
815816
let lengthLabel = "\(param.name)Len"
816-
let prepare: CodeBlockItemSyntax = """
817-
let \(raw: param.name) = String(unsafeUninitializedCapacity: Int(\(raw: lengthLabel))) { b in
818-
_swift_js_init_memory(\(raw: bytesLabel), b.baseAddress.unsafelyUnwrapped)
819-
return Int(\(raw: lengthLabel))
820-
}
821-
"""
822-
append(prepare)
823-
liftedParameterExprs.append(ExprSyntax("\(raw: enumName)(rawValue: \(raw: param.name))!"))
817+
liftedParameterExprs.append(
818+
ExprSyntax(
819+
"\(raw: enumName)(rawValue: String.bridgeJSLiftParameter(\(raw: bytesLabel), \(raw: lengthLabel)))!"
820+
)
821+
)
824822
abiParameterSignatures.append((bytesLabel, .i32))
825823
abiParameterSignatures.append((lengthLabel, .i32))
826824
} else {
827825
let conversionExpr: String
828826
switch rawType {
829827
case .bool:
830-
conversionExpr = "\(enumName)(rawValue: \(param.name) != 0)!"
828+
conversionExpr =
829+
"\(enumName)(rawValue: \(param.type.swiftType).bridgeJSLiftParameter(\(param.name)))"
831830
case .uint, .uint32, .uint64:
832831
if rawType == .uint64 {
833832
conversionExpr =
@@ -848,12 +847,9 @@ public class ExportSwift {
848847
break
849848
case .namespaceEnum:
850849
break
851-
case .jsObject(nil):
852-
liftedParameterExprs.append(ExprSyntax("JSObject(id: UInt32(bitPattern: \(raw: param.name)))"))
853-
abiParameterSignatures.append((param.name, .i32))
854850
case .jsObject(let name):
855851
liftedParameterExprs.append(
856-
ExprSyntax("\(raw: name)(takingThis: UInt32(bitPattern: \(raw: param.name)))")
852+
ExprSyntax("\(raw: name ?? "JSObject").bridgeJSLiftParameter(\(raw: param.name))")
857853
)
858854
abiParameterSignatures.append((param.name, .i32))
859855
case .swiftHeapObject:
@@ -896,16 +892,10 @@ public class ExportSwift {
896892
return CodeBlockItemSyntax(item: .init(StmtSyntax("return \(raw: callExpr).jsValue")))
897893
}
898894

899-
let retMutability: String
900-
if returnType == .string {
901-
retMutability = "var"
902-
} else {
903-
retMutability = "let"
904-
}
905895
if returnType == .void {
906896
return CodeBlockItemSyntax(item: .init(ExpressionStmtSyntax(expression: callExpr)))
907897
} else {
908-
return CodeBlockItemSyntax(item: .init(DeclSyntax("\(raw: retMutability) ret = \(raw: callExpr)")))
898+
return CodeBlockItemSyntax(item: .init(DeclSyntax("let ret = \(raw: callExpr)")))
909899
}
910900
}
911901

@@ -925,11 +915,10 @@ public class ExportSwift {
925915

926916
func callPropertyGetter(klassName: String, propertyName: String, returnType: BridgeType) {
927917
let (_, selfExpr) = removeFirstLiftedParameter()
928-
let retMutability = returnType == .string ? "var" : "let"
929918
if returnType == .void {
930919
append("\(raw: selfExpr).\(raw: propertyName)")
931920
} else {
932-
append("\(raw: retMutability) ret = \(raw: selfExpr).\(raw: propertyName)")
921+
append("let ret = \(raw: selfExpr).\(raw: propertyName)")
933922
}
934923
}
935924

@@ -988,26 +977,17 @@ public class ExportSwift {
988977
case .int, .float, .double:
989978
append("return \(raw: abiReturnType!.swiftType)(ret)")
990979
case .bool:
991-
append("return Int32(ret ? 1 : 0)")
980+
append("return ret.bridgeJSLowerReturn()")
992981
case .string:
993-
append(
994-
"""
995-
return ret.withUTF8 { ptr in
996-
_swift_js_return_string(ptr.baseAddress, Int32(ptr.count))
997-
}
998-
"""
999-
)
982+
append("return ret.bridgeJSLowerReturn()")
1000983
case .caseEnum:
1001984
abiReturnType = .i32
1002985
append("return ret.bridgeJSRawValue")
1003986
case .rawValueEnum(_, let rawType):
1004987
if rawType == .string {
1005988
append(
1006989
"""
1007-
var rawValue = ret.rawValue
1008-
return rawValue.withUTF8 { ptr in
1009-
_swift_js_return_string(ptr.baseAddress, Int32(ptr.count))
1010-
}
990+
return ret.rawValue.bridgeJSLowerReturn()
1011991
"""
1012992
)
1013993
} else {
@@ -1028,18 +1008,8 @@ public class ExportSwift {
10281008
}
10291009
case .associatedValueEnum: break;
10301010
case .namespaceEnum: break;
1031-
case .jsObject(nil):
1032-
append(
1033-
"""
1034-
return _swift_js_retain(Int32(bitPattern: ret.id))
1035-
"""
1036-
)
1037-
case .jsObject(_?):
1038-
append(
1039-
"""
1040-
return _swift_js_retain(Int32(bitPattern: ret.this.id))
1041-
"""
1042-
)
1011+
case .jsObject:
1012+
append("return ret.bridgeJSLowerReturn()")
10431013
case .swiftHeapObject:
10441014
// Perform a manual retain on the object, which will be balanced by a
10451015
// release called via FinalizationRegistry
@@ -1058,7 +1028,7 @@ public class ExportSwift {
10581028
let ret = JSPromise.async {
10591029
\(CodeBlockItemListSyntax(self.body))
10601030
}.jsObject
1061-
return _swift_js_retain(Int32(bitPattern: ret.id))
1031+
return ret.bridgeJSLowerReturn()
10621032
"""
10631033
} else if effects.isThrows {
10641034
body = """

Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public struct ImportTS {
7373
abiParameterForwardings.append(
7474
LabeledExprSyntax(
7575
label: param.label,
76-
expression: ExprSyntax("Int32(\(raw: param.name) ? 1 : 0)")
76+
expression: ExprSyntax("\(raw: param.name).bridgeJSLowerParameter()")
7777
)
7878
)
7979
abiParameterSignatures.append((param.name, .i32))
@@ -102,24 +102,10 @@ public struct ImportTS {
102102
)
103103
abiParameterSignatures.append((param.name, .f64))
104104
case .string:
105-
let stringIdName = "\(param.name)Id"
106-
body.append(
107-
"""
108-
var \(raw: param.name) = \(raw: param.name)
109-
110-
"""
111-
)
112-
body.append(
113-
"""
114-
let \(raw: stringIdName) = \(raw: param.name).withUTF8 { b in
115-
_swift_js_make_js_string(b.baseAddress.unsafelyUnwrapped, Int32(b.count))
116-
}
117-
"""
118-
)
119105
abiParameterForwardings.append(
120106
LabeledExprSyntax(
121107
label: param.label,
122-
expression: ExprSyntax("\(raw: stringIdName)")
108+
expression: ExprSyntax("\(raw: param.name).bridgeJSLowerParameter()")
123109
)
124110
)
125111
abiParameterSignatures.append((param.name, .i32))
@@ -130,14 +116,14 @@ public struct ImportTS {
130116
abiParameterForwardings.append(
131117
LabeledExprSyntax(
132118
label: param.label,
133-
expression: ExprSyntax("Int32(bitPattern: \(raw: param.name).this.id)")
119+
expression: ExprSyntax("\(raw: param.name).this.bridgeJSLowerParameter()")
134120
)
135121
)
136122
case .jsObject(nil):
137123
abiParameterForwardings.append(
138124
LabeledExprSyntax(
139125
label: param.label,
140-
expression: ExprSyntax("Int32(bitPattern: \(raw: param.name).id)")
126+
expression: ExprSyntax("\(raw: param.name).bridgeJSLowerParameter()")
141127
)
142128
)
143129
abiParameterSignatures.append((param.name, .i32))
@@ -163,7 +149,7 @@ public struct ImportTS {
163149
switch returnType {
164150
case .bool:
165151
abiReturnType = .i32
166-
body.append("return ret == 1")
152+
body.append("return \(raw: returnType.swiftType).bridgeJSLiftReturn(ret)")
167153
case .int:
168154
abiReturnType = .i32
169155
body.append("return \(raw: returnType.swiftType)(ret)")
@@ -175,22 +161,15 @@ public struct ImportTS {
175161
body.append("return \(raw: returnType.swiftType)(ret)")
176162
case .string:
177163
abiReturnType = .i32
178-
body.append(
179-
"""
180-
return String(unsafeUninitializedCapacity: Int(ret)) { b in
181-
_swift_js_init_memory_with_result(b.baseAddress.unsafelyUnwrapped, Int32(ret))
182-
return Int(ret)
183-
}
184-
"""
185-
)
164+
body.append("return \(raw: returnType.swiftType).bridgeJSLiftReturn(ret)")
186165
case .caseEnum, .rawValueEnum, .associatedValueEnum, .namespaceEnum:
187166
throw BridgeJSCoreError("Enum types are not yet supported in TypeScript imports")
188167
case .jsObject(let name):
189168
abiReturnType = .i32
190169
if let name = name {
191170
body.append("return \(raw: name)(takingThis: ret)")
192171
} else {
193-
body.append("return JSObject(id: UInt32(bitPattern: ret))")
172+
body.append("return JSObject.bridgeJSLiftReturn(ret)")
194173
}
195174
case .swiftHeapObject(_):
196175
throw BridgeJSCoreError("swiftHeapObject is not supported in imported signatures")

0 commit comments

Comments
 (0)