From 2699257a4652d1d7e144835ca9dbcf2d93e00eee Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sat, 23 Aug 2025 16:10:02 +0900 Subject: [PATCH 1/8] BridgeJS: Standardize lift/lower pattern across Swift and JavaScript Replace global intrinsic functions with consistent extension-based system. Each bridged type now defines standardized lift/lower operations: Swift side (type extensions): - bridgeJSLowerParameter/Return: Swift -> Wasm core types - bridgeJSLiftParameter/Return: Wasm core types -> Swift JavaScript side (JSGlueGen): - Corresponding lift/lower functions for JS <-> Wasm interop Adds CodeFragmentPrinter for improved code organization. Reduces generated code complexity across both Swift and JS. --- .../Sources/Generated/BridgeJS.ImportTS.swift | 6 +- .../Generated/BridgeJS.ExportSwift.swift | 34 +- .../Generated/BridgeJS.ImportTS.swift | 11 +- .../Sources/BridgeJSCore/ExportSwift.swift | 84 ++-- .../Sources/BridgeJSCore/ImportTS.swift | 35 +- .../Sources/BridgeJSLink/BridgeJSLink.swift | 410 ++++++++---------- .../BridgeJSLink/CodeFragmentPrinter.swift | 41 ++ .../Sources/BridgeJSLink/JSGlueGen.swift | 317 ++++++++++++++ .../BridgeJSLinkTests/Async.Export.js | 56 +-- .../BridgeJSLinkTests/Async.Import.js | 2 +- .../BridgeJSLinkTests/EnumCase.Export.js | 6 +- .../BridgeJSLinkTests/EnumNamespace.Export.js | 4 +- .../BridgeJSLinkTests/EnumRawType.Export.js | 4 +- .../MultipleImportedTypes.Import.js | 2 +- .../PrimitiveParameters.Import.js | 2 +- .../PrimitiveReturn.Export.js | 4 +- .../PrimitiveReturn.Import.js | 2 +- .../BridgeJSLinkTests/PropertyTypes.Export.js | 24 +- .../TS2SkeletonLike.Import.js | 2 +- .../TypeScriptClass.Import.js | 3 +- .../ExportSwiftTests/Async.swift | 26 +- .../ExportSwiftTests/EnumNamespace.swift | 6 +- .../ExportSwiftTests/EnumRawType.swift | 37 +- .../ExportSwiftTests/Namespaces.swift | 36 +- .../PrimitiveParameters.swift | 2 +- .../ExportSwiftTests/PrimitiveReturn.swift | 2 +- .../ExportSwiftTests/PropertyTypes.swift | 80 +--- .../ExportSwiftTests/StringParameter.swift | 6 +- .../ExportSwiftTests/StringReturn.swift | 6 +- .../ExportSwiftTests/SwiftClass.swift | 30 +- .../ImportTSTests/ArrayParameter.swift | 6 +- .../__Snapshots__/ImportTSTests/Async.swift | 10 +- .../ImportTSTests/Interface.swift | 8 +- .../ImportTSTests/MultipleImportedTypes.swift | 70 +-- .../ImportTSTests/PrimitiveParameters.swift | 2 +- .../ImportTSTests/PrimitiveReturn.swift | 2 +- .../ImportTSTests/StringParameter.swift | 12 +- .../ImportTSTests/StringReturn.swift | 5 +- .../ImportTSTests/TS2SkeletonLike.swift | 46 +- .../ImportTSTests/TypeScriptClass.swift | 34 +- .../JavaScriptKit/BridgeJSInstrincics.swift | 229 ++++++++-- .../include/BridgeJSInstrincics.h | 2 + .../Generated/BridgeJS.ExportSwift.swift | 248 ++++------- .../Generated/BridgeJS.ImportTS.swift | 73 +--- 44 files changed, 1033 insertions(+), 994 deletions(-) create mode 100644 Plugins/BridgeJS/Sources/BridgeJSLink/CodeFragmentPrinter.swift create mode 100644 Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift diff --git a/Benchmarks/Sources/Generated/BridgeJS.ImportTS.swift b/Benchmarks/Sources/Generated/BridgeJS.ImportTS.swift index 871938cf..afce5aca 100644 --- a/Benchmarks/Sources/Generated/BridgeJS.ImportTS.swift +++ b/Benchmarks/Sources/Generated/BridgeJS.ImportTS.swift @@ -45,11 +45,7 @@ func benchmarkRunner(_ name: String, _ body: JSObject) throws(JSException) -> Vo fatalError("Only available on WebAssembly") } #endif - var name = name - let nameId = name.withUTF8 { b in - _swift_js_make_js_string(b.baseAddress.unsafelyUnwrapped, Int32(b.count)) - } - bjs_benchmarkRunner(nameId, Int32(bitPattern: body.id)) + bjs_benchmarkRunner(name.bridgeJSLowerParameter(), body.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } diff --git a/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/BridgeJS.ExportSwift.swift b/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/BridgeJS.ExportSwift.swift index 3936b254..5deb14b9 100644 --- a/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/BridgeJS.ExportSwift.swift +++ b/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/BridgeJS.ExportSwift.swift @@ -22,15 +22,7 @@ public func _bjs_PlayBridgeJS_init() -> UnsafeMutableRawPointer { public func _bjs_PlayBridgeJS_update(_self: UnsafeMutableRawPointer, swiftSourceBytes: Int32, swiftSourceLen: Int32, dtsSourceBytes: Int32, dtsSourceLen: Int32) -> UnsafeMutableRawPointer { #if arch(wasm32) do { - let swiftSource = String(unsafeUninitializedCapacity: Int(swiftSourceLen)) { b in - _swift_js_init_memory(swiftSourceBytes, b.baseAddress.unsafelyUnwrapped) - return Int(swiftSourceLen) - } - let dtsSource = String(unsafeUninitializedCapacity: Int(dtsSourceLen)) { b in - _swift_js_init_memory(dtsSourceBytes, b.baseAddress.unsafelyUnwrapped) - return Int(dtsSourceLen) - } - let ret = try Unmanaged.fromOpaque(_self).takeUnretainedValue().update(swiftSource: swiftSource, dtsSource: dtsSource) + let ret = try Unmanaged.fromOpaque(_self).takeUnretainedValue().update(swiftSource: String.bridgeJSLiftParameter(swiftSourceBytes, swiftSourceLen), dtsSource: String.bridgeJSLiftParameter(dtsSourceBytes, dtsSourceLen)) return Unmanaged.passRetained(ret).toOpaque() } catch let error { if let error = error.thrownValue.object { @@ -68,10 +60,8 @@ extension PlayBridgeJS: ConvertibleToJSValue { @_cdecl("bjs_PlayBridgeJSOutput_outputJs") public func _bjs_PlayBridgeJSOutput_outputJs(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - var ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().outputJs() - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().outputJs() + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -81,10 +71,8 @@ public func _bjs_PlayBridgeJSOutput_outputJs(_self: UnsafeMutableRawPointer) -> @_cdecl("bjs_PlayBridgeJSOutput_outputDts") public func _bjs_PlayBridgeJSOutput_outputDts(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - var ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().outputDts() - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().outputDts() + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -94,10 +82,8 @@ public func _bjs_PlayBridgeJSOutput_outputDts(_self: UnsafeMutableRawPointer) -> @_cdecl("bjs_PlayBridgeJSOutput_importSwiftGlue") public func _bjs_PlayBridgeJSOutput_importSwiftGlue(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - var ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().importSwiftGlue() - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().importSwiftGlue() + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -107,10 +93,8 @@ public func _bjs_PlayBridgeJSOutput_importSwiftGlue(_self: UnsafeMutableRawPoint @_cdecl("bjs_PlayBridgeJSOutput_exportSwiftGlue") public func _bjs_PlayBridgeJSOutput_exportSwiftGlue(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - var ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().exportSwiftGlue() - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().exportSwiftGlue() + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif diff --git a/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/BridgeJS.ImportTS.swift b/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/BridgeJS.ImportTS.swift index 5d82db08..3cee3b6e 100644 --- a/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/BridgeJS.ImportTS.swift +++ b/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/BridgeJS.ImportTS.swift @@ -42,18 +42,11 @@ struct TS2Skeleton { fatalError("Only available on WebAssembly") } #endif - var ts = ts - let tsId = ts.withUTF8 { b in - _swift_js_make_js_string(b.baseAddress.unsafelyUnwrapped, Int32(b.count)) - } - let ret = bjs_TS2Skeleton_convert(Int32(bitPattern: self.this.id), tsId) + let ret = bjs_TS2Skeleton_convert(self.this.bridgeJSLowerParameter(), ts.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } - return String(unsafeUninitializedCapacity: Int(ret)) { b in - _swift_js_init_memory_with_result(b.baseAddress.unsafelyUnwrapped, Int32(ret)) - return Int(ret) - } + return String.bridgeJSLiftReturn(ret) } } \ No newline at end of file diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift index 56e01290..f170c03d 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift @@ -782,10 +782,14 @@ public class ExportSwift { parameters.append(param) switch param.type { case .bool: - liftedParameterExprs.append(ExprSyntax("\(raw: param.name) == 1")) + liftedParameterExprs.append( + ExprSyntax("\(raw: param.type.swiftType).bridgeJSLiftParameter(\(raw: param.name))") + ) abiParameterSignatures.append((param.name, .i32)) case .int: - liftedParameterExprs.append(ExprSyntax("\(raw: param.type.swiftType)(\(raw: param.name))")) + liftedParameterExprs.append( + ExprSyntax("\(raw: param.type.swiftType).bridgeJSLiftParameter(\(raw: param.name))") + ) abiParameterSignatures.append((param.name, .i32)) case .float: liftedParameterExprs.append(ExprSyntax("\(raw: param.name)")) @@ -796,14 +800,11 @@ public class ExportSwift { case .string: let bytesLabel = "\(param.name)Bytes" let lengthLabel = "\(param.name)Len" - let prepare: CodeBlockItemSyntax = """ - let \(raw: param.name) = String(unsafeUninitializedCapacity: Int(\(raw: lengthLabel))) { b in - _swift_js_init_memory(\(raw: bytesLabel), b.baseAddress.unsafelyUnwrapped) - return Int(\(raw: lengthLabel)) - } - """ - append(prepare) - liftedParameterExprs.append(ExprSyntax("\(raw: param.name)")) + liftedParameterExprs.append( + ExprSyntax( + "\(raw: param.type.swiftType).bridgeJSLiftParameter(\(raw: bytesLabel), \(raw: lengthLabel))" + ) + ) abiParameterSignatures.append((bytesLabel, .i32)) abiParameterSignatures.append((lengthLabel, .i32)) case .caseEnum(let enumName): @@ -813,21 +814,19 @@ public class ExportSwift { if rawType == .string { let bytesLabel = "\(param.name)Bytes" let lengthLabel = "\(param.name)Len" - let prepare: CodeBlockItemSyntax = """ - let \(raw: param.name) = String(unsafeUninitializedCapacity: Int(\(raw: lengthLabel))) { b in - _swift_js_init_memory(\(raw: bytesLabel), b.baseAddress.unsafelyUnwrapped) - return Int(\(raw: lengthLabel)) - } - """ - append(prepare) - liftedParameterExprs.append(ExprSyntax("\(raw: enumName)(rawValue: \(raw: param.name))!")) + liftedParameterExprs.append( + ExprSyntax( + "\(raw: enumName)(rawValue: String.bridgeJSLiftParameter(\(raw: bytesLabel), \(raw: lengthLabel)))!" + ) + ) abiParameterSignatures.append((bytesLabel, .i32)) abiParameterSignatures.append((lengthLabel, .i32)) } else { let conversionExpr: String switch rawType { case .bool: - conversionExpr = "\(enumName)(rawValue: \(param.name) != 0)!" + conversionExpr = + "\(enumName)(rawValue: \(param.type.swiftType).bridgeJSLiftParameter(\(param.name)))" case .uint, .uint32, .uint64: if rawType == .uint64 { conversionExpr = @@ -848,12 +847,9 @@ public class ExportSwift { break case .namespaceEnum: break - case .jsObject(nil): - liftedParameterExprs.append(ExprSyntax("JSObject(id: UInt32(bitPattern: \(raw: param.name)))")) - abiParameterSignatures.append((param.name, .i32)) case .jsObject(let name): liftedParameterExprs.append( - ExprSyntax("\(raw: name)(takingThis: UInt32(bitPattern: \(raw: param.name)))") + ExprSyntax("\(raw: name ?? "JSObject").bridgeJSLiftParameter(\(raw: param.name))") ) abiParameterSignatures.append((param.name, .i32)) case .swiftHeapObject: @@ -896,16 +892,10 @@ public class ExportSwift { return CodeBlockItemSyntax(item: .init(StmtSyntax("return \(raw: callExpr).jsValue"))) } - let retMutability: String - if returnType == .string { - retMutability = "var" - } else { - retMutability = "let" - } if returnType == .void { return CodeBlockItemSyntax(item: .init(ExpressionStmtSyntax(expression: callExpr))) } else { - return CodeBlockItemSyntax(item: .init(DeclSyntax("\(raw: retMutability) ret = \(raw: callExpr)"))) + return CodeBlockItemSyntax(item: .init(DeclSyntax("let ret = \(raw: callExpr)"))) } } @@ -925,11 +915,10 @@ public class ExportSwift { func callPropertyGetter(klassName: String, propertyName: String, returnType: BridgeType) { let (_, selfExpr) = removeFirstLiftedParameter() - let retMutability = returnType == .string ? "var" : "let" if returnType == .void { append("\(raw: selfExpr).\(raw: propertyName)") } else { - append("\(raw: retMutability) ret = \(raw: selfExpr).\(raw: propertyName)") + append("let ret = \(raw: selfExpr).\(raw: propertyName)") } } @@ -988,15 +977,9 @@ public class ExportSwift { case .int, .float, .double: append("return \(raw: abiReturnType!.swiftType)(ret)") case .bool: - append("return Int32(ret ? 1 : 0)") + append("return ret.bridgeJSLowerReturn()") case .string: - append( - """ - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } - """ - ) + append("return ret.bridgeJSLowerReturn()") case .caseEnum: abiReturnType = .i32 append("return ret.bridgeJSRawValue") @@ -1004,10 +987,7 @@ public class ExportSwift { if rawType == .string { append( """ - var rawValue = ret.rawValue - return rawValue.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + return ret.rawValue.bridgeJSLowerReturn() """ ) } else { @@ -1028,18 +1008,8 @@ public class ExportSwift { } case .associatedValueEnum: break; case .namespaceEnum: break; - case .jsObject(nil): - append( - """ - return _swift_js_retain(Int32(bitPattern: ret.id)) - """ - ) - case .jsObject(_?): - append( - """ - return _swift_js_retain(Int32(bitPattern: ret.this.id)) - """ - ) + case .jsObject: + append("return ret.bridgeJSLowerReturn()") case .swiftHeapObject: // Perform a manual retain on the object, which will be balanced by a // release called via FinalizationRegistry @@ -1058,7 +1028,7 @@ public class ExportSwift { let ret = JSPromise.async { \(CodeBlockItemListSyntax(self.body)) }.jsObject - return _swift_js_retain(Int32(bitPattern: ret.id)) + return ret.bridgeJSLowerReturn() """ } else if effects.isThrows { body = """ diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift index bcbae469..9475c784 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift @@ -73,7 +73,7 @@ public struct ImportTS { abiParameterForwardings.append( LabeledExprSyntax( label: param.label, - expression: ExprSyntax("Int32(\(raw: param.name) ? 1 : 0)") + expression: ExprSyntax("\(raw: param.name).bridgeJSLowerParameter()") ) ) abiParameterSignatures.append((param.name, .i32)) @@ -102,24 +102,10 @@ public struct ImportTS { ) abiParameterSignatures.append((param.name, .f64)) case .string: - let stringIdName = "\(param.name)Id" - body.append( - """ - var \(raw: param.name) = \(raw: param.name) - - """ - ) - body.append( - """ - let \(raw: stringIdName) = \(raw: param.name).withUTF8 { b in - _swift_js_make_js_string(b.baseAddress.unsafelyUnwrapped, Int32(b.count)) - } - """ - ) abiParameterForwardings.append( LabeledExprSyntax( label: param.label, - expression: ExprSyntax("\(raw: stringIdName)") + expression: ExprSyntax("\(raw: param.name).bridgeJSLowerParameter()") ) ) abiParameterSignatures.append((param.name, .i32)) @@ -130,14 +116,14 @@ public struct ImportTS { abiParameterForwardings.append( LabeledExprSyntax( label: param.label, - expression: ExprSyntax("Int32(bitPattern: \(raw: param.name).this.id)") + expression: ExprSyntax("\(raw: param.name).this.bridgeJSLowerParameter()") ) ) case .jsObject(nil): abiParameterForwardings.append( LabeledExprSyntax( label: param.label, - expression: ExprSyntax("Int32(bitPattern: \(raw: param.name).id)") + expression: ExprSyntax("\(raw: param.name).bridgeJSLowerParameter()") ) ) abiParameterSignatures.append((param.name, .i32)) @@ -163,7 +149,7 @@ public struct ImportTS { switch returnType { case .bool: abiReturnType = .i32 - body.append("return ret == 1") + body.append("return \(raw: returnType.swiftType).bridgeJSLiftReturn(ret)") case .int: abiReturnType = .i32 body.append("return \(raw: returnType.swiftType)(ret)") @@ -175,14 +161,7 @@ public struct ImportTS { body.append("return \(raw: returnType.swiftType)(ret)") case .string: abiReturnType = .i32 - body.append( - """ - return String(unsafeUninitializedCapacity: Int(ret)) { b in - _swift_js_init_memory_with_result(b.baseAddress.unsafelyUnwrapped, Int32(ret)) - return Int(ret) - } - """ - ) + body.append("return \(raw: returnType.swiftType).bridgeJSLiftReturn(ret)") case .caseEnum, .rawValueEnum, .associatedValueEnum, .namespaceEnum: throw BridgeJSCoreError("Enum types are not yet supported in TypeScript imports") case .jsObject(let name): @@ -190,7 +169,7 @@ public struct ImportTS { if let name = name { body.append("return \(raw: name)(takingThis: ret)") } else { - body.append("return JSObject(id: UInt32(bitPattern: ret))") + body.append("return JSObject.bridgeJSLiftReturn(ret)") } case .swiftHeapObject(_): throw BridgeJSCoreError("swiftHeapObject is not supported in imported signatures") diff --git a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift index 2b220e43..f704b828 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift @@ -90,7 +90,7 @@ struct BridgeJSLink { for skeleton in exportedSkeletons { for klass in skeleton.classes { - let (jsType, dtsType, dtsExportEntry) = renderExportedClass(klass) + let (jsType, dtsType, dtsExportEntry) = try renderExportedClass(klass) classLines.append(contentsOf: jsType) exportsLines.append("\(klass.name),") dtsExportLines.append(contentsOf: dtsExportEntry) @@ -131,7 +131,7 @@ struct BridgeJSLink { } for function in skeleton.functions { - var (js, dts) = renderExportedFunction(function: function) + var (js, dts) = try renderExportedFunction(function: function) if function.namespace != nil { namespacedFunctions.append(function) @@ -222,16 +222,16 @@ struct BridgeJSLink { // To update this file, just rebuild your project or run // `swift package bridge-js`. - \(topLevelEnumsSection)\(namespaceAssignmentsSection)export async function createInstantiator(options, swift) { - let instance; - let memory; - let setException; - const textDecoder = new TextDecoder("utf-8"); - const textEncoder = new TextEncoder("utf-8"); + \(topLevelEnumsSection)\(namespaceAssignmentsSection)export async function createInstantiator(options, \(JSGlueVariableScope.reservedSwift)) { + let \(JSGlueVariableScope.reservedInstance); + let \(JSGlueVariableScope.reservedMemory); + let \(JSGlueVariableScope.reservedSetException); + const \(JSGlueVariableScope.reservedTextDecoder) = new TextDecoder("utf-8"); + const \(JSGlueVariableScope.reservedTextEncoder) = new TextEncoder("utf-8"); - let tmpRetString; - let tmpRetBytes; - let tmpRetException; + let \(JSGlueVariableScope.reservedStorageToReturnString); + let \(JSGlueVariableScope.reservedStorageToReturnBytes); + let \(JSGlueVariableScope.reservedStorageToReturnException); return { /** * @param {WebAssembly.Imports} importObject @@ -241,45 +241,45 @@ struct BridgeJSLink { importObject["bjs"] = bjs; const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { - const bytes = new Uint8Array(memory.buffer, ptr, len)\(sharedMemory ? ".slice()" : ""); - tmpRetString = textDecoder.decode(bytes); + const bytes = new Uint8Array(\(JSGlueVariableScope.reservedMemory).buffer, ptr, len)\(sharedMemory ? ".slice()" : ""); + \(JSGlueVariableScope.reservedStorageToReturnString) = \(JSGlueVariableScope.reservedTextDecoder).decode(bytes); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { - const source = swift.memory.getObject(sourceId); - const bytes = new Uint8Array(memory.buffer, bytesPtr); + const source = \(JSGlueVariableScope.reservedSwift).memory.getObject(sourceId); + const bytes = new Uint8Array(\(JSGlueVariableScope.reservedMemory).buffer, bytesPtr); bytes.set(source); } bjs["swift_js_make_js_string"] = function(ptr, len) { - const bytes = new Uint8Array(memory.buffer, ptr, len)\(sharedMemory ? ".slice()" : ""); - return swift.memory.retain(textDecoder.decode(bytes)); + const bytes = new Uint8Array(\(JSGlueVariableScope.reservedMemory).buffer, ptr, len)\(sharedMemory ? ".slice()" : ""); + return \(JSGlueVariableScope.reservedSwift).memory.retain(\(JSGlueVariableScope.reservedTextDecoder).decode(bytes)); } bjs["swift_js_init_memory_with_result"] = function(ptr, len) { - const target = new Uint8Array(memory.buffer, ptr, len); - target.set(tmpRetBytes); - tmpRetBytes = undefined; + const target = new Uint8Array(\(JSGlueVariableScope.reservedMemory).buffer, ptr, len); + target.set(\(JSGlueVariableScope.reservedStorageToReturnBytes)); + \(JSGlueVariableScope.reservedStorageToReturnBytes) = undefined; } bjs["swift_js_throw"] = function(id) { - tmpRetException = swift.memory.retainByRef(id); + \(JSGlueVariableScope.reservedStorageToReturnException) = \(JSGlueVariableScope.reservedSwift).memory.retainByRef(id); } bjs["swift_js_retain"] = function(id) { - return swift.memory.retainByRef(id); + return \(JSGlueVariableScope.reservedSwift).memory.retainByRef(id); } bjs["swift_js_release"] = function(id) { - swift.memory.release(id); + \(JSGlueVariableScope.reservedSwift).memory.release(id); } \(renderSwiftClassWrappers().map { $0.indent(count: 12) }.joined(separator: "\n")) \(importObjectBuilders.flatMap { $0.importedLines }.map { $0.indent(count: 12) }.joined(separator: "\n")) }, setInstance: (i) => { - instance = i; - memory = instance.exports.memory; - setException = (error) => { - instance.exports._swift_js_exception.value = swift.memory.retain(error) + \(JSGlueVariableScope.reservedInstance) = i; + \(JSGlueVariableScope.reservedMemory) = \(JSGlueVariableScope.reservedInstance).exports.memory; + \(JSGlueVariableScope.reservedSetException) = (error) => { + \(JSGlueVariableScope.reservedInstance).exports._swift_js_exception.value = \(JSGlueVariableScope.reservedSwift).memory.retain(error) } }, /** @param {WebAssembly.Instance} instance */ createExports: (instance) => { - const js = swift.memory.heap; + const js = \(JSGlueVariableScope.reservedSwift).memory.heap; \(exportsSection) } } @@ -343,7 +343,7 @@ struct BridgeJSLink { let wrapperFunctionName = "bjs_\(klass.name)_wrap" wrapperLines.append("importObject[\"\(moduleName)\"][\"\(wrapperFunctionName)\"] = function(pointer) {") wrapperLines.append(" const obj = \(klass.name).__construct(pointer);") - wrapperLines.append(" return swift.memory.retain(obj);") + wrapperLines.append(" return \(JSGlueVariableScope.reservedSwift).memory.retain(obj);") wrapperLines.append("};") } } @@ -384,125 +384,66 @@ struct BridgeJSLink { } class ExportedThunkBuilder { - var bodyLines: [String] = [] - var cleanupLines: [String] = [] + var body: CodeFragmentPrinter + var cleanupCode: CodeFragmentPrinter var parameterForwardings: [String] = [] let effects: Effects + let scope: JSGlueVariableScope init(effects: Effects) { self.effects = effects + self.scope = JSGlueVariableScope() + self.body = CodeFragmentPrinter() + self.cleanupCode = CodeFragmentPrinter() } - func lowerParameter(param: Parameter) { - switch param.type { - case .void: return - case .int, .float, .double, .bool: - parameterForwardings.append(param.name) - case .string: - let bytesLabel = "\(param.name)Bytes" - let bytesIdLabel = "\(param.name)Id" - bodyLines.append("const \(bytesLabel) = textEncoder.encode(\(param.name));") - bodyLines.append("const \(bytesIdLabel) = swift.memory.retain(\(bytesLabel));") - cleanupLines.append("swift.memory.release(\(bytesIdLabel));") - parameterForwardings.append(bytesIdLabel) - parameterForwardings.append("\(bytesLabel).length") - case .caseEnum(_): - parameterForwardings.append("\(param.name) | 0") - case .rawValueEnum(_, let rawType): - switch rawType { - case .string: - let bytesLabel = "\(param.name)Bytes" - let bytesIdLabel = "\(param.name)Id" - bodyLines.append("const \(bytesLabel) = textEncoder.encode(\(param.name));") - bodyLines.append("const \(bytesIdLabel) = swift.memory.retain(\(bytesLabel));") - cleanupLines.append("swift.memory.release(\(bytesIdLabel));") - parameterForwardings.append(bytesIdLabel) - parameterForwardings.append("\(bytesLabel).length") - case .bool: - parameterForwardings.append("\(param.name) ? 1 : 0") - default: - parameterForwardings.append("\(param.name)") - } - case .associatedValueEnum: - parameterForwardings.append("0") - parameterForwardings.append("0") - case .namespaceEnum: - break - case .jsObject: - parameterForwardings.append("swift.memory.retain(\(param.name))") - case .swiftHeapObject: - parameterForwardings.append("\(param.name).pointer") - } + func lowerParameter(param: Parameter) throws { + let loweringFragment = try IntrinsicJSFragment.lowerParameter(type: param.type) + assert( + loweringFragment.parameters.count == 1, + "Lowering fragment should have exactly one parameter to lower" + ) + let loweredValues = loweringFragment.printCode([param.name], scope, body, cleanupCode) + parameterForwardings.append(contentsOf: loweredValues) } func lowerSelf() { parameterForwardings.append("this.pointer") } - func call(abiName: String, returnType: BridgeType) -> String? { + func call(abiName: String, returnType: BridgeType) throws -> String? { if effects.isAsync { - return _call(abiName: abiName, returnType: .jsObject(nil)) + return try _call(abiName: abiName, returnType: .jsObject(nil)) } else { - return _call(abiName: abiName, returnType: returnType) + return try _call(abiName: abiName, returnType: returnType) } } - private func _call(abiName: String, returnType: BridgeType) -> String? { + private func _call(abiName: String, returnType: BridgeType) throws -> String? { let call = "instance.exports.\(abiName)(\(parameterForwardings.joined(separator: ", ")))" - var returnExpr: String? - - switch returnType { - case .void: - bodyLines.append("\(call);") - case .string: - bodyLines.append("\(call);") - bodyLines.append("const ret = tmpRetString;") - bodyLines.append("tmpRetString = undefined;") - returnExpr = "ret" - case .caseEnum(_): - bodyLines.append("const ret = \(call);") - returnExpr = "ret" - case .rawValueEnum(_, let rawType): - switch rawType { - case .string: - bodyLines.append("\(call);") - bodyLines.append("const ret = tmpRetString;") - bodyLines.append("tmpRetString = undefined;") - returnExpr = "ret" - case .bool: - bodyLines.append("const ret = \(call);") - returnExpr = "ret !== 0" - default: - bodyLines.append("const ret = \(call);") - returnExpr = "ret" - } - case .associatedValueEnum: - bodyLines.append("\(call);") - returnExpr = "\"\"" - case .namespaceEnum: - break - case .int, .float, .double: - bodyLines.append("const ret = \(call);") - returnExpr = "ret" - case .bool: - bodyLines.append("const ret = \(call) !== 0;") - returnExpr = "ret" - case .jsObject: - bodyLines.append("const retId = \(call);") - // TODO: Implement "take" operation - bodyLines.append("const ret = swift.memory.getObject(retId);") - bodyLines.append("swift.memory.release(retId);") - returnExpr = "ret" - case .swiftHeapObject(let name): - bodyLines.append("const ret = \(name).__construct(\(call));") - returnExpr = "ret" + let liftingFragment = try IntrinsicJSFragment.liftReturn(type: returnType) + assert( + liftingFragment.parameters.count <= 1, + "Lifting fragment should have at most one parameter to lift" + ) + let fragmentArguments: [String] + if liftingFragment.parameters.isEmpty { + body.write("\(call);") + fragmentArguments = [] + } else { + let returnVariable = scope.variable("ret") + body.write("const \(returnVariable) = \(call);") + fragmentArguments = [returnVariable] } - return returnExpr + let liftedValues = liftingFragment.printCode(fragmentArguments, scope, body, cleanupCode) + assert(liftedValues.count <= 1, "Lifting fragment should produce at most one value") + return liftedValues.first } func callConstructor(abiName: String) -> String { - let call = "instance.exports.\(abiName)(\(parameterForwardings.joined(separator: ", ")))" - bodyLines.append("const ret = \(call);") + let call = + "\(JSGlueVariableScope.reservedInstance).exports.\(abiName)(\(parameterForwardings.joined(separator: ", ")))" + body.write("const ret = \(call);") return "ret" } @@ -510,12 +451,13 @@ struct BridgeJSLink { guard effects.isThrows else { return [] } + let exceptionVariable = JSGlueVariableScope.reservedStorageToReturnException return [ - "if (tmpRetException) {", + "if (\(exceptionVariable)) {", // TODO: Implement "take" operation - " const error = swift.memory.getObject(tmpRetException);", - " swift.memory.release(tmpRetException);", - " tmpRetException = undefined;", + " const error = \(JSGlueVariableScope.reservedSwift).memory.getObject(\(exceptionVariable));", + " \(JSGlueVariableScope.reservedSwift).memory.release(\(exceptionVariable));", + " \(exceptionVariable) = undefined;", " throw error;", "}", ] @@ -531,8 +473,8 @@ struct BridgeJSLink { funcLines.append( "\(declarationPrefixKeyword.map { "\($0) "} ?? "")\(name)(\(parameters.map { $0.name }.joined(separator: ", "))) {" ) - funcLines.append(contentsOf: bodyLines.map { $0.indent(count: 4) }) - funcLines.append(contentsOf: cleanupLines.map { $0.indent(count: 4) }) + funcLines.append(contentsOf: body.lines.map { $0.indent(count: 4) }) + funcLines.append(contentsOf: cleanupCode.lines.map { $0.indent(count: 4) }) funcLines.append(contentsOf: checkExceptionLines().map { $0.indent(count: 4) }) if let returnExpr = returnExpr { funcLines.append("return \(returnExpr);".indent(count: 4)) @@ -678,12 +620,12 @@ struct BridgeJSLink { return (jsLines, dtsLines) } - func renderExportedFunction(function: ExportedFunction) -> (js: [String], dts: [String]) { + func renderExportedFunction(function: ExportedFunction) throws -> (js: [String], dts: [String]) { let thunkBuilder = ExportedThunkBuilder(effects: function.effects) for param in function.parameters { - thunkBuilder.lowerParameter(param: param) + try thunkBuilder.lowerParameter(param: param) } - let returnExpr = thunkBuilder.call(abiName: function.abiName, returnType: function.returnType) + let returnExpr = try thunkBuilder.call(abiName: function.abiName, returnType: function.returnType) let funcLines = thunkBuilder.renderFunction( name: function.abiName, parameters: function.parameters, @@ -698,7 +640,9 @@ struct BridgeJSLink { return (funcLines, dtsLines) } - func renderExportedClass(_ klass: ExportedClass) -> (js: [String], dtsType: [String], dtsExportEntry: [String]) { + func renderExportedClass( + _ klass: ExportedClass + ) throws -> (js: [String], dtsType: [String], dtsExportEntry: [String]) { var jsLines: [String] = [] var dtsTypeLines: [String] = [] var dtsExportEntryLines: [String] = [] @@ -721,14 +665,14 @@ struct BridgeJSLink { if let constructor: ExportedConstructor = klass.constructor { let thunkBuilder = ExportedThunkBuilder(effects: constructor.effects) for param in constructor.parameters { - thunkBuilder.lowerParameter(param: param) + try thunkBuilder.lowerParameter(param: param) } var funcLines: [String] = [] funcLines.append("") funcLines.append("constructor(\(constructor.parameters.map { $0.name }.joined(separator: ", "))) {") let returnExpr = thunkBuilder.callConstructor(abiName: constructor.abiName) - funcLines.append(contentsOf: thunkBuilder.bodyLines.map { $0.indent(count: 4) }) - funcLines.append(contentsOf: thunkBuilder.cleanupLines.map { $0.indent(count: 4) }) + funcLines.append(contentsOf: thunkBuilder.body.lines.map { $0.indent(count: 4) }) + funcLines.append(contentsOf: thunkBuilder.cleanupCode.lines.map { $0.indent(count: 4) }) funcLines.append(contentsOf: thunkBuilder.checkExceptionLines().map { $0.indent(count: 4) }) funcLines.append("return \(klass.name).__construct(\(returnExpr));".indent(count: 4)) funcLines.append("}") @@ -744,9 +688,9 @@ struct BridgeJSLink { let thunkBuilder = ExportedThunkBuilder(effects: method.effects) thunkBuilder.lowerSelf() for param in method.parameters { - thunkBuilder.lowerParameter(param: param) + try thunkBuilder.lowerParameter(param: param) } - let returnExpr = thunkBuilder.call(abiName: method.abiName, returnType: method.returnType) + let returnExpr = try thunkBuilder.call(abiName: method.abiName, returnType: method.returnType) jsLines.append( contentsOf: thunkBuilder.renderFunction( name: method.name, @@ -766,7 +710,7 @@ struct BridgeJSLink { // Generate getter let getterThunkBuilder = ExportedThunkBuilder(effects: Effects(isAsync: false, isThrows: false)) getterThunkBuilder.lowerSelf() - let getterReturnExpr = getterThunkBuilder.call( + let getterReturnExpr = try getterThunkBuilder.call( abiName: property.getterAbiName(className: klass.name), returnType: property.type ) @@ -783,8 +727,10 @@ struct BridgeJSLink { if !property.isReadonly { let setterThunkBuilder = ExportedThunkBuilder(effects: Effects(isAsync: false, isThrows: false)) setterThunkBuilder.lowerSelf() - setterThunkBuilder.lowerParameter(param: Parameter(label: "value", name: "value", type: property.type)) - _ = setterThunkBuilder.call( + try setterThunkBuilder.lowerParameter( + param: Parameter(label: "value", name: "value", type: property.type) + ) + _ = try setterThunkBuilder.call( abiName: property.setterAbiName(className: klass.name), returnType: .void ) @@ -877,46 +823,38 @@ struct BridgeJSLink { } class ImportedThunkBuilder { - var bodyLines: [String] = [] + let body: CodeFragmentPrinter + let scope: JSGlueVariableScope + let cleanupCode: CodeFragmentPrinter var parameterNames: [String] = [] var parameterForwardings: [String] = [] + init() { + self.body = CodeFragmentPrinter() + self.scope = JSGlueVariableScope() + self.cleanupCode = CodeFragmentPrinter() + } + func liftSelf() { parameterNames.append("self") } - func liftParameter(param: Parameter) { - parameterNames.append(param.name) - switch param.type { - case .string: - let stringObjectName = "\(param.name)Object" - // TODO: Implement "take" operation - bodyLines.append("const \(stringObjectName) = swift.memory.getObject(\(param.name));") - bodyLines.append("swift.memory.release(\(param.name));") - parameterForwardings.append(stringObjectName) - case .caseEnum(_): - parameterForwardings.append(param.name) - case .rawValueEnum(_, let rawType): - switch rawType { - case .string: - let stringObjectName = "\(param.name)Object" - bodyLines.append("const \(stringObjectName) = swift.memory.getObject(\(param.name));") - bodyLines.append("swift.memory.release(\(param.name));") - parameterForwardings.append(stringObjectName) - case .bool: - parameterForwardings.append("\(param.name) !== 0") - default: - parameterForwardings.append(param.name) - } - case .associatedValueEnum: - parameterForwardings.append("\"\"") - case .namespaceEnum: - break - case .jsObject: - parameterForwardings.append("swift.memory.getObject(\(param.name))") - default: - parameterForwardings.append(param.name) + func liftParameter(param: Parameter) throws { + let liftingFragment = try IntrinsicJSFragment.liftParameter(type: param.type) + assert( + liftingFragment.parameters.count >= 1, + "Lifting fragment should have at least one parameter to lift" + ) + let valuesToLift: [String] + if liftingFragment.parameters.count == 1 { + parameterNames.append(param.name) + valuesToLift = [scope.variable(param.name)] + } else { + valuesToLift = liftingFragment.parameters.map { scope.variable(param.name + $0.capitalizedFirstLetter) } } + let liftedValues = liftingFragment.printCode(valuesToLift, scope, body, cleanupCode) + assert(liftedValues.count == 1, "Lifting fragment should produce exactly one value") + parameterForwardings.append(contentsOf: liftedValues) } func renderFunction( @@ -929,7 +867,7 @@ struct BridgeJSLink { "function \(name)(\(parameterNames.joined(separator: ", "))) {" ) funcLines.append("try {".indent(count: 4)) - funcLines.append(contentsOf: bodyLines.map { $0.indent(count: 8) }) + funcLines.append(contentsOf: body.lines.map { $0.indent(count: 8) }) if let returnExpr = returnExpr { funcLines.append("return \(returnExpr);".indent(count: 8)) } @@ -943,71 +881,69 @@ struct BridgeJSLink { return funcLines } - func call(name: String, returnType: BridgeType) { - let call = "imports.\(name)(\(parameterForwardings.joined(separator: ", ")))" - if returnType == .void { - bodyLines.append("\(call);") + func call(name: String, returnType: BridgeType) throws -> String? { + return try self.call(calleeExpr: "imports.\(name)", returnType: returnType) + } + + private func call(calleeExpr: String, returnType: BridgeType) throws -> String? { + let callExpr = "\(calleeExpr)(\(parameterForwardings.joined(separator: ", ")))" + return try self.call(callExpr: callExpr, returnType: returnType) + } + + private func call(callExpr: String, returnType: BridgeType) throws -> String? { + let loweringFragment = try IntrinsicJSFragment.lowerReturn(type: returnType) + let returnExpr: String? + if loweringFragment.parameters.count == 0 { + body.write("\(callExpr);") + returnExpr = nil } else { - bodyLines.append("let ret = \(call);") + let resultVariable = scope.variable("ret") + body.write("let \(resultVariable) = \(callExpr);") + returnExpr = resultVariable } + return try lowerReturnValue( + returnType: returnType, + returnExpr: returnExpr, + loweringFragment: loweringFragment + ) } - func callConstructor(name: String) { + func callConstructor(name: String) throws -> String? { let call = "new imports.\(name)(\(parameterForwardings.joined(separator: ", ")))" - bodyLines.append("let ret = \(call);") + let type: BridgeType = .jsObject(name) + let loweringFragment = try IntrinsicJSFragment.lowerReturn(type: type) + return try lowerReturnValue(returnType: type, returnExpr: call, loweringFragment: loweringFragment) } - func callMethod(name: String, returnType: BridgeType) { - let call = "swift.memory.getObject(self).\(name)(\(parameterForwardings.joined(separator: ", ")))" - if returnType == .void { - bodyLines.append("\(call);") - } else { - bodyLines.append("let ret = \(call);") - } + func callMethod(name: String, returnType: BridgeType) throws -> String? { + return try call( + calleeExpr: "\(JSGlueVariableScope.reservedSwift).memory.getObject(self).\(name)", + returnType: returnType + ) } - func callPropertyGetter(name: String, returnType: BridgeType) { - let call = "swift.memory.getObject(self).\(name)" - bodyLines.append("let ret = \(call);") + func callPropertyGetter(name: String, returnType: BridgeType) throws -> String? { + return try call( + callExpr: "\(JSGlueVariableScope.reservedSwift).memory.getObject(self).\(name)", + returnType: returnType + ) } func callPropertySetter(name: String, returnType: BridgeType) { - let call = "swift.memory.getObject(self).\(name) = \(parameterForwardings.joined(separator: ", "))" - bodyLines.append("\(call);") + let call = + "\(JSGlueVariableScope.reservedSwift).memory.getObject(self).\(name) = \(parameterForwardings.joined(separator: ", "))" + body.write("\(call);") } - func lowerReturnValue(returnType: BridgeType) throws -> String? { - switch returnType { - case .void: - return nil - case .string: - bodyLines.append("tmpRetBytes = textEncoder.encode(ret);") - return "tmpRetBytes.length" - case .caseEnum(_): - return "ret" - case .rawValueEnum(_, let rawType): - switch rawType { - case .string: - bodyLines.append("tmpRetBytes = textEncoder.encode(ret);") - return "tmpRetBytes.length" - case .bool: - return "ret ? 1 : 0" - default: - return "ret" - } - case .associatedValueEnum: - return nil - case .namespaceEnum: - return nil - case .int, .float, .double: - return "ret" - case .bool: - return "ret !== 0" - case .jsObject: - return "swift.memory.retain(ret)" - case .swiftHeapObject: - throw BridgeJSLinkError(message: "Swift heap object is not supported in imported functions") - } + private func lowerReturnValue( + returnType: BridgeType, + returnExpr: String?, + loweringFragment: IntrinsicJSFragment + ) throws -> String? { + assert(loweringFragment.parameters.count <= 1, "Lowering fragment should have at most one parameter") + let loweredValues = loweringFragment.printCode(returnExpr.map { [$0] } ?? [], scope, body, cleanupCode) + assert(loweredValues.count <= 1, "Lowering fragment should produce at most one value") + return loweredValues.first } } @@ -1385,10 +1321,9 @@ struct BridgeJSLink { ) throws { let thunkBuilder = ImportedThunkBuilder() for param in function.parameters { - thunkBuilder.liftParameter(param: param) + try thunkBuilder.liftParameter(param: param) } - thunkBuilder.call(name: function.name, returnType: function.returnType) - let returnExpr = try thunkBuilder.lowerReturnValue(returnType: function.returnType) + let returnExpr = try thunkBuilder.call(name: function.name, returnType: function.returnType) let funcLines = thunkBuilder.renderFunction( name: function.abiName(context: nil), returnExpr: returnExpr, @@ -1420,8 +1355,7 @@ struct BridgeJSLink { property: property, abiName: getterAbiName, emitCall: { thunkBuilder in - thunkBuilder.callPropertyGetter(name: property.name, returnType: property.type) - return try thunkBuilder.lowerReturnValue(returnType: property.type) + return try thunkBuilder.callPropertyGetter(name: property.name, returnType: property.type) } ) importObjectBuilder.assignToImportObject(name: getterAbiName, function: js) @@ -1433,7 +1367,7 @@ struct BridgeJSLink { property: property, abiName: setterAbiName, emitCall: { thunkBuilder in - thunkBuilder.liftParameter( + try thunkBuilder.liftParameter( param: Parameter(label: nil, name: "newValue", type: property.type) ) thunkBuilder.callPropertySetter(name: property.name, returnType: property.type) @@ -1458,11 +1392,10 @@ struct BridgeJSLink { ) throws { let thunkBuilder = ImportedThunkBuilder() for param in constructor.parameters { - thunkBuilder.liftParameter(param: param) + try thunkBuilder.liftParameter(param: param) } let returnType = BridgeType.jsObject(type.name) - thunkBuilder.callConstructor(name: type.name) - let returnExpr = try thunkBuilder.lowerReturnValue(returnType: returnType) + let returnExpr = try thunkBuilder.callConstructor(name: type.name) let abiName = constructor.abiName(context: type) let funcLines = thunkBuilder.renderFunction( name: abiName, @@ -1501,10 +1434,9 @@ struct BridgeJSLink { let thunkBuilder = ImportedThunkBuilder() thunkBuilder.liftSelf() for param in method.parameters { - thunkBuilder.liftParameter(param: param) + try thunkBuilder.liftParameter(param: param) } - thunkBuilder.callMethod(name: method.name, returnType: method.returnType) - let returnExpr = try thunkBuilder.lowerReturnValue(returnType: method.returnType) + let returnExpr = try thunkBuilder.callMethod(name: method.name, returnType: method.returnType) let funcLines = thunkBuilder.renderFunction( name: method.abiName(context: context), returnExpr: returnExpr, diff --git a/Plugins/BridgeJS/Sources/BridgeJSLink/CodeFragmentPrinter.swift b/Plugins/BridgeJS/Sources/BridgeJSLink/CodeFragmentPrinter.swift new file mode 100644 index 00000000..c4624e69 --- /dev/null +++ b/Plugins/BridgeJS/Sources/BridgeJSLink/CodeFragmentPrinter.swift @@ -0,0 +1,41 @@ +/// A printer for code fragments. +final class CodeFragmentPrinter { + private(set) var lines: [String] = [] + private var indentLevel: Int = 0 + + init(header: String = "") { + self.lines.append(contentsOf: header.split(separator: "\n").map { String($0) }) + } + + func nextLine() { + lines.append("") + } + + func write(_ line: S) { + lines.append(String(repeating: " ", count: indentLevel * 4) + String(line)) + } + + func write(lines: [String]) { + for line in lines { + write(line) + } + } + + func write(contentsOf printer: CodeFragmentPrinter) { + self.write(lines: printer.lines) + } + + func indent() { + indentLevel += 1 + } + + func unindent() { + indentLevel -= 1 + } + + func indent(_ body: () throws -> Void) rethrows { + indentLevel += 1 + try body() + indentLevel -= 1 + } +} diff --git a/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift b/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift new file mode 100644 index 00000000..ae74844f --- /dev/null +++ b/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift @@ -0,0 +1,317 @@ +#if canImport(BridgeJSSkeleton) +import BridgeJSSkeleton +#endif + +/// A scope for variables for JS glue code +final class JSGlueVariableScope { + // MARK: - Reserved variables + + static let reservedSwift = "swift" + static let reservedInstance = "instance" + static let reservedMemory = "memory" + static let reservedSetException = "setException" + static let reservedStorageToReturnString = "tmpRetString" + static let reservedStorageToReturnBytes = "tmpRetBytes" + static let reservedStorageToReturnException = "tmpRetException" + static let reservedTextEncoder = "textEncoder" + static let reservedTextDecoder = "textDecoder" + + private var variables: Set = [ + reservedSwift, + reservedMemory, + reservedStorageToReturnString, + reservedStorageToReturnBytes, + reservedStorageToReturnException, + reservedTextEncoder, + reservedTextDecoder, + ] + + /// Returns a unique variable name in the scope based on the given name hint. + /// + /// - Parameter hint: A hint for the variable name. + /// - Returns: A unique variable name. + func variable(_ hint: String) -> String { + if variables.insert(hint).inserted { + return hint + } + var suffixedName: String + var suffix = 1 + repeat { + suffixedName = hint + suffix.description + suffix += 1 + } while !variables.insert(suffixedName).inserted + return suffixedName + } +} + +/// A fragment of JS code used to convert a value between Swift and JS. +/// +/// See `BridgeJSInstrincics.swift` in the main JavaScriptKit module for Swift side lowering/lifting implementation. +struct IntrinsicJSFragment: Sendable { + /// The names of the parameters that the fragment expects. + let parameters: [String] + + /// Prints the fragment code. + /// + /// - Parameters: + /// - arguments: The arguments that the fragment expects. An argument may be an expression with side effects, + /// so the callee is responsible for evaluating the arguments only once. + /// - scope: The scope of the variables. + /// - printer: The printer to print the main fragment code. + /// - cleanupCode: The printer to print the code that is expected to be executed at the end of the caller of the + /// fragment. + /// - Returns: List of result expressions. + let printCode: + @Sendable ( + _ arguments: [String], + _ scope: JSGlueVariableScope, + _ printer: CodeFragmentPrinter, + _ cleanupCode: CodeFragmentPrinter + ) -> [String] + + /// A fragment that does nothing + static let void = IntrinsicJSFragment( + parameters: [], + printCode: { _, _, _, _ in + return [] + } + ) + + /// A fragment that returns the argument as is. + static let identity = IntrinsicJSFragment( + parameters: ["value"], + printCode: { arguments, scope, printer, cleanupCode in + return [arguments[0]] + } + ) + + /// NOTE: JavaScript engine itself converts booleans to integers when passing them to + /// Wasm functions, so we don't need to do anything here + static let boolLowerParameter = identity + static let boolLiftReturn = IntrinsicJSFragment( + parameters: ["value"], + printCode: { arguments, scope, printer, cleanupCode in + return ["\(arguments[0]) !== 0"] + } + ) + static let boolLiftParameter = IntrinsicJSFragment( + parameters: ["value"], + printCode: { arguments, scope, printer, cleanupCode in + return ["\(arguments[0]) !== 0"] + } + ) + static let boolLowerReturn = IntrinsicJSFragment( + parameters: ["value"], + printCode: { arguments, scope, printer, cleanupCode in + return ["\(arguments[0]) ? 1 : 0"] + } + ) + + static let stringLowerParameter = IntrinsicJSFragment( + parameters: ["value"], + printCode: { arguments, scope, printer, cleanupCode in + let argument = arguments[0] + let bytesLabel = scope.variable("\(argument)Bytes") + let bytesIdLabel = scope.variable("\(argument)Id") + printer.write("const \(bytesLabel) = \(JSGlueVariableScope.reservedTextEncoder).encode(\(argument));") + printer.write("const \(bytesIdLabel) = \(JSGlueVariableScope.reservedSwift).memory.retain(\(bytesLabel));") + cleanupCode.write("\(JSGlueVariableScope.reservedSwift).memory.release(\(bytesIdLabel));") + return [bytesIdLabel, "\(bytesLabel).length"] + } + ) + static let stringLiftReturn = IntrinsicJSFragment( + parameters: [], + printCode: { arguments, scope, printer, cleanupCode in + let resultLabel = scope.variable("ret") + printer.write("const \(resultLabel) = \(JSGlueVariableScope.reservedStorageToReturnString);") + printer.write("\(JSGlueVariableScope.reservedStorageToReturnString) = undefined;") + return [resultLabel] + } + ) + static let stringLiftParameter = IntrinsicJSFragment( + parameters: ["objectId"], + printCode: { arguments, scope, printer, cleanupCode in + let objectId = arguments[0] + let objectLabel = scope.variable("\(objectId)Object") + // TODO: Implement "take" operation + printer.write("const \(objectLabel) = \(JSGlueVariableScope.reservedSwift).memory.getObject(\(objectId));") + printer.write("\(JSGlueVariableScope.reservedSwift).memory.release(\(objectId));") + return [objectLabel] + } + ) + static let stringLowerReturn = IntrinsicJSFragment( + parameters: ["value"], + printCode: { arguments, scope, printer, cleanupCode in + printer.write( + "\(JSGlueVariableScope.reservedStorageToReturnBytes) = \(JSGlueVariableScope.reservedTextEncoder).encode(\(arguments[0]));" + ) + return ["\(JSGlueVariableScope.reservedStorageToReturnBytes).length"] + } + ) + + static let jsObjectLowerParameter = IntrinsicJSFragment( + parameters: ["value"], + printCode: { arguments, scope, printer, cleanupCode in + return ["swift.memory.retain(\(arguments[0]))"] + } + ) + static let jsObjectLiftReturn = IntrinsicJSFragment( + parameters: ["retId"], + printCode: { arguments, scope, printer, cleanupCode in + // TODO: Implement "take" operation + let resultLabel = scope.variable("ret") + let retId = arguments[0] + printer.write("const \(resultLabel) = \(JSGlueVariableScope.reservedSwift).memory.getObject(\(retId));") + printer.write("\(JSGlueVariableScope.reservedSwift).memory.release(\(retId));") + return [resultLabel] + } + ) + static let jsObjectLiftParameter = IntrinsicJSFragment( + parameters: ["objectId"], + printCode: { arguments, scope, printer, cleanupCode in + return ["\(JSGlueVariableScope.reservedSwift).memory.getObject(\(arguments[0]))"] + } + ) + static let jsObjectLowerReturn = IntrinsicJSFragment( + parameters: ["value"], + printCode: { arguments, scope, printer, cleanupCode in + return ["\(JSGlueVariableScope.reservedSwift).memory.retain(\(arguments[0]))"] + } + ) + + static let swiftHeapObjectLowerParameter = IntrinsicJSFragment( + parameters: ["value"], + printCode: { arguments, scope, printer, cleanupCode in + return ["\(arguments[0]).pointer"] + } + ) + static func swiftHeapObjectLiftReturn(_ name: String) -> IntrinsicJSFragment { + return IntrinsicJSFragment( + parameters: ["value"], + printCode: { arguments, scope, printer, cleanupCode in + return ["\(name).__construct(\(arguments[0]))"] + } + ) + } + + // MARK: - ExportSwift + + /// 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: return .identity + case .string: return .stringLowerParameter + case .jsObject: return .jsObjectLowerParameter + case .swiftHeapObject: + return .swiftHeapObjectLowerParameter + case .void: return .void + case .caseEnum: return .identity + case .rawValueEnum(_, let rawType): + switch rawType { + case .string: return .stringLowerParameter + default: return .identity + } + case .associatedValueEnum(let string): + throw BridgeJSLinkError( + message: "Associated value enums are not supported to be passed as parameters: \(string)" + ) + case .namespaceEnum(let string): + throw BridgeJSLinkError(message: "Namespace enums are not supported to be passed as parameters: \(string)") + } + } + + /// Returns a fragment that lifts a Wasm core value to a JS value for return values + static func liftReturn(type: BridgeType) throws -> IntrinsicJSFragment { + switch type { + case .int, .float, .double: return .identity + case .bool: return .boolLiftReturn + case .string: return .stringLiftReturn + case .jsObject: return .jsObjectLiftReturn + case .swiftHeapObject(let name): return .swiftHeapObjectLiftReturn(name) + case .void: return .void + case .caseEnum: return .identity + case .rawValueEnum(_, let rawType): + switch rawType { + case .string: return .stringLiftReturn + case .bool: return .boolLiftReturn + default: return .identity + } + case .associatedValueEnum(let string): + throw BridgeJSLinkError( + message: "Associated value enums are not supported to be returned from functions: \(string)" + ) + case .namespaceEnum(let string): + throw BridgeJSLinkError( + message: "Namespace enums are not supported to be returned from functions: \(string)" + ) + } + } + + // MARK: - ImportedJS + + /// Returns a fragment that lifts Wasm core values to JS values for parameters + static func liftParameter(type: BridgeType) throws -> IntrinsicJSFragment { + switch type { + case .int, .float, .double: return .identity + case .bool: return .boolLiftParameter + case .string: return .stringLiftParameter + case .jsObject: return .jsObjectLiftParameter + case .swiftHeapObject(let name): + throw BridgeJSLinkError( + message: + "Swift heap objects are not supported to be passed as parameters to imported JS functions: \(name)" + ) + case .void: + throw BridgeJSLinkError( + message: "Void can't appear in parameters of imported JS functions" + ) + case .caseEnum: return .identity + case .rawValueEnum(_, let rawType): + switch rawType { + case .string: return .stringLiftParameter + case .bool: return .boolLiftParameter + default: return .identity + } + case .associatedValueEnum(let string): + throw BridgeJSLinkError( + message: + "Associated value enums are not supported to be passed as parameters to imported JS functions: \(string)" + ) + case .namespaceEnum(let string): + throw BridgeJSLinkError( + message: + "Namespace enums are not supported to be passed as parameters to imported JS functions: \(string)" + ) + } + } + + /// Returns a fragment that lowers a JS value to Wasm core values for return values + static func lowerReturn(type: BridgeType) throws -> IntrinsicJSFragment { + switch type { + case .int, .float, .double: return .identity + case .bool: return .boolLowerReturn + case .string: return .stringLowerReturn + case .jsObject: return .jsObjectLowerReturn + case .swiftHeapObject: + throw BridgeJSLinkError( + message: "Swift heap objects are not supported to be returned from imported JS functions" + ) + case .void: return .void + case .caseEnum: return .identity + case .rawValueEnum(_, let rawType): + switch rawType { + case .string: return .stringLowerReturn + case .bool: return .boolLowerReturn + default: return .identity + } + case .associatedValueEnum(let string): + throw BridgeJSLinkError( + message: "Associated value enums are not supported to be returned from imported JS functions: \(string)" + ) + case .namespaceEnum(let string): + throw BridgeJSLinkError( + message: "Namespace enums are not supported to be returned from imported JS functions: \(string)" + ) + } + } +} diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Export.js index 1da2f58e..97c1e215 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Export.js @@ -65,49 +65,49 @@ export async function createInstantiator(options, swift) { return { asyncReturnVoid: function bjs_asyncReturnVoid() { - const retId = instance.exports.bjs_asyncReturnVoid(); - const ret = swift.memory.getObject(retId); - swift.memory.release(retId); - return ret; + const ret = instance.exports.bjs_asyncReturnVoid(); + const ret1 = swift.memory.getObject(ret); + swift.memory.release(ret); + return ret1; }, asyncRoundTripInt: function bjs_asyncRoundTripInt(v) { - const retId = instance.exports.bjs_asyncRoundTripInt(v); - const ret = swift.memory.getObject(retId); - swift.memory.release(retId); - return ret; + const ret = instance.exports.bjs_asyncRoundTripInt(v); + const ret1 = swift.memory.getObject(ret); + swift.memory.release(ret); + return ret1; }, asyncRoundTripString: function bjs_asyncRoundTripString(v) { const vBytes = textEncoder.encode(v); const vId = swift.memory.retain(vBytes); - const retId = instance.exports.bjs_asyncRoundTripString(vId, vBytes.length); - const ret = swift.memory.getObject(retId); - swift.memory.release(retId); + const ret = instance.exports.bjs_asyncRoundTripString(vId, vBytes.length); + const ret1 = swift.memory.getObject(ret); + swift.memory.release(ret); swift.memory.release(vId); - return ret; + return ret1; }, asyncRoundTripBool: function bjs_asyncRoundTripBool(v) { - const retId = instance.exports.bjs_asyncRoundTripBool(v); - const ret = swift.memory.getObject(retId); - swift.memory.release(retId); - return ret; + const ret = instance.exports.bjs_asyncRoundTripBool(v); + const ret1 = swift.memory.getObject(ret); + swift.memory.release(ret); + return ret1; }, asyncRoundTripFloat: function bjs_asyncRoundTripFloat(v) { - const retId = instance.exports.bjs_asyncRoundTripFloat(v); - const ret = swift.memory.getObject(retId); - swift.memory.release(retId); - return ret; + const ret = instance.exports.bjs_asyncRoundTripFloat(v); + const ret1 = swift.memory.getObject(ret); + swift.memory.release(ret); + return ret1; }, asyncRoundTripDouble: function bjs_asyncRoundTripDouble(v) { - const retId = instance.exports.bjs_asyncRoundTripDouble(v); - const ret = swift.memory.getObject(retId); - swift.memory.release(retId); - return ret; + const ret = instance.exports.bjs_asyncRoundTripDouble(v); + const ret1 = swift.memory.getObject(ret); + swift.memory.release(ret); + return ret1; }, asyncRoundTripJSObject: function bjs_asyncRoundTripJSObject(v) { - const retId = instance.exports.bjs_asyncRoundTripJSObject(swift.memory.retain(v)); - const ret = swift.memory.getObject(retId); - swift.memory.release(retId); - return ret; + const ret = instance.exports.bjs_asyncRoundTripJSObject(swift.memory.retain(v)); + const ret1 = swift.memory.getObject(ret); + swift.memory.release(ret); + return ret1; }, }; }, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Import.js index 21d11fa4..0b07aedd 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Import.js @@ -82,7 +82,7 @@ export async function createInstantiator(options, swift) { } TestModule["bjs_asyncRoundTripBool"] = function bjs_asyncRoundTripBool(v) { try { - let ret = imports.asyncRoundTripBool(v); + let ret = imports.asyncRoundTripBool(v !== 0); return swift.memory.retain(ret); } catch (error) { setException(error); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.Export.js index 3e080948..42a98f62 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.Export.js @@ -86,18 +86,18 @@ export async function createInstantiator(options, swift) { return { setDirection: function bjs_setDirection(direction) { - instance.exports.bjs_setDirection(direction | 0); + instance.exports.bjs_setDirection(direction); }, getDirection: function bjs_getDirection() { const ret = instance.exports.bjs_getDirection(); return ret; }, processDirection: function bjs_processDirection(input) { - const ret = instance.exports.bjs_processDirection(input | 0); + const ret = instance.exports.bjs_processDirection(input); return ret; }, setTSDirection: function bjs_setTSDirection(direction) { - instance.exports.bjs_setTSDirection(direction | 0); + instance.exports.bjs_setTSDirection(direction); }, getTSDirection: function bjs_getTSDirection() { const ret = instance.exports.bjs_getTSDirection(); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.js index 12613dd8..677e02c9 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.js @@ -171,7 +171,7 @@ export async function createInstantiator(options, swift) { return HTTPServer.__construct(ret); } call(method) { - instance.exports.bjs_HTTPServer_call(this.pointer, method | 0); + instance.exports.bjs_HTTPServer_call(this.pointer, method); } } class TestServer extends SwiftHeapObject { @@ -185,7 +185,7 @@ export async function createInstantiator(options, swift) { return TestServer.__construct(ret); } call(method) { - instance.exports.bjs_TestServer_call(this.pointer, method | 0); + instance.exports.bjs_TestServer_call(this.pointer, method); } } const exports = { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.Export.js index 68a2b19f..2be034b4 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.Export.js @@ -165,7 +165,7 @@ export async function createInstantiator(options, swift) { return ret; }, setFeatureFlag: function bjs_setFeatureFlag(flag) { - instance.exports.bjs_setFeatureFlag(flag ? 1 : 0); + instance.exports.bjs_setFeatureFlag(flag); }, getFeatureFlag: function bjs_getFeatureFlag() { const ret = instance.exports.bjs_getFeatureFlag(); @@ -235,7 +235,7 @@ export async function createInstantiator(options, swift) { return ret; }, setFeatureFlag: function bjs_setFeatureFlag(featureFlag) { - instance.exports.bjs_setFeatureFlag(featureFlag ? 1 : 0); + instance.exports.bjs_setFeatureFlag(featureFlag); }, getFeatureFlag: function bjs_getFeatureFlag() { const ret = instance.exports.bjs_getFeatureFlag(); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MultipleImportedTypes.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MultipleImportedTypes.Import.js index 394d996b..d9a13b5e 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MultipleImportedTypes.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MultipleImportedTypes.Import.js @@ -83,7 +83,7 @@ export async function createInstantiator(options, swift) { TestModule["bjs_DatabaseConnection_isConnected_get"] = function bjs_DatabaseConnection_isConnected_get(self) { try { let ret = swift.memory.getObject(self).isConnected; - return ret !== 0; + return ret ? 1 : 0; } catch (error) { setException(error); return 0 diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Import.js index 3b93b2dd..b0dbaa19 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Import.js @@ -53,7 +53,7 @@ export async function createInstantiator(options, swift) { const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_check"] = function bjs_check(a, b) { try { - imports.check(a, b); + imports.check(a, b !== 0); } catch (error) { setException(error); } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Export.js index 53332b97..594dc9d5 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Export.js @@ -77,8 +77,8 @@ export async function createInstantiator(options, swift) { return ret; }, checkBool: function bjs_checkBool() { - const ret = instance.exports.bjs_checkBool() !== 0; - return ret; + const ret = instance.exports.bjs_checkBool(); + return ret !== 0; }, }; }, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Import.js index 1892eb46..a61149cd 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Import.js @@ -63,7 +63,7 @@ export async function createInstantiator(options, swift) { TestModule["bjs_checkBoolean"] = function bjs_checkBoolean() { try { let ret = imports.checkBoolean(); - return ret !== 0; + return ret ? 1 : 0; } catch (error) { setException(error); return 0 diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PropertyTypes.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PropertyTypes.Export.js index ae72be66..ffc1eab6 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PropertyTypes.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PropertyTypes.Export.js @@ -129,8 +129,8 @@ export async function createInstantiator(options, swift) { instance.exports.bjs_PropertyHolder_doubleValue_set(this.pointer, value); } get boolValue() { - const ret = instance.exports.bjs_PropertyHolder_boolValue_get(this.pointer) !== 0; - return ret; + const ret = instance.exports.bjs_PropertyHolder_boolValue_get(this.pointer); + return ret !== 0; } set boolValue(value) { instance.exports.bjs_PropertyHolder_boolValue_set(this.pointer, value); @@ -160,8 +160,8 @@ export async function createInstantiator(options, swift) { return ret; } get readonlyBool() { - const ret = instance.exports.bjs_PropertyHolder_readonlyBool_get(this.pointer) !== 0; - return ret; + const ret = instance.exports.bjs_PropertyHolder_readonlyBool_get(this.pointer); + return ret !== 0; } get readonlyString() { instance.exports.bjs_PropertyHolder_readonlyString_get(this.pointer); @@ -170,17 +170,17 @@ export async function createInstantiator(options, swift) { return ret; } get jsObject() { - const retId = instance.exports.bjs_PropertyHolder_jsObject_get(this.pointer); - const ret = swift.memory.getObject(retId); - swift.memory.release(retId); - return ret; + const ret = instance.exports.bjs_PropertyHolder_jsObject_get(this.pointer); + const ret1 = swift.memory.getObject(ret); + swift.memory.release(ret); + return ret1; } set jsObject(value) { instance.exports.bjs_PropertyHolder_jsObject_set(this.pointer, swift.memory.retain(value)); } get sibling() { - const ret = PropertyHolder.__construct(instance.exports.bjs_PropertyHolder_sibling_get(this.pointer)); - return ret; + const ret = instance.exports.bjs_PropertyHolder_sibling_get(this.pointer); + return PropertyHolder.__construct(ret); } set sibling(value) { instance.exports.bjs_PropertyHolder_sibling_set(this.pointer, value.pointer); @@ -226,9 +226,9 @@ export async function createInstantiator(options, swift) { createPropertyHolder: function bjs_createPropertyHolder(intValue, floatValue, doubleValue, boolValue, stringValue, jsObject) { const stringValueBytes = textEncoder.encode(stringValue); const stringValueId = swift.memory.retain(stringValueBytes); - const ret = PropertyHolder.__construct(instance.exports.bjs_createPropertyHolder(intValue, floatValue, doubleValue, boolValue, stringValueId, stringValueBytes.length, swift.memory.retain(jsObject))); + const ret = instance.exports.bjs_createPropertyHolder(intValue, floatValue, doubleValue, boolValue, stringValueId, stringValueBytes.length, swift.memory.retain(jsObject)); swift.memory.release(stringValueId); - return ret; + return PropertyHolder.__construct(ret); }, testPropertyHolder: function bjs_testPropertyHolder(holder) { instance.exports.bjs_testPropertyHolder(holder.pointer); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TS2SkeletonLike.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TS2SkeletonLike.Import.js index 705c6a37..c7671805 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TS2SkeletonLike.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TS2SkeletonLike.Import.js @@ -96,7 +96,7 @@ export async function createInstantiator(options, swift) { const tsObject = swift.memory.getObject(ts); swift.memory.release(ts); let ret = swift.memory.getObject(self).validate(tsObject); - return ret !== 0; + return ret ? 1 : 0; } catch (error) { setException(error); return 0 diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeScriptClass.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeScriptClass.Import.js index c7d622ea..48d15c7e 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeScriptClass.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeScriptClass.Import.js @@ -55,8 +55,7 @@ export async function createInstantiator(options, swift) { try { const nameObject = swift.memory.getObject(name); swift.memory.release(name); - let ret = new imports.Greeter(nameObject); - return swift.memory.retain(ret); + return swift.memory.retain(new imports.Greeter(nameObject)); } catch (error) { setException(error); return 0 diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Async.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Async.swift index 10a3a24d..fe31c9f1 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Async.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Async.swift @@ -13,7 +13,7 @@ public func _bjs_asyncReturnVoid() -> Int32 { let ret = JSPromise.async { await asyncReturnVoid() } .jsObject - return _swift_js_retain(Int32(bitPattern: ret.id)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -24,9 +24,9 @@ public func _bjs_asyncReturnVoid() -> Int32 { public func _bjs_asyncRoundTripInt(v: Int32) -> Int32 { #if arch(wasm32) let ret = JSPromise.async { - return await asyncRoundTripInt(_: Int(v)).jsValue + return await asyncRoundTripInt(_: Int.bridgeJSLiftParameter(v)).jsValue } .jsObject - return _swift_js_retain(Int32(bitPattern: ret.id)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -37,13 +37,9 @@ public func _bjs_asyncRoundTripInt(v: Int32) -> Int32 { public func _bjs_asyncRoundTripString(vBytes: Int32, vLen: Int32) -> Int32 { #if arch(wasm32) let ret = JSPromise.async { - let v = String(unsafeUninitializedCapacity: Int(vLen)) { b in - _swift_js_init_memory(vBytes, b.baseAddress.unsafelyUnwrapped) - return Int(vLen) - } - return await asyncRoundTripString(_: v).jsValue + return await asyncRoundTripString(_: String.bridgeJSLiftParameter(vBytes, vLen)).jsValue } .jsObject - return _swift_js_retain(Int32(bitPattern: ret.id)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -54,9 +50,9 @@ public func _bjs_asyncRoundTripString(vBytes: Int32, vLen: Int32) -> Int32 { public func _bjs_asyncRoundTripBool(v: Int32) -> Int32 { #if arch(wasm32) let ret = JSPromise.async { - return await asyncRoundTripBool(_: v == 1).jsValue + return await asyncRoundTripBool(_: Bool.bridgeJSLiftParameter(v)).jsValue } .jsObject - return _swift_js_retain(Int32(bitPattern: ret.id)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -69,7 +65,7 @@ public func _bjs_asyncRoundTripFloat(v: Float32) -> Int32 { let ret = JSPromise.async { return await asyncRoundTripFloat(_: v).jsValue } .jsObject - return _swift_js_retain(Int32(bitPattern: ret.id)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -82,7 +78,7 @@ public func _bjs_asyncRoundTripDouble(v: Float64) -> Int32 { let ret = JSPromise.async { return await asyncRoundTripDouble(_: v).jsValue } .jsObject - return _swift_js_retain(Int32(bitPattern: ret.id)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -93,9 +89,9 @@ public func _bjs_asyncRoundTripDouble(v: Float64) -> Int32 { public func _bjs_asyncRoundTripJSObject(v: Int32) -> Int32 { #if arch(wasm32) let ret = JSPromise.async { - return await asyncRoundTripJSObject(_: JSObject(id: UInt32(bitPattern: v))).jsValue + return await asyncRoundTripJSObject(_: JSObject.bridgeJSLiftParameter(v)).jsValue } .jsObject - return _swift_js_retain(Int32(bitPattern: ret.id)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.swift index 9517ad80..e2a6588a 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.swift @@ -73,10 +73,8 @@ public func _bjs_Converter_init() -> UnsafeMutableRawPointer { @_cdecl("bjs_Converter_toString") public func _bjs_Converter_toString(_self: UnsafeMutableRawPointer, value: Int32) -> Void { #if arch(wasm32) - var ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().toString(value: Int(value)) - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().toString(value: Int.bridgeJSLiftParameter(value)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumRawType.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumRawType.swift index 991b5c6c..9f8f2ec3 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumRawType.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumRawType.swift @@ -10,11 +10,7 @@ @_cdecl("bjs_setTheme") public func _bjs_setTheme(themeBytes: Int32, themeLen: Int32) -> Void { #if arch(wasm32) - let theme = String(unsafeUninitializedCapacity: Int(themeLen)) { b in - _swift_js_init_memory(themeBytes, b.baseAddress.unsafelyUnwrapped) - return Int(themeLen) - } - setTheme(_: Theme(rawValue: theme)!) + setTheme(_: Theme(rawValue: String.bridgeJSLiftParameter(themeBytes, themeLen))!) #else fatalError("Only available on WebAssembly") #endif @@ -25,10 +21,7 @@ public func _bjs_setTheme(themeBytes: Int32, themeLen: Int32) -> Void { public func _bjs_getTheme() -> Void { #if arch(wasm32) let ret = getTheme() - var rawValue = ret.rawValue - return rawValue.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + return ret.rawValue.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -38,11 +31,7 @@ public func _bjs_getTheme() -> Void { @_cdecl("bjs_setTSTheme") public func _bjs_setTSTheme(themeBytes: Int32, themeLen: Int32) -> Void { #if arch(wasm32) - let theme = String(unsafeUninitializedCapacity: Int(themeLen)) { b in - _swift_js_init_memory(themeBytes, b.baseAddress.unsafelyUnwrapped) - return Int(themeLen) - } - setTSTheme(_: TSTheme(rawValue: theme)!) + setTSTheme(_: TSTheme(rawValue: String.bridgeJSLiftParameter(themeBytes, themeLen))!) #else fatalError("Only available on WebAssembly") #endif @@ -53,10 +42,7 @@ public func _bjs_setTSTheme(themeBytes: Int32, themeLen: Int32) -> Void { public func _bjs_getTSTheme() -> Void { #if arch(wasm32) let ret = getTSTheme() - var rawValue = ret.rawValue - return rawValue.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + return ret.rawValue.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -66,7 +52,7 @@ public func _bjs_getTSTheme() -> Void { @_cdecl("bjs_setFeatureFlag") public func _bjs_setFeatureFlag(flag: Int32) -> Void { #if arch(wasm32) - setFeatureFlag(_: FeatureFlag(rawValue: flag != 0)!) + setFeatureFlag(_: FeatureFlag(rawValue: FeatureFlag.bridgeJSLiftParameter(flag))) #else fatalError("Only available on WebAssembly") #endif @@ -276,7 +262,7 @@ public func _bjs_getRatio() -> Float64 { @_cdecl("bjs_setFeatureFlag") public func _bjs_setFeatureFlag(featureFlag: Int32) -> Void { #if arch(wasm32) - setFeatureFlag(_: FeatureFlag(rawValue: featureFlag != 0)!) + setFeatureFlag(_: FeatureFlag(rawValue: FeatureFlag.bridgeJSLiftParameter(featureFlag))) #else fatalError("Only available on WebAssembly") #endif @@ -297,11 +283,7 @@ public func _bjs_getFeatureFlag() -> Int32 { @_cdecl("bjs_processTheme") public func _bjs_processTheme(themeBytes: Int32, themeLen: Int32) -> Int32 { #if arch(wasm32) - let theme = String(unsafeUninitializedCapacity: Int(themeLen)) { b in - _swift_js_init_memory(themeBytes, b.baseAddress.unsafelyUnwrapped) - return Int(themeLen) - } - let ret = processTheme(_: Theme(rawValue: theme)!) + let ret = processTheme(_: Theme(rawValue: String.bridgeJSLiftParameter(themeBytes, themeLen))!) return Int32(ret.rawValue) #else fatalError("Only available on WebAssembly") @@ -324,10 +306,7 @@ public func _bjs_convertPriority(status: Int32) -> Int32 { public func _bjs_validateSession(session: Int64) -> Void { #if arch(wasm32) let ret = validateSession(_: SessionId(rawValue: UInt64(bitPattern: Int64(session)))!) - var rawValue = ret.rawValue - return rawValue.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + return ret.rawValue.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Namespaces.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Namespaces.swift index 21937c6c..e0128c5d 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Namespaces.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Namespaces.swift @@ -10,10 +10,8 @@ @_cdecl("bjs_plainFunction") public func _bjs_plainFunction() -> Void { #if arch(wasm32) - var ret = plainFunction() - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = plainFunction() + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -23,10 +21,8 @@ public func _bjs_plainFunction() -> Void { @_cdecl("bjs_namespacedFunction") public func _bjs_namespacedFunction() -> Void { #if arch(wasm32) - var ret = namespacedFunction() - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = namespacedFunction() + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -36,11 +32,7 @@ public func _bjs_namespacedFunction() -> Void { @_cdecl("bjs_Greeter_init") public func _bjs_Greeter_init(nameBytes: Int32, nameLen: Int32) -> UnsafeMutableRawPointer { #if arch(wasm32) - let name = String(unsafeUninitializedCapacity: Int(nameLen)) { b in - _swift_js_init_memory(nameBytes, b.baseAddress.unsafelyUnwrapped) - return Int(nameLen) - } - let ret = Greeter(name: name) + let ret = Greeter(name: String.bridgeJSLiftParameter(nameBytes, nameLen)) return Unmanaged.passRetained(ret).toOpaque() #else fatalError("Only available on WebAssembly") @@ -51,10 +43,8 @@ public func _bjs_Greeter_init(nameBytes: Int32, nameLen: Int32) -> UnsafeMutable @_cdecl("bjs_Greeter_greet") public func _bjs_Greeter_greet(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - var ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().greet() - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().greet() + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -89,10 +79,8 @@ public func _bjs_Converter_init() -> UnsafeMutableRawPointer { @_cdecl("bjs_Converter_toString") public func _bjs_Converter_toString(_self: UnsafeMutableRawPointer, value: Int32) -> Void { #if arch(wasm32) - var ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().toString(value: Int(value)) - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().toString(value: Int.bridgeJSLiftParameter(value)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -116,10 +104,8 @@ extension Converter: ConvertibleToJSValue { @_cdecl("bjs_UUID_uuidString") public func _bjs_UUID_uuidString(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - var ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().uuidString() - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().uuidString() + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveParameters.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveParameters.swift index c686c426..8f2e54c3 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveParameters.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveParameters.swift @@ -10,7 +10,7 @@ @_cdecl("bjs_check") public func _bjs_check(a: Int32, b: Float32, c: Float64, d: Int32) -> Void { #if arch(wasm32) - check(a: Int(a), b: b, c: c, d: d == 1) + check(a: Int.bridgeJSLiftParameter(a), b: b, c: c, d: Bool.bridgeJSLiftParameter(d)) #else fatalError("Only available on WebAssembly") #endif diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveReturn.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveReturn.swift index 7356f2c8..cc31d23e 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveReturn.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveReturn.swift @@ -44,7 +44,7 @@ public func _bjs_checkDouble() -> Float64 { public func _bjs_checkBool() -> Int32 { #if arch(wasm32) let ret = checkBool() - return Int32(ret ? 1 : 0) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PropertyTypes.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PropertyTypes.swift index 84609c74..74d3a58d 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PropertyTypes.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PropertyTypes.swift @@ -10,11 +10,7 @@ @_cdecl("bjs_createPropertyHolder") public func _bjs_createPropertyHolder(intValue: Int32, floatValue: Float32, doubleValue: Float64, boolValue: Int32, stringValueBytes: Int32, stringValueLen: Int32, jsObject: Int32) -> UnsafeMutableRawPointer { #if arch(wasm32) - let stringValue = String(unsafeUninitializedCapacity: Int(stringValueLen)) { b in - _swift_js_init_memory(stringValueBytes, b.baseAddress.unsafelyUnwrapped) - return Int(stringValueLen) - } - let ret = createPropertyHolder(intValue: Int(intValue), floatValue: floatValue, doubleValue: doubleValue, boolValue: boolValue == 1, stringValue: stringValue, jsObject: JSObject(id: UInt32(bitPattern: jsObject))) + let ret = createPropertyHolder(intValue: Int.bridgeJSLiftParameter(intValue), floatValue: floatValue, doubleValue: doubleValue, boolValue: Bool.bridgeJSLiftParameter(boolValue), stringValue: String.bridgeJSLiftParameter(stringValueBytes, stringValueLen), jsObject: JSObject.bridgeJSLiftParameter(jsObject)) return Unmanaged.passRetained(ret).toOpaque() #else fatalError("Only available on WebAssembly") @@ -25,10 +21,8 @@ public func _bjs_createPropertyHolder(intValue: Int32, floatValue: Float32, doub @_cdecl("bjs_testPropertyHolder") public func _bjs_testPropertyHolder(holder: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - var ret = testPropertyHolder(holder: Unmanaged.fromOpaque(holder).takeUnretainedValue()) - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = testPropertyHolder(holder: Unmanaged.fromOpaque(holder).takeUnretainedValue()) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -38,11 +32,7 @@ public func _bjs_testPropertyHolder(holder: UnsafeMutableRawPointer) -> Void { @_cdecl("bjs_PropertyHolder_init") public func _bjs_PropertyHolder_init(intValue: Int32, floatValue: Float32, doubleValue: Float64, boolValue: Int32, stringValueBytes: Int32, stringValueLen: Int32, jsObject: Int32) -> UnsafeMutableRawPointer { #if arch(wasm32) - let stringValue = String(unsafeUninitializedCapacity: Int(stringValueLen)) { b in - _swift_js_init_memory(stringValueBytes, b.baseAddress.unsafelyUnwrapped) - return Int(stringValueLen) - } - let ret = PropertyHolder(intValue: Int(intValue), floatValue: floatValue, doubleValue: doubleValue, boolValue: boolValue == 1, stringValue: stringValue, jsObject: JSObject(id: UInt32(bitPattern: jsObject))) + let ret = PropertyHolder(intValue: Int.bridgeJSLiftParameter(intValue), floatValue: floatValue, doubleValue: doubleValue, boolValue: Bool.bridgeJSLiftParameter(boolValue), stringValue: String.bridgeJSLiftParameter(stringValueBytes, stringValueLen), jsObject: JSObject.bridgeJSLiftParameter(jsObject)) return Unmanaged.passRetained(ret).toOpaque() #else fatalError("Only available on WebAssembly") @@ -53,10 +43,8 @@ public func _bjs_PropertyHolder_init(intValue: Int32, floatValue: Float32, doubl @_cdecl("bjs_PropertyHolder_getAllValues") public func _bjs_PropertyHolder_getAllValues(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - var ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().getAllValues() - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().getAllValues() + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -77,7 +65,7 @@ public func _bjs_PropertyHolder_intValue_get(_self: UnsafeMutableRawPointer) -> @_cdecl("bjs_PropertyHolder_intValue_set") public func _bjs_PropertyHolder_intValue_set(_self: UnsafeMutableRawPointer, value: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().intValue = Int(value) + Unmanaged.fromOpaque(_self).takeUnretainedValue().intValue = Int.bridgeJSLiftParameter(value) #else fatalError("Only available on WebAssembly") #endif @@ -130,7 +118,7 @@ public func _bjs_PropertyHolder_doubleValue_set(_self: UnsafeMutableRawPointer, public func _bjs_PropertyHolder_boolValue_get(_self: UnsafeMutableRawPointer) -> Int32 { #if arch(wasm32) let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().boolValue - return Int32(ret ? 1 : 0) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -140,7 +128,7 @@ public func _bjs_PropertyHolder_boolValue_get(_self: UnsafeMutableRawPointer) -> @_cdecl("bjs_PropertyHolder_boolValue_set") public func _bjs_PropertyHolder_boolValue_set(_self: UnsafeMutableRawPointer, value: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().boolValue = value == 1 + Unmanaged.fromOpaque(_self).takeUnretainedValue().boolValue = Bool.bridgeJSLiftParameter(value) #else fatalError("Only available on WebAssembly") #endif @@ -150,10 +138,8 @@ public func _bjs_PropertyHolder_boolValue_set(_self: UnsafeMutableRawPointer, va @_cdecl("bjs_PropertyHolder_stringValue_get") public func _bjs_PropertyHolder_stringValue_get(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - var ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().stringValue - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().stringValue + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -163,11 +149,7 @@ public func _bjs_PropertyHolder_stringValue_get(_self: UnsafeMutableRawPointer) @_cdecl("bjs_PropertyHolder_stringValue_set") public func _bjs_PropertyHolder_stringValue_set(_self: UnsafeMutableRawPointer, valueBytes: Int32, valueLen: Int32) -> Void { #if arch(wasm32) - let value = String(unsafeUninitializedCapacity: Int(valueLen)) { b in - _swift_js_init_memory(valueBytes, b.baseAddress.unsafelyUnwrapped) - return Int(valueLen) - } - Unmanaged.fromOpaque(_self).takeUnretainedValue().stringValue = value + Unmanaged.fromOpaque(_self).takeUnretainedValue().stringValue = String.bridgeJSLiftParameter(valueBytes, valueLen) #else fatalError("Only available on WebAssembly") #endif @@ -211,7 +193,7 @@ public func _bjs_PropertyHolder_readonlyDouble_get(_self: UnsafeMutableRawPointe public func _bjs_PropertyHolder_readonlyBool_get(_self: UnsafeMutableRawPointer) -> Int32 { #if arch(wasm32) let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().readonlyBool - return Int32(ret ? 1 : 0) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -221,10 +203,8 @@ public func _bjs_PropertyHolder_readonlyBool_get(_self: UnsafeMutableRawPointer) @_cdecl("bjs_PropertyHolder_readonlyString_get") public func _bjs_PropertyHolder_readonlyString_get(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - var ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().readonlyString - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().readonlyString + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -235,7 +215,7 @@ public func _bjs_PropertyHolder_readonlyString_get(_self: UnsafeMutableRawPointe public func _bjs_PropertyHolder_jsObject_get(_self: UnsafeMutableRawPointer) -> Int32 { #if arch(wasm32) let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().jsObject - return _swift_js_retain(Int32(bitPattern: ret.id)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -245,7 +225,7 @@ public func _bjs_PropertyHolder_jsObject_get(_self: UnsafeMutableRawPointer) -> @_cdecl("bjs_PropertyHolder_jsObject_set") public func _bjs_PropertyHolder_jsObject_set(_self: UnsafeMutableRawPointer, value: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().jsObject = JSObject(id: UInt32(bitPattern: value)) + Unmanaged.fromOpaque(_self).takeUnretainedValue().jsObject = JSObject.bridgeJSLiftParameter(value) #else fatalError("Only available on WebAssembly") #endif @@ -276,10 +256,8 @@ public func _bjs_PropertyHolder_sibling_set(_self: UnsafeMutableRawPointer, valu @_cdecl("bjs_PropertyHolder_lazyValue_get") public func _bjs_PropertyHolder_lazyValue_get(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - var ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().lazyValue - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().lazyValue + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -289,11 +267,7 @@ public func _bjs_PropertyHolder_lazyValue_get(_self: UnsafeMutableRawPointer) -> @_cdecl("bjs_PropertyHolder_lazyValue_set") public func _bjs_PropertyHolder_lazyValue_set(_self: UnsafeMutableRawPointer, valueBytes: Int32, valueLen: Int32) -> Void { #if arch(wasm32) - let value = String(unsafeUninitializedCapacity: Int(valueLen)) { b in - _swift_js_init_memory(valueBytes, b.baseAddress.unsafelyUnwrapped) - return Int(valueLen) - } - Unmanaged.fromOpaque(_self).takeUnretainedValue().lazyValue = value + Unmanaged.fromOpaque(_self).takeUnretainedValue().lazyValue = String.bridgeJSLiftParameter(valueBytes, valueLen) #else fatalError("Only available on WebAssembly") #endif @@ -314,10 +288,8 @@ public func _bjs_PropertyHolder_computedReadonly_get(_self: UnsafeMutableRawPoin @_cdecl("bjs_PropertyHolder_computedReadWrite_get") public func _bjs_PropertyHolder_computedReadWrite_get(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - var ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().computedReadWrite - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().computedReadWrite + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -327,11 +299,7 @@ public func _bjs_PropertyHolder_computedReadWrite_get(_self: UnsafeMutableRawPoi @_cdecl("bjs_PropertyHolder_computedReadWrite_set") public func _bjs_PropertyHolder_computedReadWrite_set(_self: UnsafeMutableRawPointer, valueBytes: Int32, valueLen: Int32) -> Void { #if arch(wasm32) - let value = String(unsafeUninitializedCapacity: Int(valueLen)) { b in - _swift_js_init_memory(valueBytes, b.baseAddress.unsafelyUnwrapped) - return Int(valueLen) - } - Unmanaged.fromOpaque(_self).takeUnretainedValue().computedReadWrite = value + Unmanaged.fromOpaque(_self).takeUnretainedValue().computedReadWrite = String.bridgeJSLiftParameter(valueBytes, valueLen) #else fatalError("Only available on WebAssembly") #endif @@ -352,7 +320,7 @@ public func _bjs_PropertyHolder_observedProperty_get(_self: UnsafeMutableRawPoin @_cdecl("bjs_PropertyHolder_observedProperty_set") public func _bjs_PropertyHolder_observedProperty_set(_self: UnsafeMutableRawPointer, value: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().observedProperty = Int(value) + Unmanaged.fromOpaque(_self).takeUnretainedValue().observedProperty = Int.bridgeJSLiftParameter(value) #else fatalError("Only available on WebAssembly") #endif diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StringParameter.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StringParameter.swift index 69bd66b5..0da63382 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StringParameter.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StringParameter.swift @@ -10,11 +10,7 @@ @_cdecl("bjs_checkString") public func _bjs_checkString(aBytes: Int32, aLen: Int32) -> Void { #if arch(wasm32) - let a = String(unsafeUninitializedCapacity: Int(aLen)) { b in - _swift_js_init_memory(aBytes, b.baseAddress.unsafelyUnwrapped) - return Int(aLen) - } - checkString(a: a) + checkString(a: String.bridgeJSLiftParameter(aBytes, aLen)) #else fatalError("Only available on WebAssembly") #endif diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StringReturn.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StringReturn.swift index 536f0623..0475def5 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StringReturn.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StringReturn.swift @@ -10,10 +10,8 @@ @_cdecl("bjs_checkString") public func _bjs_checkString() -> Void { #if arch(wasm32) - var ret = checkString() - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = checkString() + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftClass.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftClass.swift index bcb9f3d7..78f8c149 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftClass.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftClass.swift @@ -20,11 +20,7 @@ public func _bjs_takeGreeter(greeter: UnsafeMutableRawPointer) -> Void { @_cdecl("bjs_Greeter_init") public func _bjs_Greeter_init(nameBytes: Int32, nameLen: Int32) -> UnsafeMutableRawPointer { #if arch(wasm32) - let name = String(unsafeUninitializedCapacity: Int(nameLen)) { b in - _swift_js_init_memory(nameBytes, b.baseAddress.unsafelyUnwrapped) - return Int(nameLen) - } - let ret = Greeter(name: name) + let ret = Greeter(name: String.bridgeJSLiftParameter(nameBytes, nameLen)) return Unmanaged.passRetained(ret).toOpaque() #else fatalError("Only available on WebAssembly") @@ -35,10 +31,8 @@ public func _bjs_Greeter_init(nameBytes: Int32, nameLen: Int32) -> UnsafeMutable @_cdecl("bjs_Greeter_greet") public func _bjs_Greeter_greet(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - var ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().greet() - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().greet() + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -48,11 +42,7 @@ public func _bjs_Greeter_greet(_self: UnsafeMutableRawPointer) -> Void { @_cdecl("bjs_Greeter_changeName") public func _bjs_Greeter_changeName(_self: UnsafeMutableRawPointer, nameBytes: Int32, nameLen: Int32) -> Void { #if arch(wasm32) - let name = String(unsafeUninitializedCapacity: Int(nameLen)) { b in - _swift_js_init_memory(nameBytes, b.baseAddress.unsafelyUnwrapped) - return Int(nameLen) - } - Unmanaged.fromOpaque(_self).takeUnretainedValue().changeName(name: name) + Unmanaged.fromOpaque(_self).takeUnretainedValue().changeName(name: String.bridgeJSLiftParameter(nameBytes, nameLen)) #else fatalError("Only available on WebAssembly") #endif @@ -62,10 +52,8 @@ public func _bjs_Greeter_changeName(_self: UnsafeMutableRawPointer, nameBytes: I @_cdecl("bjs_Greeter_name_get") public func _bjs_Greeter_name_get(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - var ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().name - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().name + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -75,11 +63,7 @@ public func _bjs_Greeter_name_get(_self: UnsafeMutableRawPointer) -> Void { @_cdecl("bjs_Greeter_name_set") public func _bjs_Greeter_name_set(_self: UnsafeMutableRawPointer, valueBytes: Int32, valueLen: Int32) -> Void { #if arch(wasm32) - let value = String(unsafeUninitializedCapacity: Int(valueLen)) { b in - _swift_js_init_memory(valueBytes, b.baseAddress.unsafelyUnwrapped) - return Int(valueLen) - } - Unmanaged.fromOpaque(_self).takeUnretainedValue().name = value + Unmanaged.fromOpaque(_self).takeUnretainedValue().name = String.bridgeJSLiftParameter(valueBytes, valueLen) #else fatalError("Only available on WebAssembly") #endif diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/ArrayParameter.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/ArrayParameter.swift index 34841ae8..f8974961 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/ArrayParameter.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/ArrayParameter.swift @@ -15,7 +15,7 @@ func checkArray(_ a: JSObject) throws(JSException) -> Void { fatalError("Only available on WebAssembly") } #endif - bjs_checkArray(Int32(bitPattern: a.id)) + bjs_checkArray(a.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -30,7 +30,7 @@ func checkArrayWithLength(_ a: JSObject, _ b: Double) throws(JSException) -> Voi fatalError("Only available on WebAssembly") } #endif - bjs_checkArrayWithLength(Int32(bitPattern: a.id), b) + bjs_checkArrayWithLength(a.bridgeJSLowerParameter(), b) if let error = _swift_js_take_exception() { throw error } @@ -45,7 +45,7 @@ func checkArray(_ a: JSObject) throws(JSException) -> Void { fatalError("Only available on WebAssembly") } #endif - bjs_checkArray(Int32(bitPattern: a.id)) + bjs_checkArray(a.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/Async.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/Async.swift index aa11cd0c..ea9a9ab6 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/Async.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/Async.swift @@ -47,11 +47,7 @@ func asyncRoundTripString(_ v: String) throws(JSException) -> JSPromise { fatalError("Only available on WebAssembly") } #endif - var v = v - let vId = v.withUTF8 { b in - _swift_js_make_js_string(b.baseAddress.unsafelyUnwrapped, Int32(b.count)) - } - let ret = bjs_asyncRoundTripString(vId) + let ret = bjs_asyncRoundTripString(v.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -67,7 +63,7 @@ func asyncRoundTripBool(_ v: Bool) throws(JSException) -> JSPromise { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_asyncRoundTripBool(Int32(v ? 1 : 0)) + let ret = bjs_asyncRoundTripBool(v.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -115,7 +111,7 @@ func asyncRoundTripJSObject(_ v: JSObject) throws(JSException) -> JSPromise { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_asyncRoundTripJSObject(Int32(bitPattern: v.id)) + let ret = bjs_asyncRoundTripJSObject(v.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/Interface.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/Interface.swift index be9f524e..a4ee884f 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/Interface.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/Interface.swift @@ -42,11 +42,11 @@ struct Animatable { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_Animatable_animate(Int32(bitPattern: self.this.id), Int32(bitPattern: keyframes.id), Int32(bitPattern: options.id)) + let ret = bjs_Animatable_animate(self.this.bridgeJSLowerParameter(), keyframes.bridgeJSLowerParameter(), options.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } - return JSObject(id: UInt32(bitPattern: ret)) + return JSObject.bridgeJSLiftReturn(ret) } func getAnimations(_ options: JSObject) throws(JSException) -> JSObject { @@ -58,11 +58,11 @@ struct Animatable { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_Animatable_getAnimations(Int32(bitPattern: self.this.id), Int32(bitPattern: options.id)) + let ret = bjs_Animatable_getAnimations(self.this.bridgeJSLowerParameter(), options.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } - return JSObject(id: UInt32(bitPattern: ret)) + return JSObject.bridgeJSLiftReturn(ret) } } \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/MultipleImportedTypes.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/MultipleImportedTypes.swift index d3e06e81..ab07c967 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/MultipleImportedTypes.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/MultipleImportedTypes.swift @@ -15,7 +15,7 @@ func createDatabaseConnection(_ config: JSObject) throws(JSException) -> Databas fatalError("Only available on WebAssembly") } #endif - let ret = bjs_createDatabaseConnection(Int32(bitPattern: config.id)) + let ret = bjs_createDatabaseConnection(config.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -31,11 +31,7 @@ func createLogger(_ level: String) throws(JSException) -> Logger { fatalError("Only available on WebAssembly") } #endif - var level = level - let levelId = level.withUTF8 { b in - _swift_js_make_js_string(b.baseAddress.unsafelyUnwrapped, Int32(b.count)) - } - let ret = bjs_createLogger(levelId) + let ret = bjs_createLogger(level.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -79,11 +75,11 @@ struct DatabaseConnection { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_DatabaseConnection_isConnected_get(Int32(bitPattern: self.this.id)) + let ret = bjs_DatabaseConnection_isConnected_get(self.this.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } - return ret == 1 + return Bool.bridgeJSLiftReturn(ret) } } @@ -97,7 +93,7 @@ struct DatabaseConnection { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_DatabaseConnection_connectionTimeout_get(Int32(bitPattern: self.this.id)) + let ret = bjs_DatabaseConnection_connectionTimeout_get(self.this.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -114,7 +110,7 @@ struct DatabaseConnection { fatalError("Only available on WebAssembly") } #endif - bjs_DatabaseConnection_connectionTimeout_set(Int32(bitPattern: self.this.id), newValue) + bjs_DatabaseConnection_connectionTimeout_set(self.this.bridgeJSLowerParameter(), newValue) if let error = _swift_js_take_exception() { throw error } @@ -129,11 +125,7 @@ struct DatabaseConnection { fatalError("Only available on WebAssembly") } #endif - var url = url - let urlId = url.withUTF8 { b in - _swift_js_make_js_string(b.baseAddress.unsafelyUnwrapped, Int32(b.count)) - } - bjs_DatabaseConnection_connect(Int32(bitPattern: self.this.id), urlId) + bjs_DatabaseConnection_connect(self.this.bridgeJSLowerParameter(), url.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -148,15 +140,11 @@ struct DatabaseConnection { fatalError("Only available on WebAssembly") } #endif - var query = query - let queryId = query.withUTF8 { b in - _swift_js_make_js_string(b.baseAddress.unsafelyUnwrapped, Int32(b.count)) - } - let ret = bjs_DatabaseConnection_execute(Int32(bitPattern: self.this.id), queryId) + let ret = bjs_DatabaseConnection_execute(self.this.bridgeJSLowerParameter(), query.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } - return JSObject(id: UInt32(bitPattern: ret)) + return JSObject.bridgeJSLiftReturn(ret) } } @@ -182,14 +170,11 @@ struct Logger { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_Logger_level_get(Int32(bitPattern: self.this.id)) + let ret = bjs_Logger_level_get(self.this.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } - return String(unsafeUninitializedCapacity: Int(ret)) { b in - _swift_js_init_memory_with_result(b.baseAddress.unsafelyUnwrapped, Int32(ret)) - return Int(ret) - } + return String.bridgeJSLiftReturn(ret) } } @@ -202,11 +187,7 @@ struct Logger { fatalError("Only available on WebAssembly") } #endif - var message = message - let messageId = message.withUTF8 { b in - _swift_js_make_js_string(b.baseAddress.unsafelyUnwrapped, Int32(b.count)) - } - bjs_Logger_log(Int32(bitPattern: self.this.id), messageId) + bjs_Logger_log(self.this.bridgeJSLowerParameter(), message.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -221,11 +202,7 @@ struct Logger { fatalError("Only available on WebAssembly") } #endif - var message = message - let messageId = message.withUTF8 { b in - _swift_js_make_js_string(b.baseAddress.unsafelyUnwrapped, Int32(b.count)) - } - bjs_Logger_error(Int32(bitPattern: self.this.id), messageId, Int32(bitPattern: error.id)) + bjs_Logger_error(self.this.bridgeJSLowerParameter(), message.bridgeJSLowerParameter(), error.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -254,14 +231,11 @@ struct ConfigManager { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_ConfigManager_configPath_get(Int32(bitPattern: self.this.id)) + let ret = bjs_ConfigManager_configPath_get(self.this.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } - return String(unsafeUninitializedCapacity: Int(ret)) { b in - _swift_js_init_memory_with_result(b.baseAddress.unsafelyUnwrapped, Int32(ret)) - return Int(ret) - } + return String.bridgeJSLiftReturn(ret) } } @@ -274,15 +248,11 @@ struct ConfigManager { fatalError("Only available on WebAssembly") } #endif - var key = key - let keyId = key.withUTF8 { b in - _swift_js_make_js_string(b.baseAddress.unsafelyUnwrapped, Int32(b.count)) - } - let ret = bjs_ConfigManager_get(Int32(bitPattern: self.this.id), keyId) + let ret = bjs_ConfigManager_get(self.this.bridgeJSLowerParameter(), key.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } - return JSObject(id: UInt32(bitPattern: ret)) + return JSObject.bridgeJSLiftReturn(ret) } func set(_ key: String, _ value: JSObject) throws(JSException) -> Void { @@ -294,11 +264,7 @@ struct ConfigManager { fatalError("Only available on WebAssembly") } #endif - var key = key - let keyId = key.withUTF8 { b in - _swift_js_make_js_string(b.baseAddress.unsafelyUnwrapped, Int32(b.count)) - } - bjs_ConfigManager_set(Int32(bitPattern: self.this.id), keyId, Int32(bitPattern: value.id)) + bjs_ConfigManager_set(self.this.bridgeJSLowerParameter(), key.bridgeJSLowerParameter(), value.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/PrimitiveParameters.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/PrimitiveParameters.swift index c47f5f40..43b66797 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/PrimitiveParameters.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/PrimitiveParameters.swift @@ -15,7 +15,7 @@ func check(_ a: Double, _ b: Bool) throws(JSException) -> Void { fatalError("Only available on WebAssembly") } #endif - bjs_check(a, Int32(b ? 1 : 0)) + bjs_check(a, b.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/PrimitiveReturn.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/PrimitiveReturn.swift index cf26a52f..77dcc710 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/PrimitiveReturn.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/PrimitiveReturn.swift @@ -35,5 +35,5 @@ func checkBoolean() throws(JSException) -> Bool { if let error = _swift_js_take_exception() { throw error } - return ret == 1 + return Bool.bridgeJSLiftReturn(ret) } \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/StringParameter.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/StringParameter.swift index aabffacc..7ecbbac9 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/StringParameter.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/StringParameter.swift @@ -15,11 +15,7 @@ func checkString(_ a: String) throws(JSException) -> Void { fatalError("Only available on WebAssembly") } #endif - var a = a - let aId = a.withUTF8 { b in - _swift_js_make_js_string(b.baseAddress.unsafelyUnwrapped, Int32(b.count)) - } - bjs_checkString(aId) + bjs_checkString(a.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -34,11 +30,7 @@ func checkStringWithLength(_ a: String, _ b: Double) throws(JSException) -> Void fatalError("Only available on WebAssembly") } #endif - var a = a - let aId = a.withUTF8 { b in - _swift_js_make_js_string(b.baseAddress.unsafelyUnwrapped, Int32(b.count)) - } - bjs_checkStringWithLength(aId, b) + bjs_checkStringWithLength(a.bridgeJSLowerParameter(), b) if let error = _swift_js_take_exception() { throw error } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/StringReturn.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/StringReturn.swift index af7b5162..05bb8aea 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/StringReturn.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/StringReturn.swift @@ -19,8 +19,5 @@ func checkString() throws(JSException) -> String { if let error = _swift_js_take_exception() { throw error } - return String(unsafeUninitializedCapacity: Int(ret)) { b in - _swift_js_init_memory_with_result(b.baseAddress.unsafelyUnwrapped, Int32(ret)) - return Int(ret) - } + return String.bridgeJSLiftReturn(ret) } \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TS2SkeletonLike.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TS2SkeletonLike.swift index 95e9da8c..68acd5bf 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TS2SkeletonLike.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TS2SkeletonLike.swift @@ -31,11 +31,7 @@ func createCodeGenerator(_ format: String) throws(JSException) -> CodeGenerator fatalError("Only available on WebAssembly") } #endif - var format = format - let formatId = format.withUTF8 { b in - _swift_js_make_js_string(b.baseAddress.unsafelyUnwrapped, Int32(b.count)) - } - let ret = bjs_createCodeGenerator(formatId) + let ret = bjs_createCodeGenerator(format.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -63,14 +59,11 @@ struct TypeScriptProcessor { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_TypeScriptProcessor_version_get(Int32(bitPattern: self.this.id)) + let ret = bjs_TypeScriptProcessor_version_get(self.this.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } - return String(unsafeUninitializedCapacity: Int(ret)) { b in - _swift_js_init_memory_with_result(b.baseAddress.unsafelyUnwrapped, Int32(ret)) - return Int(ret) - } + return String.bridgeJSLiftReturn(ret) } } @@ -83,18 +76,11 @@ struct TypeScriptProcessor { fatalError("Only available on WebAssembly") } #endif - var ts = ts - let tsId = ts.withUTF8 { b in - _swift_js_make_js_string(b.baseAddress.unsafelyUnwrapped, Int32(b.count)) - } - let ret = bjs_TypeScriptProcessor_convert(Int32(bitPattern: self.this.id), tsId) + let ret = bjs_TypeScriptProcessor_convert(self.this.bridgeJSLowerParameter(), ts.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } - return String(unsafeUninitializedCapacity: Int(ret)) { b in - _swift_js_init_memory_with_result(b.baseAddress.unsafelyUnwrapped, Int32(ret)) - return Int(ret) - } + return String.bridgeJSLiftReturn(ret) } func validate(_ ts: String) throws(JSException) -> Bool { @@ -106,15 +92,11 @@ struct TypeScriptProcessor { fatalError("Only available on WebAssembly") } #endif - var ts = ts - let tsId = ts.withUTF8 { b in - _swift_js_make_js_string(b.baseAddress.unsafelyUnwrapped, Int32(b.count)) - } - let ret = bjs_TypeScriptProcessor_validate(Int32(bitPattern: self.this.id), tsId) + let ret = bjs_TypeScriptProcessor_validate(self.this.bridgeJSLowerParameter(), ts.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } - return ret == 1 + return Bool.bridgeJSLiftReturn(ret) } } @@ -140,14 +122,11 @@ struct CodeGenerator { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_CodeGenerator_outputFormat_get(Int32(bitPattern: self.this.id)) + let ret = bjs_CodeGenerator_outputFormat_get(self.this.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } - return String(unsafeUninitializedCapacity: Int(ret)) { b in - _swift_js_init_memory_with_result(b.baseAddress.unsafelyUnwrapped, Int32(ret)) - return Int(ret) - } + return String.bridgeJSLiftReturn(ret) } } @@ -160,14 +139,11 @@ struct CodeGenerator { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_CodeGenerator_generate(Int32(bitPattern: self.this.id), Int32(bitPattern: input.id)) + let ret = bjs_CodeGenerator_generate(self.this.bridgeJSLowerParameter(), input.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } - return String(unsafeUninitializedCapacity: Int(ret)) { b in - _swift_js_init_memory_with_result(b.baseAddress.unsafelyUnwrapped, Int32(ret)) - return Int(ret) - } + return String.bridgeJSLiftReturn(ret) } } \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TypeScriptClass.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TypeScriptClass.swift index 7a1f2a2c..f22bfda2 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TypeScriptClass.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TypeScriptClass.swift @@ -26,11 +26,7 @@ struct Greeter { fatalError("Only available on WebAssembly") } #endif - var name = name - let nameId = name.withUTF8 { b in - _swift_js_make_js_string(b.baseAddress.unsafelyUnwrapped, Int32(b.count)) - } - let ret = bjs_Greeter_init(nameId) + let ret = bjs_Greeter_init(name.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -47,14 +43,11 @@ struct Greeter { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_Greeter_name_get(Int32(bitPattern: self.this.id)) + let ret = bjs_Greeter_name_get(self.this.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } - return String(unsafeUninitializedCapacity: Int(ret)) { b in - _swift_js_init_memory_with_result(b.baseAddress.unsafelyUnwrapped, Int32(ret)) - return Int(ret) - } + return String.bridgeJSLiftReturn(ret) } } @@ -67,11 +60,7 @@ struct Greeter { fatalError("Only available on WebAssembly") } #endif - var newValue = newValue - let newValueId = newValue.withUTF8 { b in - _swift_js_make_js_string(b.baseAddress.unsafelyUnwrapped, Int32(b.count)) - } - bjs_Greeter_name_set(Int32(bitPattern: self.this.id), newValueId) + bjs_Greeter_name_set(self.this.bridgeJSLowerParameter(), newValue.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -87,7 +76,7 @@ struct Greeter { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_Greeter_age_get(Int32(bitPattern: self.this.id)) + let ret = bjs_Greeter_age_get(self.this.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -104,14 +93,11 @@ struct Greeter { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_Greeter_greet(Int32(bitPattern: self.this.id)) + let ret = bjs_Greeter_greet(self.this.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } - return String(unsafeUninitializedCapacity: Int(ret)) { b in - _swift_js_init_memory_with_result(b.baseAddress.unsafelyUnwrapped, Int32(ret)) - return Int(ret) - } + return String.bridgeJSLiftReturn(ret) } func changeName(_ name: String) throws(JSException) -> Void { @@ -123,11 +109,7 @@ struct Greeter { fatalError("Only available on WebAssembly") } #endif - var name = name - let nameId = name.withUTF8 { b in - _swift_js_make_js_string(b.baseAddress.unsafelyUnwrapped, Int32(b.count)) - } - bjs_Greeter_changeName(Int32(bitPattern: self.this.id), nameId) + bjs_Greeter_changeName(self.this.bridgeJSLowerParameter(), name.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } diff --git a/Sources/JavaScriptKit/BridgeJSInstrincics.swift b/Sources/JavaScriptKit/BridgeJSInstrincics.swift index 1a8bad7f..2756cb59 100644 --- a/Sources/JavaScriptKit/BridgeJSInstrincics.swift +++ b/Sources/JavaScriptKit/BridgeJSInstrincics.swift @@ -1,3 +1,8 @@ +/// BridgeJS Intrinsics +/// +/// This file contains low-level intrinsic functions that are used by code generated +/// by the BridgeJS system. + import _CJavaScriptKit #if !arch(wasm32) @@ -6,60 +11,31 @@ import _CJavaScriptKit } #endif -#if arch(wasm32) -@_extern(wasm, module: "bjs", name: "swift_js_return_string") -@_spi(BridgeJS) public func _swift_js_return_string(_ ptr: UnsafePointer?, _ len: Int32) -#else -@_spi(BridgeJS) public func _swift_js_return_string(_ ptr: UnsafePointer?, _ len: Int32) { - _onlyAvailableOnWasm() -} -#endif - -#if arch(wasm32) -@_extern(wasm, module: "bjs", name: "swift_js_init_memory") -@_spi(BridgeJS) public func _swift_js_init_memory(_ sourceId: Int32, _ ptr: UnsafeMutablePointer?) -#else -@_spi(BridgeJS) public func _swift_js_init_memory(_ sourceId: Int32, _ ptr: UnsafeMutablePointer?) { - _onlyAvailableOnWasm() -} -#endif - -#if arch(wasm32) -@_extern(wasm, module: "bjs", name: "swift_js_retain") -@_spi(BridgeJS) public func _swift_js_retain(_ ptr: Int32) -> Int32 -#else -@_spi(BridgeJS) public func _swift_js_retain(_ ptr: Int32) -> Int32 { - _onlyAvailableOnWasm() -} -#endif +// MARK: Exception Handling #if arch(wasm32) @_extern(wasm, module: "bjs", name: "swift_js_throw") @_spi(BridgeJS) public func _swift_js_throw(_ id: Int32) #else +/// Throws a JavaScript exception from Swift code. +/// +/// This function is called by the BridgeJS code generator when a Swift function throws +/// an error. The exception object is retained and stored for later retrieval by the +/// JavaScript-side runtime code. +/// +/// - Parameter id: The ID of the JavaScript exception object to throw @_spi(BridgeJS) public func _swift_js_throw(_ id: Int32) { _onlyAvailableOnWasm() } #endif -#if arch(wasm32) -@_extern(wasm, module: "bjs", name: "swift_js_make_js_string") -@_spi(BridgeJS) public func _swift_js_make_js_string(_ ptr: UnsafePointer?, _ len: Int32) -> Int32 -#else -@_spi(BridgeJS) public func _swift_js_make_js_string(_ ptr: UnsafePointer?, _ len: Int32) -> Int32 { - _onlyAvailableOnWasm() -} -#endif - -#if arch(wasm32) -@_extern(wasm, module: "bjs", name: "swift_js_init_memory_with_result") -@_spi(BridgeJS) public func _swift_js_init_memory_with_result(_ ptr: UnsafePointer?, _ len: Int32) -#else -@_spi(BridgeJS) public func _swift_js_init_memory_with_result(_ ptr: UnsafePointer?, _ len: Int32) { - _onlyAvailableOnWasm() -} -#endif - +/// Retrieves and clears any pending JavaScript exception. +/// +/// This function checks for any JavaScript exceptions that were thrown during +/// the execution of imported JavaScript functions. If an exception exists, it +/// is retrieved, cleared from the global storage, and returned as a `JSException`. +/// +/// - Returns: A `JSException` if an exception was pending, `nil` otherwise @_spi(BridgeJS) @_transparent public func _swift_js_take_exception() -> JSException? { #if arch(wasm32) let value = _swift_js_exception_get() @@ -72,3 +48,168 @@ import _CJavaScriptKit _onlyAvailableOnWasm() #endif } + +// MARK: Type lowering/lifting +// +// The following part defines the parameter and return value lowering/lifting +// for a given type. They follow the following pattern: +// +// ```swift +// extension <#TargetType#> { +// // MARK: ImportTS +// @_spi(BridgeJS) public consuming func bridgeJSLowerParameter() -> <#WasmCoreType#> { +// } +// @_spi(BridgeJS) public static func bridgeJSLiftReturn(_ ...) -> <#Self#> { +// } +// // MARK: ExportSwift +// @_spi(BridgeJS) public static func bridgeJSLiftParameter(_ ...) -> <#Self#> { +// } +// @_spi(BridgeJS) public consuming func bridgeJSLowerReturn() -> <#WasmCoreType#> { +// } +// } +// ``` +// +// where: +// - <#TargetType#>: the higher-level type to be lowered/lifted +// - <#WasmCoreType#>: the corresponding WebAssembly core type or Void +// - `func bridgeJSLowerParameter()`: lower the given higher-level parameter to a WebAssembly core type +// - `func bridgeJSLiftReturn(_ ...) -> <#TargetType#>`: lift the given Wasm core type return value to a higher-level type +// - `func bridgeJSLiftParameter(_ ...) -> <#TargetType#>`: lift the given Wasm core type parameters to a higher-level type +// - `func bridgeJSLowerReturn() -> <#WasmCoreType#>`: lower the given higher-level return value to a Wasm core type +// +// See JSGlueGen.swift in BridgeJSLink for JS-side lowering/lifting implementation. + +extension Bool { + // MARK: ImportTS + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + self ? 1 : 0 + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Int32) -> Bool { + value == 1 + } + // MARK: ExportSwift + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Int32) -> Bool { + value == 1 + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Int32 { + self ? 1 : 0 + } +} + +extension Int { + // MARK: ImportTS + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + Int32(self) + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Int32) -> Int { + Int(value) + } + // MARK: ExportSwift + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Int32) -> Int { + Int(value) + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Int32 { + Int32(self) + } +} + +extension String { + // MARK: ImportTS + + @_spi(BridgeJS) public consuming func bridgeJSLowerParameter() -> Int32 { + #if arch(wasm32) + @_extern(wasm, module: "bjs", name: "swift_js_make_js_string") + func _swift_js_make_js_string(_ ptr: UnsafePointer?, _ len: Int32) -> Int32 + #else + /// Creates a JavaScript string from UTF-8 data in WebAssembly memory + func _swift_js_make_js_string(_ ptr: UnsafePointer?, _ len: Int32) -> Int32 { + _onlyAvailableOnWasm() + } + #endif + return self.withUTF8 { b in + _swift_js_make_js_string(b.baseAddress.unsafelyUnwrapped, Int32(b.count)) + } + } + + @_spi(BridgeJS) public static func bridgeJSLiftReturn(_ bytesCount: Int32) -> String { + #if arch(wasm32) + @_extern(wasm, module: "bjs", name: "swift_js_init_memory_with_result") + func _swift_js_init_memory_with_result(_ ptr: UnsafePointer?, _ len: Int32) + #else + /// Initializes WebAssembly memory with result data of JavaScript function call + func _swift_js_init_memory_with_result(_ ptr: UnsafePointer?, _ len: Int32) { + _onlyAvailableOnWasm() + } + guard #available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *) else { _onlyAvailableOnWasm() } + #endif + return String(unsafeUninitializedCapacity: Int(bytesCount)) { b in + _swift_js_init_memory_with_result(b.baseAddress.unsafelyUnwrapped, Int32(bytesCount)) + return Int(bytesCount) + } + } + + // MARK: ExportSwift + + @_spi(BridgeJS) public static func bridgeJSLiftParameter(_ bytes: Int32, _ count: Int32) -> String { + #if arch(wasm32) + @_extern(wasm, module: "bjs", name: "swift_js_init_memory") + func _swift_js_init_memory(_ sourceId: Int32, _ ptr: UnsafeMutablePointer?) + #else + /// Initializes a part of WebAssembly memory with Uint8Array a JavaScript object + func _swift_js_init_memory(_ sourceId: Int32, _ ptr: UnsafeMutablePointer?) { + _onlyAvailableOnWasm() + } + guard #available(macOS 11.0, iOS 14.0, watchOS 7.0, tvOS 14.0, *) else { _onlyAvailableOnWasm() } + #endif + return String(unsafeUninitializedCapacity: Int(count)) { b in + _swift_js_init_memory(bytes, b.baseAddress.unsafelyUnwrapped) + return Int(count) + } + } + + @_spi(BridgeJS) public consuming func bridgeJSLowerReturn() -> Void { + #if arch(wasm32) + @_extern(wasm, module: "bjs", name: "swift_js_return_string") + func _swift_js_return_string(_ ptr: UnsafePointer?, _ len: Int32) + #else + /// Write a string to reserved string storage to be returned to JavaScript + func _swift_js_return_string(_ ptr: UnsafePointer?, _ len: Int32) { + _onlyAvailableOnWasm() + } + #endif + return self.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + } +} + +extension JSObject { + // MARK: ImportTS + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + Int32(bitPattern: self.id) + } + @_spi(BridgeJS) public static func bridgeJSLiftReturn(_ id: Int32) -> JSObject { + JSObject(id: JavaScriptObjectRef(bitPattern: id)) + } + + // MARK: ExportSwift + + @_spi(BridgeJS) public static func bridgeJSLiftParameter(_ id: Int32) -> JSObject { + JSObject(id: JavaScriptObjectRef(bitPattern: id)) + } + + @_spi(BridgeJS) public consuming func bridgeJSLowerReturn() -> Int32 { + #if arch(wasm32) + @_extern(wasm, module: "bjs", name: "swift_js_retain") + func _swift_js_retain(_ id: Int32) -> Int32 + #else + /// Retains a JavaScript object reference to ensure the object id + /// remains valid after the function returns + func _swift_js_retain(_ id: Int32) -> Int32 { + _onlyAvailableOnWasm() + } + #endif + return _swift_js_retain(Int32(bitPattern: self.id)) + } +} diff --git a/Sources/_CJavaScriptKit/include/BridgeJSInstrincics.h b/Sources/_CJavaScriptKit/include/BridgeJSInstrincics.h index 4f5ba93c..7ca09860 100644 --- a/Sources/_CJavaScriptKit/include/BridgeJSInstrincics.h +++ b/Sources/_CJavaScriptKit/include/BridgeJSInstrincics.h @@ -5,6 +5,8 @@ #include "WasmGlobalMacros.h" #if __wasm__ +// Global thread-local pointer storage for temporarily storing JS exceptions +// thrown from imported JavaScript functions. WASM_GLOBAL_DEFINE_INLINE_ACCESSORS(_swift_js_exception, i32, int32_t) #endif diff --git a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ExportSwift.swift b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ExportSwift.swift index d51f954e..524d7424 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ExportSwift.swift +++ b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ExportSwift.swift @@ -158,7 +158,7 @@ public func _bjs_roundTripVoid() -> Void { @_cdecl("bjs_roundTripInt") public func _bjs_roundTripInt(v: Int32) -> Int32 { #if arch(wasm32) - let ret = roundTripInt(v: Int(v)) + let ret = roundTripInt(v: Int.bridgeJSLiftParameter(v)) return Int32(ret) #else fatalError("Only available on WebAssembly") @@ -191,8 +191,8 @@ public func _bjs_roundTripDouble(v: Float64) -> Float64 { @_cdecl("bjs_roundTripBool") public func _bjs_roundTripBool(v: Int32) -> Int32 { #if arch(wasm32) - let ret = roundTripBool(v: v == 1) - return Int32(ret ? 1 : 0) + let ret = roundTripBool(v: Bool.bridgeJSLiftParameter(v)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -202,14 +202,8 @@ public func _bjs_roundTripBool(v: Int32) -> Int32 { @_cdecl("bjs_roundTripString") public func _bjs_roundTripString(vBytes: Int32, vLen: Int32) -> Void { #if arch(wasm32) - let v = String(unsafeUninitializedCapacity: Int(vLen)) { b in - _swift_js_init_memory(vBytes, b.baseAddress.unsafelyUnwrapped) - return Int(vLen) - } - var ret = roundTripString(v: v) - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = roundTripString(v: String.bridgeJSLiftParameter(vBytes, vLen)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -230,8 +224,8 @@ public func _bjs_roundTripSwiftHeapObject(v: UnsafeMutableRawPointer) -> UnsafeM @_cdecl("bjs_roundTripJSObject") public func _bjs_roundTripJSObject(v: Int32) -> Int32 { #if arch(wasm32) - let ret = roundTripJSObject(v: JSObject(id: UInt32(bitPattern: v))) - return _swift_js_retain(Int32(bitPattern: ret.id)) + let ret = roundTripJSObject(v: JSObject.bridgeJSLiftParameter(v)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -242,7 +236,7 @@ public func _bjs_roundTripJSObject(v: Int32) -> Int32 { public func _bjs_throwsSwiftError(shouldThrow: Int32) -> Void { #if arch(wasm32) do { - try throwsSwiftError(shouldThrow: shouldThrow == 1) + try throwsSwiftError(shouldThrow: Bool.bridgeJSLiftParameter(shouldThrow)) } catch let error { if let error = error.thrownValue.object { withExtendedLifetime(error) { @@ -291,10 +285,8 @@ public func _bjs_throwsWithIntResult() -> Int32 { public func _bjs_throwsWithStringResult() -> Void { #if arch(wasm32) do { - var ret = try throwsWithStringResult() - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = try throwsWithStringResult() + return ret.bridgeJSLowerReturn() } catch let error { if let error = error.thrownValue.object { withExtendedLifetime(error) { @@ -319,7 +311,7 @@ public func _bjs_throwsWithBoolResult() -> Int32 { #if arch(wasm32) do { let ret = try throwsWithBoolResult() - return Int32(ret ? 1 : 0) + return ret.bridgeJSLowerReturn() } catch let error { if let error = error.thrownValue.object { withExtendedLifetime(error) { @@ -419,7 +411,7 @@ public func _bjs_throwsWithJSObjectResult() -> Int32 { #if arch(wasm32) do { let ret = try throwsWithJSObjectResult() - return _swift_js_retain(Int32(bitPattern: ret.id)) + return ret.bridgeJSLowerReturn() } catch let error { if let error = error.thrownValue.object { withExtendedLifetime(error) { @@ -445,7 +437,7 @@ public func _bjs_asyncRoundTripVoid() -> Int32 { let ret = JSPromise.async { await asyncRoundTripVoid() } .jsObject - return _swift_js_retain(Int32(bitPattern: ret.id)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -456,9 +448,9 @@ public func _bjs_asyncRoundTripVoid() -> Int32 { public func _bjs_asyncRoundTripInt(v: Int32) -> Int32 { #if arch(wasm32) let ret = JSPromise.async { - return await asyncRoundTripInt(v: Int(v)).jsValue + return await asyncRoundTripInt(v: Int.bridgeJSLiftParameter(v)).jsValue } .jsObject - return _swift_js_retain(Int32(bitPattern: ret.id)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -471,7 +463,7 @@ public func _bjs_asyncRoundTripFloat(v: Float32) -> Int32 { let ret = JSPromise.async { return await asyncRoundTripFloat(v: v).jsValue } .jsObject - return _swift_js_retain(Int32(bitPattern: ret.id)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -484,7 +476,7 @@ public func _bjs_asyncRoundTripDouble(v: Float64) -> Int32 { let ret = JSPromise.async { return await asyncRoundTripDouble(v: v).jsValue } .jsObject - return _swift_js_retain(Int32(bitPattern: ret.id)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -495,9 +487,9 @@ public func _bjs_asyncRoundTripDouble(v: Float64) -> Int32 { public func _bjs_asyncRoundTripBool(v: Int32) -> Int32 { #if arch(wasm32) let ret = JSPromise.async { - return await asyncRoundTripBool(v: v == 1).jsValue + return await asyncRoundTripBool(v: Bool.bridgeJSLiftParameter(v)).jsValue } .jsObject - return _swift_js_retain(Int32(bitPattern: ret.id)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -508,13 +500,9 @@ public func _bjs_asyncRoundTripBool(v: Int32) -> Int32 { public func _bjs_asyncRoundTripString(vBytes: Int32, vLen: Int32) -> Int32 { #if arch(wasm32) let ret = JSPromise.async { - let v = String(unsafeUninitializedCapacity: Int(vLen)) { b in - _swift_js_init_memory(vBytes, b.baseAddress.unsafelyUnwrapped) - return Int(vLen) - } - return await asyncRoundTripString(v: v).jsValue + return await asyncRoundTripString(v: String.bridgeJSLiftParameter(vBytes, vLen)).jsValue } .jsObject - return _swift_js_retain(Int32(bitPattern: ret.id)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -527,7 +515,7 @@ public func _bjs_asyncRoundTripSwiftHeapObject(v: UnsafeMutableRawPointer) -> In let ret = JSPromise.async { return await asyncRoundTripSwiftHeapObject(v: Unmanaged.fromOpaque(v).takeUnretainedValue()).jsValue } .jsObject - return _swift_js_retain(Int32(bitPattern: ret.id)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -538,9 +526,9 @@ public func _bjs_asyncRoundTripSwiftHeapObject(v: UnsafeMutableRawPointer) -> In public func _bjs_asyncRoundTripJSObject(v: Int32) -> Int32 { #if arch(wasm32) let ret = JSPromise.async { - return await asyncRoundTripJSObject(v: JSObject(id: UInt32(bitPattern: v))).jsValue + return await asyncRoundTripJSObject(v: JSObject.bridgeJSLiftParameter(v)).jsValue } .jsObject - return _swift_js_retain(Int32(bitPattern: ret.id)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -550,11 +538,7 @@ public func _bjs_asyncRoundTripJSObject(v: Int32) -> Int32 { @_cdecl("bjs_takeGreeter") public func _bjs_takeGreeter(g: UnsafeMutableRawPointer, nameBytes: Int32, nameLen: Int32) -> Void { #if arch(wasm32) - let name = String(unsafeUninitializedCapacity: Int(nameLen)) { b in - _swift_js_init_memory(nameBytes, b.baseAddress.unsafelyUnwrapped) - return Int(nameLen) - } - takeGreeter(g: Unmanaged.fromOpaque(g).takeUnretainedValue(), name: name) + takeGreeter(g: Unmanaged.fromOpaque(g).takeUnretainedValue(), name: String.bridgeJSLiftParameter(nameBytes, nameLen)) #else fatalError("Only available on WebAssembly") #endif @@ -575,7 +559,7 @@ public func _bjs_createCalculator() -> UnsafeMutableRawPointer { @_cdecl("bjs_useCalculator") public func _bjs_useCalculator(calc: UnsafeMutableRawPointer, x: Int32, y: Int32) -> Int32 { #if arch(wasm32) - let ret = useCalculator(calc: Unmanaged.fromOpaque(calc).takeUnretainedValue(), x: Int(x), y: Int(y)) + let ret = useCalculator(calc: Unmanaged.fromOpaque(calc).takeUnretainedValue(), x: Int.bridgeJSLiftParameter(x), y: Int.bridgeJSLiftParameter(y)) return Int32(ret) #else fatalError("Only available on WebAssembly") @@ -587,7 +571,7 @@ public func _bjs_useCalculator(calc: UnsafeMutableRawPointer, x: Int32, y: Int32 public func _bjs_testGreeterToJSValue() -> Int32 { #if arch(wasm32) let ret = testGreeterToJSValue() - return _swift_js_retain(Int32(bitPattern: ret.id)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -598,7 +582,7 @@ public func _bjs_testGreeterToJSValue() -> Int32 { public func _bjs_testCalculatorToJSValue() -> Int32 { #if arch(wasm32) let ret = testCalculatorToJSValue() - return _swift_js_retain(Int32(bitPattern: ret.id)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -609,7 +593,7 @@ public func _bjs_testCalculatorToJSValue() -> Int32 { public func _bjs_testSwiftClassAsJSValue(greeter: UnsafeMutableRawPointer) -> Int32 { #if arch(wasm32) let ret = testSwiftClassAsJSValue(greeter: Unmanaged.fromOpaque(greeter).takeUnretainedValue()) - return _swift_js_retain(Int32(bitPattern: ret.id)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -652,15 +636,8 @@ public func _bjs_processDirection(input: Int32) -> Int32 { @_cdecl("bjs_setTheme") public func _bjs_setTheme(themeBytes: Int32, themeLen: Int32) -> Void { #if arch(wasm32) - let theme = String(unsafeUninitializedCapacity: Int(themeLen)) { b in - _swift_js_init_memory(themeBytes, b.baseAddress.unsafelyUnwrapped) - return Int(themeLen) - } - let ret = setTheme(_: Theme(rawValue: theme)!) - var rawValue = ret.rawValue - return rawValue.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = setTheme(_: Theme(rawValue: String.bridgeJSLiftParameter(themeBytes, themeLen))!) + return ret.rawValue.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -671,10 +648,7 @@ public func _bjs_setTheme(themeBytes: Int32, themeLen: Int32) -> Void { public func _bjs_getTheme() -> Void { #if arch(wasm32) let ret = getTheme() - var rawValue = ret.rawValue - return rawValue.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + return ret.rawValue.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -706,11 +680,7 @@ public func _bjs_getHttpStatus() -> Int32 { @_cdecl("bjs_processTheme") public func _bjs_processTheme(themeBytes: Int32, themeLen: Int32) -> Int32 { #if arch(wasm32) - let theme = String(unsafeUninitializedCapacity: Int(themeLen)) { b in - _swift_js_init_memory(themeBytes, b.baseAddress.unsafelyUnwrapped) - return Int(themeLen) - } - let ret = processTheme(_: Theme(rawValue: theme)!) + let ret = processTheme(_: Theme(rawValue: String.bridgeJSLiftParameter(themeBytes, themeLen))!) return Int32(ret.rawValue) #else fatalError("Only available on WebAssembly") @@ -743,15 +713,8 @@ public func _bjs_getTSDirection() -> Int32 { @_cdecl("bjs_setTSTheme") public func _bjs_setTSTheme(themeBytes: Int32, themeLen: Int32) -> Void { #if arch(wasm32) - let theme = String(unsafeUninitializedCapacity: Int(themeLen)) { b in - _swift_js_init_memory(themeBytes, b.baseAddress.unsafelyUnwrapped) - return Int(themeLen) - } - let ret = setTSTheme(_: TSTheme(rawValue: theme)!) - var rawValue = ret.rawValue - return rawValue.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = setTSTheme(_: TSTheme(rawValue: String.bridgeJSLiftParameter(themeBytes, themeLen))!) + return ret.rawValue.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -762,10 +725,7 @@ public func _bjs_setTSTheme(themeBytes: Int32, themeLen: Int32) -> Void { public func _bjs_getTSTheme() -> Void { #if arch(wasm32) let ret = getTSTheme() - var rawValue = ret.rawValue - return rawValue.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + return ret.rawValue.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -775,11 +735,7 @@ public func _bjs_getTSTheme() -> Void { @_cdecl("bjs_createPropertyHolder") public func _bjs_createPropertyHolder(intValue: Int32, floatValue: Float32, doubleValue: Float64, boolValue: Int32, stringValueBytes: Int32, stringValueLen: Int32, jsObject: Int32) -> UnsafeMutableRawPointer { #if arch(wasm32) - let stringValue = String(unsafeUninitializedCapacity: Int(stringValueLen)) { b in - _swift_js_init_memory(stringValueBytes, b.baseAddress.unsafelyUnwrapped) - return Int(stringValueLen) - } - let ret = createPropertyHolder(intValue: Int(intValue), floatValue: floatValue, doubleValue: doubleValue, boolValue: boolValue == 1, stringValue: stringValue, jsObject: JSObject(id: UInt32(bitPattern: jsObject))) + let ret = createPropertyHolder(intValue: Int.bridgeJSLiftParameter(intValue), floatValue: floatValue, doubleValue: doubleValue, boolValue: Bool.bridgeJSLiftParameter(boolValue), stringValue: String.bridgeJSLiftParameter(stringValueBytes, stringValueLen), jsObject: JSObject.bridgeJSLiftParameter(jsObject)) return Unmanaged.passRetained(ret).toOpaque() #else fatalError("Only available on WebAssembly") @@ -790,10 +746,8 @@ public func _bjs_createPropertyHolder(intValue: Int32, floatValue: Float32, doub @_cdecl("bjs_testPropertyHolder") public func _bjs_testPropertyHolder(holder: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - var ret = testPropertyHolder(holder: Unmanaged.fromOpaque(holder).takeUnretainedValue()) - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = testPropertyHolder(holder: Unmanaged.fromOpaque(holder).takeUnretainedValue()) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -813,10 +767,8 @@ public func _bjs_resetObserverCounts() -> Void { @_cdecl("bjs_getObserverStats") public func _bjs_getObserverStats() -> Void { #if arch(wasm32) - var ret = getObserverStats() - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = getObserverStats() + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -826,11 +778,7 @@ public func _bjs_getObserverStats() -> Void { @_cdecl("bjs_Greeter_init") public func _bjs_Greeter_init(nameBytes: Int32, nameLen: Int32) -> UnsafeMutableRawPointer { #if arch(wasm32) - let name = String(unsafeUninitializedCapacity: Int(nameLen)) { b in - _swift_js_init_memory(nameBytes, b.baseAddress.unsafelyUnwrapped) - return Int(nameLen) - } - let ret = Greeter(name: name) + let ret = Greeter(name: String.bridgeJSLiftParameter(nameBytes, nameLen)) return Unmanaged.passRetained(ret).toOpaque() #else fatalError("Only available on WebAssembly") @@ -841,10 +789,8 @@ public func _bjs_Greeter_init(nameBytes: Int32, nameLen: Int32) -> UnsafeMutable @_cdecl("bjs_Greeter_greet") public func _bjs_Greeter_greet(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - var ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().greet() - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().greet() + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -854,11 +800,7 @@ public func _bjs_Greeter_greet(_self: UnsafeMutableRawPointer) -> Void { @_cdecl("bjs_Greeter_changeName") public func _bjs_Greeter_changeName(_self: UnsafeMutableRawPointer, nameBytes: Int32, nameLen: Int32) -> Void { #if arch(wasm32) - let name = String(unsafeUninitializedCapacity: Int(nameLen)) { b in - _swift_js_init_memory(nameBytes, b.baseAddress.unsafelyUnwrapped) - return Int(nameLen) - } - Unmanaged.fromOpaque(_self).takeUnretainedValue().changeName(name: name) + Unmanaged.fromOpaque(_self).takeUnretainedValue().changeName(name: String.bridgeJSLiftParameter(nameBytes, nameLen)) #else fatalError("Only available on WebAssembly") #endif @@ -868,10 +810,8 @@ public func _bjs_Greeter_changeName(_self: UnsafeMutableRawPointer, nameBytes: I @_cdecl("bjs_Greeter_name_get") public func _bjs_Greeter_name_get(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - var ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().name - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().name + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -881,11 +821,7 @@ public func _bjs_Greeter_name_get(_self: UnsafeMutableRawPointer) -> Void { @_cdecl("bjs_Greeter_name_set") public func _bjs_Greeter_name_set(_self: UnsafeMutableRawPointer, valueBytes: Int32, valueLen: Int32) -> Void { #if arch(wasm32) - let value = String(unsafeUninitializedCapacity: Int(valueLen)) { b in - _swift_js_init_memory(valueBytes, b.baseAddress.unsafelyUnwrapped) - return Int(valueLen) - } - Unmanaged.fromOpaque(_self).takeUnretainedValue().name = value + Unmanaged.fromOpaque(_self).takeUnretainedValue().name = String.bridgeJSLiftParameter(valueBytes, valueLen) #else fatalError("Only available on WebAssembly") #endif @@ -895,10 +831,8 @@ public func _bjs_Greeter_name_set(_self: UnsafeMutableRawPointer, valueBytes: In @_cdecl("bjs_Greeter_prefix_get") public func _bjs_Greeter_prefix_get(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - var ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().prefix - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().prefix + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -922,7 +856,7 @@ extension Greeter: ConvertibleToJSValue { @_cdecl("bjs_Calculator_square") public func _bjs_Calculator_square(_self: UnsafeMutableRawPointer, value: Int32) -> Int32 { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().square(value: Int(value)) + let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().square(value: Int.bridgeJSLiftParameter(value)) return Int32(ret) #else fatalError("Only available on WebAssembly") @@ -933,7 +867,7 @@ public func _bjs_Calculator_square(_self: UnsafeMutableRawPointer, value: Int32) @_cdecl("bjs_Calculator_add") public func _bjs_Calculator_add(_self: UnsafeMutableRawPointer, a: Int32, b: Int32) -> Int32 { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().add(a: Int(a), b: Int(b)) + let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().add(a: Int.bridgeJSLiftParameter(a), b: Int.bridgeJSLiftParameter(b)) return Int32(ret) #else fatalError("Only available on WebAssembly") @@ -969,10 +903,8 @@ public func _bjs_Converter_init() -> UnsafeMutableRawPointer { @_cdecl("bjs_Converter_toString") public func _bjs_Converter_toString(_self: UnsafeMutableRawPointer, value: Int32) -> Void { #if arch(wasm32) - var ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().toString(value: Int(value)) - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().toString(value: Int.bridgeJSLiftParameter(value)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -1066,7 +998,7 @@ extension Internal.TestServer: ConvertibleToJSValue { @_cdecl("bjs_SimplePropertyHolder_init") public func _bjs_SimplePropertyHolder_init(value: Int32) -> UnsafeMutableRawPointer { #if arch(wasm32) - let ret = SimplePropertyHolder(value: Int(value)) + let ret = SimplePropertyHolder(value: Int.bridgeJSLiftParameter(value)) return Unmanaged.passRetained(ret).toOpaque() #else fatalError("Only available on WebAssembly") @@ -1088,7 +1020,7 @@ public func _bjs_SimplePropertyHolder_value_get(_self: UnsafeMutableRawPointer) @_cdecl("bjs_SimplePropertyHolder_value_set") public func _bjs_SimplePropertyHolder_value_set(_self: UnsafeMutableRawPointer, value: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().value = Int(value) + Unmanaged.fromOpaque(_self).takeUnretainedValue().value = Int.bridgeJSLiftParameter(value) #else fatalError("Only available on WebAssembly") #endif @@ -1112,11 +1044,7 @@ extension SimplePropertyHolder: ConvertibleToJSValue { @_cdecl("bjs_PropertyHolder_init") public func _bjs_PropertyHolder_init(intValue: Int32, floatValue: Float32, doubleValue: Float64, boolValue: Int32, stringValueBytes: Int32, stringValueLen: Int32, jsObject: Int32, sibling: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer { #if arch(wasm32) - let stringValue = String(unsafeUninitializedCapacity: Int(stringValueLen)) { b in - _swift_js_init_memory(stringValueBytes, b.baseAddress.unsafelyUnwrapped) - return Int(stringValueLen) - } - let ret = PropertyHolder(intValue: Int(intValue), floatValue: floatValue, doubleValue: doubleValue, boolValue: boolValue == 1, stringValue: stringValue, jsObject: JSObject(id: UInt32(bitPattern: jsObject)), sibling: Unmanaged.fromOpaque(sibling).takeUnretainedValue()) + let ret = PropertyHolder(intValue: Int.bridgeJSLiftParameter(intValue), floatValue: floatValue, doubleValue: doubleValue, boolValue: Bool.bridgeJSLiftParameter(boolValue), stringValue: String.bridgeJSLiftParameter(stringValueBytes, stringValueLen), jsObject: JSObject.bridgeJSLiftParameter(jsObject), sibling: Unmanaged.fromOpaque(sibling).takeUnretainedValue()) return Unmanaged.passRetained(ret).toOpaque() #else fatalError("Only available on WebAssembly") @@ -1127,10 +1055,8 @@ public func _bjs_PropertyHolder_init(intValue: Int32, floatValue: Float32, doubl @_cdecl("bjs_PropertyHolder_getAllValues") public func _bjs_PropertyHolder_getAllValues(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - var ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().getAllValues() - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().getAllValues() + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -1151,7 +1077,7 @@ public func _bjs_PropertyHolder_intValue_get(_self: UnsafeMutableRawPointer) -> @_cdecl("bjs_PropertyHolder_intValue_set") public func _bjs_PropertyHolder_intValue_set(_self: UnsafeMutableRawPointer, value: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().intValue = Int(value) + Unmanaged.fromOpaque(_self).takeUnretainedValue().intValue = Int.bridgeJSLiftParameter(value) #else fatalError("Only available on WebAssembly") #endif @@ -1204,7 +1130,7 @@ public func _bjs_PropertyHolder_doubleValue_set(_self: UnsafeMutableRawPointer, public func _bjs_PropertyHolder_boolValue_get(_self: UnsafeMutableRawPointer) -> Int32 { #if arch(wasm32) let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().boolValue - return Int32(ret ? 1 : 0) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -1214,7 +1140,7 @@ public func _bjs_PropertyHolder_boolValue_get(_self: UnsafeMutableRawPointer) -> @_cdecl("bjs_PropertyHolder_boolValue_set") public func _bjs_PropertyHolder_boolValue_set(_self: UnsafeMutableRawPointer, value: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().boolValue = value == 1 + Unmanaged.fromOpaque(_self).takeUnretainedValue().boolValue = Bool.bridgeJSLiftParameter(value) #else fatalError("Only available on WebAssembly") #endif @@ -1224,10 +1150,8 @@ public func _bjs_PropertyHolder_boolValue_set(_self: UnsafeMutableRawPointer, va @_cdecl("bjs_PropertyHolder_stringValue_get") public func _bjs_PropertyHolder_stringValue_get(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - var ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().stringValue - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().stringValue + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -1237,11 +1161,7 @@ public func _bjs_PropertyHolder_stringValue_get(_self: UnsafeMutableRawPointer) @_cdecl("bjs_PropertyHolder_stringValue_set") public func _bjs_PropertyHolder_stringValue_set(_self: UnsafeMutableRawPointer, valueBytes: Int32, valueLen: Int32) -> Void { #if arch(wasm32) - let value = String(unsafeUninitializedCapacity: Int(valueLen)) { b in - _swift_js_init_memory(valueBytes, b.baseAddress.unsafelyUnwrapped) - return Int(valueLen) - } - Unmanaged.fromOpaque(_self).takeUnretainedValue().stringValue = value + Unmanaged.fromOpaque(_self).takeUnretainedValue().stringValue = String.bridgeJSLiftParameter(valueBytes, valueLen) #else fatalError("Only available on WebAssembly") #endif @@ -1285,7 +1205,7 @@ public func _bjs_PropertyHolder_readonlyDouble_get(_self: UnsafeMutableRawPointe public func _bjs_PropertyHolder_readonlyBool_get(_self: UnsafeMutableRawPointer) -> Int32 { #if arch(wasm32) let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().readonlyBool - return Int32(ret ? 1 : 0) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -1295,10 +1215,8 @@ public func _bjs_PropertyHolder_readonlyBool_get(_self: UnsafeMutableRawPointer) @_cdecl("bjs_PropertyHolder_readonlyString_get") public func _bjs_PropertyHolder_readonlyString_get(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - var ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().readonlyString - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().readonlyString + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -1309,7 +1227,7 @@ public func _bjs_PropertyHolder_readonlyString_get(_self: UnsafeMutableRawPointe public func _bjs_PropertyHolder_jsObject_get(_self: UnsafeMutableRawPointer) -> Int32 { #if arch(wasm32) let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().jsObject - return _swift_js_retain(Int32(bitPattern: ret.id)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -1319,7 +1237,7 @@ public func _bjs_PropertyHolder_jsObject_get(_self: UnsafeMutableRawPointer) -> @_cdecl("bjs_PropertyHolder_jsObject_set") public func _bjs_PropertyHolder_jsObject_set(_self: UnsafeMutableRawPointer, value: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().jsObject = JSObject(id: UInt32(bitPattern: value)) + Unmanaged.fromOpaque(_self).takeUnretainedValue().jsObject = JSObject.bridgeJSLiftParameter(value) #else fatalError("Only available on WebAssembly") #endif @@ -1350,10 +1268,8 @@ public func _bjs_PropertyHolder_sibling_set(_self: UnsafeMutableRawPointer, valu @_cdecl("bjs_PropertyHolder_lazyValue_get") public func _bjs_PropertyHolder_lazyValue_get(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - var ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().lazyValue - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().lazyValue + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -1363,11 +1279,7 @@ public func _bjs_PropertyHolder_lazyValue_get(_self: UnsafeMutableRawPointer) -> @_cdecl("bjs_PropertyHolder_lazyValue_set") public func _bjs_PropertyHolder_lazyValue_set(_self: UnsafeMutableRawPointer, valueBytes: Int32, valueLen: Int32) -> Void { #if arch(wasm32) - let value = String(unsafeUninitializedCapacity: Int(valueLen)) { b in - _swift_js_init_memory(valueBytes, b.baseAddress.unsafelyUnwrapped) - return Int(valueLen) - } - Unmanaged.fromOpaque(_self).takeUnretainedValue().lazyValue = value + Unmanaged.fromOpaque(_self).takeUnretainedValue().lazyValue = String.bridgeJSLiftParameter(valueBytes, valueLen) #else fatalError("Only available on WebAssembly") #endif @@ -1388,10 +1300,8 @@ public func _bjs_PropertyHolder_computedReadonly_get(_self: UnsafeMutableRawPoin @_cdecl("bjs_PropertyHolder_computedReadWrite_get") public func _bjs_PropertyHolder_computedReadWrite_get(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - var ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().computedReadWrite - return ret.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) - } + let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().computedReadWrite + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -1401,11 +1311,7 @@ public func _bjs_PropertyHolder_computedReadWrite_get(_self: UnsafeMutableRawPoi @_cdecl("bjs_PropertyHolder_computedReadWrite_set") public func _bjs_PropertyHolder_computedReadWrite_set(_self: UnsafeMutableRawPointer, valueBytes: Int32, valueLen: Int32) -> Void { #if arch(wasm32) - let value = String(unsafeUninitializedCapacity: Int(valueLen)) { b in - _swift_js_init_memory(valueBytes, b.baseAddress.unsafelyUnwrapped) - return Int(valueLen) - } - Unmanaged.fromOpaque(_self).takeUnretainedValue().computedReadWrite = value + Unmanaged.fromOpaque(_self).takeUnretainedValue().computedReadWrite = String.bridgeJSLiftParameter(valueBytes, valueLen) #else fatalError("Only available on WebAssembly") #endif @@ -1426,7 +1332,7 @@ public func _bjs_PropertyHolder_observedProperty_get(_self: UnsafeMutableRawPoin @_cdecl("bjs_PropertyHolder_observedProperty_set") public func _bjs_PropertyHolder_observedProperty_set(_self: UnsafeMutableRawPointer, value: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().observedProperty = Int(value) + Unmanaged.fromOpaque(_self).takeUnretainedValue().observedProperty = Int.bridgeJSLiftParameter(value) #else fatalError("Only available on WebAssembly") #endif diff --git a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ImportTS.swift b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ImportTS.swift index 255853fa..733a085f 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ImportTS.swift +++ b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ImportTS.swift @@ -46,11 +46,11 @@ func jsRoundTripBool(_ v: Bool) throws(JSException) -> Bool { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_jsRoundTripBool(Int32(v ? 1 : 0)) + let ret = bjs_jsRoundTripBool(v.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } - return ret == 1 + return Bool.bridgeJSLiftReturn(ret) } func jsRoundTripString(_ v: String) throws(JSException) -> String { @@ -62,18 +62,11 @@ func jsRoundTripString(_ v: String) throws(JSException) -> String { fatalError("Only available on WebAssembly") } #endif - var v = v - let vId = v.withUTF8 { b in - _swift_js_make_js_string(b.baseAddress.unsafelyUnwrapped, Int32(b.count)) - } - let ret = bjs_jsRoundTripString(vId) + let ret = bjs_jsRoundTripString(v.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } - return String(unsafeUninitializedCapacity: Int(ret)) { b in - _swift_js_init_memory_with_result(b.baseAddress.unsafelyUnwrapped, Int32(ret)) - return Int(ret) - } + return String.bridgeJSLiftReturn(ret) } func jsThrowOrVoid(_ shouldThrow: Bool) throws(JSException) -> Void { @@ -85,7 +78,7 @@ func jsThrowOrVoid(_ shouldThrow: Bool) throws(JSException) -> Void { fatalError("Only available on WebAssembly") } #endif - bjs_jsThrowOrVoid(Int32(shouldThrow ? 1 : 0)) + bjs_jsThrowOrVoid(shouldThrow.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -100,7 +93,7 @@ func jsThrowOrNumber(_ shouldThrow: Bool) throws(JSException) -> Double { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_jsThrowOrNumber(Int32(shouldThrow ? 1 : 0)) + let ret = bjs_jsThrowOrNumber(shouldThrow.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -116,11 +109,11 @@ func jsThrowOrBool(_ shouldThrow: Bool) throws(JSException) -> Bool { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_jsThrowOrBool(Int32(shouldThrow ? 1 : 0)) + let ret = bjs_jsThrowOrBool(shouldThrow.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } - return ret == 1 + return Bool.bridgeJSLiftReturn(ret) } func jsThrowOrString(_ shouldThrow: Bool) throws(JSException) -> String { @@ -132,14 +125,11 @@ func jsThrowOrString(_ shouldThrow: Bool) throws(JSException) -> String { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_jsThrowOrString(Int32(shouldThrow ? 1 : 0)) + let ret = bjs_jsThrowOrString(shouldThrow.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } - return String(unsafeUninitializedCapacity: Int(ret)) { b in - _swift_js_init_memory_with_result(b.baseAddress.unsafelyUnwrapped, Int32(ret)) - return Int(ret) - } + return String.bridgeJSLiftReturn(ret) } func runAsyncWorks() throws(JSException) -> JSPromise { @@ -178,15 +168,7 @@ struct JsGreeter { fatalError("Only available on WebAssembly") } #endif - var name = name - let nameId = name.withUTF8 { b in - _swift_js_make_js_string(b.baseAddress.unsafelyUnwrapped, Int32(b.count)) - } - var prefix = prefix - let prefixId = prefix.withUTF8 { b in - _swift_js_make_js_string(b.baseAddress.unsafelyUnwrapped, Int32(b.count)) - } - let ret = bjs_JsGreeter_init(nameId, prefixId) + let ret = bjs_JsGreeter_init(name.bridgeJSLowerParameter(), prefix.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -203,14 +185,11 @@ struct JsGreeter { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_JsGreeter_name_get(Int32(bitPattern: self.this.id)) + let ret = bjs_JsGreeter_name_get(self.this.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } - return String(unsafeUninitializedCapacity: Int(ret)) { b in - _swift_js_init_memory_with_result(b.baseAddress.unsafelyUnwrapped, Int32(ret)) - return Int(ret) - } + return String.bridgeJSLiftReturn(ret) } } @@ -223,11 +202,7 @@ struct JsGreeter { fatalError("Only available on WebAssembly") } #endif - var newValue = newValue - let newValueId = newValue.withUTF8 { b in - _swift_js_make_js_string(b.baseAddress.unsafelyUnwrapped, Int32(b.count)) - } - bjs_JsGreeter_name_set(Int32(bitPattern: self.this.id), newValueId) + bjs_JsGreeter_name_set(self.this.bridgeJSLowerParameter(), newValue.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -243,14 +218,11 @@ struct JsGreeter { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_JsGreeter_prefix_get(Int32(bitPattern: self.this.id)) + let ret = bjs_JsGreeter_prefix_get(self.this.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } - return String(unsafeUninitializedCapacity: Int(ret)) { b in - _swift_js_init_memory_with_result(b.baseAddress.unsafelyUnwrapped, Int32(ret)) - return Int(ret) - } + return String.bridgeJSLiftReturn(ret) } } @@ -263,14 +235,11 @@ struct JsGreeter { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_JsGreeter_greet(Int32(bitPattern: self.this.id)) + let ret = bjs_JsGreeter_greet(self.this.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } - return String(unsafeUninitializedCapacity: Int(ret)) { b in - _swift_js_init_memory_with_result(b.baseAddress.unsafelyUnwrapped, Int32(ret)) - return Int(ret) - } + return String.bridgeJSLiftReturn(ret) } func changeName(_ name: String) throws(JSException) -> Void { @@ -282,11 +251,7 @@ struct JsGreeter { fatalError("Only available on WebAssembly") } #endif - var name = name - let nameId = name.withUTF8 { b in - _swift_js_make_js_string(b.baseAddress.unsafelyUnwrapped, Int32(b.count)) - } - bjs_JsGreeter_changeName(Int32(bitPattern: self.this.id), nameId) + bjs_JsGreeter_changeName(self.this.bridgeJSLowerParameter(), name.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } From 0df766ef91d4de35bf402130908f26f853b4fd62 Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sat, 23 Aug 2025 21:42:53 +0900 Subject: [PATCH 2/8] ExportSwift: Remove unused className variable Clean up variable declaration in VariableDeclSyntax visitor. --- Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift index f170c03d..e3c1a1c8 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift @@ -334,7 +334,7 @@ public class ExportSwift { override func visit(_ node: VariableDeclSyntax) -> SyntaxVisitorContinueKind { guard node.attributes.hasJSAttribute() else { return .skipChildren } - guard case .classBody(let className, let classKey) = state else { + guard case .classBody(_, let classKey) = state else { diagnose(node: node, message: "@JS var must be inside a @JS class") return .skipChildren } From e5465823345cf0d535a33596380b549fe87f4b24 Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sat, 23 Aug 2025 23:07:05 +0900 Subject: [PATCH 3/8] BridgeJS: Add protocol-based intrinsic system Introduce _BridgedSwiftTypeLoweredIntoSingleWasmCoreType protocol to formalize lift/lower operations. All basic types (Bool, Int, Float, Double) now conform to this protocol with standardized bridgeJS* methods. Add _BridgedSwiftHeapObject and _BridgedSwiftEnumNoPayload protocols for heap objects and enums respectively. Update generated code and test snapshots to use new protocol-based intrinsic functions. --- .../Generated/BridgeJS.ExportSwift.swift | 32 +- .../Sources/BridgeJSCore/ExportSwift.swift | 342 ++++++++------- .../Sources/BridgeJSCore/ImportTS.swift | 9 +- .../Sources/BridgeJSCore/Utilities.swift | 6 + .../BridgeJSSkeleton/BridgeJSSkeleton.swift | 2 +- .../ExportSwiftTests/Async.swift | 8 +- .../ExportSwiftTests/EnumCase.swift | 63 ++- .../ExportSwiftTests/EnumNamespace.swift | 79 +++- .../ExportSwiftTests/EnumRawType.swift | 116 ++++-- .../ExportSwiftTests/Namespaces.swift | 38 +- .../PrimitiveParameters.swift | 2 +- .../ExportSwiftTests/PrimitiveReturn.swift | 6 +- .../ExportSwiftTests/PropertyTypes.swift | 100 ++--- .../ExportSwiftTests/StringParameter.swift | 4 +- .../ExportSwiftTests/SwiftClass.swift | 28 +- .../JavaScriptKit/BridgeJSInstrincics.swift | 121 +++++- .../Generated/BridgeJS.ExportSwift.swift | 391 ++++++++++++------ .../WebWorkerDedicatedExecutorTests.swift | 1 + 18 files changed, 870 insertions(+), 478 deletions(-) create mode 100644 Plugins/BridgeJS/Sources/BridgeJSCore/Utilities.swift diff --git a/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/BridgeJS.ExportSwift.swift b/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/BridgeJS.ExportSwift.swift index 5deb14b9..9e4515f5 100644 --- a/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/BridgeJS.ExportSwift.swift +++ b/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/BridgeJS.ExportSwift.swift @@ -11,7 +11,7 @@ public func _bjs_PlayBridgeJS_init() -> UnsafeMutableRawPointer { #if arch(wasm32) let ret = PlayBridgeJS() - return Unmanaged.passRetained(ret).toOpaque() + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -19,11 +19,11 @@ public func _bjs_PlayBridgeJS_init() -> UnsafeMutableRawPointer { @_expose(wasm, "bjs_PlayBridgeJS_update") @_cdecl("bjs_PlayBridgeJS_update") -public func _bjs_PlayBridgeJS_update(_self: UnsafeMutableRawPointer, swiftSourceBytes: Int32, swiftSourceLen: Int32, dtsSourceBytes: Int32, dtsSourceLen: Int32) -> UnsafeMutableRawPointer { +public func _bjs_PlayBridgeJS_update(_self: UnsafeMutableRawPointer, swiftSourceBytes: Int32, swiftSourceLength: Int32, dtsSourceBytes: Int32, dtsSourceLength: Int32) -> UnsafeMutableRawPointer { #if arch(wasm32) do { - let ret = try Unmanaged.fromOpaque(_self).takeUnretainedValue().update(swiftSource: String.bridgeJSLiftParameter(swiftSourceBytes, swiftSourceLen), dtsSource: String.bridgeJSLiftParameter(dtsSourceBytes, dtsSourceLen)) - return Unmanaged.passRetained(ret).toOpaque() + let ret = try PlayBridgeJS.bridgeJSLiftParameter(_self).update(swiftSource: String.bridgeJSLiftParameter(swiftSourceBytes, swiftSourceLength), dtsSource: String.bridgeJSLiftParameter(dtsSourceBytes, dtsSourceLength)) + return ret.bridgeJSLowerReturn() } catch let error { if let error = error.thrownValue.object { withExtendedLifetime(error) { @@ -48,10 +48,16 @@ public func _bjs_PlayBridgeJS_deinit(pointer: UnsafeMutableRawPointer) { Unmanaged.fromOpaque(pointer).release() } -extension PlayBridgeJS: ConvertibleToJSValue { +extension PlayBridgeJS: ConvertibleToJSValue, _BridgedSwiftHeapObject { var jsValue: JSValue { + #if arch(wasm32) @_extern(wasm, module: "PlayBridgeJS", name: "bjs_PlayBridgeJS_wrap") func _bjs_PlayBridgeJS_wrap(_: UnsafeMutableRawPointer) -> Int32 + #else + func _bjs_PlayBridgeJS_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") + } + #endif return .object(JSObject(id: UInt32(bitPattern: _bjs_PlayBridgeJS_wrap(Unmanaged.passRetained(self).toOpaque())))) } } @@ -60,7 +66,7 @@ extension PlayBridgeJS: ConvertibleToJSValue { @_cdecl("bjs_PlayBridgeJSOutput_outputJs") public func _bjs_PlayBridgeJSOutput_outputJs(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().outputJs() + let ret = PlayBridgeJSOutput.bridgeJSLiftParameter(_self).outputJs() return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -71,7 +77,7 @@ public func _bjs_PlayBridgeJSOutput_outputJs(_self: UnsafeMutableRawPointer) -> @_cdecl("bjs_PlayBridgeJSOutput_outputDts") public func _bjs_PlayBridgeJSOutput_outputDts(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().outputDts() + let ret = PlayBridgeJSOutput.bridgeJSLiftParameter(_self).outputDts() return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -82,7 +88,7 @@ public func _bjs_PlayBridgeJSOutput_outputDts(_self: UnsafeMutableRawPointer) -> @_cdecl("bjs_PlayBridgeJSOutput_importSwiftGlue") public func _bjs_PlayBridgeJSOutput_importSwiftGlue(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().importSwiftGlue() + let ret = PlayBridgeJSOutput.bridgeJSLiftParameter(_self).importSwiftGlue() return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -93,7 +99,7 @@ public func _bjs_PlayBridgeJSOutput_importSwiftGlue(_self: UnsafeMutableRawPoint @_cdecl("bjs_PlayBridgeJSOutput_exportSwiftGlue") public func _bjs_PlayBridgeJSOutput_exportSwiftGlue(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().exportSwiftGlue() + let ret = PlayBridgeJSOutput.bridgeJSLiftParameter(_self).exportSwiftGlue() return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -106,10 +112,16 @@ public func _bjs_PlayBridgeJSOutput_deinit(pointer: UnsafeMutableRawPointer) { Unmanaged.fromOpaque(pointer).release() } -extension PlayBridgeJSOutput: ConvertibleToJSValue { +extension PlayBridgeJSOutput: ConvertibleToJSValue, _BridgedSwiftHeapObject { var jsValue: JSValue { + #if arch(wasm32) @_extern(wasm, module: "PlayBridgeJS", name: "bjs_PlayBridgeJSOutput_wrap") func _bjs_PlayBridgeJSOutput_wrap(_: UnsafeMutableRawPointer) -> Int32 + #else + func _bjs_PlayBridgeJSOutput_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") + } + #endif return .object(JSObject(id: UInt32(bitPattern: _bjs_PlayBridgeJSOutput_wrap(Unmanaged.passRetained(self).toOpaque())))) } } \ No newline at end of file diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift index e3c1a1c8..cefb334f 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift @@ -51,7 +51,7 @@ public class ExportSwift { /// - Returns: A tuple containing the generated Swift code and a skeleton /// describing the exported APIs public func finalize() throws -> (outputSwift: String, outputSkeleton: ExportedSkeleton)? { - guard let outputSwift = renderSwiftGlue() else { + guard let outputSwift = try renderSwiftGlue() else { return nil } return ( @@ -710,22 +710,26 @@ public class ExportSwift { @_spi(BridgeJS) import JavaScriptKit """ - func renderSwiftGlue() -> String? { + func renderSwiftGlue() throws -> String? { var decls: [DeclSyntax] = [] guard exportedFunctions.count > 0 || exportedClasses.count > 0 || exportedEnums.count > 0 else { return nil } decls.append(Self.prelude) - for enumDef in exportedEnums where enumDef.enumType == .simple { - decls.append(renderCaseEnumHelpers(enumDef)) + for enumDef in exportedEnums { + if enumDef.enumType == .simple { + decls.append(renderCaseEnumHelpers(enumDef)) + } else { + decls.append("extension \(raw: enumDef.swiftCallName): _BridgedSwiftEnumNoPayload {}") + } } for function in exportedFunctions { - decls.append(renderSingleExportedFunction(function: function)) + decls.append(try renderSingleExportedFunction(function: function)) } for klass in exportedClasses { - decls.append(contentsOf: renderSingleExportedClass(klass: klass)) + decls.append(contentsOf: try renderSingleExportedClass(klass: klass)) } let format = BasicFormat() return decls.map { $0.formatted(using: format).description }.joined(separator: "\n\n") @@ -746,11 +750,24 @@ public class ExportSwift { return """ extension \(raw: typeName) { - init?(bridgeJSRawValue: Int32) { + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + return bridgeJSRawValue + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Int32) -> \(raw: typeName) { + return \(raw: typeName)(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Int32) -> \(raw: typeName) { + return \(raw: typeName)(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Int32 { + return bridgeJSRawValue + } + + private init?(bridgeJSRawValue: Int32) { \(raw: initSwitch) } - var bridgeJSRawValue: Int32 { + private var bridgeJSRawValue: Int32 { \(raw: valueSwitch) } } @@ -778,87 +795,22 @@ public class ExportSwift { self.body.append(item) } - func liftParameter(param: Parameter) { + func liftParameter(param: Parameter) throws { parameters.append(param) - switch param.type { - case .bool: - liftedParameterExprs.append( - ExprSyntax("\(raw: param.type.swiftType).bridgeJSLiftParameter(\(raw: param.name))") - ) - abiParameterSignatures.append((param.name, .i32)) - case .int: - liftedParameterExprs.append( - ExprSyntax("\(raw: param.type.swiftType).bridgeJSLiftParameter(\(raw: param.name))") - ) - abiParameterSignatures.append((param.name, .i32)) - case .float: - liftedParameterExprs.append(ExprSyntax("\(raw: param.name)")) - abiParameterSignatures.append((param.name, .f32)) - case .double: - liftedParameterExprs.append(ExprSyntax("\(raw: param.name)")) - abiParameterSignatures.append((param.name, .f64)) - case .string: - let bytesLabel = "\(param.name)Bytes" - let lengthLabel = "\(param.name)Len" - liftedParameterExprs.append( - ExprSyntax( - "\(raw: param.type.swiftType).bridgeJSLiftParameter(\(raw: bytesLabel), \(raw: lengthLabel))" - ) - ) - abiParameterSignatures.append((bytesLabel, .i32)) - abiParameterSignatures.append((lengthLabel, .i32)) - case .caseEnum(let enumName): - liftedParameterExprs.append(ExprSyntax("\(raw: enumName)(bridgeJSRawValue: \(raw: param.name))!")) - abiParameterSignatures.append((param.name, .i32)) - case .rawValueEnum(let enumName, let rawType): - if rawType == .string { - let bytesLabel = "\(param.name)Bytes" - let lengthLabel = "\(param.name)Len" - liftedParameterExprs.append( - ExprSyntax( - "\(raw: enumName)(rawValue: String.bridgeJSLiftParameter(\(raw: bytesLabel), \(raw: lengthLabel)))!" - ) - ) - abiParameterSignatures.append((bytesLabel, .i32)) - abiParameterSignatures.append((lengthLabel, .i32)) - } else { - let conversionExpr: String - switch rawType { - case .bool: - conversionExpr = - "\(enumName)(rawValue: \(param.type.swiftType).bridgeJSLiftParameter(\(param.name)))" - case .uint, .uint32, .uint64: - if rawType == .uint64 { - conversionExpr = - "\(enumName)(rawValue: \(rawType.rawValue)(bitPattern: Int64(\(param.name))))!" - } else { - conversionExpr = "\(enumName)(rawValue: \(rawType.rawValue)(bitPattern: \(param.name)))!" - } - default: - conversionExpr = "\(enumName)(rawValue: \(rawType.rawValue)(\(param.name)))!" - } - - liftedParameterExprs.append(ExprSyntax(stringLiteral: conversionExpr)) - if let wasmType = rawType.wasmCoreType { - abiParameterSignatures.append((param.name, wasmType)) - } - } - case .associatedValueEnum(_): - break - case .namespaceEnum: - break - case .jsObject(let name): - liftedParameterExprs.append( - ExprSyntax("\(raw: name ?? "JSObject").bridgeJSLiftParameter(\(raw: param.name))") + let liftingInfo = try param.type.liftParameterInfo() + let argumentsToLift: [String] + if liftingInfo.parameters.count == 1 { + argumentsToLift = [param.name] + } else { + argumentsToLift = liftingInfo.parameters.map { (name, _) in param.name + name.capitalizedFirstLetter } + } + liftedParameterExprs.append( + ExprSyntax( + "\(raw: param.type.swiftType).bridgeJSLiftParameter(\(raw: argumentsToLift.joined(separator: ", ")))" ) - abiParameterSignatures.append((param.name, .i32)) - case .swiftHeapObject: - let objectExpr: ExprSyntax = - "Unmanaged<\(raw: param.type.swiftType)>.fromOpaque(\(raw: param.name)).takeUnretainedValue()" - liftedParameterExprs.append(objectExpr) - abiParameterSignatures.append((param.name, .pointer)) - case .void: - break + ) + for (name, type) in zip(argumentsToLift, liftingInfo.parameters.map { $0.type }) { + abiParameterSignatures.append((name, type)) } } @@ -928,97 +880,28 @@ public class ExportSwift { append("\(raw: selfExpr).\(raw: propertyName) = \(raw: newValueExpr)") } - func lowerReturnValue(returnType: BridgeType) { + func lowerReturnValue(returnType: BridgeType) throws { if effects.isAsync { // Async functions always return a Promise, which is a JSObject - _lowerReturnValue(returnType: .jsObject(nil)) + try _lowerReturnValue(returnType: .jsObject(nil)) } else { - _lowerReturnValue(returnType: returnType) + try _lowerReturnValue(returnType: returnType) } } - private func _lowerReturnValue(returnType: BridgeType) { - switch returnType { - case .void: - abiReturnType = nil - case .bool: - abiReturnType = .i32 - case .int: - abiReturnType = .i32 - case .float: - abiReturnType = .f32 - case .double: - abiReturnType = .f64 - case .string: - abiReturnType = nil - case .jsObject: - abiReturnType = .i32 - case .swiftHeapObject: - // UnsafeMutableRawPointer is returned as an i32 pointer - abiReturnType = .pointer - case .caseEnum: - abiReturnType = .i32 - case .rawValueEnum(_, let rawType): - abiReturnType = rawType == .string ? nil : rawType.wasmCoreType - case .associatedValueEnum: - abiReturnType = nil - case .namespaceEnum: - abiReturnType = nil + private func _lowerReturnValue(returnType: BridgeType) throws { + let loweringInfo = try returnType.loweringReturnInfo() + abiReturnType = loweringInfo.returnType + if returnType == .void { + return } - if effects.isAsync { // The return value of async function (T of `(...) async -> T`) is // handled by the JSPromise.async, so we don't need to do anything here. return } - switch returnType { - case .void: break - case .int, .float, .double: - append("return \(raw: abiReturnType!.swiftType)(ret)") - case .bool: - append("return ret.bridgeJSLowerReturn()") - case .string: - append("return ret.bridgeJSLowerReturn()") - case .caseEnum: - abiReturnType = .i32 - append("return ret.bridgeJSRawValue") - case .rawValueEnum(_, let rawType): - if rawType == .string { - append( - """ - return ret.rawValue.bridgeJSLowerReturn() - """ - ) - } else { - switch rawType { - case .bool: - append("return Int32(ret.rawValue ? 1 : 0)") - case .int, .int32, .uint, .uint32: - append("return Int32(ret.rawValue)") - case .int64, .uint64: - append("return Int64(ret.rawValue)") - case .float: - append("return Float32(ret.rawValue)") - case .double: - append("return Float64(ret.rawValue)") - default: - append("return Int32(ret.rawValue)") - } - } - case .associatedValueEnum: break; - case .namespaceEnum: break; - case .jsObject: - append("return ret.bridgeJSLowerReturn()") - case .swiftHeapObject: - // Perform a manual retain on the object, which will be balanced by a - // release called via FinalizationRegistry - append( - """ - return Unmanaged.passRetained(ret).toOpaque() - """ - ) - } + append("return ret.bridgeJSLowerReturn()") } func render(abiName: String) -> DeclSyntax { @@ -1088,13 +971,13 @@ public class ExportSwift { } } - func renderSingleExportedFunction(function: ExportedFunction) -> DeclSyntax { + func renderSingleExportedFunction(function: ExportedFunction) throws -> DeclSyntax { let builder = ExportedThunkBuilder(effects: function.effects) for param in function.parameters { - builder.liftParameter(param: param) + try builder.liftParameter(param: param) } builder.call(name: function.name, returnType: function.returnType) - builder.lowerReturnValue(returnType: function.returnType) + try builder.lowerReturnValue(returnType: function.returnType) return builder.render(abiName: function.abiName) } @@ -1145,32 +1028,32 @@ public class ExportSwift { /// Unmanaged.fromOpaque(pointer).release() /// } /// ``` - func renderSingleExportedClass(klass: ExportedClass) -> [DeclSyntax] { + func renderSingleExportedClass(klass: ExportedClass) throws -> [DeclSyntax] { var decls: [DeclSyntax] = [] if let constructor = klass.constructor { let builder = ExportedThunkBuilder(effects: constructor.effects) for param in constructor.parameters { - builder.liftParameter(param: param) + try builder.liftParameter(param: param) } builder.call(name: klass.swiftCallName, returnType: BridgeType.swiftHeapObject(klass.name)) - builder.lowerReturnValue(returnType: BridgeType.swiftHeapObject(klass.name)) + try builder.lowerReturnValue(returnType: BridgeType.swiftHeapObject(klass.name)) decls.append(builder.render(abiName: constructor.abiName)) } for method in klass.methods { let builder = ExportedThunkBuilder(effects: method.effects) - builder.liftParameter( + try builder.liftParameter( param: Parameter(label: nil, name: "_self", type: BridgeType.swiftHeapObject(klass.swiftCallName)) ) for param in method.parameters { - builder.liftParameter(param: param) + try builder.liftParameter(param: param) } builder.callMethod( klassName: klass.swiftCallName, methodName: method.name, returnType: method.returnType ) - builder.lowerReturnValue(returnType: method.returnType) + try builder.lowerReturnValue(returnType: method.returnType) decls.append(builder.render(abiName: method.abiName)) } @@ -1178,7 +1061,7 @@ public class ExportSwift { for property in klass.properties { // Generate getter let getterBuilder = ExportedThunkBuilder(effects: Effects(isAsync: false, isThrows: false)) - getterBuilder.liftParameter( + try getterBuilder.liftParameter( param: Parameter(label: nil, name: "_self", type: .swiftHeapObject(klass.name)) ) getterBuilder.callPropertyGetter( @@ -1186,23 +1069,23 @@ public class ExportSwift { propertyName: property.name, returnType: property.type ) - getterBuilder.lowerReturnValue(returnType: property.type) + try getterBuilder.lowerReturnValue(returnType: property.type) decls.append(getterBuilder.render(abiName: property.getterAbiName(className: klass.name))) // Generate setter if property is not readonly if !property.isReadonly { let setterBuilder = ExportedThunkBuilder(effects: Effects(isAsync: false, isThrows: false)) - setterBuilder.liftParameter( + try setterBuilder.liftParameter( param: Parameter(label: nil, name: "_self", type: .swiftHeapObject(klass.name)) ) - setterBuilder.liftParameter( + try setterBuilder.liftParameter( param: Parameter(label: "value", name: "value", type: property.type) ) setterBuilder.callPropertySetter( klassName: klass.name, propertyName: property.name ) - setterBuilder.lowerReturnValue(returnType: .void) + try setterBuilder.lowerReturnValue(returnType: .void) decls.append(setterBuilder.render(abiName: property.setterAbiName(className: klass.name))) } } @@ -1232,7 +1115,7 @@ public class ExportSwift { /// For a class named `Greeter`, this generates: /// /// ```swift - /// extension Greeter: ConvertibleToJSValue { + /// extension Greeter: ConvertibleToJSValue, _BridgedSwiftHeapObject { /// var jsValue: JSValue { /// @_extern(wasm, module: "MyModule", name: "bjs_Greeter_wrap") /// func _bjs_Greeter_wrap(_: UnsafeMutableRawPointer) -> Int32 @@ -1245,10 +1128,16 @@ public class ExportSwift { let externFunctionName = "bjs_\(klass.name)_wrap" return """ - extension \(raw: klass.swiftCallName): ConvertibleToJSValue { + extension \(raw: klass.swiftCallName): ConvertibleToJSValue, _BridgedSwiftHeapObject { var jsValue: JSValue { + #if arch(wasm32) @_extern(wasm, module: "\(raw: moduleName)", name: "\(raw: externFunctionName)") func \(raw: wrapFunctionName)(_: UnsafeMutableRawPointer) -> Int32 + #else + func \(raw: wrapFunctionName)(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") + } + #endif return .object(JSObject(id: UInt32(bitPattern: \(raw: wrapFunctionName)(Unmanaged.passRetained(self).toOpaque())))) } } @@ -1325,4 +1214,95 @@ extension BridgeType { case .namespaceEnum(let name): return name } } + + struct LiftingIntrinsicInfo: Sendable { + let parameters: [(name: String, type: WasmCoreType)] + + static let bool = LiftingIntrinsicInfo(parameters: [("value", .i32)]) + static let int = LiftingIntrinsicInfo(parameters: [("value", .i32)]) + static let float = LiftingIntrinsicInfo(parameters: [("value", .f32)]) + static let double = LiftingIntrinsicInfo(parameters: [("value", .f64)]) + static let string = LiftingIntrinsicInfo(parameters: [("bytes", .i32), ("length", .i32)]) + static let jsObject = LiftingIntrinsicInfo(parameters: [("value", .i32)]) + static let swiftHeapObject = LiftingIntrinsicInfo(parameters: [("value", .pointer)]) + static let void = LiftingIntrinsicInfo(parameters: []) + static let caseEnum = LiftingIntrinsicInfo(parameters: [("value", .i32)]) + } + + func liftParameterInfo() throws -> LiftingIntrinsicInfo { + switch self { + case .bool: return .bool + case .int: return .int + case .float: return .float + case .double: return .double + case .string: return .string + case .jsObject: return .jsObject + case .swiftHeapObject: return .swiftHeapObject + case .void: return .void + case .caseEnum: return .caseEnum + case .rawValueEnum(_, let rawType): + switch rawType { + case .bool: return .bool + case .int: return .int + case .float: return .float + case .double: return .double + case .string: return .string + case .int32: return .int + case .int64: return .int + case .uint: return .int + case .uint32: return .int + case .uint64: return .int + } + case .associatedValueEnum: + throw BridgeJSCoreError("Associated value enums are not supported to pass as parameters") + case .namespaceEnum: + throw BridgeJSCoreError("Namespace enums are not supported to pass as parameters") + } + } + + struct LoweringIntrinsicInfo: Sendable { + let returnType: WasmCoreType? + + static let bool = LoweringIntrinsicInfo(returnType: .i32) + static let int = LoweringIntrinsicInfo(returnType: .i32) + static let float = LoweringIntrinsicInfo(returnType: .f32) + static let double = LoweringIntrinsicInfo(returnType: .f64) + static let string = LoweringIntrinsicInfo(returnType: nil) + static let jsObject = LoweringIntrinsicInfo(returnType: .i32) + static let swiftHeapObject = LoweringIntrinsicInfo(returnType: .pointer) + static let void = LoweringIntrinsicInfo(returnType: nil) + static let caseEnum = LoweringIntrinsicInfo(returnType: .i32) + static let rawValueEnum = LoweringIntrinsicInfo(returnType: .i32) + } + + func loweringReturnInfo() throws -> LoweringIntrinsicInfo { + switch self { + case .bool: return .bool + case .int: return .int + case .float: return .float + case .double: return .double + case .string: return .string + case .jsObject: return .jsObject + case .swiftHeapObject: return .swiftHeapObject + case .void: return .void + case .caseEnum: return .caseEnum + case .rawValueEnum(_, let rawType): + switch rawType { + case .bool: return .bool + case .int: return .int + case .float: return .float + case .double: return .double + case .string: return .string + case .int32: return .int + case .int64: return .int + case .uint: return .int + case .uint32: return .int + case .uint64: return .int + } + case .associatedValueEnum: + throw BridgeJSCoreError("Associated value enums are not supported to pass as parameters") + case .namespaceEnum: + throw BridgeJSCoreError("Namespace enums are not supported to pass as parameters") + } + } } diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift index 9475c784..bf836637 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift @@ -371,7 +371,7 @@ public struct ImportTS { try builder.lowerParameter(param: newValue) builder.call(returnType: .void) return builder.renderThunkDecl( - name: "set\(property.name.capitalizedFirstLetter())", + name: "set\(property.name.capitalizedFirstLetter)", parameters: [newValue], returnType: .void ) @@ -483,10 +483,3 @@ public struct ImportTS { ) } } - -fileprivate extension String { - func capitalizedFirstLetter() -> String { - guard !isEmpty else { return self } - return prefix(1).uppercased() + dropFirst() - } -} diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/Utilities.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/Utilities.swift new file mode 100644 index 00000000..fb3a6e16 --- /dev/null +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/Utilities.swift @@ -0,0 +1,6 @@ +extension String { + var capitalizedFirstLetter: String { + guard !isEmpty else { return self } + return prefix(1).uppercased() + dropFirst() + } +} diff --git a/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift b/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift index 47083729..76385d41 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift @@ -10,7 +10,7 @@ public enum BridgeType: Codable, Equatable { case namespaceEnum(String) } -public enum WasmCoreType: String, Codable { +public enum WasmCoreType: String, Codable, Sendable { case i32, i64, f32, f64, pointer } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Async.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Async.swift index fe31c9f1..33ddda25 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Async.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Async.swift @@ -34,10 +34,10 @@ public func _bjs_asyncRoundTripInt(v: Int32) -> Int32 { @_expose(wasm, "bjs_asyncRoundTripString") @_cdecl("bjs_asyncRoundTripString") -public func _bjs_asyncRoundTripString(vBytes: Int32, vLen: Int32) -> Int32 { +public func _bjs_asyncRoundTripString(vBytes: Int32, vLength: Int32) -> Int32 { #if arch(wasm32) let ret = JSPromise.async { - return await asyncRoundTripString(_: String.bridgeJSLiftParameter(vBytes, vLen)).jsValue + return await asyncRoundTripString(_: String.bridgeJSLiftParameter(vBytes, vLength)).jsValue } .jsObject return ret.bridgeJSLowerReturn() #else @@ -63,7 +63,7 @@ public func _bjs_asyncRoundTripBool(v: Int32) -> Int32 { public func _bjs_asyncRoundTripFloat(v: Float32) -> Int32 { #if arch(wasm32) let ret = JSPromise.async { - return await asyncRoundTripFloat(_: v).jsValue + return await asyncRoundTripFloat(_: Float.bridgeJSLiftParameter(v)).jsValue } .jsObject return ret.bridgeJSLowerReturn() #else @@ -76,7 +76,7 @@ public func _bjs_asyncRoundTripFloat(v: Float32) -> Int32 { public func _bjs_asyncRoundTripDouble(v: Float64) -> Int32 { #if arch(wasm32) let ret = JSPromise.async { - return await asyncRoundTripDouble(_: v).jsValue + return await asyncRoundTripDouble(_: Double.bridgeJSLiftParameter(v)).jsValue } .jsObject return ret.bridgeJSLowerReturn() #else diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumCase.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumCase.swift index 363ade82..8b087111 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumCase.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumCase.swift @@ -7,7 +7,20 @@ @_spi(BridgeJS) import JavaScriptKit extension Direction { - init?(bridgeJSRawValue: Int32) { + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + return bridgeJSRawValue + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Int32) -> Direction { + return Direction(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Int32) -> Direction { + return Direction(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Int32 { + return bridgeJSRawValue + } + + private init?(bridgeJSRawValue: Int32) { switch bridgeJSRawValue { case 0: self = .north @@ -22,7 +35,7 @@ extension Direction { } } - var bridgeJSRawValue: Int32 { + private var bridgeJSRawValue: Int32 { switch self { case .north: return 0 @@ -37,7 +50,20 @@ extension Direction { } extension Status { - init?(bridgeJSRawValue: Int32) { + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + return bridgeJSRawValue + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Int32) -> Status { + return Status(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Int32) -> Status { + return Status(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Int32 { + return bridgeJSRawValue + } + + private init?(bridgeJSRawValue: Int32) { switch bridgeJSRawValue { case 0: self = .loading @@ -50,7 +76,7 @@ extension Status { } } - var bridgeJSRawValue: Int32 { + private var bridgeJSRawValue: Int32 { switch self { case .loading: return 0 @@ -63,7 +89,20 @@ extension Status { } extension TSDirection { - init?(bridgeJSRawValue: Int32) { + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + return bridgeJSRawValue + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Int32) -> TSDirection { + return TSDirection(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Int32) -> TSDirection { + return TSDirection(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Int32 { + return bridgeJSRawValue + } + + private init?(bridgeJSRawValue: Int32) { switch bridgeJSRawValue { case 0: self = .north @@ -78,7 +117,7 @@ extension TSDirection { } } - var bridgeJSRawValue: Int32 { + private var bridgeJSRawValue: Int32 { switch self { case .north: return 0 @@ -96,7 +135,7 @@ extension TSDirection { @_cdecl("bjs_setDirection") public func _bjs_setDirection(direction: Int32) -> Void { #if arch(wasm32) - setDirection(_: Direction(bridgeJSRawValue: direction)!) + setDirection(_: Direction.bridgeJSLiftParameter(direction)) #else fatalError("Only available on WebAssembly") #endif @@ -107,7 +146,7 @@ public func _bjs_setDirection(direction: Int32) -> Void { public func _bjs_getDirection() -> Int32 { #if arch(wasm32) let ret = getDirection() - return ret.bridgeJSRawValue + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -117,8 +156,8 @@ public func _bjs_getDirection() -> Int32 { @_cdecl("bjs_processDirection") public func _bjs_processDirection(input: Int32) -> Int32 { #if arch(wasm32) - let ret = processDirection(_: Direction(bridgeJSRawValue: input)!) - return ret.bridgeJSRawValue + let ret = processDirection(_: Direction.bridgeJSLiftParameter(input)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -128,7 +167,7 @@ public func _bjs_processDirection(input: Int32) -> Int32 { @_cdecl("bjs_setTSDirection") public func _bjs_setTSDirection(direction: Int32) -> Void { #if arch(wasm32) - setTSDirection(_: TSDirection(bridgeJSRawValue: direction)!) + setTSDirection(_: TSDirection.bridgeJSLiftParameter(direction)) #else fatalError("Only available on WebAssembly") #endif @@ -139,7 +178,7 @@ public func _bjs_setTSDirection(direction: Int32) -> Void { public func _bjs_getTSDirection() -> Int32 { #if arch(wasm32) let ret = getTSDirection() - return ret.bridgeJSRawValue + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.swift index e2a6588a..bb0fbe43 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.swift @@ -6,8 +6,24 @@ @_spi(BridgeJS) import JavaScriptKit +extension Utils: _BridgedSwiftEnumNoPayload { +} + extension Networking.API.Method { - init?(bridgeJSRawValue: Int32) { + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + return bridgeJSRawValue + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Int32) -> Networking.API.Method { + return Networking.API.Method(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Int32) -> Networking.API.Method { + return Networking.API.Method(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Int32 { + return bridgeJSRawValue + } + + private init?(bridgeJSRawValue: Int32) { switch bridgeJSRawValue { case 0: self = .get @@ -22,7 +38,7 @@ extension Networking.API.Method { } } - var bridgeJSRawValue: Int32 { + private var bridgeJSRawValue: Int32 { switch self { case .get: return 0 @@ -36,8 +52,27 @@ extension Networking.API.Method { } } +extension Configuration.LogLevel: _BridgedSwiftEnumNoPayload { +} + +extension Configuration.Port: _BridgedSwiftEnumNoPayload { +} + extension Internal.SupportedMethod { - init?(bridgeJSRawValue: Int32) { + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + return bridgeJSRawValue + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Int32) -> Internal.SupportedMethod { + return Internal.SupportedMethod(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Int32) -> Internal.SupportedMethod { + return Internal.SupportedMethod(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Int32 { + return bridgeJSRawValue + } + + private init?(bridgeJSRawValue: Int32) { switch bridgeJSRawValue { case 0: self = .get @@ -48,7 +83,7 @@ extension Internal.SupportedMethod { } } - var bridgeJSRawValue: Int32 { + private var bridgeJSRawValue: Int32 { switch self { case .get: return 0 @@ -63,7 +98,7 @@ extension Internal.SupportedMethod { public func _bjs_Converter_init() -> UnsafeMutableRawPointer { #if arch(wasm32) let ret = Utils.Converter() - return Unmanaged.passRetained(ret).toOpaque() + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -73,7 +108,7 @@ public func _bjs_Converter_init() -> UnsafeMutableRawPointer { @_cdecl("bjs_Converter_toString") public func _bjs_Converter_toString(_self: UnsafeMutableRawPointer, value: Int32) -> Void { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().toString(value: Int.bridgeJSLiftParameter(value)) + let ret = Utils.Converter.bridgeJSLiftParameter(_self).toString(value: Int.bridgeJSLiftParameter(value)) return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -86,10 +121,16 @@ public func _bjs_Converter_deinit(pointer: UnsafeMutableRawPointer) { Unmanaged.fromOpaque(pointer).release() } -extension Utils.Converter: ConvertibleToJSValue { +extension Utils.Converter: ConvertibleToJSValue, _BridgedSwiftHeapObject { var jsValue: JSValue { + #if arch(wasm32) @_extern(wasm, module: "TestModule", name: "bjs_Converter_wrap") func _bjs_Converter_wrap(_: UnsafeMutableRawPointer) -> Int32 + #else + func _bjs_Converter_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") + } + #endif return .object(JSObject(id: UInt32(bitPattern: _bjs_Converter_wrap(Unmanaged.passRetained(self).toOpaque())))) } } @@ -99,7 +140,7 @@ extension Utils.Converter: ConvertibleToJSValue { public func _bjs_HTTPServer_init() -> UnsafeMutableRawPointer { #if arch(wasm32) let ret = Networking.API.HTTPServer() - return Unmanaged.passRetained(ret).toOpaque() + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -109,7 +150,7 @@ public func _bjs_HTTPServer_init() -> UnsafeMutableRawPointer { @_cdecl("bjs_HTTPServer_call") public func _bjs_HTTPServer_call(_self: UnsafeMutableRawPointer, method: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().call(_: Networking.API.Method(bridgeJSRawValue: method)!) + Networking.API.HTTPServer.bridgeJSLiftParameter(_self).call(_: Networking.API.Method.bridgeJSLiftParameter(method)) #else fatalError("Only available on WebAssembly") #endif @@ -121,10 +162,16 @@ public func _bjs_HTTPServer_deinit(pointer: UnsafeMutableRawPointer) { Unmanaged.fromOpaque(pointer).release() } -extension Networking.API.HTTPServer: ConvertibleToJSValue { +extension Networking.API.HTTPServer: ConvertibleToJSValue, _BridgedSwiftHeapObject { var jsValue: JSValue { + #if arch(wasm32) @_extern(wasm, module: "TestModule", name: "bjs_HTTPServer_wrap") func _bjs_HTTPServer_wrap(_: UnsafeMutableRawPointer) -> Int32 + #else + func _bjs_HTTPServer_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") + } + #endif return .object(JSObject(id: UInt32(bitPattern: _bjs_HTTPServer_wrap(Unmanaged.passRetained(self).toOpaque())))) } } @@ -134,7 +181,7 @@ extension Networking.API.HTTPServer: ConvertibleToJSValue { public func _bjs_TestServer_init() -> UnsafeMutableRawPointer { #if arch(wasm32) let ret = Internal.TestServer() - return Unmanaged.passRetained(ret).toOpaque() + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -144,7 +191,7 @@ public func _bjs_TestServer_init() -> UnsafeMutableRawPointer { @_cdecl("bjs_TestServer_call") public func _bjs_TestServer_call(_self: UnsafeMutableRawPointer, method: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().call(_: Internal.SupportedMethod(bridgeJSRawValue: method)!) + Internal.TestServer.bridgeJSLiftParameter(_self).call(_: Internal.SupportedMethod.bridgeJSLiftParameter(method)) #else fatalError("Only available on WebAssembly") #endif @@ -156,10 +203,16 @@ public func _bjs_TestServer_deinit(pointer: UnsafeMutableRawPointer) { Unmanaged.fromOpaque(pointer).release() } -extension Internal.TestServer: ConvertibleToJSValue { +extension Internal.TestServer: ConvertibleToJSValue, _BridgedSwiftHeapObject { var jsValue: JSValue { + #if arch(wasm32) @_extern(wasm, module: "TestModule", name: "bjs_TestServer_wrap") func _bjs_TestServer_wrap(_: UnsafeMutableRawPointer) -> Int32 + #else + func _bjs_TestServer_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") + } + #endif return .object(JSObject(id: UInt32(bitPattern: _bjs_TestServer_wrap(Unmanaged.passRetained(self).toOpaque())))) } } \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumRawType.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumRawType.swift index 9f8f2ec3..e0a32e84 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumRawType.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumRawType.swift @@ -6,11 +6,47 @@ @_spi(BridgeJS) import JavaScriptKit +extension Theme: _BridgedSwiftEnumNoPayload { +} + +extension TSTheme: _BridgedSwiftEnumNoPayload { +} + +extension FeatureFlag: _BridgedSwiftEnumNoPayload { +} + +extension HttpStatus: _BridgedSwiftEnumNoPayload { +} + +extension TSHttpStatus: _BridgedSwiftEnumNoPayload { +} + +extension Priority: _BridgedSwiftEnumNoPayload { +} + +extension FileSize: _BridgedSwiftEnumNoPayload { +} + +extension UserId: _BridgedSwiftEnumNoPayload { +} + +extension TokenId: _BridgedSwiftEnumNoPayload { +} + +extension SessionId: _BridgedSwiftEnumNoPayload { +} + +extension Precision: _BridgedSwiftEnumNoPayload { +} + +extension Ratio: _BridgedSwiftEnumNoPayload { +} + @_expose(wasm, "bjs_setTheme") @_cdecl("bjs_setTheme") -public func _bjs_setTheme(themeBytes: Int32, themeLen: Int32) -> Void { +public func _bjs_setTheme(themeBytes: Int32, themeLength: Int32) -> Void { #if arch(wasm32) - setTheme(_: Theme(rawValue: String.bridgeJSLiftParameter(themeBytes, themeLen))!) + setTheme(_: Theme.bridgeJSLiftParameter(themeBytes, themeLength)) #else fatalError("Only available on WebAssembly") #endif @@ -21,7 +57,7 @@ public func _bjs_setTheme(themeBytes: Int32, themeLen: Int32) -> Void { public func _bjs_getTheme() -> Void { #if arch(wasm32) let ret = getTheme() - return ret.rawValue.bridgeJSLowerReturn() + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -29,9 +65,9 @@ public func _bjs_getTheme() -> Void { @_expose(wasm, "bjs_setTSTheme") @_cdecl("bjs_setTSTheme") -public func _bjs_setTSTheme(themeBytes: Int32, themeLen: Int32) -> Void { +public func _bjs_setTSTheme(themeBytes: Int32, themeLength: Int32) -> Void { #if arch(wasm32) - setTSTheme(_: TSTheme(rawValue: String.bridgeJSLiftParameter(themeBytes, themeLen))!) + setTSTheme(_: TSTheme.bridgeJSLiftParameter(themeBytes, themeLength)) #else fatalError("Only available on WebAssembly") #endif @@ -42,7 +78,7 @@ public func _bjs_setTSTheme(themeBytes: Int32, themeLen: Int32) -> Void { public func _bjs_getTSTheme() -> Void { #if arch(wasm32) let ret = getTSTheme() - return ret.rawValue.bridgeJSLowerReturn() + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -52,7 +88,7 @@ public func _bjs_getTSTheme() -> Void { @_cdecl("bjs_setFeatureFlag") public func _bjs_setFeatureFlag(flag: Int32) -> Void { #if arch(wasm32) - setFeatureFlag(_: FeatureFlag(rawValue: FeatureFlag.bridgeJSLiftParameter(flag))) + setFeatureFlag(_: FeatureFlag.bridgeJSLiftParameter(flag)) #else fatalError("Only available on WebAssembly") #endif @@ -63,7 +99,7 @@ public func _bjs_setFeatureFlag(flag: Int32) -> Void { public func _bjs_getFeatureFlag() -> Int32 { #if arch(wasm32) let ret = getFeatureFlag() - return Int32(ret.rawValue ? 1 : 0) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -73,7 +109,7 @@ public func _bjs_getFeatureFlag() -> Int32 { @_cdecl("bjs_setHttpStatus") public func _bjs_setHttpStatus(status: Int32) -> Void { #if arch(wasm32) - setHttpStatus(_: HttpStatus(rawValue: Int(status))!) + setHttpStatus(_: HttpStatus.bridgeJSLiftParameter(status)) #else fatalError("Only available on WebAssembly") #endif @@ -84,7 +120,7 @@ public func _bjs_setHttpStatus(status: Int32) -> Void { public func _bjs_getHttpStatus() -> Int32 { #if arch(wasm32) let ret = getHttpStatus() - return Int32(ret.rawValue) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -94,7 +130,7 @@ public func _bjs_getHttpStatus() -> Int32 { @_cdecl("bjs_setTSHttpStatus") public func _bjs_setTSHttpStatus(status: Int32) -> Void { #if arch(wasm32) - setTSHttpStatus(_: TSHttpStatus(rawValue: Int(status))!) + setTSHttpStatus(_: TSHttpStatus.bridgeJSLiftParameter(status)) #else fatalError("Only available on WebAssembly") #endif @@ -105,7 +141,7 @@ public func _bjs_setTSHttpStatus(status: Int32) -> Void { public func _bjs_getTSHttpStatus() -> Int32 { #if arch(wasm32) let ret = getTSHttpStatus() - return Int32(ret.rawValue) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -115,7 +151,7 @@ public func _bjs_getTSHttpStatus() -> Int32 { @_cdecl("bjs_setPriority") public func _bjs_setPriority(priority: Int32) -> Void { #if arch(wasm32) - setPriority(_: Priority(rawValue: Int32(priority))!) + setPriority(_: Priority.bridgeJSLiftParameter(priority)) #else fatalError("Only available on WebAssembly") #endif @@ -126,7 +162,7 @@ public func _bjs_setPriority(priority: Int32) -> Void { public func _bjs_getPriority() -> Int32 { #if arch(wasm32) let ret = getPriority() - return Int32(ret.rawValue) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -134,9 +170,9 @@ public func _bjs_getPriority() -> Int32 { @_expose(wasm, "bjs_setFileSize") @_cdecl("bjs_setFileSize") -public func _bjs_setFileSize(size: Int64) -> Void { +public func _bjs_setFileSize(size: Int32) -> Void { #if arch(wasm32) - setFileSize(_: FileSize(rawValue: Int64(size))!) + setFileSize(_: FileSize.bridgeJSLiftParameter(size)) #else fatalError("Only available on WebAssembly") #endif @@ -144,10 +180,10 @@ public func _bjs_setFileSize(size: Int64) -> Void { @_expose(wasm, "bjs_getFileSize") @_cdecl("bjs_getFileSize") -public func _bjs_getFileSize() -> Int64 { +public func _bjs_getFileSize() -> Int32 { #if arch(wasm32) let ret = getFileSize() - return Int64(ret.rawValue) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -157,7 +193,7 @@ public func _bjs_getFileSize() -> Int64 { @_cdecl("bjs_setUserId") public func _bjs_setUserId(id: Int32) -> Void { #if arch(wasm32) - setUserId(_: UserId(rawValue: UInt(bitPattern: id))!) + setUserId(_: UserId.bridgeJSLiftParameter(id)) #else fatalError("Only available on WebAssembly") #endif @@ -168,7 +204,7 @@ public func _bjs_setUserId(id: Int32) -> Void { public func _bjs_getUserId() -> Int32 { #if arch(wasm32) let ret = getUserId() - return Int32(ret.rawValue) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -178,7 +214,7 @@ public func _bjs_getUserId() -> Int32 { @_cdecl("bjs_setTokenId") public func _bjs_setTokenId(token: Int32) -> Void { #if arch(wasm32) - setTokenId(_: TokenId(rawValue: UInt32(bitPattern: token))!) + setTokenId(_: TokenId.bridgeJSLiftParameter(token)) #else fatalError("Only available on WebAssembly") #endif @@ -189,7 +225,7 @@ public func _bjs_setTokenId(token: Int32) -> Void { public func _bjs_getTokenId() -> Int32 { #if arch(wasm32) let ret = getTokenId() - return Int32(ret.rawValue) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -197,9 +233,9 @@ public func _bjs_getTokenId() -> Int32 { @_expose(wasm, "bjs_setSessionId") @_cdecl("bjs_setSessionId") -public func _bjs_setSessionId(session: Int64) -> Void { +public func _bjs_setSessionId(session: Int32) -> Void { #if arch(wasm32) - setSessionId(_: SessionId(rawValue: UInt64(bitPattern: Int64(session)))!) + setSessionId(_: SessionId.bridgeJSLiftParameter(session)) #else fatalError("Only available on WebAssembly") #endif @@ -207,10 +243,10 @@ public func _bjs_setSessionId(session: Int64) -> Void { @_expose(wasm, "bjs_getSessionId") @_cdecl("bjs_getSessionId") -public func _bjs_getSessionId() -> Int64 { +public func _bjs_getSessionId() -> Int32 { #if arch(wasm32) let ret = getSessionId() - return Int64(ret.rawValue) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -220,7 +256,7 @@ public func _bjs_getSessionId() -> Int64 { @_cdecl("bjs_setPrecision") public func _bjs_setPrecision(precision: Float32) -> Void { #if arch(wasm32) - setPrecision(_: Precision(rawValue: Float(precision))!) + setPrecision(_: Precision.bridgeJSLiftParameter(precision)) #else fatalError("Only available on WebAssembly") #endif @@ -231,7 +267,7 @@ public func _bjs_setPrecision(precision: Float32) -> Void { public func _bjs_getPrecision() -> Float32 { #if arch(wasm32) let ret = getPrecision() - return Float32(ret.rawValue) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -241,7 +277,7 @@ public func _bjs_getPrecision() -> Float32 { @_cdecl("bjs_setRatio") public func _bjs_setRatio(ratio: Float64) -> Void { #if arch(wasm32) - setRatio(_: Ratio(rawValue: Double(ratio))!) + setRatio(_: Ratio.bridgeJSLiftParameter(ratio)) #else fatalError("Only available on WebAssembly") #endif @@ -252,7 +288,7 @@ public func _bjs_setRatio(ratio: Float64) -> Void { public func _bjs_getRatio() -> Float64 { #if arch(wasm32) let ret = getRatio() - return Float64(ret.rawValue) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -262,7 +298,7 @@ public func _bjs_getRatio() -> Float64 { @_cdecl("bjs_setFeatureFlag") public func _bjs_setFeatureFlag(featureFlag: Int32) -> Void { #if arch(wasm32) - setFeatureFlag(_: FeatureFlag(rawValue: FeatureFlag.bridgeJSLiftParameter(featureFlag))) + setFeatureFlag(_: FeatureFlag.bridgeJSLiftParameter(featureFlag)) #else fatalError("Only available on WebAssembly") #endif @@ -273,7 +309,7 @@ public func _bjs_setFeatureFlag(featureFlag: Int32) -> Void { public func _bjs_getFeatureFlag() -> Int32 { #if arch(wasm32) let ret = getFeatureFlag() - return Int32(ret.rawValue ? 1 : 0) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -281,10 +317,10 @@ public func _bjs_getFeatureFlag() -> Int32 { @_expose(wasm, "bjs_processTheme") @_cdecl("bjs_processTheme") -public func _bjs_processTheme(themeBytes: Int32, themeLen: Int32) -> Int32 { +public func _bjs_processTheme(themeBytes: Int32, themeLength: Int32) -> Int32 { #if arch(wasm32) - let ret = processTheme(_: Theme(rawValue: String.bridgeJSLiftParameter(themeBytes, themeLen))!) - return Int32(ret.rawValue) + let ret = processTheme(_: Theme.bridgeJSLiftParameter(themeBytes, themeLength)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -294,8 +330,8 @@ public func _bjs_processTheme(themeBytes: Int32, themeLen: Int32) -> Int32 { @_cdecl("bjs_convertPriority") public func _bjs_convertPriority(status: Int32) -> Int32 { #if arch(wasm32) - let ret = convertPriority(_: HttpStatus(rawValue: Int(status))!) - return Int32(ret.rawValue) + let ret = convertPriority(_: HttpStatus.bridgeJSLiftParameter(status)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -303,10 +339,10 @@ public func _bjs_convertPriority(status: Int32) -> Int32 { @_expose(wasm, "bjs_validateSession") @_cdecl("bjs_validateSession") -public func _bjs_validateSession(session: Int64) -> Void { +public func _bjs_validateSession(session: Int32) -> Void { #if arch(wasm32) - let ret = validateSession(_: SessionId(rawValue: UInt64(bitPattern: Int64(session)))!) - return ret.rawValue.bridgeJSLowerReturn() + let ret = validateSession(_: SessionId.bridgeJSLiftParameter(session)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Namespaces.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Namespaces.swift index e0128c5d..f0e7f657 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Namespaces.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/Namespaces.swift @@ -30,10 +30,10 @@ public func _bjs_namespacedFunction() -> Void { @_expose(wasm, "bjs_Greeter_init") @_cdecl("bjs_Greeter_init") -public func _bjs_Greeter_init(nameBytes: Int32, nameLen: Int32) -> UnsafeMutableRawPointer { +public func _bjs_Greeter_init(nameBytes: Int32, nameLength: Int32) -> UnsafeMutableRawPointer { #if arch(wasm32) - let ret = Greeter(name: String.bridgeJSLiftParameter(nameBytes, nameLen)) - return Unmanaged.passRetained(ret).toOpaque() + let ret = Greeter(name: String.bridgeJSLiftParameter(nameBytes, nameLength)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -43,7 +43,7 @@ public func _bjs_Greeter_init(nameBytes: Int32, nameLen: Int32) -> UnsafeMutable @_cdecl("bjs_Greeter_greet") public func _bjs_Greeter_greet(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().greet() + let ret = Greeter.bridgeJSLiftParameter(_self).greet() return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -56,10 +56,16 @@ public func _bjs_Greeter_deinit(pointer: UnsafeMutableRawPointer) { Unmanaged.fromOpaque(pointer).release() } -extension Greeter: ConvertibleToJSValue { +extension Greeter: ConvertibleToJSValue, _BridgedSwiftHeapObject { var jsValue: JSValue { + #if arch(wasm32) @_extern(wasm, module: "TestModule", name: "bjs_Greeter_wrap") func _bjs_Greeter_wrap(_: UnsafeMutableRawPointer) -> Int32 + #else + func _bjs_Greeter_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") + } + #endif return .object(JSObject(id: UInt32(bitPattern: _bjs_Greeter_wrap(Unmanaged.passRetained(self).toOpaque())))) } } @@ -69,7 +75,7 @@ extension Greeter: ConvertibleToJSValue { public func _bjs_Converter_init() -> UnsafeMutableRawPointer { #if arch(wasm32) let ret = Converter() - return Unmanaged.passRetained(ret).toOpaque() + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -79,7 +85,7 @@ public func _bjs_Converter_init() -> UnsafeMutableRawPointer { @_cdecl("bjs_Converter_toString") public func _bjs_Converter_toString(_self: UnsafeMutableRawPointer, value: Int32) -> Void { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().toString(value: Int.bridgeJSLiftParameter(value)) + let ret = Converter.bridgeJSLiftParameter(_self).toString(value: Int.bridgeJSLiftParameter(value)) return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -92,10 +98,16 @@ public func _bjs_Converter_deinit(pointer: UnsafeMutableRawPointer) { Unmanaged.fromOpaque(pointer).release() } -extension Converter: ConvertibleToJSValue { +extension Converter: ConvertibleToJSValue, _BridgedSwiftHeapObject { var jsValue: JSValue { + #if arch(wasm32) @_extern(wasm, module: "TestModule", name: "bjs_Converter_wrap") func _bjs_Converter_wrap(_: UnsafeMutableRawPointer) -> Int32 + #else + func _bjs_Converter_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") + } + #endif return .object(JSObject(id: UInt32(bitPattern: _bjs_Converter_wrap(Unmanaged.passRetained(self).toOpaque())))) } } @@ -104,7 +116,7 @@ extension Converter: ConvertibleToJSValue { @_cdecl("bjs_UUID_uuidString") public func _bjs_UUID_uuidString(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().uuidString() + let ret = UUID.bridgeJSLiftParameter(_self).uuidString() return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -117,10 +129,16 @@ public func _bjs_UUID_deinit(pointer: UnsafeMutableRawPointer) { Unmanaged.fromOpaque(pointer).release() } -extension UUID: ConvertibleToJSValue { +extension UUID: ConvertibleToJSValue, _BridgedSwiftHeapObject { var jsValue: JSValue { + #if arch(wasm32) @_extern(wasm, module: "TestModule", name: "bjs_UUID_wrap") func _bjs_UUID_wrap(_: UnsafeMutableRawPointer) -> Int32 + #else + func _bjs_UUID_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") + } + #endif return .object(JSObject(id: UInt32(bitPattern: _bjs_UUID_wrap(Unmanaged.passRetained(self).toOpaque())))) } } \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveParameters.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveParameters.swift index 8f2e54c3..33097726 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveParameters.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveParameters.swift @@ -10,7 +10,7 @@ @_cdecl("bjs_check") public func _bjs_check(a: Int32, b: Float32, c: Float64, d: Int32) -> Void { #if arch(wasm32) - check(a: Int.bridgeJSLiftParameter(a), b: b, c: c, d: Bool.bridgeJSLiftParameter(d)) + check(a: Int.bridgeJSLiftParameter(a), b: Float.bridgeJSLiftParameter(b), c: Double.bridgeJSLiftParameter(c), d: Bool.bridgeJSLiftParameter(d)) #else fatalError("Only available on WebAssembly") #endif diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveReturn.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveReturn.swift index cc31d23e..63e5f03c 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveReturn.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveReturn.swift @@ -11,7 +11,7 @@ public func _bjs_checkInt() -> Int32 { #if arch(wasm32) let ret = checkInt() - return Int32(ret) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -22,7 +22,7 @@ public func _bjs_checkInt() -> Int32 { public func _bjs_checkFloat() -> Float32 { #if arch(wasm32) let ret = checkFloat() - return Float32(ret) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -33,7 +33,7 @@ public func _bjs_checkFloat() -> Float32 { public func _bjs_checkDouble() -> Float64 { #if arch(wasm32) let ret = checkDouble() - return Float64(ret) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PropertyTypes.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PropertyTypes.swift index 74d3a58d..822e5846 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PropertyTypes.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PropertyTypes.swift @@ -8,10 +8,10 @@ @_expose(wasm, "bjs_createPropertyHolder") @_cdecl("bjs_createPropertyHolder") -public func _bjs_createPropertyHolder(intValue: Int32, floatValue: Float32, doubleValue: Float64, boolValue: Int32, stringValueBytes: Int32, stringValueLen: Int32, jsObject: Int32) -> UnsafeMutableRawPointer { +public func _bjs_createPropertyHolder(intValue: Int32, floatValue: Float32, doubleValue: Float64, boolValue: Int32, stringValueBytes: Int32, stringValueLength: Int32, jsObject: Int32) -> UnsafeMutableRawPointer { #if arch(wasm32) - let ret = createPropertyHolder(intValue: Int.bridgeJSLiftParameter(intValue), floatValue: floatValue, doubleValue: doubleValue, boolValue: Bool.bridgeJSLiftParameter(boolValue), stringValue: String.bridgeJSLiftParameter(stringValueBytes, stringValueLen), jsObject: JSObject.bridgeJSLiftParameter(jsObject)) - return Unmanaged.passRetained(ret).toOpaque() + let ret = createPropertyHolder(intValue: Int.bridgeJSLiftParameter(intValue), floatValue: Float.bridgeJSLiftParameter(floatValue), doubleValue: Double.bridgeJSLiftParameter(doubleValue), boolValue: Bool.bridgeJSLiftParameter(boolValue), stringValue: String.bridgeJSLiftParameter(stringValueBytes, stringValueLength), jsObject: JSObject.bridgeJSLiftParameter(jsObject)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -21,7 +21,7 @@ public func _bjs_createPropertyHolder(intValue: Int32, floatValue: Float32, doub @_cdecl("bjs_testPropertyHolder") public func _bjs_testPropertyHolder(holder: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - let ret = testPropertyHolder(holder: Unmanaged.fromOpaque(holder).takeUnretainedValue()) + let ret = testPropertyHolder(holder: PropertyHolder.bridgeJSLiftParameter(holder)) return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -30,10 +30,10 @@ public func _bjs_testPropertyHolder(holder: UnsafeMutableRawPointer) -> Void { @_expose(wasm, "bjs_PropertyHolder_init") @_cdecl("bjs_PropertyHolder_init") -public func _bjs_PropertyHolder_init(intValue: Int32, floatValue: Float32, doubleValue: Float64, boolValue: Int32, stringValueBytes: Int32, stringValueLen: Int32, jsObject: Int32) -> UnsafeMutableRawPointer { +public func _bjs_PropertyHolder_init(intValue: Int32, floatValue: Float32, doubleValue: Float64, boolValue: Int32, stringValueBytes: Int32, stringValueLength: Int32, jsObject: Int32) -> UnsafeMutableRawPointer { #if arch(wasm32) - let ret = PropertyHolder(intValue: Int.bridgeJSLiftParameter(intValue), floatValue: floatValue, doubleValue: doubleValue, boolValue: Bool.bridgeJSLiftParameter(boolValue), stringValue: String.bridgeJSLiftParameter(stringValueBytes, stringValueLen), jsObject: JSObject.bridgeJSLiftParameter(jsObject)) - return Unmanaged.passRetained(ret).toOpaque() + let ret = PropertyHolder(intValue: Int.bridgeJSLiftParameter(intValue), floatValue: Float.bridgeJSLiftParameter(floatValue), doubleValue: Double.bridgeJSLiftParameter(doubleValue), boolValue: Bool.bridgeJSLiftParameter(boolValue), stringValue: String.bridgeJSLiftParameter(stringValueBytes, stringValueLength), jsObject: JSObject.bridgeJSLiftParameter(jsObject)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -43,7 +43,7 @@ public func _bjs_PropertyHolder_init(intValue: Int32, floatValue: Float32, doubl @_cdecl("bjs_PropertyHolder_getAllValues") public func _bjs_PropertyHolder_getAllValues(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().getAllValues() + let ret = PropertyHolder.bridgeJSLiftParameter(_self).getAllValues() return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -54,8 +54,8 @@ public func _bjs_PropertyHolder_getAllValues(_self: UnsafeMutableRawPointer) -> @_cdecl("bjs_PropertyHolder_intValue_get") public func _bjs_PropertyHolder_intValue_get(_self: UnsafeMutableRawPointer) -> Int32 { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().intValue - return Int32(ret) + let ret = PropertyHolder.bridgeJSLiftParameter(_self).intValue + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -65,7 +65,7 @@ public func _bjs_PropertyHolder_intValue_get(_self: UnsafeMutableRawPointer) -> @_cdecl("bjs_PropertyHolder_intValue_set") public func _bjs_PropertyHolder_intValue_set(_self: UnsafeMutableRawPointer, value: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().intValue = Int.bridgeJSLiftParameter(value) + PropertyHolder.bridgeJSLiftParameter(_self).intValue = Int.bridgeJSLiftParameter(value) #else fatalError("Only available on WebAssembly") #endif @@ -75,8 +75,8 @@ public func _bjs_PropertyHolder_intValue_set(_self: UnsafeMutableRawPointer, val @_cdecl("bjs_PropertyHolder_floatValue_get") public func _bjs_PropertyHolder_floatValue_get(_self: UnsafeMutableRawPointer) -> Float32 { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().floatValue - return Float32(ret) + let ret = PropertyHolder.bridgeJSLiftParameter(_self).floatValue + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -86,7 +86,7 @@ public func _bjs_PropertyHolder_floatValue_get(_self: UnsafeMutableRawPointer) - @_cdecl("bjs_PropertyHolder_floatValue_set") public func _bjs_PropertyHolder_floatValue_set(_self: UnsafeMutableRawPointer, value: Float32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().floatValue = value + PropertyHolder.bridgeJSLiftParameter(_self).floatValue = Float.bridgeJSLiftParameter(value) #else fatalError("Only available on WebAssembly") #endif @@ -96,8 +96,8 @@ public func _bjs_PropertyHolder_floatValue_set(_self: UnsafeMutableRawPointer, v @_cdecl("bjs_PropertyHolder_doubleValue_get") public func _bjs_PropertyHolder_doubleValue_get(_self: UnsafeMutableRawPointer) -> Float64 { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().doubleValue - return Float64(ret) + let ret = PropertyHolder.bridgeJSLiftParameter(_self).doubleValue + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -107,7 +107,7 @@ public func _bjs_PropertyHolder_doubleValue_get(_self: UnsafeMutableRawPointer) @_cdecl("bjs_PropertyHolder_doubleValue_set") public func _bjs_PropertyHolder_doubleValue_set(_self: UnsafeMutableRawPointer, value: Float64) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().doubleValue = value + PropertyHolder.bridgeJSLiftParameter(_self).doubleValue = Double.bridgeJSLiftParameter(value) #else fatalError("Only available on WebAssembly") #endif @@ -117,7 +117,7 @@ public func _bjs_PropertyHolder_doubleValue_set(_self: UnsafeMutableRawPointer, @_cdecl("bjs_PropertyHolder_boolValue_get") public func _bjs_PropertyHolder_boolValue_get(_self: UnsafeMutableRawPointer) -> Int32 { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().boolValue + let ret = PropertyHolder.bridgeJSLiftParameter(_self).boolValue return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -128,7 +128,7 @@ public func _bjs_PropertyHolder_boolValue_get(_self: UnsafeMutableRawPointer) -> @_cdecl("bjs_PropertyHolder_boolValue_set") public func _bjs_PropertyHolder_boolValue_set(_self: UnsafeMutableRawPointer, value: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().boolValue = Bool.bridgeJSLiftParameter(value) + PropertyHolder.bridgeJSLiftParameter(_self).boolValue = Bool.bridgeJSLiftParameter(value) #else fatalError("Only available on WebAssembly") #endif @@ -138,7 +138,7 @@ public func _bjs_PropertyHolder_boolValue_set(_self: UnsafeMutableRawPointer, va @_cdecl("bjs_PropertyHolder_stringValue_get") public func _bjs_PropertyHolder_stringValue_get(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().stringValue + let ret = PropertyHolder.bridgeJSLiftParameter(_self).stringValue return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -147,9 +147,9 @@ public func _bjs_PropertyHolder_stringValue_get(_self: UnsafeMutableRawPointer) @_expose(wasm, "bjs_PropertyHolder_stringValue_set") @_cdecl("bjs_PropertyHolder_stringValue_set") -public func _bjs_PropertyHolder_stringValue_set(_self: UnsafeMutableRawPointer, valueBytes: Int32, valueLen: Int32) -> Void { +public func _bjs_PropertyHolder_stringValue_set(_self: UnsafeMutableRawPointer, valueBytes: Int32, valueLength: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().stringValue = String.bridgeJSLiftParameter(valueBytes, valueLen) + PropertyHolder.bridgeJSLiftParameter(_self).stringValue = String.bridgeJSLiftParameter(valueBytes, valueLength) #else fatalError("Only available on WebAssembly") #endif @@ -159,8 +159,8 @@ public func _bjs_PropertyHolder_stringValue_set(_self: UnsafeMutableRawPointer, @_cdecl("bjs_PropertyHolder_readonlyInt_get") public func _bjs_PropertyHolder_readonlyInt_get(_self: UnsafeMutableRawPointer) -> Int32 { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().readonlyInt - return Int32(ret) + let ret = PropertyHolder.bridgeJSLiftParameter(_self).readonlyInt + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -170,8 +170,8 @@ public func _bjs_PropertyHolder_readonlyInt_get(_self: UnsafeMutableRawPointer) @_cdecl("bjs_PropertyHolder_readonlyFloat_get") public func _bjs_PropertyHolder_readonlyFloat_get(_self: UnsafeMutableRawPointer) -> Float32 { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().readonlyFloat - return Float32(ret) + let ret = PropertyHolder.bridgeJSLiftParameter(_self).readonlyFloat + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -181,8 +181,8 @@ public func _bjs_PropertyHolder_readonlyFloat_get(_self: UnsafeMutableRawPointer @_cdecl("bjs_PropertyHolder_readonlyDouble_get") public func _bjs_PropertyHolder_readonlyDouble_get(_self: UnsafeMutableRawPointer) -> Float64 { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().readonlyDouble - return Float64(ret) + let ret = PropertyHolder.bridgeJSLiftParameter(_self).readonlyDouble + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -192,7 +192,7 @@ public func _bjs_PropertyHolder_readonlyDouble_get(_self: UnsafeMutableRawPointe @_cdecl("bjs_PropertyHolder_readonlyBool_get") public func _bjs_PropertyHolder_readonlyBool_get(_self: UnsafeMutableRawPointer) -> Int32 { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().readonlyBool + let ret = PropertyHolder.bridgeJSLiftParameter(_self).readonlyBool return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -203,7 +203,7 @@ public func _bjs_PropertyHolder_readonlyBool_get(_self: UnsafeMutableRawPointer) @_cdecl("bjs_PropertyHolder_readonlyString_get") public func _bjs_PropertyHolder_readonlyString_get(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().readonlyString + let ret = PropertyHolder.bridgeJSLiftParameter(_self).readonlyString return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -214,7 +214,7 @@ public func _bjs_PropertyHolder_readonlyString_get(_self: UnsafeMutableRawPointe @_cdecl("bjs_PropertyHolder_jsObject_get") public func _bjs_PropertyHolder_jsObject_get(_self: UnsafeMutableRawPointer) -> Int32 { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().jsObject + let ret = PropertyHolder.bridgeJSLiftParameter(_self).jsObject return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -225,7 +225,7 @@ public func _bjs_PropertyHolder_jsObject_get(_self: UnsafeMutableRawPointer) -> @_cdecl("bjs_PropertyHolder_jsObject_set") public func _bjs_PropertyHolder_jsObject_set(_self: UnsafeMutableRawPointer, value: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().jsObject = JSObject.bridgeJSLiftParameter(value) + PropertyHolder.bridgeJSLiftParameter(_self).jsObject = JSObject.bridgeJSLiftParameter(value) #else fatalError("Only available on WebAssembly") #endif @@ -235,8 +235,8 @@ public func _bjs_PropertyHolder_jsObject_set(_self: UnsafeMutableRawPointer, val @_cdecl("bjs_PropertyHolder_sibling_get") public func _bjs_PropertyHolder_sibling_get(_self: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().sibling - return Unmanaged.passRetained(ret).toOpaque() + let ret = PropertyHolder.bridgeJSLiftParameter(_self).sibling + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -246,7 +246,7 @@ public func _bjs_PropertyHolder_sibling_get(_self: UnsafeMutableRawPointer) -> U @_cdecl("bjs_PropertyHolder_sibling_set") public func _bjs_PropertyHolder_sibling_set(_self: UnsafeMutableRawPointer, value: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().sibling = Unmanaged.fromOpaque(value).takeUnretainedValue() + PropertyHolder.bridgeJSLiftParameter(_self).sibling = PropertyHolder.bridgeJSLiftParameter(value) #else fatalError("Only available on WebAssembly") #endif @@ -256,7 +256,7 @@ public func _bjs_PropertyHolder_sibling_set(_self: UnsafeMutableRawPointer, valu @_cdecl("bjs_PropertyHolder_lazyValue_get") public func _bjs_PropertyHolder_lazyValue_get(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().lazyValue + let ret = PropertyHolder.bridgeJSLiftParameter(_self).lazyValue return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -265,9 +265,9 @@ public func _bjs_PropertyHolder_lazyValue_get(_self: UnsafeMutableRawPointer) -> @_expose(wasm, "bjs_PropertyHolder_lazyValue_set") @_cdecl("bjs_PropertyHolder_lazyValue_set") -public func _bjs_PropertyHolder_lazyValue_set(_self: UnsafeMutableRawPointer, valueBytes: Int32, valueLen: Int32) -> Void { +public func _bjs_PropertyHolder_lazyValue_set(_self: UnsafeMutableRawPointer, valueBytes: Int32, valueLength: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().lazyValue = String.bridgeJSLiftParameter(valueBytes, valueLen) + PropertyHolder.bridgeJSLiftParameter(_self).lazyValue = String.bridgeJSLiftParameter(valueBytes, valueLength) #else fatalError("Only available on WebAssembly") #endif @@ -277,8 +277,8 @@ public func _bjs_PropertyHolder_lazyValue_set(_self: UnsafeMutableRawPointer, va @_cdecl("bjs_PropertyHolder_computedReadonly_get") public func _bjs_PropertyHolder_computedReadonly_get(_self: UnsafeMutableRawPointer) -> Int32 { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().computedReadonly - return Int32(ret) + let ret = PropertyHolder.bridgeJSLiftParameter(_self).computedReadonly + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -288,7 +288,7 @@ public func _bjs_PropertyHolder_computedReadonly_get(_self: UnsafeMutableRawPoin @_cdecl("bjs_PropertyHolder_computedReadWrite_get") public func _bjs_PropertyHolder_computedReadWrite_get(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().computedReadWrite + let ret = PropertyHolder.bridgeJSLiftParameter(_self).computedReadWrite return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -297,9 +297,9 @@ public func _bjs_PropertyHolder_computedReadWrite_get(_self: UnsafeMutableRawPoi @_expose(wasm, "bjs_PropertyHolder_computedReadWrite_set") @_cdecl("bjs_PropertyHolder_computedReadWrite_set") -public func _bjs_PropertyHolder_computedReadWrite_set(_self: UnsafeMutableRawPointer, valueBytes: Int32, valueLen: Int32) -> Void { +public func _bjs_PropertyHolder_computedReadWrite_set(_self: UnsafeMutableRawPointer, valueBytes: Int32, valueLength: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().computedReadWrite = String.bridgeJSLiftParameter(valueBytes, valueLen) + PropertyHolder.bridgeJSLiftParameter(_self).computedReadWrite = String.bridgeJSLiftParameter(valueBytes, valueLength) #else fatalError("Only available on WebAssembly") #endif @@ -309,8 +309,8 @@ public func _bjs_PropertyHolder_computedReadWrite_set(_self: UnsafeMutableRawPoi @_cdecl("bjs_PropertyHolder_observedProperty_get") public func _bjs_PropertyHolder_observedProperty_get(_self: UnsafeMutableRawPointer) -> Int32 { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().observedProperty - return Int32(ret) + let ret = PropertyHolder.bridgeJSLiftParameter(_self).observedProperty + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -320,7 +320,7 @@ public func _bjs_PropertyHolder_observedProperty_get(_self: UnsafeMutableRawPoin @_cdecl("bjs_PropertyHolder_observedProperty_set") public func _bjs_PropertyHolder_observedProperty_set(_self: UnsafeMutableRawPointer, value: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().observedProperty = Int.bridgeJSLiftParameter(value) + PropertyHolder.bridgeJSLiftParameter(_self).observedProperty = Int.bridgeJSLiftParameter(value) #else fatalError("Only available on WebAssembly") #endif @@ -332,10 +332,16 @@ public func _bjs_PropertyHolder_deinit(pointer: UnsafeMutableRawPointer) { Unmanaged.fromOpaque(pointer).release() } -extension PropertyHolder: ConvertibleToJSValue { +extension PropertyHolder: ConvertibleToJSValue, _BridgedSwiftHeapObject { var jsValue: JSValue { + #if arch(wasm32) @_extern(wasm, module: "TestModule", name: "bjs_PropertyHolder_wrap") func _bjs_PropertyHolder_wrap(_: UnsafeMutableRawPointer) -> Int32 + #else + func _bjs_PropertyHolder_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") + } + #endif return .object(JSObject(id: UInt32(bitPattern: _bjs_PropertyHolder_wrap(Unmanaged.passRetained(self).toOpaque())))) } } \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StringParameter.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StringParameter.swift index 0da63382..723a639c 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StringParameter.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StringParameter.swift @@ -8,9 +8,9 @@ @_expose(wasm, "bjs_checkString") @_cdecl("bjs_checkString") -public func _bjs_checkString(aBytes: Int32, aLen: Int32) -> Void { +public func _bjs_checkString(aBytes: Int32, aLength: Int32) -> Void { #if arch(wasm32) - checkString(a: String.bridgeJSLiftParameter(aBytes, aLen)) + checkString(a: String.bridgeJSLiftParameter(aBytes, aLength)) #else fatalError("Only available on WebAssembly") #endif diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftClass.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftClass.swift index 78f8c149..5a354b43 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftClass.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftClass.swift @@ -10,7 +10,7 @@ @_cdecl("bjs_takeGreeter") public func _bjs_takeGreeter(greeter: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - takeGreeter(greeter: Unmanaged.fromOpaque(greeter).takeUnretainedValue()) + takeGreeter(greeter: Greeter.bridgeJSLiftParameter(greeter)) #else fatalError("Only available on WebAssembly") #endif @@ -18,10 +18,10 @@ public func _bjs_takeGreeter(greeter: UnsafeMutableRawPointer) -> Void { @_expose(wasm, "bjs_Greeter_init") @_cdecl("bjs_Greeter_init") -public func _bjs_Greeter_init(nameBytes: Int32, nameLen: Int32) -> UnsafeMutableRawPointer { +public func _bjs_Greeter_init(nameBytes: Int32, nameLength: Int32) -> UnsafeMutableRawPointer { #if arch(wasm32) - let ret = Greeter(name: String.bridgeJSLiftParameter(nameBytes, nameLen)) - return Unmanaged.passRetained(ret).toOpaque() + let ret = Greeter(name: String.bridgeJSLiftParameter(nameBytes, nameLength)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -31,7 +31,7 @@ public func _bjs_Greeter_init(nameBytes: Int32, nameLen: Int32) -> UnsafeMutable @_cdecl("bjs_Greeter_greet") public func _bjs_Greeter_greet(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().greet() + let ret = Greeter.bridgeJSLiftParameter(_self).greet() return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -40,9 +40,9 @@ public func _bjs_Greeter_greet(_self: UnsafeMutableRawPointer) -> Void { @_expose(wasm, "bjs_Greeter_changeName") @_cdecl("bjs_Greeter_changeName") -public func _bjs_Greeter_changeName(_self: UnsafeMutableRawPointer, nameBytes: Int32, nameLen: Int32) -> Void { +public func _bjs_Greeter_changeName(_self: UnsafeMutableRawPointer, nameBytes: Int32, nameLength: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().changeName(name: String.bridgeJSLiftParameter(nameBytes, nameLen)) + Greeter.bridgeJSLiftParameter(_self).changeName(name: String.bridgeJSLiftParameter(nameBytes, nameLength)) #else fatalError("Only available on WebAssembly") #endif @@ -52,7 +52,7 @@ public func _bjs_Greeter_changeName(_self: UnsafeMutableRawPointer, nameBytes: I @_cdecl("bjs_Greeter_name_get") public func _bjs_Greeter_name_get(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().name + let ret = Greeter.bridgeJSLiftParameter(_self).name return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -61,9 +61,9 @@ public func _bjs_Greeter_name_get(_self: UnsafeMutableRawPointer) -> Void { @_expose(wasm, "bjs_Greeter_name_set") @_cdecl("bjs_Greeter_name_set") -public func _bjs_Greeter_name_set(_self: UnsafeMutableRawPointer, valueBytes: Int32, valueLen: Int32) -> Void { +public func _bjs_Greeter_name_set(_self: UnsafeMutableRawPointer, valueBytes: Int32, valueLength: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().name = String.bridgeJSLiftParameter(valueBytes, valueLen) + Greeter.bridgeJSLiftParameter(_self).name = String.bridgeJSLiftParameter(valueBytes, valueLength) #else fatalError("Only available on WebAssembly") #endif @@ -75,10 +75,16 @@ public func _bjs_Greeter_deinit(pointer: UnsafeMutableRawPointer) { Unmanaged.fromOpaque(pointer).release() } -extension Greeter: ConvertibleToJSValue { +extension Greeter: ConvertibleToJSValue, _BridgedSwiftHeapObject { var jsValue: JSValue { + #if arch(wasm32) @_extern(wasm, module: "TestModule", name: "bjs_Greeter_wrap") func _bjs_Greeter_wrap(_: UnsafeMutableRawPointer) -> Int32 + #else + func _bjs_Greeter_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") + } + #endif return .object(JSObject(id: UInt32(bitPattern: _bjs_Greeter_wrap(Unmanaged.passRetained(self).toOpaque())))) } } \ No newline at end of file diff --git a/Sources/JavaScriptKit/BridgeJSInstrincics.swift b/Sources/JavaScriptKit/BridgeJSInstrincics.swift index 2756cb59..4d609dc7 100644 --- a/Sources/JavaScriptKit/BridgeJSInstrincics.swift +++ b/Sources/JavaScriptKit/BridgeJSInstrincics.swift @@ -79,7 +79,24 @@ import _CJavaScriptKit // // See JSGlueGen.swift in BridgeJSLink for JS-side lowering/lifting implementation. -extension Bool { +/// A protocol that Swift types that can be lowered into a single Wasm core type. +public protocol _BridgedSwiftTypeLoweredIntoWasmCoreType { + associatedtype WasmCoreType +} + +/// A protocol that Swift types that can appear as parameters or return values on +/// The conformance is automatically synthesized by the BridgeJS code generator. +public protocol _BridgedSwiftTypeLoweredIntoSingleWasmCoreType { + associatedtype WasmCoreType + // MARK: ImportTS + consuming func bridgeJSLowerParameter() -> WasmCoreType + static func bridgeJSLiftReturn(_ value: WasmCoreType) -> Self + // MARK: ExportSwift + static func bridgeJSLiftParameter(_ value: WasmCoreType) -> Self + consuming func bridgeJSLowerReturn() -> WasmCoreType +} + +extension Bool: _BridgedSwiftTypeLoweredIntoSingleWasmCoreType { // MARK: ImportTS @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { self ? 1 : 0 @@ -96,7 +113,7 @@ extension Bool { } } -extension Int { +extension Int: _BridgedSwiftTypeLoweredIntoSingleWasmCoreType { // MARK: ImportTS @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { Int32(self) @@ -113,6 +130,40 @@ extension Int { } } +extension Float: _BridgedSwiftTypeLoweredIntoSingleWasmCoreType { + // MARK: ImportTS + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Float32 { + Float32(self) + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Float32) -> Float { + Float(value) + } + // MARK: ExportSwift + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Float32) -> Float { + Float(value) + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Float32 { + Float32(self) + } +} + +extension Double: _BridgedSwiftTypeLoweredIntoSingleWasmCoreType { + // MARK: ImportTS + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Float64 { + Float64(self) + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Float64) -> Double { + Double(value) + } + // MARK: ExportSwift + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Float64) -> Double { + Double(value) + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Float64 { + Float64(self) + } +} + extension String { // MARK: ImportTS @@ -213,3 +264,69 @@ extension JSObject { return _swift_js_retain(Int32(bitPattern: self.id)) } } + +/// A protocol that Swift heap objects exposed to JavaScript via `@JS class` must conform to. +/// +/// The conformance is automatically synthesized by the BridgeJS code generator. +public protocol _BridgedSwiftHeapObject: AnyObject {} + +/// Define the lowering/lifting for `_BridgedSwiftHeapObject` +extension _BridgedSwiftHeapObject { + + // MARK: ImportTS + @available(*, unavailable, message: "Swift heap objects are not supported to be passed to imported JS functions") + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Void {} + @available( + *, + unavailable, + message: "Swift heap objects are not supported to be returned from imported JS functions" + ) + @_spi(BridgeJS) public static func bridgeJSLiftReturn(_ pointer: UnsafeMutableRawPointer) -> Void {} + + // MARK: ExportSwift + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ pointer: UnsafeMutableRawPointer) -> Self { + Unmanaged.fromOpaque(pointer).takeUnretainedValue() + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> UnsafeMutableRawPointer { + // Perform a manual retain on the object, which will be balanced by a release called via FinalizationRegistry + return Unmanaged.passRetained(self).toOpaque() + } +} + +/// A protocol that Swift enum types that do not have a payload can conform to. +/// +/// The conformance is automatically synthesized by the BridgeJS code generator. +public protocol _BridgedSwiftEnumNoPayload {} + +extension _BridgedSwiftEnumNoPayload where Self: RawRepresentable, RawValue == String { + // MARK: ImportTS + @_spi(BridgeJS) public consuming func bridgeJSLowerParameter() -> Int32 { rawValue.bridgeJSLowerParameter() } + @_spi(BridgeJS) public static func bridgeJSLiftReturn(_ bytesCount: Int32) -> Self { + Self(rawValue: .bridgeJSLiftReturn(bytesCount))! + } + + // MARK: ExportSwift + @_spi(BridgeJS) public static func bridgeJSLiftParameter(_ bytes: Int32, _ count: Int32) -> Self { + Self(rawValue: .bridgeJSLiftParameter(bytes, count))! + } + @_spi(BridgeJS) public consuming func bridgeJSLowerReturn() -> Void { rawValue.bridgeJSLowerReturn() } +} + +extension _BridgedSwiftEnumNoPayload +where Self: RawRepresentable, RawValue: _BridgedSwiftTypeLoweredIntoSingleWasmCoreType { + // MARK: ImportTS + @_spi(BridgeJS) public consuming func bridgeJSLowerParameter() -> RawValue.WasmCoreType { + rawValue.bridgeJSLowerParameter() + } + @_spi(BridgeJS) public static func bridgeJSLiftReturn(_ value: RawValue.WasmCoreType) -> Self { + Self(rawValue: .bridgeJSLiftReturn(value))! + } + + // MARK: ExportSwift + @_spi(BridgeJS) public static func bridgeJSLiftParameter(_ value: RawValue.WasmCoreType) -> Self { + Self(rawValue: .bridgeJSLiftParameter(value))! + } + @_spi(BridgeJS) public consuming func bridgeJSLowerReturn() -> RawValue.WasmCoreType { + rawValue.bridgeJSLowerReturn() + } +} diff --git a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ExportSwift.swift b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ExportSwift.swift index 524d7424..e5999f4d 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ExportSwift.swift +++ b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ExportSwift.swift @@ -7,7 +7,20 @@ @_spi(BridgeJS) import JavaScriptKit extension Direction { - init?(bridgeJSRawValue: Int32) { + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + return bridgeJSRawValue + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Int32) -> Direction { + return Direction(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Int32) -> Direction { + return Direction(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Int32 { + return bridgeJSRawValue + } + + private init?(bridgeJSRawValue: Int32) { switch bridgeJSRawValue { case 0: self = .north @@ -22,7 +35,7 @@ extension Direction { } } - var bridgeJSRawValue: Int32 { + private var bridgeJSRawValue: Int32 { switch self { case .north: return 0 @@ -37,7 +50,20 @@ extension Direction { } extension Status { - init?(bridgeJSRawValue: Int32) { + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + return bridgeJSRawValue + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Int32) -> Status { + return Status(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Int32) -> Status { + return Status(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Int32 { + return bridgeJSRawValue + } + + private init?(bridgeJSRawValue: Int32) { switch bridgeJSRawValue { case 0: self = .loading @@ -50,7 +76,7 @@ extension Status { } } - var bridgeJSRawValue: Int32 { + private var bridgeJSRawValue: Int32 { switch self { case .loading: return 0 @@ -62,8 +88,27 @@ extension Status { } } +extension Theme: _BridgedSwiftEnumNoPayload { +} + +extension HttpStatus: _BridgedSwiftEnumNoPayload { +} + extension TSDirection { - init?(bridgeJSRawValue: Int32) { + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + return bridgeJSRawValue + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Int32) -> TSDirection { + return TSDirection(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Int32) -> TSDirection { + return TSDirection(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Int32 { + return bridgeJSRawValue + } + + private init?(bridgeJSRawValue: Int32) { switch bridgeJSRawValue { case 0: self = .north @@ -78,7 +123,7 @@ extension TSDirection { } } - var bridgeJSRawValue: Int32 { + private var bridgeJSRawValue: Int32 { switch self { case .north: return 0 @@ -92,8 +137,27 @@ extension TSDirection { } } +extension TSTheme: _BridgedSwiftEnumNoPayload { +} + +extension Utils: _BridgedSwiftEnumNoPayload { +} + extension Networking.API.Method { - init?(bridgeJSRawValue: Int32) { + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + return bridgeJSRawValue + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Int32) -> Networking.API.Method { + return Networking.API.Method(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Int32) -> Networking.API.Method { + return Networking.API.Method(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Int32 { + return bridgeJSRawValue + } + + private init?(bridgeJSRawValue: Int32) { switch bridgeJSRawValue { case 0: self = .get @@ -108,7 +172,7 @@ extension Networking.API.Method { } } - var bridgeJSRawValue: Int32 { + private var bridgeJSRawValue: Int32 { switch self { case .get: return 0 @@ -122,8 +186,27 @@ extension Networking.API.Method { } } +extension Configuration.LogLevel: _BridgedSwiftEnumNoPayload { +} + +extension Configuration.Port: _BridgedSwiftEnumNoPayload { +} + extension Internal.SupportedMethod { - init?(bridgeJSRawValue: Int32) { + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + return bridgeJSRawValue + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Int32) -> Internal.SupportedMethod { + return Internal.SupportedMethod(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Int32) -> Internal.SupportedMethod { + return Internal.SupportedMethod(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Int32 { + return bridgeJSRawValue + } + + private init?(bridgeJSRawValue: Int32) { switch bridgeJSRawValue { case 0: self = .get @@ -134,7 +217,7 @@ extension Internal.SupportedMethod { } } - var bridgeJSRawValue: Int32 { + private var bridgeJSRawValue: Int32 { switch self { case .get: return 0 @@ -159,7 +242,7 @@ public func _bjs_roundTripVoid() -> Void { public func _bjs_roundTripInt(v: Int32) -> Int32 { #if arch(wasm32) let ret = roundTripInt(v: Int.bridgeJSLiftParameter(v)) - return Int32(ret) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -169,8 +252,8 @@ public func _bjs_roundTripInt(v: Int32) -> Int32 { @_cdecl("bjs_roundTripFloat") public func _bjs_roundTripFloat(v: Float32) -> Float32 { #if arch(wasm32) - let ret = roundTripFloat(v: v) - return Float32(ret) + let ret = roundTripFloat(v: Float.bridgeJSLiftParameter(v)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -180,8 +263,8 @@ public func _bjs_roundTripFloat(v: Float32) -> Float32 { @_cdecl("bjs_roundTripDouble") public func _bjs_roundTripDouble(v: Float64) -> Float64 { #if arch(wasm32) - let ret = roundTripDouble(v: v) - return Float64(ret) + let ret = roundTripDouble(v: Double.bridgeJSLiftParameter(v)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -200,9 +283,9 @@ public func _bjs_roundTripBool(v: Int32) -> Int32 { @_expose(wasm, "bjs_roundTripString") @_cdecl("bjs_roundTripString") -public func _bjs_roundTripString(vBytes: Int32, vLen: Int32) -> Void { +public func _bjs_roundTripString(vBytes: Int32, vLength: Int32) -> Void { #if arch(wasm32) - let ret = roundTripString(v: String.bridgeJSLiftParameter(vBytes, vLen)) + let ret = roundTripString(v: String.bridgeJSLiftParameter(vBytes, vLength)) return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -213,8 +296,8 @@ public func _bjs_roundTripString(vBytes: Int32, vLen: Int32) -> Void { @_cdecl("bjs_roundTripSwiftHeapObject") public func _bjs_roundTripSwiftHeapObject(v: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer { #if arch(wasm32) - let ret = roundTripSwiftHeapObject(v: Unmanaged.fromOpaque(v).takeUnretainedValue()) - return Unmanaged.passRetained(ret).toOpaque() + let ret = roundTripSwiftHeapObject(v: Greeter.bridgeJSLiftParameter(v)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -261,7 +344,7 @@ public func _bjs_throwsWithIntResult() -> Int32 { #if arch(wasm32) do { let ret = try throwsWithIntResult() - return Int32(ret) + return ret.bridgeJSLowerReturn() } catch let error { if let error = error.thrownValue.object { withExtendedLifetime(error) { @@ -336,7 +419,7 @@ public func _bjs_throwsWithFloatResult() -> Float32 { #if arch(wasm32) do { let ret = try throwsWithFloatResult() - return Float32(ret) + return ret.bridgeJSLowerReturn() } catch let error { if let error = error.thrownValue.object { withExtendedLifetime(error) { @@ -361,7 +444,7 @@ public func _bjs_throwsWithDoubleResult() -> Float64 { #if arch(wasm32) do { let ret = try throwsWithDoubleResult() - return Float64(ret) + return ret.bridgeJSLowerReturn() } catch let error { if let error = error.thrownValue.object { withExtendedLifetime(error) { @@ -386,7 +469,7 @@ public func _bjs_throwsWithSwiftHeapObjectResult() -> UnsafeMutableRawPointer { #if arch(wasm32) do { let ret = try throwsWithSwiftHeapObjectResult() - return Unmanaged.passRetained(ret).toOpaque() + return ret.bridgeJSLowerReturn() } catch let error { if let error = error.thrownValue.object { withExtendedLifetime(error) { @@ -461,7 +544,7 @@ public func _bjs_asyncRoundTripInt(v: Int32) -> Int32 { public func _bjs_asyncRoundTripFloat(v: Float32) -> Int32 { #if arch(wasm32) let ret = JSPromise.async { - return await asyncRoundTripFloat(v: v).jsValue + return await asyncRoundTripFloat(v: Float.bridgeJSLiftParameter(v)).jsValue } .jsObject return ret.bridgeJSLowerReturn() #else @@ -474,7 +557,7 @@ public func _bjs_asyncRoundTripFloat(v: Float32) -> Int32 { public func _bjs_asyncRoundTripDouble(v: Float64) -> Int32 { #if arch(wasm32) let ret = JSPromise.async { - return await asyncRoundTripDouble(v: v).jsValue + return await asyncRoundTripDouble(v: Double.bridgeJSLiftParameter(v)).jsValue } .jsObject return ret.bridgeJSLowerReturn() #else @@ -497,10 +580,10 @@ public func _bjs_asyncRoundTripBool(v: Int32) -> Int32 { @_expose(wasm, "bjs_asyncRoundTripString") @_cdecl("bjs_asyncRoundTripString") -public func _bjs_asyncRoundTripString(vBytes: Int32, vLen: Int32) -> Int32 { +public func _bjs_asyncRoundTripString(vBytes: Int32, vLength: Int32) -> Int32 { #if arch(wasm32) let ret = JSPromise.async { - return await asyncRoundTripString(v: String.bridgeJSLiftParameter(vBytes, vLen)).jsValue + return await asyncRoundTripString(v: String.bridgeJSLiftParameter(vBytes, vLength)).jsValue } .jsObject return ret.bridgeJSLowerReturn() #else @@ -513,7 +596,7 @@ public func _bjs_asyncRoundTripString(vBytes: Int32, vLen: Int32) -> Int32 { public func _bjs_asyncRoundTripSwiftHeapObject(v: UnsafeMutableRawPointer) -> Int32 { #if arch(wasm32) let ret = JSPromise.async { - return await asyncRoundTripSwiftHeapObject(v: Unmanaged.fromOpaque(v).takeUnretainedValue()).jsValue + return await asyncRoundTripSwiftHeapObject(v: Greeter.bridgeJSLiftParameter(v)).jsValue } .jsObject return ret.bridgeJSLowerReturn() #else @@ -536,9 +619,9 @@ public func _bjs_asyncRoundTripJSObject(v: Int32) -> Int32 { @_expose(wasm, "bjs_takeGreeter") @_cdecl("bjs_takeGreeter") -public func _bjs_takeGreeter(g: UnsafeMutableRawPointer, nameBytes: Int32, nameLen: Int32) -> Void { +public func _bjs_takeGreeter(g: UnsafeMutableRawPointer, nameBytes: Int32, nameLength: Int32) -> Void { #if arch(wasm32) - takeGreeter(g: Unmanaged.fromOpaque(g).takeUnretainedValue(), name: String.bridgeJSLiftParameter(nameBytes, nameLen)) + takeGreeter(g: Greeter.bridgeJSLiftParameter(g), name: String.bridgeJSLiftParameter(nameBytes, nameLength)) #else fatalError("Only available on WebAssembly") #endif @@ -549,7 +632,7 @@ public func _bjs_takeGreeter(g: UnsafeMutableRawPointer, nameBytes: Int32, nameL public func _bjs_createCalculator() -> UnsafeMutableRawPointer { #if arch(wasm32) let ret = createCalculator() - return Unmanaged.passRetained(ret).toOpaque() + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -559,8 +642,8 @@ public func _bjs_createCalculator() -> UnsafeMutableRawPointer { @_cdecl("bjs_useCalculator") public func _bjs_useCalculator(calc: UnsafeMutableRawPointer, x: Int32, y: Int32) -> Int32 { #if arch(wasm32) - let ret = useCalculator(calc: Unmanaged.fromOpaque(calc).takeUnretainedValue(), x: Int.bridgeJSLiftParameter(x), y: Int.bridgeJSLiftParameter(y)) - return Int32(ret) + let ret = useCalculator(calc: Calculator.bridgeJSLiftParameter(calc), x: Int.bridgeJSLiftParameter(x), y: Int.bridgeJSLiftParameter(y)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -592,7 +675,7 @@ public func _bjs_testCalculatorToJSValue() -> Int32 { @_cdecl("bjs_testSwiftClassAsJSValue") public func _bjs_testSwiftClassAsJSValue(greeter: UnsafeMutableRawPointer) -> Int32 { #if arch(wasm32) - let ret = testSwiftClassAsJSValue(greeter: Unmanaged.fromOpaque(greeter).takeUnretainedValue()) + let ret = testSwiftClassAsJSValue(greeter: Greeter.bridgeJSLiftParameter(greeter)) return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -603,8 +686,8 @@ public func _bjs_testSwiftClassAsJSValue(greeter: UnsafeMutableRawPointer) -> In @_cdecl("bjs_setDirection") public func _bjs_setDirection(direction: Int32) -> Int32 { #if arch(wasm32) - let ret = setDirection(_: Direction(bridgeJSRawValue: direction)!) - return ret.bridgeJSRawValue + let ret = setDirection(_: Direction.bridgeJSLiftParameter(direction)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -615,7 +698,7 @@ public func _bjs_setDirection(direction: Int32) -> Int32 { public func _bjs_getDirection() -> Int32 { #if arch(wasm32) let ret = getDirection() - return ret.bridgeJSRawValue + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -625,8 +708,8 @@ public func _bjs_getDirection() -> Int32 { @_cdecl("bjs_processDirection") public func _bjs_processDirection(input: Int32) -> Int32 { #if arch(wasm32) - let ret = processDirection(_: Direction(bridgeJSRawValue: input)!) - return ret.bridgeJSRawValue + let ret = processDirection(_: Direction.bridgeJSLiftParameter(input)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -634,10 +717,10 @@ public func _bjs_processDirection(input: Int32) -> Int32 { @_expose(wasm, "bjs_setTheme") @_cdecl("bjs_setTheme") -public func _bjs_setTheme(themeBytes: Int32, themeLen: Int32) -> Void { +public func _bjs_setTheme(themeBytes: Int32, themeLength: Int32) -> Void { #if arch(wasm32) - let ret = setTheme(_: Theme(rawValue: String.bridgeJSLiftParameter(themeBytes, themeLen))!) - return ret.rawValue.bridgeJSLowerReturn() + let ret = setTheme(_: Theme.bridgeJSLiftParameter(themeBytes, themeLength)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -648,7 +731,7 @@ public func _bjs_setTheme(themeBytes: Int32, themeLen: Int32) -> Void { public func _bjs_getTheme() -> Void { #if arch(wasm32) let ret = getTheme() - return ret.rawValue.bridgeJSLowerReturn() + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -658,8 +741,8 @@ public func _bjs_getTheme() -> Void { @_cdecl("bjs_setHttpStatus") public func _bjs_setHttpStatus(status: Int32) -> Int32 { #if arch(wasm32) - let ret = setHttpStatus(_: HttpStatus(rawValue: Int(status))!) - return Int32(ret.rawValue) + let ret = setHttpStatus(_: HttpStatus.bridgeJSLiftParameter(status)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -670,7 +753,7 @@ public func _bjs_setHttpStatus(status: Int32) -> Int32 { public func _bjs_getHttpStatus() -> Int32 { #if arch(wasm32) let ret = getHttpStatus() - return Int32(ret.rawValue) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -678,10 +761,10 @@ public func _bjs_getHttpStatus() -> Int32 { @_expose(wasm, "bjs_processTheme") @_cdecl("bjs_processTheme") -public func _bjs_processTheme(themeBytes: Int32, themeLen: Int32) -> Int32 { +public func _bjs_processTheme(themeBytes: Int32, themeLength: Int32) -> Int32 { #if arch(wasm32) - let ret = processTheme(_: Theme(rawValue: String.bridgeJSLiftParameter(themeBytes, themeLen))!) - return Int32(ret.rawValue) + let ret = processTheme(_: Theme.bridgeJSLiftParameter(themeBytes, themeLength)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -691,8 +774,8 @@ public func _bjs_processTheme(themeBytes: Int32, themeLen: Int32) -> Int32 { @_cdecl("bjs_setTSDirection") public func _bjs_setTSDirection(direction: Int32) -> Int32 { #if arch(wasm32) - let ret = setTSDirection(_: TSDirection(bridgeJSRawValue: direction)!) - return ret.bridgeJSRawValue + let ret = setTSDirection(_: TSDirection.bridgeJSLiftParameter(direction)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -703,7 +786,7 @@ public func _bjs_setTSDirection(direction: Int32) -> Int32 { public func _bjs_getTSDirection() -> Int32 { #if arch(wasm32) let ret = getTSDirection() - return ret.bridgeJSRawValue + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -711,10 +794,10 @@ public func _bjs_getTSDirection() -> Int32 { @_expose(wasm, "bjs_setTSTheme") @_cdecl("bjs_setTSTheme") -public func _bjs_setTSTheme(themeBytes: Int32, themeLen: Int32) -> Void { +public func _bjs_setTSTheme(themeBytes: Int32, themeLength: Int32) -> Void { #if arch(wasm32) - let ret = setTSTheme(_: TSTheme(rawValue: String.bridgeJSLiftParameter(themeBytes, themeLen))!) - return ret.rawValue.bridgeJSLowerReturn() + let ret = setTSTheme(_: TSTheme.bridgeJSLiftParameter(themeBytes, themeLength)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -725,7 +808,7 @@ public func _bjs_setTSTheme(themeBytes: Int32, themeLen: Int32) -> Void { public func _bjs_getTSTheme() -> Void { #if arch(wasm32) let ret = getTSTheme() - return ret.rawValue.bridgeJSLowerReturn() + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -733,10 +816,10 @@ public func _bjs_getTSTheme() -> Void { @_expose(wasm, "bjs_createPropertyHolder") @_cdecl("bjs_createPropertyHolder") -public func _bjs_createPropertyHolder(intValue: Int32, floatValue: Float32, doubleValue: Float64, boolValue: Int32, stringValueBytes: Int32, stringValueLen: Int32, jsObject: Int32) -> UnsafeMutableRawPointer { +public func _bjs_createPropertyHolder(intValue: Int32, floatValue: Float32, doubleValue: Float64, boolValue: Int32, stringValueBytes: Int32, stringValueLength: Int32, jsObject: Int32) -> UnsafeMutableRawPointer { #if arch(wasm32) - let ret = createPropertyHolder(intValue: Int.bridgeJSLiftParameter(intValue), floatValue: floatValue, doubleValue: doubleValue, boolValue: Bool.bridgeJSLiftParameter(boolValue), stringValue: String.bridgeJSLiftParameter(stringValueBytes, stringValueLen), jsObject: JSObject.bridgeJSLiftParameter(jsObject)) - return Unmanaged.passRetained(ret).toOpaque() + let ret = createPropertyHolder(intValue: Int.bridgeJSLiftParameter(intValue), floatValue: Float.bridgeJSLiftParameter(floatValue), doubleValue: Double.bridgeJSLiftParameter(doubleValue), boolValue: Bool.bridgeJSLiftParameter(boolValue), stringValue: String.bridgeJSLiftParameter(stringValueBytes, stringValueLength), jsObject: JSObject.bridgeJSLiftParameter(jsObject)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -746,7 +829,7 @@ public func _bjs_createPropertyHolder(intValue: Int32, floatValue: Float32, doub @_cdecl("bjs_testPropertyHolder") public func _bjs_testPropertyHolder(holder: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - let ret = testPropertyHolder(holder: Unmanaged.fromOpaque(holder).takeUnretainedValue()) + let ret = testPropertyHolder(holder: PropertyHolder.bridgeJSLiftParameter(holder)) return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -776,10 +859,10 @@ public func _bjs_getObserverStats() -> Void { @_expose(wasm, "bjs_Greeter_init") @_cdecl("bjs_Greeter_init") -public func _bjs_Greeter_init(nameBytes: Int32, nameLen: Int32) -> UnsafeMutableRawPointer { +public func _bjs_Greeter_init(nameBytes: Int32, nameLength: Int32) -> UnsafeMutableRawPointer { #if arch(wasm32) - let ret = Greeter(name: String.bridgeJSLiftParameter(nameBytes, nameLen)) - return Unmanaged.passRetained(ret).toOpaque() + let ret = Greeter(name: String.bridgeJSLiftParameter(nameBytes, nameLength)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -789,7 +872,7 @@ public func _bjs_Greeter_init(nameBytes: Int32, nameLen: Int32) -> UnsafeMutable @_cdecl("bjs_Greeter_greet") public func _bjs_Greeter_greet(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().greet() + let ret = Greeter.bridgeJSLiftParameter(_self).greet() return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -798,9 +881,9 @@ public func _bjs_Greeter_greet(_self: UnsafeMutableRawPointer) -> Void { @_expose(wasm, "bjs_Greeter_changeName") @_cdecl("bjs_Greeter_changeName") -public func _bjs_Greeter_changeName(_self: UnsafeMutableRawPointer, nameBytes: Int32, nameLen: Int32) -> Void { +public func _bjs_Greeter_changeName(_self: UnsafeMutableRawPointer, nameBytes: Int32, nameLength: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().changeName(name: String.bridgeJSLiftParameter(nameBytes, nameLen)) + Greeter.bridgeJSLiftParameter(_self).changeName(name: String.bridgeJSLiftParameter(nameBytes, nameLength)) #else fatalError("Only available on WebAssembly") #endif @@ -810,7 +893,7 @@ public func _bjs_Greeter_changeName(_self: UnsafeMutableRawPointer, nameBytes: I @_cdecl("bjs_Greeter_name_get") public func _bjs_Greeter_name_get(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().name + let ret = Greeter.bridgeJSLiftParameter(_self).name return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -819,9 +902,9 @@ public func _bjs_Greeter_name_get(_self: UnsafeMutableRawPointer) -> Void { @_expose(wasm, "bjs_Greeter_name_set") @_cdecl("bjs_Greeter_name_set") -public func _bjs_Greeter_name_set(_self: UnsafeMutableRawPointer, valueBytes: Int32, valueLen: Int32) -> Void { +public func _bjs_Greeter_name_set(_self: UnsafeMutableRawPointer, valueBytes: Int32, valueLength: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().name = String.bridgeJSLiftParameter(valueBytes, valueLen) + Greeter.bridgeJSLiftParameter(_self).name = String.bridgeJSLiftParameter(valueBytes, valueLength) #else fatalError("Only available on WebAssembly") #endif @@ -831,7 +914,7 @@ public func _bjs_Greeter_name_set(_self: UnsafeMutableRawPointer, valueBytes: In @_cdecl("bjs_Greeter_prefix_get") public func _bjs_Greeter_prefix_get(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().prefix + let ret = Greeter.bridgeJSLiftParameter(_self).prefix return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -844,10 +927,16 @@ public func _bjs_Greeter_deinit(pointer: UnsafeMutableRawPointer) { Unmanaged.fromOpaque(pointer).release() } -extension Greeter: ConvertibleToJSValue { +extension Greeter: ConvertibleToJSValue, _BridgedSwiftHeapObject { var jsValue: JSValue { + #if arch(wasm32) @_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_Greeter_wrap") func _bjs_Greeter_wrap(_: UnsafeMutableRawPointer) -> Int32 + #else + func _bjs_Greeter_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") + } + #endif return .object(JSObject(id: UInt32(bitPattern: _bjs_Greeter_wrap(Unmanaged.passRetained(self).toOpaque())))) } } @@ -856,8 +945,8 @@ extension Greeter: ConvertibleToJSValue { @_cdecl("bjs_Calculator_square") public func _bjs_Calculator_square(_self: UnsafeMutableRawPointer, value: Int32) -> Int32 { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().square(value: Int.bridgeJSLiftParameter(value)) - return Int32(ret) + let ret = Calculator.bridgeJSLiftParameter(_self).square(value: Int.bridgeJSLiftParameter(value)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -867,8 +956,8 @@ public func _bjs_Calculator_square(_self: UnsafeMutableRawPointer, value: Int32) @_cdecl("bjs_Calculator_add") public func _bjs_Calculator_add(_self: UnsafeMutableRawPointer, a: Int32, b: Int32) -> Int32 { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().add(a: Int.bridgeJSLiftParameter(a), b: Int.bridgeJSLiftParameter(b)) - return Int32(ret) + let ret = Calculator.bridgeJSLiftParameter(_self).add(a: Int.bridgeJSLiftParameter(a), b: Int.bridgeJSLiftParameter(b)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -880,10 +969,16 @@ public func _bjs_Calculator_deinit(pointer: UnsafeMutableRawPointer) { Unmanaged.fromOpaque(pointer).release() } -extension Calculator: ConvertibleToJSValue { +extension Calculator: ConvertibleToJSValue, _BridgedSwiftHeapObject { var jsValue: JSValue { + #if arch(wasm32) @_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_Calculator_wrap") func _bjs_Calculator_wrap(_: UnsafeMutableRawPointer) -> Int32 + #else + func _bjs_Calculator_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") + } + #endif return .object(JSObject(id: UInt32(bitPattern: _bjs_Calculator_wrap(Unmanaged.passRetained(self).toOpaque())))) } } @@ -893,7 +988,7 @@ extension Calculator: ConvertibleToJSValue { public func _bjs_Converter_init() -> UnsafeMutableRawPointer { #if arch(wasm32) let ret = Utils.Converter() - return Unmanaged.passRetained(ret).toOpaque() + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -903,7 +998,7 @@ public func _bjs_Converter_init() -> UnsafeMutableRawPointer { @_cdecl("bjs_Converter_toString") public func _bjs_Converter_toString(_self: UnsafeMutableRawPointer, value: Int32) -> Void { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().toString(value: Int.bridgeJSLiftParameter(value)) + let ret = Utils.Converter.bridgeJSLiftParameter(_self).toString(value: Int.bridgeJSLiftParameter(value)) return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -916,10 +1011,16 @@ public func _bjs_Converter_deinit(pointer: UnsafeMutableRawPointer) { Unmanaged.fromOpaque(pointer).release() } -extension Utils.Converter: ConvertibleToJSValue { +extension Utils.Converter: ConvertibleToJSValue, _BridgedSwiftHeapObject { var jsValue: JSValue { + #if arch(wasm32) @_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_Converter_wrap") func _bjs_Converter_wrap(_: UnsafeMutableRawPointer) -> Int32 + #else + func _bjs_Converter_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") + } + #endif return .object(JSObject(id: UInt32(bitPattern: _bjs_Converter_wrap(Unmanaged.passRetained(self).toOpaque())))) } } @@ -929,7 +1030,7 @@ extension Utils.Converter: ConvertibleToJSValue { public func _bjs_HTTPServer_init() -> UnsafeMutableRawPointer { #if arch(wasm32) let ret = Networking.API.HTTPServer() - return Unmanaged.passRetained(ret).toOpaque() + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -939,7 +1040,7 @@ public func _bjs_HTTPServer_init() -> UnsafeMutableRawPointer { @_cdecl("bjs_HTTPServer_call") public func _bjs_HTTPServer_call(_self: UnsafeMutableRawPointer, method: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().call(_: Networking.API.Method(bridgeJSRawValue: method)!) + Networking.API.HTTPServer.bridgeJSLiftParameter(_self).call(_: Networking.API.Method.bridgeJSLiftParameter(method)) #else fatalError("Only available on WebAssembly") #endif @@ -951,10 +1052,16 @@ public func _bjs_HTTPServer_deinit(pointer: UnsafeMutableRawPointer) { Unmanaged.fromOpaque(pointer).release() } -extension Networking.API.HTTPServer: ConvertibleToJSValue { +extension Networking.API.HTTPServer: ConvertibleToJSValue, _BridgedSwiftHeapObject { var jsValue: JSValue { + #if arch(wasm32) @_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_HTTPServer_wrap") func _bjs_HTTPServer_wrap(_: UnsafeMutableRawPointer) -> Int32 + #else + func _bjs_HTTPServer_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") + } + #endif return .object(JSObject(id: UInt32(bitPattern: _bjs_HTTPServer_wrap(Unmanaged.passRetained(self).toOpaque())))) } } @@ -964,7 +1071,7 @@ extension Networking.API.HTTPServer: ConvertibleToJSValue { public func _bjs_TestServer_init() -> UnsafeMutableRawPointer { #if arch(wasm32) let ret = Internal.TestServer() - return Unmanaged.passRetained(ret).toOpaque() + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -974,7 +1081,7 @@ public func _bjs_TestServer_init() -> UnsafeMutableRawPointer { @_cdecl("bjs_TestServer_call") public func _bjs_TestServer_call(_self: UnsafeMutableRawPointer, method: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().call(_: Internal.SupportedMethod(bridgeJSRawValue: method)!) + Internal.TestServer.bridgeJSLiftParameter(_self).call(_: Internal.SupportedMethod.bridgeJSLiftParameter(method)) #else fatalError("Only available on WebAssembly") #endif @@ -986,10 +1093,16 @@ public func _bjs_TestServer_deinit(pointer: UnsafeMutableRawPointer) { Unmanaged.fromOpaque(pointer).release() } -extension Internal.TestServer: ConvertibleToJSValue { +extension Internal.TestServer: ConvertibleToJSValue, _BridgedSwiftHeapObject { var jsValue: JSValue { + #if arch(wasm32) @_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_TestServer_wrap") func _bjs_TestServer_wrap(_: UnsafeMutableRawPointer) -> Int32 + #else + func _bjs_TestServer_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") + } + #endif return .object(JSObject(id: UInt32(bitPattern: _bjs_TestServer_wrap(Unmanaged.passRetained(self).toOpaque())))) } } @@ -999,7 +1112,7 @@ extension Internal.TestServer: ConvertibleToJSValue { public func _bjs_SimplePropertyHolder_init(value: Int32) -> UnsafeMutableRawPointer { #if arch(wasm32) let ret = SimplePropertyHolder(value: Int.bridgeJSLiftParameter(value)) - return Unmanaged.passRetained(ret).toOpaque() + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -1009,8 +1122,8 @@ public func _bjs_SimplePropertyHolder_init(value: Int32) -> UnsafeMutableRawPoin @_cdecl("bjs_SimplePropertyHolder_value_get") public func _bjs_SimplePropertyHolder_value_get(_self: UnsafeMutableRawPointer) -> Int32 { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().value - return Int32(ret) + let ret = SimplePropertyHolder.bridgeJSLiftParameter(_self).value + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -1020,7 +1133,7 @@ public func _bjs_SimplePropertyHolder_value_get(_self: UnsafeMutableRawPointer) @_cdecl("bjs_SimplePropertyHolder_value_set") public func _bjs_SimplePropertyHolder_value_set(_self: UnsafeMutableRawPointer, value: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().value = Int.bridgeJSLiftParameter(value) + SimplePropertyHolder.bridgeJSLiftParameter(_self).value = Int.bridgeJSLiftParameter(value) #else fatalError("Only available on WebAssembly") #endif @@ -1032,20 +1145,26 @@ public func _bjs_SimplePropertyHolder_deinit(pointer: UnsafeMutableRawPointer) { Unmanaged.fromOpaque(pointer).release() } -extension SimplePropertyHolder: ConvertibleToJSValue { +extension SimplePropertyHolder: ConvertibleToJSValue, _BridgedSwiftHeapObject { var jsValue: JSValue { + #if arch(wasm32) @_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_SimplePropertyHolder_wrap") func _bjs_SimplePropertyHolder_wrap(_: UnsafeMutableRawPointer) -> Int32 + #else + func _bjs_SimplePropertyHolder_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") + } + #endif return .object(JSObject(id: UInt32(bitPattern: _bjs_SimplePropertyHolder_wrap(Unmanaged.passRetained(self).toOpaque())))) } } @_expose(wasm, "bjs_PropertyHolder_init") @_cdecl("bjs_PropertyHolder_init") -public func _bjs_PropertyHolder_init(intValue: Int32, floatValue: Float32, doubleValue: Float64, boolValue: Int32, stringValueBytes: Int32, stringValueLen: Int32, jsObject: Int32, sibling: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer { +public func _bjs_PropertyHolder_init(intValue: Int32, floatValue: Float32, doubleValue: Float64, boolValue: Int32, stringValueBytes: Int32, stringValueLength: Int32, jsObject: Int32, sibling: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer { #if arch(wasm32) - let ret = PropertyHolder(intValue: Int.bridgeJSLiftParameter(intValue), floatValue: floatValue, doubleValue: doubleValue, boolValue: Bool.bridgeJSLiftParameter(boolValue), stringValue: String.bridgeJSLiftParameter(stringValueBytes, stringValueLen), jsObject: JSObject.bridgeJSLiftParameter(jsObject), sibling: Unmanaged.fromOpaque(sibling).takeUnretainedValue()) - return Unmanaged.passRetained(ret).toOpaque() + let ret = PropertyHolder(intValue: Int.bridgeJSLiftParameter(intValue), floatValue: Float.bridgeJSLiftParameter(floatValue), doubleValue: Double.bridgeJSLiftParameter(doubleValue), boolValue: Bool.bridgeJSLiftParameter(boolValue), stringValue: String.bridgeJSLiftParameter(stringValueBytes, stringValueLength), jsObject: JSObject.bridgeJSLiftParameter(jsObject), sibling: SimplePropertyHolder.bridgeJSLiftParameter(sibling)) + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -1055,7 +1174,7 @@ public func _bjs_PropertyHolder_init(intValue: Int32, floatValue: Float32, doubl @_cdecl("bjs_PropertyHolder_getAllValues") public func _bjs_PropertyHolder_getAllValues(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().getAllValues() + let ret = PropertyHolder.bridgeJSLiftParameter(_self).getAllValues() return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -1066,8 +1185,8 @@ public func _bjs_PropertyHolder_getAllValues(_self: UnsafeMutableRawPointer) -> @_cdecl("bjs_PropertyHolder_intValue_get") public func _bjs_PropertyHolder_intValue_get(_self: UnsafeMutableRawPointer) -> Int32 { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().intValue - return Int32(ret) + let ret = PropertyHolder.bridgeJSLiftParameter(_self).intValue + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -1077,7 +1196,7 @@ public func _bjs_PropertyHolder_intValue_get(_self: UnsafeMutableRawPointer) -> @_cdecl("bjs_PropertyHolder_intValue_set") public func _bjs_PropertyHolder_intValue_set(_self: UnsafeMutableRawPointer, value: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().intValue = Int.bridgeJSLiftParameter(value) + PropertyHolder.bridgeJSLiftParameter(_self).intValue = Int.bridgeJSLiftParameter(value) #else fatalError("Only available on WebAssembly") #endif @@ -1087,8 +1206,8 @@ public func _bjs_PropertyHolder_intValue_set(_self: UnsafeMutableRawPointer, val @_cdecl("bjs_PropertyHolder_floatValue_get") public func _bjs_PropertyHolder_floatValue_get(_self: UnsafeMutableRawPointer) -> Float32 { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().floatValue - return Float32(ret) + let ret = PropertyHolder.bridgeJSLiftParameter(_self).floatValue + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -1098,7 +1217,7 @@ public func _bjs_PropertyHolder_floatValue_get(_self: UnsafeMutableRawPointer) - @_cdecl("bjs_PropertyHolder_floatValue_set") public func _bjs_PropertyHolder_floatValue_set(_self: UnsafeMutableRawPointer, value: Float32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().floatValue = value + PropertyHolder.bridgeJSLiftParameter(_self).floatValue = Float.bridgeJSLiftParameter(value) #else fatalError("Only available on WebAssembly") #endif @@ -1108,8 +1227,8 @@ public func _bjs_PropertyHolder_floatValue_set(_self: UnsafeMutableRawPointer, v @_cdecl("bjs_PropertyHolder_doubleValue_get") public func _bjs_PropertyHolder_doubleValue_get(_self: UnsafeMutableRawPointer) -> Float64 { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().doubleValue - return Float64(ret) + let ret = PropertyHolder.bridgeJSLiftParameter(_self).doubleValue + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -1119,7 +1238,7 @@ public func _bjs_PropertyHolder_doubleValue_get(_self: UnsafeMutableRawPointer) @_cdecl("bjs_PropertyHolder_doubleValue_set") public func _bjs_PropertyHolder_doubleValue_set(_self: UnsafeMutableRawPointer, value: Float64) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().doubleValue = value + PropertyHolder.bridgeJSLiftParameter(_self).doubleValue = Double.bridgeJSLiftParameter(value) #else fatalError("Only available on WebAssembly") #endif @@ -1129,7 +1248,7 @@ public func _bjs_PropertyHolder_doubleValue_set(_self: UnsafeMutableRawPointer, @_cdecl("bjs_PropertyHolder_boolValue_get") public func _bjs_PropertyHolder_boolValue_get(_self: UnsafeMutableRawPointer) -> Int32 { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().boolValue + let ret = PropertyHolder.bridgeJSLiftParameter(_self).boolValue return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -1140,7 +1259,7 @@ public func _bjs_PropertyHolder_boolValue_get(_self: UnsafeMutableRawPointer) -> @_cdecl("bjs_PropertyHolder_boolValue_set") public func _bjs_PropertyHolder_boolValue_set(_self: UnsafeMutableRawPointer, value: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().boolValue = Bool.bridgeJSLiftParameter(value) + PropertyHolder.bridgeJSLiftParameter(_self).boolValue = Bool.bridgeJSLiftParameter(value) #else fatalError("Only available on WebAssembly") #endif @@ -1150,7 +1269,7 @@ public func _bjs_PropertyHolder_boolValue_set(_self: UnsafeMutableRawPointer, va @_cdecl("bjs_PropertyHolder_stringValue_get") public func _bjs_PropertyHolder_stringValue_get(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().stringValue + let ret = PropertyHolder.bridgeJSLiftParameter(_self).stringValue return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -1159,9 +1278,9 @@ public func _bjs_PropertyHolder_stringValue_get(_self: UnsafeMutableRawPointer) @_expose(wasm, "bjs_PropertyHolder_stringValue_set") @_cdecl("bjs_PropertyHolder_stringValue_set") -public func _bjs_PropertyHolder_stringValue_set(_self: UnsafeMutableRawPointer, valueBytes: Int32, valueLen: Int32) -> Void { +public func _bjs_PropertyHolder_stringValue_set(_self: UnsafeMutableRawPointer, valueBytes: Int32, valueLength: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().stringValue = String.bridgeJSLiftParameter(valueBytes, valueLen) + PropertyHolder.bridgeJSLiftParameter(_self).stringValue = String.bridgeJSLiftParameter(valueBytes, valueLength) #else fatalError("Only available on WebAssembly") #endif @@ -1171,8 +1290,8 @@ public func _bjs_PropertyHolder_stringValue_set(_self: UnsafeMutableRawPointer, @_cdecl("bjs_PropertyHolder_readonlyInt_get") public func _bjs_PropertyHolder_readonlyInt_get(_self: UnsafeMutableRawPointer) -> Int32 { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().readonlyInt - return Int32(ret) + let ret = PropertyHolder.bridgeJSLiftParameter(_self).readonlyInt + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -1182,8 +1301,8 @@ public func _bjs_PropertyHolder_readonlyInt_get(_self: UnsafeMutableRawPointer) @_cdecl("bjs_PropertyHolder_readonlyFloat_get") public func _bjs_PropertyHolder_readonlyFloat_get(_self: UnsafeMutableRawPointer) -> Float32 { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().readonlyFloat - return Float32(ret) + let ret = PropertyHolder.bridgeJSLiftParameter(_self).readonlyFloat + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -1193,8 +1312,8 @@ public func _bjs_PropertyHolder_readonlyFloat_get(_self: UnsafeMutableRawPointer @_cdecl("bjs_PropertyHolder_readonlyDouble_get") public func _bjs_PropertyHolder_readonlyDouble_get(_self: UnsafeMutableRawPointer) -> Float64 { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().readonlyDouble - return Float64(ret) + let ret = PropertyHolder.bridgeJSLiftParameter(_self).readonlyDouble + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -1204,7 +1323,7 @@ public func _bjs_PropertyHolder_readonlyDouble_get(_self: UnsafeMutableRawPointe @_cdecl("bjs_PropertyHolder_readonlyBool_get") public func _bjs_PropertyHolder_readonlyBool_get(_self: UnsafeMutableRawPointer) -> Int32 { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().readonlyBool + let ret = PropertyHolder.bridgeJSLiftParameter(_self).readonlyBool return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -1215,7 +1334,7 @@ public func _bjs_PropertyHolder_readonlyBool_get(_self: UnsafeMutableRawPointer) @_cdecl("bjs_PropertyHolder_readonlyString_get") public func _bjs_PropertyHolder_readonlyString_get(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().readonlyString + let ret = PropertyHolder.bridgeJSLiftParameter(_self).readonlyString return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -1226,7 +1345,7 @@ public func _bjs_PropertyHolder_readonlyString_get(_self: UnsafeMutableRawPointe @_cdecl("bjs_PropertyHolder_jsObject_get") public func _bjs_PropertyHolder_jsObject_get(_self: UnsafeMutableRawPointer) -> Int32 { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().jsObject + let ret = PropertyHolder.bridgeJSLiftParameter(_self).jsObject return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -1237,7 +1356,7 @@ public func _bjs_PropertyHolder_jsObject_get(_self: UnsafeMutableRawPointer) -> @_cdecl("bjs_PropertyHolder_jsObject_set") public func _bjs_PropertyHolder_jsObject_set(_self: UnsafeMutableRawPointer, value: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().jsObject = JSObject.bridgeJSLiftParameter(value) + PropertyHolder.bridgeJSLiftParameter(_self).jsObject = JSObject.bridgeJSLiftParameter(value) #else fatalError("Only available on WebAssembly") #endif @@ -1247,8 +1366,8 @@ public func _bjs_PropertyHolder_jsObject_set(_self: UnsafeMutableRawPointer, val @_cdecl("bjs_PropertyHolder_sibling_get") public func _bjs_PropertyHolder_sibling_get(_self: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().sibling - return Unmanaged.passRetained(ret).toOpaque() + let ret = PropertyHolder.bridgeJSLiftParameter(_self).sibling + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -1258,7 +1377,7 @@ public func _bjs_PropertyHolder_sibling_get(_self: UnsafeMutableRawPointer) -> U @_cdecl("bjs_PropertyHolder_sibling_set") public func _bjs_PropertyHolder_sibling_set(_self: UnsafeMutableRawPointer, value: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().sibling = Unmanaged.fromOpaque(value).takeUnretainedValue() + PropertyHolder.bridgeJSLiftParameter(_self).sibling = SimplePropertyHolder.bridgeJSLiftParameter(value) #else fatalError("Only available on WebAssembly") #endif @@ -1268,7 +1387,7 @@ public func _bjs_PropertyHolder_sibling_set(_self: UnsafeMutableRawPointer, valu @_cdecl("bjs_PropertyHolder_lazyValue_get") public func _bjs_PropertyHolder_lazyValue_get(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().lazyValue + let ret = PropertyHolder.bridgeJSLiftParameter(_self).lazyValue return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -1277,9 +1396,9 @@ public func _bjs_PropertyHolder_lazyValue_get(_self: UnsafeMutableRawPointer) -> @_expose(wasm, "bjs_PropertyHolder_lazyValue_set") @_cdecl("bjs_PropertyHolder_lazyValue_set") -public func _bjs_PropertyHolder_lazyValue_set(_self: UnsafeMutableRawPointer, valueBytes: Int32, valueLen: Int32) -> Void { +public func _bjs_PropertyHolder_lazyValue_set(_self: UnsafeMutableRawPointer, valueBytes: Int32, valueLength: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().lazyValue = String.bridgeJSLiftParameter(valueBytes, valueLen) + PropertyHolder.bridgeJSLiftParameter(_self).lazyValue = String.bridgeJSLiftParameter(valueBytes, valueLength) #else fatalError("Only available on WebAssembly") #endif @@ -1289,8 +1408,8 @@ public func _bjs_PropertyHolder_lazyValue_set(_self: UnsafeMutableRawPointer, va @_cdecl("bjs_PropertyHolder_computedReadonly_get") public func _bjs_PropertyHolder_computedReadonly_get(_self: UnsafeMutableRawPointer) -> Int32 { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().computedReadonly - return Int32(ret) + let ret = PropertyHolder.bridgeJSLiftParameter(_self).computedReadonly + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -1300,7 +1419,7 @@ public func _bjs_PropertyHolder_computedReadonly_get(_self: UnsafeMutableRawPoin @_cdecl("bjs_PropertyHolder_computedReadWrite_get") public func _bjs_PropertyHolder_computedReadWrite_get(_self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().computedReadWrite + let ret = PropertyHolder.bridgeJSLiftParameter(_self).computedReadWrite return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -1309,9 +1428,9 @@ public func _bjs_PropertyHolder_computedReadWrite_get(_self: UnsafeMutableRawPoi @_expose(wasm, "bjs_PropertyHolder_computedReadWrite_set") @_cdecl("bjs_PropertyHolder_computedReadWrite_set") -public func _bjs_PropertyHolder_computedReadWrite_set(_self: UnsafeMutableRawPointer, valueBytes: Int32, valueLen: Int32) -> Void { +public func _bjs_PropertyHolder_computedReadWrite_set(_self: UnsafeMutableRawPointer, valueBytes: Int32, valueLength: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().computedReadWrite = String.bridgeJSLiftParameter(valueBytes, valueLen) + PropertyHolder.bridgeJSLiftParameter(_self).computedReadWrite = String.bridgeJSLiftParameter(valueBytes, valueLength) #else fatalError("Only available on WebAssembly") #endif @@ -1321,8 +1440,8 @@ public func _bjs_PropertyHolder_computedReadWrite_set(_self: UnsafeMutableRawPoi @_cdecl("bjs_PropertyHolder_observedProperty_get") public func _bjs_PropertyHolder_observedProperty_get(_self: UnsafeMutableRawPointer) -> Int32 { #if arch(wasm32) - let ret = Unmanaged.fromOpaque(_self).takeUnretainedValue().observedProperty - return Int32(ret) + let ret = PropertyHolder.bridgeJSLiftParameter(_self).observedProperty + return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif @@ -1332,7 +1451,7 @@ public func _bjs_PropertyHolder_observedProperty_get(_self: UnsafeMutableRawPoin @_cdecl("bjs_PropertyHolder_observedProperty_set") public func _bjs_PropertyHolder_observedProperty_set(_self: UnsafeMutableRawPointer, value: Int32) -> Void { #if arch(wasm32) - Unmanaged.fromOpaque(_self).takeUnretainedValue().observedProperty = Int.bridgeJSLiftParameter(value) + PropertyHolder.bridgeJSLiftParameter(_self).observedProperty = Int.bridgeJSLiftParameter(value) #else fatalError("Only available on WebAssembly") #endif @@ -1344,10 +1463,16 @@ public func _bjs_PropertyHolder_deinit(pointer: UnsafeMutableRawPointer) { Unmanaged.fromOpaque(pointer).release() } -extension PropertyHolder: ConvertibleToJSValue { +extension PropertyHolder: ConvertibleToJSValue, _BridgedSwiftHeapObject { var jsValue: JSValue { + #if arch(wasm32) @_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_PropertyHolder_wrap") func _bjs_PropertyHolder_wrap(_: UnsafeMutableRawPointer) -> Int32 + #else + func _bjs_PropertyHolder_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") + } + #endif return .object(JSObject(id: UInt32(bitPattern: _bjs_PropertyHolder_wrap(Unmanaged.passRetained(self).toOpaque())))) } } \ No newline at end of file diff --git a/Tests/JavaScriptEventLoopTests/WebWorkerDedicatedExecutorTests.swift b/Tests/JavaScriptEventLoopTests/WebWorkerDedicatedExecutorTests.swift index b6c2bd8d..aae8c2ce 100644 --- a/Tests/JavaScriptEventLoopTests/WebWorkerDedicatedExecutorTests.swift +++ b/Tests/JavaScriptEventLoopTests/WebWorkerDedicatedExecutorTests.swift @@ -2,6 +2,7 @@ import XCTest @testable import JavaScriptEventLoop +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) final class WebWorkerDedicatedExecutorTests: XCTestCase { actor MyActor { let executor: WebWorkerDedicatedExecutor From 177be43a5f72f7a910c77a7c81a78fe63e49d25c Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sat, 23 Aug 2025 23:37:19 +0900 Subject: [PATCH 4/8] BridgeJS: Complete protocol-based lift/lower for ImportTS and _JSBridgedClass Add _JSBridgedClass protocol with lift/lower operations for JavaScript objects imported into Swift. Update ImportTS code generation to use new protocol-based bridgeJS* methods. Update all generated ImportTS Swift files and test snapshots to use the new bridgeJS* method calls instead of legacy functions. --- .../Sources/Generated/BridgeJS.ImportTS.swift | 2 +- .../Generated/BridgeJS.ImportTS.swift | 16 +- .../Sources/BridgeJSCore/ImportTS.swift | 188 ++++++++---------- .../ImportTSTests/ArrayParameter.swift | 2 +- .../__Snapshots__/ImportTSTests/Async.swift | 20 +- .../ImportTSTests/Interface.swift | 18 +- .../ImportTSTests/MultipleImportedTypes.swift | 66 +++--- .../ImportTSTests/PrimitiveParameters.swift | 2 +- .../ImportTSTests/PrimitiveReturn.swift | 2 +- .../ImportTSTests/StringParameter.swift | 2 +- .../ImportTSTests/TS2SkeletonLike.swift | 38 ++-- .../ImportTSTests/TypeAlias.swift | 2 +- .../ImportTSTests/TypeScriptClass.swift | 26 +-- .../BasicObjects/JSPromise.swift | 4 - .../JavaScriptKit/BridgeJSInstrincics.swift | 14 ++ Sources/JavaScriptKit/JSBridgedType.swift | 15 +- .../Generated/BridgeJS.ImportTS.swift | 32 ++- 17 files changed, 208 insertions(+), 241 deletions(-) diff --git a/Benchmarks/Sources/Generated/BridgeJS.ImportTS.swift b/Benchmarks/Sources/Generated/BridgeJS.ImportTS.swift index afce5aca..bc7f0b17 100644 --- a/Benchmarks/Sources/Generated/BridgeJS.ImportTS.swift +++ b/Benchmarks/Sources/Generated/BridgeJS.ImportTS.swift @@ -30,7 +30,7 @@ func benchmarkHelperNoopWithNumber(_ n: Double) throws(JSException) -> Void { fatalError("Only available on WebAssembly") } #endif - bjs_benchmarkHelperNoopWithNumber(n) + bjs_benchmarkHelperNoopWithNumber(n.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } diff --git a/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/BridgeJS.ImportTS.swift b/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/BridgeJS.ImportTS.swift index 3cee3b6e..4d35ef74 100644 --- a/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/BridgeJS.ImportTS.swift +++ b/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/BridgeJS.ImportTS.swift @@ -19,18 +19,14 @@ func createTS2Skeleton() throws(JSException) -> TS2Skeleton { if let error = _swift_js_take_exception() { throw error } - return TS2Skeleton(takingThis: ret) + return TS2Skeleton.bridgeJSLiftReturn(ret) } -struct TS2Skeleton { - let this: JSObject +struct TS2Skeleton: _JSBridgedClass { + let jsObject: JSObject - init(this: JSObject) { - self.this = this - } - - init(takingThis this: Int32) { - self.this = JSObject(id: UInt32(bitPattern: this)) + init(unsafelyWrapping jsObject: JSObject) { + self.jsObject = jsObject } func convert(_ ts: String) throws(JSException) -> String { @@ -42,7 +38,7 @@ struct TS2Skeleton { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_TS2Skeleton_convert(self.this.bridgeJSLowerParameter(), ts.bridgeJSLowerParameter()) + let ret = bjs_TS2Skeleton_convert(self.bridgeJSLowerParameter(), ts.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift index bf836637..3e09e5f6 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift @@ -68,70 +68,19 @@ public struct ImportTS { } func lowerParameter(param: Parameter) throws { - switch param.type { - case .bool: - abiParameterForwardings.append( - LabeledExprSyntax( - label: param.label, - expression: ExprSyntax("\(raw: param.name).bridgeJSLowerParameter()") - ) - ) - abiParameterSignatures.append((param.name, .i32)) - case .int: - abiParameterForwardings.append( - LabeledExprSyntax( - label: param.label, - expression: ExprSyntax("\(raw: param.name)") - ) - ) - abiParameterSignatures.append((param.name, .i32)) - case .float: - abiParameterForwardings.append( - LabeledExprSyntax( - label: param.label, - expression: ExprSyntax("\(raw: param.name)") - ) - ) - abiParameterSignatures.append((param.name, .f32)) - case .double: - abiParameterForwardings.append( - LabeledExprSyntax( - label: param.label, - expression: ExprSyntax("\(raw: param.name)") - ) - ) - abiParameterSignatures.append((param.name, .f64)) - case .string: - abiParameterForwardings.append( - LabeledExprSyntax( - label: param.label, - expression: ExprSyntax("\(raw: param.name).bridgeJSLowerParameter()") - ) - ) - abiParameterSignatures.append((param.name, .i32)) - case .caseEnum, .rawValueEnum, .associatedValueEnum, .namespaceEnum: - throw BridgeJSCoreError("Enum types are not yet supported in TypeScript imports") - case .jsObject(_?): - abiParameterSignatures.append((param.name, .i32)) - abiParameterForwardings.append( - LabeledExprSyntax( - label: param.label, - expression: ExprSyntax("\(raw: param.name).this.bridgeJSLowerParameter()") - ) - ) - case .jsObject(nil): - abiParameterForwardings.append( - LabeledExprSyntax( - label: param.label, - expression: ExprSyntax("\(raw: param.name).bridgeJSLowerParameter()") - ) + let loweringInfo = try param.type.loweringParameterInfo() + assert( + loweringInfo.loweredParameters.count == 1, + "For now, we require a single parameter to be lowered to a single Wasm core type" + ) + let (_, type) = loweringInfo.loweredParameters[0] + abiParameterForwardings.append( + LabeledExprSyntax( + label: param.label, + expression: ExprSyntax("\(raw: param.name).bridgeJSLowerParameter()") ) - abiParameterSignatures.append((param.name, .i32)) - case .swiftHeapObject(_): - throw BridgeJSCoreError("swiftHeapObject is not supported in imported signatures") - case .void: - break - } + ) + abiParameterSignatures.append((param.name, type)) } func call(returnType: BridgeType) { @@ -146,36 +95,12 @@ public struct ImportTS { } func liftReturnValue(returnType: BridgeType) throws { - switch returnType { - case .bool: - abiReturnType = .i32 - body.append("return \(raw: returnType.swiftType).bridgeJSLiftReturn(ret)") - case .int: - abiReturnType = .i32 - body.append("return \(raw: returnType.swiftType)(ret)") - case .float: - abiReturnType = .f32 - body.append("return \(raw: returnType.swiftType)(ret)") - case .double: - abiReturnType = .f64 - body.append("return \(raw: returnType.swiftType)(ret)") - case .string: - abiReturnType = .i32 - body.append("return \(raw: returnType.swiftType).bridgeJSLiftReturn(ret)") - case .caseEnum, .rawValueEnum, .associatedValueEnum, .namespaceEnum: - throw BridgeJSCoreError("Enum types are not yet supported in TypeScript imports") - case .jsObject(let name): - abiReturnType = .i32 - if let name = name { - body.append("return \(raw: name)(takingThis: ret)") - } else { - body.append("return JSObject.bridgeJSLiftReturn(ret)") - } - case .swiftHeapObject(_): - throw BridgeJSCoreError("swiftHeapObject is not supported in imported signatures") - case .void: - break + let liftingInfo = try returnType.liftingReturnInfo() + abiReturnType = liftingInfo.valueToLift + if returnType == .void { + return } + body.append("return \(raw: returnType.swiftType).bridgeJSLiftReturn(ret)") } func assignThis(returnType: BridgeType) { @@ -183,7 +108,7 @@ public struct ImportTS { preconditionFailure("assignThis can only be called with a jsObject return type") } abiReturnType = .i32 - body.append("self.this = JSObject(id: UInt32(bitPattern: ret))") + body.append("self.jsObject = JSObject(id: UInt32(bitPattern: ret))") } func renderImportDecl() -> DeclSyntax { @@ -410,25 +335,22 @@ public struct ImportTS { let classDecl = try StructDeclSyntax( leadingTrivia: Self.renderDocumentation(documentation: type.documentation), name: .identifier(name), + inheritanceClause: InheritanceClauseSyntax( + inheritedTypesBuilder: { + InheritedTypeSyntax(type: TypeSyntax("_JSBridgedClass")) + } + ), memberBlockBuilder: { DeclSyntax( """ - let this: JSObject + let jsObject: JSObject """ ).with(\.trailingTrivia, .newlines(2)) DeclSyntax( """ - init(this: JSObject) { - self.this = this - } - """ - ).with(\.trailingTrivia, .newlines(2)) - - DeclSyntax( - """ - init(takingThis this: Int32) { - self.this = JSObject(id: UInt32(bitPattern: this)) + init(unsafelyWrapping jsObject: JSObject) { + self.jsObject = jsObject } """ ).with(\.trailingTrivia, .newlines(2)) @@ -483,3 +405,61 @@ public struct ImportTS { ) } } + +extension BridgeType { + struct LoweringParameterInfo { + let loweredParameters: [(name: String, type: WasmCoreType)] + + static let bool = LoweringParameterInfo(loweredParameters: [("value", .i32)]) + static let int = LoweringParameterInfo(loweredParameters: [("value", .i32)]) + static let float = LoweringParameterInfo(loweredParameters: [("value", .f32)]) + static let double = LoweringParameterInfo(loweredParameters: [("value", .f64)]) + static let string = LoweringParameterInfo(loweredParameters: [("value", .i32)]) + static let jsObject = LoweringParameterInfo(loweredParameters: [("value", .i32)]) + static let void = LoweringParameterInfo(loweredParameters: []) + } + + func loweringParameterInfo() throws -> LoweringParameterInfo { + switch self { + case .bool: return .bool + case .int: return .int + case .float: return .float + case .double: return .double + case .string: return .string + case .jsObject: return .jsObject + case .void: return .void + case .swiftHeapObject: + throw BridgeJSCoreError("swiftHeapObject is not supported in imported signatures") + case .caseEnum, .rawValueEnum, .associatedValueEnum, .namespaceEnum: + throw BridgeJSCoreError("Enum types are not yet supported in TypeScript imports") + } + } + + struct LiftingReturnInfo { + let valueToLift: WasmCoreType? + + static let bool = LiftingReturnInfo(valueToLift: .i32) + static let int = LiftingReturnInfo(valueToLift: .i32) + static let float = LiftingReturnInfo(valueToLift: .f32) + static let double = LiftingReturnInfo(valueToLift: .f64) + static let string = LiftingReturnInfo(valueToLift: .i32) + static let jsObject = LiftingReturnInfo(valueToLift: .i32) + static let void = LiftingReturnInfo(valueToLift: nil) + } + + func liftingReturnInfo() throws -> LiftingReturnInfo { + switch self { + case .bool: return .bool + case .int: return .int + case .float: return .float + case .double: return .double + case .string: return .string + case .jsObject: return .jsObject + case .void: return .void + case .swiftHeapObject: + throw BridgeJSCoreError("swiftHeapObject is not supported in imported signatures") + case .caseEnum, .rawValueEnum, .associatedValueEnum, .namespaceEnum: + throw BridgeJSCoreError("Enum types are not yet supported in TypeScript imports") + } + } +} diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/ArrayParameter.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/ArrayParameter.swift index f8974961..96fac13d 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/ArrayParameter.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/ArrayParameter.swift @@ -30,7 +30,7 @@ func checkArrayWithLength(_ a: JSObject, _ b: Double) throws(JSException) -> Voi fatalError("Only available on WebAssembly") } #endif - bjs_checkArrayWithLength(a.bridgeJSLowerParameter(), b) + bjs_checkArrayWithLength(a.bridgeJSLowerParameter(), b.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/Async.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/Async.swift index ea9a9ab6..a8ecf8d5 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/Async.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/Async.swift @@ -19,7 +19,7 @@ func asyncReturnVoid() throws(JSException) -> JSPromise { if let error = _swift_js_take_exception() { throw error } - return JSPromise(takingThis: ret) + return JSPromise.bridgeJSLiftReturn(ret) } func asyncRoundTripInt(_ v: Double) throws(JSException) -> JSPromise { @@ -31,11 +31,11 @@ func asyncRoundTripInt(_ v: Double) throws(JSException) -> JSPromise { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_asyncRoundTripInt(v) + let ret = bjs_asyncRoundTripInt(v.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } - return JSPromise(takingThis: ret) + return JSPromise.bridgeJSLiftReturn(ret) } func asyncRoundTripString(_ v: String) throws(JSException) -> JSPromise { @@ -51,7 +51,7 @@ func asyncRoundTripString(_ v: String) throws(JSException) -> JSPromise { if let error = _swift_js_take_exception() { throw error } - return JSPromise(takingThis: ret) + return JSPromise.bridgeJSLiftReturn(ret) } func asyncRoundTripBool(_ v: Bool) throws(JSException) -> JSPromise { @@ -67,7 +67,7 @@ func asyncRoundTripBool(_ v: Bool) throws(JSException) -> JSPromise { if let error = _swift_js_take_exception() { throw error } - return JSPromise(takingThis: ret) + return JSPromise.bridgeJSLiftReturn(ret) } func asyncRoundTripFloat(_ v: Double) throws(JSException) -> JSPromise { @@ -79,11 +79,11 @@ func asyncRoundTripFloat(_ v: Double) throws(JSException) -> JSPromise { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_asyncRoundTripFloat(v) + let ret = bjs_asyncRoundTripFloat(v.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } - return JSPromise(takingThis: ret) + return JSPromise.bridgeJSLiftReturn(ret) } func asyncRoundTripDouble(_ v: Double) throws(JSException) -> JSPromise { @@ -95,11 +95,11 @@ func asyncRoundTripDouble(_ v: Double) throws(JSException) -> JSPromise { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_asyncRoundTripDouble(v) + let ret = bjs_asyncRoundTripDouble(v.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } - return JSPromise(takingThis: ret) + return JSPromise.bridgeJSLiftReturn(ret) } func asyncRoundTripJSObject(_ v: JSObject) throws(JSException) -> JSPromise { @@ -115,5 +115,5 @@ func asyncRoundTripJSObject(_ v: JSObject) throws(JSException) -> JSPromise { if let error = _swift_js_take_exception() { throw error } - return JSPromise(takingThis: ret) + return JSPromise.bridgeJSLiftReturn(ret) } \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/Interface.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/Interface.swift index a4ee884f..48a0db2b 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/Interface.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/Interface.swift @@ -19,18 +19,14 @@ func returnAnimatable() throws(JSException) -> Animatable { if let error = _swift_js_take_exception() { throw error } - return Animatable(takingThis: ret) + return Animatable.bridgeJSLiftReturn(ret) } -struct Animatable { - let this: JSObject +struct Animatable: _BridgedJSClass { + let jsObject: JSObject - init(this: JSObject) { - self.this = this - } - - init(takingThis this: Int32) { - self.this = JSObject(id: UInt32(bitPattern: this)) + init(unsafelyWrapping jsObject: JSObject) { + self.jsObject = jsObject } func animate(_ keyframes: JSObject, _ options: JSObject) throws(JSException) -> JSObject { @@ -42,7 +38,7 @@ struct Animatable { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_Animatable_animate(self.this.bridgeJSLowerParameter(), keyframes.bridgeJSLowerParameter(), options.bridgeJSLowerParameter()) + let ret = bjs_Animatable_animate(self.bridgeJSLowerParameter(), keyframes.bridgeJSLowerParameter(), options.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -58,7 +54,7 @@ struct Animatable { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_Animatable_getAnimations(self.this.bridgeJSLowerParameter(), options.bridgeJSLowerParameter()) + let ret = bjs_Animatable_getAnimations(self.bridgeJSLowerParameter(), options.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/MultipleImportedTypes.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/MultipleImportedTypes.swift index ab07c967..c2f39d4f 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/MultipleImportedTypes.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/MultipleImportedTypes.swift @@ -19,7 +19,7 @@ func createDatabaseConnection(_ config: JSObject) throws(JSException) -> Databas if let error = _swift_js_take_exception() { throw error } - return DatabaseConnection(takingThis: ret) + return DatabaseConnection.bridgeJSLiftReturn(ret) } func createLogger(_ level: String) throws(JSException) -> Logger { @@ -35,7 +35,7 @@ func createLogger(_ level: String) throws(JSException) -> Logger { if let error = _swift_js_take_exception() { throw error } - return Logger(takingThis: ret) + return Logger.bridgeJSLiftReturn(ret) } func getConfigManager() throws(JSException) -> ConfigManager { @@ -51,18 +51,14 @@ func getConfigManager() throws(JSException) -> ConfigManager { if let error = _swift_js_take_exception() { throw error } - return ConfigManager(takingThis: ret) + return ConfigManager.bridgeJSLiftReturn(ret) } -struct DatabaseConnection { - let this: JSObject +struct DatabaseConnection: _BridgedJSClass { + let jsObject: JSObject - init(this: JSObject) { - self.this = this - } - - init(takingThis this: Int32) { - self.this = JSObject(id: UInt32(bitPattern: this)) + init(unsafelyWrapping jsObject: JSObject) { + self.jsObject = jsObject } var isConnected: Bool { @@ -75,7 +71,7 @@ struct DatabaseConnection { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_DatabaseConnection_isConnected_get(self.this.bridgeJSLowerParameter()) + let ret = bjs_DatabaseConnection_isConnected_get(self.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -93,11 +89,11 @@ struct DatabaseConnection { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_DatabaseConnection_connectionTimeout_get(self.this.bridgeJSLowerParameter()) + let ret = bjs_DatabaseConnection_connectionTimeout_get(self.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } - return Double(ret) + return Double.bridgeJSLiftReturn(ret) } } @@ -110,7 +106,7 @@ struct DatabaseConnection { fatalError("Only available on WebAssembly") } #endif - bjs_DatabaseConnection_connectionTimeout_set(self.this.bridgeJSLowerParameter(), newValue) + bjs_DatabaseConnection_connectionTimeout_set(self.bridgeJSLowerParameter(), newValue.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -125,7 +121,7 @@ struct DatabaseConnection { fatalError("Only available on WebAssembly") } #endif - bjs_DatabaseConnection_connect(self.this.bridgeJSLowerParameter(), url.bridgeJSLowerParameter()) + bjs_DatabaseConnection_connect(self.bridgeJSLowerParameter(), url.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -140,7 +136,7 @@ struct DatabaseConnection { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_DatabaseConnection_execute(self.this.bridgeJSLowerParameter(), query.bridgeJSLowerParameter()) + let ret = bjs_DatabaseConnection_execute(self.bridgeJSLowerParameter(), query.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -149,15 +145,11 @@ struct DatabaseConnection { } -struct Logger { - let this: JSObject - - init(this: JSObject) { - self.this = this - } +struct Logger: _BridgedJSClass { + let jsObject: JSObject - init(takingThis this: Int32) { - self.this = JSObject(id: UInt32(bitPattern: this)) + init(unsafelyWrapping jsObject: JSObject) { + self.jsObject = jsObject } var level: String { @@ -170,7 +162,7 @@ struct Logger { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_Logger_level_get(self.this.bridgeJSLowerParameter()) + let ret = bjs_Logger_level_get(self.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -187,7 +179,7 @@ struct Logger { fatalError("Only available on WebAssembly") } #endif - bjs_Logger_log(self.this.bridgeJSLowerParameter(), message.bridgeJSLowerParameter()) + bjs_Logger_log(self.bridgeJSLowerParameter(), message.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -202,7 +194,7 @@ struct Logger { fatalError("Only available on WebAssembly") } #endif - bjs_Logger_error(self.this.bridgeJSLowerParameter(), message.bridgeJSLowerParameter(), error.bridgeJSLowerParameter()) + bjs_Logger_error(self.bridgeJSLowerParameter(), message.bridgeJSLowerParameter(), error.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -210,15 +202,11 @@ struct Logger { } -struct ConfigManager { - let this: JSObject - - init(this: JSObject) { - self.this = this - } +struct ConfigManager: _BridgedJSClass { + let jsObject: JSObject - init(takingThis this: Int32) { - self.this = JSObject(id: UInt32(bitPattern: this)) + init(unsafelyWrapping jsObject: JSObject) { + self.jsObject = jsObject } var configPath: String { @@ -231,7 +219,7 @@ struct ConfigManager { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_ConfigManager_configPath_get(self.this.bridgeJSLowerParameter()) + let ret = bjs_ConfigManager_configPath_get(self.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -248,7 +236,7 @@ struct ConfigManager { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_ConfigManager_get(self.this.bridgeJSLowerParameter(), key.bridgeJSLowerParameter()) + let ret = bjs_ConfigManager_get(self.bridgeJSLowerParameter(), key.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -264,7 +252,7 @@ struct ConfigManager { fatalError("Only available on WebAssembly") } #endif - bjs_ConfigManager_set(self.this.bridgeJSLowerParameter(), key.bridgeJSLowerParameter(), value.bridgeJSLowerParameter()) + bjs_ConfigManager_set(self.bridgeJSLowerParameter(), key.bridgeJSLowerParameter(), value.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/PrimitiveParameters.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/PrimitiveParameters.swift index 43b66797..30f66a26 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/PrimitiveParameters.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/PrimitiveParameters.swift @@ -15,7 +15,7 @@ func check(_ a: Double, _ b: Bool) throws(JSException) -> Void { fatalError("Only available on WebAssembly") } #endif - bjs_check(a, b.bridgeJSLowerParameter()) + bjs_check(a.bridgeJSLowerParameter(), b.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/PrimitiveReturn.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/PrimitiveReturn.swift index 77dcc710..29ba81c6 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/PrimitiveReturn.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/PrimitiveReturn.swift @@ -19,7 +19,7 @@ func checkNumber() throws(JSException) -> Double { if let error = _swift_js_take_exception() { throw error } - return Double(ret) + return Double.bridgeJSLiftReturn(ret) } func checkBoolean() throws(JSException) -> Bool { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/StringParameter.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/StringParameter.swift index 7ecbbac9..99215a30 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/StringParameter.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/StringParameter.swift @@ -30,7 +30,7 @@ func checkStringWithLength(_ a: String, _ b: Double) throws(JSException) -> Void fatalError("Only available on WebAssembly") } #endif - bjs_checkStringWithLength(a.bridgeJSLowerParameter(), b) + bjs_checkStringWithLength(a.bridgeJSLowerParameter(), b.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TS2SkeletonLike.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TS2SkeletonLike.swift index 68acd5bf..2a1a76ce 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TS2SkeletonLike.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TS2SkeletonLike.swift @@ -19,7 +19,7 @@ func createTS2Skeleton() throws(JSException) -> TypeScriptProcessor { if let error = _swift_js_take_exception() { throw error } - return TypeScriptProcessor(takingThis: ret) + return TypeScriptProcessor.bridgeJSLiftReturn(ret) } func createCodeGenerator(_ format: String) throws(JSException) -> CodeGenerator { @@ -35,18 +35,14 @@ func createCodeGenerator(_ format: String) throws(JSException) -> CodeGenerator if let error = _swift_js_take_exception() { throw error } - return CodeGenerator(takingThis: ret) + return CodeGenerator.bridgeJSLiftReturn(ret) } -struct TypeScriptProcessor { - let this: JSObject +struct TypeScriptProcessor: _BridgedJSClass { + let jsObject: JSObject - init(this: JSObject) { - self.this = this - } - - init(takingThis this: Int32) { - self.this = JSObject(id: UInt32(bitPattern: this)) + init(unsafelyWrapping jsObject: JSObject) { + self.jsObject = jsObject } var version: String { @@ -59,7 +55,7 @@ struct TypeScriptProcessor { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_TypeScriptProcessor_version_get(self.this.bridgeJSLowerParameter()) + let ret = bjs_TypeScriptProcessor_version_get(self.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -76,7 +72,7 @@ struct TypeScriptProcessor { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_TypeScriptProcessor_convert(self.this.bridgeJSLowerParameter(), ts.bridgeJSLowerParameter()) + let ret = bjs_TypeScriptProcessor_convert(self.bridgeJSLowerParameter(), ts.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -92,7 +88,7 @@ struct TypeScriptProcessor { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_TypeScriptProcessor_validate(self.this.bridgeJSLowerParameter(), ts.bridgeJSLowerParameter()) + let ret = bjs_TypeScriptProcessor_validate(self.bridgeJSLowerParameter(), ts.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -101,15 +97,11 @@ struct TypeScriptProcessor { } -struct CodeGenerator { - let this: JSObject - - init(this: JSObject) { - self.this = this - } +struct CodeGenerator: _BridgedJSClass { + let jsObject: JSObject - init(takingThis this: Int32) { - self.this = JSObject(id: UInt32(bitPattern: this)) + init(unsafelyWrapping jsObject: JSObject) { + self.jsObject = jsObject } var outputFormat: String { @@ -122,7 +114,7 @@ struct CodeGenerator { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_CodeGenerator_outputFormat_get(self.this.bridgeJSLowerParameter()) + let ret = bjs_CodeGenerator_outputFormat_get(self.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -139,7 +131,7 @@ struct CodeGenerator { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_CodeGenerator_generate(self.this.bridgeJSLowerParameter(), input.bridgeJSLowerParameter()) + let ret = bjs_CodeGenerator_generate(self.bridgeJSLowerParameter(), input.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TypeAlias.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TypeAlias.swift index 7523101f..d8b18463 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TypeAlias.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TypeAlias.swift @@ -15,7 +15,7 @@ func checkSimple(_ a: Double) throws(JSException) -> Void { fatalError("Only available on WebAssembly") } #endif - bjs_checkSimple(a) + bjs_checkSimple(a.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TypeScriptClass.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TypeScriptClass.swift index f22bfda2..649eb8cf 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TypeScriptClass.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TypeScriptClass.swift @@ -6,15 +6,11 @@ @_spi(BridgeJS) import JavaScriptKit -struct Greeter { - let this: JSObject +struct Greeter: _BridgedJSClass { + let jsObject: JSObject - init(this: JSObject) { - self.this = this - } - - init(takingThis this: Int32) { - self.this = JSObject(id: UInt32(bitPattern: this)) + init(unsafelyWrapping jsObject: JSObject) { + self.jsObject = jsObject } init(_ name: String) throws(JSException) { @@ -30,7 +26,7 @@ struct Greeter { if let error = _swift_js_take_exception() { throw error } - self.this = JSObject(id: UInt32(bitPattern: ret)) + self.jsObject = JSObject(id: UInt32(bitPattern: ret)) } var name: String { @@ -43,7 +39,7 @@ struct Greeter { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_Greeter_name_get(self.this.bridgeJSLowerParameter()) + let ret = bjs_Greeter_name_get(self.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -60,7 +56,7 @@ struct Greeter { fatalError("Only available on WebAssembly") } #endif - bjs_Greeter_name_set(self.this.bridgeJSLowerParameter(), newValue.bridgeJSLowerParameter()) + bjs_Greeter_name_set(self.bridgeJSLowerParameter(), newValue.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -76,11 +72,11 @@ struct Greeter { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_Greeter_age_get(self.this.bridgeJSLowerParameter()) + let ret = bjs_Greeter_age_get(self.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } - return Double(ret) + return Double.bridgeJSLiftReturn(ret) } } @@ -93,7 +89,7 @@ struct Greeter { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_Greeter_greet(self.this.bridgeJSLowerParameter()) + let ret = bjs_Greeter_greet(self.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -109,7 +105,7 @@ struct Greeter { fatalError("Only available on WebAssembly") } #endif - bjs_Greeter_changeName(self.this.bridgeJSLowerParameter(), name.bridgeJSLowerParameter()) + bjs_Greeter_changeName(self.bridgeJSLowerParameter(), name.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } diff --git a/Sources/JavaScriptKit/BasicObjects/JSPromise.swift b/Sources/JavaScriptKit/BasicObjects/JSPromise.swift index ec2a7724..201e8fa6 100644 --- a/Sources/JavaScriptKit/BasicObjects/JSPromise.swift +++ b/Sources/JavaScriptKit/BasicObjects/JSPromise.swift @@ -23,10 +23,6 @@ public final class JSPromise: JSBridgedClass { self.init(from: jsObject) } - @_spi(BridgeJS) public convenience init(takingThis: Int32) { - self.init(unsafelyWrapping: JSObject(id: UInt32(bitPattern: takingThis))) - } - /// Creates a new `JSPromise` instance from a given JavaScript `Promise` object. If `value` /// is not an object and is not an instance of JavaScript `Promise`, this function will /// return `nil`. diff --git a/Sources/JavaScriptKit/BridgeJSInstrincics.swift b/Sources/JavaScriptKit/BridgeJSInstrincics.swift index 4d609dc7..969fb4e1 100644 --- a/Sources/JavaScriptKit/BridgeJSInstrincics.swift +++ b/Sources/JavaScriptKit/BridgeJSInstrincics.swift @@ -293,6 +293,20 @@ extension _BridgedSwiftHeapObject { } } +extension _JSBridgedClass { + // MARK: ImportTS + @_spi(BridgeJS) public consuming func bridgeJSLowerParameter() -> Int32 { jsObject.bridgeJSLowerParameter() } + @_spi(BridgeJS) public static func bridgeJSLiftReturn(_ id: Int32) -> Self { + Self(unsafelyWrapping: JSObject.bridgeJSLiftReturn(id)) + } + + // MARK: ExportSwift + @_spi(BridgeJS) public static func bridgeJSLiftParameter(_ id: Int32) -> Self { + Self(unsafelyWrapping: JSObject.bridgeJSLiftParameter(id)) + } + @_spi(BridgeJS) public consuming func bridgeJSLowerReturn() -> Int32 { jsObject.bridgeJSLowerReturn() } +} + /// A protocol that Swift enum types that do not have a payload can conform to. /// /// The conformance is automatically synthesized by the BridgeJS code generator. diff --git a/Sources/JavaScriptKit/JSBridgedType.swift b/Sources/JavaScriptKit/JSBridgedType.swift index 92739079..ffa65f4a 100644 --- a/Sources/JavaScriptKit/JSBridgedType.swift +++ b/Sources/JavaScriptKit/JSBridgedType.swift @@ -13,8 +13,21 @@ extension JSBridgedType { public var description: String { jsValue.description } } +/// A protocol that Swift classes that are exposed to JavaScript via `@JS class` conform to. +/// +/// The conformance is automatically synthesized by the BridgeJS code generator. +public protocol _JSBridgedClass { + /// The JavaScript object wrapped by this instance. + /// You may assume that `jsObject instanceof Self.constructor == true` + var jsObject: JSObject { get } + + /// Create an instance wrapping the given JavaScript object. + /// You may assume that `jsObject instanceof Self.constructor` + init(unsafelyWrapping jsObject: JSObject) +} + /// Conform to this protocol when your Swift class wraps a JavaScript class. -public protocol JSBridgedClass: JSBridgedType { +public protocol JSBridgedClass: JSBridgedType, _JSBridgedClass { /// The constructor function for the JavaScript class static var constructor: JSFunction? { get } diff --git a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ImportTS.swift b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ImportTS.swift index 733a085f..19bc82fc 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ImportTS.swift +++ b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ImportTS.swift @@ -30,11 +30,11 @@ func jsRoundTripNumber(_ v: Double) throws(JSException) -> Double { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_jsRoundTripNumber(v) + let ret = bjs_jsRoundTripNumber(v.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } - return Double(ret) + return Double.bridgeJSLiftReturn(ret) } func jsRoundTripBool(_ v: Bool) throws(JSException) -> Bool { @@ -97,7 +97,7 @@ func jsThrowOrNumber(_ shouldThrow: Bool) throws(JSException) -> Double { if let error = _swift_js_take_exception() { throw error } - return Double(ret) + return Double.bridgeJSLiftReturn(ret) } func jsThrowOrBool(_ shouldThrow: Bool) throws(JSException) -> Bool { @@ -145,18 +145,14 @@ func runAsyncWorks() throws(JSException) -> JSPromise { if let error = _swift_js_take_exception() { throw error } - return JSPromise(takingThis: ret) + return JSPromise.bridgeJSLiftReturn(ret) } -struct JsGreeter { - let this: JSObject +struct JsGreeter: _JSBridgedClass { + let jsObject: JSObject - init(this: JSObject) { - self.this = this - } - - init(takingThis this: Int32) { - self.this = JSObject(id: UInt32(bitPattern: this)) + init(unsafelyWrapping jsObject: JSObject) { + self.jsObject = jsObject } init(_ name: String, _ prefix: String) throws(JSException) { @@ -172,7 +168,7 @@ struct JsGreeter { if let error = _swift_js_take_exception() { throw error } - self.this = JSObject(id: UInt32(bitPattern: ret)) + self.jsObject = JSObject(id: UInt32(bitPattern: ret)) } var name: String { @@ -185,7 +181,7 @@ struct JsGreeter { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_JsGreeter_name_get(self.this.bridgeJSLowerParameter()) + let ret = bjs_JsGreeter_name_get(self.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -202,7 +198,7 @@ struct JsGreeter { fatalError("Only available on WebAssembly") } #endif - bjs_JsGreeter_name_set(self.this.bridgeJSLowerParameter(), newValue.bridgeJSLowerParameter()) + bjs_JsGreeter_name_set(self.bridgeJSLowerParameter(), newValue.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -218,7 +214,7 @@ struct JsGreeter { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_JsGreeter_prefix_get(self.this.bridgeJSLowerParameter()) + let ret = bjs_JsGreeter_prefix_get(self.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -235,7 +231,7 @@ struct JsGreeter { fatalError("Only available on WebAssembly") } #endif - let ret = bjs_JsGreeter_greet(self.this.bridgeJSLowerParameter()) + let ret = bjs_JsGreeter_greet(self.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } @@ -251,7 +247,7 @@ struct JsGreeter { fatalError("Only available on WebAssembly") } #endif - bjs_JsGreeter_changeName(self.this.bridgeJSLowerParameter(), name.bridgeJSLowerParameter()) + bjs_JsGreeter_changeName(self.bridgeJSLowerParameter(), name.bridgeJSLowerParameter()) if let error = _swift_js_take_exception() { throw error } From 9aad68d14fa1232b3f5e220a3a5429b2938072c6 Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sun, 24 Aug 2025 01:18:11 +0900 Subject: [PATCH 5/8] BridgeJS: Provide default implementation for BridgeJS functions This is a workaround for the issue that reference to imported bjs wasm functions can't be eliminated in debug builds, even if they are not reachable at runtime without explicit BridgeJS usage. --- Plugins/PackageToJS/Templates/instantiate.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Plugins/PackageToJS/Templates/instantiate.js b/Plugins/PackageToJS/Templates/instantiate.js index 5d6fe6b9..9b35efd1 100644 --- a/Plugins/PackageToJS/Templates/instantiate.js +++ b/Plugins/PackageToJS/Templates/instantiate.js @@ -27,7 +27,20 @@ async function createInstantiator(options, swift) { * @param {WebAssembly.Imports} importObject * @param {unknown} importsContext */ - addImports: (importObject, importsContext) => {}, + addImports: (importObject, importsContext) => { + // Provide a default implementation for BridgeJS functions that are not + // used at runtime without BridgeJS but required to instantiate the module. + const unexpectedBjsCall = () => { throw new Error("Unexpected call to BridgeJS function") } + importObject["bjs"] = { + swift_js_return_string: unexpectedBjsCall, + swift_js_init_memory: unexpectedBjsCall, + swift_js_make_js_string: unexpectedBjsCall, + swift_js_init_memory_with_result: unexpectedBjsCall, + swift_js_throw: unexpectedBjsCall, + swift_js_retain: unexpectedBjsCall, + swift_js_release: unexpectedBjsCall, + } + }, /** @param {WebAssembly.Instance} instance */ setInstance: (instance) => {}, /** @param {WebAssembly.Instance} instance */ From 7a31c5e749b9dc3820579a6dbbb248e2ff04989a Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sun, 24 Aug 2025 01:52:38 +0900 Subject: [PATCH 6/8] BridgeJS: Update test snapshot files --- .../__Snapshots__/ImportTSTests/Interface.swift | 2 +- .../__Snapshots__/ImportTSTests/MultipleImportedTypes.swift | 6 +++--- .../__Snapshots__/ImportTSTests/TS2SkeletonLike.swift | 4 ++-- .../__Snapshots__/ImportTSTests/TypeScriptClass.swift | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/Interface.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/Interface.swift index 48a0db2b..68f14808 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/Interface.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/Interface.swift @@ -22,7 +22,7 @@ func returnAnimatable() throws(JSException) -> Animatable { return Animatable.bridgeJSLiftReturn(ret) } -struct Animatable: _BridgedJSClass { +struct Animatable: _JSBridgedClass { let jsObject: JSObject init(unsafelyWrapping jsObject: JSObject) { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/MultipleImportedTypes.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/MultipleImportedTypes.swift index c2f39d4f..810df368 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/MultipleImportedTypes.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/MultipleImportedTypes.swift @@ -54,7 +54,7 @@ func getConfigManager() throws(JSException) -> ConfigManager { return ConfigManager.bridgeJSLiftReturn(ret) } -struct DatabaseConnection: _BridgedJSClass { +struct DatabaseConnection: _JSBridgedClass { let jsObject: JSObject init(unsafelyWrapping jsObject: JSObject) { @@ -145,7 +145,7 @@ struct DatabaseConnection: _BridgedJSClass { } -struct Logger: _BridgedJSClass { +struct Logger: _JSBridgedClass { let jsObject: JSObject init(unsafelyWrapping jsObject: JSObject) { @@ -202,7 +202,7 @@ struct Logger: _BridgedJSClass { } -struct ConfigManager: _BridgedJSClass { +struct ConfigManager: _JSBridgedClass { let jsObject: JSObject init(unsafelyWrapping jsObject: JSObject) { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TS2SkeletonLike.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TS2SkeletonLike.swift index 2a1a76ce..0b17f13b 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TS2SkeletonLike.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TS2SkeletonLike.swift @@ -38,7 +38,7 @@ func createCodeGenerator(_ format: String) throws(JSException) -> CodeGenerator return CodeGenerator.bridgeJSLiftReturn(ret) } -struct TypeScriptProcessor: _BridgedJSClass { +struct TypeScriptProcessor: _JSBridgedClass { let jsObject: JSObject init(unsafelyWrapping jsObject: JSObject) { @@ -97,7 +97,7 @@ struct TypeScriptProcessor: _BridgedJSClass { } -struct CodeGenerator: _BridgedJSClass { +struct CodeGenerator: _JSBridgedClass { let jsObject: JSObject init(unsafelyWrapping jsObject: JSObject) { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TypeScriptClass.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TypeScriptClass.swift index 649eb8cf..455b38bc 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TypeScriptClass.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TypeScriptClass.swift @@ -6,7 +6,7 @@ @_spi(BridgeJS) import JavaScriptKit -struct Greeter: _BridgedJSClass { +struct Greeter: _JSBridgedClass { let jsObject: JSObject init(unsafelyWrapping jsObject: JSObject) { From 5f6573833079dcb11fdddf70b10a513f3157cf5e Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sun, 24 Aug 2025 01:52:41 +0900 Subject: [PATCH 7/8] BridgeJS: Repair PlayBridgeJS build --- .../Sources/PlayBridgeJS/BridgeJSUtilities | 1 + Plugins/BridgeJS/Package.swift | 7 ++++++- .../BridgeJS/Sources/BridgeJSCore/ExportSwift.swift | 3 +++ Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift | 3 +++ .../BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift | 10 +++------- .../Utilities.swift | 2 +- Plugins/PackageToJS/Sources/BridgeJSUtilities | 1 + Sources/BridgeJSTool/BridgeJSUtilities | 1 + 8 files changed, 19 insertions(+), 9 deletions(-) create mode 120000 Examples/PlayBridgeJS/Sources/PlayBridgeJS/BridgeJSUtilities rename Plugins/BridgeJS/Sources/{BridgeJSCore => BridgeJSUtilities}/Utilities.swift (71%) create mode 120000 Plugins/PackageToJS/Sources/BridgeJSUtilities create mode 120000 Sources/BridgeJSTool/BridgeJSUtilities diff --git a/Examples/PlayBridgeJS/Sources/PlayBridgeJS/BridgeJSUtilities b/Examples/PlayBridgeJS/Sources/PlayBridgeJS/BridgeJSUtilities new file mode 120000 index 00000000..a43f43e2 --- /dev/null +++ b/Examples/PlayBridgeJS/Sources/PlayBridgeJS/BridgeJSUtilities @@ -0,0 +1 @@ +../../../../Plugins/BridgeJS/Sources/BridgeJSUtilities \ No newline at end of file diff --git a/Plugins/BridgeJS/Package.swift b/Plugins/BridgeJS/Package.swift index 9ac96d95..bb7daac2 100644 --- a/Plugins/BridgeJS/Package.swift +++ b/Plugins/BridgeJS/Package.swift @@ -29,6 +29,7 @@ let package = Package( name: "BridgeJSCore", dependencies: [ "BridgeJSSkeleton", + "BridgeJSUtilities", .product(name: "SwiftParser", package: "swift-syntax"), .product(name: "SwiftSyntax", package: "swift-syntax"), .product(name: "SwiftBasicFormat", package: "swift-syntax"), @@ -36,10 +37,14 @@ let package = Package( ] ), .target(name: "BridgeJSSkeleton"), + .target(name: "BridgeJSUtilities"), .target( name: "BridgeJSLink", - dependencies: ["BridgeJSSkeleton"] + dependencies: [ + "BridgeJSSkeleton", + "BridgeJSUtilities", + ] ), .testTarget( diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift index cefb334f..76ce16d6 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift @@ -4,6 +4,9 @@ import SwiftSyntaxBuilder #if canImport(BridgeJSSkeleton) import BridgeJSSkeleton #endif +#if canImport(BridgeJSUtilities) +import BridgeJSUtilities +#endif /// Exports Swift functions and classes to JavaScript /// diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift index 3e09e5f6..148157d3 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift @@ -4,6 +4,9 @@ import SwiftSyntaxBuilder #if canImport(BridgeJSSkeleton) import BridgeJSSkeleton #endif +#if canImport(BridgeJSUtilities) +import BridgeJSUtilities +#endif /// Imports TypeScript declarations and generates Swift bridge code /// diff --git a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift index f704b828..360a6274 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift @@ -3,6 +3,9 @@ import struct Foundation.Data #if canImport(BridgeJSSkeleton) import BridgeJSSkeleton #endif +#if canImport(BridgeJSUtilities) +import BridgeJSUtilities +#endif struct BridgeJSLink { /// The exported skeletons @@ -1456,13 +1459,6 @@ extension String { } } -fileprivate extension String { - var capitalizedFirstLetter: String { - guard !isEmpty else { return self } - return prefix(1).uppercased() + dropFirst() - } -} - extension BridgeType { var tsType: String { switch self { diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/Utilities.swift b/Plugins/BridgeJS/Sources/BridgeJSUtilities/Utilities.swift similarity index 71% rename from Plugins/BridgeJS/Sources/BridgeJSCore/Utilities.swift rename to Plugins/BridgeJS/Sources/BridgeJSUtilities/Utilities.swift index fb3a6e16..f091e4a3 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/Utilities.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSUtilities/Utilities.swift @@ -1,5 +1,5 @@ extension String { - var capitalizedFirstLetter: String { + public var capitalizedFirstLetter: String { guard !isEmpty else { return self } return prefix(1).uppercased() + dropFirst() } diff --git a/Plugins/PackageToJS/Sources/BridgeJSUtilities b/Plugins/PackageToJS/Sources/BridgeJSUtilities new file mode 120000 index 00000000..52bf489d --- /dev/null +++ b/Plugins/PackageToJS/Sources/BridgeJSUtilities @@ -0,0 +1 @@ +../../../Plugins/BridgeJS/Sources/BridgeJSUtilities \ No newline at end of file diff --git a/Sources/BridgeJSTool/BridgeJSUtilities b/Sources/BridgeJSTool/BridgeJSUtilities new file mode 120000 index 00000000..75db3bd9 --- /dev/null +++ b/Sources/BridgeJSTool/BridgeJSUtilities @@ -0,0 +1 @@ +../../Plugins/BridgeJS/Sources/BridgeJSUtilities \ No newline at end of file From 07c1ef730bd215bdb5dcd88018e769550b15fa9c Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sun, 24 Aug 2025 09:35:40 +0900 Subject: [PATCH 8/8] BridgeJS: Clean up protocol definitions and documentation Remove unused _BridgedSwiftTypeLoweredIntoWasmCoreType protocol and fix incomplete documentation comment for the remaining protocol. --- Sources/JavaScriptKit/BridgeJSInstrincics.swift | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Sources/JavaScriptKit/BridgeJSInstrincics.swift b/Sources/JavaScriptKit/BridgeJSInstrincics.swift index 969fb4e1..56b87fa5 100644 --- a/Sources/JavaScriptKit/BridgeJSInstrincics.swift +++ b/Sources/JavaScriptKit/BridgeJSInstrincics.swift @@ -79,13 +79,7 @@ import _CJavaScriptKit // // See JSGlueGen.swift in BridgeJSLink for JS-side lowering/lifting implementation. -/// A protocol that Swift types that can be lowered into a single Wasm core type. -public protocol _BridgedSwiftTypeLoweredIntoWasmCoreType { - associatedtype WasmCoreType -} - /// A protocol that Swift types that can appear as parameters or return values on -/// The conformance is automatically synthesized by the BridgeJS code generator. public protocol _BridgedSwiftTypeLoweredIntoSingleWasmCoreType { associatedtype WasmCoreType // MARK: ImportTS