Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,7 @@ struct IntrinsicJSFragment: Sendable {
resultExpr =
"\(isSome) ? \(JSGlueVariableScope.reservedSwift).memory.getObject(\(wrappedValue)) : \(absenceLiteral)"
case .swiftHeapObject(let name):
resultExpr = "\(isSome) ? \(name).__construct(\(wrappedValue)) : \(absenceLiteral)"
resultExpr = "\(isSome) ? _exports['\(name)'].__construct(\(wrappedValue)) : \(absenceLiteral)"
case .jsObject:
resultExpr =
"\(isSome) ? \(JSGlueVariableScope.reservedSwift).memory.getObject(\(wrappedValue)) : \(absenceLiteral)"
Expand Down Expand Up @@ -1120,6 +1120,8 @@ struct IntrinsicJSFragment: Sendable {
scope.emitPushF64Parameter(payload2Var, printer: printer)
}
scope.emitPushI32Parameter("\(isSomeVar) ? 1 : 0", printer: printer)
case .swiftHeapObject:
printer.write("return \(isSomeVar) ? \(value).pointer : 0;")
case .array(let elementType):
printer.write("if (\(isSomeVar)) {")
try printer.indent {
Expand Down Expand Up @@ -1230,7 +1232,9 @@ struct IntrinsicJSFragment: Sendable {
printer.write("}")
scope.emitPushI32Parameter("\(isSomeVar) ? 1 : 0", printer: printer)
default:
()
throw BridgeJSLinkError(
message: "Unsupported wrapped type for returning from JS function: \(wrappedType)"
)
}

return []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@
@JS package class PackageGreeter {}

@JSFunction func jsRoundTripGreeter(greeter: Greeter) throws(JSException) -> Greeter
@JSFunction func jsRoundTripOptionalGreeter(greeter: Greeter?) throws(JSException) -> Greeter?
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,34 @@
"_0" : "Greeter"
}
}
},
{
"name" : "jsRoundTripOptionalGreeter",
"parameters" : [
{
"name" : "greeter",
"type" : {
"nullable" : {
"_0" : {
"swiftHeapObject" : {
"_0" : "Greeter"
}
},
"_1" : "null"
}
}
}
],
"returnType" : {
"nullable" : {
"_0" : {
"swiftHeapObject" : {
"_0" : "Greeter"
}
},
"_1" : "null"
}
}
}
],
"types" : [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,4 +152,22 @@ func _$jsRoundTripGreeter(_ greeter: Greeter) throws(JSException) -> Greeter {
throw error
}
return Greeter.bridgeJSLiftReturn(ret)
}

#if arch(wasm32)
@_extern(wasm, module: "TestModule", name: "bjs_jsRoundTripOptionalGreeter")
fileprivate func bjs_jsRoundTripOptionalGreeter(_ greeterIsSome: Int32, _ greeterPointer: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer
#else
fileprivate func bjs_jsRoundTripOptionalGreeter(_ greeterIsSome: Int32, _ greeterPointer: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer {
fatalError("Only available on WebAssembly")
}
#endif

func _$jsRoundTripOptionalGreeter(_ greeter: Optional<Greeter>) throws(JSException) -> Optional<Greeter> {
let (greeterIsSome, greeterPointer) = greeter.bridgeJSLowerParameter()
let ret = bjs_jsRoundTripOptionalGreeter(greeterIsSome, greeterPointer)
if let error = _swift_js_take_exception() {
throw error
}
return Optional<Greeter>.bridgeJSLiftReturn(ret)
}
Original file line number Diff line number Diff line change
Expand Up @@ -529,7 +529,7 @@ export async function createInstantiator(options, swift) {
}
TestModule["bjs_MyViewControllerDelegate_onOptionalHelperUpdated"] = function bjs_MyViewControllerDelegate_onOptionalHelperUpdated(self, helperIsSome, helperWrappedValue) {
try {
swift.memory.getObject(self).onOptionalHelperUpdated(helperIsSome ? Helper.__construct(helperWrappedValue) : null);
swift.memory.getObject(self).onOptionalHelperUpdated(helperIsSome ? _exports['Helper'].__construct(helperWrappedValue) : null);
} catch (error) {
setException(error);
}
Expand All @@ -538,6 +538,7 @@ export async function createInstantiator(options, swift) {
try {
let ret = swift.memory.getObject(self).createOptionalHelper();
const isSome = ret != null;
return isSome ? ret.pointer : 0;
} catch (error) {
setException(error);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export type Exports = {
}
export type Imports = {
jsRoundTripGreeter(greeter: Greeter): Greeter;
jsRoundTripOptionalGreeter(greeter: Greeter | null): Greeter | null;
}
export function createInstantiator(options: {
imports: Imports;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,15 @@ export async function createInstantiator(options, swift) {
return 0
}
}
TestModule["bjs_jsRoundTripOptionalGreeter"] = function bjs_jsRoundTripOptionalGreeter(greeterIsSome, greeterWrappedValue) {
try {
let ret = imports.jsRoundTripOptionalGreeter(greeterIsSome ? _exports['Greeter'].__construct(greeterWrappedValue) : null);
const isSome = ret != null;
return isSome ? ret.pointer : 0;
} catch (error) {
setException(error);
}
}
},
setInstance: (i) => {
instance = i;
Expand Down
18 changes: 18 additions & 0 deletions Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10677,11 +10677,29 @@ fileprivate func bjs_SwiftClassSupportImports_jsRoundTripGreeter_static(_ greete
}
#endif

#if arch(wasm32)
@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_SwiftClassSupportImports_jsRoundTripOptionalGreeter_static")
fileprivate func bjs_SwiftClassSupportImports_jsRoundTripOptionalGreeter_static(_ greeterIsSome: Int32, _ greeterPointer: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer
#else
fileprivate func bjs_SwiftClassSupportImports_jsRoundTripOptionalGreeter_static(_ greeterIsSome: Int32, _ greeterPointer: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer {
fatalError("Only available on WebAssembly")
}
#endif

func _$SwiftClassSupportImports_jsRoundTripGreeter(_ greeter: Greeter) throws(JSException) -> Greeter {
let greeterPointer = greeter.bridgeJSLowerParameter()
let ret = bjs_SwiftClassSupportImports_jsRoundTripGreeter_static(greeterPointer)
if let error = _swift_js_take_exception() {
throw error
}
return Greeter.bridgeJSLiftReturn(ret)
}

func _$SwiftClassSupportImports_jsRoundTripOptionalGreeter(_ greeter: Optional<Greeter>) throws(JSException) -> Optional<Greeter> {
let (greeterIsSome, greeterPointer) = greeter.bridgeJSLowerParameter()
let ret = bjs_SwiftClassSupportImports_jsRoundTripOptionalGreeter_static(greeterIsSome, greeterPointer)
if let error = _swift_js_take_exception() {
throw error
}
return Optional<Greeter>.bridgeJSLiftReturn(ret)
}
28 changes: 28 additions & 0 deletions Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json
Original file line number Diff line number Diff line change
Expand Up @@ -15345,6 +15345,34 @@
"_0" : "Greeter"
}
}
},
{
"name" : "jsRoundTripOptionalGreeter",
"parameters" : [
{
"name" : "greeter",
"type" : {
"nullable" : {
"_0" : {
"swiftHeapObject" : {
"_0" : "Greeter"
}
},
"_1" : "null"
}
}
}
],
"returnType" : {
"nullable" : {
"_0" : {
"swiftHeapObject" : {
"_0" : "Greeter"
}
},
"_1" : "null"
}
}
}
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,8 @@ export function getImports(importsContext) {
jsRoundTripGreeter: (greeter) => {
return greeter;
},
jsRoundTripOptionalGreeter: (greeter) => {
return greeter;
},
};
}
9 changes: 9 additions & 0 deletions Tests/BridgeJSRuntimeTests/SwiftClassSupportTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,20 @@ import XCTest

@JSClass struct SwiftClassSupportImports {
@JSFunction static func jsRoundTripGreeter(_ greeter: Greeter) throws(JSException) -> Greeter
@JSFunction static func jsRoundTripOptionalGreeter(_ greeter: Greeter?) throws(JSException) -> Greeter?
}

final class SwiftClassSupportTests: XCTestCase {
func testRoundTripGreeter() throws {
let greeter = try SwiftClassSupportImports.jsRoundTripGreeter(Greeter(name: "Hello"))
XCTAssertEqual(greeter.name, "Hello")
}

func testRoundTripOptionalGreeter() throws {
let greeter1 = try SwiftClassSupportImports.jsRoundTripOptionalGreeter(nil)
XCTAssertNil(greeter1)

let greeter2 = try SwiftClassSupportImports.jsRoundTripOptionalGreeter(Greeter(name: "Hello"))
XCTAssertEqual(greeter2?.name, "Hello")
}
}