From 5b177a5b9703025c460d73a51803fc17e589f17c Mon Sep 17 00:00:00 2001 From: Krzysztof Rodak Date: Fri, 22 Aug 2025 15:46:53 +0200 Subject: [PATCH 1/4] BridgeJS: Support for multiple associated values in enums using binary buffer format --- .../Sources/BridgeJSCore/ExportSwift.swift | 237 ++- .../Sources/BridgeJSLink/BridgeJSLink.swift | 395 +++- .../Sources/BridgeJSLink/JSGlueGen.swift | 57 +- .../Inputs/EnumAssociatedValue.swift | 40 + .../ArrayParameter.Import.js | 38 +- .../BridgeJSLinkTests/Async.Export.js | 38 +- .../BridgeJSLinkTests/Async.Import.js | 38 +- .../EnumAssociatedValue.Export.d.ts | 75 + .../EnumAssociatedValue.Export.js | 445 ++++ .../BridgeJSLinkTests/EnumCase.Export.js | 38 +- .../BridgeJSLinkTests/EnumNamespace.Export.js | 38 +- .../BridgeJSLinkTests/EnumRawType.Export.js | 38 +- .../BridgeJSLinkTests/Interface.Import.js | 38 +- .../InvalidPropertyNames.Import.js | 38 +- .../MultipleImportedTypes.Import.js | 38 +- .../BridgeJSLinkTests/Namespaces.Export.js | 38 +- .../PrimitiveParameters.Export.js | 38 +- .../PrimitiveParameters.Import.js | 38 +- .../PrimitiveReturn.Export.js | 38 +- .../PrimitiveReturn.Import.js | 38 +- .../BridgeJSLinkTests/PropertyTypes.Export.js | 38 +- .../StringParameter.Export.js | 38 +- .../StringParameter.Import.js | 38 +- .../BridgeJSLinkTests/StringReturn.Export.js | 38 +- .../BridgeJSLinkTests/StringReturn.Import.js | 38 +- .../BridgeJSLinkTests/SwiftClass.Export.js | 38 +- .../TS2SkeletonLike.Import.js | 38 +- .../BridgeJSLinkTests/Throws.Export.js | 38 +- .../BridgeJSLinkTests/TypeAlias.Import.js | 38 +- .../TypeScriptClass.Import.js | 38 +- .../VoidParameterVoidReturn.Export.js | 38 +- .../VoidParameterVoidReturn.Import.js | 38 +- .../ExportSwiftTests/EnumAssociatedValue.json | 435 ++++ .../EnumAssociatedValue.swift | 348 ++++ .../ExportSwiftTests/EnumNamespace.swift | 3 - .../JavaScriptKit/BridgeJSInstrincics.swift | 161 ++ .../Exporting-Swift/Exporting-Swift-Enum.md | 136 +- .../BridgeJSRuntimeTests/ExportAPITests.swift | 137 ++ .../Generated/BridgeJS.ExportSwift.swift | 572 ++++- .../JavaScript/BridgeJS.ExportSwift.json | 1834 +++++++++++++---- Tests/prelude.mjs | 89 +- 41 files changed, 5415 insertions(+), 537 deletions(-) create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/EnumAssociatedValue.swift create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.d.ts create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.js create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumAssociatedValue.json create mode 100644 Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumAssociatedValue.swift diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift index 117158df..af23c4d0 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift @@ -25,6 +25,7 @@ public class ExportSwift { private var exportedClasses: [ExportedClass] = [] private var exportedEnums: [ExportedEnum] = [] private var typeDeclResolver: TypeDeclResolver = TypeDeclResolver() + private let enumCodegen: EnumCodegen = EnumCodegen() public init(progress: ProgressReporting, moduleName: String) { self.progress = progress @@ -524,6 +525,31 @@ public class ExportSwift { ) } + if currentEnum.cases.contains(where: { !$0.associatedValues.isEmpty }) { + if case .tsEnum = emitStyle { + diagnose( + node: jsAttribute, + message: "TypeScript enum style is not supported for associated value enums", + hint: "Use enumStyle: .const in order to map associated-value enums" + ) + } + for enumCase in currentEnum.cases { + for associatedValue in enumCase.associatedValues { + switch associatedValue.type { + case .string, .int, .float, .double, .bool: + break + default: + diagnose( + node: node, + message: "Unsupported associated value type: \(associatedValue.type.swiftType)", + hint: + "Only primitive types (String, Int, Float, Double, Bool) are supported in associated-value enums" + ) + } + } + } + } + let swiftCallName = ExportSwift.computeSwiftCallName(for: node, itemName: enumName) let explicitAccessControl = computeExplicitAtLeastInternalAccessControl( for: node, @@ -753,10 +779,15 @@ public class ExportSwift { decls.append(Self.prelude) for enumDef in exportedEnums { - if enumDef.enumType == .simple { - decls.append(renderCaseEnumHelpers(enumDef)) - } else { + switch enumDef.enumType { + case .simple: + decls.append(enumCodegen.renderCaseEnumHelpers(enumDef)) + case .rawValue: decls.append("extension \(raw: enumDef.swiftCallName): _BridgedSwiftEnumNoPayload {}") + case .associatedValue: + decls.append(enumCodegen.renderAssociatedValueEnumHelpers(enumDef)) + case .namespace: + () } } @@ -770,45 +801,6 @@ public class ExportSwift { return decls.map { $0.formatted(using: format).description }.joined(separator: "\n\n") } - func renderCaseEnumHelpers(_ enumDef: ExportedEnum) -> DeclSyntax { - let typeName = enumDef.swiftCallName - var initCases: [String] = [] - var valueCases: [String] = [] - for (index, c) in enumDef.cases.enumerated() { - initCases.append("case \(index): self = .\(c.name)") - valueCases.append("case .\(c.name): return \(index)") - } - let initSwitch = (["switch bridgeJSRawValue {"] + initCases + ["default: return nil", "}"]).joined( - separator: "\n" - ) - let valueSwitch = (["switch self {"] + valueCases + ["}"]).joined(separator: "\n") - - return """ - extension \(raw: typeName) { - @_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) - } - - private var bridgeJSRawValue: Int32 { - \(raw: valueSwitch) - } - } - """ - } - class ExportedThunkBuilder { var body: [CodeBlockItemSyntax] = [] var liftedParameterExprs: [ExprSyntax] = [] @@ -1006,6 +998,159 @@ public class ExportSwift { } } + private struct EnumCodegen { + func renderCaseEnumHelpers(_ enumDef: ExportedEnum) -> DeclSyntax { + let typeName = enumDef.swiftCallName + var initCases: [String] = [] + var valueCases: [String] = [] + for (index, enumCase) in enumDef.cases.enumerated() { + initCases.append("case \(index): self = .\(enumCase.name)") + valueCases.append("case .\(enumCase.name): return \(index)") + } + let initSwitch = (["switch bridgeJSRawValue {"] + initCases + ["default: return nil", "}"]).joined( + separator: "\n" + ) + let valueSwitch = (["switch self {"] + valueCases + ["}"]).joined(separator: "\n") + + return """ + extension \(raw: typeName) { + @_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) + } + + private var bridgeJSRawValue: Int32 { + \(raw: valueSwitch) + } + } + """ + } + + func renderAssociatedValueEnumHelpers(_ enumDef: ExportedEnum) -> DeclSyntax { + let typeName = enumDef.swiftCallName + return """ + private extension \(raw: typeName) { + static func bridgeJSLiftParameter(_ caseId: Int32, _ paramsId: Int32, _ paramsLen: Int32) -> \(raw: typeName) { + let params: [UInt8] = .init(unsafeUninitializedCapacity: Int(paramsLen)) { buf, initializedCount in + _swift_js_init_memory(paramsId, buf.baseAddress.unsafelyUnwrapped) + initializedCount = Int(paramsLen) + } + return params.withUnsafeBytes { raw in + var reader = _BJSBinaryReader(raw: raw) + switch caseId { + \(raw: generateBinaryLiftSwitchCases(enumDef: enumDef).joined(separator: "\n")) + default: fatalError("Unknown \(raw: typeName) case ID: \\(caseId)") + } + } + } + + func bridgeJSLowerReturn() { + switch self { + \(raw: generateReturnSwitchCases(enumDef: enumDef).joined(separator: "\n")) + } + } + } + """ + } + + private func generateBinaryLiftSwitchCases(enumDef: ExportedEnum) -> [String] { + var cases: [String] = [] + for (caseIndex, enumCase) in enumDef.cases.enumerated() { + if enumCase.associatedValues.isEmpty { + cases.append("case \(caseIndex): return .\(enumCase.name)") + } else { + var lines: [String] = [] + lines.append("case \(caseIndex):") + lines.append("reader.readParamCount(expected: \(enumCase.associatedValues.count))") + var argList: [String] = [] + + for (paramIndex, associatedValue) in enumCase.associatedValues.enumerated() { + let paramName = associatedValue.label ?? "param\(paramIndex)" + argList.append(paramName) + + switch associatedValue.type { + case .string: + lines.append("reader.expectTag(.string)") + lines.append("let \(paramName) = reader.readString()") + case .int: + lines.append("reader.expectTag(.int32)") + lines.append("let \(paramName) = Int(reader.readInt32())") + case .bool: + lines.append("reader.expectTag(.bool)") + lines.append("let \(paramName) = Int32(reader.readUInt8()) != 0") + case .float: + lines.append("reader.expectTag(.float32)") + lines.append("let \(paramName) = reader.readFloat32()") + case .double: + lines.append("reader.expectTag(.float64)") + lines.append("let \(paramName) = reader.readFloat64()") + default: + lines.append("reader.expectTag(.int32)") + lines.append("let \(paramName) = reader.readInt32()") + } + } + + lines.append("return .\(enumCase.name)(\(argList.joined(separator: ", ")))") + cases.append(lines.joined(separator: "\n")) + } + } + return cases + } + + private func generateReturnSwitchCases(enumDef: ExportedEnum) -> [String] { + var cases: [String] = [] + for (caseIndex, enumCase) in enumDef.cases.enumerated() { + if enumCase.associatedValues.isEmpty { + cases.append("case .\(enumCase.name):") + cases.append("_swift_js_return_tag(Int32(\(caseIndex)))") + } else { + var bodyLines: [String] = [] + bodyLines.append("_swift_js_return_tag(Int32(\(caseIndex)))") + for (index, associatedValue) in enumCase.associatedValues.enumerated() { + let paramName = associatedValue.label ?? "param\(index)" + switch associatedValue.type { + case .string: + bodyLines.append("var __bjs_\(paramName) = \(paramName)") + bodyLines.append("__bjs_\(paramName).withUTF8 { ptr in") + bodyLines.append("_swift_js_return_string(ptr.baseAddress, Int32(ptr.count))") + bodyLines.append("}") + case .int: + bodyLines.append("_swift_js_return_int(Int32(\(paramName)))") + case .bool: + bodyLines.append("_swift_js_return_bool(\(paramName) ? 1 : 0)") + case .float: + bodyLines.append("_swift_js_return_f32(\(paramName))") + case .double: + bodyLines.append("_swift_js_return_f64(\(paramName))") + default: + bodyLines.append( + "preconditionFailure(\"BridgeJS: unsupported associated value type in generated code\")" + ) + } + } + let pattern = enumCase.associatedValues.enumerated() + .map { index, associatedValue in "let \(associatedValue.label ?? "param\(index)")" } + .joined(separator: ", ") + cases.append("case .\(enumCase.name)(\(pattern)):") + cases.append(contentsOf: bodyLines) + } + } + return cases + } + } + func renderSingleExportedFunction(function: ExportedFunction) throws -> DeclSyntax { let builder = ExportedThunkBuilder(effects: function.effects) for param in function.parameters { @@ -1264,6 +1409,9 @@ extension BridgeType { static let swiftHeapObject = LiftingIntrinsicInfo(parameters: [("value", .pointer)]) static let void = LiftingIntrinsicInfo(parameters: []) static let caseEnum = LiftingIntrinsicInfo(parameters: [("value", .i32)]) + static let associatedValueEnum = LiftingIntrinsicInfo(parameters: [ + ("caseId", .i32), ("paramsId", .i32), ("paramsLen", .i32), + ]) } func liftParameterInfo() throws -> LiftingIntrinsicInfo { @@ -1291,7 +1439,7 @@ extension BridgeType { case .uint64: return .int } case .associatedValueEnum: - throw BridgeJSCoreError("Associated value enums are not supported to pass as parameters") + return .associatedValueEnum case .namespaceEnum: throw BridgeJSCoreError("Namespace enums are not supported to pass as parameters") } @@ -1310,6 +1458,7 @@ extension BridgeType { static let void = LoweringIntrinsicInfo(returnType: nil) static let caseEnum = LoweringIntrinsicInfo(returnType: .i32) static let rawValueEnum = LoweringIntrinsicInfo(returnType: .i32) + static let associatedValueEnum = LoweringIntrinsicInfo(returnType: nil) } func loweringReturnInfo() throws -> LoweringIntrinsicInfo { @@ -1337,7 +1486,7 @@ extension BridgeType { case .uint64: return .int } case .associatedValueEnum: - throw BridgeJSCoreError("Associated value enums are not supported to pass as parameters") + return .associatedValueEnum case .namespaceEnum: throw BridgeJSCoreError("Namespace enums are not supported to pass as parameters") } diff --git a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift index 360a6274..75c07466 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift @@ -65,6 +65,57 @@ struct BridgeJSLink { } """ + let sharedEnumHelpersJs = """ + /// Shared helpers for encoding associated-value enums between JS and Swift. + const __bjs_ParamType = { STRING: 1, INT32: 2, BOOL: 3, FLOAT32: 4, FLOAT64: 5 }; + function __bjs_encodeEnumParams(textEncoder, swift, parts) { + const SIZE_U8 = 1, SIZE_U32 = 4, SIZE_F32 = 4, SIZE_F64 = 8; + let totalLen = SIZE_U32; + for (const p of parts) { + switch (p.t) { + case __bjs_ParamType.STRING: { + const bytes = textEncoder.encode(p.v); + p._bytes = bytes; + totalLen += SIZE_U8 + SIZE_U32 + bytes.length; + break; + } + case __bjs_ParamType.INT32: totalLen += SIZE_U8 + SIZE_U32; break; + case __bjs_ParamType.BOOL: totalLen += SIZE_U8 + SIZE_U8; break; + case __bjs_ParamType.FLOAT32: totalLen += SIZE_U8 + SIZE_F32; break; + case __bjs_ParamType.FLOAT64: totalLen += SIZE_U8 + SIZE_F64; break; + default: throw new Error("Unsupported param type tag: " + p.t); + } + } + const buf = new Uint8Array(totalLen); + const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength); + let off = 0; + view.setUint32(off, parts.length, true); off += SIZE_U32; + for (const p of parts) { + view.setUint8(off, p.t); off += SIZE_U8; + switch (p.t) { + case __bjs_ParamType.STRING: { + const b = p._bytes; + view.setUint32(off, b.length, true); off += SIZE_U32; + buf.set(b, off); off += b.length; + break; + } + case __bjs_ParamType.INT32: + view.setInt32(off, (p.v | 0), true); off += SIZE_U32; break; + case __bjs_ParamType.BOOL: + view.setUint8(off, p.v ? 1 : 0); off += SIZE_U8; break; + case __bjs_ParamType.FLOAT32: + view.setFloat32(off, Math.fround(p.v), true); off += SIZE_F32; break; + case __bjs_ParamType.FLOAT64: + view.setFloat64(off, p.v, true); off += SIZE_F64; break; + default: throw new Error("Unsupported param type tag: " + p.t); + } + } + const paramsId = swift.memory.retain(buf); + return { paramsId, paramsLen: buf.length, cleanup: () => { swift.memory.release(paramsId); } }; + } + + """ + func link() throws -> (outputJs: String, outputDts: String) { var exportsLines: [String] = [] var classLines: [String] = [] @@ -73,8 +124,6 @@ struct BridgeJSLink { var namespacedFunctions: [ExportedFunction] = [] var namespacedClasses: [ExportedClass] = [] var namespacedEnums: [ExportedEnum] = [] - var enumConstantLines: [String] = [] - var dtsEnumLines: [String] = [] var topLevelEnumLines: [String] = [] var topLevelDtsEnumLines: [String] = [] @@ -123,12 +172,15 @@ struct BridgeJSLink { namespacedEnums.append(enumDefinition) } case .associatedValue: - enumConstantLines.append(contentsOf: jsEnum) - exportsLines.append("\(enumDefinition.name),") + var exportedJsEnum = jsEnum + if !exportedJsEnum.isEmpty && exportedJsEnum[0].hasPrefix("const ") { + exportedJsEnum[0] = "export " + exportedJsEnum[0] + } + topLevelEnumLines.append(contentsOf: exportedJsEnum) + topLevelDtsEnumLines.append(contentsOf: dtsEnum) if enumDefinition.namespace != nil { namespacedEnums.append(enumDefinition) } - dtsEnumLines.append(contentsOf: dtsEnum) } } } @@ -161,7 +213,7 @@ struct BridgeJSLink { importObjectBuilders.append(importObjectBuilder) } - let hasNamespacedItems = !namespacedFunctions.isEmpty || !namespacedClasses.isEmpty || !namespacedEnums.isEmpty + let hasNamespacedItems = !namespacedFunctions.isEmpty || !namespacedClasses.isEmpty let namespaceBuilder = NamespaceBuilder() let namespaceDeclarationsLines = namespaceBuilder.namespaceDeclarations( @@ -173,21 +225,15 @@ struct BridgeJSLink { let exportsSection: String if hasNamespacedItems { - let namespacedEnumsForExports = namespacedEnums.filter { $0.enumType == .associatedValue } let namespaceSetupCode = namespaceBuilder.renderGlobalNamespace( namespacedFunctions: namespacedFunctions, - namespacedClasses: namespacedClasses, - namespacedEnums: namespacedEnumsForExports + namespacedClasses: namespacedClasses ) .map { $0.indent(count: 12) }.joined(separator: "\n") - let enumSection = - enumConstantLines.isEmpty - ? "" : enumConstantLines.map { $0.indent(count: 12) }.joined(separator: "\n") + "\n" - exportsSection = """ \(classLines.map { $0.indent(count: 12) }.joined(separator: "\n")) - \(enumSection)\("const exports = {".indent(count: 12)) + \("const exports = {".indent(count: 12)) \(exportsLines.map { $0.indent(count: 16) }.joined(separator: "\n")) \("};".indent(count: 12)) @@ -197,27 +243,31 @@ struct BridgeJSLink { }, """ } else { - let enumSection = - enumConstantLines.isEmpty - ? "" : enumConstantLines.map { $0.indent(count: 12) }.joined(separator: "\n") + "\n" - exportsSection = """ \(classLines.map { $0.indent(count: 12) }.joined(separator: "\n")) - \(enumSection)\("return {".indent(count: 12)) + \("return {".indent(count: 12)) \(exportsLines.map { $0.indent(count: 16) }.joined(separator: "\n")) \("};".indent(count: 12)) }, """ } + let hasAssociatedValueEnums = exportedSkeletons.contains { skeleton in + skeleton.enums.contains { $0.enumType == .associatedValue } + } + let sharedEnumHelpersSection = hasAssociatedValueEnums ? sharedEnumHelpersJs : "" let topLevelEnumsSection = topLevelEnumLines.isEmpty ? "" : topLevelEnumLines.joined(separator: "\n") + "\n\n" - let topLevelNamespaceCode = namespaceBuilder.renderTopLevelEnumNamespaceAssignments( namespacedEnums: namespacedEnums ) let namespaceAssignmentsSection = topLevelNamespaceCode.isEmpty ? "" : topLevelNamespaceCode.joined(separator: "\n") + "\n\n" + let enumHelpers = renderEnumHelperAssignments() + let enumHelpersSection = + enumHelpers.isEmpty ? "" : "\n\n" + enumHelpers.map { $0.indent(count: 12) }.joined(separator: "\n") + let enumHelpersDeclaration = hasAssociatedValueEnums ? "const enumHelpers = {};\n" : "\n" + let outputJs = """ // NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit, // DO NOT EDIT. @@ -225,16 +275,22 @@ struct BridgeJSLink { // To update this file, just rebuild your project or run // `swift package bridge-js`. - \(topLevelEnumsSection)\(namespaceAssignmentsSection)export async function createInstantiator(options, \(JSGlueVariableScope.reservedSwift)) { + \(sharedEnumHelpersSection)\(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 \(JSGlueVariableScope.reservedStorageToReturnString); let \(JSGlueVariableScope.reservedStorageToReturnBytes); let \(JSGlueVariableScope.reservedStorageToReturnException); + let \(JSGlueVariableScope.reservedTmpRetTag); + let \(JSGlueVariableScope.reservedTmpRetStrings) = []; + let \(JSGlueVariableScope.reservedTmpRetInts) = []; + let \(JSGlueVariableScope.reservedTmpRetF32s) = []; + let \(JSGlueVariableScope.reservedTmpRetF64s) = []; + let \(JSGlueVariableScope.reservedTmpRetBools) = []; + \(enumHelpersDeclaration) return { /** * @param {WebAssembly.Imports} importObject @@ -245,7 +301,9 @@ struct BridgeJSLink { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(\(JSGlueVariableScope.reservedMemory).buffer, ptr, len)\(sharedMemory ? ".slice()" : ""); - \(JSGlueVariableScope.reservedStorageToReturnString) = \(JSGlueVariableScope.reservedTextDecoder).decode(bytes); + const value = \(JSGlueVariableScope.reservedTextDecoder).decode(bytes); + \(JSGlueVariableScope.reservedStorageToReturnString) = value; + \(JSGlueVariableScope.reservedTmpRetStrings).push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = \(JSGlueVariableScope.reservedSwift).memory.getObject(sourceId); @@ -270,12 +328,37 @@ struct BridgeJSLink { bjs["swift_js_release"] = function(id) { \(JSGlueVariableScope.reservedSwift).memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + \(JSGlueVariableScope.reservedTmpRetTag) = tag | 0; + tmpRetString = undefined; + \(JSGlueVariableScope.reservedTmpRetStrings) = []; + \(JSGlueVariableScope.reservedTmpRetInts) = []; + \(JSGlueVariableScope.reservedTmpRetF32s) = []; + \(JSGlueVariableScope.reservedTmpRetF64s) = []; + \(JSGlueVariableScope.reservedTmpRetBools) = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + \(JSGlueVariableScope.reservedTmpRetInts).push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + \(JSGlueVariableScope.reservedTmpRetF32s).push(value); + } + bjs["swift_js_return_f64"] = function(v) { + \(JSGlueVariableScope.reservedTmpRetF64s).push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + \(JSGlueVariableScope.reservedTmpRetBools).push(value); + } \(renderSwiftClassWrappers().map { $0.indent(count: 12) }.joined(separator: "\n")) \(importObjectBuilders.flatMap { $0.importedLines }.map { $0.indent(count: 12) }.joined(separator: "\n")) }, setInstance: (i) => { \(JSGlueVariableScope.reservedInstance) = i; \(JSGlueVariableScope.reservedMemory) = \(JSGlueVariableScope.reservedInstance).exports.memory; + \(enumHelpersSection) \(JSGlueVariableScope.reservedSetException) = (error) => { \(JSGlueVariableScope.reservedInstance).exports._swift_js_exception.value = \(JSGlueVariableScope.reservedSwift).memory.retain(error) } @@ -291,7 +374,6 @@ struct BridgeJSLink { var dtsLines: [String] = [] dtsLines.append(contentsOf: namespaceDeclarationsLines) dtsLines.append(contentsOf: dtsClassLines) - dtsLines.append(contentsOf: dtsEnumLines) dtsLines.append(contentsOf: generateImportedTypeDefinitions()) dtsLines.append("export type Exports = {") dtsLines.append(contentsOf: dtsExportLines.map { $0.indent(count: 4) }) @@ -321,6 +403,21 @@ struct BridgeJSLink { return (outputJs, outputDts) } + private func renderEnumHelperAssignments() -> [String] { + var lines: [String] = [] + + for skeleton in exportedSkeletons { + for enumDef in skeleton.enums where enumDef.enumType == .associatedValue { + let base = enumDef.name + lines.append("const \(base)Helpers = __bjs_create\(base)Helpers()(textEncoder, swift);") + lines.append("enumHelpers.\(base) = \(base)Helpers;") + lines.append("") + } + } + + return lines + } + private func renderSwiftClassWrappers() -> [String] { var wrapperLines: [String] = [] var modulesByName: [String: [ExportedClass]] = [:] @@ -612,10 +709,185 @@ struct BridgeJSLink { dtsLines.append("") } } - case .associatedValue: - jsLines.append("// TODO: Implement \(enumDefinition.enumType) enum: \(enumDefinition.name)") - dtsLines.append("// TODO: Implement \(enumDefinition.enumType) enum: \(enumDefinition.name)") + do { + jsLines.append("const \(enumDefinition.name) = {") + jsLines.append("Tag: {".indent(count: 4)) + for (caseIndex, enumCase) in enumDefinition.cases.enumerated() { + let caseName = enumCase.name.capitalizedFirstLetter + jsLines.append("\(caseName): \(caseIndex),".indent(count: 8)) + } + jsLines.append("}".indent(count: 4)) + jsLines.append("};") + jsLines.append("") + jsLines.append("const __bjs_create\(enumDefinition.name)Helpers = () => {") + jsLines.append("return (textEncoder, swift) => ({".indent(count: 4)) + + jsLines.append("lower: (value) => {".indent(count: 8)) + jsLines.append("const enumTag = value.tag;".indent(count: 12)) + jsLines.append("switch (enumTag) {".indent(count: 12)) + for (_, enumCase) in enumDefinition.cases.enumerated() { + let caseName = enumCase.name.capitalizedFirstLetter + if enumCase.associatedValues.isEmpty { + jsLines.append("case \(enumDefinition.name).Tag.\(caseName): {".indent(count: 16)) + jsLines.append("const parts = [];".indent(count: 20)) + jsLines.append( + "const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts);" + .indent(count: 20) + ) + jsLines.append( + "return { caseId: \(enumDefinition.name).Tag.\(caseName), paramsId, paramsLen, cleanup };" + .indent(count: 20) + ) + jsLines.append("}".indent(count: 16)) + } else { + jsLines.append("case \(enumDefinition.name).Tag.\(caseName): {".indent(count: 16)) + var partLines: [String] = [] + for (associatedValueIndex, associatedValue) in enumCase.associatedValues.enumerated() { + let prop = associatedValue.label ?? "param\(associatedValueIndex)" + switch associatedValue.type { + case .string: + partLines.append("{ t: __bjs_ParamType.STRING, v: value.\(prop) }") + case .int: + partLines.append("{ t: __bjs_ParamType.INT32, v: (value.\(prop) | 0) }") + case .bool: + partLines.append("{ t: __bjs_ParamType.BOOL, v: value.\(prop) }") + case .float: + partLines.append("{ t: __bjs_ParamType.FLOAT32, v: value.\(prop) }") + case .double: + partLines.append("{ t: __bjs_ParamType.FLOAT64, v: value.\(prop) }") + default: + partLines.append("{ t: __bjs_ParamType.INT32, v: 0 }") + } + } + jsLines.append("const parts = [".indent(count: 20)) + if !partLines.isEmpty { + for (i, pl) in partLines.enumerated() { + let suffix = i == partLines.count - 1 ? "" : "," + jsLines.append("\(pl)\(suffix)".indent(count: 24)) + } + } + jsLines.append("];".indent(count: 20)) + jsLines.append( + "const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts);" + .indent(count: 20) + ) + jsLines.append( + "return { caseId: \(enumDefinition.name).Tag.\(caseName), paramsId, paramsLen, cleanup };" + .indent(count: 20) + ) + jsLines.append("}".indent(count: 16)) + } + } + jsLines.append( + "default: throw new Error(\"Unknown \(enumDefinition.name) tag: \" + String(enumTag));".indent( + count: 16 + ) + ) + jsLines.append("}".indent(count: 12)) + jsLines.append("},".indent(count: 8)) + + jsLines.append( + "raise: (tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetBools) => {".indent( + count: 8 + ) + ) + jsLines.append("const tag = tmpRetTag | 0;".indent(count: 12)) + jsLines.append("switch (tag) {".indent(count: 12)) + for (_, enumCase) in enumDefinition.cases.enumerated() { + let caseName = enumCase.name.capitalizedFirstLetter + if enumCase.associatedValues.isEmpty { + jsLines.append( + "case \(enumDefinition.name).Tag.\(caseName): return { tag: \(enumDefinition.name).Tag.\(caseName) };" + .indent(count: 16) + ) + } else { + var fields: [String] = ["tag: \(enumDefinition.name).Tag.\(caseName)"] + var stringIndex = 0 + var intIndex = 0 + var f32Index = 0 + var f64Index = 0 + var boolIndex = 0 + for (associatedValueIndex, associatedValue) in enumCase.associatedValues.enumerated() { + let prop = associatedValue.label ?? "param\(associatedValueIndex)" + switch associatedValue.type { + case .string: + fields.append("\(prop): tmpRetStrings[\(stringIndex)]") + stringIndex += 1 + case .bool: + fields.append("\(prop): tmpRetBools[\(boolIndex)]") + boolIndex += 1 + case .int: + fields.append("\(prop): tmpRetInts[\(intIndex)]") + intIndex += 1 + case .float: + fields.append("\(prop): tmpRetF32s[\(f32Index)]") + f32Index += 1 + case .double: + fields.append("\(prop): tmpRetF64s[\(f64Index)]") + f64Index += 1 + default: + fields.append("\(prop): undefined") + } + } + jsLines.append( + "case \(enumDefinition.name).Tag.\(caseName): return { \(fields.joined(separator: ", ")) };" + .indent(count: 16) + ) + } + } + jsLines.append( + "default: throw new Error(\"Unknown \(enumDefinition.name) tag returned from Swift: \" + String(tag));" + .indent( + count: 16 + ) + ) + jsLines.append("}".indent(count: 12)) + jsLines.append("}".indent(count: 8)) + jsLines.append("});".indent(count: 4)) + jsLines.append("};") + + if enumDefinition.namespace == nil { + dtsLines.append("export const \(enumDefinition.name): {") + dtsLines.append("readonly Tag: {".indent(count: 4)) + for (caseIndex, enumCase) in enumDefinition.cases.enumerated() { + let caseName = enumCase.name.capitalizedFirstLetter + dtsLines.append("readonly \(caseName): \(caseIndex);".indent(count: 8)) + } + dtsLines.append("};".indent(count: 4)) + dtsLines.append("};") + dtsLines.append("") + var unionParts: [String] = [] + for enumCase in enumDefinition.cases { + if enumCase.associatedValues.isEmpty { + unionParts.append( + "{ tag: typeof \(enumDefinition.name).Tag.\(enumCase.name.capitalizedFirstLetter) }" + ) + } else { + var fields: [String] = [ + "tag: typeof \(enumDefinition.name).Tag.\(enumCase.name.capitalizedFirstLetter)" + ] + for (associatedValueIndex, associatedValue) in enumCase.associatedValues + .enumerated() + { + let prop = associatedValue.label ?? "param\(associatedValueIndex)" + let ts: String + switch associatedValue.type { + case .string: ts = "string" + case .bool: ts = "boolean" + case .int, .float, .double: ts = "number" + default: ts = "never" + } + fields.append("\(prop): \(ts)") + } + unionParts.append("{ \(fields.joined(separator: "; ")) }") + } + } + dtsLines.append("export type \(enumDefinition.name) =") + dtsLines.append(" " + unionParts.joined(separator: " | ")) + dtsLines.append("") + } + } case .namespace: break } @@ -992,8 +1264,7 @@ struct BridgeJSLink { /// - Returns: Array of JavaScript code lines that set up the global namespace structure func renderGlobalNamespace( namespacedFunctions: [ExportedFunction], - namespacedClasses: [ExportedClass], - namespacedEnums: [ExportedEnum] + namespacedClasses: [ExportedClass] ) -> [String] { var lines: [String] = [] var uniqueNamespaces: [String] = [] @@ -1007,15 +1278,10 @@ struct BridgeJSLink { namespacedClasses .compactMap { $0.namespace } ) - let enumNamespacePaths: Set<[String]> = Set( - namespacedEnums - .compactMap { $0.namespace } - ) let allNamespacePaths = functionNamespacePaths .union(classNamespacePaths) - .union(enumNamespacePaths) allNamespacePaths.forEach { namespacePath in namespacePath.makeIterator().enumerated().forEach { (index, _) in @@ -1037,11 +1303,6 @@ struct BridgeJSLink { lines.append("globalThis.\(namespacePath).\(klass.name) = exports.\(klass.name);") } - namespacedEnums.forEach { enumDefinition in - let namespacePath: String = enumDefinition.namespace?.joined(separator: ".") ?? "" - lines.append("globalThis.\(namespacePath).\(enumDefinition.name) = exports.\(enumDefinition.name);") - } - namespacedFunctions.forEach { function in let namespacePath: String = function.namespace?.joined(separator: ".") ?? "" lines.append("globalThis.\(namespacePath).\(function.name) = exports.\(function.name);") @@ -1051,15 +1312,13 @@ struct BridgeJSLink { } func renderTopLevelEnumNamespaceAssignments(namespacedEnums: [ExportedEnum]) -> [String] { - let topLevelNamespacedEnums = namespacedEnums.filter { $0.enumType == .simple || $0.enumType == .rawValue } - - guard !topLevelNamespacedEnums.isEmpty else { return [] } + guard !namespacedEnums.isEmpty else { return [] } var lines: [String] = [] var uniqueNamespaces: [String] = [] var seen = Set() - for enumDef in topLevelNamespacedEnums { + for enumDef in namespacedEnums { guard let namespacePath = enumDef.namespace else { continue } namespacePath.enumerated().forEach { (index, _) in let path = namespacePath[0...index].joined(separator: ".") @@ -1080,7 +1339,7 @@ struct BridgeJSLink { lines.append("") } - for enumDef in topLevelNamespacedEnums { + for enumDef in namespacedEnums { let namespacePath = enumDef.namespace?.joined(separator: ".") ?? "" lines.append("globalThis.\(namespacePath).\(enumDef.name) = \(enumDef.name);") } @@ -1291,7 +1550,53 @@ struct BridgeJSLink { .indent(count: identBaseSize * contentDepth) ) } - case .associatedValue, .namespace: + case .associatedValue: + dtsLines.append( + "const \(enumDefinition.name): {".indent(count: identBaseSize * contentDepth) + ) + dtsLines.append("readonly Tag: {".indent(count: identBaseSize * (contentDepth + 1))) + for (caseIndex, enumCase) in enumDefinition.cases.enumerated() { + let caseName = enumCase.name.capitalizedFirstLetter + dtsLines.append( + "readonly \(caseName): \(caseIndex);".indent( + count: identBaseSize * (contentDepth + 2) + ) + ) + } + dtsLines.append("};".indent(count: identBaseSize * (contentDepth + 1))) + dtsLines.append("};".indent(count: identBaseSize * contentDepth)) + + var unionParts: [String] = [] + for enumCase in enumDefinition.cases { + if enumCase.associatedValues.isEmpty { + unionParts.append( + "{ tag: typeof \(enumDefinition.name).Tag.\(enumCase.name.capitalizedFirstLetter) }" + ) + } else { + var fields: [String] = [ + "tag: typeof \(enumDefinition.name).Tag.\(enumCase.name.capitalizedFirstLetter)" + ] + for (associatedValueIndex, associatedValue) in enumCase.associatedValues + .enumerated() + { + let prop = associatedValue.label ?? "param\(associatedValueIndex)" + let ts: String + switch associatedValue.type { + case .string: ts = "string" + case .bool: ts = "boolean" + case .int, .float, .double: ts = "number" + default: ts = "never" + } + fields.append("\(prop): \(ts)") + } + unionParts.append("{ \(fields.joined(separator: "; ")) }") + } + } + dtsLines.append("type \(enumDefinition.name) =".indent(count: identBaseSize * contentDepth)) + dtsLines.append( + " " + unionParts.joined(separator: " | ").indent(count: identBaseSize * contentDepth) + ) + case .namespace: continue } } diff --git a/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift b/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift index ae74844f..84417cd4 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift @@ -15,6 +15,12 @@ final class JSGlueVariableScope { static let reservedStorageToReturnException = "tmpRetException" static let reservedTextEncoder = "textEncoder" static let reservedTextDecoder = "textDecoder" + static let reservedTmpRetTag = "tmpRetTag" + static let reservedTmpRetStrings = "tmpRetStrings" + static let reservedTmpRetInts = "tmpRetInts" + static let reservedTmpRetF32s = "tmpRetF32s" + static let reservedTmpRetF64s = "tmpRetF64s" + static let reservedTmpRetBools = "tmpRetBools" private var variables: Set = [ reservedSwift, @@ -24,6 +30,12 @@ final class JSGlueVariableScope { reservedStorageToReturnException, reservedTextEncoder, reservedTextDecoder, + reservedTmpRetTag, + reservedTmpRetStrings, + reservedTmpRetInts, + reservedTmpRetF32s, + reservedTmpRetF64s, + reservedTmpRetBools, ] /// Returns a unique variable name in the scope based on the given name hint. @@ -194,6 +206,37 @@ struct IntrinsicJSFragment: Sendable { ) } + static func associatedEnumLowerParameter(enumBase: String) -> IntrinsicJSFragment { + IntrinsicJSFragment( + parameters: ["value"], + printCode: { arguments, scope, printer, cleanup in + let value = arguments[0] + let caseIdName = "\(value)CaseId" + let paramsIdName = "\(value)ParamsId" + let paramsLenName = "\(value)ParamsLen" + let cleanupName = "\(value)Cleanup" + printer.write( + "const { caseId: \(caseIdName), paramsId: \(paramsIdName), paramsLen: \(paramsLenName), cleanup: \(cleanupName) } = enumHelpers.\(enumBase).lower(\(value));" + ) + cleanup.write("if (\(cleanupName)) { \(cleanupName)(); }") + return [caseIdName, paramsIdName, paramsLenName] + } + ) + } + + static func associatedEnumLiftReturn(enumBase: String) -> IntrinsicJSFragment { + IntrinsicJSFragment( + parameters: [], + printCode: { _, scope, printer, _ in + let retName = scope.variable("ret") + printer.write( + "const \(retName) = enumHelpers.\(enumBase).raise(\(JSGlueVariableScope.reservedTmpRetTag), \(JSGlueVariableScope.reservedTmpRetStrings), \(JSGlueVariableScope.reservedTmpRetInts), \(JSGlueVariableScope.reservedTmpRetF32s), \(JSGlueVariableScope.reservedTmpRetF64s), \(JSGlueVariableScope.reservedTmpRetBools));" + ) + return [retName] + } + ) + } + // MARK: - ExportSwift /// Returns a fragment that lowers a JS value to Wasm core values for parameters @@ -211,10 +254,9 @@ struct IntrinsicJSFragment: Sendable { 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 .associatedValueEnum(let fullName): + let base = fullName.components(separatedBy: ".").last ?? fullName + return .associatedEnumLowerParameter(enumBase: base) case .namespaceEnum(let string): throw BridgeJSLinkError(message: "Namespace enums are not supported to be passed as parameters: \(string)") } @@ -236,10 +278,9 @@ struct IntrinsicJSFragment: Sendable { 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 .associatedValueEnum(let fullName): + let base = fullName.components(separatedBy: ".").last ?? fullName + return .associatedEnumLiftReturn(enumBase: base) case .namespaceEnum(let string): throw BridgeJSLinkError( message: "Namespace enums are not supported to be returned from functions: \(string)" diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/EnumAssociatedValue.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/EnumAssociatedValue.swift new file mode 100644 index 00000000..08d03a2b --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/EnumAssociatedValue.swift @@ -0,0 +1,40 @@ +@JS +enum APIResult { + case success(String) + case failure(Int) + case flag(Bool) + case rate(Float) + case precise(Double) + case info +} + +@JS func handle(result: APIResult) +@JS func getResult() -> APIResult + +@JS +enum ComplexResult { + case success(String) + case error(String, Int) + case status(Bool, Int, String) + case coordinates(Double, Double, Double) + case comprehensive(Bool, Bool, Int, Int, Double, Double, String, String, String) + case info +} + +@JS func handleComplex(result: ComplexResult) +@JS func getComplexResult() -> ComplexResult + +@JS +enum Utilities { + @JS enum Result { + case success(String) + case failure(String, Int) + case status(Bool, Int, String) + } +} + +@JS(namespace: "API") +@JS enum NetworkingResult { + case success(String) + case failure(String, Int) +} diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayParameter.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayParameter.Import.js index c122f179..602cd9a4 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayParameter.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayParameter.Import.js @@ -10,10 +10,17 @@ export async function createInstantiator(options, swift) { let setException; const textDecoder = new TextDecoder("utf-8"); const textEncoder = new TextEncoder("utf-8"); - let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +31,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +58,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_checkArray"] = function bjs_checkArray(a) { @@ -76,6 +109,7 @@ export async function createInstantiator(options, swift) { setInstance: (i) => { instance = i; memory = instance.exports.memory; + setException = (error) => { instance.exports._swift_js_exception.value = swift.memory.retain(error) } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Export.js index 97c1e215..f20f4932 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Export.js @@ -10,10 +10,17 @@ export async function createInstantiator(options, swift) { let setException; const textDecoder = new TextDecoder("utf-8"); const textEncoder = new TextEncoder("utf-8"); - let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +31,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,12 +58,37 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } }, setInstance: (i) => { instance = i; memory = instance.exports.memory; + setException = (error) => { instance.exports._swift_js_exception.value = swift.memory.retain(error) } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Import.js index 0b07aedd..95898a12 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Import.js @@ -10,10 +10,17 @@ export async function createInstantiator(options, swift) { let setException; const textDecoder = new TextDecoder("utf-8"); const textEncoder = new TextEncoder("utf-8"); - let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +31,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +58,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_asyncReturnVoid"] = function bjs_asyncReturnVoid() { @@ -120,6 +153,7 @@ export async function createInstantiator(options, swift) { setInstance: (i) => { instance = i; memory = instance.exports.memory; + setException = (error) => { instance.exports._swift_js_exception.value = swift.memory.retain(error) } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.d.ts new file mode 100644 index 00000000..4d7394b4 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.d.ts @@ -0,0 +1,75 @@ +// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit, +// DO NOT EDIT. +// +// To update this file, just rebuild your project or run +// `swift package bridge-js`. + +export const APIResult: { + readonly Tag: { + readonly Success: 0; + readonly Failure: 1; + readonly Flag: 2; + readonly Rate: 3; + readonly Precise: 4; + readonly Info: 5; + }; +}; + +export type APIResult = + { tag: typeof APIResult.Tag.Success; param0: string } | { tag: typeof APIResult.Tag.Failure; param0: number } | { tag: typeof APIResult.Tag.Flag; param0: boolean } | { tag: typeof APIResult.Tag.Rate; param0: number } | { tag: typeof APIResult.Tag.Precise; param0: number } | { tag: typeof APIResult.Tag.Info } + +export const ComplexResult: { + readonly Tag: { + readonly Success: 0; + readonly Error: 1; + readonly Status: 2; + readonly Coordinates: 3; + readonly Comprehensive: 4; + readonly Info: 5; + }; +}; + +export type ComplexResult = + { tag: typeof ComplexResult.Tag.Success; param0: string } | { tag: typeof ComplexResult.Tag.Error; param0: string; param1: number } | { tag: typeof ComplexResult.Tag.Status; param0: boolean; param1: number; param2: string } | { tag: typeof ComplexResult.Tag.Coordinates; param0: number; param1: number; param2: number } | { tag: typeof ComplexResult.Tag.Comprehensive; param0: boolean; param1: boolean; param2: number; param3: number; param4: number; param5: number; param6: string; param7: string; param8: string } | { tag: typeof ComplexResult.Tag.Info } + +export {}; + +declare global { + namespace API { + const NetworkingResult: { + readonly Tag: { + readonly Success: 0; + readonly Failure: 1; + }; + }; + type NetworkingResult = + { tag: typeof NetworkingResult.Tag.Success; param0: string } | { tag: typeof NetworkingResult.Tag.Failure; param0: string; param1: number } + } + namespace Utilities { + const Result: { + readonly Tag: { + readonly Success: 0; + readonly Failure: 1; + readonly Status: 2; + }; + }; + type Result = + { tag: typeof Result.Tag.Success; param0: string } | { tag: typeof Result.Tag.Failure; param0: string; param1: number } | { tag: typeof Result.Tag.Status; param0: boolean; param1: number; param2: string } + } +} + +export type Exports = { + handle(result: APIResult): void; + getResult(): APIResult; + handleComplex(result: ComplexResult): void; + getComplexResult(): ComplexResult; +} +export type Imports = { +} +export function createInstantiator(options: { + imports: Imports; +}, swift: any): Promise<{ + addImports: (importObject: WebAssembly.Imports) => void; + setInstance: (instance: WebAssembly.Instance) => void; + createExports: (instance: WebAssembly.Instance) => Exports; +}>; \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.js new file mode 100644 index 00000000..79a2e777 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.js @@ -0,0 +1,445 @@ +// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit, +// DO NOT EDIT. +// +// To update this file, just rebuild your project or run +// `swift package bridge-js`. + +/// Shared helpers for encoding associated-value enums between JS and Swift. +const __bjs_ParamType = { STRING: 1, INT32: 2, BOOL: 3, FLOAT32: 4, FLOAT64: 5 }; +function __bjs_encodeEnumParams(textEncoder, swift, parts) { + const SIZE_U8 = 1, SIZE_U32 = 4, SIZE_F32 = 4, SIZE_F64 = 8; + let totalLen = SIZE_U32; + for (const p of parts) { + switch (p.t) { + case __bjs_ParamType.STRING: { + const bytes = textEncoder.encode(p.v); + p._bytes = bytes; + totalLen += SIZE_U8 + SIZE_U32 + bytes.length; + break; + } + case __bjs_ParamType.INT32: totalLen += SIZE_U8 + SIZE_U32; break; + case __bjs_ParamType.BOOL: totalLen += SIZE_U8 + SIZE_U8; break; + case __bjs_ParamType.FLOAT32: totalLen += SIZE_U8 + SIZE_F32; break; + case __bjs_ParamType.FLOAT64: totalLen += SIZE_U8 + SIZE_F64; break; + default: throw new Error("Unsupported param type tag: " + p.t); + } + } + const buf = new Uint8Array(totalLen); + const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength); + let off = 0; + view.setUint32(off, parts.length, true); off += SIZE_U32; + for (const p of parts) { + view.setUint8(off, p.t); off += SIZE_U8; + switch (p.t) { + case __bjs_ParamType.STRING: { + const b = p._bytes; + view.setUint32(off, b.length, true); off += SIZE_U32; + buf.set(b, off); off += b.length; + break; + } + case __bjs_ParamType.INT32: + view.setInt32(off, (p.v | 0), true); off += SIZE_U32; break; + case __bjs_ParamType.BOOL: + view.setUint8(off, p.v ? 1 : 0); off += SIZE_U8; break; + case __bjs_ParamType.FLOAT32: + view.setFloat32(off, Math.fround(p.v), true); off += SIZE_F32; break; + case __bjs_ParamType.FLOAT64: + view.setFloat64(off, p.v, true); off += SIZE_F64; break; + default: throw new Error("Unsupported param type tag: " + p.t); + } + } + const paramsId = swift.memory.retain(buf); + return { paramsId, paramsLen: buf.length, cleanup: () => { swift.memory.release(paramsId); } }; +} +export const APIResult = { + Tag: { + Success: 0, + Failure: 1, + Flag: 2, + Rate: 3, + Precise: 4, + Info: 5, + } +}; + +const __bjs_createAPIResultHelpers = () => { + return (textEncoder, swift) => ({ + lower: (value) => { + const enumTag = value.tag; + switch (enumTag) { + case APIResult.Tag.Success: { + const parts = [ + { t: __bjs_ParamType.STRING, v: value.param0 } + ]; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: APIResult.Tag.Success, paramsId, paramsLen, cleanup }; + } + case APIResult.Tag.Failure: { + const parts = [ + { t: __bjs_ParamType.INT32, v: (value.param0 | 0) } + ]; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: APIResult.Tag.Failure, paramsId, paramsLen, cleanup }; + } + case APIResult.Tag.Flag: { + const parts = [ + { t: __bjs_ParamType.BOOL, v: value.param0 } + ]; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: APIResult.Tag.Flag, paramsId, paramsLen, cleanup }; + } + case APIResult.Tag.Rate: { + const parts = [ + { t: __bjs_ParamType.FLOAT32, v: value.param0 } + ]; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: APIResult.Tag.Rate, paramsId, paramsLen, cleanup }; + } + case APIResult.Tag.Precise: { + const parts = [ + { t: __bjs_ParamType.FLOAT64, v: value.param0 } + ]; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: APIResult.Tag.Precise, paramsId, paramsLen, cleanup }; + } + case APIResult.Tag.Info: { + const parts = []; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: APIResult.Tag.Info, paramsId, paramsLen, cleanup }; + } + default: throw new Error("Unknown APIResult tag: " + String(enumTag)); + } + }, + raise: (tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetBools) => { + const tag = tmpRetTag | 0; + switch (tag) { + case APIResult.Tag.Success: return { tag: APIResult.Tag.Success, param0: tmpRetStrings[0] }; + case APIResult.Tag.Failure: return { tag: APIResult.Tag.Failure, param0: tmpRetInts[0] }; + case APIResult.Tag.Flag: return { tag: APIResult.Tag.Flag, param0: tmpRetBools[0] }; + case APIResult.Tag.Rate: return { tag: APIResult.Tag.Rate, param0: tmpRetF32s[0] }; + case APIResult.Tag.Precise: return { tag: APIResult.Tag.Precise, param0: tmpRetF64s[0] }; + case APIResult.Tag.Info: return { tag: APIResult.Tag.Info }; + default: throw new Error("Unknown APIResult tag returned from Swift: " + String(tag)); + } + } + }); +}; +export const ComplexResult = { + Tag: { + Success: 0, + Error: 1, + Status: 2, + Coordinates: 3, + Comprehensive: 4, + Info: 5, + } +}; + +const __bjs_createComplexResultHelpers = () => { + return (textEncoder, swift) => ({ + lower: (value) => { + const enumTag = value.tag; + switch (enumTag) { + case ComplexResult.Tag.Success: { + const parts = [ + { t: __bjs_ParamType.STRING, v: value.param0 } + ]; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: ComplexResult.Tag.Success, paramsId, paramsLen, cleanup }; + } + case ComplexResult.Tag.Error: { + const parts = [ + { t: __bjs_ParamType.STRING, v: value.param0 }, + { t: __bjs_ParamType.INT32, v: (value.param1 | 0) } + ]; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: ComplexResult.Tag.Error, paramsId, paramsLen, cleanup }; + } + case ComplexResult.Tag.Status: { + const parts = [ + { t: __bjs_ParamType.BOOL, v: value.param0 }, + { t: __bjs_ParamType.INT32, v: (value.param1 | 0) }, + { t: __bjs_ParamType.STRING, v: value.param2 } + ]; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: ComplexResult.Tag.Status, paramsId, paramsLen, cleanup }; + } + case ComplexResult.Tag.Coordinates: { + const parts = [ + { t: __bjs_ParamType.FLOAT64, v: value.param0 }, + { t: __bjs_ParamType.FLOAT64, v: value.param1 }, + { t: __bjs_ParamType.FLOAT64, v: value.param2 } + ]; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: ComplexResult.Tag.Coordinates, paramsId, paramsLen, cleanup }; + } + case ComplexResult.Tag.Comprehensive: { + const parts = [ + { t: __bjs_ParamType.BOOL, v: value.param0 }, + { t: __bjs_ParamType.BOOL, v: value.param1 }, + { t: __bjs_ParamType.INT32, v: (value.param2 | 0) }, + { t: __bjs_ParamType.INT32, v: (value.param3 | 0) }, + { t: __bjs_ParamType.FLOAT64, v: value.param4 }, + { t: __bjs_ParamType.FLOAT64, v: value.param5 }, + { t: __bjs_ParamType.STRING, v: value.param6 }, + { t: __bjs_ParamType.STRING, v: value.param7 }, + { t: __bjs_ParamType.STRING, v: value.param8 } + ]; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: ComplexResult.Tag.Comprehensive, paramsId, paramsLen, cleanup }; + } + case ComplexResult.Tag.Info: { + const parts = []; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: ComplexResult.Tag.Info, paramsId, paramsLen, cleanup }; + } + default: throw new Error("Unknown ComplexResult tag: " + String(enumTag)); + } + }, + raise: (tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetBools) => { + const tag = tmpRetTag | 0; + switch (tag) { + case ComplexResult.Tag.Success: return { tag: ComplexResult.Tag.Success, param0: tmpRetStrings[0] }; + case ComplexResult.Tag.Error: return { tag: ComplexResult.Tag.Error, param0: tmpRetStrings[0], param1: tmpRetInts[0] }; + case ComplexResult.Tag.Status: return { tag: ComplexResult.Tag.Status, param0: tmpRetBools[0], param1: tmpRetInts[0], param2: tmpRetStrings[0] }; + case ComplexResult.Tag.Coordinates: return { tag: ComplexResult.Tag.Coordinates, param0: tmpRetF64s[0], param1: tmpRetF64s[1], param2: tmpRetF64s[2] }; + case ComplexResult.Tag.Comprehensive: return { tag: ComplexResult.Tag.Comprehensive, param0: tmpRetBools[0], param1: tmpRetBools[1], param2: tmpRetInts[0], param3: tmpRetInts[1], param4: tmpRetF64s[0], param5: tmpRetF64s[1], param6: tmpRetStrings[0], param7: tmpRetStrings[1], param8: tmpRetStrings[2] }; + case ComplexResult.Tag.Info: return { tag: ComplexResult.Tag.Info }; + default: throw new Error("Unknown ComplexResult tag returned from Swift: " + String(tag)); + } + } + }); +}; +export const Result = { + Tag: { + Success: 0, + Failure: 1, + Status: 2, + } +}; + +const __bjs_createResultHelpers = () => { + return (textEncoder, swift) => ({ + lower: (value) => { + const enumTag = value.tag; + switch (enumTag) { + case Result.Tag.Success: { + const parts = [ + { t: __bjs_ParamType.STRING, v: value.param0 } + ]; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: Result.Tag.Success, paramsId, paramsLen, cleanup }; + } + case Result.Tag.Failure: { + const parts = [ + { t: __bjs_ParamType.STRING, v: value.param0 }, + { t: __bjs_ParamType.INT32, v: (value.param1 | 0) } + ]; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: Result.Tag.Failure, paramsId, paramsLen, cleanup }; + } + case Result.Tag.Status: { + const parts = [ + { t: __bjs_ParamType.BOOL, v: value.param0 }, + { t: __bjs_ParamType.INT32, v: (value.param1 | 0) }, + { t: __bjs_ParamType.STRING, v: value.param2 } + ]; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: Result.Tag.Status, paramsId, paramsLen, cleanup }; + } + default: throw new Error("Unknown Result tag: " + String(enumTag)); + } + }, + raise: (tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetBools) => { + const tag = tmpRetTag | 0; + switch (tag) { + case Result.Tag.Success: return { tag: Result.Tag.Success, param0: tmpRetStrings[0] }; + case Result.Tag.Failure: return { tag: Result.Tag.Failure, param0: tmpRetStrings[0], param1: tmpRetInts[0] }; + case Result.Tag.Status: return { tag: Result.Tag.Status, param0: tmpRetBools[0], param1: tmpRetInts[0], param2: tmpRetStrings[0] }; + default: throw new Error("Unknown Result tag returned from Swift: " + String(tag)); + } + } + }); +}; +export const NetworkingResult = { + Tag: { + Success: 0, + Failure: 1, + } +}; + +const __bjs_createNetworkingResultHelpers = () => { + return (textEncoder, swift) => ({ + lower: (value) => { + const enumTag = value.tag; + switch (enumTag) { + case NetworkingResult.Tag.Success: { + const parts = [ + { t: __bjs_ParamType.STRING, v: value.param0 } + ]; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: NetworkingResult.Tag.Success, paramsId, paramsLen, cleanup }; + } + case NetworkingResult.Tag.Failure: { + const parts = [ + { t: __bjs_ParamType.STRING, v: value.param0 }, + { t: __bjs_ParamType.INT32, v: (value.param1 | 0) } + ]; + const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); + return { caseId: NetworkingResult.Tag.Failure, paramsId, paramsLen, cleanup }; + } + default: throw new Error("Unknown NetworkingResult tag: " + String(enumTag)); + } + }, + raise: (tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetBools) => { + const tag = tmpRetTag | 0; + switch (tag) { + case NetworkingResult.Tag.Success: return { tag: NetworkingResult.Tag.Success, param0: tmpRetStrings[0] }; + case NetworkingResult.Tag.Failure: return { tag: NetworkingResult.Tag.Failure, param0: tmpRetStrings[0], param1: tmpRetInts[0] }; + default: throw new Error("Unknown NetworkingResult tag returned from Swift: " + String(tag)); + } + } + }); +}; + +if (typeof globalThis.Utilities === 'undefined') { + globalThis.Utilities = {}; +} +if (typeof globalThis.API === 'undefined') { + globalThis.API = {}; +} + +globalThis.Utilities.Result = Result; +globalThis.API.NetworkingResult = NetworkingResult; + +export async function createInstantiator(options, swift) { + let instance; + let memory; + let setException; + const textDecoder = new TextDecoder("utf-8"); + const textEncoder = new TextEncoder("utf-8"); + let tmpRetString; + let tmpRetBytes; + let tmpRetException; + let tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + const enumHelpers = {}; + + return { + /** + * @param {WebAssembly.Imports} importObject + */ + addImports: (importObject, importsContext) => { + const bjs = {}; + importObject["bjs"] = bjs; + const imports = options.getImports(importsContext); + bjs["swift_js_return_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); + } + bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { + const source = swift.memory.getObject(sourceId); + const bytes = new Uint8Array(memory.buffer, bytesPtr); + bytes.set(source); + } + bjs["swift_js_make_js_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + return swift.memory.retain(textDecoder.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; + } + bjs["swift_js_throw"] = function(id) { + tmpRetException = swift.memory.retainByRef(id); + } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } + + + }, + setInstance: (i) => { + instance = i; + memory = instance.exports.memory; + + + const APIResultHelpers = __bjs_createAPIResultHelpers()(textEncoder, swift); + enumHelpers.APIResult = APIResultHelpers; + + const ComplexResultHelpers = __bjs_createComplexResultHelpers()(textEncoder, swift); + enumHelpers.ComplexResult = ComplexResultHelpers; + + const ResultHelpers = __bjs_createResultHelpers()(textEncoder, swift); + enumHelpers.Result = ResultHelpers; + + const NetworkingResultHelpers = __bjs_createNetworkingResultHelpers()(textEncoder, swift); + enumHelpers.NetworkingResult = NetworkingResultHelpers; + + setException = (error) => { + instance.exports._swift_js_exception.value = swift.memory.retain(error) + } + }, + /** @param {WebAssembly.Instance} instance */ + createExports: (instance) => { + const js = swift.memory.heap; + + return { + handle: function bjs_handle(result) { + const { caseId: resultCaseId, paramsId: resultParamsId, paramsLen: resultParamsLen, cleanup: resultCleanup } = enumHelpers.APIResult.lower(result); + instance.exports.bjs_handle(resultCaseId, resultParamsId, resultParamsLen); + if (resultCleanup) { resultCleanup(); } + }, + getResult: function bjs_getResult() { + instance.exports.bjs_getResult(); + const ret = enumHelpers.APIResult.raise(tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetBools); + return ret; + }, + handleComplex: function bjs_handleComplex(result) { + const { caseId: resultCaseId, paramsId: resultParamsId, paramsLen: resultParamsLen, cleanup: resultCleanup } = enumHelpers.ComplexResult.lower(result); + instance.exports.bjs_handleComplex(resultCaseId, resultParamsId, resultParamsLen); + if (resultCleanup) { resultCleanup(); } + }, + getComplexResult: function bjs_getComplexResult() { + instance.exports.bjs_getComplexResult(); + const ret = enumHelpers.ComplexResult.raise(tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetBools); + return ret; + }, + }; + }, + } +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.Export.js index b5bc1145..7b7a3003 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.Export.js @@ -35,10 +35,17 @@ export async function createInstantiator(options, swift) { let setException; const textDecoder = new TextDecoder("utf-8"); const textEncoder = new TextEncoder("utf-8"); - let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + + return { /** * @param {WebAssembly.Imports} importObject @@ -49,7 +56,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -74,12 +83,37 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } }, setInstance: (i) => { instance = i; memory = instance.exports.memory; + setException = (error) => { instance.exports._swift_js_exception.value = swift.memory.retain(error) } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.js index 677e02c9..b6f5ff98 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.js @@ -57,10 +57,17 @@ export async function createInstantiator(options, swift) { let setException; const textDecoder = new TextDecoder("utf-8"); const textEncoder = new TextEncoder("utf-8"); - let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + + return { /** * @param {WebAssembly.Imports} importObject @@ -71,7 +78,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -96,6 +105,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } // Wrapper functions for module: TestModule if (!importObject["TestModule"]) { importObject["TestModule"] = {}; @@ -117,6 +150,7 @@ export async function createInstantiator(options, swift) { setInstance: (i) => { instance = i; memory = instance.exports.memory; + setException = (error) => { instance.exports._swift_js_exception.value = swift.memory.retain(error) } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.Export.js index 2be034b4..0d85607a 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.Export.js @@ -86,10 +86,17 @@ export async function createInstantiator(options, swift) { let setException; const textDecoder = new TextDecoder("utf-8"); const textEncoder = new TextEncoder("utf-8"); - let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + + return { /** * @param {WebAssembly.Imports} importObject @@ -100,7 +107,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -125,12 +134,37 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } }, setInstance: (i) => { instance = i; memory = instance.exports.memory; + setException = (error) => { instance.exports._swift_js_exception.value = swift.memory.retain(error) } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Interface.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Interface.Import.js index f81c7e47..18fd6be1 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Interface.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Interface.Import.js @@ -10,10 +10,17 @@ export async function createInstantiator(options, swift) { let setException; const textDecoder = new TextDecoder("utf-8"); const textEncoder = new TextEncoder("utf-8"); - let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +31,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +58,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_returnAnimatable"] = function bjs_returnAnimatable() { @@ -82,6 +115,7 @@ export async function createInstantiator(options, swift) { setInstance: (i) => { instance = i; memory = instance.exports.memory; + setException = (error) => { instance.exports._swift_js_exception.value = swift.memory.retain(error) } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/InvalidPropertyNames.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/InvalidPropertyNames.Import.js index 6b5211e0..834f1a79 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/InvalidPropertyNames.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/InvalidPropertyNames.Import.js @@ -10,10 +10,17 @@ export async function createInstantiator(options, swift) { let setException; const textDecoder = new TextDecoder("utf-8"); const textEncoder = new TextEncoder("utf-8"); - let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +31,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +58,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_createArrayBuffer"] = function bjs_createArrayBuffer() { @@ -152,6 +185,7 @@ export async function createInstantiator(options, swift) { setInstance: (i) => { instance = i; memory = instance.exports.memory; + setException = (error) => { instance.exports._swift_js_exception.value = swift.memory.retain(error) } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MultipleImportedTypes.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MultipleImportedTypes.Import.js index d9a13b5e..d4e582ed 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MultipleImportedTypes.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MultipleImportedTypes.Import.js @@ -10,10 +10,17 @@ export async function createInstantiator(options, swift) { let setException; const textDecoder = new TextDecoder("utf-8"); const textEncoder = new TextEncoder("utf-8"); - let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +31,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +58,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_createDatabaseConnection"] = function bjs_createDatabaseConnection(config) { @@ -186,6 +219,7 @@ export async function createInstantiator(options, swift) { setInstance: (i) => { instance = i; memory = instance.exports.memory; + setException = (error) => { instance.exports._swift_js_exception.value = swift.memory.retain(error) } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Export.js index 6915a61a..519058fa 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Export.js @@ -10,10 +10,17 @@ export async function createInstantiator(options, swift) { let setException; const textDecoder = new TextDecoder("utf-8"); const textEncoder = new TextEncoder("utf-8"); - let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +31,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +58,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } // Wrapper functions for module: TestModule if (!importObject["TestModule"]) { importObject["TestModule"] = {}; @@ -70,6 +103,7 @@ export async function createInstantiator(options, swift) { setInstance: (i) => { instance = i; memory = instance.exports.memory; + setException = (error) => { instance.exports._swift_js_exception.value = swift.memory.retain(error) } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Export.js index 4873fc33..e10084e5 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Export.js @@ -10,10 +10,17 @@ export async function createInstantiator(options, swift) { let setException; const textDecoder = new TextDecoder("utf-8"); const textEncoder = new TextEncoder("utf-8"); - let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +31,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,12 +58,37 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } }, setInstance: (i) => { instance = i; memory = instance.exports.memory; + setException = (error) => { instance.exports._swift_js_exception.value = swift.memory.retain(error) } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Import.js index b0dbaa19..f6d572b1 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Import.js @@ -10,10 +10,17 @@ export async function createInstantiator(options, swift) { let setException; const textDecoder = new TextDecoder("utf-8"); const textEncoder = new TextEncoder("utf-8"); - let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +31,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +58,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_check"] = function bjs_check(a, b) { @@ -62,6 +95,7 @@ export async function createInstantiator(options, swift) { setInstance: (i) => { instance = i; memory = instance.exports.memory; + setException = (error) => { instance.exports._swift_js_exception.value = swift.memory.retain(error) } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Export.js index 594dc9d5..8fe8c446 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Export.js @@ -10,10 +10,17 @@ export async function createInstantiator(options, swift) { let setException; const textDecoder = new TextDecoder("utf-8"); const textEncoder = new TextEncoder("utf-8"); - let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +31,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,12 +58,37 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } }, setInstance: (i) => { instance = i; memory = instance.exports.memory; + setException = (error) => { instance.exports._swift_js_exception.value = swift.memory.retain(error) } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Import.js index a61149cd..6dbbbac5 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Import.js @@ -10,10 +10,17 @@ export async function createInstantiator(options, swift) { let setException; const textDecoder = new TextDecoder("utf-8"); const textEncoder = new TextEncoder("utf-8"); - let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +31,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +58,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_checkNumber"] = function bjs_checkNumber() { @@ -73,6 +106,7 @@ export async function createInstantiator(options, swift) { setInstance: (i) => { instance = i; memory = instance.exports.memory; + setException = (error) => { instance.exports._swift_js_exception.value = swift.memory.retain(error) } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PropertyTypes.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PropertyTypes.Export.js index ffc1eab6..f273ef10 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PropertyTypes.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PropertyTypes.Export.js @@ -10,10 +10,17 @@ export async function createInstantiator(options, swift) { let setException; const textDecoder = new TextDecoder("utf-8"); const textEncoder = new TextEncoder("utf-8"); - let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +31,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +58,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } // Wrapper functions for module: TestModule if (!importObject["TestModule"]) { importObject["TestModule"] = {}; @@ -62,6 +95,7 @@ export async function createInstantiator(options, swift) { setInstance: (i) => { instance = i; memory = instance.exports.memory; + setException = (error) => { instance.exports._swift_js_exception.value = swift.memory.retain(error) } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Export.js index ea47fb55..835eb802 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Export.js @@ -10,10 +10,17 @@ export async function createInstantiator(options, swift) { let setException; const textDecoder = new TextDecoder("utf-8"); const textEncoder = new TextEncoder("utf-8"); - let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +31,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,12 +58,37 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } }, setInstance: (i) => { instance = i; memory = instance.exports.memory; + setException = (error) => { instance.exports._swift_js_exception.value = swift.memory.retain(error) } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Import.js index 16ed1081..9e28b776 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Import.js @@ -10,10 +10,17 @@ export async function createInstantiator(options, swift) { let setException; const textDecoder = new TextDecoder("utf-8"); const textEncoder = new TextEncoder("utf-8"); - let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +31,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +58,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_checkString"] = function bjs_checkString(a) { @@ -73,6 +106,7 @@ export async function createInstantiator(options, swift) { setInstance: (i) => { instance = i; memory = instance.exports.memory; + setException = (error) => { instance.exports._swift_js_exception.value = swift.memory.retain(error) } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Export.js index f98cea55..43d2e4fb 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Export.js @@ -10,10 +10,17 @@ export async function createInstantiator(options, swift) { let setException; const textDecoder = new TextDecoder("utf-8"); const textEncoder = new TextEncoder("utf-8"); - let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +31,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,12 +58,37 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } }, setInstance: (i) => { instance = i; memory = instance.exports.memory; + setException = (error) => { instance.exports._swift_js_exception.value = swift.memory.retain(error) } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Import.js index 3220ae7b..0c9eccf8 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Import.js @@ -10,10 +10,17 @@ export async function createInstantiator(options, swift) { let setException; const textDecoder = new TextDecoder("utf-8"); const textEncoder = new TextEncoder("utf-8"); - let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +31,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +58,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_checkString"] = function bjs_checkString() { @@ -64,6 +97,7 @@ export async function createInstantiator(options, swift) { setInstance: (i) => { instance = i; memory = instance.exports.memory; + setException = (error) => { instance.exports._swift_js_exception.value = swift.memory.retain(error) } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.Export.js index fb995d24..370c6229 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.Export.js @@ -10,10 +10,17 @@ export async function createInstantiator(options, swift) { let setException; const textDecoder = new TextDecoder("utf-8"); const textEncoder = new TextEncoder("utf-8"); - let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +31,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +58,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } // Wrapper functions for module: TestModule if (!importObject["TestModule"]) { importObject["TestModule"] = {}; @@ -70,6 +103,7 @@ export async function createInstantiator(options, swift) { setInstance: (i) => { instance = i; memory = instance.exports.memory; + setException = (error) => { instance.exports._swift_js_exception.value = swift.memory.retain(error) } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TS2SkeletonLike.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TS2SkeletonLike.Import.js index c7671805..cb20a60b 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TS2SkeletonLike.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TS2SkeletonLike.Import.js @@ -10,10 +10,17 @@ export async function createInstantiator(options, swift) { let setException; const textDecoder = new TextDecoder("utf-8"); const textEncoder = new TextEncoder("utf-8"); - let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +31,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +58,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_createTS2Skeleton"] = function bjs_createTS2Skeleton() { @@ -124,6 +157,7 @@ export async function createInstantiator(options, swift) { setInstance: (i) => { instance = i; memory = instance.exports.memory; + setException = (error) => { instance.exports._swift_js_exception.value = swift.memory.retain(error) } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Throws.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Throws.Export.js index b2089962..3836d437 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Throws.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Throws.Export.js @@ -10,10 +10,17 @@ export async function createInstantiator(options, swift) { let setException; const textDecoder = new TextDecoder("utf-8"); const textEncoder = new TextEncoder("utf-8"); - let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +31,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,12 +58,37 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } }, setInstance: (i) => { instance = i; memory = instance.exports.memory; + setException = (error) => { instance.exports._swift_js_exception.value = swift.memory.retain(error) } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeAlias.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeAlias.Import.js index 2eb9dee5..578ec5d6 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeAlias.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeAlias.Import.js @@ -10,10 +10,17 @@ export async function createInstantiator(options, swift) { let setException; const textDecoder = new TextDecoder("utf-8"); const textEncoder = new TextEncoder("utf-8"); - let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +31,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +58,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_checkSimple"] = function bjs_checkSimple(a) { @@ -62,6 +95,7 @@ export async function createInstantiator(options, swift) { setInstance: (i) => { instance = i; memory = instance.exports.memory; + setException = (error) => { instance.exports._swift_js_exception.value = swift.memory.retain(error) } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeScriptClass.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeScriptClass.Import.js index 48d15c7e..bd6a6907 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeScriptClass.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeScriptClass.Import.js @@ -10,10 +10,17 @@ export async function createInstantiator(options, swift) { let setException; const textDecoder = new TextDecoder("utf-8"); const textEncoder = new TextEncoder("utf-8"); - let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +31,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +58,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_Greeter_init"] = function bjs_Greeter_init(name) { @@ -110,6 +143,7 @@ export async function createInstantiator(options, swift) { setInstance: (i) => { instance = i; memory = instance.exports.memory; + setException = (error) => { instance.exports._swift_js_exception.value = swift.memory.retain(error) } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Export.js index c200c077..91f069dd 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Export.js @@ -10,10 +10,17 @@ export async function createInstantiator(options, swift) { let setException; const textDecoder = new TextDecoder("utf-8"); const textEncoder = new TextEncoder("utf-8"); - let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +31,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,12 +58,37 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } }, setInstance: (i) => { instance = i; memory = instance.exports.memory; + setException = (error) => { instance.exports._swift_js_exception.value = swift.memory.retain(error) } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Import.js index ca497688..5eab9f77 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Import.js @@ -10,10 +10,17 @@ export async function createInstantiator(options, swift) { let setException; const textDecoder = new TextDecoder("utf-8"); const textEncoder = new TextEncoder("utf-8"); - let tmpRetString; let tmpRetBytes; let tmpRetException; + let tmpRetTag; + let tmpRetStrings = []; + let tmpRetInts = []; + let tmpRetF32s = []; + let tmpRetF64s = []; + let tmpRetBools = []; + + return { /** * @param {WebAssembly.Imports} importObject @@ -24,7 +31,9 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - tmpRetString = textDecoder.decode(bytes); + const value = textDecoder.decode(bytes); + tmpRetString = value; + tmpRetStrings.push(value); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -49,6 +58,30 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } + bjs["swift_js_return_tag"] = function(tag) { + tmpRetTag = tag | 0; + tmpRetString = undefined; + tmpRetStrings = []; + tmpRetInts = []; + tmpRetF32s = []; + tmpRetF64s = []; + tmpRetBools = []; + } + bjs["swift_js_return_int"] = function(v) { + const value = v | 0; + tmpRetInts.push(value); + } + bjs["swift_js_return_f32"] = function(v) { + const value = Math.fround(v); + tmpRetF32s.push(value); + } + bjs["swift_js_return_f64"] = function(v) { + tmpRetF64s.push(v); + } + bjs["swift_js_return_bool"] = function(v) { + const value = v !== 0; + tmpRetBools.push(value); + } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_check"] = function bjs_check() { @@ -62,6 +95,7 @@ export async function createInstantiator(options, swift) { setInstance: (i) => { instance = i; memory = instance.exports.memory; + setException = (error) => { instance.exports._swift_js_exception.value = swift.memory.retain(error) } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumAssociatedValue.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumAssociatedValue.json new file mode 100644 index 00000000..1eeca1b8 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumAssociatedValue.json @@ -0,0 +1,435 @@ +{ + "classes" : [ + + ], + "enums" : [ + { + "cases" : [ + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "success" + }, + { + "associatedValues" : [ + { + "type" : { + "int" : { + + } + } + } + ], + "name" : "failure" + }, + { + "associatedValues" : [ + { + "type" : { + "bool" : { + + } + } + } + ], + "name" : "flag" + }, + { + "associatedValues" : [ + { + "type" : { + "float" : { + + } + } + } + ], + "name" : "rate" + }, + { + "associatedValues" : [ + { + "type" : { + "double" : { + + } + } + } + ], + "name" : "precise" + }, + { + "associatedValues" : [ + + ], + "name" : "info" + } + ], + "emitStyle" : "const", + "name" : "APIResult", + "swiftCallName" : "APIResult" + }, + { + "cases" : [ + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "success" + }, + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + }, + { + "type" : { + "int" : { + + } + } + } + ], + "name" : "error" + }, + { + "associatedValues" : [ + { + "type" : { + "bool" : { + + } + } + }, + { + "type" : { + "int" : { + + } + } + }, + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "status" + }, + { + "associatedValues" : [ + { + "type" : { + "double" : { + + } + } + }, + { + "type" : { + "double" : { + + } + } + }, + { + "type" : { + "double" : { + + } + } + } + ], + "name" : "coordinates" + }, + { + "associatedValues" : [ + { + "type" : { + "bool" : { + + } + } + }, + { + "type" : { + "bool" : { + + } + } + }, + { + "type" : { + "int" : { + + } + } + }, + { + "type" : { + "int" : { + + } + } + }, + { + "type" : { + "double" : { + + } + } + }, + { + "type" : { + "double" : { + + } + } + }, + { + "type" : { + "string" : { + + } + } + }, + { + "type" : { + "string" : { + + } + } + }, + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "comprehensive" + }, + { + "associatedValues" : [ + + ], + "name" : "info" + } + ], + "emitStyle" : "const", + "name" : "ComplexResult", + "swiftCallName" : "ComplexResult" + }, + { + "cases" : [ + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "success" + }, + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + }, + { + "type" : { + "int" : { + + } + } + } + ], + "name" : "failure" + }, + { + "associatedValues" : [ + { + "type" : { + "bool" : { + + } + } + }, + { + "type" : { + "int" : { + + } + } + }, + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "status" + } + ], + "emitStyle" : "const", + "name" : "Result", + "namespace" : [ + "Utilities" + ], + "swiftCallName" : "Utilities.Result" + }, + { + "cases" : [ + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "success" + }, + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + }, + { + "type" : { + "int" : { + + } + } + } + ], + "name" : "failure" + } + ], + "emitStyle" : "const", + "name" : "NetworkingResult", + "namespace" : [ + "API" + ], + "swiftCallName" : "NetworkingResult" + } + ], + "functions" : [ + { + "abiName" : "bjs_handle", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "handle", + "parameters" : [ + { + "label" : "result", + "name" : "result", + "type" : { + "associatedValueEnum" : { + "_0" : "APIResult" + } + } + } + ], + "returnType" : { + "void" : { + + } + } + }, + { + "abiName" : "bjs_getResult", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "getResult", + "parameters" : [ + + ], + "returnType" : { + "associatedValueEnum" : { + "_0" : "APIResult" + } + } + }, + { + "abiName" : "bjs_handleComplex", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "handleComplex", + "parameters" : [ + { + "label" : "result", + "name" : "result", + "type" : { + "associatedValueEnum" : { + "_0" : "ComplexResult" + } + } + } + ], + "returnType" : { + "void" : { + + } + } + }, + { + "abiName" : "bjs_getComplexResult", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "getComplexResult", + "parameters" : [ + + ], + "returnType" : { + "associatedValueEnum" : { + "_0" : "ComplexResult" + } + } + } + ], + "moduleName" : "TestModule" +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumAssociatedValue.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumAssociatedValue.swift new file mode 100644 index 00000000..fa3cef9e --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumAssociatedValue.swift @@ -0,0 +1,348 @@ +// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit, +// DO NOT EDIT. +// +// To update this file, just rebuild your project or run +// `swift package bridge-js`. + +@_spi(BridgeJS) import JavaScriptKit + +private extension APIResult { + static func bridgeJSLiftParameter(_ caseId: Int32, _ paramsId: Int32, _ paramsLen: Int32) -> APIResult { + let params: [UInt8] = .init(unsafeUninitializedCapacity: Int(paramsLen)) { buf, initializedCount in + _swift_js_init_memory(paramsId, buf.baseAddress.unsafelyUnwrapped) + initializedCount = Int(paramsLen) + } + return params.withUnsafeBytes { raw in + var reader = _BJSBinaryReader(raw: raw) + switch caseId { + case 0: + reader.readParamCount(expected: 1) + reader.expectTag(.string) + let param0 = reader.readString() + return .success(param0) + case 1: + reader.readParamCount(expected: 1) + reader.expectTag(.int32) + let param0 = Int(reader.readInt32()) + return .failure(param0) + case 2: + reader.readParamCount(expected: 1) + reader.expectTag(.bool) + let param0 = Int32(reader.readUInt8()) != 0 + return .flag(param0) + case 3: + reader.readParamCount(expected: 1) + reader.expectTag(.float32) + let param0 = reader.readFloat32() + return .rate(param0) + case 4: + reader.readParamCount(expected: 1) + reader.expectTag(.float64) + let param0 = reader.readFloat64() + return .precise(param0) + case 5: + return .info + default: + fatalError("Unknown APIResult case ID: \(caseId)") + } + } + } + + func bridgeJSLowerReturn() { + switch self { + case .success(let param0): + _swift_js_return_tag(Int32(0)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + case .failure(let param0): + _swift_js_return_tag(Int32(1)) + _swift_js_return_int(Int32(param0)) + case .flag(let param0): + _swift_js_return_tag(Int32(2)) + _swift_js_return_bool(param0 ? 1 : 0) + case .rate(let param0): + _swift_js_return_tag(Int32(3)) + _swift_js_return_f32(param0) + case .precise(let param0): + _swift_js_return_tag(Int32(4)) + _swift_js_return_f64(param0) + case .info: + _swift_js_return_tag(Int32(5)) + } + } +} + +private extension ComplexResult { + static func bridgeJSLiftParameter(_ caseId: Int32, _ paramsId: Int32, _ paramsLen: Int32) -> ComplexResult { + let params: [UInt8] = .init(unsafeUninitializedCapacity: Int(paramsLen)) { buf, initializedCount in + _swift_js_init_memory(paramsId, buf.baseAddress.unsafelyUnwrapped) + initializedCount = Int(paramsLen) + } + return params.withUnsafeBytes { raw in + var reader = _BJSBinaryReader(raw: raw) + switch caseId { + case 0: + reader.readParamCount(expected: 1) + reader.expectTag(.string) + let param0 = reader.readString() + return .success(param0) + case 1: + reader.readParamCount(expected: 2) + reader.expectTag(.string) + let param0 = reader.readString() + reader.expectTag(.int32) + let param1 = Int(reader.readInt32()) + return .error(param0, param1) + case 2: + reader.readParamCount(expected: 3) + reader.expectTag(.bool) + let param0 = Int32(reader.readUInt8()) != 0 + reader.expectTag(.int32) + let param1 = Int(reader.readInt32()) + reader.expectTag(.string) + let param2 = reader.readString() + return .status(param0, param1, param2) + case 3: + reader.readParamCount(expected: 3) + reader.expectTag(.float64) + let param0 = reader.readFloat64() + reader.expectTag(.float64) + let param1 = reader.readFloat64() + reader.expectTag(.float64) + let param2 = reader.readFloat64() + return .coordinates(param0, param1, param2) + case 4: + reader.readParamCount(expected: 9) + reader.expectTag(.bool) + let param0 = Int32(reader.readUInt8()) != 0 + reader.expectTag(.bool) + let param1 = Int32(reader.readUInt8()) != 0 + reader.expectTag(.int32) + let param2 = Int(reader.readInt32()) + reader.expectTag(.int32) + let param3 = Int(reader.readInt32()) + reader.expectTag(.float64) + let param4 = reader.readFloat64() + reader.expectTag(.float64) + let param5 = reader.readFloat64() + reader.expectTag(.string) + let param6 = reader.readString() + reader.expectTag(.string) + let param7 = reader.readString() + reader.expectTag(.string) + let param8 = reader.readString() + return .comprehensive(param0, param1, param2, param3, param4, param5, param6, param7, param8) + case 5: + return .info + default: + fatalError("Unknown ComplexResult case ID: \(caseId)") + } + } + } + + func bridgeJSLowerReturn() { + switch self { + case .success(let param0): + _swift_js_return_tag(Int32(0)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + case .error(let param0, let param1): + _swift_js_return_tag(Int32(1)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + _swift_js_return_int(Int32(param1)) + case .status(let param0, let param1, let param2): + _swift_js_return_tag(Int32(2)) + _swift_js_return_bool(param0 ? 1 : 0) + _swift_js_return_int(Int32(param1)) + var __bjs_param2 = param2 + __bjs_param2.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + case .coordinates(let param0, let param1, let param2): + _swift_js_return_tag(Int32(3)) + _swift_js_return_f64(param0) + _swift_js_return_f64(param1) + _swift_js_return_f64(param2) + case .comprehensive(let param0, let param1, let param2, let param3, let param4, let param5, let param6, let param7, let param8): + _swift_js_return_tag(Int32(4)) + _swift_js_return_bool(param0 ? 1 : 0) + _swift_js_return_bool(param1 ? 1 : 0) + _swift_js_return_int(Int32(param2)) + _swift_js_return_int(Int32(param3)) + _swift_js_return_f64(param4) + _swift_js_return_f64(param5) + var __bjs_param6 = param6 + __bjs_param6.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + var __bjs_param7 = param7 + __bjs_param7.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + var __bjs_param8 = param8 + __bjs_param8.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + case .info: + _swift_js_return_tag(Int32(5)) + } + } +} + +private extension Utilities.Result { + static func bridgeJSLiftParameter(_ caseId: Int32, _ paramsId: Int32, _ paramsLen: Int32) -> Utilities.Result { + let params: [UInt8] = .init(unsafeUninitializedCapacity: Int(paramsLen)) { buf, initializedCount in + _swift_js_init_memory(paramsId, buf.baseAddress.unsafelyUnwrapped) + initializedCount = Int(paramsLen) + } + return params.withUnsafeBytes { raw in + var reader = _BJSBinaryReader(raw: raw) + switch caseId { + case 0: + reader.readParamCount(expected: 1) + reader.expectTag(.string) + let param0 = reader.readString() + return .success(param0) + case 1: + reader.readParamCount(expected: 2) + reader.expectTag(.string) + let param0 = reader.readString() + reader.expectTag(.int32) + let param1 = Int(reader.readInt32()) + return .failure(param0, param1) + case 2: + reader.readParamCount(expected: 3) + reader.expectTag(.bool) + let param0 = Int32(reader.readUInt8()) != 0 + reader.expectTag(.int32) + let param1 = Int(reader.readInt32()) + reader.expectTag(.string) + let param2 = reader.readString() + return .status(param0, param1, param2) + default: + fatalError("Unknown Utilities.Result case ID: \(caseId)") + } + } + } + + func bridgeJSLowerReturn() { + switch self { + case .success(let param0): + _swift_js_return_tag(Int32(0)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + case .failure(let param0, let param1): + _swift_js_return_tag(Int32(1)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + _swift_js_return_int(Int32(param1)) + case .status(let param0, let param1, let param2): + _swift_js_return_tag(Int32(2)) + _swift_js_return_bool(param0 ? 1 : 0) + _swift_js_return_int(Int32(param1)) + var __bjs_param2 = param2 + __bjs_param2.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + } + } +} + +private extension NetworkingResult { + static func bridgeJSLiftParameter(_ caseId: Int32, _ paramsId: Int32, _ paramsLen: Int32) -> NetworkingResult { + let params: [UInt8] = .init(unsafeUninitializedCapacity: Int(paramsLen)) { buf, initializedCount in + _swift_js_init_memory(paramsId, buf.baseAddress.unsafelyUnwrapped) + initializedCount = Int(paramsLen) + } + return params.withUnsafeBytes { raw in + var reader = _BJSBinaryReader(raw: raw) + switch caseId { + case 0: + reader.readParamCount(expected: 1) + reader.expectTag(.string) + let param0 = reader.readString() + return .success(param0) + case 1: + reader.readParamCount(expected: 2) + reader.expectTag(.string) + let param0 = reader.readString() + reader.expectTag(.int32) + let param1 = Int(reader.readInt32()) + return .failure(param0, param1) + default: + fatalError("Unknown NetworkingResult case ID: \(caseId)") + } + } + } + + func bridgeJSLowerReturn() { + switch self { + case .success(let param0): + _swift_js_return_tag(Int32(0)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + case .failure(let param0, let param1): + _swift_js_return_tag(Int32(1)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + _swift_js_return_int(Int32(param1)) + } + } +} + +@_expose(wasm, "bjs_handle") +@_cdecl("bjs_handle") +public func _bjs_handle(resultCaseId: Int32, resultParamsId: Int32, resultParamsLen: Int32) -> Void { + #if arch(wasm32) + handle(result: APIResult.bridgeJSLiftParameter(resultCaseId, resultParamsId, resultParamsLen)) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_getResult") +@_cdecl("bjs_getResult") +public func _bjs_getResult() -> Void { + #if arch(wasm32) + let ret = getResult() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_handleComplex") +@_cdecl("bjs_handleComplex") +public func _bjs_handleComplex(resultCaseId: Int32, resultParamsId: Int32, resultParamsLen: Int32) -> Void { + #if arch(wasm32) + handleComplex(result: ComplexResult.bridgeJSLiftParameter(resultCaseId, resultParamsId, resultParamsLen)) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_getComplexResult") +@_cdecl("bjs_getComplexResult") +public func _bjs_getComplexResult() -> Void { + #if arch(wasm32) + let ret = getComplexResult() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.swift index bb0fbe43..23120ea7 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumNamespace.swift @@ -6,9 +6,6 @@ @_spi(BridgeJS) import JavaScriptKit -extension Utils: _BridgedSwiftEnumNoPayload { -} - extension Networking.API.Method { @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { return bridgeJSRawValue diff --git a/Sources/JavaScriptKit/BridgeJSInstrincics.swift b/Sources/JavaScriptKit/BridgeJSInstrincics.swift index 56b87fa5..3107252d 100644 --- a/Sources/JavaScriptKit/BridgeJSInstrincics.swift +++ b/Sources/JavaScriptKit/BridgeJSInstrincics.swift @@ -338,3 +338,164 @@ where Self: RawRepresentable, RawValue: _BridgedSwiftTypeLoweredIntoSingleWasmCo rawValue.bridgeJSLowerReturn() } } + +// MARK: Enum binary helpers + +@_spi(BridgeJS) public enum _BJSParamType: UInt8 { + case string = 1 + case int32 = 2 + case bool = 3 + case float32 = 4 + case float64 = 5 +} + +@_spi(BridgeJS) public struct _BJSBinaryReader { + public let raw: UnsafeRawBufferPointer + public var offset: Int = 0 + + public init(raw: UnsafeRawBufferPointer) { + self.raw = raw + } + + @inline(__always) + public mutating func readUInt8() -> UInt8 { + let b = raw[offset] + offset += 1 + return b + } + + @inline(__always) + public mutating func readUInt32() -> UInt32 { + var v = UInt32(0) + withUnsafeMutableBytes(of: &v) { dst in + dst.copyBytes(from: UnsafeRawBufferPointer(rebasing: raw[offset..<(offset + 4)])) + } + offset += 4 + return UInt32(littleEndian: v) + } + + @inline(__always) + public mutating func readInt32() -> Int32 { + var v = Int32(0) + withUnsafeMutableBytes(of: &v) { dst in + dst.copyBytes(from: UnsafeRawBufferPointer(rebasing: raw[offset..<(offset + 4)])) + } + offset += 4 + return Int32(littleEndian: v) + } + + @inline(__always) + public mutating func readFloat32() -> Float32 { + var bits = UInt32(0) + withUnsafeMutableBytes(of: &bits) { dst in + dst.copyBytes(from: UnsafeRawBufferPointer(rebasing: raw[offset..<(offset + 4)])) + } + offset += 4 + return Float32(bitPattern: UInt32(littleEndian: bits)) + } + + @inline(__always) + public mutating func readFloat64() -> Float64 { + var bits = UInt64(0) + withUnsafeMutableBytes(of: &bits) { dst in + dst.copyBytes(from: UnsafeRawBufferPointer(rebasing: raw[offset..<(offset + 8)])) + } + offset += 8 + return Float64(bitPattern: UInt64(littleEndian: bits)) + } + + @inline(__always) + public mutating func readString() -> String { + let len = Int(readUInt32()) + let s = String( + decoding: UnsafeBufferPointer( + start: raw.baseAddress!.advanced(by: offset).assumingMemoryBound(to: UInt8.self), + count: len + ), + as: UTF8.self + ) + offset += len + return s + } + + @inline(__always) + public mutating func expectTag(_ expected: _BJSParamType) { + let rawTag = readUInt8() + guard let got = _BJSParamType(rawValue: rawTag), got == expected else { + preconditionFailure( + "BridgeJS: mismatched enum param tag. Expected \(expected) got \(String(describing: _BJSParamType(rawValue: rawTag)))" + ) + } + } + + @inline(__always) + public mutating func readParamCount(expected: Int) { + let count = Int(readUInt32()) + precondition(count == expected, "BridgeJS: mismatched enum param count. Expected \(expected) got \(count)") + } +} + +// MARK: Wasm externs used by generated enum glue + +#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_return_tag") +@_spi(BridgeJS) public func _swift_js_return_tag(_ tag: Int32) +#else +@_spi(BridgeJS) public func _swift_js_return_tag(_ tag: Int32) { + _onlyAvailableOnWasm() +} +#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_return_int") +@_spi(BridgeJS) public func _swift_js_return_int(_ value: Int32) +#else +@_spi(BridgeJS) public func _swift_js_return_int(_ value: Int32) { + _onlyAvailableOnWasm() +} +#endif + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_return_f32") +@_spi(BridgeJS) public func _swift_js_return_f32(_ value: Float32) +#else +@_spi(BridgeJS) public func _swift_js_return_f32(_ value: Float32) { + _onlyAvailableOnWasm() +} +#endif + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_return_f64") +@_spi(BridgeJS) public func _swift_js_return_f64(_ value: Float64) +#else +@_spi(BridgeJS) public func _swift_js_return_f64(_ value: Float64) { + _onlyAvailableOnWasm() +} +#endif + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_return_bool") +@_spi(BridgeJS) public func _swift_js_return_bool(_ value: Int32) +#else +@_spi(BridgeJS) public func _swift_js_return_bool(_ value: Int32) { + _onlyAvailableOnWasm() +} +#endif diff --git a/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Exporting-Swift/Exporting-Swift-Enum.md b/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Exporting-Swift/Exporting-Swift-Enum.md index e4bc1d7f..9c0f9971 100644 --- a/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Exporting-Swift/Exporting-Swift-Enum.md +++ b/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Exporting-Swift/Exporting-Swift-Enum.md @@ -405,4 +405,138 @@ enum Helper { #### Associated Value Enums -Associated value enums are not currently supported, but are planned for future releases. +Associated value enums are supported and allow you to pass data along with each enum case. BridgeJS generates TypeScript discriminated union types. Associated values are encoded into a binary format for efficient transfer between JavaScript and WebAssembly + +**Swift Definition:** + +```swift +@JS +enum APIResult { + case success(String) + case failure(Int) + case flag(Bool) + case rate(Float) + case precise(Double) + case info +} + +@JS +enum ComplexResult { + case success(String) + case error(String, Int) + case status(Bool, Int, String) + case coordinates(Double, Double, Double) + case comprehensive(Bool, Bool, Int, Int, Double, Double, String, String, String) + case info +} + +@JS func handle(result: APIResult) +@JS func getResult() -> APIResult +``` + +**Generated TypeScript Declaration:** + +```typescript +export const APIResult: { + readonly Tag: { + readonly Success: 0; + readonly Failure: 1; + readonly Flag: 2; + readonly Rate: 3; + readonly Precise: 4; + readonly Info: 5; + }; +}; + +export type APIResult = + { tag: typeof APIResult.Tag.Success; param0: string } | + { tag: typeof APIResult.Tag.Failure; param0: number } | + { tag: typeof APIResult.Tag.Flag; param0: boolean } | + { tag: typeof APIResult.Tag.Rate; param0: number } | + { tag: typeof APIResult.Tag.Precise; param0: number } | + { tag: typeof APIResult.Tag.Info } + +export const ComplexResult: { + readonly Tag: { + readonly Success: 0; + readonly Error: 1; + readonly Status: 2; + readonly Coordinates: 3; + readonly Comprehensive: 4; + readonly Info: 5; + }; +}; + +export type ComplexResult = + { tag: typeof ComplexResult.Tag.Success; param0: string } | + { tag: typeof ComplexResult.Tag.Error; param0: string; param1: number } | + { tag: typeof ComplexResult.Tag.Status; param0: boolean; param1: number; param2: string } | + { tag: typeof ComplexResult.Tag.Coordinates; param0: number; param1: number; param2: number } | + { tag: typeof ComplexResult.Tag.Comprehensive; param0: boolean; param1: boolean; param2: number; param3: number; param4: number; param5: number; param6: string; param7: string; param8: string } | + { tag: typeof ComplexResult.Tag.Info } +``` + +**Usage in TypeScript:** + +```typescript +const successResult: APIResult = { + tag: exports.APIResult.Tag.Success, + param0: "Operation completed successfully" +}; + +const errorResult: ComplexResult = { + tag: exports.ComplexResult.Tag.Error, + param0: "Network timeout", + param1: 503 +}; + +const statusResult: ComplexResult = { + tag: exports.ComplexResult.Tag.Status, + param0: true, + param1: 200, + param2: "OK" +}; + +exports.handle(successResult); +exports.handle(errorResult); + +const result: APIResult = exports.getResult(); + +// Pattern matching with discriminated unions +function processResult(result: APIResult) { + switch (result.tag) { + case exports.APIResult.Tag.Success: + console.log("Success:", result.param0); // TypeScript knows param0 is string + break; + case exports.APIResult.Tag.Failure: + console.log("Failure code:", result.param0); // TypeScript knows param0 is number + break; + case exports.APIResult.Tag.Flag: + console.log("Flag value:", result.param0); // TypeScript knows param0 is boolean + break; + case exports.APIResult.Tag.Info: + console.log("Info case has no associated data"); + break; + // TypeScript will warn about missing cases + } +} +``` + +**Supported Features:** + +| Swift Feature | Status | +|:--------------|:-------| +| Associated values: `String` | ✅ | +| Associated values: `Int` | ✅ | +| Associated values: `Bool` | ✅ | +| Associated values: `Float` | ✅ | +| Associated values: `Double` | ✅ | +| Associated values: Custom classes/structs | ❌ | +| Associated values: Other enums | ❌ | +| Associated values: Arrays/Collections | ❌ | +| Associated values: Optionals | ❌ | +| Use as exported function parameters | ✅ | +| Use as exported function return values | ✅ | +| Use as imported function parameters | ❌ | +| Use as imported function return values | ❌ | +| Namespace support | ✅ | diff --git a/Tests/BridgeJSRuntimeTests/ExportAPITests.swift b/Tests/BridgeJSRuntimeTests/ExportAPITests.swift index ff42f3c7..995a856f 100644 --- a/Tests/BridgeJSRuntimeTests/ExportAPITests.swift +++ b/Tests/BridgeJSRuntimeTests/ExportAPITests.swift @@ -302,6 +302,143 @@ enum Internal { return method } +@JS enum APIResult { + case success(String) + case failure(Int) + case flag(Bool) + case rate(Float) + case precise(Double) + case info +} + +@JS func echoAPIResult(result: APIResult) -> APIResult { + return result +} + +@JS func makeAPIResultSuccess(_ value: String) -> APIResult { + return .success(value) +} + +@JS func makeAPIResultFailure(_ value: Int) -> APIResult { + return .failure(value) +} + +@JS func makeAPIResultInfo() -> APIResult { + return .info +} + +@JS func makeAPIResultFlag(_ value: Bool) -> APIResult { + return .flag(value) +} + +@JS func makeAPIResultRate(_ value: Float) -> APIResult { + return .rate(value) +} + +@JS func makeAPIResultPrecise(_ value: Double) -> APIResult { + return .precise(value) +} + +@JS +enum ComplexResult { + case success(String) + case error(String, Int) + case location(Double, Double, String) + case status(Bool, Int, String) + case coordinates(Double, Double, Double) + case comprehensive(Bool, Bool, Int, Int, Double, Double, String, String, String) + case info +} + +@JS func echoComplexResult(result: ComplexResult) -> ComplexResult { + return result +} + +@JS func makeComplexResultSuccess(_ value: String) -> ComplexResult { + return .success(value) +} + +@JS func makeComplexResultError(_ message: String, _ code: Int) -> ComplexResult { + return .error(message, code) +} + +@JS func makeComplexResultLocation(_ lat: Double, _ lng: Double, _ name: String) -> ComplexResult { + return .location(lat, lng, name) +} + +@JS func makeComplexResultStatus(_ active: Bool, _ code: Int, _ message: String) -> ComplexResult { + return .status(active, code, message) +} + +@JS func makeComplexResultCoordinates(_ x: Double, _ y: Double, _ z: Double) -> ComplexResult { + return .coordinates(x, y, z) +} + +@JS func makeComplexResultComprehensive( + _ flag1: Bool, + _ flag2: Bool, + _ count1: Int, + _ count2: Int, + _ value1: Double, + _ value2: Double, + _ text1: String, + _ text2: String, + _ text3: String +) -> ComplexResult { + return .comprehensive(flag1, flag2, count1, count2, value1, value2, text1, text2, text3) +} + +@JS func makeComplexResultInfo() -> ComplexResult { + return .info +} + +@JS func roundtripComplexResult(_ result: ComplexResult) -> ComplexResult { + return result +} + +@JS enum Utilities { + @JS enum Result { + case success(String) + case failure(String, Int) + case status(Bool, Int, String) + } +} + +@JS enum API { + @JS enum NetworkingResult { + case success(String) + case failure(String, Int) + } +} + +@JS func makeUtilitiesResultSuccess(_ message: String) -> Utilities.Result { + return .success(message) +} + +@JS func makeUtilitiesResultFailure(_ error: String, _ code: Int) -> Utilities.Result { + return .failure(error, code) +} + +@JS func makeUtilitiesResultStatus(_ active: Bool, _ code: Int, _ message: String) -> Utilities.Result { + return .status(active, code, message) +} + +@JS func makeAPINetworkingResultSuccess(_ message: String) -> API.NetworkingResult { + return .success(message) +} + +@JS func makeAPINetworkingResultFailure(_ error: String, _ code: Int) -> API.NetworkingResult { + return .failure(error, code) +} + +@JS func roundtripUtilitiesResult(_ result: Utilities.Result) -> Utilities.Result { + return result +} + +@JS func roundtripAPINetworkingResult(_ result: API.NetworkingResult) -> API.NetworkingResult { + return result +} + // MARK: - Property Tests // Simple class for SwiftHeapObject property testing diff --git a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ExportSwift.swift b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ExportSwift.swift index 2c70c647..6b22899c 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ExportSwift.swift +++ b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ExportSwift.swift @@ -140,9 +140,6 @@ extension TSDirection { extension TSTheme: _BridgedSwiftEnumNoPayload { } -extension Utils: _BridgedSwiftEnumNoPayload { -} - extension Networking.API.Method { @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { return bridgeJSRawValue @@ -227,6 +224,322 @@ extension Internal.SupportedMethod { } } +private extension APIResult { + static func bridgeJSLiftParameter(_ caseId: Int32, _ paramsId: Int32, _ paramsLen: Int32) -> APIResult { + let params: [UInt8] = .init(unsafeUninitializedCapacity: Int(paramsLen)) { buf, initializedCount in + _swift_js_init_memory(paramsId, buf.baseAddress.unsafelyUnwrapped) + initializedCount = Int(paramsLen) + } + return params.withUnsafeBytes { raw in + var reader = _BJSBinaryReader(raw: raw) + switch caseId { + case 0: + reader.readParamCount(expected: 1) + reader.expectTag(.string) + let param0 = reader.readString() + return .success(param0) + case 1: + reader.readParamCount(expected: 1) + reader.expectTag(.int32) + let param0 = Int(reader.readInt32()) + return .failure(param0) + case 2: + reader.readParamCount(expected: 1) + reader.expectTag(.bool) + let param0 = Int32(reader.readUInt8()) != 0 + return .flag(param0) + case 3: + reader.readParamCount(expected: 1) + reader.expectTag(.float32) + let param0 = reader.readFloat32() + return .rate(param0) + case 4: + reader.readParamCount(expected: 1) + reader.expectTag(.float64) + let param0 = reader.readFloat64() + return .precise(param0) + case 5: + return .info + default: + fatalError("Unknown APIResult case ID: \(caseId)") + } + } + } + + func bridgeJSLowerReturn() { + switch self { + case .success(let param0): + _swift_js_return_tag(Int32(0)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + case .failure(let param0): + _swift_js_return_tag(Int32(1)) + _swift_js_return_int(Int32(param0)) + case .flag(let param0): + _swift_js_return_tag(Int32(2)) + _swift_js_return_bool(param0 ? 1 : 0) + case .rate(let param0): + _swift_js_return_tag(Int32(3)) + _swift_js_return_f32(param0) + case .precise(let param0): + _swift_js_return_tag(Int32(4)) + _swift_js_return_f64(param0) + case .info: + _swift_js_return_tag(Int32(5)) + } + } +} + +private extension ComplexResult { + static func bridgeJSLiftParameter(_ caseId: Int32, _ paramsId: Int32, _ paramsLen: Int32) -> ComplexResult { + let params: [UInt8] = .init(unsafeUninitializedCapacity: Int(paramsLen)) { buf, initializedCount in + _swift_js_init_memory(paramsId, buf.baseAddress.unsafelyUnwrapped) + initializedCount = Int(paramsLen) + } + return params.withUnsafeBytes { raw in + var reader = _BJSBinaryReader(raw: raw) + switch caseId { + case 0: + reader.readParamCount(expected: 1) + reader.expectTag(.string) + let param0 = reader.readString() + return .success(param0) + case 1: + reader.readParamCount(expected: 2) + reader.expectTag(.string) + let param0 = reader.readString() + reader.expectTag(.int32) + let param1 = Int(reader.readInt32()) + return .error(param0, param1) + case 2: + reader.readParamCount(expected: 3) + reader.expectTag(.float64) + let param0 = reader.readFloat64() + reader.expectTag(.float64) + let param1 = reader.readFloat64() + reader.expectTag(.string) + let param2 = reader.readString() + return .location(param0, param1, param2) + case 3: + reader.readParamCount(expected: 3) + reader.expectTag(.bool) + let param0 = Int32(reader.readUInt8()) != 0 + reader.expectTag(.int32) + let param1 = Int(reader.readInt32()) + reader.expectTag(.string) + let param2 = reader.readString() + return .status(param0, param1, param2) + case 4: + reader.readParamCount(expected: 3) + reader.expectTag(.float64) + let param0 = reader.readFloat64() + reader.expectTag(.float64) + let param1 = reader.readFloat64() + reader.expectTag(.float64) + let param2 = reader.readFloat64() + return .coordinates(param0, param1, param2) + case 5: + reader.readParamCount(expected: 9) + reader.expectTag(.bool) + let param0 = Int32(reader.readUInt8()) != 0 + reader.expectTag(.bool) + let param1 = Int32(reader.readUInt8()) != 0 + reader.expectTag(.int32) + let param2 = Int(reader.readInt32()) + reader.expectTag(.int32) + let param3 = Int(reader.readInt32()) + reader.expectTag(.float64) + let param4 = reader.readFloat64() + reader.expectTag(.float64) + let param5 = reader.readFloat64() + reader.expectTag(.string) + let param6 = reader.readString() + reader.expectTag(.string) + let param7 = reader.readString() + reader.expectTag(.string) + let param8 = reader.readString() + return .comprehensive(param0, param1, param2, param3, param4, param5, param6, param7, param8) + case 6: + return .info + default: + fatalError("Unknown ComplexResult case ID: \(caseId)") + } + } + } + + func bridgeJSLowerReturn() { + switch self { + case .success(let param0): + _swift_js_return_tag(Int32(0)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + case .error(let param0, let param1): + _swift_js_return_tag(Int32(1)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + _swift_js_return_int(Int32(param1)) + case .location(let param0, let param1, let param2): + _swift_js_return_tag(Int32(2)) + _swift_js_return_f64(param0) + _swift_js_return_f64(param1) + var __bjs_param2 = param2 + __bjs_param2.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + case .status(let param0, let param1, let param2): + _swift_js_return_tag(Int32(3)) + _swift_js_return_bool(param0 ? 1 : 0) + _swift_js_return_int(Int32(param1)) + var __bjs_param2 = param2 + __bjs_param2.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + case .coordinates(let param0, let param1, let param2): + _swift_js_return_tag(Int32(4)) + _swift_js_return_f64(param0) + _swift_js_return_f64(param1) + _swift_js_return_f64(param2) + case .comprehensive(let param0, let param1, let param2, let param3, let param4, let param5, let param6, let param7, let param8): + _swift_js_return_tag(Int32(5)) + _swift_js_return_bool(param0 ? 1 : 0) + _swift_js_return_bool(param1 ? 1 : 0) + _swift_js_return_int(Int32(param2)) + _swift_js_return_int(Int32(param3)) + _swift_js_return_f64(param4) + _swift_js_return_f64(param5) + var __bjs_param6 = param6 + __bjs_param6.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + var __bjs_param7 = param7 + __bjs_param7.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + var __bjs_param8 = param8 + __bjs_param8.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + case .info: + _swift_js_return_tag(Int32(6)) + } + } +} + +private extension Utilities.Result { + static func bridgeJSLiftParameter(_ caseId: Int32, _ paramsId: Int32, _ paramsLen: Int32) -> Utilities.Result { + let params: [UInt8] = .init(unsafeUninitializedCapacity: Int(paramsLen)) { buf, initializedCount in + _swift_js_init_memory(paramsId, buf.baseAddress.unsafelyUnwrapped) + initializedCount = Int(paramsLen) + } + return params.withUnsafeBytes { raw in + var reader = _BJSBinaryReader(raw: raw) + switch caseId { + case 0: + reader.readParamCount(expected: 1) + reader.expectTag(.string) + let param0 = reader.readString() + return .success(param0) + case 1: + reader.readParamCount(expected: 2) + reader.expectTag(.string) + let param0 = reader.readString() + reader.expectTag(.int32) + let param1 = Int(reader.readInt32()) + return .failure(param0, param1) + case 2: + reader.readParamCount(expected: 3) + reader.expectTag(.bool) + let param0 = Int32(reader.readUInt8()) != 0 + reader.expectTag(.int32) + let param1 = Int(reader.readInt32()) + reader.expectTag(.string) + let param2 = reader.readString() + return .status(param0, param1, param2) + default: + fatalError("Unknown Utilities.Result case ID: \(caseId)") + } + } + } + + func bridgeJSLowerReturn() { + switch self { + case .success(let param0): + _swift_js_return_tag(Int32(0)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + case .failure(let param0, let param1): + _swift_js_return_tag(Int32(1)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + _swift_js_return_int(Int32(param1)) + case .status(let param0, let param1, let param2): + _swift_js_return_tag(Int32(2)) + _swift_js_return_bool(param0 ? 1 : 0) + _swift_js_return_int(Int32(param1)) + var __bjs_param2 = param2 + __bjs_param2.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + } + } +} + +private extension API.NetworkingResult { + static func bridgeJSLiftParameter(_ caseId: Int32, _ paramsId: Int32, _ paramsLen: Int32) -> API.NetworkingResult { + let params: [UInt8] = .init(unsafeUninitializedCapacity: Int(paramsLen)) { buf, initializedCount in + _swift_js_init_memory(paramsId, buf.baseAddress.unsafelyUnwrapped) + initializedCount = Int(paramsLen) + } + return params.withUnsafeBytes { raw in + var reader = _BJSBinaryReader(raw: raw) + switch caseId { + case 0: + reader.readParamCount(expected: 1) + reader.expectTag(.string) + let param0 = reader.readString() + return .success(param0) + case 1: + reader.readParamCount(expected: 2) + reader.expectTag(.string) + let param0 = reader.readString() + reader.expectTag(.int32) + let param1 = Int(reader.readInt32()) + return .failure(param0, param1) + default: + fatalError("Unknown API.NetworkingResult case ID: \(caseId)") + } + } + } + + func bridgeJSLowerReturn() { + switch self { + case .success(let param0): + _swift_js_return_tag(Int32(0)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + case .failure(let param0, let param1): + _swift_js_return_tag(Int32(1)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + } + _swift_js_return_int(Int32(param1)) + } + } +} + @_expose(wasm, "bjs_roundTripVoid") @_cdecl("bjs_roundTripVoid") public func _bjs_roundTripVoid() -> Void { @@ -869,6 +1182,259 @@ public func _bjs_echoInternalSupportedMethod(method: Int32) -> Int32 { #endif } +@_expose(wasm, "bjs_echoAPIResult") +@_cdecl("bjs_echoAPIResult") +public func _bjs_echoAPIResult(resultCaseId: Int32, resultParamsId: Int32, resultParamsLen: Int32) -> Void { + #if arch(wasm32) + let ret = echoAPIResult(result: APIResult.bridgeJSLiftParameter(resultCaseId, resultParamsId, resultParamsLen)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeAPIResultSuccess") +@_cdecl("bjs_makeAPIResultSuccess") +public func _bjs_makeAPIResultSuccess(valueBytes: Int32, valueLength: Int32) -> Void { + #if arch(wasm32) + let ret = makeAPIResultSuccess(_: String.bridgeJSLiftParameter(valueBytes, valueLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeAPIResultFailure") +@_cdecl("bjs_makeAPIResultFailure") +public func _bjs_makeAPIResultFailure(value: Int32) -> Void { + #if arch(wasm32) + let ret = makeAPIResultFailure(_: Int.bridgeJSLiftParameter(value)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeAPIResultInfo") +@_cdecl("bjs_makeAPIResultInfo") +public func _bjs_makeAPIResultInfo() -> Void { + #if arch(wasm32) + let ret = makeAPIResultInfo() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeAPIResultFlag") +@_cdecl("bjs_makeAPIResultFlag") +public func _bjs_makeAPIResultFlag(value: Int32) -> Void { + #if arch(wasm32) + let ret = makeAPIResultFlag(_: Bool.bridgeJSLiftParameter(value)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeAPIResultRate") +@_cdecl("bjs_makeAPIResultRate") +public func _bjs_makeAPIResultRate(value: Float32) -> Void { + #if arch(wasm32) + let ret = makeAPIResultRate(_: Float.bridgeJSLiftParameter(value)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeAPIResultPrecise") +@_cdecl("bjs_makeAPIResultPrecise") +public func _bjs_makeAPIResultPrecise(value: Float64) -> Void { + #if arch(wasm32) + let ret = makeAPIResultPrecise(_: Double.bridgeJSLiftParameter(value)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_echoComplexResult") +@_cdecl("bjs_echoComplexResult") +public func _bjs_echoComplexResult(resultCaseId: Int32, resultParamsId: Int32, resultParamsLen: Int32) -> Void { + #if arch(wasm32) + let ret = echoComplexResult(result: ComplexResult.bridgeJSLiftParameter(resultCaseId, resultParamsId, resultParamsLen)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeComplexResultSuccess") +@_cdecl("bjs_makeComplexResultSuccess") +public func _bjs_makeComplexResultSuccess(valueBytes: Int32, valueLength: Int32) -> Void { + #if arch(wasm32) + let ret = makeComplexResultSuccess(_: String.bridgeJSLiftParameter(valueBytes, valueLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeComplexResultError") +@_cdecl("bjs_makeComplexResultError") +public func _bjs_makeComplexResultError(messageBytes: Int32, messageLength: Int32, code: Int32) -> Void { + #if arch(wasm32) + let ret = makeComplexResultError(_: String.bridgeJSLiftParameter(messageBytes, messageLength), _: Int.bridgeJSLiftParameter(code)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeComplexResultLocation") +@_cdecl("bjs_makeComplexResultLocation") +public func _bjs_makeComplexResultLocation(lat: Float64, lng: Float64, nameBytes: Int32, nameLength: Int32) -> Void { + #if arch(wasm32) + let ret = makeComplexResultLocation(_: Double.bridgeJSLiftParameter(lat), _: Double.bridgeJSLiftParameter(lng), _: String.bridgeJSLiftParameter(nameBytes, nameLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeComplexResultStatus") +@_cdecl("bjs_makeComplexResultStatus") +public func _bjs_makeComplexResultStatus(active: Int32, code: Int32, messageBytes: Int32, messageLength: Int32) -> Void { + #if arch(wasm32) + let ret = makeComplexResultStatus(_: Bool.bridgeJSLiftParameter(active), _: Int.bridgeJSLiftParameter(code), _: String.bridgeJSLiftParameter(messageBytes, messageLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeComplexResultCoordinates") +@_cdecl("bjs_makeComplexResultCoordinates") +public func _bjs_makeComplexResultCoordinates(x: Float64, y: Float64, z: Float64) -> Void { + #if arch(wasm32) + let ret = makeComplexResultCoordinates(_: Double.bridgeJSLiftParameter(x), _: Double.bridgeJSLiftParameter(y), _: Double.bridgeJSLiftParameter(z)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeComplexResultComprehensive") +@_cdecl("bjs_makeComplexResultComprehensive") +public func _bjs_makeComplexResultComprehensive(flag1: Int32, flag2: Int32, count1: Int32, count2: Int32, value1: Float64, value2: Float64, text1Bytes: Int32, text1Length: Int32, text2Bytes: Int32, text2Length: Int32, text3Bytes: Int32, text3Length: Int32) -> Void { + #if arch(wasm32) + let ret = makeComplexResultComprehensive(_: Bool.bridgeJSLiftParameter(flag1), _: Bool.bridgeJSLiftParameter(flag2), _: Int.bridgeJSLiftParameter(count1), _: Int.bridgeJSLiftParameter(count2), _: Double.bridgeJSLiftParameter(value1), _: Double.bridgeJSLiftParameter(value2), _: String.bridgeJSLiftParameter(text1Bytes, text1Length), _: String.bridgeJSLiftParameter(text2Bytes, text2Length), _: String.bridgeJSLiftParameter(text3Bytes, text3Length)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeComplexResultInfo") +@_cdecl("bjs_makeComplexResultInfo") +public func _bjs_makeComplexResultInfo() -> Void { + #if arch(wasm32) + let ret = makeComplexResultInfo() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_roundtripComplexResult") +@_cdecl("bjs_roundtripComplexResult") +public func _bjs_roundtripComplexResult(resultCaseId: Int32, resultParamsId: Int32, resultParamsLen: Int32) -> Void { + #if arch(wasm32) + let ret = roundtripComplexResult(_: ComplexResult.bridgeJSLiftParameter(resultCaseId, resultParamsId, resultParamsLen)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeUtilitiesResultSuccess") +@_cdecl("bjs_makeUtilitiesResultSuccess") +public func _bjs_makeUtilitiesResultSuccess(messageBytes: Int32, messageLength: Int32) -> Void { + #if arch(wasm32) + let ret = makeUtilitiesResultSuccess(_: String.bridgeJSLiftParameter(messageBytes, messageLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeUtilitiesResultFailure") +@_cdecl("bjs_makeUtilitiesResultFailure") +public func _bjs_makeUtilitiesResultFailure(errorBytes: Int32, errorLength: Int32, code: Int32) -> Void { + #if arch(wasm32) + let ret = makeUtilitiesResultFailure(_: String.bridgeJSLiftParameter(errorBytes, errorLength), _: Int.bridgeJSLiftParameter(code)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeUtilitiesResultStatus") +@_cdecl("bjs_makeUtilitiesResultStatus") +public func _bjs_makeUtilitiesResultStatus(active: Int32, code: Int32, messageBytes: Int32, messageLength: Int32) -> Void { + #if arch(wasm32) + let ret = makeUtilitiesResultStatus(_: Bool.bridgeJSLiftParameter(active), _: Int.bridgeJSLiftParameter(code), _: String.bridgeJSLiftParameter(messageBytes, messageLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeAPINetworkingResultSuccess") +@_cdecl("bjs_makeAPINetworkingResultSuccess") +public func _bjs_makeAPINetworkingResultSuccess(messageBytes: Int32, messageLength: Int32) -> Void { + #if arch(wasm32) + let ret = makeAPINetworkingResultSuccess(_: String.bridgeJSLiftParameter(messageBytes, messageLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeAPINetworkingResultFailure") +@_cdecl("bjs_makeAPINetworkingResultFailure") +public func _bjs_makeAPINetworkingResultFailure(errorBytes: Int32, errorLength: Int32, code: Int32) -> Void { + #if arch(wasm32) + let ret = makeAPINetworkingResultFailure(_: String.bridgeJSLiftParameter(errorBytes, errorLength), _: Int.bridgeJSLiftParameter(code)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_roundtripUtilitiesResult") +@_cdecl("bjs_roundtripUtilitiesResult") +public func _bjs_roundtripUtilitiesResult(resultCaseId: Int32, resultParamsId: Int32, resultParamsLen: Int32) -> Void { + #if arch(wasm32) + let ret = roundtripUtilitiesResult(_: Utilities.Result.bridgeJSLiftParameter(resultCaseId, resultParamsId, resultParamsLen)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_roundtripAPINetworkingResult") +@_cdecl("bjs_roundtripAPINetworkingResult") +public func _bjs_roundtripAPINetworkingResult(resultCaseId: Int32, resultParamsId: Int32, resultParamsLen: Int32) -> Void { + #if arch(wasm32) + let ret = roundtripAPINetworkingResult(_: API.NetworkingResult.bridgeJSLiftParameter(resultCaseId, resultParamsId, resultParamsLen)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + @_expose(wasm, "bjs_createPropertyHolder") @_cdecl("bjs_createPropertyHolder") public func _bjs_createPropertyHolder(intValue: Int32, floatValue: Float32, doubleValue: Float64, boolValue: Int32, stringValueBytes: Int32, stringValueLength: Int32, jsObject: Int32) -> UnsafeMutableRawPointer { diff --git a/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.ExportSwift.json b/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.ExportSwift.json index 8e65a50d..c1638c67 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.ExportSwift.json +++ b/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.ExportSwift.json @@ -913,16 +913,707 @@ "Internal" ], "swiftCallName" : "Internal.SupportedMethod" + }, + { + "cases" : [ + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "success" + }, + { + "associatedValues" : [ + { + "type" : { + "int" : { + + } + } + } + ], + "name" : "failure" + }, + { + "associatedValues" : [ + { + "type" : { + "bool" : { + + } + } + } + ], + "name" : "flag" + }, + { + "associatedValues" : [ + { + "type" : { + "float" : { + + } + } + } + ], + "name" : "rate" + }, + { + "associatedValues" : [ + { + "type" : { + "double" : { + + } + } + } + ], + "name" : "precise" + }, + { + "associatedValues" : [ + + ], + "name" : "info" + } + ], + "emitStyle" : "const", + "name" : "APIResult", + "swiftCallName" : "APIResult" + }, + { + "cases" : [ + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "success" + }, + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + }, + { + "type" : { + "int" : { + + } + } + } + ], + "name" : "error" + }, + { + "associatedValues" : [ + { + "type" : { + "double" : { + + } + } + }, + { + "type" : { + "double" : { + + } + } + }, + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "location" + }, + { + "associatedValues" : [ + { + "type" : { + "bool" : { + + } + } + }, + { + "type" : { + "int" : { + + } + } + }, + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "status" + }, + { + "associatedValues" : [ + { + "type" : { + "double" : { + + } + } + }, + { + "type" : { + "double" : { + + } + } + }, + { + "type" : { + "double" : { + + } + } + } + ], + "name" : "coordinates" + }, + { + "associatedValues" : [ + { + "type" : { + "bool" : { + + } + } + }, + { + "type" : { + "bool" : { + + } + } + }, + { + "type" : { + "int" : { + + } + } + }, + { + "type" : { + "int" : { + + } + } + }, + { + "type" : { + "double" : { + + } + } + }, + { + "type" : { + "double" : { + + } + } + }, + { + "type" : { + "string" : { + + } + } + }, + { + "type" : { + "string" : { + + } + } + }, + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "comprehensive" + }, + { + "associatedValues" : [ + + ], + "name" : "info" + } + ], + "emitStyle" : "const", + "name" : "ComplexResult", + "swiftCallName" : "ComplexResult" + }, + { + "cases" : [ + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "success" + }, + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + }, + { + "type" : { + "int" : { + + } + } + } + ], + "name" : "failure" + }, + { + "associatedValues" : [ + { + "type" : { + "bool" : { + + } + } + }, + { + "type" : { + "int" : { + + } + } + }, + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "status" + } + ], + "emitStyle" : "const", + "name" : "Result", + "namespace" : [ + "Utilities" + ], + "swiftCallName" : "Utilities.Result" + }, + { + "cases" : [ + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "success" + }, + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + }, + { + "type" : { + "int" : { + + } + } + } + ], + "name" : "failure" + } + ], + "emitStyle" : "const", + "name" : "NetworkingResult", + "namespace" : [ + "API" + ], + "swiftCallName" : "API.NetworkingResult" } ], "functions" : [ { - "abiName" : "bjs_roundTripVoid", + "abiName" : "bjs_roundTripVoid", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "roundTripVoid", + "parameters" : [ + + ], + "returnType" : { + "void" : { + + } + } + }, + { + "abiName" : "bjs_roundTripInt", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "roundTripInt", + "parameters" : [ + { + "label" : "v", + "name" : "v", + "type" : { + "int" : { + + } + } + } + ], + "returnType" : { + "int" : { + + } + } + }, + { + "abiName" : "bjs_roundTripFloat", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "roundTripFloat", + "parameters" : [ + { + "label" : "v", + "name" : "v", + "type" : { + "float" : { + + } + } + } + ], + "returnType" : { + "float" : { + + } + } + }, + { + "abiName" : "bjs_roundTripDouble", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "roundTripDouble", + "parameters" : [ + { + "label" : "v", + "name" : "v", + "type" : { + "double" : { + + } + } + } + ], + "returnType" : { + "double" : { + + } + } + }, + { + "abiName" : "bjs_roundTripBool", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "roundTripBool", + "parameters" : [ + { + "label" : "v", + "name" : "v", + "type" : { + "bool" : { + + } + } + } + ], + "returnType" : { + "bool" : { + + } + } + }, + { + "abiName" : "bjs_roundTripString", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "roundTripString", + "parameters" : [ + { + "label" : "v", + "name" : "v", + "type" : { + "string" : { + + } + } + } + ], + "returnType" : { + "string" : { + + } + } + }, + { + "abiName" : "bjs_roundTripSwiftHeapObject", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "roundTripSwiftHeapObject", + "parameters" : [ + { + "label" : "v", + "name" : "v", + "type" : { + "swiftHeapObject" : { + "_0" : "Greeter" + } + } + } + ], + "returnType" : { + "swiftHeapObject" : { + "_0" : "Greeter" + } + } + }, + { + "abiName" : "bjs_roundTripJSObject", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "roundTripJSObject", + "parameters" : [ + { + "label" : "v", + "name" : "v", + "type" : { + "jsObject" : { + + } + } + } + ], + "returnType" : { + "jsObject" : { + + } + } + }, + { + "abiName" : "bjs_throwsSwiftError", + "effects" : { + "isAsync" : false, + "isThrows" : true + }, + "name" : "throwsSwiftError", + "parameters" : [ + { + "label" : "shouldThrow", + "name" : "shouldThrow", + "type" : { + "bool" : { + + } + } + } + ], + "returnType" : { + "void" : { + + } + } + }, + { + "abiName" : "bjs_throwsWithIntResult", + "effects" : { + "isAsync" : false, + "isThrows" : true + }, + "name" : "throwsWithIntResult", + "parameters" : [ + + ], + "returnType" : { + "int" : { + + } + } + }, + { + "abiName" : "bjs_throwsWithStringResult", + "effects" : { + "isAsync" : false, + "isThrows" : true + }, + "name" : "throwsWithStringResult", + "parameters" : [ + + ], + "returnType" : { + "string" : { + + } + } + }, + { + "abiName" : "bjs_throwsWithBoolResult", + "effects" : { + "isAsync" : false, + "isThrows" : true + }, + "name" : "throwsWithBoolResult", + "parameters" : [ + + ], + "returnType" : { + "bool" : { + + } + } + }, + { + "abiName" : "bjs_throwsWithFloatResult", + "effects" : { + "isAsync" : false, + "isThrows" : true + }, + "name" : "throwsWithFloatResult", + "parameters" : [ + + ], + "returnType" : { + "float" : { + + } + } + }, + { + "abiName" : "bjs_throwsWithDoubleResult", + "effects" : { + "isAsync" : false, + "isThrows" : true + }, + "name" : "throwsWithDoubleResult", + "parameters" : [ + + ], + "returnType" : { + "double" : { + + } + } + }, + { + "abiName" : "bjs_throwsWithSwiftHeapObjectResult", + "effects" : { + "isAsync" : false, + "isThrows" : true + }, + "name" : "throwsWithSwiftHeapObjectResult", + "parameters" : [ + + ], + "returnType" : { + "swiftHeapObject" : { + "_0" : "Greeter" + } + } + }, + { + "abiName" : "bjs_throwsWithJSObjectResult", "effects" : { "isAsync" : false, + "isThrows" : true + }, + "name" : "throwsWithJSObjectResult", + "parameters" : [ + + ], + "returnType" : { + "jsObject" : { + + } + } + }, + { + "abiName" : "bjs_asyncRoundTripVoid", + "effects" : { + "isAsync" : true, "isThrows" : false }, - "name" : "roundTripVoid", + "name" : "asyncRoundTripVoid", "parameters" : [ ], @@ -933,12 +1624,12 @@ } }, { - "abiName" : "bjs_roundTripInt", + "abiName" : "bjs_asyncRoundTripInt", "effects" : { - "isAsync" : false, + "isAsync" : true, "isThrows" : false }, - "name" : "roundTripInt", + "name" : "asyncRoundTripInt", "parameters" : [ { "label" : "v", @@ -957,12 +1648,12 @@ } }, { - "abiName" : "bjs_roundTripFloat", + "abiName" : "bjs_asyncRoundTripFloat", "effects" : { - "isAsync" : false, + "isAsync" : true, "isThrows" : false }, - "name" : "roundTripFloat", + "name" : "asyncRoundTripFloat", "parameters" : [ { "label" : "v", @@ -970,985 +1661,1372 @@ "type" : { "float" : { - } - } - } + } + } + } + ], + "returnType" : { + "float" : { + + } + } + }, + { + "abiName" : "bjs_asyncRoundTripDouble", + "effects" : { + "isAsync" : true, + "isThrows" : false + }, + "name" : "asyncRoundTripDouble", + "parameters" : [ + { + "label" : "v", + "name" : "v", + "type" : { + "double" : { + + } + } + } + ], + "returnType" : { + "double" : { + + } + } + }, + { + "abiName" : "bjs_asyncRoundTripBool", + "effects" : { + "isAsync" : true, + "isThrows" : false + }, + "name" : "asyncRoundTripBool", + "parameters" : [ + { + "label" : "v", + "name" : "v", + "type" : { + "bool" : { + + } + } + } + ], + "returnType" : { + "bool" : { + + } + } + }, + { + "abiName" : "bjs_asyncRoundTripString", + "effects" : { + "isAsync" : true, + "isThrows" : false + }, + "name" : "asyncRoundTripString", + "parameters" : [ + { + "label" : "v", + "name" : "v", + "type" : { + "string" : { + + } + } + } + ], + "returnType" : { + "string" : { + + } + } + }, + { + "abiName" : "bjs_asyncRoundTripSwiftHeapObject", + "effects" : { + "isAsync" : true, + "isThrows" : false + }, + "name" : "asyncRoundTripSwiftHeapObject", + "parameters" : [ + { + "label" : "v", + "name" : "v", + "type" : { + "swiftHeapObject" : { + "_0" : "Greeter" + } + } + } + ], + "returnType" : { + "swiftHeapObject" : { + "_0" : "Greeter" + } + } + }, + { + "abiName" : "bjs_asyncRoundTripJSObject", + "effects" : { + "isAsync" : true, + "isThrows" : false + }, + "name" : "asyncRoundTripJSObject", + "parameters" : [ + { + "label" : "v", + "name" : "v", + "type" : { + "jsObject" : { + + } + } + } + ], + "returnType" : { + "jsObject" : { + + } + } + }, + { + "abiName" : "bjs_takeGreeter", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "takeGreeter", + "parameters" : [ + { + "label" : "g", + "name" : "g", + "type" : { + "swiftHeapObject" : { + "_0" : "Greeter" + } + } + }, + { + "label" : "name", + "name" : "name", + "type" : { + "string" : { + + } + } + } + ], + "returnType" : { + "void" : { + + } + } + }, + { + "abiName" : "bjs_createCalculator", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "createCalculator", + "parameters" : [ + + ], + "returnType" : { + "swiftHeapObject" : { + "_0" : "Calculator" + } + } + }, + { + "abiName" : "bjs_useCalculator", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "useCalculator", + "parameters" : [ + { + "label" : "calc", + "name" : "calc", + "type" : { + "swiftHeapObject" : { + "_0" : "Calculator" + } + } + }, + { + "label" : "x", + "name" : "x", + "type" : { + "int" : { + + } + } + }, + { + "label" : "y", + "name" : "y", + "type" : { + "int" : { + + } + } + } + ], + "returnType" : { + "int" : { + + } + } + }, + { + "abiName" : "bjs_testGreeterToJSValue", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "testGreeterToJSValue", + "parameters" : [ + ], "returnType" : { - "float" : { + "jsObject" : { } } }, { - "abiName" : "bjs_roundTripDouble", + "abiName" : "bjs_testCalculatorToJSValue", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "roundTripDouble", + "name" : "testCalculatorToJSValue", "parameters" : [ - { - "label" : "v", - "name" : "v", - "type" : { - "double" : { - } - } - } ], "returnType" : { - "double" : { + "jsObject" : { } } }, { - "abiName" : "bjs_roundTripBool", + "abiName" : "bjs_testSwiftClassAsJSValue", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "roundTripBool", + "name" : "testSwiftClassAsJSValue", "parameters" : [ { - "label" : "v", - "name" : "v", + "label" : "greeter", + "name" : "greeter", "type" : { - "bool" : { - + "swiftHeapObject" : { + "_0" : "Greeter" } } } ], "returnType" : { - "bool" : { + "jsObject" : { } } }, { - "abiName" : "bjs_roundTripString", + "abiName" : "bjs_setDirection", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "roundTripString", + "name" : "setDirection", "parameters" : [ { - "label" : "v", - "name" : "v", + "label" : "_", + "name" : "direction", "type" : { - "string" : { - + "caseEnum" : { + "_0" : "Direction" } } } ], "returnType" : { - "string" : { - + "caseEnum" : { + "_0" : "Direction" } } }, { - "abiName" : "bjs_roundTripSwiftHeapObject", + "abiName" : "bjs_getDirection", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "roundTripSwiftHeapObject", + "name" : "getDirection", "parameters" : [ - { - "label" : "v", - "name" : "v", - "type" : { - "swiftHeapObject" : { - "_0" : "Greeter" - } - } - } + ], "returnType" : { - "swiftHeapObject" : { - "_0" : "Greeter" + "caseEnum" : { + "_0" : "Direction" } } }, { - "abiName" : "bjs_roundTripJSObject", + "abiName" : "bjs_processDirection", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "roundTripJSObject", + "name" : "processDirection", "parameters" : [ { - "label" : "v", - "name" : "v", + "label" : "_", + "name" : "input", "type" : { - "jsObject" : { - + "caseEnum" : { + "_0" : "Direction" } } } ], "returnType" : { - "jsObject" : { - + "caseEnum" : { + "_0" : "Status" } } }, { - "abiName" : "bjs_throwsSwiftError", + "abiName" : "bjs_setTheme", "effects" : { "isAsync" : false, - "isThrows" : true + "isThrows" : false }, - "name" : "throwsSwiftError", + "name" : "setTheme", "parameters" : [ { - "label" : "shouldThrow", - "name" : "shouldThrow", + "label" : "_", + "name" : "theme", "type" : { - "bool" : { - + "rawValueEnum" : { + "_0" : "Theme", + "_1" : "String" } } } ], "returnType" : { - "void" : { - + "rawValueEnum" : { + "_0" : "Theme", + "_1" : "String" } } }, { - "abiName" : "bjs_throwsWithIntResult", + "abiName" : "bjs_getTheme", "effects" : { "isAsync" : false, - "isThrows" : true + "isThrows" : false }, - "name" : "throwsWithIntResult", + "name" : "getTheme", "parameters" : [ ], "returnType" : { - "int" : { - + "rawValueEnum" : { + "_0" : "Theme", + "_1" : "String" } } }, { - "abiName" : "bjs_throwsWithStringResult", + "abiName" : "bjs_setHttpStatus", "effects" : { "isAsync" : false, - "isThrows" : true + "isThrows" : false }, - "name" : "throwsWithStringResult", + "name" : "setHttpStatus", "parameters" : [ - + { + "label" : "_", + "name" : "status", + "type" : { + "rawValueEnum" : { + "_0" : "HttpStatus", + "_1" : "Int" + } + } + } ], "returnType" : { - "string" : { - + "rawValueEnum" : { + "_0" : "HttpStatus", + "_1" : "Int" } } }, { - "abiName" : "bjs_throwsWithBoolResult", + "abiName" : "bjs_getHttpStatus", "effects" : { "isAsync" : false, - "isThrows" : true + "isThrows" : false }, - "name" : "throwsWithBoolResult", + "name" : "getHttpStatus", "parameters" : [ ], "returnType" : { - "bool" : { - + "rawValueEnum" : { + "_0" : "HttpStatus", + "_1" : "Int" } } }, { - "abiName" : "bjs_throwsWithFloatResult", + "abiName" : "bjs_processTheme", "effects" : { "isAsync" : false, - "isThrows" : true + "isThrows" : false }, - "name" : "throwsWithFloatResult", + "name" : "processTheme", "parameters" : [ - + { + "label" : "_", + "name" : "theme", + "type" : { + "rawValueEnum" : { + "_0" : "Theme", + "_1" : "String" + } + } + } ], "returnType" : { - "float" : { - + "rawValueEnum" : { + "_0" : "HttpStatus", + "_1" : "Int" } } }, { - "abiName" : "bjs_throwsWithDoubleResult", + "abiName" : "bjs_setTSDirection", "effects" : { "isAsync" : false, - "isThrows" : true + "isThrows" : false }, - "name" : "throwsWithDoubleResult", + "name" : "setTSDirection", "parameters" : [ - + { + "label" : "_", + "name" : "direction", + "type" : { + "caseEnum" : { + "_0" : "TSDirection" + } + } + } ], "returnType" : { - "double" : { - + "caseEnum" : { + "_0" : "TSDirection" } } }, { - "abiName" : "bjs_throwsWithSwiftHeapObjectResult", + "abiName" : "bjs_getTSDirection", "effects" : { "isAsync" : false, - "isThrows" : true + "isThrows" : false }, - "name" : "throwsWithSwiftHeapObjectResult", + "name" : "getTSDirection", "parameters" : [ ], "returnType" : { - "swiftHeapObject" : { - "_0" : "Greeter" + "caseEnum" : { + "_0" : "TSDirection" } } }, { - "abiName" : "bjs_throwsWithJSObjectResult", + "abiName" : "bjs_setTSTheme", "effects" : { "isAsync" : false, - "isThrows" : true + "isThrows" : false }, - "name" : "throwsWithJSObjectResult", + "name" : "setTSTheme", "parameters" : [ - + { + "label" : "_", + "name" : "theme", + "type" : { + "rawValueEnum" : { + "_0" : "TSTheme", + "_1" : "String" + } + } + } ], "returnType" : { - "jsObject" : { - + "rawValueEnum" : { + "_0" : "TSTheme", + "_1" : "String" } } }, { - "abiName" : "bjs_asyncRoundTripVoid", + "abiName" : "bjs_getTSTheme", "effects" : { - "isAsync" : true, + "isAsync" : false, "isThrows" : false }, - "name" : "asyncRoundTripVoid", + "name" : "getTSTheme", "parameters" : [ ], "returnType" : { - "void" : { - + "rawValueEnum" : { + "_0" : "TSTheme", + "_1" : "String" } } }, { - "abiName" : "bjs_asyncRoundTripInt", + "abiName" : "bjs_echoNetworkingAPIMethod", "effects" : { - "isAsync" : true, + "isAsync" : false, "isThrows" : false }, - "name" : "asyncRoundTripInt", + "name" : "echoNetworkingAPIMethod", "parameters" : [ { - "label" : "v", - "name" : "v", + "label" : "_", + "name" : "method", "type" : { - "int" : { - + "caseEnum" : { + "_0" : "Networking.API.Method" } } } ], "returnType" : { - "int" : { - + "caseEnum" : { + "_0" : "Networking.API.Method" } } }, { - "abiName" : "bjs_asyncRoundTripFloat", + "abiName" : "bjs_echoConfigurationLogLevel", "effects" : { - "isAsync" : true, + "isAsync" : false, "isThrows" : false }, - "name" : "asyncRoundTripFloat", + "name" : "echoConfigurationLogLevel", "parameters" : [ { - "label" : "v", - "name" : "v", + "label" : "_", + "name" : "level", "type" : { - "float" : { - + "rawValueEnum" : { + "_0" : "Configuration.LogLevel", + "_1" : "String" } } } ], "returnType" : { - "float" : { - + "rawValueEnum" : { + "_0" : "Configuration.LogLevel", + "_1" : "String" } } }, { - "abiName" : "bjs_asyncRoundTripDouble", + "abiName" : "bjs_echoConfigurationPort", "effects" : { - "isAsync" : true, + "isAsync" : false, "isThrows" : false }, - "name" : "asyncRoundTripDouble", + "name" : "echoConfigurationPort", "parameters" : [ { - "label" : "v", - "name" : "v", + "label" : "_", + "name" : "port", "type" : { - "double" : { - + "rawValueEnum" : { + "_0" : "Configuration.Port", + "_1" : "Int" } } } ], "returnType" : { - "double" : { - + "rawValueEnum" : { + "_0" : "Configuration.Port", + "_1" : "Int" } } }, { - "abiName" : "bjs_asyncRoundTripBool", + "abiName" : "bjs_processConfigurationLogLevel", "effects" : { - "isAsync" : true, + "isAsync" : false, "isThrows" : false }, - "name" : "asyncRoundTripBool", + "name" : "processConfigurationLogLevel", "parameters" : [ { - "label" : "v", - "name" : "v", + "label" : "_", + "name" : "level", "type" : { - "bool" : { - + "rawValueEnum" : { + "_0" : "Configuration.LogLevel", + "_1" : "String" } } } ], "returnType" : { - "bool" : { - + "rawValueEnum" : { + "_0" : "Configuration.Port", + "_1" : "Int" } } }, { - "abiName" : "bjs_asyncRoundTripString", + "abiName" : "bjs_echoInternalSupportedMethod", "effects" : { - "isAsync" : true, + "isAsync" : false, "isThrows" : false }, - "name" : "asyncRoundTripString", + "name" : "echoInternalSupportedMethod", "parameters" : [ { - "label" : "v", - "name" : "v", + "label" : "_", + "name" : "method", "type" : { - "string" : { - + "caseEnum" : { + "_0" : "Internal.SupportedMethod" } } } ], "returnType" : { - "string" : { - + "caseEnum" : { + "_0" : "Internal.SupportedMethod" } } }, { - "abiName" : "bjs_asyncRoundTripSwiftHeapObject", + "abiName" : "bjs_echoAPIResult", "effects" : { - "isAsync" : true, + "isAsync" : false, "isThrows" : false }, - "name" : "asyncRoundTripSwiftHeapObject", + "name" : "echoAPIResult", "parameters" : [ { - "label" : "v", - "name" : "v", + "label" : "result", + "name" : "result", "type" : { - "swiftHeapObject" : { - "_0" : "Greeter" + "associatedValueEnum" : { + "_0" : "APIResult" } } } ], "returnType" : { - "swiftHeapObject" : { - "_0" : "Greeter" + "associatedValueEnum" : { + "_0" : "APIResult" } } }, { - "abiName" : "bjs_asyncRoundTripJSObject", + "abiName" : "bjs_makeAPIResultSuccess", "effects" : { - "isAsync" : true, + "isAsync" : false, "isThrows" : false }, - "name" : "asyncRoundTripJSObject", + "name" : "makeAPIResultSuccess", "parameters" : [ { - "label" : "v", - "name" : "v", + "label" : "_", + "name" : "value", "type" : { - "jsObject" : { + "string" : { } } } ], "returnType" : { - "jsObject" : { - + "associatedValueEnum" : { + "_0" : "APIResult" } } }, { - "abiName" : "bjs_takeGreeter", + "abiName" : "bjs_makeAPIResultFailure", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "takeGreeter", + "name" : "makeAPIResultFailure", "parameters" : [ { - "label" : "g", - "name" : "g", - "type" : { - "swiftHeapObject" : { - "_0" : "Greeter" - } - } - }, - { - "label" : "name", - "name" : "name", + "label" : "_", + "name" : "value", "type" : { - "string" : { + "int" : { } } } ], "returnType" : { - "void" : { - + "associatedValueEnum" : { + "_0" : "APIResult" } } }, { - "abiName" : "bjs_createCalculator", + "abiName" : "bjs_makeAPIResultInfo", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "createCalculator", + "name" : "makeAPIResultInfo", "parameters" : [ ], "returnType" : { - "swiftHeapObject" : { - "_0" : "Calculator" + "associatedValueEnum" : { + "_0" : "APIResult" } } }, { - "abiName" : "bjs_useCalculator", + "abiName" : "bjs_makeAPIResultFlag", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "useCalculator", + "name" : "makeAPIResultFlag", "parameters" : [ { - "label" : "calc", - "name" : "calc", - "type" : { - "swiftHeapObject" : { - "_0" : "Calculator" - } - } - }, - { - "label" : "x", - "name" : "x", - "type" : { - "int" : { - - } - } - }, - { - "label" : "y", - "name" : "y", + "label" : "_", + "name" : "value", "type" : { - "int" : { + "bool" : { } } } ], "returnType" : { - "int" : { - + "associatedValueEnum" : { + "_0" : "APIResult" } } }, { - "abiName" : "bjs_testGreeterToJSValue", + "abiName" : "bjs_makeAPIResultRate", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "testGreeterToJSValue", + "name" : "makeAPIResultRate", "parameters" : [ + { + "label" : "_", + "name" : "value", + "type" : { + "float" : { + } + } + } ], "returnType" : { - "jsObject" : { - + "associatedValueEnum" : { + "_0" : "APIResult" } } }, { - "abiName" : "bjs_testCalculatorToJSValue", + "abiName" : "bjs_makeAPIResultPrecise", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "testCalculatorToJSValue", + "name" : "makeAPIResultPrecise", "parameters" : [ + { + "label" : "_", + "name" : "value", + "type" : { + "double" : { + } + } + } ], "returnType" : { - "jsObject" : { - + "associatedValueEnum" : { + "_0" : "APIResult" } } }, { - "abiName" : "bjs_testSwiftClassAsJSValue", + "abiName" : "bjs_echoComplexResult", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "testSwiftClassAsJSValue", + "name" : "echoComplexResult", "parameters" : [ { - "label" : "greeter", - "name" : "greeter", + "label" : "result", + "name" : "result", "type" : { - "swiftHeapObject" : { - "_0" : "Greeter" + "associatedValueEnum" : { + "_0" : "ComplexResult" } } } ], "returnType" : { - "jsObject" : { - + "associatedValueEnum" : { + "_0" : "ComplexResult" } } }, { - "abiName" : "bjs_setDirection", + "abiName" : "bjs_makeComplexResultSuccess", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "setDirection", + "name" : "makeComplexResultSuccess", "parameters" : [ { "label" : "_", - "name" : "direction", + "name" : "value", "type" : { - "caseEnum" : { - "_0" : "Direction" + "string" : { + } } } ], "returnType" : { - "caseEnum" : { - "_0" : "Direction" + "associatedValueEnum" : { + "_0" : "ComplexResult" } } }, { - "abiName" : "bjs_getDirection", + "abiName" : "bjs_makeComplexResultError", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "getDirection", + "name" : "makeComplexResultError", "parameters" : [ + { + "label" : "_", + "name" : "message", + "type" : { + "string" : { + + } + } + }, + { + "label" : "_", + "name" : "code", + "type" : { + "int" : { + } + } + } ], "returnType" : { - "caseEnum" : { - "_0" : "Direction" + "associatedValueEnum" : { + "_0" : "ComplexResult" } } }, { - "abiName" : "bjs_processDirection", + "abiName" : "bjs_makeComplexResultLocation", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "processDirection", + "name" : "makeComplexResultLocation", "parameters" : [ { "label" : "_", - "name" : "input", + "name" : "lat", "type" : { - "caseEnum" : { - "_0" : "Direction" + "double" : { + + } + } + }, + { + "label" : "_", + "name" : "lng", + "type" : { + "double" : { + + } + } + }, + { + "label" : "_", + "name" : "name", + "type" : { + "string" : { + } } } ], "returnType" : { - "caseEnum" : { - "_0" : "Status" + "associatedValueEnum" : { + "_0" : "ComplexResult" } } }, { - "abiName" : "bjs_setTheme", + "abiName" : "bjs_makeComplexResultStatus", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "setTheme", + "name" : "makeComplexResultStatus", "parameters" : [ { "label" : "_", - "name" : "theme", + "name" : "active", "type" : { - "rawValueEnum" : { - "_0" : "Theme", - "_1" : "String" + "bool" : { + + } + } + }, + { + "label" : "_", + "name" : "code", + "type" : { + "int" : { + + } + } + }, + { + "label" : "_", + "name" : "message", + "type" : { + "string" : { + } } } ], "returnType" : { - "rawValueEnum" : { - "_0" : "Theme", - "_1" : "String" + "associatedValueEnum" : { + "_0" : "ComplexResult" } } }, { - "abiName" : "bjs_getTheme", + "abiName" : "bjs_makeComplexResultCoordinates", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "getTheme", + "name" : "makeComplexResultCoordinates", "parameters" : [ + { + "label" : "_", + "name" : "x", + "type" : { + "double" : { + + } + } + }, + { + "label" : "_", + "name" : "y", + "type" : { + "double" : { + + } + } + }, + { + "label" : "_", + "name" : "z", + "type" : { + "double" : { + } + } + } ], "returnType" : { - "rawValueEnum" : { - "_0" : "Theme", - "_1" : "String" + "associatedValueEnum" : { + "_0" : "ComplexResult" } } }, { - "abiName" : "bjs_setHttpStatus", + "abiName" : "bjs_makeComplexResultComprehensive", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "setHttpStatus", + "name" : "makeComplexResultComprehensive", "parameters" : [ { "label" : "_", - "name" : "status", + "name" : "flag1", "type" : { - "rawValueEnum" : { - "_0" : "HttpStatus", - "_1" : "Int" + "bool" : { + + } + } + }, + { + "label" : "_", + "name" : "flag2", + "type" : { + "bool" : { + + } + } + }, + { + "label" : "_", + "name" : "count1", + "type" : { + "int" : { + + } + } + }, + { + "label" : "_", + "name" : "count2", + "type" : { + "int" : { + + } + } + }, + { + "label" : "_", + "name" : "value1", + "type" : { + "double" : { + + } + } + }, + { + "label" : "_", + "name" : "value2", + "type" : { + "double" : { + + } + } + }, + { + "label" : "_", + "name" : "text1", + "type" : { + "string" : { + + } + } + }, + { + "label" : "_", + "name" : "text2", + "type" : { + "string" : { + + } + } + }, + { + "label" : "_", + "name" : "text3", + "type" : { + "string" : { + } } } ], "returnType" : { - "rawValueEnum" : { - "_0" : "HttpStatus", - "_1" : "Int" + "associatedValueEnum" : { + "_0" : "ComplexResult" } } }, { - "abiName" : "bjs_getHttpStatus", + "abiName" : "bjs_makeComplexResultInfo", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "getHttpStatus", + "name" : "makeComplexResultInfo", "parameters" : [ ], "returnType" : { - "rawValueEnum" : { - "_0" : "HttpStatus", - "_1" : "Int" + "associatedValueEnum" : { + "_0" : "ComplexResult" } } }, { - "abiName" : "bjs_processTheme", + "abiName" : "bjs_roundtripComplexResult", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "processTheme", + "name" : "roundtripComplexResult", "parameters" : [ { "label" : "_", - "name" : "theme", + "name" : "result", "type" : { - "rawValueEnum" : { - "_0" : "Theme", - "_1" : "String" + "associatedValueEnum" : { + "_0" : "ComplexResult" } } } ], "returnType" : { - "rawValueEnum" : { - "_0" : "HttpStatus", - "_1" : "Int" + "associatedValueEnum" : { + "_0" : "ComplexResult" } } }, { - "abiName" : "bjs_setTSDirection", + "abiName" : "bjs_makeUtilitiesResultSuccess", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "setTSDirection", + "name" : "makeUtilitiesResultSuccess", "parameters" : [ { "label" : "_", - "name" : "direction", + "name" : "message", "type" : { - "caseEnum" : { - "_0" : "TSDirection" + "string" : { + } } } ], "returnType" : { - "caseEnum" : { - "_0" : "TSDirection" + "associatedValueEnum" : { + "_0" : "Utilities.Result" } } }, { - "abiName" : "bjs_getTSDirection", + "abiName" : "bjs_makeUtilitiesResultFailure", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "getTSDirection", + "name" : "makeUtilitiesResultFailure", "parameters" : [ + { + "label" : "_", + "name" : "error", + "type" : { + "string" : { - ], - "returnType" : { - "caseEnum" : { - "_0" : "TSDirection" - } - } - }, - { - "abiName" : "bjs_setTSTheme", - "effects" : { - "isAsync" : false, - "isThrows" : false - }, - "name" : "setTSTheme", - "parameters" : [ + } + } + }, { "label" : "_", - "name" : "theme", + "name" : "code", "type" : { - "rawValueEnum" : { - "_0" : "TSTheme", - "_1" : "String" + "int" : { + } } } ], "returnType" : { - "rawValueEnum" : { - "_0" : "TSTheme", - "_1" : "String" + "associatedValueEnum" : { + "_0" : "Utilities.Result" } } }, { - "abiName" : "bjs_getTSTheme", + "abiName" : "bjs_makeUtilitiesResultStatus", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "getTSTheme", + "name" : "makeUtilitiesResultStatus", "parameters" : [ + { + "label" : "_", + "name" : "active", + "type" : { + "bool" : { - ], - "returnType" : { - "rawValueEnum" : { - "_0" : "TSTheme", - "_1" : "String" - } - } - }, - { - "abiName" : "bjs_echoNetworkingAPIMethod", - "effects" : { - "isAsync" : false, - "isThrows" : false - }, - "name" : "echoNetworkingAPIMethod", - "parameters" : [ + } + } + }, { "label" : "_", - "name" : "method", + "name" : "code", "type" : { - "caseEnum" : { - "_0" : "Networking.API.Method" + "int" : { + + } + } + }, + { + "label" : "_", + "name" : "message", + "type" : { + "string" : { + } } } ], "returnType" : { - "caseEnum" : { - "_0" : "Networking.API.Method" + "associatedValueEnum" : { + "_0" : "Utilities.Result" } } }, { - "abiName" : "bjs_echoConfigurationLogLevel", + "abiName" : "bjs_makeAPINetworkingResultSuccess", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "echoConfigurationLogLevel", + "name" : "makeAPINetworkingResultSuccess", "parameters" : [ { "label" : "_", - "name" : "level", + "name" : "message", "type" : { - "rawValueEnum" : { - "_0" : "Configuration.LogLevel", - "_1" : "String" + "string" : { + } } } ], "returnType" : { - "rawValueEnum" : { - "_0" : "Configuration.LogLevel", - "_1" : "String" + "associatedValueEnum" : { + "_0" : "API.NetworkingResult" } } }, { - "abiName" : "bjs_echoConfigurationPort", + "abiName" : "bjs_makeAPINetworkingResultFailure", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "echoConfigurationPort", + "name" : "makeAPINetworkingResultFailure", "parameters" : [ { "label" : "_", - "name" : "port", + "name" : "error", "type" : { - "rawValueEnum" : { - "_0" : "Configuration.Port", - "_1" : "Int" + "string" : { + + } + } + }, + { + "label" : "_", + "name" : "code", + "type" : { + "int" : { + } } } ], "returnType" : { - "rawValueEnum" : { - "_0" : "Configuration.Port", - "_1" : "Int" + "associatedValueEnum" : { + "_0" : "API.NetworkingResult" } } }, { - "abiName" : "bjs_processConfigurationLogLevel", + "abiName" : "bjs_roundtripUtilitiesResult", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "processConfigurationLogLevel", + "name" : "roundtripUtilitiesResult", "parameters" : [ { "label" : "_", - "name" : "level", + "name" : "result", "type" : { - "rawValueEnum" : { - "_0" : "Configuration.LogLevel", - "_1" : "String" + "associatedValueEnum" : { + "_0" : "Utilities.Result" } } } ], "returnType" : { - "rawValueEnum" : { - "_0" : "Configuration.Port", - "_1" : "Int" + "associatedValueEnum" : { + "_0" : "Utilities.Result" } } }, { - "abiName" : "bjs_echoInternalSupportedMethod", + "abiName" : "bjs_roundtripAPINetworkingResult", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "echoInternalSupportedMethod", + "name" : "roundtripAPINetworkingResult", "parameters" : [ { "label" : "_", - "name" : "method", + "name" : "result", "type" : { - "caseEnum" : { - "_0" : "Internal.SupportedMethod" + "associatedValueEnum" : { + "_0" : "API.NetworkingResult" } } } ], "returnType" : { - "caseEnum" : { - "_0" : "Internal.SupportedMethod" + "associatedValueEnum" : { + "_0" : "API.NetworkingResult" } } }, diff --git a/Tests/prelude.mjs b/Tests/prelude.mjs index 8094a465..fc7598e3 100644 --- a/Tests/prelude.mjs +++ b/Tests/prelude.mjs @@ -1,7 +1,7 @@ // @ts-check -import { - Direction, Status, Theme, HttpStatus, TSDirection, TSTheme +import { + Direction, Status, Theme, HttpStatus, TSDirection, TSTheme, APIResult, ComplexResult } from '../.build/plugins/PackageToJS/outputs/PackageTests/bridge-js.js'; /** @type {import('../.build/plugins/PackageToJS/outputs/PackageTests/test.d.ts').SetupOptionsFn} */ @@ -389,6 +389,89 @@ function BridgeJSRuntimeTests_runJsWorks(instance, exports) { const globalTestServer = new globalThis.Networking.APIV2.Internal.TestServer(); globalTestServer.call(globalThis.Networking.APIV2.Internal.SupportedMethod.Post); globalTestServer.release(); + + const s1 = { tag: APIResult.Tag.Success, param0: "Cześć 🙋‍♂️" }; + const f1 = { tag: APIResult.Tag.Failure, param0: 42 }; + const i1 = { tag: APIResult.Tag.Info }; + + assert.deepEqual(exports.echoAPIResult(s1), s1); + assert.deepEqual(exports.echoAPIResult(f1), f1); + assert.deepEqual(exports.echoAPIResult(i1), i1); + + + assert.deepEqual(exports.makeAPIResultSuccess("Test"), { tag: APIResult.Tag.Success, param0: "Test" }); + assert.deepEqual(exports.makeAPIResultSuccess("ok"), { tag: APIResult.Tag.Success, param0: "ok" }); + assert.deepEqual(exports.makeAPIResultFailure(123), { tag: APIResult.Tag.Failure, param0: 123 }); + assert.deepEqual(exports.makeAPIResultInfo(), { tag: APIResult.Tag.Info }); + + const bTrue = { tag: APIResult.Tag.Flag, param0: true }; + const bFalse = { tag: APIResult.Tag.Flag, param0: false }; + assert.deepEqual(exports.makeAPIResultFlag(true), bTrue); + assert.deepEqual(exports.makeAPIResultFlag(false), bFalse); + + const rVal = 3.25; + const r1 = { tag: APIResult.Tag.Rate, param0: rVal }; + assert.deepEqual(exports.echoAPIResult(r1), r1); + assert.deepEqual(exports.makeAPIResultRate(rVal), r1); + + const pVal = 3.141592653589793; + const p1 = { tag: APIResult.Tag.Precise, param0: pVal }; + assert.deepEqual(exports.echoAPIResult(p1), p1); + assert.deepEqual(exports.makeAPIResultPrecise(pVal), p1); + + const cs1 = { tag: ComplexResult.Tag.Success, param0: "All good!" }; + const ce1 = { tag: ComplexResult.Tag.Error, param0: "Network error", param1: 503 }; + const cl1 = { tag: ComplexResult.Tag.Location, param0: 37.7749, param1: -122.4194, param2: "San Francisco" }; + const cst1 = { tag: ComplexResult.Tag.Status, param0: true, param1: 200, param2: "OK" }; + const cc1 = { tag: ComplexResult.Tag.Coordinates, param0: 10.5, param1: 20.3, param2: 30.7 }; + const ccomp1 = { tag: ComplexResult.Tag.Comprehensive, param0: true, param1: false, param2: 42, param3: 100, param4: 3.14, param5: 2.718, param6: "Hello", param7: "World", param8: "Test" }; + const ci1 = { tag: ComplexResult.Tag.Info }; + + assert.deepEqual(exports.echoComplexResult(cs1), cs1); + assert.deepEqual(exports.echoComplexResult(ce1), ce1); + assert.deepEqual(exports.echoComplexResult(cl1), cl1); + assert.deepEqual(exports.echoComplexResult(cst1), cst1); + assert.deepEqual(exports.echoComplexResult(cc1), cc1); + assert.deepEqual(exports.echoComplexResult(ccomp1), ccomp1); + assert.deepEqual(exports.echoComplexResult(ci1), ci1); + + assert.deepEqual(exports.roundtripComplexResult(cs1), cs1); + assert.deepEqual(exports.roundtripComplexResult(ce1), ce1); + assert.deepEqual(exports.roundtripComplexResult(cl1), cl1); + assert.deepEqual(exports.roundtripComplexResult(cst1), cst1); + assert.deepEqual(exports.roundtripComplexResult(cc1), cc1); + assert.deepEqual(exports.roundtripComplexResult(ccomp1), ccomp1); + assert.deepEqual(exports.roundtripComplexResult(ci1), ci1); + + assert.deepEqual(exports.makeComplexResultSuccess("Great!"), { tag: ComplexResult.Tag.Success, param0: "Great!" }); + assert.deepEqual(exports.makeComplexResultError("Timeout", 408), { tag: ComplexResult.Tag.Error, param0: "Timeout", param1: 408 }); + assert.deepEqual(exports.makeComplexResultLocation(40.7128, -74.0060, "New York"), { tag: ComplexResult.Tag.Location, param0: 40.7128, param1: -74.0060, param2: "New York" }); + assert.deepEqual(exports.makeComplexResultStatus(false, 500, "Internal Server Error"), { tag: ComplexResult.Tag.Status, param0: false, param1: 500, param2: "Internal Server Error" }); + assert.deepEqual(exports.makeComplexResultCoordinates(1.1, 2.2, 3.3), { tag: ComplexResult.Tag.Coordinates, param0: 1.1, param1: 2.2, param2: 3.3 }); + assert.deepEqual(exports.makeComplexResultComprehensive(true, false, 10, 20, 1.5, 2.5, "First", "Second", "Third"), { tag: ComplexResult.Tag.Comprehensive, param0: true, param1: false, param2: 10, param3: 20, param4: 1.5, param5: 2.5, param6: "First", param7: "Second", param8: "Third" }); + assert.deepEqual(exports.makeComplexResultInfo(), { tag: ComplexResult.Tag.Info }); + + const urSuccess = { tag: globalThis.Utilities.Result.Tag.Success, param0: "Utility operation completed" }; + const urFailure = { tag: globalThis.Utilities.Result.Tag.Failure, param0: "Utility error occurred", param1: 500 }; + const urStatus = { tag: globalThis.Utilities.Result.Tag.Status, param0: true, param1: 200, param2: "Utility status OK" }; + + assert.deepEqual(exports.roundtripUtilitiesResult(urSuccess), urSuccess); + assert.deepEqual(exports.roundtripUtilitiesResult(urFailure), urFailure); + assert.deepEqual(exports.roundtripUtilitiesResult(urStatus), urStatus); + + assert.deepEqual(exports.makeUtilitiesResultSuccess("Test"), { tag: globalThis.Utilities.Result.Tag.Success, param0: "Test" }); + assert.deepEqual(exports.makeUtilitiesResultSuccess("ok"), { tag: globalThis.Utilities.Result.Tag.Success, param0: "ok" }); + assert.deepEqual(exports.makeUtilitiesResultFailure("Error", 123), { tag: globalThis.Utilities.Result.Tag.Failure, param0: "Error", param1: 123 }); + assert.deepEqual(exports.makeUtilitiesResultStatus(true, 200, "OK"), { tag: globalThis.Utilities.Result.Tag.Status, param0: true, param1: 200, param2: "OK" }); + + const nrSuccess = { tag: globalThis.API.NetworkingResult.Tag.Success, param0: "Network request successful" }; + const nrFailure = { tag: globalThis.API.NetworkingResult.Tag.Failure, param0: "Network timeout", param1: 408 }; + + assert.deepEqual(exports.roundtripAPINetworkingResult(nrSuccess), nrSuccess); + assert.deepEqual(exports.roundtripAPINetworkingResult(nrFailure), nrFailure); + + assert.deepEqual(exports.makeAPINetworkingResultSuccess("Connected"), { tag: globalThis.API.NetworkingResult.Tag.Success, param0: "Connected" }); + assert.deepEqual(exports.makeAPINetworkingResultFailure("Timeout", 408), { tag: globalThis.API.NetworkingResult.Tag.Failure, param0: "Timeout", param1: 408 }); } /** @param {import('./../.build/plugins/PackageToJS/outputs/PackageTests/bridge-js.d.ts').Exports} exports */ @@ -487,4 +570,4 @@ function setupTestGlobals(global) { sym: Symbol("s"), bi: BigInt(3) }; -} +} \ No newline at end of file From 08dce16b0ea9311b4410b3da14a123f28e8c3f35 Mon Sep 17 00:00:00 2001 From: Krzysztof Rodak Date: Thu, 28 Aug 2025 10:51:31 +0200 Subject: [PATCH 2/4] BridgeJS: Fix build error on CI --- Sources/JavaScriptKit/BridgeJSInstrincics.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Sources/JavaScriptKit/BridgeJSInstrincics.swift b/Sources/JavaScriptKit/BridgeJSInstrincics.swift index 3107252d..555a21f4 100644 --- a/Sources/JavaScriptKit/BridgeJSInstrincics.swift +++ b/Sources/JavaScriptKit/BridgeJSInstrincics.swift @@ -422,8 +422,9 @@ where Self: RawRepresentable, RawValue: _BridgedSwiftTypeLoweredIntoSingleWasmCo public mutating func expectTag(_ expected: _BJSParamType) { let rawTag = readUInt8() guard let got = _BJSParamType(rawValue: rawTag), got == expected else { + let resultString = _BJSParamType(rawValue: rawTag).map { "\($0)" } ?? "invalid(\(rawTag))" preconditionFailure( - "BridgeJS: mismatched enum param tag. Expected \(expected) got \(String(describing: _BJSParamType(rawValue: rawTag)))" + "BridgeJS: mismatched enum param tag. Expected \(expected) got \(resultString))" ) } } From e89dfc0a7e4921b7862275fa7ae772d68eea6f15 Mon Sep 17 00:00:00 2001 From: Krzysztof Rodak Date: Fri, 29 Aug 2025 11:15:50 +0200 Subject: [PATCH 3/4] BridgeJS: Migrate to stack based solution for storing / passing value types --- .../Sources/BridgeJSCore/ExportSwift.swift | 67 ++- .../Sources/BridgeJSLink/BridgeJSLink.swift | 239 +++++---- .../Sources/BridgeJSLink/JSGlueGen.swift | 16 +- .../Inputs/EnumAssociatedValue.swift | 6 + .../ArrayParameter.Import.js | 46 +- .../BridgeJSLinkTests/Async.Export.js | 46 +- .../BridgeJSLinkTests/Async.Import.js | 46 +- .../EnumAssociatedValue.Export.d.ts | 2 + .../EnumAssociatedValue.Export.js | 457 ++++++++++-------- .../BridgeJSLinkTests/EnumCase.Export.js | 46 +- .../BridgeJSLinkTests/EnumNamespace.Export.js | 46 +- .../BridgeJSLinkTests/EnumRawType.Export.js | 46 +- .../BridgeJSLinkTests/Interface.Import.js | 46 +- .../InvalidPropertyNames.Import.js | 46 +- .../MultipleImportedTypes.Import.js | 46 +- .../BridgeJSLinkTests/Namespaces.Export.js | 46 +- .../PrimitiveParameters.Export.js | 46 +- .../PrimitiveParameters.Import.js | 46 +- .../PrimitiveReturn.Export.js | 46 +- .../PrimitiveReturn.Import.js | 46 +- .../BridgeJSLinkTests/PropertyTypes.Export.js | 46 +- .../StringParameter.Export.js | 46 +- .../StringParameter.Import.js | 46 +- .../BridgeJSLinkTests/StringReturn.Export.js | 46 +- .../BridgeJSLinkTests/StringReturn.Import.js | 46 +- .../BridgeJSLinkTests/SwiftClass.Export.js | 46 +- .../TS2SkeletonLike.Import.js | 46 +- .../BridgeJSLinkTests/Throws.Export.js | 46 +- .../BridgeJSLinkTests/TypeAlias.Import.js | 46 +- .../TypeScriptClass.Import.js | 46 +- .../VoidParameterVoidReturn.Export.js | 46 +- .../VoidParameterVoidReturn.Import.js | 46 +- .../ExportSwiftTests/EnumAssociatedValue.json | 48 ++ .../EnumAssociatedValue.swift | 335 +++++-------- .../JavaScriptKit/BridgeJSInstrincics.swift | 149 ++---- .../BridgeJSRuntimeTests/ExportAPITests.swift | 16 +- .../Generated/BridgeJS.ExportSwift.swift | 391 +++++---------- .../JavaScript/BridgeJS.ExportSwift.json | 50 +- Tests/prelude.mjs | 27 +- 39 files changed, 1404 insertions(+), 1595 deletions(-) diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift index af23c4d0..a8a50acf 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift @@ -1042,17 +1042,10 @@ public class ExportSwift { let typeName = enumDef.swiftCallName return """ private extension \(raw: typeName) { - static func bridgeJSLiftParameter(_ caseId: Int32, _ paramsId: Int32, _ paramsLen: Int32) -> \(raw: typeName) { - let params: [UInt8] = .init(unsafeUninitializedCapacity: Int(paramsLen)) { buf, initializedCount in - _swift_js_init_memory(paramsId, buf.baseAddress.unsafelyUnwrapped) - initializedCount = Int(paramsLen) - } - return params.withUnsafeBytes { raw in - var reader = _BJSBinaryReader(raw: raw) - switch caseId { - \(raw: generateBinaryLiftSwitchCases(enumDef: enumDef).joined(separator: "\n")) - default: fatalError("Unknown \(raw: typeName) case ID: \\(caseId)") - } + static func bridgeJSLiftParameter(_ caseId: Int32) -> \(raw: typeName) { + switch caseId { + \(raw: generateStackLiftSwitchCases(enumDef: enumDef).joined(separator: "\n")) + default: fatalError("Unknown \(raw: typeName) case ID: \\(caseId)") } } @@ -1065,7 +1058,7 @@ public class ExportSwift { """ } - private func generateBinaryLiftSwitchCases(enumDef: ExportedEnum) -> [String] { + private func generateStackLiftSwitchCases(enumDef: ExportedEnum) -> [String] { var cases: [String] = [] for (caseIndex, enumCase) in enumDef.cases.enumerated() { if enumCase.associatedValues.isEmpty { @@ -1073,35 +1066,29 @@ public class ExportSwift { } else { var lines: [String] = [] lines.append("case \(caseIndex):") - lines.append("reader.readParamCount(expected: \(enumCase.associatedValues.count))") - var argList: [String] = [] - - for (paramIndex, associatedValue) in enumCase.associatedValues.enumerated() { - let paramName = associatedValue.label ?? "param\(paramIndex)" - argList.append(paramName) - + let argList = enumCase.associatedValues.map { associatedValue in + let paramName: String + if let label = associatedValue.label { + paramName = "\(label): " + } else { + paramName = "" + } switch associatedValue.type { case .string: - lines.append("reader.expectTag(.string)") - lines.append("let \(paramName) = reader.readString()") + return + "\(paramName)String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32())" case .int: - lines.append("reader.expectTag(.int32)") - lines.append("let \(paramName) = Int(reader.readInt32())") + return "\(paramName)Int.bridgeJSLiftParameter(_swift_js_pop_param_int32())" case .bool: - lines.append("reader.expectTag(.bool)") - lines.append("let \(paramName) = Int32(reader.readUInt8()) != 0") + return "\(paramName)Bool.bridgeJSLiftParameter(_swift_js_pop_param_int32())" case .float: - lines.append("reader.expectTag(.float32)") - lines.append("let \(paramName) = reader.readFloat32()") + return "\(paramName)Float.bridgeJSLiftParameter(_swift_js_pop_param_f32())" case .double: - lines.append("reader.expectTag(.float64)") - lines.append("let \(paramName) = reader.readFloat64()") + return "\(paramName)Double.bridgeJSLiftParameter(_swift_js_pop_param_f64())" default: - lines.append("reader.expectTag(.int32)") - lines.append("let \(paramName) = reader.readInt32()") + return "\(paramName)Int.bridgeJSLiftParameter(_swift_js_pop_param_int32())" } } - lines.append("return .\(enumCase.name)(\(argList.joined(separator: ", ")))") cases.append(lines.joined(separator: "\n")) } @@ -1114,26 +1101,26 @@ public class ExportSwift { for (caseIndex, enumCase) in enumDef.cases.enumerated() { if enumCase.associatedValues.isEmpty { cases.append("case .\(enumCase.name):") - cases.append("_swift_js_return_tag(Int32(\(caseIndex)))") + cases.append("_swift_js_push_tag(Int32(\(caseIndex)))") } else { var bodyLines: [String] = [] - bodyLines.append("_swift_js_return_tag(Int32(\(caseIndex)))") + bodyLines.append("_swift_js_push_tag(Int32(\(caseIndex)))") for (index, associatedValue) in enumCase.associatedValues.enumerated() { let paramName = associatedValue.label ?? "param\(index)" switch associatedValue.type { case .string: bodyLines.append("var __bjs_\(paramName) = \(paramName)") bodyLines.append("__bjs_\(paramName).withUTF8 { ptr in") - bodyLines.append("_swift_js_return_string(ptr.baseAddress, Int32(ptr.count))") + bodyLines.append("_swift_js_push_string(ptr.baseAddress, Int32(ptr.count))") bodyLines.append("}") case .int: - bodyLines.append("_swift_js_return_int(Int32(\(paramName)))") + bodyLines.append("_swift_js_push_int(Int32(\(paramName)))") case .bool: - bodyLines.append("_swift_js_return_bool(\(paramName) ? 1 : 0)") + bodyLines.append("_swift_js_push_int(\(paramName) ? 1 : 0)") case .float: - bodyLines.append("_swift_js_return_f32(\(paramName))") + bodyLines.append("_swift_js_push_f32(\(paramName))") case .double: - bodyLines.append("_swift_js_return_f64(\(paramName))") + bodyLines.append("_swift_js_push_f64(\(paramName))") default: bodyLines.append( "preconditionFailure(\"BridgeJS: unsupported associated value type in generated code\")" @@ -1410,7 +1397,7 @@ extension BridgeType { static let void = LiftingIntrinsicInfo(parameters: []) static let caseEnum = LiftingIntrinsicInfo(parameters: [("value", .i32)]) static let associatedValueEnum = LiftingIntrinsicInfo(parameters: [ - ("caseId", .i32), ("paramsId", .i32), ("paramsLen", .i32), + ("caseId", .i32) ]) } diff --git a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift index 75c07466..494351db 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift @@ -66,54 +66,6 @@ struct BridgeJSLink { """ let sharedEnumHelpersJs = """ - /// Shared helpers for encoding associated-value enums between JS and Swift. - const __bjs_ParamType = { STRING: 1, INT32: 2, BOOL: 3, FLOAT32: 4, FLOAT64: 5 }; - function __bjs_encodeEnumParams(textEncoder, swift, parts) { - const SIZE_U8 = 1, SIZE_U32 = 4, SIZE_F32 = 4, SIZE_F64 = 8; - let totalLen = SIZE_U32; - for (const p of parts) { - switch (p.t) { - case __bjs_ParamType.STRING: { - const bytes = textEncoder.encode(p.v); - p._bytes = bytes; - totalLen += SIZE_U8 + SIZE_U32 + bytes.length; - break; - } - case __bjs_ParamType.INT32: totalLen += SIZE_U8 + SIZE_U32; break; - case __bjs_ParamType.BOOL: totalLen += SIZE_U8 + SIZE_U8; break; - case __bjs_ParamType.FLOAT32: totalLen += SIZE_U8 + SIZE_F32; break; - case __bjs_ParamType.FLOAT64: totalLen += SIZE_U8 + SIZE_F64; break; - default: throw new Error("Unsupported param type tag: " + p.t); - } - } - const buf = new Uint8Array(totalLen); - const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength); - let off = 0; - view.setUint32(off, parts.length, true); off += SIZE_U32; - for (const p of parts) { - view.setUint8(off, p.t); off += SIZE_U8; - switch (p.t) { - case __bjs_ParamType.STRING: { - const b = p._bytes; - view.setUint32(off, b.length, true); off += SIZE_U32; - buf.set(b, off); off += b.length; - break; - } - case __bjs_ParamType.INT32: - view.setInt32(off, (p.v | 0), true); off += SIZE_U32; break; - case __bjs_ParamType.BOOL: - view.setUint8(off, p.v ? 1 : 0); off += SIZE_U8; break; - case __bjs_ParamType.FLOAT32: - view.setFloat32(off, Math.fround(p.v), true); off += SIZE_F32; break; - case __bjs_ParamType.FLOAT64: - view.setFloat64(off, p.v, true); off += SIZE_F64; break; - default: throw new Error("Unsupported param type tag: " + p.t); - } - } - const paramsId = swift.memory.retain(buf); - return { paramsId, paramsLen: buf.length, cleanup: () => { swift.memory.release(paramsId); } }; - } - """ func link() throws -> (outputJs: String, outputDts: String) { @@ -289,7 +241,9 @@ struct BridgeJSLink { let \(JSGlueVariableScope.reservedTmpRetInts) = []; let \(JSGlueVariableScope.reservedTmpRetF32s) = []; let \(JSGlueVariableScope.reservedTmpRetF64s) = []; - let \(JSGlueVariableScope.reservedTmpRetBools) = []; + let \(JSGlueVariableScope.reservedTmpParamInts) = []; + let \(JSGlueVariableScope.reservedTmpParamF32s) = []; + let \(JSGlueVariableScope.reservedTmpParamF64s) = []; \(enumHelpersDeclaration) return { /** @@ -301,18 +255,16 @@ struct BridgeJSLink { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(\(JSGlueVariableScope.reservedMemory).buffer, ptr, len)\(sharedMemory ? ".slice()" : ""); - const value = \(JSGlueVariableScope.reservedTextDecoder).decode(bytes); - \(JSGlueVariableScope.reservedStorageToReturnString) = value; - \(JSGlueVariableScope.reservedTmpRetStrings).push(value); + \(JSGlueVariableScope.reservedStorageToReturnString) = \(JSGlueVariableScope.reservedTextDecoder).decode(bytes); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { - const source = \(JSGlueVariableScope.reservedSwift).memory.getObject(sourceId); + const source = \(JSGlueVariableScope.reservedSwift).\(JSGlueVariableScope.reservedMemory).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(\(JSGlueVariableScope.reservedMemory).buffer, ptr, len)\(sharedMemory ? ".slice()" : ""); - return \(JSGlueVariableScope.reservedSwift).memory.retain(\(JSGlueVariableScope.reservedTextDecoder).decode(bytes)); + return \(JSGlueVariableScope.reservedSwift).\(JSGlueVariableScope.reservedMemory).retain(\(JSGlueVariableScope.reservedTextDecoder).decode(bytes)); } bjs["swift_js_init_memory_with_result"] = function(ptr, len) { const target = new Uint8Array(\(JSGlueVariableScope.reservedMemory).buffer, ptr, len); @@ -320,37 +272,39 @@ struct BridgeJSLink { \(JSGlueVariableScope.reservedStorageToReturnBytes) = undefined; } bjs["swift_js_throw"] = function(id) { - \(JSGlueVariableScope.reservedStorageToReturnException) = \(JSGlueVariableScope.reservedSwift).memory.retainByRef(id); + \(JSGlueVariableScope.reservedStorageToReturnException) = \(JSGlueVariableScope.reservedSwift).\(JSGlueVariableScope.reservedMemory).retainByRef(id); } bjs["swift_js_retain"] = function(id) { - return \(JSGlueVariableScope.reservedSwift).memory.retainByRef(id); + return \(JSGlueVariableScope.reservedSwift).\(JSGlueVariableScope.reservedMemory).retainByRef(id); } bjs["swift_js_release"] = function(id) { \(JSGlueVariableScope.reservedSwift).memory.release(id); } - bjs["swift_js_return_tag"] = function(tag) { - \(JSGlueVariableScope.reservedTmpRetTag) = tag | 0; - tmpRetString = undefined; - \(JSGlueVariableScope.reservedTmpRetStrings) = []; - \(JSGlueVariableScope.reservedTmpRetInts) = []; - \(JSGlueVariableScope.reservedTmpRetF32s) = []; - \(JSGlueVariableScope.reservedTmpRetF64s) = []; - \(JSGlueVariableScope.reservedTmpRetBools) = []; + bjs["swift_js_push_tag"] = function(tag) { + \(JSGlueVariableScope.reservedTmpRetTag) = tag; } - bjs["swift_js_return_int"] = function(v) { - const value = v | 0; - \(JSGlueVariableScope.reservedTmpRetInts).push(value); + bjs["swift_js_push_int"] = function(v) { + \(JSGlueVariableScope.reservedTmpRetInts).push(v | 0); } - bjs["swift_js_return_f32"] = function(v) { - const value = Math.fround(v); - \(JSGlueVariableScope.reservedTmpRetF32s).push(value); + bjs["swift_js_push_f32"] = function(v) { + \(JSGlueVariableScope.reservedTmpRetF32s).push(Math.fround(v)); } - bjs["swift_js_return_f64"] = function(v) { + bjs["swift_js_push_f64"] = function(v) { \(JSGlueVariableScope.reservedTmpRetF64s).push(v); } - bjs["swift_js_return_bool"] = function(v) { - const value = v !== 0; - \(JSGlueVariableScope.reservedTmpRetBools).push(value); + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(\(JSGlueVariableScope.reservedMemory).buffer, ptr, len)\(sharedMemory ? ".slice()" : ""); + const value = \(JSGlueVariableScope.reservedTextDecoder).decode(bytes); + \(JSGlueVariableScope.reservedTmpRetStrings).push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return \(JSGlueVariableScope.reservedTmpParamInts).pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return \(JSGlueVariableScope.reservedTmpParamF32s).pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return \(JSGlueVariableScope.reservedTmpParamF64s).pop(); } \(renderSwiftClassWrappers().map { $0.indent(count: 12) }.joined(separator: "\n")) \(importObjectBuilders.flatMap { $0.importedLines }.map { $0.indent(count: 12) }.joined(separator: "\n")) @@ -409,7 +363,9 @@ struct BridgeJSLink { for skeleton in exportedSkeletons { for enumDef in skeleton.enums where enumDef.enumType == .associatedValue { let base = enumDef.name - lines.append("const \(base)Helpers = __bjs_create\(base)Helpers()(textEncoder, swift);") + lines.append( + "const \(base)Helpers = __bjs_create\(base)Helpers()(\(JSGlueVariableScope.reservedTmpParamInts), \(JSGlueVariableScope.reservedTmpParamF32s), \(JSGlueVariableScope.reservedTmpParamF64s), \(JSGlueVariableScope.reservedTextEncoder), \(JSGlueVariableScope.reservedSwift));" + ) lines.append("enumHelpers.\(base) = \(base)Helpers;") lines.append("") } @@ -721,59 +677,78 @@ struct BridgeJSLink { jsLines.append("};") jsLines.append("") jsLines.append("const __bjs_create\(enumDefinition.name)Helpers = () => {") - jsLines.append("return (textEncoder, swift) => ({".indent(count: 4)) + jsLines.append( + "return (\(JSGlueVariableScope.reservedTmpParamInts), \(JSGlueVariableScope.reservedTmpParamF32s), \(JSGlueVariableScope.reservedTmpParamF64s), textEncoder, swift) => ({" + .indent(count: 4) + ) jsLines.append("lower: (value) => {".indent(count: 8)) jsLines.append("const enumTag = value.tag;".indent(count: 12)) jsLines.append("switch (enumTag) {".indent(count: 12)) - for (_, enumCase) in enumDefinition.cases.enumerated() { + enumDefinition.cases.forEach { enumCase in let caseName = enumCase.name.capitalizedFirstLetter if enumCase.associatedValues.isEmpty { jsLines.append("case \(enumDefinition.name).Tag.\(caseName): {".indent(count: 16)) - jsLines.append("const parts = [];".indent(count: 20)) - jsLines.append( - "const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts);" - .indent(count: 20) - ) + jsLines.append("const cleanup = undefined;".indent(count: 20)) jsLines.append( - "return { caseId: \(enumDefinition.name).Tag.\(caseName), paramsId, paramsLen, cleanup };" + "return { caseId: \(enumDefinition.name).Tag.\(caseName), cleanup };" .indent(count: 20) ) jsLines.append("}".indent(count: 16)) } else { jsLines.append("case \(enumDefinition.name).Tag.\(caseName): {".indent(count: 16)) - var partLines: [String] = [] - for (associatedValueIndex, associatedValue) in enumCase.associatedValues.enumerated() { + var pushLines: [String] = [] + var releaseIds: [String] = [] + let reversedValues = enumCase.associatedValues.enumerated().reversed() + for (associatedValueIndex, associatedValue) in reversedValues { let prop = associatedValue.label ?? "param\(associatedValueIndex)" switch associatedValue.type { case .string: - partLines.append("{ t: __bjs_ParamType.STRING, v: value.\(prop) }") - case .int: - partLines.append("{ t: __bjs_ParamType.INT32, v: (value.\(prop) | 0) }") + let bytesVar = "bytes_\(associatedValueIndex)" + let idVar = "bytesId_\(associatedValueIndex)" + pushLines.append( + "const \(bytesVar) = \(JSGlueVariableScope.reservedTextEncoder).encode(value.\(prop));" + ) + pushLines.append( + "const \(idVar) = \(JSGlueVariableScope.reservedSwift).memory.retain(\(bytesVar));" + ) + pushLines.append( + "\(JSGlueVariableScope.reservedTmpParamInts).push(\(bytesVar).length);" + ) + pushLines.append("\(JSGlueVariableScope.reservedTmpParamInts).push(\(idVar));") + releaseIds.append(idVar) case .bool: - partLines.append("{ t: __bjs_ParamType.BOOL, v: value.\(prop) }") + pushLines.append( + "\(JSGlueVariableScope.reservedTmpParamInts).push(value.\(prop) ? 1 : 0);" + ) + case .int: + pushLines.append( + "\(JSGlueVariableScope.reservedTmpParamInts).push((value.\(prop) | 0));" + ) case .float: - partLines.append("{ t: __bjs_ParamType.FLOAT32, v: value.\(prop) }") + pushLines.append( + "\(JSGlueVariableScope.reservedTmpParamF32s).push(Math.fround(value.\(prop)));" + ) case .double: - partLines.append("{ t: __bjs_ParamType.FLOAT64, v: value.\(prop) }") + pushLines.append("\(JSGlueVariableScope.reservedTmpParamF64s).push(value.\(prop));") default: - partLines.append("{ t: __bjs_ParamType.INT32, v: 0 }") + pushLines.append("\(JSGlueVariableScope.reservedTmpParamInts).push(0);") } } - jsLines.append("const parts = [".indent(count: 20)) - if !partLines.isEmpty { - for (i, pl) in partLines.enumerated() { - let suffix = i == partLines.count - 1 ? "" : "," - jsLines.append("\(pl)\(suffix)".indent(count: 24)) + jsLines.append(contentsOf: pushLines.map { $0.indent(count: 20) }) + if releaseIds.isEmpty { + jsLines.append("const cleanup = undefined;".indent(count: 20)) + } else { + jsLines.append("const cleanup = () => {".indent(count: 20)) + for id in releaseIds { + jsLines.append( + "\(JSGlueVariableScope.reservedSwift).memory.release(\(id));".indent(count: 24) + ) } + jsLines.append("};".indent(count: 20)) } - jsLines.append("];".indent(count: 20)) jsLines.append( - "const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts);" - .indent(count: 20) - ) - jsLines.append( - "return { caseId: \(enumDefinition.name).Tag.\(caseName), paramsId, paramsLen, cleanup };" + "return { caseId: \(enumDefinition.name).Tag.\(caseName), cleanup };" .indent(count: 20) ) jsLines.append("}".indent(count: 16)) @@ -788,13 +763,14 @@ struct BridgeJSLink { jsLines.append("},".indent(count: 8)) jsLines.append( - "raise: (tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetBools) => {".indent( - count: 8 - ) + "raise: (\(JSGlueVariableScope.reservedTmpRetTag), \(JSGlueVariableScope.reservedTmpRetStrings), \(JSGlueVariableScope.reservedTmpRetInts), \(JSGlueVariableScope.reservedTmpRetF32s), \(JSGlueVariableScope.reservedTmpRetF64s)) => {" + .indent( + count: 8 + ) ) jsLines.append("const tag = tmpRetTag | 0;".indent(count: 12)) jsLines.append("switch (tag) {".indent(count: 12)) - for (_, enumCase) in enumDefinition.cases.enumerated() { + enumDefinition.cases.forEach { enumCase in let caseName = enumCase.name.capitalizedFirstLetter if enumCase.associatedValues.isEmpty { jsLines.append( @@ -802,38 +778,43 @@ struct BridgeJSLink { .indent(count: 16) ) } else { - var fields: [String] = ["tag: \(enumDefinition.name).Tag.\(caseName)"] - var stringIndex = 0 - var intIndex = 0 - var f32Index = 0 - var f64Index = 0 - var boolIndex = 0 - for (associatedValueIndex, associatedValue) in enumCase.associatedValues.enumerated() { + var locals: [String] = [] + var fieldPairs: [String] = [] + for (associatedValueIndex, associatedValue) in enumCase.associatedValues.enumerated().reversed() + { let prop = associatedValue.label ?? "param\(associatedValueIndex)" switch associatedValue.type { case .string: - fields.append("\(prop): tmpRetStrings[\(stringIndex)]") - stringIndex += 1 + let strVar = "string_\(associatedValueIndex)" + locals.append("const \(strVar) = tmpRetStrings.pop();") + fieldPairs.append("\(prop): \(strVar)") case .bool: - fields.append("\(prop): tmpRetBools[\(boolIndex)]") - boolIndex += 1 + let bVar = "bool_\(associatedValueIndex)" + locals.append("const \(bVar) = tmpRetInts.pop();") + fieldPairs.append("\(prop): \(bVar)") case .int: - fields.append("\(prop): tmpRetInts[\(intIndex)]") - intIndex += 1 + let iVar = "int_\(associatedValueIndex)" + locals.append("const \(iVar) = tmpRetInts.pop();") + fieldPairs.append("\(prop): \(iVar)") case .float: - fields.append("\(prop): tmpRetF32s[\(f32Index)]") - f32Index += 1 + let fVar = "f32_\(associatedValueIndex)" + locals.append("const \(fVar) = tmpRetF32s.pop();") + fieldPairs.append("\(prop): \(fVar)") case .double: - fields.append("\(prop): tmpRetF64s[\(f64Index)]") - f64Index += 1 + let dVar = "f64_\(associatedValueIndex)" + locals.append("const \(dVar) = tmpRetF64s.pop();") + fieldPairs.append("\(prop): \(dVar)") default: - fields.append("\(prop): undefined") + fieldPairs.append("\(prop): undefined") } } + jsLines.append("case \(enumDefinition.name).Tag.\(caseName): {".indent(count: 16)) + jsLines.append(contentsOf: locals.map { $0.indent(count: 20) }) jsLines.append( - "case \(enumDefinition.name).Tag.\(caseName): return { \(fields.joined(separator: ", ")) };" - .indent(count: 16) + "return { tag: \(enumDefinition.name).Tag.\(caseName), \(fieldPairs.reversed().joined(separator: ", ")) };" + .indent(count: 20) ) + jsLines.append("}".indent(count: 16)) } } jsLines.append( @@ -850,9 +831,9 @@ struct BridgeJSLink { if enumDefinition.namespace == nil { dtsLines.append("export const \(enumDefinition.name): {") dtsLines.append("readonly Tag: {".indent(count: 4)) - for (caseIndex, enumCase) in enumDefinition.cases.enumerated() { + for (index, enumCase) in enumDefinition.cases.enumerated() { let caseName = enumCase.name.capitalizedFirstLetter - dtsLines.append("readonly \(caseName): \(caseIndex);".indent(count: 8)) + dtsLines.append("readonly \(caseName): \(index);".indent(count: 8)) } dtsLines.append("};".indent(count: 4)) dtsLines.append("};") diff --git a/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift b/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift index 84417cd4..f559e62f 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift @@ -20,7 +20,9 @@ final class JSGlueVariableScope { static let reservedTmpRetInts = "tmpRetInts" static let reservedTmpRetF32s = "tmpRetF32s" static let reservedTmpRetF64s = "tmpRetF64s" - static let reservedTmpRetBools = "tmpRetBools" + static let reservedTmpParamInts = "tmpParamInts" + static let reservedTmpParamF32s = "tmpParamF32s" + static let reservedTmpParamF64s = "tmpParamF64s" private var variables: Set = [ reservedSwift, @@ -35,7 +37,9 @@ final class JSGlueVariableScope { reservedTmpRetInts, reservedTmpRetF32s, reservedTmpRetF64s, - reservedTmpRetBools, + reservedTmpParamInts, + reservedTmpParamF32s, + reservedTmpParamF64s, ] /// Returns a unique variable name in the scope based on the given name hint. @@ -212,14 +216,12 @@ struct IntrinsicJSFragment: Sendable { printCode: { arguments, scope, printer, cleanup in let value = arguments[0] let caseIdName = "\(value)CaseId" - let paramsIdName = "\(value)ParamsId" - let paramsLenName = "\(value)ParamsLen" let cleanupName = "\(value)Cleanup" printer.write( - "const { caseId: \(caseIdName), paramsId: \(paramsIdName), paramsLen: \(paramsLenName), cleanup: \(cleanupName) } = enumHelpers.\(enumBase).lower(\(value));" + "const { caseId: \(caseIdName), cleanup: \(cleanupName) } = enumHelpers.\(enumBase).lower(\(value));" ) cleanup.write("if (\(cleanupName)) { \(cleanupName)(); }") - return [caseIdName, paramsIdName, paramsLenName] + return [caseIdName] } ) } @@ -230,7 +232,7 @@ struct IntrinsicJSFragment: Sendable { printCode: { _, scope, printer, _ in let retName = scope.variable("ret") printer.write( - "const \(retName) = enumHelpers.\(enumBase).raise(\(JSGlueVariableScope.reservedTmpRetTag), \(JSGlueVariableScope.reservedTmpRetStrings), \(JSGlueVariableScope.reservedTmpRetInts), \(JSGlueVariableScope.reservedTmpRetF32s), \(JSGlueVariableScope.reservedTmpRetF64s), \(JSGlueVariableScope.reservedTmpRetBools));" + "const \(retName) = enumHelpers.\(enumBase).raise(\(JSGlueVariableScope.reservedTmpRetTag), \(JSGlueVariableScope.reservedTmpRetStrings), \(JSGlueVariableScope.reservedTmpRetInts), \(JSGlueVariableScope.reservedTmpRetF32s), \(JSGlueVariableScope.reservedTmpRetF64s));" ) return [retName] } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/EnumAssociatedValue.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/EnumAssociatedValue.swift index 08d03a2b..419800d6 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/EnumAssociatedValue.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/EnumAssociatedValue.swift @@ -10,6 +10,9 @@ enum APIResult { @JS func handle(result: APIResult) @JS func getResult() -> APIResult +@JS func roundtripAPIResult(result: APIResult) -> APIResult { + return result +} @JS enum ComplexResult { @@ -23,6 +26,9 @@ enum ComplexResult { @JS func handleComplex(result: ComplexResult) @JS func getComplexResult() -> ComplexResult +@JS func roundtripComplexResult(_ result: ComplexResult) -> ComplexResult { + return result +} @JS enum Utilities { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayParameter.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayParameter.Import.js index 602cd9a4..ef8b096f 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayParameter.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayParameter.Import.js @@ -18,7 +18,9 @@ export async function createInstantiator(options, swift) { let tmpRetInts = []; let tmpRetF32s = []; let tmpRetF64s = []; - let tmpRetBools = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; return { @@ -31,9 +33,7 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - const value = textDecoder.decode(bytes); - tmpRetString = value; - tmpRetStrings.push(value); + tmpRetString = textDecoder.decode(bytes); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -58,29 +58,31 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } - bjs["swift_js_return_tag"] = function(tag) { - tmpRetTag = tag | 0; - tmpRetString = undefined; - tmpRetStrings = []; - tmpRetInts = []; - tmpRetF32s = []; - tmpRetF64s = []; - tmpRetBools = []; + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; } - bjs["swift_js_return_int"] = function(v) { - const value = v | 0; - tmpRetInts.push(value); + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); } - bjs["swift_js_return_f32"] = function(v) { - const value = Math.fround(v); - tmpRetF32s.push(value); + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); } - bjs["swift_js_return_f64"] = function(v) { + bjs["swift_js_push_f64"] = function(v) { tmpRetF64s.push(v); } - bjs["swift_js_return_bool"] = function(v) { - const value = v !== 0; - tmpRetBools.push(value); + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Export.js index f20f4932..45744231 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Export.js @@ -18,7 +18,9 @@ export async function createInstantiator(options, swift) { let tmpRetInts = []; let tmpRetF32s = []; let tmpRetF64s = []; - let tmpRetBools = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; return { @@ -31,9 +33,7 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - const value = textDecoder.decode(bytes); - tmpRetString = value; - tmpRetStrings.push(value); + tmpRetString = textDecoder.decode(bytes); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -58,29 +58,31 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } - bjs["swift_js_return_tag"] = function(tag) { - tmpRetTag = tag | 0; - tmpRetString = undefined; - tmpRetStrings = []; - tmpRetInts = []; - tmpRetF32s = []; - tmpRetF64s = []; - tmpRetBools = []; + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; } - bjs["swift_js_return_int"] = function(v) { - const value = v | 0; - tmpRetInts.push(value); + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); } - bjs["swift_js_return_f32"] = function(v) { - const value = Math.fround(v); - tmpRetF32s.push(value); + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); } - bjs["swift_js_return_f64"] = function(v) { + bjs["swift_js_push_f64"] = function(v) { tmpRetF64s.push(v); } - bjs["swift_js_return_bool"] = function(v) { - const value = v !== 0; - tmpRetBools.push(value); + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Import.js index 95898a12..56b27ffb 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.Import.js @@ -18,7 +18,9 @@ export async function createInstantiator(options, swift) { let tmpRetInts = []; let tmpRetF32s = []; let tmpRetF64s = []; - let tmpRetBools = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; return { @@ -31,9 +33,7 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - const value = textDecoder.decode(bytes); - tmpRetString = value; - tmpRetStrings.push(value); + tmpRetString = textDecoder.decode(bytes); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -58,29 +58,31 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } - bjs["swift_js_return_tag"] = function(tag) { - tmpRetTag = tag | 0; - tmpRetString = undefined; - tmpRetStrings = []; - tmpRetInts = []; - tmpRetF32s = []; - tmpRetF64s = []; - tmpRetBools = []; + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; } - bjs["swift_js_return_int"] = function(v) { - const value = v | 0; - tmpRetInts.push(value); + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); } - bjs["swift_js_return_f32"] = function(v) { - const value = Math.fround(v); - tmpRetF32s.push(value); + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); } - bjs["swift_js_return_f64"] = function(v) { + bjs["swift_js_push_f64"] = function(v) { tmpRetF64s.push(v); } - bjs["swift_js_return_bool"] = function(v) { - const value = v !== 0; - tmpRetBools.push(value); + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.d.ts index 4d7394b4..18d8a763 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.d.ts +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.d.ts @@ -61,8 +61,10 @@ declare global { export type Exports = { handle(result: APIResult): void; getResult(): APIResult; + roundtripAPIResult(result: APIResult): APIResult; handleComplex(result: ComplexResult): void; getComplexResult(): ComplexResult; + roundtripComplexResult(result: ComplexResult): ComplexResult; } export type Imports = { } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.js index 79a2e777..7a189d19 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.Export.js @@ -4,53 +4,6 @@ // To update this file, just rebuild your project or run // `swift package bridge-js`. -/// Shared helpers for encoding associated-value enums between JS and Swift. -const __bjs_ParamType = { STRING: 1, INT32: 2, BOOL: 3, FLOAT32: 4, FLOAT64: 5 }; -function __bjs_encodeEnumParams(textEncoder, swift, parts) { - const SIZE_U8 = 1, SIZE_U32 = 4, SIZE_F32 = 4, SIZE_F64 = 8; - let totalLen = SIZE_U32; - for (const p of parts) { - switch (p.t) { - case __bjs_ParamType.STRING: { - const bytes = textEncoder.encode(p.v); - p._bytes = bytes; - totalLen += SIZE_U8 + SIZE_U32 + bytes.length; - break; - } - case __bjs_ParamType.INT32: totalLen += SIZE_U8 + SIZE_U32; break; - case __bjs_ParamType.BOOL: totalLen += SIZE_U8 + SIZE_U8; break; - case __bjs_ParamType.FLOAT32: totalLen += SIZE_U8 + SIZE_F32; break; - case __bjs_ParamType.FLOAT64: totalLen += SIZE_U8 + SIZE_F64; break; - default: throw new Error("Unsupported param type tag: " + p.t); - } - } - const buf = new Uint8Array(totalLen); - const view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength); - let off = 0; - view.setUint32(off, parts.length, true); off += SIZE_U32; - for (const p of parts) { - view.setUint8(off, p.t); off += SIZE_U8; - switch (p.t) { - case __bjs_ParamType.STRING: { - const b = p._bytes; - view.setUint32(off, b.length, true); off += SIZE_U32; - buf.set(b, off); off += b.length; - break; - } - case __bjs_ParamType.INT32: - view.setInt32(off, (p.v | 0), true); off += SIZE_U32; break; - case __bjs_ParamType.BOOL: - view.setUint8(off, p.v ? 1 : 0); off += SIZE_U8; break; - case __bjs_ParamType.FLOAT32: - view.setFloat32(off, Math.fround(p.v), true); off += SIZE_F32; break; - case __bjs_ParamType.FLOAT64: - view.setFloat64(off, p.v, true); off += SIZE_F64; break; - default: throw new Error("Unsupported param type tag: " + p.t); - } - } - const paramsId = swift.memory.retain(buf); - return { paramsId, paramsLen: buf.length, cleanup: () => { swift.memory.release(paramsId); } }; -} export const APIResult = { Tag: { Success: 0, @@ -63,61 +16,70 @@ export const APIResult = { }; const __bjs_createAPIResultHelpers = () => { - return (textEncoder, swift) => ({ + return (tmpParamInts, tmpParamF32s, tmpParamF64s, textEncoder, swift) => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { case APIResult.Tag.Success: { - const parts = [ - { t: __bjs_ParamType.STRING, v: value.param0 } - ]; - const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); - return { caseId: APIResult.Tag.Success, paramsId, paramsLen, cleanup }; + const bytes_0 = textEncoder.encode(value.param0); + const bytesId_0 = swift.memory.retain(bytes_0); + tmpParamInts.push(bytes_0.length); + tmpParamInts.push(bytesId_0); + const cleanup = () => { + swift.memory.release(bytesId_0); + }; + return { caseId: APIResult.Tag.Success, cleanup }; } case APIResult.Tag.Failure: { - const parts = [ - { t: __bjs_ParamType.INT32, v: (value.param0 | 0) } - ]; - const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); - return { caseId: APIResult.Tag.Failure, paramsId, paramsLen, cleanup }; + tmpParamInts.push((value.param0 | 0)); + const cleanup = undefined; + return { caseId: APIResult.Tag.Failure, cleanup }; } case APIResult.Tag.Flag: { - const parts = [ - { t: __bjs_ParamType.BOOL, v: value.param0 } - ]; - const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); - return { caseId: APIResult.Tag.Flag, paramsId, paramsLen, cleanup }; + tmpParamInts.push(value.param0 ? 1 : 0); + const cleanup = undefined; + return { caseId: APIResult.Tag.Flag, cleanup }; } case APIResult.Tag.Rate: { - const parts = [ - { t: __bjs_ParamType.FLOAT32, v: value.param0 } - ]; - const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); - return { caseId: APIResult.Tag.Rate, paramsId, paramsLen, cleanup }; + tmpParamF32s.push(Math.fround(value.param0)); + const cleanup = undefined; + return { caseId: APIResult.Tag.Rate, cleanup }; } case APIResult.Tag.Precise: { - const parts = [ - { t: __bjs_ParamType.FLOAT64, v: value.param0 } - ]; - const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); - return { caseId: APIResult.Tag.Precise, paramsId, paramsLen, cleanup }; + tmpParamF64s.push(value.param0); + const cleanup = undefined; + return { caseId: APIResult.Tag.Precise, cleanup }; } case APIResult.Tag.Info: { - const parts = []; - const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); - return { caseId: APIResult.Tag.Info, paramsId, paramsLen, cleanup }; + const cleanup = undefined; + return { caseId: APIResult.Tag.Info, cleanup }; } default: throw new Error("Unknown APIResult tag: " + String(enumTag)); } }, - raise: (tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetBools) => { + raise: (tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s) => { const tag = tmpRetTag | 0; switch (tag) { - case APIResult.Tag.Success: return { tag: APIResult.Tag.Success, param0: tmpRetStrings[0] }; - case APIResult.Tag.Failure: return { tag: APIResult.Tag.Failure, param0: tmpRetInts[0] }; - case APIResult.Tag.Flag: return { tag: APIResult.Tag.Flag, param0: tmpRetBools[0] }; - case APIResult.Tag.Rate: return { tag: APIResult.Tag.Rate, param0: tmpRetF32s[0] }; - case APIResult.Tag.Precise: return { tag: APIResult.Tag.Precise, param0: tmpRetF64s[0] }; + case APIResult.Tag.Success: { + const string_0 = tmpRetStrings.pop(); + return { tag: APIResult.Tag.Success, param0: string_0 }; + } + case APIResult.Tag.Failure: { + const int_0 = tmpRetInts.pop(); + return { tag: APIResult.Tag.Failure, param0: int_0 }; + } + case APIResult.Tag.Flag: { + const bool_0 = tmpRetInts.pop(); + return { tag: APIResult.Tag.Flag, param0: bool_0 }; + } + case APIResult.Tag.Rate: { + const f32_0 = tmpRetF32s.pop(); + return { tag: APIResult.Tag.Rate, param0: f32_0 }; + } + case APIResult.Tag.Precise: { + const f64_0 = tmpRetF64s.pop(); + return { tag: APIResult.Tag.Precise, param0: f64_0 }; + } case APIResult.Tag.Info: return { tag: APIResult.Tag.Info }; default: throw new Error("Unknown APIResult tag returned from Swift: " + String(tag)); } @@ -136,74 +98,119 @@ export const ComplexResult = { }; const __bjs_createComplexResultHelpers = () => { - return (textEncoder, swift) => ({ + return (tmpParamInts, tmpParamF32s, tmpParamF64s, textEncoder, swift) => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { case ComplexResult.Tag.Success: { - const parts = [ - { t: __bjs_ParamType.STRING, v: value.param0 } - ]; - const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); - return { caseId: ComplexResult.Tag.Success, paramsId, paramsLen, cleanup }; + const bytes_0 = textEncoder.encode(value.param0); + const bytesId_0 = swift.memory.retain(bytes_0); + tmpParamInts.push(bytes_0.length); + tmpParamInts.push(bytesId_0); + const cleanup = () => { + swift.memory.release(bytesId_0); + }; + return { caseId: ComplexResult.Tag.Success, cleanup }; } case ComplexResult.Tag.Error: { - const parts = [ - { t: __bjs_ParamType.STRING, v: value.param0 }, - { t: __bjs_ParamType.INT32, v: (value.param1 | 0) } - ]; - const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); - return { caseId: ComplexResult.Tag.Error, paramsId, paramsLen, cleanup }; + tmpParamInts.push((value.param1 | 0)); + const bytes_0 = textEncoder.encode(value.param0); + const bytesId_0 = swift.memory.retain(bytes_0); + tmpParamInts.push(bytes_0.length); + tmpParamInts.push(bytesId_0); + const cleanup = () => { + swift.memory.release(bytesId_0); + }; + return { caseId: ComplexResult.Tag.Error, cleanup }; } case ComplexResult.Tag.Status: { - const parts = [ - { t: __bjs_ParamType.BOOL, v: value.param0 }, - { t: __bjs_ParamType.INT32, v: (value.param1 | 0) }, - { t: __bjs_ParamType.STRING, v: value.param2 } - ]; - const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); - return { caseId: ComplexResult.Tag.Status, paramsId, paramsLen, cleanup }; + const bytes_2 = textEncoder.encode(value.param2); + const bytesId_2 = swift.memory.retain(bytes_2); + tmpParamInts.push(bytes_2.length); + tmpParamInts.push(bytesId_2); + tmpParamInts.push((value.param1 | 0)); + tmpParamInts.push(value.param0 ? 1 : 0); + const cleanup = () => { + swift.memory.release(bytesId_2); + }; + return { caseId: ComplexResult.Tag.Status, cleanup }; } case ComplexResult.Tag.Coordinates: { - const parts = [ - { t: __bjs_ParamType.FLOAT64, v: value.param0 }, - { t: __bjs_ParamType.FLOAT64, v: value.param1 }, - { t: __bjs_ParamType.FLOAT64, v: value.param2 } - ]; - const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); - return { caseId: ComplexResult.Tag.Coordinates, paramsId, paramsLen, cleanup }; + tmpParamF64s.push(value.param2); + tmpParamF64s.push(value.param1); + tmpParamF64s.push(value.param0); + const cleanup = undefined; + return { caseId: ComplexResult.Tag.Coordinates, cleanup }; } case ComplexResult.Tag.Comprehensive: { - const parts = [ - { t: __bjs_ParamType.BOOL, v: value.param0 }, - { t: __bjs_ParamType.BOOL, v: value.param1 }, - { t: __bjs_ParamType.INT32, v: (value.param2 | 0) }, - { t: __bjs_ParamType.INT32, v: (value.param3 | 0) }, - { t: __bjs_ParamType.FLOAT64, v: value.param4 }, - { t: __bjs_ParamType.FLOAT64, v: value.param5 }, - { t: __bjs_ParamType.STRING, v: value.param6 }, - { t: __bjs_ParamType.STRING, v: value.param7 }, - { t: __bjs_ParamType.STRING, v: value.param8 } - ]; - const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); - return { caseId: ComplexResult.Tag.Comprehensive, paramsId, paramsLen, cleanup }; + const bytes_8 = textEncoder.encode(value.param8); + const bytesId_8 = swift.memory.retain(bytes_8); + tmpParamInts.push(bytes_8.length); + tmpParamInts.push(bytesId_8); + const bytes_7 = textEncoder.encode(value.param7); + const bytesId_7 = swift.memory.retain(bytes_7); + tmpParamInts.push(bytes_7.length); + tmpParamInts.push(bytesId_7); + const bytes_6 = textEncoder.encode(value.param6); + const bytesId_6 = swift.memory.retain(bytes_6); + tmpParamInts.push(bytes_6.length); + tmpParamInts.push(bytesId_6); + tmpParamF64s.push(value.param5); + tmpParamF64s.push(value.param4); + tmpParamInts.push((value.param3 | 0)); + tmpParamInts.push((value.param2 | 0)); + tmpParamInts.push(value.param1 ? 1 : 0); + tmpParamInts.push(value.param0 ? 1 : 0); + const cleanup = () => { + swift.memory.release(bytesId_8); + swift.memory.release(bytesId_7); + swift.memory.release(bytesId_6); + }; + return { caseId: ComplexResult.Tag.Comprehensive, cleanup }; } case ComplexResult.Tag.Info: { - const parts = []; - const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); - return { caseId: ComplexResult.Tag.Info, paramsId, paramsLen, cleanup }; + const cleanup = undefined; + return { caseId: ComplexResult.Tag.Info, cleanup }; } default: throw new Error("Unknown ComplexResult tag: " + String(enumTag)); } }, - raise: (tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetBools) => { + raise: (tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s) => { const tag = tmpRetTag | 0; switch (tag) { - case ComplexResult.Tag.Success: return { tag: ComplexResult.Tag.Success, param0: tmpRetStrings[0] }; - case ComplexResult.Tag.Error: return { tag: ComplexResult.Tag.Error, param0: tmpRetStrings[0], param1: tmpRetInts[0] }; - case ComplexResult.Tag.Status: return { tag: ComplexResult.Tag.Status, param0: tmpRetBools[0], param1: tmpRetInts[0], param2: tmpRetStrings[0] }; - case ComplexResult.Tag.Coordinates: return { tag: ComplexResult.Tag.Coordinates, param0: tmpRetF64s[0], param1: tmpRetF64s[1], param2: tmpRetF64s[2] }; - case ComplexResult.Tag.Comprehensive: return { tag: ComplexResult.Tag.Comprehensive, param0: tmpRetBools[0], param1: tmpRetBools[1], param2: tmpRetInts[0], param3: tmpRetInts[1], param4: tmpRetF64s[0], param5: tmpRetF64s[1], param6: tmpRetStrings[0], param7: tmpRetStrings[1], param8: tmpRetStrings[2] }; + case ComplexResult.Tag.Success: { + const string_0 = tmpRetStrings.pop(); + return { tag: ComplexResult.Tag.Success, param0: string_0 }; + } + case ComplexResult.Tag.Error: { + const int_1 = tmpRetInts.pop(); + const string_0 = tmpRetStrings.pop(); + return { tag: ComplexResult.Tag.Error, param0: string_0, param1: int_1 }; + } + case ComplexResult.Tag.Status: { + const string_2 = tmpRetStrings.pop(); + const int_1 = tmpRetInts.pop(); + const bool_0 = tmpRetInts.pop(); + return { tag: ComplexResult.Tag.Status, param0: bool_0, param1: int_1, param2: string_2 }; + } + case ComplexResult.Tag.Coordinates: { + const f64_2 = tmpRetF64s.pop(); + const f64_1 = tmpRetF64s.pop(); + const f64_0 = tmpRetF64s.pop(); + return { tag: ComplexResult.Tag.Coordinates, param0: f64_0, param1: f64_1, param2: f64_2 }; + } + case ComplexResult.Tag.Comprehensive: { + const string_8 = tmpRetStrings.pop(); + const string_7 = tmpRetStrings.pop(); + const string_6 = tmpRetStrings.pop(); + const f64_5 = tmpRetF64s.pop(); + const f64_4 = tmpRetF64s.pop(); + const int_3 = tmpRetInts.pop(); + const int_2 = tmpRetInts.pop(); + const bool_1 = tmpRetInts.pop(); + const bool_0 = tmpRetInts.pop(); + return { tag: ComplexResult.Tag.Comprehensive, param0: bool_0, param1: bool_1, param2: int_2, param3: int_3, param4: f64_4, param5: f64_5, param6: string_6, param7: string_7, param8: string_8 }; + } case ComplexResult.Tag.Info: return { tag: ComplexResult.Tag.Info }; default: throw new Error("Unknown ComplexResult tag returned from Swift: " + String(tag)); } @@ -219,43 +226,64 @@ export const Result = { }; const __bjs_createResultHelpers = () => { - return (textEncoder, swift) => ({ + return (tmpParamInts, tmpParamF32s, tmpParamF64s, textEncoder, swift) => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { case Result.Tag.Success: { - const parts = [ - { t: __bjs_ParamType.STRING, v: value.param0 } - ]; - const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); - return { caseId: Result.Tag.Success, paramsId, paramsLen, cleanup }; + const bytes_0 = textEncoder.encode(value.param0); + const bytesId_0 = swift.memory.retain(bytes_0); + tmpParamInts.push(bytes_0.length); + tmpParamInts.push(bytesId_0); + const cleanup = () => { + swift.memory.release(bytesId_0); + }; + return { caseId: Result.Tag.Success, cleanup }; } case Result.Tag.Failure: { - const parts = [ - { t: __bjs_ParamType.STRING, v: value.param0 }, - { t: __bjs_ParamType.INT32, v: (value.param1 | 0) } - ]; - const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); - return { caseId: Result.Tag.Failure, paramsId, paramsLen, cleanup }; + tmpParamInts.push((value.param1 | 0)); + const bytes_0 = textEncoder.encode(value.param0); + const bytesId_0 = swift.memory.retain(bytes_0); + tmpParamInts.push(bytes_0.length); + tmpParamInts.push(bytesId_0); + const cleanup = () => { + swift.memory.release(bytesId_0); + }; + return { caseId: Result.Tag.Failure, cleanup }; } case Result.Tag.Status: { - const parts = [ - { t: __bjs_ParamType.BOOL, v: value.param0 }, - { t: __bjs_ParamType.INT32, v: (value.param1 | 0) }, - { t: __bjs_ParamType.STRING, v: value.param2 } - ]; - const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); - return { caseId: Result.Tag.Status, paramsId, paramsLen, cleanup }; + const bytes_2 = textEncoder.encode(value.param2); + const bytesId_2 = swift.memory.retain(bytes_2); + tmpParamInts.push(bytes_2.length); + tmpParamInts.push(bytesId_2); + tmpParamInts.push((value.param1 | 0)); + tmpParamInts.push(value.param0 ? 1 : 0); + const cleanup = () => { + swift.memory.release(bytesId_2); + }; + return { caseId: Result.Tag.Status, cleanup }; } default: throw new Error("Unknown Result tag: " + String(enumTag)); } }, - raise: (tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetBools) => { + raise: (tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s) => { const tag = tmpRetTag | 0; switch (tag) { - case Result.Tag.Success: return { tag: Result.Tag.Success, param0: tmpRetStrings[0] }; - case Result.Tag.Failure: return { tag: Result.Tag.Failure, param0: tmpRetStrings[0], param1: tmpRetInts[0] }; - case Result.Tag.Status: return { tag: Result.Tag.Status, param0: tmpRetBools[0], param1: tmpRetInts[0], param2: tmpRetStrings[0] }; + case Result.Tag.Success: { + const string_0 = tmpRetStrings.pop(); + return { tag: Result.Tag.Success, param0: string_0 }; + } + case Result.Tag.Failure: { + const int_1 = tmpRetInts.pop(); + const string_0 = tmpRetStrings.pop(); + return { tag: Result.Tag.Failure, param0: string_0, param1: int_1 }; + } + case Result.Tag.Status: { + const string_2 = tmpRetStrings.pop(); + const int_1 = tmpRetInts.pop(); + const bool_0 = tmpRetInts.pop(); + return { tag: Result.Tag.Status, param0: bool_0, param1: int_1, param2: string_2 }; + } default: throw new Error("Unknown Result tag returned from Swift: " + String(tag)); } } @@ -269,33 +297,46 @@ export const NetworkingResult = { }; const __bjs_createNetworkingResultHelpers = () => { - return (textEncoder, swift) => ({ + return (tmpParamInts, tmpParamF32s, tmpParamF64s, textEncoder, swift) => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { case NetworkingResult.Tag.Success: { - const parts = [ - { t: __bjs_ParamType.STRING, v: value.param0 } - ]; - const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); - return { caseId: NetworkingResult.Tag.Success, paramsId, paramsLen, cleanup }; + const bytes_0 = textEncoder.encode(value.param0); + const bytesId_0 = swift.memory.retain(bytes_0); + tmpParamInts.push(bytes_0.length); + tmpParamInts.push(bytesId_0); + const cleanup = () => { + swift.memory.release(bytesId_0); + }; + return { caseId: NetworkingResult.Tag.Success, cleanup }; } case NetworkingResult.Tag.Failure: { - const parts = [ - { t: __bjs_ParamType.STRING, v: value.param0 }, - { t: __bjs_ParamType.INT32, v: (value.param1 | 0) } - ]; - const { paramsId, paramsLen, cleanup } = __bjs_encodeEnumParams(textEncoder, swift, parts); - return { caseId: NetworkingResult.Tag.Failure, paramsId, paramsLen, cleanup }; + tmpParamInts.push((value.param1 | 0)); + const bytes_0 = textEncoder.encode(value.param0); + const bytesId_0 = swift.memory.retain(bytes_0); + tmpParamInts.push(bytes_0.length); + tmpParamInts.push(bytesId_0); + const cleanup = () => { + swift.memory.release(bytesId_0); + }; + return { caseId: NetworkingResult.Tag.Failure, cleanup }; } default: throw new Error("Unknown NetworkingResult tag: " + String(enumTag)); } }, - raise: (tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetBools) => { + raise: (tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s) => { const tag = tmpRetTag | 0; switch (tag) { - case NetworkingResult.Tag.Success: return { tag: NetworkingResult.Tag.Success, param0: tmpRetStrings[0] }; - case NetworkingResult.Tag.Failure: return { tag: NetworkingResult.Tag.Failure, param0: tmpRetStrings[0], param1: tmpRetInts[0] }; + case NetworkingResult.Tag.Success: { + const string_0 = tmpRetStrings.pop(); + return { tag: NetworkingResult.Tag.Success, param0: string_0 }; + } + case NetworkingResult.Tag.Failure: { + const int_1 = tmpRetInts.pop(); + const string_0 = tmpRetStrings.pop(); + return { tag: NetworkingResult.Tag.Failure, param0: string_0, param1: int_1 }; + } default: throw new Error("Unknown NetworkingResult tag returned from Swift: " + String(tag)); } } @@ -326,7 +367,9 @@ export async function createInstantiator(options, swift) { let tmpRetInts = []; let tmpRetF32s = []; let tmpRetF64s = []; - let tmpRetBools = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; const enumHelpers = {}; return { @@ -339,9 +382,7 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - const value = textDecoder.decode(bytes); - tmpRetString = value; - tmpRetStrings.push(value); + tmpRetString = textDecoder.decode(bytes); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -366,29 +407,31 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } - bjs["swift_js_return_tag"] = function(tag) { - tmpRetTag = tag | 0; - tmpRetString = undefined; - tmpRetStrings = []; - tmpRetInts = []; - tmpRetF32s = []; - tmpRetF64s = []; - tmpRetBools = []; + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; } - bjs["swift_js_return_int"] = function(v) { - const value = v | 0; - tmpRetInts.push(value); + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); } - bjs["swift_js_return_f32"] = function(v) { - const value = Math.fround(v); - tmpRetF32s.push(value); + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); } - bjs["swift_js_return_f64"] = function(v) { + bjs["swift_js_push_f64"] = function(v) { tmpRetF64s.push(v); } - bjs["swift_js_return_bool"] = function(v) { - const value = v !== 0; - tmpRetBools.push(value); + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); } @@ -398,16 +441,16 @@ export async function createInstantiator(options, swift) { memory = instance.exports.memory; - const APIResultHelpers = __bjs_createAPIResultHelpers()(textEncoder, swift); + const APIResultHelpers = __bjs_createAPIResultHelpers()(tmpParamInts, tmpParamF32s, tmpParamF64s, textEncoder, swift); enumHelpers.APIResult = APIResultHelpers; - const ComplexResultHelpers = __bjs_createComplexResultHelpers()(textEncoder, swift); + const ComplexResultHelpers = __bjs_createComplexResultHelpers()(tmpParamInts, tmpParamF32s, tmpParamF64s, textEncoder, swift); enumHelpers.ComplexResult = ComplexResultHelpers; - const ResultHelpers = __bjs_createResultHelpers()(textEncoder, swift); + const ResultHelpers = __bjs_createResultHelpers()(tmpParamInts, tmpParamF32s, tmpParamF64s, textEncoder, swift); enumHelpers.Result = ResultHelpers; - const NetworkingResultHelpers = __bjs_createNetworkingResultHelpers()(textEncoder, swift); + const NetworkingResultHelpers = __bjs_createNetworkingResultHelpers()(tmpParamInts, tmpParamF32s, tmpParamF64s, textEncoder, swift); enumHelpers.NetworkingResult = NetworkingResultHelpers; setException = (error) => { @@ -420,23 +463,37 @@ export async function createInstantiator(options, swift) { return { handle: function bjs_handle(result) { - const { caseId: resultCaseId, paramsId: resultParamsId, paramsLen: resultParamsLen, cleanup: resultCleanup } = enumHelpers.APIResult.lower(result); - instance.exports.bjs_handle(resultCaseId, resultParamsId, resultParamsLen); + const { caseId: resultCaseId, cleanup: resultCleanup } = enumHelpers.APIResult.lower(result); + instance.exports.bjs_handle(resultCaseId); if (resultCleanup) { resultCleanup(); } }, getResult: function bjs_getResult() { instance.exports.bjs_getResult(); - const ret = enumHelpers.APIResult.raise(tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetBools); + const ret = enumHelpers.APIResult.raise(tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s); + return ret; + }, + roundtripAPIResult: function bjs_roundtripAPIResult(result) { + const { caseId: resultCaseId, cleanup: resultCleanup } = enumHelpers.APIResult.lower(result); + instance.exports.bjs_roundtripAPIResult(resultCaseId); + const ret = enumHelpers.APIResult.raise(tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s); + if (resultCleanup) { resultCleanup(); } return ret; }, handleComplex: function bjs_handleComplex(result) { - const { caseId: resultCaseId, paramsId: resultParamsId, paramsLen: resultParamsLen, cleanup: resultCleanup } = enumHelpers.ComplexResult.lower(result); - instance.exports.bjs_handleComplex(resultCaseId, resultParamsId, resultParamsLen); + const { caseId: resultCaseId, cleanup: resultCleanup } = enumHelpers.ComplexResult.lower(result); + instance.exports.bjs_handleComplex(resultCaseId); if (resultCleanup) { resultCleanup(); } }, getComplexResult: function bjs_getComplexResult() { instance.exports.bjs_getComplexResult(); - const ret = enumHelpers.ComplexResult.raise(tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetBools); + const ret = enumHelpers.ComplexResult.raise(tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s); + return ret; + }, + roundtripComplexResult: function bjs_roundtripComplexResult(result) { + const { caseId: resultCaseId, cleanup: resultCleanup } = enumHelpers.ComplexResult.lower(result); + instance.exports.bjs_roundtripComplexResult(resultCaseId); + const ret = enumHelpers.ComplexResult.raise(tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s); + if (resultCleanup) { resultCleanup(); } return ret; }, }; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.Export.js index 7b7a3003..acb5877a 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.Export.js @@ -43,7 +43,9 @@ export async function createInstantiator(options, swift) { let tmpRetInts = []; let tmpRetF32s = []; let tmpRetF64s = []; - let tmpRetBools = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; return { @@ -56,9 +58,7 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - const value = textDecoder.decode(bytes); - tmpRetString = value; - tmpRetStrings.push(value); + tmpRetString = textDecoder.decode(bytes); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -83,29 +83,31 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } - bjs["swift_js_return_tag"] = function(tag) { - tmpRetTag = tag | 0; - tmpRetString = undefined; - tmpRetStrings = []; - tmpRetInts = []; - tmpRetF32s = []; - tmpRetF64s = []; - tmpRetBools = []; + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; } - bjs["swift_js_return_int"] = function(v) { - const value = v | 0; - tmpRetInts.push(value); + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); } - bjs["swift_js_return_f32"] = function(v) { - const value = Math.fround(v); - tmpRetF32s.push(value); + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); } - bjs["swift_js_return_f64"] = function(v) { + bjs["swift_js_push_f64"] = function(v) { tmpRetF64s.push(v); } - bjs["swift_js_return_bool"] = function(v) { - const value = v !== 0; - tmpRetBools.push(value); + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.js index b6f5ff98..9db3b5f4 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Export.js @@ -65,7 +65,9 @@ export async function createInstantiator(options, swift) { let tmpRetInts = []; let tmpRetF32s = []; let tmpRetF64s = []; - let tmpRetBools = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; return { @@ -78,9 +80,7 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - const value = textDecoder.decode(bytes); - tmpRetString = value; - tmpRetStrings.push(value); + tmpRetString = textDecoder.decode(bytes); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -105,29 +105,31 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } - bjs["swift_js_return_tag"] = function(tag) { - tmpRetTag = tag | 0; - tmpRetString = undefined; - tmpRetStrings = []; - tmpRetInts = []; - tmpRetF32s = []; - tmpRetF64s = []; - tmpRetBools = []; + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; } - bjs["swift_js_return_int"] = function(v) { - const value = v | 0; - tmpRetInts.push(value); + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); } - bjs["swift_js_return_f32"] = function(v) { - const value = Math.fround(v); - tmpRetF32s.push(value); + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); } - bjs["swift_js_return_f64"] = function(v) { + bjs["swift_js_push_f64"] = function(v) { tmpRetF64s.push(v); } - bjs["swift_js_return_bool"] = function(v) { - const value = v !== 0; - tmpRetBools.push(value); + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); } // Wrapper functions for module: TestModule if (!importObject["TestModule"]) { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.Export.js index 0d85607a..8419a835 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.Export.js @@ -94,7 +94,9 @@ export async function createInstantiator(options, swift) { let tmpRetInts = []; let tmpRetF32s = []; let tmpRetF64s = []; - let tmpRetBools = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; return { @@ -107,9 +109,7 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - const value = textDecoder.decode(bytes); - tmpRetString = value; - tmpRetStrings.push(value); + tmpRetString = textDecoder.decode(bytes); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -134,29 +134,31 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } - bjs["swift_js_return_tag"] = function(tag) { - tmpRetTag = tag | 0; - tmpRetString = undefined; - tmpRetStrings = []; - tmpRetInts = []; - tmpRetF32s = []; - tmpRetF64s = []; - tmpRetBools = []; + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; } - bjs["swift_js_return_int"] = function(v) { - const value = v | 0; - tmpRetInts.push(value); + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); } - bjs["swift_js_return_f32"] = function(v) { - const value = Math.fround(v); - tmpRetF32s.push(value); + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); } - bjs["swift_js_return_f64"] = function(v) { + bjs["swift_js_push_f64"] = function(v) { tmpRetF64s.push(v); } - bjs["swift_js_return_bool"] = function(v) { - const value = v !== 0; - tmpRetBools.push(value); + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Interface.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Interface.Import.js index 18fd6be1..4b6e9fc8 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Interface.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Interface.Import.js @@ -18,7 +18,9 @@ export async function createInstantiator(options, swift) { let tmpRetInts = []; let tmpRetF32s = []; let tmpRetF64s = []; - let tmpRetBools = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; return { @@ -31,9 +33,7 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - const value = textDecoder.decode(bytes); - tmpRetString = value; - tmpRetStrings.push(value); + tmpRetString = textDecoder.decode(bytes); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -58,29 +58,31 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } - bjs["swift_js_return_tag"] = function(tag) { - tmpRetTag = tag | 0; - tmpRetString = undefined; - tmpRetStrings = []; - tmpRetInts = []; - tmpRetF32s = []; - tmpRetF64s = []; - tmpRetBools = []; + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; } - bjs["swift_js_return_int"] = function(v) { - const value = v | 0; - tmpRetInts.push(value); + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); } - bjs["swift_js_return_f32"] = function(v) { - const value = Math.fround(v); - tmpRetF32s.push(value); + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); } - bjs["swift_js_return_f64"] = function(v) { + bjs["swift_js_push_f64"] = function(v) { tmpRetF64s.push(v); } - bjs["swift_js_return_bool"] = function(v) { - const value = v !== 0; - tmpRetBools.push(value); + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/InvalidPropertyNames.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/InvalidPropertyNames.Import.js index 834f1a79..318afa1d 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/InvalidPropertyNames.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/InvalidPropertyNames.Import.js @@ -18,7 +18,9 @@ export async function createInstantiator(options, swift) { let tmpRetInts = []; let tmpRetF32s = []; let tmpRetF64s = []; - let tmpRetBools = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; return { @@ -31,9 +33,7 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - const value = textDecoder.decode(bytes); - tmpRetString = value; - tmpRetStrings.push(value); + tmpRetString = textDecoder.decode(bytes); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -58,29 +58,31 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } - bjs["swift_js_return_tag"] = function(tag) { - tmpRetTag = tag | 0; - tmpRetString = undefined; - tmpRetStrings = []; - tmpRetInts = []; - tmpRetF32s = []; - tmpRetF64s = []; - tmpRetBools = []; + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; } - bjs["swift_js_return_int"] = function(v) { - const value = v | 0; - tmpRetInts.push(value); + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); } - bjs["swift_js_return_f32"] = function(v) { - const value = Math.fround(v); - tmpRetF32s.push(value); + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); } - bjs["swift_js_return_f64"] = function(v) { + bjs["swift_js_push_f64"] = function(v) { tmpRetF64s.push(v); } - bjs["swift_js_return_bool"] = function(v) { - const value = v !== 0; - tmpRetBools.push(value); + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MultipleImportedTypes.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MultipleImportedTypes.Import.js index d4e582ed..8fe1102c 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MultipleImportedTypes.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MultipleImportedTypes.Import.js @@ -18,7 +18,9 @@ export async function createInstantiator(options, swift) { let tmpRetInts = []; let tmpRetF32s = []; let tmpRetF64s = []; - let tmpRetBools = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; return { @@ -31,9 +33,7 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - const value = textDecoder.decode(bytes); - tmpRetString = value; - tmpRetStrings.push(value); + tmpRetString = textDecoder.decode(bytes); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -58,29 +58,31 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } - bjs["swift_js_return_tag"] = function(tag) { - tmpRetTag = tag | 0; - tmpRetString = undefined; - tmpRetStrings = []; - tmpRetInts = []; - tmpRetF32s = []; - tmpRetF64s = []; - tmpRetBools = []; + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; } - bjs["swift_js_return_int"] = function(v) { - const value = v | 0; - tmpRetInts.push(value); + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); } - bjs["swift_js_return_f32"] = function(v) { - const value = Math.fround(v); - tmpRetF32s.push(value); + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); } - bjs["swift_js_return_f64"] = function(v) { + bjs["swift_js_push_f64"] = function(v) { tmpRetF64s.push(v); } - bjs["swift_js_return_bool"] = function(v) { - const value = v !== 0; - tmpRetBools.push(value); + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Export.js index 519058fa..ca477bdf 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Export.js @@ -18,7 +18,9 @@ export async function createInstantiator(options, swift) { let tmpRetInts = []; let tmpRetF32s = []; let tmpRetF64s = []; - let tmpRetBools = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; return { @@ -31,9 +33,7 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - const value = textDecoder.decode(bytes); - tmpRetString = value; - tmpRetStrings.push(value); + tmpRetString = textDecoder.decode(bytes); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -58,29 +58,31 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } - bjs["swift_js_return_tag"] = function(tag) { - tmpRetTag = tag | 0; - tmpRetString = undefined; - tmpRetStrings = []; - tmpRetInts = []; - tmpRetF32s = []; - tmpRetF64s = []; - tmpRetBools = []; + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; } - bjs["swift_js_return_int"] = function(v) { - const value = v | 0; - tmpRetInts.push(value); + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); } - bjs["swift_js_return_f32"] = function(v) { - const value = Math.fround(v); - tmpRetF32s.push(value); + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); } - bjs["swift_js_return_f64"] = function(v) { + bjs["swift_js_push_f64"] = function(v) { tmpRetF64s.push(v); } - bjs["swift_js_return_bool"] = function(v) { - const value = v !== 0; - tmpRetBools.push(value); + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); } // Wrapper functions for module: TestModule if (!importObject["TestModule"]) { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Export.js index e10084e5..c56a487d 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Export.js @@ -18,7 +18,9 @@ export async function createInstantiator(options, swift) { let tmpRetInts = []; let tmpRetF32s = []; let tmpRetF64s = []; - let tmpRetBools = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; return { @@ -31,9 +33,7 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - const value = textDecoder.decode(bytes); - tmpRetString = value; - tmpRetStrings.push(value); + tmpRetString = textDecoder.decode(bytes); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -58,29 +58,31 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } - bjs["swift_js_return_tag"] = function(tag) { - tmpRetTag = tag | 0; - tmpRetString = undefined; - tmpRetStrings = []; - tmpRetInts = []; - tmpRetF32s = []; - tmpRetF64s = []; - tmpRetBools = []; + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; } - bjs["swift_js_return_int"] = function(v) { - const value = v | 0; - tmpRetInts.push(value); + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); } - bjs["swift_js_return_f32"] = function(v) { - const value = Math.fround(v); - tmpRetF32s.push(value); + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); } - bjs["swift_js_return_f64"] = function(v) { + bjs["swift_js_push_f64"] = function(v) { tmpRetF64s.push(v); } - bjs["swift_js_return_bool"] = function(v) { - const value = v !== 0; - tmpRetBools.push(value); + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Import.js index f6d572b1..fb10cc4e 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Import.js @@ -18,7 +18,9 @@ export async function createInstantiator(options, swift) { let tmpRetInts = []; let tmpRetF32s = []; let tmpRetF64s = []; - let tmpRetBools = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; return { @@ -31,9 +33,7 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - const value = textDecoder.decode(bytes); - tmpRetString = value; - tmpRetStrings.push(value); + tmpRetString = textDecoder.decode(bytes); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -58,29 +58,31 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } - bjs["swift_js_return_tag"] = function(tag) { - tmpRetTag = tag | 0; - tmpRetString = undefined; - tmpRetStrings = []; - tmpRetInts = []; - tmpRetF32s = []; - tmpRetF64s = []; - tmpRetBools = []; + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; } - bjs["swift_js_return_int"] = function(v) { - const value = v | 0; - tmpRetInts.push(value); + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); } - bjs["swift_js_return_f32"] = function(v) { - const value = Math.fround(v); - tmpRetF32s.push(value); + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); } - bjs["swift_js_return_f64"] = function(v) { + bjs["swift_js_push_f64"] = function(v) { tmpRetF64s.push(v); } - bjs["swift_js_return_bool"] = function(v) { - const value = v !== 0; - tmpRetBools.push(value); + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Export.js index 8fe8c446..d8f0949d 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Export.js @@ -18,7 +18,9 @@ export async function createInstantiator(options, swift) { let tmpRetInts = []; let tmpRetF32s = []; let tmpRetF64s = []; - let tmpRetBools = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; return { @@ -31,9 +33,7 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - const value = textDecoder.decode(bytes); - tmpRetString = value; - tmpRetStrings.push(value); + tmpRetString = textDecoder.decode(bytes); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -58,29 +58,31 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } - bjs["swift_js_return_tag"] = function(tag) { - tmpRetTag = tag | 0; - tmpRetString = undefined; - tmpRetStrings = []; - tmpRetInts = []; - tmpRetF32s = []; - tmpRetF64s = []; - tmpRetBools = []; + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; } - bjs["swift_js_return_int"] = function(v) { - const value = v | 0; - tmpRetInts.push(value); + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); } - bjs["swift_js_return_f32"] = function(v) { - const value = Math.fround(v); - tmpRetF32s.push(value); + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); } - bjs["swift_js_return_f64"] = function(v) { + bjs["swift_js_push_f64"] = function(v) { tmpRetF64s.push(v); } - bjs["swift_js_return_bool"] = function(v) { - const value = v !== 0; - tmpRetBools.push(value); + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Import.js index 6dbbbac5..d839dd03 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Import.js @@ -18,7 +18,9 @@ export async function createInstantiator(options, swift) { let tmpRetInts = []; let tmpRetF32s = []; let tmpRetF64s = []; - let tmpRetBools = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; return { @@ -31,9 +33,7 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - const value = textDecoder.decode(bytes); - tmpRetString = value; - tmpRetStrings.push(value); + tmpRetString = textDecoder.decode(bytes); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -58,29 +58,31 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } - bjs["swift_js_return_tag"] = function(tag) { - tmpRetTag = tag | 0; - tmpRetString = undefined; - tmpRetStrings = []; - tmpRetInts = []; - tmpRetF32s = []; - tmpRetF64s = []; - tmpRetBools = []; + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; } - bjs["swift_js_return_int"] = function(v) { - const value = v | 0; - tmpRetInts.push(value); + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); } - bjs["swift_js_return_f32"] = function(v) { - const value = Math.fround(v); - tmpRetF32s.push(value); + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); } - bjs["swift_js_return_f64"] = function(v) { + bjs["swift_js_push_f64"] = function(v) { tmpRetF64s.push(v); } - bjs["swift_js_return_bool"] = function(v) { - const value = v !== 0; - tmpRetBools.push(value); + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PropertyTypes.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PropertyTypes.Export.js index f273ef10..3b91c039 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PropertyTypes.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PropertyTypes.Export.js @@ -18,7 +18,9 @@ export async function createInstantiator(options, swift) { let tmpRetInts = []; let tmpRetF32s = []; let tmpRetF64s = []; - let tmpRetBools = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; return { @@ -31,9 +33,7 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - const value = textDecoder.decode(bytes); - tmpRetString = value; - tmpRetStrings.push(value); + tmpRetString = textDecoder.decode(bytes); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -58,29 +58,31 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } - bjs["swift_js_return_tag"] = function(tag) { - tmpRetTag = tag | 0; - tmpRetString = undefined; - tmpRetStrings = []; - tmpRetInts = []; - tmpRetF32s = []; - tmpRetF64s = []; - tmpRetBools = []; + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; } - bjs["swift_js_return_int"] = function(v) { - const value = v | 0; - tmpRetInts.push(value); + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); } - bjs["swift_js_return_f32"] = function(v) { - const value = Math.fround(v); - tmpRetF32s.push(value); + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); } - bjs["swift_js_return_f64"] = function(v) { + bjs["swift_js_push_f64"] = function(v) { tmpRetF64s.push(v); } - bjs["swift_js_return_bool"] = function(v) { - const value = v !== 0; - tmpRetBools.push(value); + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); } // Wrapper functions for module: TestModule if (!importObject["TestModule"]) { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Export.js index 835eb802..78b1dd66 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Export.js @@ -18,7 +18,9 @@ export async function createInstantiator(options, swift) { let tmpRetInts = []; let tmpRetF32s = []; let tmpRetF64s = []; - let tmpRetBools = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; return { @@ -31,9 +33,7 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - const value = textDecoder.decode(bytes); - tmpRetString = value; - tmpRetStrings.push(value); + tmpRetString = textDecoder.decode(bytes); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -58,29 +58,31 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } - bjs["swift_js_return_tag"] = function(tag) { - tmpRetTag = tag | 0; - tmpRetString = undefined; - tmpRetStrings = []; - tmpRetInts = []; - tmpRetF32s = []; - tmpRetF64s = []; - tmpRetBools = []; + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; } - bjs["swift_js_return_int"] = function(v) { - const value = v | 0; - tmpRetInts.push(value); + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); } - bjs["swift_js_return_f32"] = function(v) { - const value = Math.fround(v); - tmpRetF32s.push(value); + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); } - bjs["swift_js_return_f64"] = function(v) { + bjs["swift_js_push_f64"] = function(v) { tmpRetF64s.push(v); } - bjs["swift_js_return_bool"] = function(v) { - const value = v !== 0; - tmpRetBools.push(value); + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Import.js index 9e28b776..70f2a3d5 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Import.js @@ -18,7 +18,9 @@ export async function createInstantiator(options, swift) { let tmpRetInts = []; let tmpRetF32s = []; let tmpRetF64s = []; - let tmpRetBools = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; return { @@ -31,9 +33,7 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - const value = textDecoder.decode(bytes); - tmpRetString = value; - tmpRetStrings.push(value); + tmpRetString = textDecoder.decode(bytes); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -58,29 +58,31 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } - bjs["swift_js_return_tag"] = function(tag) { - tmpRetTag = tag | 0; - tmpRetString = undefined; - tmpRetStrings = []; - tmpRetInts = []; - tmpRetF32s = []; - tmpRetF64s = []; - tmpRetBools = []; + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; } - bjs["swift_js_return_int"] = function(v) { - const value = v | 0; - tmpRetInts.push(value); + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); } - bjs["swift_js_return_f32"] = function(v) { - const value = Math.fround(v); - tmpRetF32s.push(value); + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); } - bjs["swift_js_return_f64"] = function(v) { + bjs["swift_js_push_f64"] = function(v) { tmpRetF64s.push(v); } - bjs["swift_js_return_bool"] = function(v) { - const value = v !== 0; - tmpRetBools.push(value); + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Export.js index 43d2e4fb..9b7359e9 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Export.js @@ -18,7 +18,9 @@ export async function createInstantiator(options, swift) { let tmpRetInts = []; let tmpRetF32s = []; let tmpRetF64s = []; - let tmpRetBools = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; return { @@ -31,9 +33,7 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - const value = textDecoder.decode(bytes); - tmpRetString = value; - tmpRetStrings.push(value); + tmpRetString = textDecoder.decode(bytes); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -58,29 +58,31 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } - bjs["swift_js_return_tag"] = function(tag) { - tmpRetTag = tag | 0; - tmpRetString = undefined; - tmpRetStrings = []; - tmpRetInts = []; - tmpRetF32s = []; - tmpRetF64s = []; - tmpRetBools = []; + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; } - bjs["swift_js_return_int"] = function(v) { - const value = v | 0; - tmpRetInts.push(value); + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); } - bjs["swift_js_return_f32"] = function(v) { - const value = Math.fround(v); - tmpRetF32s.push(value); + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); } - bjs["swift_js_return_f64"] = function(v) { + bjs["swift_js_push_f64"] = function(v) { tmpRetF64s.push(v); } - bjs["swift_js_return_bool"] = function(v) { - const value = v !== 0; - tmpRetBools.push(value); + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Import.js index 0c9eccf8..315e6bf8 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Import.js @@ -18,7 +18,9 @@ export async function createInstantiator(options, swift) { let tmpRetInts = []; let tmpRetF32s = []; let tmpRetF64s = []; - let tmpRetBools = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; return { @@ -31,9 +33,7 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - const value = textDecoder.decode(bytes); - tmpRetString = value; - tmpRetStrings.push(value); + tmpRetString = textDecoder.decode(bytes); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -58,29 +58,31 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } - bjs["swift_js_return_tag"] = function(tag) { - tmpRetTag = tag | 0; - tmpRetString = undefined; - tmpRetStrings = []; - tmpRetInts = []; - tmpRetF32s = []; - tmpRetF64s = []; - tmpRetBools = []; + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; } - bjs["swift_js_return_int"] = function(v) { - const value = v | 0; - tmpRetInts.push(value); + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); } - bjs["swift_js_return_f32"] = function(v) { - const value = Math.fround(v); - tmpRetF32s.push(value); + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); } - bjs["swift_js_return_f64"] = function(v) { + bjs["swift_js_push_f64"] = function(v) { tmpRetF64s.push(v); } - bjs["swift_js_return_bool"] = function(v) { - const value = v !== 0; - tmpRetBools.push(value); + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.Export.js index 370c6229..ed64ec10 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.Export.js @@ -18,7 +18,9 @@ export async function createInstantiator(options, swift) { let tmpRetInts = []; let tmpRetF32s = []; let tmpRetF64s = []; - let tmpRetBools = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; return { @@ -31,9 +33,7 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - const value = textDecoder.decode(bytes); - tmpRetString = value; - tmpRetStrings.push(value); + tmpRetString = textDecoder.decode(bytes); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -58,29 +58,31 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } - bjs["swift_js_return_tag"] = function(tag) { - tmpRetTag = tag | 0; - tmpRetString = undefined; - tmpRetStrings = []; - tmpRetInts = []; - tmpRetF32s = []; - tmpRetF64s = []; - tmpRetBools = []; + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; } - bjs["swift_js_return_int"] = function(v) { - const value = v | 0; - tmpRetInts.push(value); + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); } - bjs["swift_js_return_f32"] = function(v) { - const value = Math.fround(v); - tmpRetF32s.push(value); + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); } - bjs["swift_js_return_f64"] = function(v) { + bjs["swift_js_push_f64"] = function(v) { tmpRetF64s.push(v); } - bjs["swift_js_return_bool"] = function(v) { - const value = v !== 0; - tmpRetBools.push(value); + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); } // Wrapper functions for module: TestModule if (!importObject["TestModule"]) { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TS2SkeletonLike.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TS2SkeletonLike.Import.js index cb20a60b..812a53cd 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TS2SkeletonLike.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TS2SkeletonLike.Import.js @@ -18,7 +18,9 @@ export async function createInstantiator(options, swift) { let tmpRetInts = []; let tmpRetF32s = []; let tmpRetF64s = []; - let tmpRetBools = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; return { @@ -31,9 +33,7 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - const value = textDecoder.decode(bytes); - tmpRetString = value; - tmpRetStrings.push(value); + tmpRetString = textDecoder.decode(bytes); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -58,29 +58,31 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } - bjs["swift_js_return_tag"] = function(tag) { - tmpRetTag = tag | 0; - tmpRetString = undefined; - tmpRetStrings = []; - tmpRetInts = []; - tmpRetF32s = []; - tmpRetF64s = []; - tmpRetBools = []; + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; } - bjs["swift_js_return_int"] = function(v) { - const value = v | 0; - tmpRetInts.push(value); + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); } - bjs["swift_js_return_f32"] = function(v) { - const value = Math.fround(v); - tmpRetF32s.push(value); + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); } - bjs["swift_js_return_f64"] = function(v) { + bjs["swift_js_push_f64"] = function(v) { tmpRetF64s.push(v); } - bjs["swift_js_return_bool"] = function(v) { - const value = v !== 0; - tmpRetBools.push(value); + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Throws.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Throws.Export.js index 3836d437..15b6eaa7 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Throws.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Throws.Export.js @@ -18,7 +18,9 @@ export async function createInstantiator(options, swift) { let tmpRetInts = []; let tmpRetF32s = []; let tmpRetF64s = []; - let tmpRetBools = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; return { @@ -31,9 +33,7 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - const value = textDecoder.decode(bytes); - tmpRetString = value; - tmpRetStrings.push(value); + tmpRetString = textDecoder.decode(bytes); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -58,29 +58,31 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } - bjs["swift_js_return_tag"] = function(tag) { - tmpRetTag = tag | 0; - tmpRetString = undefined; - tmpRetStrings = []; - tmpRetInts = []; - tmpRetF32s = []; - tmpRetF64s = []; - tmpRetBools = []; + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; } - bjs["swift_js_return_int"] = function(v) { - const value = v | 0; - tmpRetInts.push(value); + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); } - bjs["swift_js_return_f32"] = function(v) { - const value = Math.fround(v); - tmpRetF32s.push(value); + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); } - bjs["swift_js_return_f64"] = function(v) { + bjs["swift_js_push_f64"] = function(v) { tmpRetF64s.push(v); } - bjs["swift_js_return_bool"] = function(v) { - const value = v !== 0; - tmpRetBools.push(value); + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeAlias.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeAlias.Import.js index 578ec5d6..7f285863 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeAlias.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeAlias.Import.js @@ -18,7 +18,9 @@ export async function createInstantiator(options, swift) { let tmpRetInts = []; let tmpRetF32s = []; let tmpRetF64s = []; - let tmpRetBools = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; return { @@ -31,9 +33,7 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - const value = textDecoder.decode(bytes); - tmpRetString = value; - tmpRetStrings.push(value); + tmpRetString = textDecoder.decode(bytes); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -58,29 +58,31 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } - bjs["swift_js_return_tag"] = function(tag) { - tmpRetTag = tag | 0; - tmpRetString = undefined; - tmpRetStrings = []; - tmpRetInts = []; - tmpRetF32s = []; - tmpRetF64s = []; - tmpRetBools = []; + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; } - bjs["swift_js_return_int"] = function(v) { - const value = v | 0; - tmpRetInts.push(value); + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); } - bjs["swift_js_return_f32"] = function(v) { - const value = Math.fround(v); - tmpRetF32s.push(value); + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); } - bjs["swift_js_return_f64"] = function(v) { + bjs["swift_js_push_f64"] = function(v) { tmpRetF64s.push(v); } - bjs["swift_js_return_bool"] = function(v) { - const value = v !== 0; - tmpRetBools.push(value); + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeScriptClass.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeScriptClass.Import.js index bd6a6907..47828d7a 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeScriptClass.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeScriptClass.Import.js @@ -18,7 +18,9 @@ export async function createInstantiator(options, swift) { let tmpRetInts = []; let tmpRetF32s = []; let tmpRetF64s = []; - let tmpRetBools = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; return { @@ -31,9 +33,7 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - const value = textDecoder.decode(bytes); - tmpRetString = value; - tmpRetStrings.push(value); + tmpRetString = textDecoder.decode(bytes); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -58,29 +58,31 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } - bjs["swift_js_return_tag"] = function(tag) { - tmpRetTag = tag | 0; - tmpRetString = undefined; - tmpRetStrings = []; - tmpRetInts = []; - tmpRetF32s = []; - tmpRetF64s = []; - tmpRetBools = []; + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; } - bjs["swift_js_return_int"] = function(v) { - const value = v | 0; - tmpRetInts.push(value); + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); } - bjs["swift_js_return_f32"] = function(v) { - const value = Math.fround(v); - tmpRetF32s.push(value); + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); } - bjs["swift_js_return_f64"] = function(v) { + bjs["swift_js_push_f64"] = function(v) { tmpRetF64s.push(v); } - bjs["swift_js_return_bool"] = function(v) { - const value = v !== 0; - tmpRetBools.push(value); + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Export.js index 91f069dd..ef2ef687 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Export.js @@ -18,7 +18,9 @@ export async function createInstantiator(options, swift) { let tmpRetInts = []; let tmpRetF32s = []; let tmpRetF64s = []; - let tmpRetBools = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; return { @@ -31,9 +33,7 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - const value = textDecoder.decode(bytes); - tmpRetString = value; - tmpRetStrings.push(value); + tmpRetString = textDecoder.decode(bytes); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -58,29 +58,31 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } - bjs["swift_js_return_tag"] = function(tag) { - tmpRetTag = tag | 0; - tmpRetString = undefined; - tmpRetStrings = []; - tmpRetInts = []; - tmpRetF32s = []; - tmpRetF64s = []; - tmpRetBools = []; + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; } - bjs["swift_js_return_int"] = function(v) { - const value = v | 0; - tmpRetInts.push(value); + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); } - bjs["swift_js_return_f32"] = function(v) { - const value = Math.fround(v); - tmpRetF32s.push(value); + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); } - bjs["swift_js_return_f64"] = function(v) { + bjs["swift_js_push_f64"] = function(v) { tmpRetF64s.push(v); } - bjs["swift_js_return_bool"] = function(v) { - const value = v !== 0; - tmpRetBools.push(value); + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Import.js index 5eab9f77..c102415e 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Import.js @@ -18,7 +18,9 @@ export async function createInstantiator(options, swift) { let tmpRetInts = []; let tmpRetF32s = []; let tmpRetF64s = []; - let tmpRetBools = []; + let tmpParamInts = []; + let tmpParamF32s = []; + let tmpParamF64s = []; return { @@ -31,9 +33,7 @@ export async function createInstantiator(options, swift) { const imports = options.getImports(importsContext); bjs["swift_js_return_string"] = function(ptr, len) { const bytes = new Uint8Array(memory.buffer, ptr, len); - const value = textDecoder.decode(bytes); - tmpRetString = value; - tmpRetStrings.push(value); + tmpRetString = textDecoder.decode(bytes); } bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { const source = swift.memory.getObject(sourceId); @@ -58,29 +58,31 @@ export async function createInstantiator(options, swift) { bjs["swift_js_release"] = function(id) { swift.memory.release(id); } - bjs["swift_js_return_tag"] = function(tag) { - tmpRetTag = tag | 0; - tmpRetString = undefined; - tmpRetStrings = []; - tmpRetInts = []; - tmpRetF32s = []; - tmpRetF64s = []; - tmpRetBools = []; + bjs["swift_js_push_tag"] = function(tag) { + tmpRetTag = tag; } - bjs["swift_js_return_int"] = function(v) { - const value = v | 0; - tmpRetInts.push(value); + bjs["swift_js_push_int"] = function(v) { + tmpRetInts.push(v | 0); } - bjs["swift_js_return_f32"] = function(v) { - const value = Math.fround(v); - tmpRetF32s.push(value); + bjs["swift_js_push_f32"] = function(v) { + tmpRetF32s.push(Math.fround(v)); } - bjs["swift_js_return_f64"] = function(v) { + bjs["swift_js_push_f64"] = function(v) { tmpRetF64s.push(v); } - bjs["swift_js_return_bool"] = function(v) { - const value = v !== 0; - tmpRetBools.push(value); + bjs["swift_js_push_string"] = function(ptr, len) { + const bytes = new Uint8Array(memory.buffer, ptr, len); + const value = textDecoder.decode(bytes); + tmpRetStrings.push(value); + } + bjs["swift_js_pop_param_int32"] = function() { + return tmpParamInts.pop(); + } + bjs["swift_js_pop_param_f32"] = function() { + return tmpParamF32s.pop(); + } + bjs["swift_js_pop_param_f64"] = function() { + return tmpParamF64s.pop(); } const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumAssociatedValue.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumAssociatedValue.json index 1eeca1b8..37f4b61f 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumAssociatedValue.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumAssociatedValue.json @@ -390,6 +390,30 @@ } } }, + { + "abiName" : "bjs_roundtripAPIResult", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "roundtripAPIResult", + "parameters" : [ + { + "label" : "result", + "name" : "result", + "type" : { + "associatedValueEnum" : { + "_0" : "APIResult" + } + } + } + ], + "returnType" : { + "associatedValueEnum" : { + "_0" : "APIResult" + } + } + }, { "abiName" : "bjs_handleComplex", "effects" : { @@ -429,6 +453,30 @@ "_0" : "ComplexResult" } } + }, + { + "abiName" : "bjs_roundtripComplexResult", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "roundtripComplexResult", + "parameters" : [ + { + "label" : "_", + "name" : "result", + "type" : { + "associatedValueEnum" : { + "_0" : "ComplexResult" + } + } + } + ], + "returnType" : { + "associatedValueEnum" : { + "_0" : "ComplexResult" + } + } } ], "moduleName" : "TestModule" diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumAssociatedValue.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumAssociatedValue.swift index fa3cef9e..410c569d 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumAssociatedValue.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/EnumAssociatedValue.swift @@ -7,309 +7,202 @@ @_spi(BridgeJS) import JavaScriptKit private extension APIResult { - static func bridgeJSLiftParameter(_ caseId: Int32, _ paramsId: Int32, _ paramsLen: Int32) -> APIResult { - let params: [UInt8] = .init(unsafeUninitializedCapacity: Int(paramsLen)) { buf, initializedCount in - _swift_js_init_memory(paramsId, buf.baseAddress.unsafelyUnwrapped) - initializedCount = Int(paramsLen) - } - return params.withUnsafeBytes { raw in - var reader = _BJSBinaryReader(raw: raw) - switch caseId { - case 0: - reader.readParamCount(expected: 1) - reader.expectTag(.string) - let param0 = reader.readString() - return .success(param0) - case 1: - reader.readParamCount(expected: 1) - reader.expectTag(.int32) - let param0 = Int(reader.readInt32()) - return .failure(param0) - case 2: - reader.readParamCount(expected: 1) - reader.expectTag(.bool) - let param0 = Int32(reader.readUInt8()) != 0 - return .flag(param0) - case 3: - reader.readParamCount(expected: 1) - reader.expectTag(.float32) - let param0 = reader.readFloat32() - return .rate(param0) - case 4: - reader.readParamCount(expected: 1) - reader.expectTag(.float64) - let param0 = reader.readFloat64() - return .precise(param0) - case 5: - return .info - default: - fatalError("Unknown APIResult case ID: \(caseId)") - } + static func bridgeJSLiftParameter(_ caseId: Int32) -> APIResult { + switch caseId { + case 0: + return .success(String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32())) + case 1: + return .failure(Int.bridgeJSLiftParameter(_swift_js_pop_param_int32())) + case 2: + return .flag(Bool.bridgeJSLiftParameter(_swift_js_pop_param_int32())) + case 3: + return .rate(Float.bridgeJSLiftParameter(_swift_js_pop_param_f32())) + case 4: + return .precise(Double.bridgeJSLiftParameter(_swift_js_pop_param_f64())) + case 5: + return .info + default: + fatalError("Unknown APIResult case ID: \(caseId)") } } func bridgeJSLowerReturn() { switch self { case .success(let param0): - _swift_js_return_tag(Int32(0)) + _swift_js_push_tag(Int32(0)) var __bjs_param0 = param0 __bjs_param0.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) } case .failure(let param0): - _swift_js_return_tag(Int32(1)) - _swift_js_return_int(Int32(param0)) + _swift_js_push_tag(Int32(1)) + _swift_js_push_int(Int32(param0)) case .flag(let param0): - _swift_js_return_tag(Int32(2)) - _swift_js_return_bool(param0 ? 1 : 0) + _swift_js_push_tag(Int32(2)) + _swift_js_push_int(param0 ? 1 : 0) case .rate(let param0): - _swift_js_return_tag(Int32(3)) - _swift_js_return_f32(param0) + _swift_js_push_tag(Int32(3)) + _swift_js_push_f32(param0) case .precise(let param0): - _swift_js_return_tag(Int32(4)) - _swift_js_return_f64(param0) + _swift_js_push_tag(Int32(4)) + _swift_js_push_f64(param0) case .info: - _swift_js_return_tag(Int32(5)) + _swift_js_push_tag(Int32(5)) } } } private extension ComplexResult { - static func bridgeJSLiftParameter(_ caseId: Int32, _ paramsId: Int32, _ paramsLen: Int32) -> ComplexResult { - let params: [UInt8] = .init(unsafeUninitializedCapacity: Int(paramsLen)) { buf, initializedCount in - _swift_js_init_memory(paramsId, buf.baseAddress.unsafelyUnwrapped) - initializedCount = Int(paramsLen) - } - return params.withUnsafeBytes { raw in - var reader = _BJSBinaryReader(raw: raw) - switch caseId { - case 0: - reader.readParamCount(expected: 1) - reader.expectTag(.string) - let param0 = reader.readString() - return .success(param0) - case 1: - reader.readParamCount(expected: 2) - reader.expectTag(.string) - let param0 = reader.readString() - reader.expectTag(.int32) - let param1 = Int(reader.readInt32()) - return .error(param0, param1) - case 2: - reader.readParamCount(expected: 3) - reader.expectTag(.bool) - let param0 = Int32(reader.readUInt8()) != 0 - reader.expectTag(.int32) - let param1 = Int(reader.readInt32()) - reader.expectTag(.string) - let param2 = reader.readString() - return .status(param0, param1, param2) - case 3: - reader.readParamCount(expected: 3) - reader.expectTag(.float64) - let param0 = reader.readFloat64() - reader.expectTag(.float64) - let param1 = reader.readFloat64() - reader.expectTag(.float64) - let param2 = reader.readFloat64() - return .coordinates(param0, param1, param2) - case 4: - reader.readParamCount(expected: 9) - reader.expectTag(.bool) - let param0 = Int32(reader.readUInt8()) != 0 - reader.expectTag(.bool) - let param1 = Int32(reader.readUInt8()) != 0 - reader.expectTag(.int32) - let param2 = Int(reader.readInt32()) - reader.expectTag(.int32) - let param3 = Int(reader.readInt32()) - reader.expectTag(.float64) - let param4 = reader.readFloat64() - reader.expectTag(.float64) - let param5 = reader.readFloat64() - reader.expectTag(.string) - let param6 = reader.readString() - reader.expectTag(.string) - let param7 = reader.readString() - reader.expectTag(.string) - let param8 = reader.readString() - return .comprehensive(param0, param1, param2, param3, param4, param5, param6, param7, param8) - case 5: - return .info - default: - fatalError("Unknown ComplexResult case ID: \(caseId)") - } + static func bridgeJSLiftParameter(_ caseId: Int32) -> ComplexResult { + switch caseId { + case 0: + return .success(String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32())) + case 1: + return .error(String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32()), Int.bridgeJSLiftParameter(_swift_js_pop_param_int32())) + case 2: + return .status(Bool.bridgeJSLiftParameter(_swift_js_pop_param_int32()), Int.bridgeJSLiftParameter(_swift_js_pop_param_int32()), String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32())) + case 3: + return .coordinates(Double.bridgeJSLiftParameter(_swift_js_pop_param_f64()), Double.bridgeJSLiftParameter(_swift_js_pop_param_f64()), Double.bridgeJSLiftParameter(_swift_js_pop_param_f64())) + case 4: + return .comprehensive(Bool.bridgeJSLiftParameter(_swift_js_pop_param_int32()), Bool.bridgeJSLiftParameter(_swift_js_pop_param_int32()), Int.bridgeJSLiftParameter(_swift_js_pop_param_int32()), Int.bridgeJSLiftParameter(_swift_js_pop_param_int32()), Double.bridgeJSLiftParameter(_swift_js_pop_param_f64()), Double.bridgeJSLiftParameter(_swift_js_pop_param_f64()), String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32()), String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32()), String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32())) + case 5: + return .info + default: + fatalError("Unknown ComplexResult case ID: \(caseId)") } } func bridgeJSLowerReturn() { switch self { case .success(let param0): - _swift_js_return_tag(Int32(0)) + _swift_js_push_tag(Int32(0)) var __bjs_param0 = param0 __bjs_param0.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) } case .error(let param0, let param1): - _swift_js_return_tag(Int32(1)) + _swift_js_push_tag(Int32(1)) var __bjs_param0 = param0 __bjs_param0.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) } - _swift_js_return_int(Int32(param1)) + _swift_js_push_int(Int32(param1)) case .status(let param0, let param1, let param2): - _swift_js_return_tag(Int32(2)) - _swift_js_return_bool(param0 ? 1 : 0) - _swift_js_return_int(Int32(param1)) + _swift_js_push_tag(Int32(2)) + _swift_js_push_int(param0 ? 1 : 0) + _swift_js_push_int(Int32(param1)) var __bjs_param2 = param2 __bjs_param2.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) } case .coordinates(let param0, let param1, let param2): - _swift_js_return_tag(Int32(3)) - _swift_js_return_f64(param0) - _swift_js_return_f64(param1) - _swift_js_return_f64(param2) + _swift_js_push_tag(Int32(3)) + _swift_js_push_f64(param0) + _swift_js_push_f64(param1) + _swift_js_push_f64(param2) case .comprehensive(let param0, let param1, let param2, let param3, let param4, let param5, let param6, let param7, let param8): - _swift_js_return_tag(Int32(4)) - _swift_js_return_bool(param0 ? 1 : 0) - _swift_js_return_bool(param1 ? 1 : 0) - _swift_js_return_int(Int32(param2)) - _swift_js_return_int(Int32(param3)) - _swift_js_return_f64(param4) - _swift_js_return_f64(param5) + _swift_js_push_tag(Int32(4)) + _swift_js_push_int(param0 ? 1 : 0) + _swift_js_push_int(param1 ? 1 : 0) + _swift_js_push_int(Int32(param2)) + _swift_js_push_int(Int32(param3)) + _swift_js_push_f64(param4) + _swift_js_push_f64(param5) var __bjs_param6 = param6 __bjs_param6.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) } var __bjs_param7 = param7 __bjs_param7.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) } var __bjs_param8 = param8 __bjs_param8.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) } case .info: - _swift_js_return_tag(Int32(5)) + _swift_js_push_tag(Int32(5)) } } } private extension Utilities.Result { - static func bridgeJSLiftParameter(_ caseId: Int32, _ paramsId: Int32, _ paramsLen: Int32) -> Utilities.Result { - let params: [UInt8] = .init(unsafeUninitializedCapacity: Int(paramsLen)) { buf, initializedCount in - _swift_js_init_memory(paramsId, buf.baseAddress.unsafelyUnwrapped) - initializedCount = Int(paramsLen) - } - return params.withUnsafeBytes { raw in - var reader = _BJSBinaryReader(raw: raw) - switch caseId { - case 0: - reader.readParamCount(expected: 1) - reader.expectTag(.string) - let param0 = reader.readString() - return .success(param0) - case 1: - reader.readParamCount(expected: 2) - reader.expectTag(.string) - let param0 = reader.readString() - reader.expectTag(.int32) - let param1 = Int(reader.readInt32()) - return .failure(param0, param1) - case 2: - reader.readParamCount(expected: 3) - reader.expectTag(.bool) - let param0 = Int32(reader.readUInt8()) != 0 - reader.expectTag(.int32) - let param1 = Int(reader.readInt32()) - reader.expectTag(.string) - let param2 = reader.readString() - return .status(param0, param1, param2) - default: - fatalError("Unknown Utilities.Result case ID: \(caseId)") - } + static func bridgeJSLiftParameter(_ caseId: Int32) -> Utilities.Result { + switch caseId { + case 0: + return .success(String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32())) + case 1: + return .failure(String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32()), Int.bridgeJSLiftParameter(_swift_js_pop_param_int32())) + case 2: + return .status(Bool.bridgeJSLiftParameter(_swift_js_pop_param_int32()), Int.bridgeJSLiftParameter(_swift_js_pop_param_int32()), String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32())) + default: + fatalError("Unknown Utilities.Result case ID: \(caseId)") } } func bridgeJSLowerReturn() { switch self { case .success(let param0): - _swift_js_return_tag(Int32(0)) + _swift_js_push_tag(Int32(0)) var __bjs_param0 = param0 __bjs_param0.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) } case .failure(let param0, let param1): - _swift_js_return_tag(Int32(1)) + _swift_js_push_tag(Int32(1)) var __bjs_param0 = param0 __bjs_param0.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) } - _swift_js_return_int(Int32(param1)) + _swift_js_push_int(Int32(param1)) case .status(let param0, let param1, let param2): - _swift_js_return_tag(Int32(2)) - _swift_js_return_bool(param0 ? 1 : 0) - _swift_js_return_int(Int32(param1)) + _swift_js_push_tag(Int32(2)) + _swift_js_push_int(param0 ? 1 : 0) + _swift_js_push_int(Int32(param1)) var __bjs_param2 = param2 __bjs_param2.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) } } } } private extension NetworkingResult { - static func bridgeJSLiftParameter(_ caseId: Int32, _ paramsId: Int32, _ paramsLen: Int32) -> NetworkingResult { - let params: [UInt8] = .init(unsafeUninitializedCapacity: Int(paramsLen)) { buf, initializedCount in - _swift_js_init_memory(paramsId, buf.baseAddress.unsafelyUnwrapped) - initializedCount = Int(paramsLen) - } - return params.withUnsafeBytes { raw in - var reader = _BJSBinaryReader(raw: raw) - switch caseId { - case 0: - reader.readParamCount(expected: 1) - reader.expectTag(.string) - let param0 = reader.readString() - return .success(param0) - case 1: - reader.readParamCount(expected: 2) - reader.expectTag(.string) - let param0 = reader.readString() - reader.expectTag(.int32) - let param1 = Int(reader.readInt32()) - return .failure(param0, param1) - default: - fatalError("Unknown NetworkingResult case ID: \(caseId)") - } + static func bridgeJSLiftParameter(_ caseId: Int32) -> NetworkingResult { + switch caseId { + case 0: + return .success(String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32())) + case 1: + return .failure(String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32()), Int.bridgeJSLiftParameter(_swift_js_pop_param_int32())) + default: + fatalError("Unknown NetworkingResult case ID: \(caseId)") } } func bridgeJSLowerReturn() { switch self { case .success(let param0): - _swift_js_return_tag(Int32(0)) + _swift_js_push_tag(Int32(0)) var __bjs_param0 = param0 __bjs_param0.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) } case .failure(let param0, let param1): - _swift_js_return_tag(Int32(1)) + _swift_js_push_tag(Int32(1)) var __bjs_param0 = param0 __bjs_param0.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) } - _swift_js_return_int(Int32(param1)) + _swift_js_push_int(Int32(param1)) } } } @_expose(wasm, "bjs_handle") @_cdecl("bjs_handle") -public func _bjs_handle(resultCaseId: Int32, resultParamsId: Int32, resultParamsLen: Int32) -> Void { +public func _bjs_handle(result: Int32) -> Void { #if arch(wasm32) - handle(result: APIResult.bridgeJSLiftParameter(resultCaseId, resultParamsId, resultParamsLen)) + handle(result: APIResult.bridgeJSLiftParameter(result)) #else fatalError("Only available on WebAssembly") #endif @@ -326,11 +219,22 @@ public func _bjs_getResult() -> Void { #endif } +@_expose(wasm, "bjs_roundtripAPIResult") +@_cdecl("bjs_roundtripAPIResult") +public func _bjs_roundtripAPIResult(result: Int32) -> Void { + #if arch(wasm32) + let ret = roundtripAPIResult(result: APIResult.bridgeJSLiftParameter(result)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + @_expose(wasm, "bjs_handleComplex") @_cdecl("bjs_handleComplex") -public func _bjs_handleComplex(resultCaseId: Int32, resultParamsId: Int32, resultParamsLen: Int32) -> Void { +public func _bjs_handleComplex(result: Int32) -> Void { #if arch(wasm32) - handleComplex(result: ComplexResult.bridgeJSLiftParameter(resultCaseId, resultParamsId, resultParamsLen)) + handleComplex(result: ComplexResult.bridgeJSLiftParameter(result)) #else fatalError("Only available on WebAssembly") #endif @@ -345,4 +249,15 @@ public func _bjs_getComplexResult() -> Void { #else fatalError("Only available on WebAssembly") #endif +} + +@_expose(wasm, "bjs_roundtripComplexResult") +@_cdecl("bjs_roundtripComplexResult") +public func _bjs_roundtripComplexResult(result: Int32) -> Void { + #if arch(wasm32) + let ret = roundtripComplexResult(_: ComplexResult.bridgeJSLiftParameter(result)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif } \ No newline at end of file diff --git a/Sources/JavaScriptKit/BridgeJSInstrincics.swift b/Sources/JavaScriptKit/BridgeJSInstrincics.swift index 555a21f4..31f56a2a 100644 --- a/Sources/JavaScriptKit/BridgeJSInstrincics.swift +++ b/Sources/JavaScriptKit/BridgeJSInstrincics.swift @@ -339,103 +339,6 @@ where Self: RawRepresentable, RawValue: _BridgedSwiftTypeLoweredIntoSingleWasmCo } } -// MARK: Enum binary helpers - -@_spi(BridgeJS) public enum _BJSParamType: UInt8 { - case string = 1 - case int32 = 2 - case bool = 3 - case float32 = 4 - case float64 = 5 -} - -@_spi(BridgeJS) public struct _BJSBinaryReader { - public let raw: UnsafeRawBufferPointer - public var offset: Int = 0 - - public init(raw: UnsafeRawBufferPointer) { - self.raw = raw - } - - @inline(__always) - public mutating func readUInt8() -> UInt8 { - let b = raw[offset] - offset += 1 - return b - } - - @inline(__always) - public mutating func readUInt32() -> UInt32 { - var v = UInt32(0) - withUnsafeMutableBytes(of: &v) { dst in - dst.copyBytes(from: UnsafeRawBufferPointer(rebasing: raw[offset..<(offset + 4)])) - } - offset += 4 - return UInt32(littleEndian: v) - } - - @inline(__always) - public mutating func readInt32() -> Int32 { - var v = Int32(0) - withUnsafeMutableBytes(of: &v) { dst in - dst.copyBytes(from: UnsafeRawBufferPointer(rebasing: raw[offset..<(offset + 4)])) - } - offset += 4 - return Int32(littleEndian: v) - } - - @inline(__always) - public mutating func readFloat32() -> Float32 { - var bits = UInt32(0) - withUnsafeMutableBytes(of: &bits) { dst in - dst.copyBytes(from: UnsafeRawBufferPointer(rebasing: raw[offset..<(offset + 4)])) - } - offset += 4 - return Float32(bitPattern: UInt32(littleEndian: bits)) - } - - @inline(__always) - public mutating func readFloat64() -> Float64 { - var bits = UInt64(0) - withUnsafeMutableBytes(of: &bits) { dst in - dst.copyBytes(from: UnsafeRawBufferPointer(rebasing: raw[offset..<(offset + 8)])) - } - offset += 8 - return Float64(bitPattern: UInt64(littleEndian: bits)) - } - - @inline(__always) - public mutating func readString() -> String { - let len = Int(readUInt32()) - let s = String( - decoding: UnsafeBufferPointer( - start: raw.baseAddress!.advanced(by: offset).assumingMemoryBound(to: UInt8.self), - count: len - ), - as: UTF8.self - ) - offset += len - return s - } - - @inline(__always) - public mutating func expectTag(_ expected: _BJSParamType) { - let rawTag = readUInt8() - guard let got = _BJSParamType(rawValue: rawTag), got == expected else { - let resultString = _BJSParamType(rawValue: rawTag).map { "\($0)" } ?? "invalid(\(rawTag))" - preconditionFailure( - "BridgeJS: mismatched enum param tag. Expected \(expected) got \(resultString))" - ) - } - } - - @inline(__always) - public mutating func readParamCount(expected: Int) { - let count = Int(readUInt32()) - precondition(count == expected, "BridgeJS: mismatched enum param count. Expected \(expected) got \(count)") - } -} - // MARK: Wasm externs used by generated enum glue #if arch(wasm32) @@ -448,26 +351,26 @@ where Self: RawRepresentable, RawValue: _BridgedSwiftTypeLoweredIntoSingleWasmCo #endif #if arch(wasm32) -@_extern(wasm, module: "bjs", name: "swift_js_return_tag") -@_spi(BridgeJS) public func _swift_js_return_tag(_ tag: Int32) +@_extern(wasm, module: "bjs", name: "swift_js_push_tag") +@_spi(BridgeJS) public func _swift_js_push_tag(_ tag: Int32) #else -@_spi(BridgeJS) public func _swift_js_return_tag(_ tag: Int32) { +@_spi(BridgeJS) public func _swift_js_push_tag(_ tag: Int32) { _onlyAvailableOnWasm() } #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) +@_extern(wasm, module: "bjs", name: "swift_js_push_string") +@_spi(BridgeJS) public func _swift_js_push_string(_ ptr: UnsafePointer?, _ len: Int32) #else -@_spi(BridgeJS) public func _swift_js_return_string(_ ptr: UnsafePointer?, _ len: Int32) { +@_spi(BridgeJS) public func _swift_js_push_string(_ ptr: UnsafePointer?, _ len: Int32) { _onlyAvailableOnWasm() } #endif #if arch(wasm32) -@_extern(wasm, module: "bjs", name: "swift_js_return_int") -@_spi(BridgeJS) public func _swift_js_return_int(_ value: Int32) +@_extern(wasm, module: "bjs", name: "swift_js_push_int") +@_spi(BridgeJS) public func _swift_js_push_int(_ value: Int32) #else @_spi(BridgeJS) public func _swift_js_return_int(_ value: Int32) { _onlyAvailableOnWasm() @@ -475,28 +378,46 @@ where Self: RawRepresentable, RawValue: _BridgedSwiftTypeLoweredIntoSingleWasmCo #endif #if arch(wasm32) -@_extern(wasm, module: "bjs", name: "swift_js_return_f32") -@_spi(BridgeJS) public func _swift_js_return_f32(_ value: Float32) +@_extern(wasm, module: "bjs", name: "swift_js_push_f32") +@_spi(BridgeJS) public func _swift_js_push_f32(_ value: Float32) +#else +@_spi(BridgeJS) public func _swift_js_push_f32(_ value: Float32) { + _onlyAvailableOnWasm() +} +#endif + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_push_f64") +@_spi(BridgeJS) public func _swift_js_push_f64(_ value: Float64) +#else +@_spi(BridgeJS) public func _swift_js_push_f64(_ value: Float64) { + _onlyAvailableOnWasm() +} +#endif + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_pop_param_int32") +@_spi(BridgeJS) public func _swift_js_pop_param_int32() -> Int32 #else -@_spi(BridgeJS) public func _swift_js_return_f32(_ value: Float32) { +@_spi(BridgeJS) public func _swift_js_pop_param_int32() { _onlyAvailableOnWasm() } #endif #if arch(wasm32) -@_extern(wasm, module: "bjs", name: "swift_js_return_f64") -@_spi(BridgeJS) public func _swift_js_return_f64(_ value: Float64) +@_extern(wasm, module: "bjs", name: "swift_js_pop_param_f32") +@_spi(BridgeJS) public func _swift_js_pop_param_f32() -> Float32 #else -@_spi(BridgeJS) public func _swift_js_return_f64(_ value: Float64) { +@_spi(BridgeJS) public func _swift_js_pop_param_f32() { _onlyAvailableOnWasm() } #endif #if arch(wasm32) -@_extern(wasm, module: "bjs", name: "swift_js_return_bool") -@_spi(BridgeJS) public func _swift_js_return_bool(_ value: Int32) +@_extern(wasm, module: "bjs", name: "swift_js_pop_param_f64") +@_spi(BridgeJS) public func _swift_js_pop_param_f64() -> Float64 #else -@_spi(BridgeJS) public func _swift_js_return_bool(_ value: Int32) { +@_spi(BridgeJS) public func _swift_js_pop_param_f64() { _onlyAvailableOnWasm() } #endif diff --git a/Tests/BridgeJSRuntimeTests/ExportAPITests.swift b/Tests/BridgeJSRuntimeTests/ExportAPITests.swift index 995a856f..b00aa67b 100644 --- a/Tests/BridgeJSRuntimeTests/ExportAPITests.swift +++ b/Tests/BridgeJSRuntimeTests/ExportAPITests.swift @@ -277,15 +277,15 @@ enum Internal { } } -@JS func echoNetworkingAPIMethod(_ method: Networking.API.Method) -> Networking.API.Method { +@JS func roundtripNetworkingAPIMethod(_ method: Networking.API.Method) -> Networking.API.Method { return method } -@JS func echoConfigurationLogLevel(_ level: Configuration.LogLevel) -> Configuration.LogLevel { +@JS func roundtripConfigurationLogLevel(_ level: Configuration.LogLevel) -> Configuration.LogLevel { return level } -@JS func echoConfigurationPort(_ port: Configuration.Port) -> Configuration.Port { +@JS func roundtripConfigurationPort(_ port: Configuration.Port) -> Configuration.Port { return port } @@ -298,7 +298,7 @@ enum Internal { } } -@JS func echoInternalSupportedMethod(_ method: Internal.SupportedMethod) -> Internal.SupportedMethod { +@JS func roundtripInternalSupportedMethod(_ method: Internal.SupportedMethod) -> Internal.SupportedMethod { return method } @@ -311,7 +311,7 @@ enum Internal { case info } -@JS func echoAPIResult(result: APIResult) -> APIResult { +@JS func roundtripAPIResult(result: APIResult) -> APIResult { return result } @@ -350,7 +350,7 @@ enum ComplexResult { case info } -@JS func echoComplexResult(result: ComplexResult) -> ComplexResult { +@JS func roundtripComplexResult(_ result: ComplexResult) -> ComplexResult { return result } @@ -392,10 +392,6 @@ enum ComplexResult { return .info } -@JS func roundtripComplexResult(_ result: ComplexResult) -> ComplexResult { - return result -} - @JS enum Utilities { @JS enum Result { case success(String) diff --git a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ExportSwift.swift b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ExportSwift.swift index 6b22899c..5ae4e055 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ExportSwift.swift +++ b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.ExportSwift.swift @@ -225,317 +225,203 @@ extension Internal.SupportedMethod { } private extension APIResult { - static func bridgeJSLiftParameter(_ caseId: Int32, _ paramsId: Int32, _ paramsLen: Int32) -> APIResult { - let params: [UInt8] = .init(unsafeUninitializedCapacity: Int(paramsLen)) { buf, initializedCount in - _swift_js_init_memory(paramsId, buf.baseAddress.unsafelyUnwrapped) - initializedCount = Int(paramsLen) - } - return params.withUnsafeBytes { raw in - var reader = _BJSBinaryReader(raw: raw) - switch caseId { - case 0: - reader.readParamCount(expected: 1) - reader.expectTag(.string) - let param0 = reader.readString() - return .success(param0) - case 1: - reader.readParamCount(expected: 1) - reader.expectTag(.int32) - let param0 = Int(reader.readInt32()) - return .failure(param0) - case 2: - reader.readParamCount(expected: 1) - reader.expectTag(.bool) - let param0 = Int32(reader.readUInt8()) != 0 - return .flag(param0) - case 3: - reader.readParamCount(expected: 1) - reader.expectTag(.float32) - let param0 = reader.readFloat32() - return .rate(param0) - case 4: - reader.readParamCount(expected: 1) - reader.expectTag(.float64) - let param0 = reader.readFloat64() - return .precise(param0) - case 5: - return .info - default: - fatalError("Unknown APIResult case ID: \(caseId)") - } + static func bridgeJSLiftParameter(_ caseId: Int32) -> APIResult { + switch caseId { + case 0: + return .success(String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32())) + case 1: + return .failure(Int.bridgeJSLiftParameter(_swift_js_pop_param_int32())) + case 2: + return .flag(Bool.bridgeJSLiftParameter(_swift_js_pop_param_int32())) + case 3: + return .rate(Float.bridgeJSLiftParameter(_swift_js_pop_param_f32())) + case 4: + return .precise(Double.bridgeJSLiftParameter(_swift_js_pop_param_f64())) + case 5: + return .info + default: + fatalError("Unknown APIResult case ID: \(caseId)") } } func bridgeJSLowerReturn() { switch self { case .success(let param0): - _swift_js_return_tag(Int32(0)) + _swift_js_push_tag(Int32(0)) var __bjs_param0 = param0 __bjs_param0.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) } case .failure(let param0): - _swift_js_return_tag(Int32(1)) - _swift_js_return_int(Int32(param0)) + _swift_js_push_tag(Int32(1)) + _swift_js_push_int(Int32(param0)) case .flag(let param0): - _swift_js_return_tag(Int32(2)) - _swift_js_return_bool(param0 ? 1 : 0) + _swift_js_push_tag(Int32(2)) + _swift_js_push_int(param0 ? 1 : 0) case .rate(let param0): - _swift_js_return_tag(Int32(3)) - _swift_js_return_f32(param0) + _swift_js_push_tag(Int32(3)) + _swift_js_push_f32(param0) case .precise(let param0): - _swift_js_return_tag(Int32(4)) - _swift_js_return_f64(param0) + _swift_js_push_tag(Int32(4)) + _swift_js_push_f64(param0) case .info: - _swift_js_return_tag(Int32(5)) + _swift_js_push_tag(Int32(5)) } } } private extension ComplexResult { - static func bridgeJSLiftParameter(_ caseId: Int32, _ paramsId: Int32, _ paramsLen: Int32) -> ComplexResult { - let params: [UInt8] = .init(unsafeUninitializedCapacity: Int(paramsLen)) { buf, initializedCount in - _swift_js_init_memory(paramsId, buf.baseAddress.unsafelyUnwrapped) - initializedCount = Int(paramsLen) - } - return params.withUnsafeBytes { raw in - var reader = _BJSBinaryReader(raw: raw) - switch caseId { - case 0: - reader.readParamCount(expected: 1) - reader.expectTag(.string) - let param0 = reader.readString() - return .success(param0) - case 1: - reader.readParamCount(expected: 2) - reader.expectTag(.string) - let param0 = reader.readString() - reader.expectTag(.int32) - let param1 = Int(reader.readInt32()) - return .error(param0, param1) - case 2: - reader.readParamCount(expected: 3) - reader.expectTag(.float64) - let param0 = reader.readFloat64() - reader.expectTag(.float64) - let param1 = reader.readFloat64() - reader.expectTag(.string) - let param2 = reader.readString() - return .location(param0, param1, param2) - case 3: - reader.readParamCount(expected: 3) - reader.expectTag(.bool) - let param0 = Int32(reader.readUInt8()) != 0 - reader.expectTag(.int32) - let param1 = Int(reader.readInt32()) - reader.expectTag(.string) - let param2 = reader.readString() - return .status(param0, param1, param2) - case 4: - reader.readParamCount(expected: 3) - reader.expectTag(.float64) - let param0 = reader.readFloat64() - reader.expectTag(.float64) - let param1 = reader.readFloat64() - reader.expectTag(.float64) - let param2 = reader.readFloat64() - return .coordinates(param0, param1, param2) - case 5: - reader.readParamCount(expected: 9) - reader.expectTag(.bool) - let param0 = Int32(reader.readUInt8()) != 0 - reader.expectTag(.bool) - let param1 = Int32(reader.readUInt8()) != 0 - reader.expectTag(.int32) - let param2 = Int(reader.readInt32()) - reader.expectTag(.int32) - let param3 = Int(reader.readInt32()) - reader.expectTag(.float64) - let param4 = reader.readFloat64() - reader.expectTag(.float64) - let param5 = reader.readFloat64() - reader.expectTag(.string) - let param6 = reader.readString() - reader.expectTag(.string) - let param7 = reader.readString() - reader.expectTag(.string) - let param8 = reader.readString() - return .comprehensive(param0, param1, param2, param3, param4, param5, param6, param7, param8) - case 6: - return .info - default: - fatalError("Unknown ComplexResult case ID: \(caseId)") - } + static func bridgeJSLiftParameter(_ caseId: Int32) -> ComplexResult { + switch caseId { + case 0: + return .success(String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32())) + case 1: + return .error(String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32()), Int.bridgeJSLiftParameter(_swift_js_pop_param_int32())) + case 2: + return .location(Double.bridgeJSLiftParameter(_swift_js_pop_param_f64()), Double.bridgeJSLiftParameter(_swift_js_pop_param_f64()), String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32())) + case 3: + return .status(Bool.bridgeJSLiftParameter(_swift_js_pop_param_int32()), Int.bridgeJSLiftParameter(_swift_js_pop_param_int32()), String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32())) + case 4: + return .coordinates(Double.bridgeJSLiftParameter(_swift_js_pop_param_f64()), Double.bridgeJSLiftParameter(_swift_js_pop_param_f64()), Double.bridgeJSLiftParameter(_swift_js_pop_param_f64())) + case 5: + return .comprehensive(Bool.bridgeJSLiftParameter(_swift_js_pop_param_int32()), Bool.bridgeJSLiftParameter(_swift_js_pop_param_int32()), Int.bridgeJSLiftParameter(_swift_js_pop_param_int32()), Int.bridgeJSLiftParameter(_swift_js_pop_param_int32()), Double.bridgeJSLiftParameter(_swift_js_pop_param_f64()), Double.bridgeJSLiftParameter(_swift_js_pop_param_f64()), String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32()), String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32()), String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32())) + case 6: + return .info + default: + fatalError("Unknown ComplexResult case ID: \(caseId)") } } func bridgeJSLowerReturn() { switch self { case .success(let param0): - _swift_js_return_tag(Int32(0)) + _swift_js_push_tag(Int32(0)) var __bjs_param0 = param0 __bjs_param0.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) } case .error(let param0, let param1): - _swift_js_return_tag(Int32(1)) + _swift_js_push_tag(Int32(1)) var __bjs_param0 = param0 __bjs_param0.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) } - _swift_js_return_int(Int32(param1)) + _swift_js_push_int(Int32(param1)) case .location(let param0, let param1, let param2): - _swift_js_return_tag(Int32(2)) - _swift_js_return_f64(param0) - _swift_js_return_f64(param1) + _swift_js_push_tag(Int32(2)) + _swift_js_push_f64(param0) + _swift_js_push_f64(param1) var __bjs_param2 = param2 __bjs_param2.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) } case .status(let param0, let param1, let param2): - _swift_js_return_tag(Int32(3)) - _swift_js_return_bool(param0 ? 1 : 0) - _swift_js_return_int(Int32(param1)) + _swift_js_push_tag(Int32(3)) + _swift_js_push_int(param0 ? 1 : 0) + _swift_js_push_int(Int32(param1)) var __bjs_param2 = param2 __bjs_param2.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) } case .coordinates(let param0, let param1, let param2): - _swift_js_return_tag(Int32(4)) - _swift_js_return_f64(param0) - _swift_js_return_f64(param1) - _swift_js_return_f64(param2) + _swift_js_push_tag(Int32(4)) + _swift_js_push_f64(param0) + _swift_js_push_f64(param1) + _swift_js_push_f64(param2) case .comprehensive(let param0, let param1, let param2, let param3, let param4, let param5, let param6, let param7, let param8): - _swift_js_return_tag(Int32(5)) - _swift_js_return_bool(param0 ? 1 : 0) - _swift_js_return_bool(param1 ? 1 : 0) - _swift_js_return_int(Int32(param2)) - _swift_js_return_int(Int32(param3)) - _swift_js_return_f64(param4) - _swift_js_return_f64(param5) + _swift_js_push_tag(Int32(5)) + _swift_js_push_int(param0 ? 1 : 0) + _swift_js_push_int(param1 ? 1 : 0) + _swift_js_push_int(Int32(param2)) + _swift_js_push_int(Int32(param3)) + _swift_js_push_f64(param4) + _swift_js_push_f64(param5) var __bjs_param6 = param6 __bjs_param6.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) } var __bjs_param7 = param7 __bjs_param7.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) } var __bjs_param8 = param8 __bjs_param8.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) } case .info: - _swift_js_return_tag(Int32(6)) + _swift_js_push_tag(Int32(6)) } } } private extension Utilities.Result { - static func bridgeJSLiftParameter(_ caseId: Int32, _ paramsId: Int32, _ paramsLen: Int32) -> Utilities.Result { - let params: [UInt8] = .init(unsafeUninitializedCapacity: Int(paramsLen)) { buf, initializedCount in - _swift_js_init_memory(paramsId, buf.baseAddress.unsafelyUnwrapped) - initializedCount = Int(paramsLen) - } - return params.withUnsafeBytes { raw in - var reader = _BJSBinaryReader(raw: raw) - switch caseId { - case 0: - reader.readParamCount(expected: 1) - reader.expectTag(.string) - let param0 = reader.readString() - return .success(param0) - case 1: - reader.readParamCount(expected: 2) - reader.expectTag(.string) - let param0 = reader.readString() - reader.expectTag(.int32) - let param1 = Int(reader.readInt32()) - return .failure(param0, param1) - case 2: - reader.readParamCount(expected: 3) - reader.expectTag(.bool) - let param0 = Int32(reader.readUInt8()) != 0 - reader.expectTag(.int32) - let param1 = Int(reader.readInt32()) - reader.expectTag(.string) - let param2 = reader.readString() - return .status(param0, param1, param2) - default: - fatalError("Unknown Utilities.Result case ID: \(caseId)") - } + static func bridgeJSLiftParameter(_ caseId: Int32) -> Utilities.Result { + switch caseId { + case 0: + return .success(String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32())) + case 1: + return .failure(String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32()), Int.bridgeJSLiftParameter(_swift_js_pop_param_int32())) + case 2: + return .status(Bool.bridgeJSLiftParameter(_swift_js_pop_param_int32()), Int.bridgeJSLiftParameter(_swift_js_pop_param_int32()), String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32())) + default: + fatalError("Unknown Utilities.Result case ID: \(caseId)") } } func bridgeJSLowerReturn() { switch self { case .success(let param0): - _swift_js_return_tag(Int32(0)) + _swift_js_push_tag(Int32(0)) var __bjs_param0 = param0 __bjs_param0.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) } case .failure(let param0, let param1): - _swift_js_return_tag(Int32(1)) + _swift_js_push_tag(Int32(1)) var __bjs_param0 = param0 __bjs_param0.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) } - _swift_js_return_int(Int32(param1)) + _swift_js_push_int(Int32(param1)) case .status(let param0, let param1, let param2): - _swift_js_return_tag(Int32(2)) - _swift_js_return_bool(param0 ? 1 : 0) - _swift_js_return_int(Int32(param1)) + _swift_js_push_tag(Int32(2)) + _swift_js_push_int(param0 ? 1 : 0) + _swift_js_push_int(Int32(param1)) var __bjs_param2 = param2 __bjs_param2.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) } } } } private extension API.NetworkingResult { - static func bridgeJSLiftParameter(_ caseId: Int32, _ paramsId: Int32, _ paramsLen: Int32) -> API.NetworkingResult { - let params: [UInt8] = .init(unsafeUninitializedCapacity: Int(paramsLen)) { buf, initializedCount in - _swift_js_init_memory(paramsId, buf.baseAddress.unsafelyUnwrapped) - initializedCount = Int(paramsLen) - } - return params.withUnsafeBytes { raw in - var reader = _BJSBinaryReader(raw: raw) - switch caseId { - case 0: - reader.readParamCount(expected: 1) - reader.expectTag(.string) - let param0 = reader.readString() - return .success(param0) - case 1: - reader.readParamCount(expected: 2) - reader.expectTag(.string) - let param0 = reader.readString() - reader.expectTag(.int32) - let param1 = Int(reader.readInt32()) - return .failure(param0, param1) - default: - fatalError("Unknown API.NetworkingResult case ID: \(caseId)") - } + static func bridgeJSLiftParameter(_ caseId: Int32) -> API.NetworkingResult { + switch caseId { + case 0: + return .success(String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32())) + case 1: + return .failure(String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32()), Int.bridgeJSLiftParameter(_swift_js_pop_param_int32())) + default: + fatalError("Unknown API.NetworkingResult case ID: \(caseId)") } } func bridgeJSLowerReturn() { switch self { case .success(let param0): - _swift_js_return_tag(Int32(0)) + _swift_js_push_tag(Int32(0)) var __bjs_param0 = param0 __bjs_param0.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) } case .failure(let param0, let param1): - _swift_js_return_tag(Int32(1)) + _swift_js_push_tag(Int32(1)) var __bjs_param0 = param0 __bjs_param0.withUTF8 { ptr in - _swift_js_return_string(ptr.baseAddress, Int32(ptr.count)) + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) } - _swift_js_return_int(Int32(param1)) + _swift_js_push_int(Int32(param1)) } } } @@ -1127,33 +1013,33 @@ public func _bjs_getTSTheme() -> Void { #endif } -@_expose(wasm, "bjs_echoNetworkingAPIMethod") -@_cdecl("bjs_echoNetworkingAPIMethod") -public func _bjs_echoNetworkingAPIMethod(method: Int32) -> Int32 { +@_expose(wasm, "bjs_roundtripNetworkingAPIMethod") +@_cdecl("bjs_roundtripNetworkingAPIMethod") +public func _bjs_roundtripNetworkingAPIMethod(method: Int32) -> Int32 { #if arch(wasm32) - let ret = echoNetworkingAPIMethod(_: Networking.API.Method.bridgeJSLiftParameter(method)) + let ret = roundtripNetworkingAPIMethod(_: Networking.API.Method.bridgeJSLiftParameter(method)) return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif } -@_expose(wasm, "bjs_echoConfigurationLogLevel") -@_cdecl("bjs_echoConfigurationLogLevel") -public func _bjs_echoConfigurationLogLevel(levelBytes: Int32, levelLength: Int32) -> Void { +@_expose(wasm, "bjs_roundtripConfigurationLogLevel") +@_cdecl("bjs_roundtripConfigurationLogLevel") +public func _bjs_roundtripConfigurationLogLevel(levelBytes: Int32, levelLength: Int32) -> Void { #if arch(wasm32) - let ret = echoConfigurationLogLevel(_: Configuration.LogLevel.bridgeJSLiftParameter(levelBytes, levelLength)) + let ret = roundtripConfigurationLogLevel(_: Configuration.LogLevel.bridgeJSLiftParameter(levelBytes, levelLength)) return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif } -@_expose(wasm, "bjs_echoConfigurationPort") -@_cdecl("bjs_echoConfigurationPort") -public func _bjs_echoConfigurationPort(port: Int32) -> Int32 { +@_expose(wasm, "bjs_roundtripConfigurationPort") +@_cdecl("bjs_roundtripConfigurationPort") +public func _bjs_roundtripConfigurationPort(port: Int32) -> Int32 { #if arch(wasm32) - let ret = echoConfigurationPort(_: Configuration.Port.bridgeJSLiftParameter(port)) + let ret = roundtripConfigurationPort(_: Configuration.Port.bridgeJSLiftParameter(port)) return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -1171,22 +1057,22 @@ public func _bjs_processConfigurationLogLevel(levelBytes: Int32, levelLength: In #endif } -@_expose(wasm, "bjs_echoInternalSupportedMethod") -@_cdecl("bjs_echoInternalSupportedMethod") -public func _bjs_echoInternalSupportedMethod(method: Int32) -> Int32 { +@_expose(wasm, "bjs_roundtripInternalSupportedMethod") +@_cdecl("bjs_roundtripInternalSupportedMethod") +public func _bjs_roundtripInternalSupportedMethod(method: Int32) -> Int32 { #if arch(wasm32) - let ret = echoInternalSupportedMethod(_: Internal.SupportedMethod.bridgeJSLiftParameter(method)) + let ret = roundtripInternalSupportedMethod(_: Internal.SupportedMethod.bridgeJSLiftParameter(method)) return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") #endif } -@_expose(wasm, "bjs_echoAPIResult") -@_cdecl("bjs_echoAPIResult") -public func _bjs_echoAPIResult(resultCaseId: Int32, resultParamsId: Int32, resultParamsLen: Int32) -> Void { +@_expose(wasm, "bjs_roundtripAPIResult") +@_cdecl("bjs_roundtripAPIResult") +public func _bjs_roundtripAPIResult(result: Int32) -> Void { #if arch(wasm32) - let ret = echoAPIResult(result: APIResult.bridgeJSLiftParameter(resultCaseId, resultParamsId, resultParamsLen)) + let ret = roundtripAPIResult(result: APIResult.bridgeJSLiftParameter(result)) return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -1259,11 +1145,11 @@ public func _bjs_makeAPIResultPrecise(value: Float64) -> Void { #endif } -@_expose(wasm, "bjs_echoComplexResult") -@_cdecl("bjs_echoComplexResult") -public func _bjs_echoComplexResult(resultCaseId: Int32, resultParamsId: Int32, resultParamsLen: Int32) -> Void { +@_expose(wasm, "bjs_roundtripComplexResult") +@_cdecl("bjs_roundtripComplexResult") +public func _bjs_roundtripComplexResult(result: Int32) -> Void { #if arch(wasm32) - let ret = echoComplexResult(result: ComplexResult.bridgeJSLiftParameter(resultCaseId, resultParamsId, resultParamsLen)) + let ret = roundtripComplexResult(_: ComplexResult.bridgeJSLiftParameter(result)) return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -1347,17 +1233,6 @@ public func _bjs_makeComplexResultInfo() -> Void { #endif } -@_expose(wasm, "bjs_roundtripComplexResult") -@_cdecl("bjs_roundtripComplexResult") -public func _bjs_roundtripComplexResult(resultCaseId: Int32, resultParamsId: Int32, resultParamsLen: Int32) -> Void { - #if arch(wasm32) - let ret = roundtripComplexResult(_: ComplexResult.bridgeJSLiftParameter(resultCaseId, resultParamsId, resultParamsLen)) - return ret.bridgeJSLowerReturn() - #else - fatalError("Only available on WebAssembly") - #endif -} - @_expose(wasm, "bjs_makeUtilitiesResultSuccess") @_cdecl("bjs_makeUtilitiesResultSuccess") public func _bjs_makeUtilitiesResultSuccess(messageBytes: Int32, messageLength: Int32) -> Void { @@ -1415,9 +1290,9 @@ public func _bjs_makeAPINetworkingResultFailure(errorBytes: Int32, errorLength: @_expose(wasm, "bjs_roundtripUtilitiesResult") @_cdecl("bjs_roundtripUtilitiesResult") -public func _bjs_roundtripUtilitiesResult(resultCaseId: Int32, resultParamsId: Int32, resultParamsLen: Int32) -> Void { +public func _bjs_roundtripUtilitiesResult(result: Int32) -> Void { #if arch(wasm32) - let ret = roundtripUtilitiesResult(_: Utilities.Result.bridgeJSLiftParameter(resultCaseId, resultParamsId, resultParamsLen)) + let ret = roundtripUtilitiesResult(_: Utilities.Result.bridgeJSLiftParameter(result)) return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -1426,9 +1301,9 @@ public func _bjs_roundtripUtilitiesResult(resultCaseId: Int32, resultParamsId: I @_expose(wasm, "bjs_roundtripAPINetworkingResult") @_cdecl("bjs_roundtripAPINetworkingResult") -public func _bjs_roundtripAPINetworkingResult(resultCaseId: Int32, resultParamsId: Int32, resultParamsLen: Int32) -> Void { +public func _bjs_roundtripAPINetworkingResult(result: Int32) -> Void { #if arch(wasm32) - let ret = roundtripAPINetworkingResult(_: API.NetworkingResult.bridgeJSLiftParameter(resultCaseId, resultParamsId, resultParamsLen)) + let ret = roundtripAPINetworkingResult(_: API.NetworkingResult.bridgeJSLiftParameter(result)) return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") diff --git a/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.ExportSwift.json b/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.ExportSwift.json index c1638c67..5609a0f2 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.ExportSwift.json +++ b/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.ExportSwift.json @@ -2198,12 +2198,12 @@ } }, { - "abiName" : "bjs_echoNetworkingAPIMethod", + "abiName" : "bjs_roundtripNetworkingAPIMethod", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "echoNetworkingAPIMethod", + "name" : "roundtripNetworkingAPIMethod", "parameters" : [ { "label" : "_", @@ -2222,12 +2222,12 @@ } }, { - "abiName" : "bjs_echoConfigurationLogLevel", + "abiName" : "bjs_roundtripConfigurationLogLevel", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "echoConfigurationLogLevel", + "name" : "roundtripConfigurationLogLevel", "parameters" : [ { "label" : "_", @@ -2248,12 +2248,12 @@ } }, { - "abiName" : "bjs_echoConfigurationPort", + "abiName" : "bjs_roundtripConfigurationPort", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "echoConfigurationPort", + "name" : "roundtripConfigurationPort", "parameters" : [ { "label" : "_", @@ -2300,12 +2300,12 @@ } }, { - "abiName" : "bjs_echoInternalSupportedMethod", + "abiName" : "bjs_roundtripInternalSupportedMethod", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "echoInternalSupportedMethod", + "name" : "roundtripInternalSupportedMethod", "parameters" : [ { "label" : "_", @@ -2324,12 +2324,12 @@ } }, { - "abiName" : "bjs_echoAPIResult", + "abiName" : "bjs_roundtripAPIResult", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "echoAPIResult", + "name" : "roundtripAPIResult", "parameters" : [ { "label" : "result", @@ -2484,15 +2484,15 @@ } }, { - "abiName" : "bjs_echoComplexResult", + "abiName" : "bjs_roundtripComplexResult", "effects" : { "isAsync" : false, "isThrows" : false }, - "name" : "echoComplexResult", + "name" : "roundtripComplexResult", "parameters" : [ { - "label" : "result", + "label" : "_", "name" : "result", "type" : { "associatedValueEnum" : { @@ -2802,30 +2802,6 @@ } } }, - { - "abiName" : "bjs_roundtripComplexResult", - "effects" : { - "isAsync" : false, - "isThrows" : false - }, - "name" : "roundtripComplexResult", - "parameters" : [ - { - "label" : "_", - "name" : "result", - "type" : { - "associatedValueEnum" : { - "_0" : "ComplexResult" - } - } - } - ], - "returnType" : { - "associatedValueEnum" : { - "_0" : "ComplexResult" - } - } - }, { "abiName" : "bjs_makeUtilitiesResultSuccess", "effects" : { diff --git a/Tests/prelude.mjs b/Tests/prelude.mjs index fc7598e3..5ce68b5c 100644 --- a/Tests/prelude.mjs +++ b/Tests/prelude.mjs @@ -354,14 +354,14 @@ function BridgeJSRuntimeTests_runJsWorks(instance, exports) { assert.equal(globalThis.Networking.APIV2.Internal.SupportedMethod.Get, 0); assert.equal(globalThis.Networking.APIV2.Internal.SupportedMethod.Post, 1); - assert.equal(exports.echoNetworkingAPIMethod(globalThis.Networking.API.Method.Get), globalThis.Networking.API.Method.Get); - assert.equal(exports.echoConfigurationLogLevel(globalThis.Configuration.LogLevel.Debug), globalThis.Configuration.LogLevel.Debug); - assert.equal(exports.echoConfigurationPort(globalThis.Configuration.Port.Http), globalThis.Configuration.Port.Http); + assert.equal(exports.roundtripNetworkingAPIMethod(globalThis.Networking.API.Method.Get), globalThis.Networking.API.Method.Get); + assert.equal(exports.roundtripConfigurationLogLevel(globalThis.Configuration.LogLevel.Debug), globalThis.Configuration.LogLevel.Debug); + assert.equal(exports.roundtripConfigurationPort(globalThis.Configuration.Port.Http), globalThis.Configuration.Port.Http); assert.equal(exports.processConfigurationLogLevel(globalThis.Configuration.LogLevel.Debug), globalThis.Configuration.Port.Development); assert.equal(exports.processConfigurationLogLevel(globalThis.Configuration.LogLevel.Info), globalThis.Configuration.Port.Http); assert.equal(exports.processConfigurationLogLevel(globalThis.Configuration.LogLevel.Warning), globalThis.Configuration.Port.Https); assert.equal(exports.processConfigurationLogLevel(globalThis.Configuration.LogLevel.Error), globalThis.Configuration.Port.Development); - assert.equal(exports.echoInternalSupportedMethod(globalThis.Networking.APIV2.Internal.SupportedMethod.Get), globalThis.Networking.APIV2.Internal.SupportedMethod.Get); + assert.equal(exports.roundtripInternalSupportedMethod(globalThis.Networking.APIV2.Internal.SupportedMethod.Get), globalThis.Networking.APIV2.Internal.SupportedMethod.Get); const converter = new exports.Converter(); assert.equal(converter.toString(42), "42"); @@ -394,10 +394,9 @@ function BridgeJSRuntimeTests_runJsWorks(instance, exports) { const f1 = { tag: APIResult.Tag.Failure, param0: 42 }; const i1 = { tag: APIResult.Tag.Info }; - assert.deepEqual(exports.echoAPIResult(s1), s1); - assert.deepEqual(exports.echoAPIResult(f1), f1); - assert.deepEqual(exports.echoAPIResult(i1), i1); - + assert.deepEqual(exports.roundtripAPIResult(s1), s1); + assert.deepEqual(exports.roundtripAPIResult(f1), f1); + assert.deepEqual(exports.roundtripAPIResult(i1), i1); assert.deepEqual(exports.makeAPIResultSuccess("Test"), { tag: APIResult.Tag.Success, param0: "Test" }); assert.deepEqual(exports.makeAPIResultSuccess("ok"), { tag: APIResult.Tag.Success, param0: "ok" }); @@ -411,12 +410,12 @@ function BridgeJSRuntimeTests_runJsWorks(instance, exports) { const rVal = 3.25; const r1 = { tag: APIResult.Tag.Rate, param0: rVal }; - assert.deepEqual(exports.echoAPIResult(r1), r1); + assert.deepEqual(exports.roundtripAPIResult(r1), r1); assert.deepEqual(exports.makeAPIResultRate(rVal), r1); const pVal = 3.141592653589793; const p1 = { tag: APIResult.Tag.Precise, param0: pVal }; - assert.deepEqual(exports.echoAPIResult(p1), p1); + assert.deepEqual(exports.roundtripAPIResult(p1), p1); assert.deepEqual(exports.makeAPIResultPrecise(pVal), p1); const cs1 = { tag: ComplexResult.Tag.Success, param0: "All good!" }; @@ -427,14 +426,6 @@ function BridgeJSRuntimeTests_runJsWorks(instance, exports) { const ccomp1 = { tag: ComplexResult.Tag.Comprehensive, param0: true, param1: false, param2: 42, param3: 100, param4: 3.14, param5: 2.718, param6: "Hello", param7: "World", param8: "Test" }; const ci1 = { tag: ComplexResult.Tag.Info }; - assert.deepEqual(exports.echoComplexResult(cs1), cs1); - assert.deepEqual(exports.echoComplexResult(ce1), ce1); - assert.deepEqual(exports.echoComplexResult(cl1), cl1); - assert.deepEqual(exports.echoComplexResult(cst1), cst1); - assert.deepEqual(exports.echoComplexResult(cc1), cc1); - assert.deepEqual(exports.echoComplexResult(ccomp1), ccomp1); - assert.deepEqual(exports.echoComplexResult(ci1), ci1); - assert.deepEqual(exports.roundtripComplexResult(cs1), cs1); assert.deepEqual(exports.roundtripComplexResult(ce1), ce1); assert.deepEqual(exports.roundtripComplexResult(cl1), cl1); From 4489d910724fe1489fa6acf53e55b9ab52bd8fa7 Mon Sep 17 00:00:00 2001 From: Krzysztof Rodak Date: Fri, 29 Aug 2025 16:14:24 +0200 Subject: [PATCH 4/4] BridgeJS: Add enum and string benchmarks --- Benchmarks/Sources/Benchmarks.swift | 93 +++ .../Generated/BridgeJS.ExportSwift.swift | 429 ++++++++++++ .../JavaScript/BridgeJS.ExportSwift.json | 662 ++++++++++++++++++ Benchmarks/run.js | 166 +++++ 4 files changed, 1350 insertions(+) diff --git a/Benchmarks/Sources/Benchmarks.swift b/Benchmarks/Sources/Benchmarks.swift index 55b9f3eb..b05075eb 100644 --- a/Benchmarks/Sources/Benchmarks.swift +++ b/Benchmarks/Sources/Benchmarks.swift @@ -18,6 +18,99 @@ class Benchmark { } } +@JS enum APIResult { + case success(String) + case failure(Int) + case flag(Bool) + case rate(Float) + case precise(Double) + case info +} + +@JS class EnumRoundtrip { + @JS init() {} + + @JS func take(_ value: APIResult) {} + @JS func makeSuccess() -> APIResult { + return .success("Hello, world") + } + @JS func makeFailure() -> APIResult { + return .failure(42) + } + @JS func makeFlag() -> APIResult { + return .flag(true) + } + @JS func makeRate() -> APIResult { + return .rate(0.5) + } + @JS func makePrecise() -> APIResult { + return .precise(0.5) + } + @JS func makeInfo() -> APIResult { + return .info + } + + @JS func roundtrip(_ result: APIResult) -> APIResult { + return result + } +} + +@JS +enum ComplexResult { + case success(String) + case error(String, Int) + case location(Double, Double, String) + case status(Bool, Int, String) + case coordinates(Double, Double, Double) + case comprehensive(Bool, Bool, Int, Int, Double, Double, String, String, String) + case info +} + +@JS class ComplexResultRoundtrip { + @JS init() {} + + @JS func take(_ value: ComplexResult) {} + + @JS func makeSuccess() -> ComplexResult { + return .success("Hello, world") + } + + @JS func makeError() -> ComplexResult { + return .error("Network timeout", 503) + } + + @JS func makeLocation() -> ComplexResult { + return .location(37.7749, -122.4194, "San Francisco") + } + + @JS func makeStatus() -> ComplexResult { + return .status(true, 200, "OK") + } + + @JS func makeCoordinates() -> ComplexResult { + return .coordinates(10.5, 20.3, 30.7) + } + + @JS func makeComprehensive() -> ComplexResult { + return .comprehensive(true, false, 42, 100, 3.14, 2.718, "Hello", "World", "Test") + } + + @JS func makeInfo() -> ComplexResult { + return .info + } + + @JS func roundtrip(_ result: ComplexResult) -> ComplexResult { + return result + } +} +@JS class StringRoundtrip { + @JS init() {} + @JS func take(_ value: String) {} + @JS func make() -> String { + return "Hello, world" + } +} + @JS func run() { let call = Benchmark("Call") diff --git a/Benchmarks/Sources/Generated/BridgeJS.ExportSwift.swift b/Benchmarks/Sources/Generated/BridgeJS.ExportSwift.swift index ee86def7..2d9f61b9 100644 --- a/Benchmarks/Sources/Generated/BridgeJS.ExportSwift.swift +++ b/Benchmarks/Sources/Generated/BridgeJS.ExportSwift.swift @@ -6,6 +6,136 @@ @_spi(BridgeJS) import JavaScriptKit +private extension APIResult { + static func bridgeJSLiftParameter(_ caseId: Int32) -> APIResult { + switch caseId { + case 0: + return .success(String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32())) + case 1: + return .failure(Int.bridgeJSLiftParameter(_swift_js_pop_param_int32())) + case 2: + return .flag(Bool.bridgeJSLiftParameter(_swift_js_pop_param_int32())) + case 3: + return .rate(Float.bridgeJSLiftParameter(_swift_js_pop_param_f32())) + case 4: + return .precise(Double.bridgeJSLiftParameter(_swift_js_pop_param_f64())) + case 5: + return .info + default: + fatalError("Unknown APIResult case ID: \(caseId)") + } + } + + func bridgeJSLowerReturn() { + switch self { + case .success(let param0): + _swift_js_push_tag(Int32(0)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) + } + case .failure(let param0): + _swift_js_push_tag(Int32(1)) + _swift_js_push_int(Int32(param0)) + case .flag(let param0): + _swift_js_push_tag(Int32(2)) + _swift_js_push_int(param0 ? 1 : 0) + case .rate(let param0): + _swift_js_push_tag(Int32(3)) + _swift_js_push_f32(param0) + case .precise(let param0): + _swift_js_push_tag(Int32(4)) + _swift_js_push_f64(param0) + case .info: + _swift_js_push_tag(Int32(5)) + } + } +} + +private extension ComplexResult { + static func bridgeJSLiftParameter(_ caseId: Int32) -> ComplexResult { + switch caseId { + case 0: + return .success(String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32())) + case 1: + return .error(String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32()), Int.bridgeJSLiftParameter(_swift_js_pop_param_int32())) + case 2: + return .location(Double.bridgeJSLiftParameter(_swift_js_pop_param_f64()), Double.bridgeJSLiftParameter(_swift_js_pop_param_f64()), String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32())) + case 3: + return .status(Bool.bridgeJSLiftParameter(_swift_js_pop_param_int32()), Int.bridgeJSLiftParameter(_swift_js_pop_param_int32()), String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32())) + case 4: + return .coordinates(Double.bridgeJSLiftParameter(_swift_js_pop_param_f64()), Double.bridgeJSLiftParameter(_swift_js_pop_param_f64()), Double.bridgeJSLiftParameter(_swift_js_pop_param_f64())) + case 5: + return .comprehensive(Bool.bridgeJSLiftParameter(_swift_js_pop_param_int32()), Bool.bridgeJSLiftParameter(_swift_js_pop_param_int32()), Int.bridgeJSLiftParameter(_swift_js_pop_param_int32()), Int.bridgeJSLiftParameter(_swift_js_pop_param_int32()), Double.bridgeJSLiftParameter(_swift_js_pop_param_f64()), Double.bridgeJSLiftParameter(_swift_js_pop_param_f64()), String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32()), String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32()), String.bridgeJSLiftParameter(_swift_js_pop_param_int32(), _swift_js_pop_param_int32())) + case 6: + return .info + default: + fatalError("Unknown ComplexResult case ID: \(caseId)") + } + } + + func bridgeJSLowerReturn() { + switch self { + case .success(let param0): + _swift_js_push_tag(Int32(0)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) + } + case .error(let param0, let param1): + _swift_js_push_tag(Int32(1)) + var __bjs_param0 = param0 + __bjs_param0.withUTF8 { ptr in + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) + } + _swift_js_push_int(Int32(param1)) + case .location(let param0, let param1, let param2): + _swift_js_push_tag(Int32(2)) + _swift_js_push_f64(param0) + _swift_js_push_f64(param1) + var __bjs_param2 = param2 + __bjs_param2.withUTF8 { ptr in + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) + } + case .status(let param0, let param1, let param2): + _swift_js_push_tag(Int32(3)) + _swift_js_push_int(param0 ? 1 : 0) + _swift_js_push_int(Int32(param1)) + var __bjs_param2 = param2 + __bjs_param2.withUTF8 { ptr in + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) + } + case .coordinates(let param0, let param1, let param2): + _swift_js_push_tag(Int32(4)) + _swift_js_push_f64(param0) + _swift_js_push_f64(param1) + _swift_js_push_f64(param2) + case .comprehensive(let param0, let param1, let param2, let param3, let param4, let param5, let param6, let param7, let param8): + _swift_js_push_tag(Int32(5)) + _swift_js_push_int(param0 ? 1 : 0) + _swift_js_push_int(param1 ? 1 : 0) + _swift_js_push_int(Int32(param2)) + _swift_js_push_int(Int32(param3)) + _swift_js_push_f64(param4) + _swift_js_push_f64(param5) + var __bjs_param6 = param6 + __bjs_param6.withUTF8 { ptr in + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) + } + var __bjs_param7 = param7 + __bjs_param7.withUTF8 { ptr in + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) + } + var __bjs_param8 = param8 + __bjs_param8.withUTF8 { ptr in + _swift_js_push_string(ptr.baseAddress, Int32(ptr.count)) + } + case .info: + _swift_js_push_tag(Int32(6)) + } + } +} + @_expose(wasm, "bjs_run") @_cdecl("bjs_run") public func _bjs_run() -> Void { @@ -14,4 +144,303 @@ public func _bjs_run() -> Void { #else fatalError("Only available on WebAssembly") #endif +} + +@_expose(wasm, "bjs_EnumRoundtrip_init") +@_cdecl("bjs_EnumRoundtrip_init") +public func _bjs_EnumRoundtrip_init() -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = EnumRoundtrip() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_EnumRoundtrip_take") +@_cdecl("bjs_EnumRoundtrip_take") +public func _bjs_EnumRoundtrip_take(_self: UnsafeMutableRawPointer, value: Int32) -> Void { + #if arch(wasm32) + EnumRoundtrip.bridgeJSLiftParameter(_self).take(_: APIResult.bridgeJSLiftParameter(value)) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_EnumRoundtrip_makeSuccess") +@_cdecl("bjs_EnumRoundtrip_makeSuccess") +public func _bjs_EnumRoundtrip_makeSuccess(_self: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + let ret = EnumRoundtrip.bridgeJSLiftParameter(_self).makeSuccess() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_EnumRoundtrip_makeFailure") +@_cdecl("bjs_EnumRoundtrip_makeFailure") +public func _bjs_EnumRoundtrip_makeFailure(_self: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + let ret = EnumRoundtrip.bridgeJSLiftParameter(_self).makeFailure() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_EnumRoundtrip_makeFlag") +@_cdecl("bjs_EnumRoundtrip_makeFlag") +public func _bjs_EnumRoundtrip_makeFlag(_self: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + let ret = EnumRoundtrip.bridgeJSLiftParameter(_self).makeFlag() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_EnumRoundtrip_makeRate") +@_cdecl("bjs_EnumRoundtrip_makeRate") +public func _bjs_EnumRoundtrip_makeRate(_self: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + let ret = EnumRoundtrip.bridgeJSLiftParameter(_self).makeRate() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_EnumRoundtrip_makePrecise") +@_cdecl("bjs_EnumRoundtrip_makePrecise") +public func _bjs_EnumRoundtrip_makePrecise(_self: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + let ret = EnumRoundtrip.bridgeJSLiftParameter(_self).makePrecise() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_EnumRoundtrip_makeInfo") +@_cdecl("bjs_EnumRoundtrip_makeInfo") +public func _bjs_EnumRoundtrip_makeInfo(_self: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + let ret = EnumRoundtrip.bridgeJSLiftParameter(_self).makeInfo() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_EnumRoundtrip_roundtrip") +@_cdecl("bjs_EnumRoundtrip_roundtrip") +public func _bjs_EnumRoundtrip_roundtrip(_self: UnsafeMutableRawPointer, result: Int32) -> Void { + #if arch(wasm32) + let ret = EnumRoundtrip.bridgeJSLiftParameter(_self).roundtrip(_: APIResult.bridgeJSLiftParameter(result)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_EnumRoundtrip_deinit") +@_cdecl("bjs_EnumRoundtrip_deinit") +public func _bjs_EnumRoundtrip_deinit(pointer: UnsafeMutableRawPointer) { + Unmanaged.fromOpaque(pointer).release() +} + +extension EnumRoundtrip: ConvertibleToJSValue, _BridgedSwiftHeapObject { + var jsValue: JSValue { + #if arch(wasm32) + @_extern(wasm, module: "Benchmarks", name: "bjs_EnumRoundtrip_wrap") + func _bjs_EnumRoundtrip_wrap(_: UnsafeMutableRawPointer) -> Int32 + #else + func _bjs_EnumRoundtrip_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") + } + #endif + return .object(JSObject(id: UInt32(bitPattern: _bjs_EnumRoundtrip_wrap(Unmanaged.passRetained(self).toOpaque())))) + } +} + +@_expose(wasm, "bjs_ComplexResultRoundtrip_init") +@_cdecl("bjs_ComplexResultRoundtrip_init") +public func _bjs_ComplexResultRoundtrip_init() -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = ComplexResultRoundtrip() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_ComplexResultRoundtrip_take") +@_cdecl("bjs_ComplexResultRoundtrip_take") +public func _bjs_ComplexResultRoundtrip_take(_self: UnsafeMutableRawPointer, value: Int32) -> Void { + #if arch(wasm32) + ComplexResultRoundtrip.bridgeJSLiftParameter(_self).take(_: ComplexResult.bridgeJSLiftParameter(value)) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_ComplexResultRoundtrip_makeSuccess") +@_cdecl("bjs_ComplexResultRoundtrip_makeSuccess") +public func _bjs_ComplexResultRoundtrip_makeSuccess(_self: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + let ret = ComplexResultRoundtrip.bridgeJSLiftParameter(_self).makeSuccess() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_ComplexResultRoundtrip_makeError") +@_cdecl("bjs_ComplexResultRoundtrip_makeError") +public func _bjs_ComplexResultRoundtrip_makeError(_self: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + let ret = ComplexResultRoundtrip.bridgeJSLiftParameter(_self).makeError() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_ComplexResultRoundtrip_makeLocation") +@_cdecl("bjs_ComplexResultRoundtrip_makeLocation") +public func _bjs_ComplexResultRoundtrip_makeLocation(_self: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + let ret = ComplexResultRoundtrip.bridgeJSLiftParameter(_self).makeLocation() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_ComplexResultRoundtrip_makeStatus") +@_cdecl("bjs_ComplexResultRoundtrip_makeStatus") +public func _bjs_ComplexResultRoundtrip_makeStatus(_self: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + let ret = ComplexResultRoundtrip.bridgeJSLiftParameter(_self).makeStatus() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_ComplexResultRoundtrip_makeCoordinates") +@_cdecl("bjs_ComplexResultRoundtrip_makeCoordinates") +public func _bjs_ComplexResultRoundtrip_makeCoordinates(_self: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + let ret = ComplexResultRoundtrip.bridgeJSLiftParameter(_self).makeCoordinates() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_ComplexResultRoundtrip_makeComprehensive") +@_cdecl("bjs_ComplexResultRoundtrip_makeComprehensive") +public func _bjs_ComplexResultRoundtrip_makeComprehensive(_self: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + let ret = ComplexResultRoundtrip.bridgeJSLiftParameter(_self).makeComprehensive() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_ComplexResultRoundtrip_makeInfo") +@_cdecl("bjs_ComplexResultRoundtrip_makeInfo") +public func _bjs_ComplexResultRoundtrip_makeInfo(_self: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + let ret = ComplexResultRoundtrip.bridgeJSLiftParameter(_self).makeInfo() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_ComplexResultRoundtrip_roundtrip") +@_cdecl("bjs_ComplexResultRoundtrip_roundtrip") +public func _bjs_ComplexResultRoundtrip_roundtrip(_self: UnsafeMutableRawPointer, result: Int32) -> Void { + #if arch(wasm32) + let ret = ComplexResultRoundtrip.bridgeJSLiftParameter(_self).roundtrip(_: ComplexResult.bridgeJSLiftParameter(result)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_ComplexResultRoundtrip_deinit") +@_cdecl("bjs_ComplexResultRoundtrip_deinit") +public func _bjs_ComplexResultRoundtrip_deinit(pointer: UnsafeMutableRawPointer) { + Unmanaged.fromOpaque(pointer).release() +} + +extension ComplexResultRoundtrip: ConvertibleToJSValue, _BridgedSwiftHeapObject { + var jsValue: JSValue { + #if arch(wasm32) + @_extern(wasm, module: "Benchmarks", name: "bjs_ComplexResultRoundtrip_wrap") + func _bjs_ComplexResultRoundtrip_wrap(_: UnsafeMutableRawPointer) -> Int32 + #else + func _bjs_ComplexResultRoundtrip_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") + } + #endif + return .object(JSObject(id: UInt32(bitPattern: _bjs_ComplexResultRoundtrip_wrap(Unmanaged.passRetained(self).toOpaque())))) + } +} + +@_expose(wasm, "bjs_StringRoundtrip_init") +@_cdecl("bjs_StringRoundtrip_init") +public func _bjs_StringRoundtrip_init() -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = StringRoundtrip() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_StringRoundtrip_take") +@_cdecl("bjs_StringRoundtrip_take") +public func _bjs_StringRoundtrip_take(_self: UnsafeMutableRawPointer, valueBytes: Int32, valueLength: Int32) -> Void { + #if arch(wasm32) + StringRoundtrip.bridgeJSLiftParameter(_self).take(_: String.bridgeJSLiftParameter(valueBytes, valueLength)) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_StringRoundtrip_make") +@_cdecl("bjs_StringRoundtrip_make") +public func _bjs_StringRoundtrip_make(_self: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + let ret = StringRoundtrip.bridgeJSLiftParameter(_self).make() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_StringRoundtrip_deinit") +@_cdecl("bjs_StringRoundtrip_deinit") +public func _bjs_StringRoundtrip_deinit(pointer: UnsafeMutableRawPointer) { + Unmanaged.fromOpaque(pointer).release() +} + +extension StringRoundtrip: ConvertibleToJSValue, _BridgedSwiftHeapObject { + var jsValue: JSValue { + #if arch(wasm32) + @_extern(wasm, module: "Benchmarks", name: "bjs_StringRoundtrip_wrap") + func _bjs_StringRoundtrip_wrap(_: UnsafeMutableRawPointer) -> Int32 + #else + func _bjs_StringRoundtrip_wrap(_: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") + } + #endif + return .object(JSObject(id: UInt32(bitPattern: _bjs_StringRoundtrip_wrap(Unmanaged.passRetained(self).toOpaque())))) + } } \ No newline at end of file diff --git a/Benchmarks/Sources/Generated/JavaScript/BridgeJS.ExportSwift.json b/Benchmarks/Sources/Generated/JavaScript/BridgeJS.ExportSwift.json index b00ec9ab..cfd7c19e 100644 --- a/Benchmarks/Sources/Generated/JavaScript/BridgeJS.ExportSwift.json +++ b/Benchmarks/Sources/Generated/JavaScript/BridgeJS.ExportSwift.json @@ -1,9 +1,671 @@ { "classes" : [ + { + "constructor" : { + "abiName" : "bjs_EnumRoundtrip_init", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "parameters" : [ + + ] + }, + "methods" : [ + { + "abiName" : "bjs_EnumRoundtrip_take", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "take", + "parameters" : [ + { + "label" : "_", + "name" : "value", + "type" : { + "associatedValueEnum" : { + "_0" : "APIResult" + } + } + } + ], + "returnType" : { + "void" : { + + } + } + }, + { + "abiName" : "bjs_EnumRoundtrip_makeSuccess", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "makeSuccess", + "parameters" : [ + + ], + "returnType" : { + "associatedValueEnum" : { + "_0" : "APIResult" + } + } + }, + { + "abiName" : "bjs_EnumRoundtrip_makeFailure", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "makeFailure", + "parameters" : [ + + ], + "returnType" : { + "associatedValueEnum" : { + "_0" : "APIResult" + } + } + }, + { + "abiName" : "bjs_EnumRoundtrip_makeFlag", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "makeFlag", + "parameters" : [ + + ], + "returnType" : { + "associatedValueEnum" : { + "_0" : "APIResult" + } + } + }, + { + "abiName" : "bjs_EnumRoundtrip_makeRate", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "makeRate", + "parameters" : [ + + ], + "returnType" : { + "associatedValueEnum" : { + "_0" : "APIResult" + } + } + }, + { + "abiName" : "bjs_EnumRoundtrip_makePrecise", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "makePrecise", + "parameters" : [ + + ], + "returnType" : { + "associatedValueEnum" : { + "_0" : "APIResult" + } + } + }, + { + "abiName" : "bjs_EnumRoundtrip_makeInfo", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "makeInfo", + "parameters" : [ + + ], + "returnType" : { + "associatedValueEnum" : { + "_0" : "APIResult" + } + } + }, + { + "abiName" : "bjs_EnumRoundtrip_roundtrip", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "roundtrip", + "parameters" : [ + { + "label" : "_", + "name" : "result", + "type" : { + "associatedValueEnum" : { + "_0" : "APIResult" + } + } + } + ], + "returnType" : { + "associatedValueEnum" : { + "_0" : "APIResult" + } + } + } + ], + "name" : "EnumRoundtrip", + "properties" : [ + + ], + "swiftCallName" : "EnumRoundtrip" + }, + { + "constructor" : { + "abiName" : "bjs_ComplexResultRoundtrip_init", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "parameters" : [ + + ] + }, + "methods" : [ + { + "abiName" : "bjs_ComplexResultRoundtrip_take", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "take", + "parameters" : [ + { + "label" : "_", + "name" : "value", + "type" : { + "associatedValueEnum" : { + "_0" : "ComplexResult" + } + } + } + ], + "returnType" : { + "void" : { + + } + } + }, + { + "abiName" : "bjs_ComplexResultRoundtrip_makeSuccess", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "makeSuccess", + "parameters" : [ + + ], + "returnType" : { + "associatedValueEnum" : { + "_0" : "ComplexResult" + } + } + }, + { + "abiName" : "bjs_ComplexResultRoundtrip_makeError", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "makeError", + "parameters" : [ + + ], + "returnType" : { + "associatedValueEnum" : { + "_0" : "ComplexResult" + } + } + }, + { + "abiName" : "bjs_ComplexResultRoundtrip_makeLocation", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "makeLocation", + "parameters" : [ + + ], + "returnType" : { + "associatedValueEnum" : { + "_0" : "ComplexResult" + } + } + }, + { + "abiName" : "bjs_ComplexResultRoundtrip_makeStatus", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "makeStatus", + "parameters" : [ + + ], + "returnType" : { + "associatedValueEnum" : { + "_0" : "ComplexResult" + } + } + }, + { + "abiName" : "bjs_ComplexResultRoundtrip_makeCoordinates", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "makeCoordinates", + "parameters" : [ + + ], + "returnType" : { + "associatedValueEnum" : { + "_0" : "ComplexResult" + } + } + }, + { + "abiName" : "bjs_ComplexResultRoundtrip_makeComprehensive", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "makeComprehensive", + "parameters" : [ + + ], + "returnType" : { + "associatedValueEnum" : { + "_0" : "ComplexResult" + } + } + }, + { + "abiName" : "bjs_ComplexResultRoundtrip_makeInfo", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "makeInfo", + "parameters" : [ + + ], + "returnType" : { + "associatedValueEnum" : { + "_0" : "ComplexResult" + } + } + }, + { + "abiName" : "bjs_ComplexResultRoundtrip_roundtrip", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "roundtrip", + "parameters" : [ + { + "label" : "_", + "name" : "result", + "type" : { + "associatedValueEnum" : { + "_0" : "ComplexResult" + } + } + } + ], + "returnType" : { + "associatedValueEnum" : { + "_0" : "ComplexResult" + } + } + } + ], + "name" : "ComplexResultRoundtrip", + "properties" : [ + + ], + "swiftCallName" : "ComplexResultRoundtrip" + }, + { + "constructor" : { + "abiName" : "bjs_StringRoundtrip_init", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "parameters" : [ + + ] + }, + "methods" : [ + { + "abiName" : "bjs_StringRoundtrip_take", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "take", + "parameters" : [ + { + "label" : "_", + "name" : "value", + "type" : { + "string" : { + + } + } + } + ], + "returnType" : { + "void" : { + + } + } + }, + { + "abiName" : "bjs_StringRoundtrip_make", + "effects" : { + "isAsync" : false, + "isThrows" : false + }, + "name" : "make", + "parameters" : [ + + ], + "returnType" : { + "string" : { + + } + } + } + ], + "name" : "StringRoundtrip", + "properties" : [ + ], + "swiftCallName" : "StringRoundtrip" + } ], "enums" : [ + { + "cases" : [ + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "success" + }, + { + "associatedValues" : [ + { + "type" : { + "int" : { + + } + } + } + ], + "name" : "failure" + }, + { + "associatedValues" : [ + { + "type" : { + "bool" : { + + } + } + } + ], + "name" : "flag" + }, + { + "associatedValues" : [ + { + "type" : { + "float" : { + + } + } + } + ], + "name" : "rate" + }, + { + "associatedValues" : [ + { + "type" : { + "double" : { + + } + } + } + ], + "name" : "precise" + }, + { + "associatedValues" : [ + + ], + "name" : "info" + } + ], + "emitStyle" : "const", + "name" : "APIResult", + "swiftCallName" : "APIResult" + }, + { + "cases" : [ + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "success" + }, + { + "associatedValues" : [ + { + "type" : { + "string" : { + + } + } + }, + { + "type" : { + "int" : { + + } + } + } + ], + "name" : "error" + }, + { + "associatedValues" : [ + { + "type" : { + "double" : { + + } + } + }, + { + "type" : { + "double" : { + + } + } + }, + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "location" + }, + { + "associatedValues" : [ + { + "type" : { + "bool" : { + } + } + }, + { + "type" : { + "int" : { + + } + } + }, + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "status" + }, + { + "associatedValues" : [ + { + "type" : { + "double" : { + + } + } + }, + { + "type" : { + "double" : { + + } + } + }, + { + "type" : { + "double" : { + + } + } + } + ], + "name" : "coordinates" + }, + { + "associatedValues" : [ + { + "type" : { + "bool" : { + + } + } + }, + { + "type" : { + "bool" : { + + } + } + }, + { + "type" : { + "int" : { + + } + } + }, + { + "type" : { + "int" : { + + } + } + }, + { + "type" : { + "double" : { + + } + } + }, + { + "type" : { + "double" : { + + } + } + }, + { + "type" : { + "string" : { + + } + } + }, + { + "type" : { + "string" : { + + } + } + }, + { + "type" : { + "string" : { + + } + } + } + ], + "name" : "comprehensive" + }, + { + "associatedValues" : [ + + ], + "name" : "info" + } + ], + "emitStyle" : "const", + "name" : "ComplexResult", + "swiftCallName" : "ComplexResult" + } ], "functions" : [ { diff --git a/Benchmarks/run.js b/Benchmarks/run.js index 17b19214..d4747311 100644 --- a/Benchmarks/run.js +++ b/Benchmarks/run.js @@ -3,6 +3,7 @@ import { defaultNodeSetup } from "./.build/plugins/PackageToJS/outputs/Package/p import fs from 'fs'; import path from 'path'; import { parseArgs } from "util"; +import { APIResult, ComplexResult } from "./.build/plugins/PackageToJS/outputs/Package/bridge-js.js"; /** * Update progress bar on the current line @@ -288,6 +289,171 @@ async function singleRun(results, nameFilter) { }) }); exports.run(); + + const enumRoundtrip = new exports.EnumRoundtrip(); + const iterations = 100_000; + benchmarkRunner("EnumRoundtrip/takeEnum success", () => { + for (let i = 0; i < iterations; i++) { + enumRoundtrip.take({ tag: APIResult.Tag.Success, param0: "Hello, world" }) + } + }) + benchmarkRunner("EnumRoundtrip/takeEnum failure", () => { + for (let i = 0; i < iterations; i++) { + enumRoundtrip.take({ tag: APIResult.Tag.Failure, param0: 42 }) + } + }) + benchmarkRunner("EnumRoundtrip/takeEnum flag", () => { + for (let i = 0; i < iterations; i++) { + enumRoundtrip.take({ tag: APIResult.Tag.Flag, param0: true }) + } + }) + benchmarkRunner("EnumRoundtrip/takeEnum rate", () => { + for (let i = 0; i < iterations; i++) { + enumRoundtrip.take({ tag: APIResult.Tag.Rate, param0: 0.5 }) + } + }) + benchmarkRunner("EnumRoundtrip/takeEnum precise", () => { + for (let i = 0; i < iterations; i++) { + enumRoundtrip.take({ tag: APIResult.Tag.Precise, param0: 0.5 }) + } + }) + benchmarkRunner("EnumRoundtrip/takeEnum info", () => { + for (let i = 0; i < iterations; i++) { + enumRoundtrip.take({ tag: APIResult.Tag.Info }) + } + }) + benchmarkRunner("EnumRoundtrip/makeSuccess", () => { + for (let i = 0; i < iterations; i++) { + enumRoundtrip.makeSuccess() + } + }) + benchmarkRunner("EnumRoundtrip/makeFailure", () => { + for (let i = 0; i < iterations; i++) { + enumRoundtrip.makeFailure() + } + }) + benchmarkRunner("EnumRoundtrip/makeFlag", () => { + for (let i = 0; i < iterations; i++) { + enumRoundtrip.makeFlag() + } + }) + benchmarkRunner("EnumRoundtrip/makeRate", () => { + for (let i = 0; i < iterations; i++) { + enumRoundtrip.makeRate() + } + }) + benchmarkRunner("EnumRoundtrip/makePrecise", () => { + for (let i = 0; i < iterations; i++) { + enumRoundtrip.makePrecise() + } + }) + benchmarkRunner("EnumRoundtrip/makeInfo", () => { + for (let i = 0; i < iterations; i++) { + enumRoundtrip.makeInfo() + } + }) + + benchmarkRunner("EnumRoundtrip/roundtrip", () => { + for (let i = 0; i < iterations; i++) { + enumRoundtrip.roundtrip({ tag: APIResult.Tag.Success, param0: "Hello, world" }) + } + }) + + const complexResultRoundtrip = new exports.ComplexResultRoundtrip(); + + benchmarkRunner("ComplexResultRoundtrip/takeEnum success", () => { + for (let i = 0; i < iterations; i++) { + complexResultRoundtrip.take({ tag: ComplexResult.Tag.Success, param0: "Operation completed" }) + } + }) + benchmarkRunner("ComplexResultRoundtrip/takeEnum error", () => { + for (let i = 0; i < iterations; i++) { + complexResultRoundtrip.take({ tag: ComplexResult.Tag.Error, param0: "Network timeout", param1: 503 }) + } + }) + benchmarkRunner("ComplexResultRoundtrip/takeEnum location", () => { + for (let i = 0; i < iterations; i++) { + complexResultRoundtrip.take({ tag: ComplexResult.Tag.Location, param0: 37.7749, param1: -122.4194, param2: "San Francisco" }) + } + }) + benchmarkRunner("ComplexResultRoundtrip/takeEnum status", () => { + for (let i = 0; i < iterations; i++) { + complexResultRoundtrip.take({ tag: ComplexResult.Tag.Status, param0: true, param1: 200, param2: "OK" }) + } + }) + benchmarkRunner("ComplexResultRoundtrip/takeEnum coordinates", () => { + for (let i = 0; i < iterations; i++) { + complexResultRoundtrip.take({ tag: ComplexResult.Tag.Coordinates, param0: 10.5, param1: 20.3, param2: 30.7 }) + } + }) + benchmarkRunner("ComplexResultRoundtrip/takeEnum comprehensive", () => { + for (let i = 0; i < iterations; i++) { + complexResultRoundtrip.take({ + tag: ComplexResult.Tag.Comprehensive, + param0: true, param1: false, param2: 42, param3: 100, + param4: 3.14, param5: 2.718, param6: "Hello", param7: "World", param8: "Test" + }) + } + }) + benchmarkRunner("ComplexResultRoundtrip/takeEnum info", () => { + for (let i = 0; i < iterations; i++) { + complexResultRoundtrip.take({ tag: ComplexResult.Tag.Info }) + } + }) + + benchmarkRunner("ComplexResultRoundtrip/makeSuccess", () => { + for (let i = 0; i < iterations; i++) { + complexResultRoundtrip.makeSuccess() + } + }) + benchmarkRunner("ComplexResultRoundtrip/makeError", () => { + for (let i = 0; i < iterations; i++) { + complexResultRoundtrip.makeError() + } + }) + benchmarkRunner("ComplexResultRoundtrip/makeLocation", () => { + for (let i = 0; i < iterations; i++) { + complexResultRoundtrip.makeLocation() + } + }) + benchmarkRunner("ComplexResultRoundtrip/makeStatus", () => { + for (let i = 0; i < iterations; i++) { + complexResultRoundtrip.makeStatus() + } + }) + benchmarkRunner("ComplexResultRoundtrip/makeCoordinates", () => { + for (let i = 0; i < iterations; i++) { + complexResultRoundtrip.makeCoordinates() + } + }) + benchmarkRunner("ComplexResultRoundtrip/makeComprehensive", () => { + for (let i = 0; i < iterations; i++) { + complexResultRoundtrip.makeComprehensive() + } + }) + benchmarkRunner("ComplexResultRoundtrip/makeInfo", () => { + for (let i = 0; i < iterations; i++) { + complexResultRoundtrip.makeInfo() + } + }) + + benchmarkRunner("ComplexResultRoundtrip/roundtrip", () => { + for (let i = 0; i < iterations; i++) { + complexResultRoundtrip.roundtrip({ tag: ComplexResult.Tag.Success, param0: "Hello, world" }) + } + }) + + const stringRoundtrip = new exports.StringRoundtrip(); + benchmarkRunner("StringRoundtrip/takeString", () => { + for (let i = 0; i < iterations; i++) { + stringRoundtrip.take("Hello, world") + } + }) + benchmarkRunner("StringRoundtrip/makeString", () => { + for (let i = 0; i < iterations; i++) { + stringRoundtrip.make() + } + }) } /**