Skip to content
Open
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: 7 additions & 1 deletion Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,9 @@ public struct ImportTS {
self.returnType = returnType
self.context = context
let liftingInfo = try returnType.liftingReturnInfo(context: context)
if effects.isAsync || returnType == .void || returnType.usesSideChannelForOptionalReturn() {
if effects.isAsync || returnType == .void || returnType.usesSideChannelForOptionalReturn()
|| liftingInfo.valueToLift == nil
{
abiReturnType = nil
} else {
abiReturnType = liftingInfo.valueToLift
Expand Down Expand Up @@ -1032,6 +1034,10 @@ extension BridgeType {
case .namespaceEnum:
throw BridgeJSCoreError("Namespace enums cannot be used as return values")
case .nullable(let wrappedType, _):
// jsObject uses stack ABI for optionals — returns void, value goes through stacks
if case .jsObject = wrappedType {
return LiftingReturnInfo(valueToLift: nil)
}
let wrappedInfo = try wrappedType.liftingReturnInfo(context: context)
return LiftingReturnInfo(valueToLift: wrappedInfo.valueToLift)
case .array, .dictionary:
Expand Down
4 changes: 2 additions & 2 deletions Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2648,7 +2648,7 @@ private extension BridgeType {
case .string:
return .sideChannelReturn(.storage)
case .jsObject:
return .sideChannelReturn(.retainedObject)
return .stackABI
case .jsValue:
return .inlineFlag
case .swiftHeapObject:
Expand Down Expand Up @@ -2685,7 +2685,7 @@ private extension BridgeType {

var nilSentinel: NilSentinel {
switch self {
case .jsObject, .swiftProtocol:
case .swiftProtocol:
return .i32(0)
case .swiftHeapObject:
return .pointer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1655,7 +1655,7 @@ extension BridgeType {
}

switch wrappedType {
case .string, .integer, .float, .double, .jsObject, .swiftProtocol:
case .string, .integer, .float, .double, .swiftProtocol:
return true
case .rawValueEnum(_, let rawType):
switch rawType {
Expand All @@ -1666,7 +1666,7 @@ extension BridgeType {
default:
return false
}
case .bool, .caseEnum, .swiftHeapObject, .associatedValueEnum:
case .bool, .caseEnum, .swiftHeapObject, .associatedValueEnum, .jsObject:
return false
default:
return false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,4 +155,10 @@ func testMixedOptionals(firstName: String?, lastName: String?, age: Int?, active
@JSSetter func setIntOrUndefined(_ value: JSUndefinedOr<Int>) throws(JSException)
@JSFunction func roundTripIntOrNull(value: Int?) throws(JSException) -> Int?
@JSFunction func roundTripIntOrUndefined(value: JSUndefinedOr<Int>) throws(JSException) -> JSUndefinedOr<Int>

@JSGetter var childOrNull: WithOptionalJSClass?
@JSSetter func setChildOrNull(_ value: WithOptionalJSClass?) throws(JSException)
@JSFunction func roundTripChildOrNull(
value: WithOptionalJSClass?
) throws(JSException) -> WithOptionalJSClass?
}
Original file line number Diff line number Diff line change
Expand Up @@ -1158,6 +1158,20 @@
"_1" : "undefined"
}
}
},
{
"accessLevel" : "internal",
"name" : "childOrNull",
"type" : {
"nullable" : {
"_0" : {
"jsObject" : {
"_0" : "WithOptionalJSClass"
}
},
"_1" : "null"
}
}
}
],
"methods" : [
Expand Down Expand Up @@ -1444,6 +1458,40 @@
"_1" : "undefined"
}
}
},
{
"accessLevel" : "internal",
"effects" : {
"isAsync" : false,
"isStatic" : false,
"isThrows" : true
},
"name" : "roundTripChildOrNull",
"parameters" : [
{
"name" : "value",
"type" : {
"nullable" : {
"_0" : {
"jsObject" : {
"_0" : "WithOptionalJSClass"
}
},
"_1" : "null"
}
}
}
],
"returnType" : {
"nullable" : {
"_0" : {
"jsObject" : {
"_0" : "WithOptionalJSClass"
}
},
"_1" : "null"
}
}
}
],
"name" : "WithOptionalJSClass",
Expand Down Expand Up @@ -1573,6 +1621,21 @@
"_1" : "undefined"
}
}
},
{
"accessLevel" : "internal",
"functionName" : "childOrNull_set",
"name" : "childOrNull",
"type" : {
"nullable" : {
"_0" : {
"jsObject" : {
"_0" : "WithOptionalJSClass"
}
},
"_1" : "null"
}
}
}
],
"staticMethods" : [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,18 @@ fileprivate func bjs_WithOptionalJSClass_intOrUndefined_get_extern(_ self: Int32
return bjs_WithOptionalJSClass_intOrUndefined_get_extern(self)
}

#if arch(wasm32)
@_extern(wasm, module: "TestModule", name: "bjs_WithOptionalJSClass_childOrNull_get")
fileprivate func bjs_WithOptionalJSClass_childOrNull_get_extern(_ self: Int32) -> Void
#else
fileprivate func bjs_WithOptionalJSClass_childOrNull_get_extern(_ self: Int32) -> Void {
fatalError("Only available on WebAssembly")
}
#endif
@inline(never) fileprivate func bjs_WithOptionalJSClass_childOrNull_get(_ self: Int32) -> Void {
return bjs_WithOptionalJSClass_childOrNull_get_extern(self)
}

#if arch(wasm32)
@_extern(wasm, module: "TestModule", name: "bjs_WithOptionalJSClass_stringOrNull_set")
fileprivate func bjs_WithOptionalJSClass_stringOrNull_set_extern(_ self: Int32, _ newValueIsSome: Int32, _ newValueBytes: Int32, _ newValueLength: Int32) -> Void
Expand Down Expand Up @@ -622,6 +634,18 @@ fileprivate func bjs_WithOptionalJSClass_intOrUndefined_set_extern(_ self: Int32
return bjs_WithOptionalJSClass_intOrUndefined_set_extern(self, newValueIsSome, newValueValue)
}

#if arch(wasm32)
@_extern(wasm, module: "TestModule", name: "bjs_WithOptionalJSClass_childOrNull_set")
fileprivate func bjs_WithOptionalJSClass_childOrNull_set_extern(_ self: Int32, _ newValueIsSome: Int32, _ newValueValue: Int32) -> Void
#else
fileprivate func bjs_WithOptionalJSClass_childOrNull_set_extern(_ self: Int32, _ newValueIsSome: Int32, _ newValueValue: Int32) -> Void {
fatalError("Only available on WebAssembly")
}
#endif
@inline(never) fileprivate func bjs_WithOptionalJSClass_childOrNull_set(_ self: Int32, _ newValueIsSome: Int32, _ newValueValue: Int32) -> Void {
return bjs_WithOptionalJSClass_childOrNull_set_extern(self, newValueIsSome, newValueValue)
}

#if arch(wasm32)
@_extern(wasm, module: "TestModule", name: "bjs_WithOptionalJSClass_roundTripStringOrNull")
fileprivate func bjs_WithOptionalJSClass_roundTripStringOrNull_extern(_ self: Int32, _ valueIsSome: Int32, _ valueBytes: Int32, _ valueLength: Int32) -> Void
Expand Down Expand Up @@ -718,6 +742,18 @@ fileprivate func bjs_WithOptionalJSClass_roundTripIntOrUndefined_extern(_ self:
return bjs_WithOptionalJSClass_roundTripIntOrUndefined_extern(self, valueIsSome, valueValue)
}

#if arch(wasm32)
@_extern(wasm, module: "TestModule", name: "bjs_WithOptionalJSClass_roundTripChildOrNull")
fileprivate func bjs_WithOptionalJSClass_roundTripChildOrNull_extern(_ self: Int32, _ valueIsSome: Int32, _ valueValue: Int32) -> Void
#else
fileprivate func bjs_WithOptionalJSClass_roundTripChildOrNull_extern(_ self: Int32, _ valueIsSome: Int32, _ valueValue: Int32) -> Void {
fatalError("Only available on WebAssembly")
}
#endif
@inline(never) fileprivate func bjs_WithOptionalJSClass_roundTripChildOrNull(_ self: Int32, _ valueIsSome: Int32, _ valueValue: Int32) -> Void {
return bjs_WithOptionalJSClass_roundTripChildOrNull_extern(self, valueIsSome, valueValue)
}

func _$WithOptionalJSClass_init(_ valueOrNull: Optional<String>, _ valueOrUndefined: JSUndefinedOr<String>) throws(JSException) -> JSObject {
let ret0 = valueOrNull.bridgeJSWithLoweredParameter { (valueOrNullIsSome, valueOrNullBytes, valueOrNullLength) in
let ret1 = valueOrUndefined.bridgeJSWithLoweredParameter { (valueOrUndefinedIsSome, valueOrUndefinedBytes, valueOrUndefinedLength) in
Expand Down Expand Up @@ -805,6 +841,15 @@ func _$WithOptionalJSClass_intOrUndefined_get(_ self: JSObject) throws(JSExcepti
return JSUndefinedOr<Int>.bridgeJSLiftReturnFromSideChannel()
}

func _$WithOptionalJSClass_childOrNull_get(_ self: JSObject) throws(JSException) -> Optional<WithOptionalJSClass> {
let selfValue = self.bridgeJSLowerParameter()
bjs_WithOptionalJSClass_childOrNull_get(selfValue)
if let error = _swift_js_take_exception() {
throw error
}
return Optional<WithOptionalJSClass>.bridgeJSLiftReturn()
}

func _$WithOptionalJSClass_stringOrNull_set(_ self: JSObject, _ newValue: Optional<String>) throws(JSException) -> Void {
let selfValue = self.bridgeJSLowerParameter()
newValue.bridgeJSWithLoweredParameter { (newValueIsSome, newValueBytes, newValueLength) in
Expand Down Expand Up @@ -879,6 +924,15 @@ func _$WithOptionalJSClass_intOrUndefined_set(_ self: JSObject, _ newValue: JSUn
}
}

func _$WithOptionalJSClass_childOrNull_set(_ self: JSObject, _ newValue: Optional<WithOptionalJSClass>) throws(JSException) -> Void {
let selfValue = self.bridgeJSLowerParameter()
let (newValueIsSome, newValueValue) = newValue.bridgeJSLowerParameter()
bjs_WithOptionalJSClass_childOrNull_set(selfValue, newValueIsSome, newValueValue)
if let error = _swift_js_take_exception() {
throw error
}
}

func _$WithOptionalJSClass_roundTripStringOrNull(_ self: JSObject, _ value: Optional<String>) throws(JSException) -> Optional<String> {
let selfValue = self.bridgeJSLowerParameter()
value.bridgeJSWithLoweredParameter { (valueIsSome, valueBytes, valueLength) in
Expand Down Expand Up @@ -959,4 +1013,14 @@ func _$WithOptionalJSClass_roundTripIntOrUndefined(_ self: JSObject, _ value: JS
throw error
}
return JSUndefinedOr<Int>.bridgeJSLiftReturnFromSideChannel()
}

func _$WithOptionalJSClass_roundTripChildOrNull(_ self: JSObject, _ value: Optional<WithOptionalJSClass>) throws(JSException) -> Optional<WithOptionalJSClass> {
let selfValue = self.bridgeJSLowerParameter()
let (valueIsSome, valueValue) = value.bridgeJSLowerParameter()
bjs_WithOptionalJSClass_roundTripChildOrNull(selfValue, valueIsSome, valueValue)
if let error = _swift_js_take_exception() {
throw error
}
return Optional<WithOptionalJSClass>.bridgeJSLiftReturn()
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export interface WithOptionalJSClass {
roundTripBoolOrUndefined(value: boolean | undefined): boolean | undefined;
roundTripIntOrNull(value: number | null): number | null;
roundTripIntOrUndefined(value: number | undefined): number | undefined;
roundTripChildOrNull(value: WithOptionalJSClass | null): WithOptionalJSClass | null;
stringOrNull: string | null;
stringOrUndefined: string | undefined;
doubleOrNull: number | null;
Expand All @@ -38,6 +39,7 @@ export interface WithOptionalJSClass {
boolOrUndefined: boolean | undefined;
intOrNull: number | null;
intOrUndefined: number | undefined;
childOrNull: WithOptionalJSClass | null;
}
export type Exports = {
Greeter: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,19 @@ export async function createInstantiator(options, swift) {
setException(error);
}
}
TestModule["bjs_WithOptionalJSClass_childOrNull_get"] = function bjs_WithOptionalJSClass_childOrNull_get(self) {
try {
let ret = swift.memory.getObject(self).childOrNull;
const isSome = ret != null;
if (isSome) {
const objId = swift.memory.retain(ret);
i32Stack.push(objId);
}
i32Stack.push(isSome ? 1 : 0);
} catch (error) {
setException(error);
}
}
TestModule["bjs_WithOptionalJSClass_stringOrNull_set"] = function bjs_WithOptionalJSClass_stringOrNull_set(self, newValueIsSome, newValueBytes, newValueCount) {
try {
let optResult;
Expand Down Expand Up @@ -366,6 +379,22 @@ export async function createInstantiator(options, swift) {
setException(error);
}
}
TestModule["bjs_WithOptionalJSClass_childOrNull_set"] = function bjs_WithOptionalJSClass_childOrNull_set(self, newValue) {
try {
let optResult;
if (newValue) {
const objId = i32Stack.pop();
const obj = swift.memory.getObject(objId);
swift.memory.release(objId);
optResult = obj;
} else {
optResult = null;
}
swift.memory.getObject(self).childOrNull = optResult;
} catch (error) {
setException(error);
}
}
TestModule["bjs_WithOptionalJSClass_roundTripStringOrNull"] = function bjs_WithOptionalJSClass_roundTripStringOrNull(self, valueIsSome, valueBytes, valueCount) {
try {
let optResult;
Expand Down Expand Up @@ -452,6 +481,28 @@ export async function createInstantiator(options, swift) {
setException(error);
}
}
TestModule["bjs_WithOptionalJSClass_roundTripChildOrNull"] = function bjs_WithOptionalJSClass_roundTripChildOrNull(self, value) {
try {
let optResult;
if (value) {
const objId = i32Stack.pop();
const obj = swift.memory.getObject(objId);
swift.memory.release(objId);
optResult = obj;
} else {
optResult = null;
}
let ret = swift.memory.getObject(self).roundTripChildOrNull(optResult);
const isSome = ret != null;
if (isSome) {
const objId1 = swift.memory.retain(ret);
i32Stack.push(objId1);
}
i32Stack.push(isSome ? 1 : 0);
} catch (error) {
setException(error);
}
}
},
setInstance: (i) => {
instance = i;
Expand Down
6 changes: 1 addition & 5 deletions Sources/JavaScriptKit/BridgeJSIntrinsics.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1693,11 +1693,7 @@ extension _BridgedAsOptional where Wrapped == JSObject {
}

@_spi(BridgeJS) public consuming func bridgeJSLowerReturn() -> Void {
asOptional._bridgeJSLowerReturn(
noneValue: 0,
lowerWrapped: { $0.bridgeJSLowerReturn() },
write: _swift_js_return_optional_object
)
Wrapped.bridgeJSStackPushAsOptional(asOptional)
}
}

Expand Down
Loading