Skip to content

Commit 771bd03

Browse files
committed
BridgeJS: Move usesSideChannelForOptionalReturn and usesStackLifting into descriptor, unify return-type switches
1 parent 4097e13 commit 771bd03

File tree

4 files changed

+94
-162
lines changed

4 files changed

+94
-162
lines changed

Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift

Lines changed: 48 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -134,39 +134,26 @@ public class ExportSwift {
134134
case .closure(let signature, _):
135135
typeNameForIntrinsic = param.type.swiftType
136136
liftingExpr = ExprSyntax("_BJS_Closure_\(raw: signature.mangleName).bridgeJSLift(\(raw: param.name))")
137-
case .swiftStruct(let structName):
138-
typeNameForIntrinsic = structName
139-
liftingExpr = ExprSyntax("\(raw: structName).bridgeJSLiftParameter()")
140137
case .array:
141138
typeNameForIntrinsic = param.type.swiftType
142139
liftingExpr = StackCodegen().liftExpression(for: param.type)
143140
case .nullable(let wrappedType, let kind):
144-
let optionalSwiftType: String
145-
if case .null = kind {
146-
optionalSwiftType = "Optional"
147-
} else {
148-
optionalSwiftType = "JSUndefinedOr"
149-
}
150-
if case .swiftProtocol(let protocolName) = wrappedType {
151-
let wrapperName = "Any\(protocolName)"
152-
typeNameForIntrinsic = "\(optionalSwiftType)<\(wrapperName)>"
153-
liftingExpr = ExprSyntax(
154-
"\(raw: typeNameForIntrinsic).bridgeJSLiftParameter(\(raw: argumentsToLift.joined(separator: ", ")))"
155-
)
156-
} else {
157-
typeNameForIntrinsic = "\(optionalSwiftType)<\(wrappedType.swiftType)>"
158-
liftingExpr = ExprSyntax(
159-
"\(raw: typeNameForIntrinsic).bridgeJSLiftParameter(\(raw: argumentsToLift.joined(separator: ", ")))"
160-
)
161-
}
162-
case .swiftProtocol(let protocolName):
163-
let wrapperName = "Any\(protocolName)"
164-
typeNameForIntrinsic = wrapperName
141+
let optionalSwiftType: String =
142+
if case .null = kind { "Optional" } else { "JSUndefinedOr" }
143+
let wrappedName: String =
144+
if case .cast(let name) = wrappedType.descriptor.accessorTransform { name } else {
145+
wrappedType.swiftType
146+
}
147+
typeNameForIntrinsic = "\(optionalSwiftType)<\(wrappedName)>"
165148
liftingExpr = ExprSyntax(
166-
"\(raw: wrapperName).bridgeJSLiftParameter(\(raw: argumentsToLift.joined(separator: ", ")))"
149+
"\(raw: typeNameForIntrinsic).bridgeJSLiftParameter(\(raw: argumentsToLift.joined(separator: ", ")))"
167150
)
168151
default:
169-
typeNameForIntrinsic = param.type.swiftType
152+
if case .cast(let name) = param.type.descriptor.accessorTransform {
153+
typeNameForIntrinsic = name
154+
} else {
155+
typeNameForIntrinsic = param.type.swiftType
156+
}
170157
liftingExpr = ExprSyntax(
171158
"\(raw: typeNameForIntrinsic).bridgeJSLiftParameter(\(raw: argumentsToLift.joined(separator: ", ")))"
172159
)
@@ -211,26 +198,9 @@ public class ExportSwift {
211198
if returnType == .void {
212199
return CodeBlockItemSyntax(item: .init(ExpressionStmtSyntax(expression: callExpr)))
213200
} else {
214-
switch returnType {
215-
case .swiftProtocol(let protocolName):
216-
let wrapperName = "Any\(protocolName)"
217-
return CodeBlockItemSyntax(
218-
item: .init(DeclSyntax("let ret = \(raw: callExpr) as! \(raw: wrapperName)"))
219-
)
220-
case .nullable(let wrappedType, _):
221-
if case .swiftProtocol(let protocolName) = wrappedType {
222-
let wrapperName = "Any\(protocolName)"
223-
return CodeBlockItemSyntax(
224-
item: .init(
225-
DeclSyntax("let ret = (\(raw: callExpr)).flatMap { $0 as? \(raw: wrapperName) }")
226-
)
227-
)
228-
} else {
229-
return CodeBlockItemSyntax(item: .init(DeclSyntax("let ret = \(raw: callExpr)")))
230-
}
231-
default:
232-
return CodeBlockItemSyntax(item: .init(DeclSyntax("let ret = \(raw: callExpr)")))
233-
}
201+
let binding = returnType.descriptor.accessorTransform
202+
.applyToReturnBinding("\(callExpr)", isOptional: returnType.isOptional)
203+
return CodeBlockItemSyntax(item: .init(DeclSyntax("\(raw: binding)")))
234204
}
235205
}
236206

@@ -244,20 +214,9 @@ public class ExportSwift {
244214
if returnType == .void {
245215
append("\(raw: name)")
246216
} else {
247-
switch returnType {
248-
case .swiftProtocol(let protocolName):
249-
let wrapperName = "Any\(protocolName)"
250-
append("let ret = \(raw: name) as! \(raw: wrapperName)")
251-
case .nullable(let wrappedType, _):
252-
if case .swiftProtocol(let protocolName) = wrappedType {
253-
let wrapperName = "Any\(protocolName)"
254-
append("let ret = \(raw: name).flatMap { $0 as? \(raw: wrapperName) }")
255-
} else {
256-
append("let ret = \(raw: name)")
257-
}
258-
default:
259-
append("let ret = \(raw: name)")
260-
}
217+
let binding = returnType.descriptor.accessorTransform
218+
.applyToReturnBinding(name, isOptional: returnType.isOptional)
219+
append("\(raw: binding)")
261220
}
262221
}
263222

@@ -274,14 +233,7 @@ public class ExportSwift {
274233
/// Generates intermediate variables for stack-using parameters if needed for LIFO compatibility
275234
private func generateParameterLifting() {
276235
let stackParamIndices = parameters.enumerated().compactMap { index, param -> Int? in
277-
switch param.type {
278-
case .swiftStruct, .nullable(.swiftStruct, _),
279-
.associatedValueEnum, .nullable(.associatedValueEnum, _),
280-
.array:
281-
return index
282-
default:
283-
return nil
284-
}
236+
param.type.descriptor.usesStackLifting ? index : nil
285237
}
286238

287239
guard stackParamIndices.count > 1 else { return }
@@ -298,23 +250,13 @@ public class ExportSwift {
298250

299251
func callPropertyGetter(propertyName: String, returnType: BridgeType) {
300252
let (_, selfExpr) = removeFirstLiftedParameter()
253+
let expr = "\(selfExpr).\(propertyName)"
301254
if returnType == .void {
302-
append("\(raw: selfExpr).\(raw: propertyName)")
255+
append("\(raw: expr)")
303256
} else {
304-
switch returnType {
305-
case .swiftProtocol(let protocolName):
306-
let wrapperName = "Any\(protocolName)"
307-
append("let ret = \(raw: selfExpr).\(raw: propertyName) as! \(raw: wrapperName)")
308-
case .nullable(let wrappedType, _):
309-
if case .swiftProtocol(let protocolName) = wrappedType {
310-
let wrapperName = "Any\(protocolName)"
311-
append("let ret = \(raw: selfExpr).\(raw: propertyName).flatMap { $0 as? \(raw: wrapperName) }")
312-
} else {
313-
append("let ret = \(raw: selfExpr).\(raw: propertyName)")
314-
}
315-
default:
316-
append("let ret = \(raw: selfExpr).\(raw: propertyName)")
317-
}
257+
let binding = returnType.descriptor.accessorTransform
258+
.applyToReturnBinding(expr, isOptional: returnType.isOptional)
259+
append("\(raw: binding)")
318260
}
319261
}
320262

@@ -778,30 +720,15 @@ struct StackCodegen {
778720
func liftExpression(for type: BridgeType) -> ExprSyntax {
779721
switch type {
780722
case .string, .int, .uint, .bool, .float, .double,
781-
.jsObject(nil), .jsValue, .swiftStruct, .swiftHeapObject:
723+
.jsObject(nil), .jsValue, .swiftStruct, .swiftHeapObject, .unsafePointer:
782724
return "\(raw: type.swiftType).bridgeJSLiftParameter()"
783725
case .jsObject(let className?):
784726
return "\(raw: className)(unsafelyWrapping: JSObject.bridgeJSLiftParameter())"
785-
case .unsafePointer:
786-
return "\(raw: type.swiftType).bridgeJSLiftParameter()"
787-
case .swiftProtocol(let protocolName):
788-
return "Any\(raw: protocolName).bridgeJSLiftParameter(_swift_js_pop_i32())"
789-
case .caseEnum:
790-
return "\(raw: type.swiftType).bridgeJSLiftParameter(_swift_js_pop_i32())"
791-
case .rawValueEnum(_, let rawType):
792-
switch rawType {
793-
case .string:
794-
return
795-
"\(raw: type.swiftType).bridgeJSLiftParameter(_swift_js_pop_i32(), _swift_js_pop_i32())"
796-
case .float:
797-
return "\(raw: type.swiftType).bridgeJSLiftParameter(_swift_js_pop_f32())"
798-
case .double:
799-
return "\(raw: type.swiftType).bridgeJSLiftParameter(_swift_js_pop_f64())"
800-
case .bool, .int, .int32, .int64, .uint, .uint32, .uint64:
801-
return "\(raw: type.swiftType).bridgeJSLiftParameter(_swift_js_pop_i32())"
802-
}
803-
case .associatedValueEnum:
727+
case .swiftProtocol, .caseEnum, .associatedValueEnum:
804728
return "\(raw: type.swiftType).bridgeJSLiftParameter(_swift_js_pop_i32())"
729+
case .rawValueEnum:
730+
let popArgs = type.descriptor.wasmParams.map { "_swift_js_pop_\($0.type.rawValue)()" }.joined(separator: ", ")
731+
return "\(raw: type.swiftType).bridgeJSLiftParameter(\(raw: popArgs))"
805732
case .nullable(let wrappedType, let kind):
806733
return liftNullableExpression(wrappedType: wrappedType, kind: kind)
807734
case .array(let elementType):
@@ -819,12 +746,8 @@ struct StackCodegen {
819746
switch elementType {
820747
case .jsObject(let className?) where className != "JSObject":
821748
return liftArrayExpressionInline(elementType: elementType)
822-
case .swiftProtocol(let protocolName):
823-
return "[Any\(raw: protocolName)].bridgeJSLiftParameter()"
824749
case .nullable, .closure:
825750
return liftArrayExpressionInline(elementType: elementType)
826-
case .void, .namespaceEnum:
827-
fatalError("Invalid array element type: \(elementType)")
828751
default:
829752
return "[\(raw: elementType.swiftType)].bridgeJSLiftParameter()"
830753
}
@@ -943,23 +866,16 @@ struct StackCodegen {
943866
accessor: String,
944867
varPrefix: String
945868
) -> [CodeBlockItemSyntax] {
946-
// Types needing accessor transformation
947-
switch elementType {
948-
case .jsObject(let className?) where className != "JSObject":
949-
return ["\(raw: accessor).map { $0.jsObject }.bridgeJSLowerReturn()"]
950-
case .swiftProtocol(let protocolName):
951-
return ["\(raw: accessor).map { $0 as! Any\(raw: protocolName) }.bridgeJSLowerReturn()"]
952-
case .nullable, .closure:
953-
return lowerArrayStatementsInline(
954-
elementType: elementType,
955-
accessor: accessor,
956-
varPrefix: varPrefix
957-
)
958-
case .void, .namespaceEnum:
959-
fatalError("Invalid array element type: \(elementType)")
960-
default:
961-
return ["\(raw: accessor).bridgeJSLowerReturn()"]
869+
if case .nullable = elementType {
870+
return lowerArrayStatementsInline(elementType: elementType, accessor: accessor, varPrefix: varPrefix)
871+
}
872+
if case .closure = elementType {
873+
return lowerArrayStatementsInline(elementType: elementType, accessor: accessor, varPrefix: varPrefix)
962874
}
875+
if let mapClosure = elementType.descriptor.accessorTransform.mapClosure {
876+
return ["\(raw: accessor).map { \(raw: mapClosure) }.bridgeJSLowerReturn()"]
877+
}
878+
return ["\(raw: accessor).bridgeJSLowerReturn()"]
963879
}
964880

965881
private func lowerArrayStatementsInline(
@@ -991,22 +907,16 @@ struct StackCodegen {
991907
accessor: String,
992908
varPrefix: String
993909
) -> [CodeBlockItemSyntax] {
994-
switch valueType {
995-
case .jsObject(let className?) where className != "JSObject":
996-
return ["\(raw: accessor).mapValues { $0.jsObject }.bridgeJSLowerReturn()"]
997-
case .swiftProtocol(let protocolName):
998-
return ["\(raw: accessor).mapValues { $0 as! Any\(raw: protocolName) }.bridgeJSLowerReturn()"]
999-
case .nullable, .closure:
1000-
return lowerDictionaryStatementsInline(
1001-
valueType: valueType,
1002-
accessor: accessor,
1003-
varPrefix: varPrefix
1004-
)
1005-
case .void, .namespaceEnum:
1006-
fatalError("Invalid dictionary value type: \(valueType)")
1007-
default:
1008-
return ["\(raw: accessor).bridgeJSLowerReturn()"]
910+
if case .nullable = valueType {
911+
return lowerDictionaryStatementsInline(valueType: valueType, accessor: accessor, varPrefix: varPrefix)
912+
}
913+
if case .closure = valueType {
914+
return lowerDictionaryStatementsInline(valueType: valueType, accessor: accessor, varPrefix: varPrefix)
915+
}
916+
if let mapClosure = valueType.descriptor.accessorTransform.mapClosure {
917+
return ["\(raw: accessor).mapValues { \(raw: mapClosure) }.bridgeJSLowerReturn()"]
1009918
}
919+
return ["\(raw: accessor).bridgeJSLowerReturn()"]
1010920
}
1011921

1012922
private func lowerDictionaryStatementsInline(

0 commit comments

Comments
 (0)