diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift index 5b0105bf..dd28397d 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift @@ -800,7 +800,7 @@ struct StackCodegen { switch type { case .string: return "String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32())" - case .int: + case .int, .uint: return "Int.bridgeJSLiftParameter(_swift_js_pop_param_int32())" case .bool: return "Bool.bridgeJSLiftParameter(_swift_js_pop_param_int32())" @@ -873,7 +873,7 @@ struct StackCodegen { case .string: return "Optional.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32(), _swift_js_pop_param_int32())" - case .int: + case .int, .uint: return "Optional.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32())" case .bool: return "Optional.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32())" @@ -945,7 +945,7 @@ struct StackCodegen { "var __bjs_\(raw: varPrefix) = \(raw: accessor)", "__bjs_\(raw: varPrefix).withUTF8 { ptr in _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) }", ] - case .int: + case .int, .uint: return ["_swift_js_push_int(Int32(\(raw: accessor)))"] case .bool: return ["_swift_js_push_int(\(raw: accessor) ? 1 : 0)"] @@ -1052,7 +1052,7 @@ struct StackCodegen { "var __bjs_str_\(raw: varPrefix) = \(raw: unwrappedVar)", "__bjs_str_\(raw: varPrefix).withUTF8 { ptr in _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) }", ] - case .int: + case .int, .uint: return ["_swift_js_push_int(Int32(\(raw: unwrappedVar)))"] case .bool: return ["_swift_js_push_int(\(raw: unwrappedVar) ? 1 : 0)"] @@ -1643,6 +1643,7 @@ extension BridgeType { switch self { case .bool: return "Bool" case .int: return "Int" + case .uint: return "UInt" case .float: return "Float" case .double: return "Double" case .string: return "String" @@ -1687,7 +1688,7 @@ extension BridgeType { func liftParameterInfo() throws -> LiftingIntrinsicInfo { switch self { case .bool: return .bool - case .int: return .int + case .int, .uint: return .int case .float: return .float case .double: return .double case .string: return .string @@ -1739,7 +1740,7 @@ extension BridgeType { func loweringReturnInfo() throws -> LoweringIntrinsicInfo { switch self { case .bool: return .bool - case .int: return .int + case .int, .uint: return .int case .float: return .float case .double: return .double case .string: return .string diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift index 8a6ad930..9e5575c4 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift @@ -866,7 +866,7 @@ extension BridgeType { func loweringParameterInfo(context: BridgeContext = .importTS) throws -> LoweringParameterInfo { switch self { case .bool: return .bool - case .int: return .int + case .int, .uint: return .int case .float: return .float case .double: return .double case .string: return .string @@ -960,7 +960,7 @@ extension BridgeType { ) throws -> LiftingReturnInfo { switch self { case .bool: return .bool - case .int: return .int + case .int, .uint: return .int case .float: return .float case .double: return .double case .string: return .string diff --git a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift index 794637d9..4e2c9f86 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift @@ -3401,7 +3401,7 @@ extension BridgeType { return "void" case .string: return "string" - case .int: + case .int, .uint: return "number" case .float: return "number" diff --git a/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift b/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift index c0282cd3..cf091930 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift @@ -149,6 +149,15 @@ struct IntrinsicJSFragment: Sendable { } ) + /// Convert signed Int32 to unsigned for UInt values + static let uintLiftReturn = IntrinsicJSFragment( + parameters: ["value"], + printCode: { arguments, scope, printer, cleanupCode in + return ["\(arguments[0]) >>> 0"] + } + ) + static let uintLiftParameter = uintLiftReturn + static let stringLowerParameter = IntrinsicJSFragment( parameters: ["value"], printCode: { arguments, scope, printer, cleanupCode in @@ -519,7 +528,7 @@ struct IntrinsicJSFragment: Sendable { case .bool: printer.write("const \(resultVar) = \(JSGlueVariableScope.reservedStorageToReturnOptionalBool);") printer.write("\(JSGlueVariableScope.reservedStorageToReturnOptionalBool) = undefined;") - case .int: + case .int, .uint: printer.write("const \(resultVar) = \(JSGlueVariableScope.reservedStorageToReturnOptionalInt);") printer.write("\(JSGlueVariableScope.reservedStorageToReturnOptionalInt) = undefined;") case .float: @@ -651,7 +660,7 @@ struct IntrinsicJSFragment: Sendable { printer.write( "bjs[\"swift_js_return_optional_bool\"](\(isSomeVar) ? 1 : 0, \(isSomeVar) ? (\(value) ? 1 : 0) : 0);" ) - case .int: + case .int, .uint: printer.write( "bjs[\"swift_js_return_optional_int\"](\(isSomeVar) ? 1 : 0, \(isSomeVar) ? (\(value) | 0) : 0);" ) @@ -937,7 +946,7 @@ struct IntrinsicJSFragment: Sendable { ) printer.write("\(JSGlueVariableScope.reservedSwift).memory.release(\(value));") printer.write("\(targetVar) = String(\(objectLabel));") - case .int: + case .int, .uint: printer.write("\(targetVar) = \(value) | 0;") case .bool: printer.write("\(targetVar) = \(value) !== 0;") @@ -1121,7 +1130,7 @@ struct IntrinsicJSFragment: Sendable { case .string: printer.write("\(JSGlueVariableScope.reservedStorageToReturnString) = \(result);") printer.write("return;") - case .int: + case .int, .uint: printer.write("\(JSGlueVariableScope.reservedStorageToReturnOptionalInt) = \(result);") printer.write("return;") case .bool: @@ -1370,7 +1379,7 @@ struct IntrinsicJSFragment: Sendable { /// Returns a fragment that lowers a JS value to Wasm core values for parameters static func lowerParameter(type: BridgeType) throws -> IntrinsicJSFragment { switch type { - case .int, .float, .double, .bool, .unsafePointer: return .identity + case .int, .uint, .float, .double, .bool, .unsafePointer: return .identity case .string: return .stringLowerParameter case .jsObject: return .jsObjectLowerParameter case .swiftHeapObject: @@ -1414,6 +1423,7 @@ struct IntrinsicJSFragment: Sendable { static func liftReturn(type: BridgeType) throws -> IntrinsicJSFragment { switch type { case .int, .float, .double: return .identity + case .uint: return .uintLiftReturn case .bool: return .boolLiftReturn case .string: return .stringLiftReturn case .jsObject: return .jsObjectLiftReturn @@ -1460,6 +1470,7 @@ struct IntrinsicJSFragment: Sendable { static func liftParameter(type: BridgeType, context: BridgeContext = .importTS) throws -> IntrinsicJSFragment { switch type { case .int, .float, .double: return .identity + case .uint: return .uintLiftParameter case .bool: return .boolLiftParameter case .string: return .stringLiftParameter case .jsObject: return .jsObjectLiftParameter @@ -1560,7 +1571,7 @@ struct IntrinsicJSFragment: Sendable { /// Returns a fragment that lowers a JS value to Wasm core values for return values static func lowerReturn(type: BridgeType, context: BridgeContext = .importTS) throws -> IntrinsicJSFragment { switch type { - case .int, .float, .double: return .identity + case .int, .uint, .float, .double: return .identity case .bool: return .boolLowerReturn case .string: return .stringLowerReturn case .jsObject: return .jsObjectLowerReturn @@ -1909,7 +1920,7 @@ struct IntrinsicJSFragment: Sendable { return [] } ) - case .int: + case .int, .uint: return IntrinsicJSFragment( parameters: ["value"], printCode: { arguments, scope, printer, cleanup in @@ -1967,7 +1978,7 @@ struct IntrinsicJSFragment: Sendable { cleanup.write("\(JSGlueVariableScope.reservedSwift).memory.release(\(idVar));") } cleanup.write("}") - case .int: + case .int, .uint: printer.write( "\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? (\(value) | 0) : 0);" ) @@ -2024,7 +2035,7 @@ struct IntrinsicJSFragment: Sendable { return [bVar] } ) - case .int: + case .int, .uint: return IntrinsicJSFragment( parameters: [], printCode: { arguments, scope, printer, cleanup in @@ -2214,7 +2225,7 @@ struct IntrinsicJSFragment: Sendable { return [bVar] } ) - case .int: + case .int, .uint: return IntrinsicJSFragment( parameters: [], printCode: { arguments, scope, printer, cleanup in @@ -2363,7 +2374,7 @@ struct IntrinsicJSFragment: Sendable { return [] } ) - case .int: + case .int, .uint: return IntrinsicJSFragment( parameters: ["value"], printCode: { arguments, scope, printer, cleanup in @@ -2779,7 +2790,7 @@ struct IntrinsicJSFragment: Sendable { return [] } ) - case .int: + case .int, .uint: return IntrinsicJSFragment( parameters: ["value"], printCode: { arguments, scope, printer, cleanup in @@ -3009,7 +3020,7 @@ struct IntrinsicJSFragment: Sendable { } else { // Handle optional primitive types using helper switch wrappedType { - case .int: + case .int, .uint: pushOptionalPrimitive( value: value, isSomeVar: isSomeVar, @@ -3260,7 +3271,7 @@ struct IntrinsicJSFragment: Sendable { return [bVar] } ) - case .int: + case .int, .uint: return IntrinsicJSFragment( parameters: [], printCode: { arguments, scope, printer, cleanup in diff --git a/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift b/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift index d2f60cc4..33cc9447 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift @@ -127,7 +127,7 @@ public struct UnsafePointerType: Codable, Equatable, Hashable, Sendable { } public enum BridgeType: Codable, Equatable, Hashable, Sendable { - case int, float, double, string, bool, jsObject(String?), swiftHeapObject(String), void + case int, uint, float, double, string, bool, jsObject(String?), swiftHeapObject(String), void case unsafePointer(UnsafePointerType) indirect case optional(BridgeType) indirect case array(BridgeType) @@ -860,6 +860,8 @@ extension BridgeType { switch swiftType { case "Int": self = .int + case "UInt": + self = .uint case "Float": self = .float case "Double": @@ -887,7 +889,7 @@ extension BridgeType { switch self { case .void: return nil case .bool: return .i32 - case .int: return .i32 + case .int, .uint: return .i32 case .float: return .f32 case .double: return .f64 case .string: return nil @@ -933,6 +935,7 @@ extension BridgeType { public var mangleTypeName: String { switch self { case .int: return "Si" + case .uint: return "Su" case .float: return "Sf" case .double: return "Sd" case .string: return "SS" diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/PrimitiveParameters.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/PrimitiveParameters.swift index 62e78008..a0d4353e 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/PrimitiveParameters.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/PrimitiveParameters.swift @@ -1 +1 @@ -@JS func check(a: Int, b: Float, c: Double, d: Bool) {} +@JS func check(a: Int, b: UInt, c: Float, d: Double, e: Bool) {} diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/PrimitiveReturn.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/PrimitiveReturn.swift index 96a5dbc3..144a759e 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/PrimitiveReturn.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/PrimitiveReturn.swift @@ -1,4 +1,5 @@ @JS func checkInt() -> Int { fatalError() } +@JS func checkUInt() -> UInt { fatalError() } @JS func checkFloat() -> Float { fatalError() } @JS func checkDouble() -> Double { fatalError() } @JS func checkBool() -> Bool { fatalError() } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Export.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Export.d.ts index a9c37f37..9bf0e1e3 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Export.d.ts +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Export.d.ts @@ -5,7 +5,7 @@ // `swift package bridge-js`. export type Exports = { - check(a: number, b: number, c: number, d: boolean): void; + check(a: number, b: number, c: number, d: number, e: boolean): void; } export type Imports = { } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Export.js index c4c355c6..8e14c6c7 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Export.js @@ -222,8 +222,8 @@ export async function createInstantiator(options, swift) { createExports: (instance) => { const js = swift.memory.heap; const exports = { - check: function bjs_check(a, b, c, d) { - instance.exports.bjs_check(a, b, c, d); + check: function bjs_check(a, b, c, d, e) { + instance.exports.bjs_check(a, b, c, d, e); }, }; _exports = exports; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Export.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Export.d.ts index da7f5977..c726e1f5 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Export.d.ts +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Export.d.ts @@ -6,6 +6,7 @@ export type Exports = { checkInt(): number; + checkUInt(): number; checkFloat(): number; checkDouble(): number; checkBool(): boolean; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Export.js index e36b1820..f187fa8f 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Export.js @@ -226,6 +226,10 @@ export async function createInstantiator(options, swift) { const ret = instance.exports.bjs_checkInt(); return ret; }, + checkUInt: function bjs_checkUInt() { + const ret = instance.exports.bjs_checkUInt(); + return ret >>> 0; + }, checkFloat: function bjs_checkFloat() { const ret = instance.exports.bjs_checkFloat(); return ret; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveParameters.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveParameters.json index ab2539ab..3b45bf30 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveParameters.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveParameters.json @@ -29,7 +29,7 @@ "label" : "b", "name" : "b", "type" : { - "float" : { + "uint" : { } } @@ -38,7 +38,7 @@ "label" : "c", "name" : "c", "type" : { - "double" : { + "float" : { } } @@ -46,6 +46,15 @@ { "label" : "d", "name" : "d", + "type" : { + "double" : { + + } + } + }, + { + "label" : "e", + "name" : "e", "type" : { "bool" : { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveParameters.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveParameters.swift index bb3ea0fd..f91e1e21 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveParameters.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveParameters.swift @@ -1,8 +1,8 @@ @_expose(wasm, "bjs_check") @_cdecl("bjs_check") -public func _bjs_check(_ a: Int32, _ b: Float32, _ c: Float64, _ d: Int32) -> Void { +public func _bjs_check(_ a: Int32, _ b: Int32, _ c: Float32, _ d: Float64, _ e: Int32) -> Void { #if arch(wasm32) - check(a: Int.bridgeJSLiftParameter(a), b: Float.bridgeJSLiftParameter(b), c: Double.bridgeJSLiftParameter(c), d: Bool.bridgeJSLiftParameter(d)) + check(a: Int.bridgeJSLiftParameter(a), b: UInt.bridgeJSLiftParameter(b), c: Float.bridgeJSLiftParameter(c), d: Double.bridgeJSLiftParameter(d), e: Bool.bridgeJSLiftParameter(e)) #else fatalError("Only available on WebAssembly") #endif diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveReturn.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveReturn.json index e63b4a24..d70b0c9b 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveReturn.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveReturn.json @@ -24,6 +24,23 @@ } } }, + { + "abiName" : "bjs_checkUInt", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "checkUInt", + "parameters" : [ + + ], + "returnType" : { + "uint" : { + + } + } + }, { "abiName" : "bjs_checkFloat", "effects" : { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveReturn.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveReturn.swift index 62b5826d..74ee7b1c 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveReturn.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveReturn.swift @@ -9,6 +9,17 @@ public func _bjs_checkInt() -> Int32 { #endif } +@_expose(wasm, "bjs_checkUInt") +@_cdecl("bjs_checkUInt") +public func _bjs_checkUInt() -> Int32 { + #if arch(wasm32) + let ret = checkUInt() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + @_expose(wasm, "bjs_checkFloat") @_cdecl("bjs_checkFloat") public func _bjs_checkFloat() -> Float32 { diff --git a/Sources/JavaScriptKit/BridgeJSIntrinsics.swift b/Sources/JavaScriptKit/BridgeJSIntrinsics.swift index d8145e3a..dcdb8f6d 100644 --- a/Sources/JavaScriptKit/BridgeJSIntrinsics.swift +++ b/Sources/JavaScriptKit/BridgeJSIntrinsics.swift @@ -128,6 +128,23 @@ extension Int: _BridgedSwiftTypeLoweredIntoSingleWasmCoreType { } } +extension UInt: _BridgedSwiftTypeLoweredIntoSingleWasmCoreType { + // MARK: ImportTS + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + Int32(bitPattern: UInt32(self)) + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Int32) -> UInt { + UInt(UInt32(bitPattern: value)) + } + // MARK: ExportSwift + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Int32) -> UInt { + UInt(UInt32(bitPattern: value)) + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Int32 { + Int32(bitPattern: UInt32(self)) + } +} + extension Float: _BridgedSwiftTypeLoweredIntoSingleWasmCoreType { // MARK: ImportTS @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Float32 { @@ -918,6 +935,52 @@ extension Optional where Wrapped == Int { } } } + +extension Optional where Wrapped == UInt { + // MARK: ImportTS + + @available(*, unavailable, message: "Optional UInt type is not supported to be passed to imported JS functions") + @_spi(BridgeJS) public func bridgeJSLowerParameter() -> Void {} + + // MARK: ExportSwift + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameterWithPresence() -> ( + isSome: Int32, value: Int32 + ) { + switch consume self { + case .none: + return (isSome: 0, value: 0) + case .some(let wrapped): + return (isSome: 1, value: wrapped.bridgeJSLowerParameter()) + } + } + + @_spi(BridgeJS) public static func bridgeJSLiftParameter(_ isSome: Int32, _ wrappedValue: Int32) -> UInt? { + if isSome == 0 { + return nil + } else { + return UInt.bridgeJSLiftParameter(wrappedValue) + } + } + + @_spi(BridgeJS) public static func bridgeJSLiftReturnFromSideChannel() -> UInt? { + let isSome = _swift_js_get_optional_int_presence() + if isSome == 0 { + return nil + } else { + return UInt.bridgeJSLiftReturn(_swift_js_get_optional_int_value()) + } + } + + @_spi(BridgeJS) public func bridgeJSLowerReturn() -> Void { + switch self { + case .none: + _swift_js_return_optional_int(0, 0) + case .some(let value): + _swift_js_return_optional_int(1, value.bridgeJSLowerReturn()) + } + } +} extension Optional where Wrapped == String { // MARK: ExportSwift diff --git a/Tests/BridgeJSRuntimeTests/ExportAPITests.swift b/Tests/BridgeJSRuntimeTests/ExportAPITests.swift index af6ad530..2aee862c 100644 --- a/Tests/BridgeJSRuntimeTests/ExportAPITests.swift +++ b/Tests/BridgeJSRuntimeTests/ExportAPITests.swift @@ -13,6 +13,9 @@ func runJsWorks() -> Void @JS func roundTripInt(v: Int) -> Int { return v } +@JS func roundTripUInt(v: UInt) -> UInt { + return v +} @JS func roundTripFloat(v: Float) -> Float { return v } diff --git a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift index 7f35f672..948b454c 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift +++ b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift @@ -3222,6 +3222,17 @@ public func _bjs_roundTripInt(_ v: Int32) -> Int32 { #endif } +@_expose(wasm, "bjs_roundTripUInt") +@_cdecl("bjs_roundTripUInt") +public func _bjs_roundTripUInt(_ v: Int32) -> Int32 { + #if arch(wasm32) + let ret = roundTripUInt(v: UInt.bridgeJSLiftParameter(v)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + @_expose(wasm, "bjs_roundTripFloat") @_cdecl("bjs_roundTripFloat") public func _bjs_roundTripFloat(_ v: Float32) -> Float32 { diff --git a/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json b/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json index 2f0f964b..c79139ea 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json +++ b/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json @@ -4651,6 +4651,31 @@ } } }, + { + "abiName" : "bjs_roundTripUInt", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "roundTripUInt", + "parameters" : [ + { + "label" : "v", + "name" : "v", + "type" : { + "uint" : { + + } + } + } + ], + "returnType" : { + "uint" : { + + } + } + }, { "abiName" : "bjs_roundTripFloat", "effects" : { diff --git a/Tests/prelude.mjs b/Tests/prelude.mjs index b2a079c3..12307d60 100644 --- a/Tests/prelude.mjs +++ b/Tests/prelude.mjs @@ -155,6 +155,9 @@ function BridgeJSRuntimeTests_runJsWorks(instance, exports) { for (const v of [0, 1, -1, 2147483647, -2147483648]) { assert.equal(exports.roundTripInt(v), v); } + for (const v of [0, 1, 2147483647, 4294967295]) { + assert.equal(exports.roundTripUInt(v), v); + } for (const v of [ 0.0, 1.0, -1.0, NaN,