Skip to content

Commit d35ef58

Browse files
authored
Merge pull request #566 from PassiveLogic/krodak/jsobject-stack-support
BridgeJS: Add JSObject and @jsclass struct support for arrays and struct
2 parents 0662e3b + 1714f28 commit d35ef58

File tree

24 files changed

+1463
-51
lines changed

24 files changed

+1463
-51
lines changed

Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -794,8 +794,10 @@ struct StackCodegen {
794794
func liftExpression(for type: BridgeType) -> ExprSyntax {
795795
switch type {
796796
case .string, .int, .uint, .bool, .float, .double,
797-
.jsObject, .swiftStruct, .swiftHeapObject:
797+
.jsObject(nil), .swiftStruct, .swiftHeapObject:
798798
return "\(raw: type.swiftType).bridgeJSLiftParameter()"
799+
case .jsObject(let className?):
800+
return "\(raw: className)(unsafelyWrapping: JSObject.bridgeJSLiftParameter())"
799801
case .unsafePointer:
800802
return "\(raw: type.swiftType).bridgeJSLiftParameter()"
801803
case .swiftProtocol(let protocolName):
@@ -830,9 +832,11 @@ struct StackCodegen {
830832
func liftArrayExpression(elementType: BridgeType) -> ExprSyntax {
831833
switch elementType {
832834
case .int, .uint, .float, .double, .string, .bool,
833-
.jsObject, .swiftStruct, .caseEnum, .swiftHeapObject,
835+
.jsObject(nil), .swiftStruct, .caseEnum, .swiftHeapObject,
834836
.unsafePointer, .rawValueEnum, .associatedValueEnum:
835837
return "[\(raw: elementType.swiftType)].bridgeJSLiftParameter()"
838+
case .jsObject(_?):
839+
return liftArrayExpressionInline(elementType: elementType)
836840
case .swiftProtocol(let protocolName):
837841
return "[Any\(raw: protocolName)].bridgeJSLiftParameter()"
838842
case .optional, .array, .closure:
@@ -861,9 +865,11 @@ struct StackCodegen {
861865

862866
private func liftOptionalExpression(wrappedType: BridgeType) -> ExprSyntax {
863867
switch wrappedType {
864-
case .string, .int, .uint, .bool, .float, .double, .jsObject,
868+
case .string, .int, .uint, .bool, .float, .double, .jsObject(nil),
865869
.swiftStruct, .swiftHeapObject, .caseEnum, .associatedValueEnum, .rawValueEnum:
866870
return "Optional<\(raw: wrappedType.swiftType)>.bridgeJSLiftParameter()"
871+
case .jsObject(let className?):
872+
return "Optional<JSObject>.bridgeJSLiftParameter().map { \(raw: className)(unsafelyWrapping: $0) }"
867873
case .array(let elementType):
868874
let arrayLift = liftArrayExpression(elementType: elementType)
869875
let swiftTypeName = elementType.swiftType
@@ -896,8 +902,10 @@ struct StackCodegen {
896902
switch type {
897903
case .string, .int, .uint, .bool, .float, .double:
898904
return ["\(raw: accessor).bridgeJSLowerStackReturn()"]
899-
case .jsObject:
905+
case .jsObject(nil):
900906
return ["\(raw: accessor).bridgeJSLowerStackReturn()"]
907+
case .jsObject(_?):
908+
return ["\(raw: accessor).jsObject.bridgeJSLowerStackReturn()"]
901909
case .swiftHeapObject, .unsafePointer, .closure:
902910
return ["\(raw: accessor).bridgeJSLowerStackReturn()"]
903911
case .swiftProtocol(let protocolName):
@@ -923,9 +931,11 @@ struct StackCodegen {
923931
) -> [CodeBlockItemSyntax] {
924932
switch elementType {
925933
case .int, .uint, .float, .double, .string, .bool,
926-
.jsObject, .swiftStruct, .caseEnum, .swiftHeapObject,
934+
.jsObject(nil), .swiftStruct, .caseEnum, .swiftHeapObject,
927935
.unsafePointer, .rawValueEnum, .associatedValueEnum:
928936
return ["\(raw: accessor).bridgeJSLowerReturn()"]
937+
case .jsObject(_?):
938+
return ["\(raw: accessor).map { $0.jsObject }.bridgeJSLowerReturn()"]
929939
case .swiftProtocol(let protocolName):
930940
return ["\(raw: accessor).map { $0 as! Any\(raw: protocolName) }.bridgeJSLowerReturn()"]
931941
case .optional, .array, .closure:
@@ -1003,8 +1013,10 @@ struct StackCodegen {
10031013
case .associatedValueEnum:
10041014
// Push payloads via bridgeJSLowerParameter(), then push the returned case ID
10051015
return ["_swift_js_push_i32(\(raw: unwrappedVar).bridgeJSLowerParameter())"]
1006-
case .jsObject:
1016+
case .jsObject(nil):
10071017
return ["\(raw: unwrappedVar).bridgeJSLowerStackReturn()"]
1018+
case .jsObject(_?):
1019+
return ["\(raw: unwrappedVar).jsObject.bridgeJSLowerStackReturn()"]
10081020
case .array(let elementType):
10091021
return lowerArrayStatements(elementType: elementType, accessor: unwrappedVar, varPrefix: varPrefix)
10101022
default:

Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2474,7 +2474,6 @@ struct IntrinsicJSFragment: Sendable {
24742474
let idVar = scope.variable("objId")
24752475
printer.write("const \(idVar) = \(JSGlueVariableScope.reservedSwift).memory.retain(\(value));")
24762476
printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(idVar));")
2477-
cleanup.write("\(JSGlueVariableScope.reservedSwift).memory.release(\(idVar));")
24782477
return []
24792478
}
24802479
)

Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/ArrayTypes.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@
5555
@JS func processItemArray(_ items: [Item]) -> [Item]
5656
@JS func processNestedItemArray(_ items: [[Item]]) -> [[Item]]
5757

58+
@JS func processJSObjectArray(_ objects: [JSObject]) -> [JSObject]
59+
@JS func processOptionalJSObjectArray(_ objects: [JSObject?]) -> [JSObject?]
60+
@JS func processNestedJSObjectArray(_ objects: [[JSObject]]) -> [[JSObject]]
61+
5862
@JSFunction func checkArray(_ a: JSObject) throws(JSException) -> Void
5963
@JSFunction func checkArrayWithLength(_ a: JSObject, _ b: Double) throws(JSException) -> Void
60-
@JSFunction func checkArray(_ a: JSObject) throws(JSException) -> Void

Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/ImportedTypeInExportedInterface.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,13 @@
55
@JS func makeFoo() throws(JSException) -> Foo {
66
return try Foo()
77
}
8+
9+
@JS func processFooArray(_ foos: [Foo]) -> [Foo]
10+
@JS func processOptionalFooArray(_ foos: [Foo?]) -> [Foo?]
11+
12+
@JS struct FooContainer {
13+
var foo: Foo
14+
var optionalFoo: Foo?
15+
}
16+
17+
@JS func roundtripFooContainer(_ container: FooContainer) -> FooContainer

Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/SwiftStruct.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,10 @@
5353
@JS static var computedSetting: String { "Config: \(defaultConfig)" }
5454
@JS static func update(_ timeout: Double) -> Double
5555
}
56+
57+
@JS struct Container {
58+
var object: JSObject
59+
var optionalObject: JSObject?
60+
}
61+
62+
@JS func roundtripContainer(_ container: Container) -> Container

Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ArrayTypes.json

Lines changed: 115 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -945,6 +945,121 @@
945945
}
946946
}
947947
}
948+
},
949+
{
950+
"abiName" : "bjs_processJSObjectArray",
951+
"effects" : {
952+
"isAsync" : false,
953+
"isStatic" : false,
954+
"isThrows" : false
955+
},
956+
"name" : "processJSObjectArray",
957+
"parameters" : [
958+
{
959+
"label" : "_",
960+
"name" : "objects",
961+
"type" : {
962+
"array" : {
963+
"_0" : {
964+
"jsObject" : {
965+
966+
}
967+
}
968+
}
969+
}
970+
}
971+
],
972+
"returnType" : {
973+
"array" : {
974+
"_0" : {
975+
"jsObject" : {
976+
977+
}
978+
}
979+
}
980+
}
981+
},
982+
{
983+
"abiName" : "bjs_processOptionalJSObjectArray",
984+
"effects" : {
985+
"isAsync" : false,
986+
"isStatic" : false,
987+
"isThrows" : false
988+
},
989+
"name" : "processOptionalJSObjectArray",
990+
"parameters" : [
991+
{
992+
"label" : "_",
993+
"name" : "objects",
994+
"type" : {
995+
"array" : {
996+
"_0" : {
997+
"optional" : {
998+
"_0" : {
999+
"jsObject" : {
1000+
1001+
}
1002+
}
1003+
}
1004+
}
1005+
}
1006+
}
1007+
}
1008+
],
1009+
"returnType" : {
1010+
"array" : {
1011+
"_0" : {
1012+
"optional" : {
1013+
"_0" : {
1014+
"jsObject" : {
1015+
1016+
}
1017+
}
1018+
}
1019+
}
1020+
}
1021+
}
1022+
},
1023+
{
1024+
"abiName" : "bjs_processNestedJSObjectArray",
1025+
"effects" : {
1026+
"isAsync" : false,
1027+
"isStatic" : false,
1028+
"isThrows" : false
1029+
},
1030+
"name" : "processNestedJSObjectArray",
1031+
"parameters" : [
1032+
{
1033+
"label" : "_",
1034+
"name" : "objects",
1035+
"type" : {
1036+
"array" : {
1037+
"_0" : {
1038+
"array" : {
1039+
"_0" : {
1040+
"jsObject" : {
1041+
1042+
}
1043+
}
1044+
}
1045+
}
1046+
}
1047+
}
1048+
}
1049+
],
1050+
"returnType" : {
1051+
"array" : {
1052+
"_0" : {
1053+
"array" : {
1054+
"_0" : {
1055+
"jsObject" : {
1056+
1057+
}
1058+
}
1059+
}
1060+
}
1061+
}
1062+
}
9481063
}
9491064
],
9501065
"protocols" : [
@@ -1027,24 +1142,6 @@
10271142
"returnType" : {
10281143
"void" : {
10291144

1030-
}
1031-
}
1032-
},
1033-
{
1034-
"name" : "checkArray",
1035-
"parameters" : [
1036-
{
1037-
"name" : "a",
1038-
"type" : {
1039-
"jsObject" : {
1040-
1041-
}
1042-
}
1043-
}
1044-
],
1045-
"returnType" : {
1046-
"void" : {
1047-
10481145
}
10491146
}
10501147
}

Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ArrayTypes.swift

Lines changed: 58 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,64 @@ public func _bjs_processNestedItemArray() -> Void {
465465
#endif
466466
}
467467

468+
@_expose(wasm, "bjs_processJSObjectArray")
469+
@_cdecl("bjs_processJSObjectArray")
470+
public func _bjs_processJSObjectArray() -> Void {
471+
#if arch(wasm32)
472+
let ret = processJSObjectArray(_: [JSObject].bridgeJSLiftParameter())
473+
ret.bridgeJSLowerReturn()
474+
#else
475+
fatalError("Only available on WebAssembly")
476+
#endif
477+
}
478+
479+
@_expose(wasm, "bjs_processOptionalJSObjectArray")
480+
@_cdecl("bjs_processOptionalJSObjectArray")
481+
public func _bjs_processOptionalJSObjectArray() -> Void {
482+
#if arch(wasm32)
483+
let ret = processOptionalJSObjectArray(_: {
484+
let __count = Int(_swift_js_pop_i32())
485+
var __result: [Optional<JSObject>] = []
486+
__result.reserveCapacity(__count)
487+
for _ in 0 ..< __count {
488+
__result.append(Optional<JSObject>.bridgeJSLiftParameter())
489+
}
490+
__result.reverse()
491+
return __result
492+
}())
493+
for __bjs_elem_ret in ret {
494+
let __bjs_isSome_ret_elem = __bjs_elem_ret != nil
495+
if let __bjs_unwrapped_ret_elem = __bjs_elem_ret {
496+
__bjs_unwrapped_ret_elem.bridgeJSLowerStackReturn()}
497+
_swift_js_push_i32(__bjs_isSome_ret_elem ? 1 : 0)}
498+
_swift_js_push_i32(Int32(ret.count))
499+
#else
500+
fatalError("Only available on WebAssembly")
501+
#endif
502+
}
503+
504+
@_expose(wasm, "bjs_processNestedJSObjectArray")
505+
@_cdecl("bjs_processNestedJSObjectArray")
506+
public func _bjs_processNestedJSObjectArray() -> Void {
507+
#if arch(wasm32)
508+
let ret = processNestedJSObjectArray(_: {
509+
let __count = Int(_swift_js_pop_i32())
510+
var __result: [[JSObject]] = []
511+
__result.reserveCapacity(__count)
512+
for _ in 0 ..< __count {
513+
__result.append([JSObject].bridgeJSLiftParameter())
514+
}
515+
__result.reverse()
516+
return __result
517+
}())
518+
for __bjs_elem_ret in ret {
519+
__bjs_elem_ret.bridgeJSLowerReturn()}
520+
_swift_js_push_i32(Int32(ret.count))
521+
#else
522+
fatalError("Only available on WebAssembly")
523+
#endif
524+
}
525+
468526
@_expose(wasm, "bjs_Item_deinit")
469527
@_cdecl("bjs_Item_deinit")
470528
public func _bjs_Item_deinit(_ pointer: UnsafeMutableRawPointer) -> Void {
@@ -523,21 +581,4 @@ func _$checkArrayWithLength(_ a: JSObject, _ b: Double) throws(JSException) -> V
523581
if let error = _swift_js_take_exception() {
524582
throw error
525583
}
526-
}
527-
528-
#if arch(wasm32)
529-
@_extern(wasm, module: "TestModule", name: "bjs_checkArray")
530-
fileprivate func bjs_checkArray(_ a: Int32) -> Void
531-
#else
532-
fileprivate func bjs_checkArray(_ a: Int32) -> Void {
533-
fatalError("Only available on WebAssembly")
534-
}
535-
#endif
536-
537-
func _$checkArray(_ a: JSObject) throws(JSException) -> Void {
538-
let aValue = a.bridgeJSLowerParameter()
539-
bjs_checkArray(aValue)
540-
if let error = _swift_js_take_exception() {
541-
throw error
542-
}
543584
}

0 commit comments

Comments
 (0)