Skip to content

Commit 8641276

Browse files
BridgeJS: Simplify Stack ABI for Optional
Now `Optional` conforms to `_BridgedSwiftStackType` whenever `Wrapped` conforms to `_BridgedSwiftStackType`. This makes generic programming easier and reduces boilerplate in intrinsics and codegen. For specialized handling of certain types like associated value enums, where the presence of a value is encoded as a sentinel case ID (-1), we implement `bridgeJSStack{Push,Pop}AsOptional` methods, which is on the witness table of `_BridgedSwiftStackType`. Also now some of optional types no longer pushes placeholders values for `nil` cases when pushing in JS and popping in Swift.
1 parent cf7a4f3 commit 8641276

File tree

14 files changed

+450
-1054
lines changed

14 files changed

+450
-1054
lines changed

Benchmarks/Sources/Generated/BridgeJS.swift

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -230,11 +230,7 @@ extension Person: _BridgedSwiftStruct {
230230
self.name.bridgeJSStackPush()
231231
self.age.bridgeJSStackPush()
232232
self.address.bridgeJSStackPush()
233-
let __bjs_isSome_email = self.email != nil
234-
if let __bjs_unwrapped_email = self.email {
235-
__bjs_unwrapped_email.bridgeJSStackPush()
236-
}
237-
_swift_js_push_i32(__bjs_isSome_email ? 1 : 0)
233+
self.email.bridgeJSStackPush()
238234
}
239235

240236
init(unsafelyCopying jsObject: JSObject) {
@@ -1603,11 +1599,7 @@ public func _bjs_ArrayRoundtrip_makeOptionalIntArray(_ _self: UnsafeMutableRawPo
16031599
#if arch(wasm32)
16041600
let ret = ArrayRoundtrip.bridgeJSLiftParameter(_self).makeOptionalIntArray()
16051601
for __bjs_elem_ret in ret {
1606-
let __bjs_isSome_ret_elem = __bjs_elem_ret != nil
1607-
if let __bjs_unwrapped_ret_elem = __bjs_elem_ret {
1608-
__bjs_unwrapped_ret_elem.bridgeJSStackPush()
1609-
}
1610-
_swift_js_push_i32(__bjs_isSome_ret_elem ? 1 : 0)
1602+
__bjs_elem_ret.bridgeJSStackPush()
16111603
}
16121604
_swift_js_push_i32(Int32(ret.count))
16131605
#else
@@ -1630,11 +1622,7 @@ public func _bjs_ArrayRoundtrip_roundtripOptionalIntArray(_ _self: UnsafeMutable
16301622
return __result
16311623
}())
16321624
for __bjs_elem_ret in ret {
1633-
let __bjs_isSome_ret_elem = __bjs_elem_ret != nil
1634-
if let __bjs_unwrapped_ret_elem = __bjs_elem_ret {
1635-
__bjs_unwrapped_ret_elem.bridgeJSStackPush()
1636-
}
1637-
_swift_js_push_i32(__bjs_isSome_ret_elem ? 1 : 0)
1625+
__bjs_elem_ret.bridgeJSStackPush()
16381626
}
16391627
_swift_js_push_i32(Int32(ret.count))
16401628
#else

Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift

Lines changed: 1 addition & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -824,16 +824,12 @@ struct StackCodegen {
824824
switch type {
825825
case .string, .int, .uint, .bool, .float, .double, .jsValue,
826826
.jsObject(nil), .swiftHeapObject, .unsafePointer, .closure,
827-
.caseEnum, .rawValueEnum:
827+
.caseEnum, .rawValueEnum, .associatedValueEnum, .swiftStruct, .nullable:
828828
return ["\(raw: accessor).bridgeJSStackPush()"]
829829
case .jsObject(_?):
830830
return ["\(raw: accessor).jsObject.bridgeJSStackPush()"]
831831
case .swiftProtocol:
832832
return ["(\(raw: accessor) as! \(raw: type.swiftType)).bridgeJSStackPush()"]
833-
case .associatedValueEnum, .swiftStruct:
834-
return ["\(raw: accessor).bridgeJSStackPush()"]
835-
case .nullable(let wrappedType, _):
836-
return lowerOptionalStatements(wrappedType: wrappedType, accessor: accessor, varPrefix: varPrefix)
837833
case .void, .namespaceEnum:
838834
return []
839835
case .array(let elementType):
@@ -946,54 +942,6 @@ struct StackCodegen {
946942
statements.append("_swift_js_push_i32(Int32(\(raw: accessor).count))")
947943
return statements
948944
}
949-
950-
private func lowerOptionalStatements(
951-
wrappedType: BridgeType,
952-
accessor: String,
953-
varPrefix: String
954-
) -> [CodeBlockItemSyntax] {
955-
switch wrappedType {
956-
case .array, .dictionary, .swiftStruct:
957-
return ["\(raw: accessor).bridgeJSStackPush()"]
958-
default:
959-
break
960-
}
961-
962-
var statements: [String] = []
963-
statements.append("let __bjs_isSome_\(varPrefix) = \(accessor) != nil")
964-
statements.append("if let __bjs_unwrapped_\(varPrefix) = \(accessor) {")
965-
966-
let innerStatements = lowerUnwrappedOptionalStatements(
967-
wrappedType: wrappedType,
968-
unwrappedVar: "__bjs_unwrapped_\(varPrefix)"
969-
)
970-
for stmt in innerStatements {
971-
statements.append(stmt.description)
972-
}
973-
974-
statements.append("}")
975-
statements.append("_swift_js_push_i32(__bjs_isSome_\(varPrefix) ? 1 : 0)")
976-
let parsed: CodeBlockItemListSyntax = "\(raw: statements.joined(separator: "\n"))"
977-
return Array(parsed)
978-
}
979-
980-
private func lowerUnwrappedOptionalStatements(
981-
wrappedType: BridgeType,
982-
unwrappedVar: String
983-
) -> [CodeBlockItemSyntax] {
984-
switch wrappedType {
985-
case .jsObject(_?):
986-
return ["\(raw: unwrappedVar).jsObject.bridgeJSStackPush()"]
987-
case .swiftProtocol:
988-
return ["(\(raw: unwrappedVar) as! \(raw: wrappedType.swiftType)).bridgeJSStackPush()"]
989-
case .string, .int, .uint, .bool, .float, .double, .jsValue,
990-
.jsObject(nil), .swiftHeapObject, .unsafePointer, .closure,
991-
.caseEnum, .rawValueEnum, .associatedValueEnum:
992-
return ["\(raw: unwrappedVar).bridgeJSStackPush()"]
993-
default:
994-
return ["preconditionFailure(\"BridgeJS: unsupported optional wrapped type\")"]
995-
}
996-
}
997945
}
998946

999947
// MARK: - EnumCodegen

0 commit comments

Comments
 (0)