Skip to content

Commit 16e3f44

Browse files
BridgeJS: Add JSValue parameter/return support (#570)
* BridgeJS: Add support for `JSValue` * BridgeJS: Fix unused result warnings * BridgeJS: Keep translating object-like types to JSObject * UPDATE_SNAPSHOTS=1 swift test --package-path ./Plugins/BridgeJS * BridgeJS: Update object-like check not to rely on definition location * BridgeJS: Add __bjs_jsValueLower/Lift helper functions * UPDATE_SNAPSHOTS=1 swift test --package-path ./Plugins/BridgeJS
1 parent 81885ea commit 16e3f44

File tree

23 files changed

+1841
-89
lines changed

23 files changed

+1841
-89
lines changed

Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -804,7 +804,7 @@ struct StackCodegen {
804804
func liftExpression(for type: BridgeType) -> ExprSyntax {
805805
switch type {
806806
case .string, .int, .uint, .bool, .float, .double,
807-
.jsObject(nil), .swiftStruct, .swiftHeapObject:
807+
.jsObject(nil), .jsValue, .swiftStruct, .swiftHeapObject:
808808
return "\(raw: type.swiftType).bridgeJSLiftParameter()"
809809
case .jsObject(let className?):
810810
return "\(raw: className)(unsafelyWrapping: JSObject.bridgeJSLiftParameter())"
@@ -841,7 +841,7 @@ struct StackCodegen {
841841

842842
func liftArrayExpression(elementType: BridgeType) -> ExprSyntax {
843843
switch elementType {
844-
case .int, .uint, .float, .double, .string, .bool,
844+
case .int, .uint, .float, .double, .string, .bool, .jsValue,
845845
.jsObject(nil), .swiftStruct, .caseEnum, .swiftHeapObject,
846846
.unsafePointer, .rawValueEnum, .associatedValueEnum:
847847
return "[\(raw: elementType.swiftType)].bridgeJSLiftParameter()"
@@ -876,7 +876,7 @@ struct StackCodegen {
876876
private func liftNullableExpression(wrappedType: BridgeType, kind: JSOptionalKind) -> ExprSyntax {
877877
let typeName = kind == .null ? "Optional" : "JSUndefinedOr"
878878
switch wrappedType {
879-
case .string, .int, .uint, .bool, .float, .double, .jsObject(nil),
879+
case .string, .int, .uint, .bool, .float, .double, .jsObject(nil), .jsValue,
880880
.swiftStruct, .swiftHeapObject, .caseEnum, .associatedValueEnum, .rawValueEnum:
881881
return "\(raw: typeName)<\(raw: wrappedType.swiftType)>.bridgeJSLiftParameter()"
882882
case .jsObject(let className?):
@@ -914,7 +914,7 @@ struct StackCodegen {
914914
varPrefix: String
915915
) -> [CodeBlockItemSyntax] {
916916
switch type {
917-
case .string, .int, .uint, .bool, .float, .double:
917+
case .string, .int, .uint, .bool, .float, .double, .jsValue:
918918
return ["\(raw: accessor).bridgeJSLowerStackReturn()"]
919919
case .jsObject(nil):
920920
return ["\(raw: accessor).bridgeJSLowerStackReturn()"]
@@ -944,7 +944,7 @@ struct StackCodegen {
944944
varPrefix: String
945945
) -> [CodeBlockItemSyntax] {
946946
switch elementType {
947-
case .int, .uint, .float, .double, .string, .bool,
947+
case .int, .uint, .float, .double, .string, .bool, .jsValue,
948948
.jsObject(nil), .swiftStruct, .caseEnum, .swiftHeapObject,
949949
.unsafePointer, .rawValueEnum, .associatedValueEnum:
950950
return ["\(raw: accessor).bridgeJSLowerReturn()"]
@@ -1015,7 +1015,7 @@ struct StackCodegen {
10151015
varPrefix: String
10161016
) -> [CodeBlockItemSyntax] {
10171017
switch wrappedType {
1018-
case .string, .int, .uint, .bool, .float, .double:
1018+
case .string, .int, .uint, .bool, .float, .double, .jsValue:
10191019
return ["\(raw: unwrappedVar).bridgeJSLowerStackReturn()"]
10201020
case .caseEnum, .rawValueEnum:
10211021
// Enums conform to _BridgedSwiftStackType
@@ -1604,6 +1604,7 @@ extension BridgeType {
16041604
case .float: return "Float"
16051605
case .double: return "Double"
16061606
case .string: return "String"
1607+
case .jsValue: return "JSValue"
16071608
case .jsObject(nil): return "JSObject"
16081609
case .jsObject(let name?): return name
16091610
case .swiftHeapObject(let name): return name
@@ -1634,6 +1635,7 @@ extension BridgeType {
16341635
static let double = LiftingIntrinsicInfo(parameters: [("value", .f64)])
16351636
static let string = LiftingIntrinsicInfo(parameters: [("bytes", .i32), ("length", .i32)])
16361637
static let jsObject = LiftingIntrinsicInfo(parameters: [("value", .i32)])
1638+
static let jsValue = LiftingIntrinsicInfo(parameters: [("kind", .i32), ("payload1", .i32), ("payload2", .f64)])
16371639
static let swiftHeapObject = LiftingIntrinsicInfo(parameters: [("value", .pointer)])
16381640
static let unsafePointer = LiftingIntrinsicInfo(parameters: [("pointer", .pointer)])
16391641
static let void = LiftingIntrinsicInfo(parameters: [])
@@ -1651,6 +1653,7 @@ extension BridgeType {
16511653
case .double: return .double
16521654
case .string: return .string
16531655
case .jsObject: return .jsObject
1656+
case .jsValue: return .jsValue
16541657
case .swiftHeapObject: return .swiftHeapObject
16551658
case .unsafePointer: return .unsafePointer
16561659
case .swiftProtocol: return .jsObject
@@ -1684,6 +1687,7 @@ extension BridgeType {
16841687
static let double = LoweringIntrinsicInfo(returnType: .f64)
16851688
static let string = LoweringIntrinsicInfo(returnType: nil)
16861689
static let jsObject = LoweringIntrinsicInfo(returnType: .i32)
1690+
static let jsValue = LoweringIntrinsicInfo(returnType: nil)
16871691
static let swiftHeapObject = LoweringIntrinsicInfo(returnType: .pointer)
16881692
static let unsafePointer = LoweringIntrinsicInfo(returnType: .pointer)
16891693
static let void = LoweringIntrinsicInfo(returnType: nil)
@@ -1703,6 +1707,7 @@ extension BridgeType {
17031707
case .double: return .double
17041708
case .string: return .string
17051709
case .jsObject: return .jsObject
1710+
case .jsValue: return .jsValue
17061711
case .swiftHeapObject: return .swiftHeapObject
17071712
case .unsafePointer: return .unsafePointer
17081713
case .swiftProtocol: return .jsObject

Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -178,13 +178,19 @@ public struct ImportTS {
178178
rightParen: .rightParenToken()
179179
)
180180

181-
if returnType == .void {
182-
body.append(CodeBlockItemSyntax(item: .stmt(StmtSyntax(ExpressionStmtSyntax(expression: callExpr)))))
183-
} else if returnType.usesSideChannelForOptionalReturn() {
184-
// Side channel returns don't need "let ret ="
185-
body.append(CodeBlockItemSyntax(item: .stmt(StmtSyntax(ExpressionStmtSyntax(expression: callExpr)))))
181+
let needsRetBinding: Bool
182+
let liftingInfo = try returnType.liftingReturnInfo(context: context)
183+
if liftingInfo.valueToLift == nil || returnType.usesSideChannelForOptionalReturn() {
184+
// Void and side-channel returns don't need "let ret ="
185+
needsRetBinding = false
186186
} else {
187+
needsRetBinding = true
188+
}
189+
190+
if needsRetBinding {
187191
body.append("let ret = \(raw: callExpr)")
192+
} else {
193+
body.append(CodeBlockItemSyntax(item: .stmt(StmtSyntax(ExpressionStmtSyntax(expression: callExpr)))))
188194
}
189195

190196
// Add exception check for ImportTS context
@@ -883,6 +889,11 @@ extension BridgeType {
883889
static let double = LoweringParameterInfo(loweredParameters: [("value", .f64)])
884890
static let string = LoweringParameterInfo(loweredParameters: [("value", .i32)])
885891
static let jsObject = LoweringParameterInfo(loweredParameters: [("value", .i32)])
892+
static let jsValue = LoweringParameterInfo(loweredParameters: [
893+
("kind", .i32),
894+
("payload1", .i32),
895+
("payload2", .f64),
896+
])
886897
static let void = LoweringParameterInfo(loweredParameters: [])
887898
}
888899

@@ -894,6 +905,7 @@ extension BridgeType {
894905
case .double: return .double
895906
case .string: return .string
896907
case .jsObject: return .jsObject
908+
case .jsValue: return .jsValue
897909
case .void: return .void
898910
case .closure:
899911
// Swift closure is boxed and passed to JS as a pointer.
@@ -970,6 +982,7 @@ extension BridgeType {
970982
static let double = LiftingReturnInfo(valueToLift: .f64)
971983
static let string = LiftingReturnInfo(valueToLift: .i32)
972984
static let jsObject = LiftingReturnInfo(valueToLift: .i32)
985+
static let jsValue = LiftingReturnInfo(valueToLift: nil)
973986
static let void = LiftingReturnInfo(valueToLift: nil)
974987
}
975988

@@ -983,6 +996,7 @@ extension BridgeType {
983996
case .double: return .double
984997
case .string: return .string
985998
case .jsObject: return .jsObject
999+
case .jsValue: return .jsValue
9861000
case .void: return .void
9871001
case .closure:
9881002
// JS returns a callback ID for closures, which Swift lifts to a typed closure.

0 commit comments

Comments
 (0)