diff --git a/Benchmarks/Sources/Generated/BridgeJS.swift b/Benchmarks/Sources/Generated/BridgeJS.swift index 1a413268..5a480694 100644 --- a/Benchmarks/Sources/Generated/BridgeJS.swift +++ b/Benchmarks/Sources/Generated/BridgeJS.swift @@ -64,20 +64,20 @@ extension APIResult: _BridgedSwiftAssociatedValueEnum { @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() { switch self { case .success(let param0): - _swift_js_push_tag(Int32(0)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(0)) case .failure(let param0): - _swift_js_push_tag(Int32(1)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(1)) case .flag(let param0): - _swift_js_push_tag(Int32(2)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(2)) case .rate(let param0): - _swift_js_push_tag(Int32(3)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(3)) case .precise(let param0): - _swift_js_push_tag(Int32(4)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(4)) case .info: _swift_js_push_tag(Int32(5)) } @@ -161,29 +161,28 @@ extension ComplexResult: _BridgedSwiftAssociatedValueEnum { @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() { switch self { case .success(let param0): - _swift_js_push_tag(Int32(0)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(0)) case .error(let param0, let param1): - _swift_js_push_tag(Int32(1)) param0.bridgeJSLowerStackReturn() param1.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(1)) case .location(let param0, let param1, let param2): - _swift_js_push_tag(Int32(2)) param0.bridgeJSLowerStackReturn() param1.bridgeJSLowerStackReturn() param2.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(2)) case .status(let param0, let param1, let param2): - _swift_js_push_tag(Int32(3)) param0.bridgeJSLowerStackReturn() param1.bridgeJSLowerStackReturn() param2.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(3)) case .coordinates(let param0, let param1, let param2): - _swift_js_push_tag(Int32(4)) param0.bridgeJSLowerStackReturn() param1.bridgeJSLowerStackReturn() param2.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(4)) 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)) param0.bridgeJSLowerStackReturn() param1.bridgeJSLowerStackReturn() param2.bridgeJSLowerStackReturn() @@ -193,6 +192,7 @@ extension ComplexResult: _BridgedSwiftAssociatedValueEnum { param6.bridgeJSLowerStackReturn() param7.bridgeJSLowerStackReturn() param8.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(5)) case .info: _swift_js_push_tag(Int32(6)) } diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift index 1137343b..51ff9169 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift @@ -1221,9 +1221,11 @@ struct EnumCodegen { .map { index, associatedValue in "let \(associatedValue.label ?? "param\(index)")" } .joined(separator: ", ") cases.append("case .\(enumCase.name)(\(pattern)):") - cases.append("_swift_js_push_tag(Int32(\(caseIndex)))") let payloadCode = generatePayloadPushingCode(associatedValues: enumCase.associatedValues) cases.append(contentsOf: payloadCode) + // Push tag AFTER payloads so it's popped first (LIFO) by the JS lift function. + // This ensures nested enum tags don't overwrite the outer tag. + cases.append("_swift_js_push_tag(Int32(\(caseIndex)))") } } return cases diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/SwiftToSkeleton.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/SwiftToSkeleton.swift index d32d85f5..39e3090c 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/SwiftToSkeleton.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/SwiftToSkeleton.swift @@ -1428,18 +1428,20 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { for enumCase in exportedEnum.cases { for associatedValue in enumCase.associatedValues { switch associatedValue.type { - case .string, .int, .float, .double, .bool: + case .string, .int, .float, .double, .bool, .caseEnum, .rawValueEnum, + .swiftStruct, .swiftHeapObject, .jsObject, .associatedValueEnum, .array: break case .nullable(let wrappedType, _): switch wrappedType { - case .string, .int, .float, .double, .bool: + case .string, .int, .float, .double, .bool, .caseEnum, .rawValueEnum, + .swiftStruct, .swiftHeapObject, .jsObject, .associatedValueEnum, .array: break default: diagnose( node: node, message: "Unsupported associated value type: \(associatedValue.type.swiftType)", hint: - "Only primitive types and optional primitives (String?, Int?, Float?, Double?, Bool?) are supported in associated-value enums" + "Only primitive types, enums, structs, classes, JSObject, arrays, and their optionals are supported in associated-value enums" ) } default: @@ -1447,7 +1449,7 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { node: node, message: "Unsupported associated value type: \(associatedValue.type.swiftType)", hint: - "Only primitive types and optional primitives (String?, Int?, Float?, Double?, Bool?) are supported in associated-value enums" + "Only primitive types, enums, structs, classes, JSObject, arrays, and their optionals are supported in associated-value enums" ) } } diff --git a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift index 4695f328..27ef6076 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift @@ -246,7 +246,7 @@ public struct BridgeJSLink { "let \(JSGlueVariableScope.reservedStorageToReturnOptionalFloat);", "let \(JSGlueVariableScope.reservedStorageToReturnOptionalDouble);", "let \(JSGlueVariableScope.reservedStorageToReturnOptionalHeapObject);", - "let \(JSGlueVariableScope.reservedTmpRetTag);", + "let \(JSGlueVariableScope.reservedTmpRetTag) = [];", "let \(JSGlueVariableScope.reservedTmpRetStrings) = [];", "let \(JSGlueVariableScope.reservedTmpRetInts) = [];", "let \(JSGlueVariableScope.reservedTmpRetF32s) = [];", @@ -388,7 +388,7 @@ public struct BridgeJSLink { printer.write("}") printer.write("bjs[\"swift_js_push_tag\"] = function(tag) {") printer.indent { - printer.write("\(JSGlueVariableScope.reservedTmpRetTag) = tag;") + printer.write("\(JSGlueVariableScope.reservedTmpRetTag).push(tag);") } printer.write("}") printer.write("bjs[\"swift_js_push_i32\"] = function(v) {") @@ -1059,6 +1059,18 @@ public struct BridgeJSLink { _ = fragment.printCode([structDef.name], structScope, structPrinter, structCleanup) bodyPrinter.write(lines: structPrinter.lines) } + + let allAssocEnums = exportedSkeletons.flatMap { + $0.enums.filter { $0.enumType == .associatedValue } + } + for enumDef in allAssocEnums { + let enumPrinter = CodeFragmentPrinter() + let enumScope = JSGlueVariableScope() + let enumCleanup = CodeFragmentPrinter() + let fragment = IntrinsicJSFragment.associatedValueEnumHelperFactory(enumDefinition: enumDef) + _ = fragment.printCode([enumDef.valuesName], enumScope, enumPrinter, enumCleanup) + bodyPrinter.write(lines: enumPrinter.lines) + } bodyPrinter.nextLine() bodyPrinter.write(contentsOf: generateAddImports(needsImportsObject: data.needsImportsObject)) @@ -1094,8 +1106,6 @@ public struct BridgeJSLink { "\(JSGlueVariableScope.reservedMemory) = \(JSGlueVariableScope.reservedInstance).exports.memory;", ]) printer.nextLine() - // Enum helpers section - printer.write(contentsOf: enumHelperAssignments()) // Error handling printer.write("\(JSGlueVariableScope.reservedSetException) = (error) => {") printer.indent { @@ -1109,18 +1119,19 @@ public struct BridgeJSLink { } // createExports method - try printer.indent { + printer.indent { printer.write(lines: [ "/** @param {WebAssembly.Instance} instance */", "createExports: (instance) => {", ]) - try printer.indent { + printer.indent { printer.write("const js = \(JSGlueVariableScope.reservedSwift).memory.heap;") printer.write(lines: data.classLines) - // Struct helpers must be initialized AFTER classes are defined (to allow _exports access) + // Struct and enum helpers must be initialized AFTER classes are defined (to allow _exports access) printer.write(contentsOf: structHelperAssignments()) + printer.write(contentsOf: enumHelperAssignments()) let namespaceInitCode = namespaceBuilder.buildNamespaceInitialization( exportedSkeletons: exportedSkeletons ) @@ -1151,7 +1162,7 @@ public struct BridgeJSLink { for skeleton in skeletons.compactMap(\.exported) { for enumDef in skeleton.enums where enumDef.enumType == .associatedValue { printer.write( - "const \(enumDef.name)Helpers = __bjs_create\(enumDef.valuesName)Helpers()(\(JSGlueVariableScope.reservedTmpParamInts), \(JSGlueVariableScope.reservedTmpParamF32s), \(JSGlueVariableScope.reservedTmpParamF64s), \(JSGlueVariableScope.reservedTextEncoder), \(JSGlueVariableScope.reservedSwift));" + "const \(enumDef.name)Helpers = __bjs_create\(enumDef.valuesName)Helpers()(\(JSGlueVariableScope.reservedTmpParamInts), \(JSGlueVariableScope.reservedTmpParamF32s), \(JSGlueVariableScope.reservedTmpParamF64s), \(JSGlueVariableScope.reservedTmpParamPointers), \(JSGlueVariableScope.reservedTmpRetPointers), \(JSGlueVariableScope.reservedTextEncoder), \(JSGlueVariableScope.reservedSwift), \(JSGlueVariableScope.reservedStructHelpers), \(JSGlueVariableScope.reservedEnumHelpers));" ) printer.write("\(JSGlueVariableScope.reservedEnumHelpers).\(enumDef.name) = \(enumDef.name)Helpers;") printer.nextLine() @@ -1616,7 +1627,7 @@ public struct BridgeJSLink { _ = fragment.printCode([enumValuesName], scope, printer, cleanup) jsTopLevelLines.append(contentsOf: printer.lines) case .associatedValue: - let fragment = IntrinsicJSFragment.associatedValueEnumHelper(enumDefinition: enumDefinition) + let fragment = IntrinsicJSFragment.associatedValueEnumValues(enumDefinition: enumDefinition) _ = fragment.printCode([enumValuesName], scope, printer, cleanup) jsTopLevelLines.append(contentsOf: printer.lines) case .namespace: diff --git a/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift b/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift index ef72cf6f..1547d63a 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift @@ -571,7 +571,7 @@ struct IntrinsicJSFragment: Sendable { printCode: { _, scope, printer, _ in let retName = scope.variable("ret") printer.write( - "const \(retName) = \(JSGlueVariableScope.reservedEnumHelpers).\(enumBase).lift(\(JSGlueVariableScope.reservedTmpRetTag), \(JSGlueVariableScope.reservedTmpRetStrings), \(JSGlueVariableScope.reservedTmpRetInts), \(JSGlueVariableScope.reservedTmpRetF32s), \(JSGlueVariableScope.reservedTmpRetF64s));" + "const \(retName) = \(JSGlueVariableScope.reservedEnumHelpers).\(enumBase).lift(\(JSGlueVariableScope.reservedTmpRetTag).pop(), \(JSGlueVariableScope.reservedTmpRetStrings), \(JSGlueVariableScope.reservedTmpRetInts), \(JSGlueVariableScope.reservedTmpRetF32s), \(JSGlueVariableScope.reservedTmpRetF64s), \(JSGlueVariableScope.reservedTmpRetPointers));" ) return [retName] } @@ -652,7 +652,7 @@ struct IntrinsicJSFragment: Sendable { printer.write("if (\(isSome)) {") printer.indent { printer.write( - "\(enumVar) = \(JSGlueVariableScope.reservedEnumHelpers).\(base).lift(\(wrappedValue), \(JSGlueVariableScope.reservedTmpRetStrings), \(JSGlueVariableScope.reservedTmpRetInts), \(JSGlueVariableScope.reservedTmpRetF32s), \(JSGlueVariableScope.reservedTmpRetF64s));" + "\(enumVar) = \(JSGlueVariableScope.reservedEnumHelpers).\(base).lift(\(wrappedValue), \(JSGlueVariableScope.reservedTmpRetStrings), \(JSGlueVariableScope.reservedTmpRetInts), \(JSGlueVariableScope.reservedTmpRetF32s), \(JSGlueVariableScope.reservedTmpRetF64s), \(JSGlueVariableScope.reservedTmpRetPointers));" ) } printer.write("}") @@ -678,7 +678,6 @@ struct IntrinsicJSFragment: Sendable { printer.write("let \(arrayVar);") printer.write("if (\(isSome)) {") printer.indent { - // Lift array from stacks - reuse array lift return logic let arrayLiftFragment = try! arrayLift(elementType: elementType) let liftResults = arrayLiftFragment.printCode([], scope, printer, cleanupCode) if let liftResult = liftResults.first { @@ -886,8 +885,10 @@ struct IntrinsicJSFragment: Sendable { } case .associatedValueEnum(let fullName): let base = fullName.components(separatedBy: ".").last ?? fullName + let tagVar = scope.variable("tag") + printer.write("const \(tagVar) = \(JSGlueVariableScope.reservedTmpRetTag).pop();") let isNullVar = scope.variable("isNull") - printer.write("const \(isNullVar) = (\(JSGlueVariableScope.reservedTmpRetTag) === -1);") + printer.write("const \(isNullVar) = (\(tagVar) === -1);") printer.write("let \(resultVar);") printer.write("if (\(isNullVar)) {") printer.indent { @@ -896,7 +897,7 @@ struct IntrinsicJSFragment: Sendable { printer.write("} else {") printer.indent { printer.write( - "\(resultVar) = \(JSGlueVariableScope.reservedEnumHelpers).\(base).lift(\(JSGlueVariableScope.reservedTmpRetTag), \(JSGlueVariableScope.reservedTmpRetStrings), \(JSGlueVariableScope.reservedTmpRetInts), \(JSGlueVariableScope.reservedTmpRetF32s), \(JSGlueVariableScope.reservedTmpRetF64s));" + "\(resultVar) = \(JSGlueVariableScope.reservedEnumHelpers).\(base).lift(\(tagVar), \(JSGlueVariableScope.reservedTmpRetStrings), \(JSGlueVariableScope.reservedTmpRetInts), \(JSGlueVariableScope.reservedTmpRetF32s), \(JSGlueVariableScope.reservedTmpRetF64s), \(JSGlueVariableScope.reservedTmpRetPointers));" ) } printer.write("}") @@ -1233,7 +1234,7 @@ struct IntrinsicJSFragment: Sendable { let targetVar = arguments[1] let base = fullName.components(separatedBy: ".").last ?? fullName printer.write( - "let \(targetVar) = \(JSGlueVariableScope.reservedEnumHelpers).\(base).lift(\(caseId), \(JSGlueVariableScope.reservedTmpRetStrings), \(JSGlueVariableScope.reservedTmpRetInts), \(JSGlueVariableScope.reservedTmpRetF32s), \(JSGlueVariableScope.reservedTmpRetF64s));" + "let \(targetVar) = \(JSGlueVariableScope.reservedEnumHelpers).\(base).lift(\(caseId), \(JSGlueVariableScope.reservedTmpRetStrings), \(JSGlueVariableScope.reservedTmpRetInts), \(JSGlueVariableScope.reservedTmpRetF32s), \(JSGlueVariableScope.reservedTmpRetF64s), \(JSGlueVariableScope.reservedTmpRetPointers));" ) return [] } @@ -1304,7 +1305,7 @@ struct IntrinsicJSFragment: Sendable { case .associatedValueEnum(let fullName): let base = fullName.components(separatedBy: ".").last ?? fullName printer.write( - "\(targetVar) = \(JSGlueVariableScope.reservedEnumHelpers).\(base).lift(\(value), \(JSGlueVariableScope.reservedTmpRetStrings), \(JSGlueVariableScope.reservedTmpRetInts), \(JSGlueVariableScope.reservedTmpRetF32s), \(JSGlueVariableScope.reservedTmpRetF64s));" + "\(targetVar) = \(JSGlueVariableScope.reservedEnumHelpers).\(base).lift(\(value), \(JSGlueVariableScope.reservedTmpRetStrings), \(JSGlueVariableScope.reservedTmpRetInts), \(JSGlueVariableScope.reservedTmpRetF32s), \(JSGlueVariableScope.reservedTmpRetF64s), \(JSGlueVariableScope.reservedTmpRetPointers));" ) default: fatalError("Unsupported optional wrapped type in closure parameter lifting: \(wrappedType)") @@ -1632,7 +1633,7 @@ struct IntrinsicJSFragment: Sendable { let base = fullName.components(separatedBy: ".").last ?? fullName let resultVar = scope.variable("result") printer.write( - "const \(resultVar) = \(JSGlueVariableScope.reservedEnumHelpers).\(base).lift(\(JSGlueVariableScope.reservedTmpRetTag), \(JSGlueVariableScope.reservedTmpRetStrings), \(JSGlueVariableScope.reservedTmpRetInts), \(JSGlueVariableScope.reservedTmpRetF32s), \(JSGlueVariableScope.reservedTmpRetF64s));" + "const \(resultVar) = \(JSGlueVariableScope.reservedEnumHelpers).\(base).lift(\(JSGlueVariableScope.reservedTmpRetTag).pop(), \(JSGlueVariableScope.reservedTmpRetStrings), \(JSGlueVariableScope.reservedTmpRetInts), \(JSGlueVariableScope.reservedTmpRetF32s), \(JSGlueVariableScope.reservedTmpRetF64s), \(JSGlueVariableScope.reservedTmpRetPointers));" ) printer.write("return \(resultVar);") return [] @@ -1857,7 +1858,7 @@ struct IntrinsicJSFragment: Sendable { let caseId = arguments[0] let resultVar = scope.variable("enumValue") printer.write( - "const \(resultVar) = \(JSGlueVariableScope.reservedEnumHelpers).\(base).lift(\(caseId), \(JSGlueVariableScope.reservedTmpRetStrings), \(JSGlueVariableScope.reservedTmpRetInts), \(JSGlueVariableScope.reservedTmpRetF32s), \(JSGlueVariableScope.reservedTmpRetF64s));" + "const \(resultVar) = \(JSGlueVariableScope.reservedEnumHelpers).\(base).lift(\(caseId), \(JSGlueVariableScope.reservedTmpRetStrings), \(JSGlueVariableScope.reservedTmpRetInts), \(JSGlueVariableScope.reservedTmpRetF32s), \(JSGlueVariableScope.reservedTmpRetF64s), \(JSGlueVariableScope.reservedTmpRetPointers));" ) return [resultVar] } @@ -2001,13 +2002,14 @@ struct IntrinsicJSFragment: Sendable { ) } /// Fragment for generating an entire associated value enum helper - static func associatedValueEnumHelper(enumDefinition: ExportedEnum) -> IntrinsicJSFragment { + /// Generates the enum tag constants (e.g. `const XValues = { Tag: { ... } }`) + /// This is placed at module level for exports/imports. + static func associatedValueEnumValues(enumDefinition: ExportedEnum) -> IntrinsicJSFragment { return IntrinsicJSFragment( parameters: ["enumName"], printCode: { arguments, scope, printer, cleanup in let enumName = arguments[0] - // Generate the enum tag object printer.write("const \(enumName) = {") printer.indent { printer.write("Tag: {") @@ -2020,13 +2022,25 @@ struct IntrinsicJSFragment: Sendable { printer.write("},") } printer.write("};") - printer.nextLine() - // Generate the helper function + return [] + } + ) + } + + /// Generates the enum helper factory function (lower/lift closures). + /// This is placed inside `createInstantiator` alongside struct helpers, + /// so it has access to `_exports` for class references. + static func associatedValueEnumHelperFactory(enumDefinition: ExportedEnum) -> IntrinsicJSFragment { + return IntrinsicJSFragment( + parameters: ["enumName"], + printCode: { arguments, scope, printer, cleanup in + let enumName = arguments[0] + printer.write("const __bjs_create\(enumName)Helpers = () => {") printer.indent() printer.write( - "return (\(JSGlueVariableScope.reservedTmpParamInts), \(JSGlueVariableScope.reservedTmpParamF32s), \(JSGlueVariableScope.reservedTmpParamF64s), textEncoder, \(JSGlueVariableScope.reservedSwift)) => ({" + "return (\(JSGlueVariableScope.reservedTmpParamInts), \(JSGlueVariableScope.reservedTmpParamF32s), \(JSGlueVariableScope.reservedTmpParamF64s), \(JSGlueVariableScope.reservedTmpParamPointers), \(JSGlueVariableScope.reservedTmpRetPointers), textEncoder, \(JSGlueVariableScope.reservedSwift), \(JSGlueVariableScope.reservedStructHelpers), \(JSGlueVariableScope.reservedEnumHelpers)) => ({" ) printer.indent() @@ -2058,10 +2072,10 @@ struct IntrinsicJSFragment: Sendable { // Generate lift function printer.write( - "lift: (\(JSGlueVariableScope.reservedTmpRetTag), \(JSGlueVariableScope.reservedTmpRetStrings), \(JSGlueVariableScope.reservedTmpRetInts), \(JSGlueVariableScope.reservedTmpRetF32s), \(JSGlueVariableScope.reservedTmpRetF64s)) => {" + "lift: (tag, \(JSGlueVariableScope.reservedTmpRetStrings), \(JSGlueVariableScope.reservedTmpRetInts), \(JSGlueVariableScope.reservedTmpRetF32s), \(JSGlueVariableScope.reservedTmpRetF64s), \(JSGlueVariableScope.reservedTmpRetPointers)) => {" ) printer.indent { - printer.write("const tag = tmpRetTag | 0;") + printer.write("tag = tag | 0;") printer.write("switch (tag) {") printer.indent { let liftPrinter = CodeFragmentPrinter() @@ -2228,62 +2242,77 @@ struct IntrinsicJSFragment: Sendable { private static func associatedValuePushPayload(type: BridgeType) -> IntrinsicJSFragment { switch type { - case .string: - return IntrinsicJSFragment( - parameters: ["value"], - printCode: { arguments, scope, printer, cleanup in - let value = arguments[0] - let bytesVar = scope.variable("bytes") - let idVar = scope.variable("id") - printer.write("const \(bytesVar) = \(JSGlueVariableScope.reservedTextEncoder).encode(\(value));") - printer.write("const \(idVar) = \(JSGlueVariableScope.reservedSwift).memory.retain(\(bytesVar));") - printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(bytesVar).length);") - printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(idVar));") - cleanup.write("\(JSGlueVariableScope.reservedSwift).memory.release(\(idVar));") - return [] - } - ) - case .bool: - return IntrinsicJSFragment( - parameters: ["value"], - printCode: { arguments, scope, printer, cleanup in - printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(arguments[0]) ? 1 : 0);") - return [] - } - ) - case .int, .uint: - return IntrinsicJSFragment( - parameters: ["value"], - printCode: { arguments, scope, printer, cleanup in - printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push((\(arguments[0]) | 0));") - return [] - } - ) - case .float: - return IntrinsicJSFragment( - parameters: ["value"], - printCode: { arguments, scope, printer, cleanup in - printer.write("\(JSGlueVariableScope.reservedTmpParamF32s).push(Math.fround(\(arguments[0])));") - return [] - } - ) - case .double: - return IntrinsicJSFragment( - parameters: ["value"], - printCode: { arguments, scope, printer, cleanup in - printer.write("\(JSGlueVariableScope.reservedTmpParamF64s).push(\(arguments[0]));") - return [] - } - ) case .nullable(let wrappedType, let kind): - return IntrinsicJSFragment( - parameters: ["value"], - printCode: { arguments, scope, printer, cleanup in - let value = arguments[0] - let isSomeVar = scope.variable("isSome") - printer.write("const \(isSomeVar) = \(kind.presenceCheck(value: value));") + return associatedValueOptionalPushPayload(wrappedType: wrappedType, kind: kind) + default: + return try! stackLowerFragment(elementType: type) + } + } - switch wrappedType { + private static func associatedValueOptionalPushPayload( + wrappedType: BridgeType, + kind: JSOptionalKind + ) -> IntrinsicJSFragment { + return IntrinsicJSFragment( + parameters: ["value"], + printCode: { arguments, scope, printer, cleanup in + let value = arguments[0] + let isSomeVar = scope.variable("isSome") + printer.write("const \(isSomeVar) = \(kind.presenceCheck(value: value));") + + switch wrappedType { + case .string: + let idVar = scope.variable("id") + printer.write("let \(idVar);") + printer.write("if (\(isSomeVar)) {") + printer.indent { + let bytesVar = scope.variable("bytes") + printer.write( + "let \(bytesVar) = \(JSGlueVariableScope.reservedTextEncoder).encode(\(value));" + ) + printer.write("\(idVar) = \(JSGlueVariableScope.reservedSwift).memory.retain(\(bytesVar));") + printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(bytesVar).length);") + printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(idVar));") + } + printer.write("} else {") + printer.indent { + printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(0);") + printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(0);") + } + printer.write("}") + printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? 1 : 0);") + cleanup.write("if(\(idVar)) {") + cleanup.indent { + cleanup.write("\(JSGlueVariableScope.reservedSwift).memory.release(\(idVar));") + } + cleanup.write("}") + case .int, .uint: + printer.write( + "\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? (\(value) | 0) : 0);" + ) + printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? 1 : 0);") + case .bool: + printer.write( + "\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? (\(value) ? 1 : 0) : 0);" + ) + printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? 1 : 0);") + case .float: + printer.write( + "\(JSGlueVariableScope.reservedTmpParamF32s).push(\(isSomeVar) ? Math.fround(\(value)) : 0.0);" + ) + printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? 1 : 0);") + case .double: + printer.write( + "\(JSGlueVariableScope.reservedTmpParamF64s).push(\(isSomeVar) ? \(value) : 0.0);" + ) + printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? 1 : 0);") + case .caseEnum: + printer.write( + "\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? (\(value) | 0) : 0);" + ) + printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? 1 : 0);") + case .rawValueEnum(_, let rawType): + switch rawType { case .string: let idVar = scope.variable("id") printer.write("let \(idVar);") @@ -2293,8 +2322,12 @@ struct IntrinsicJSFragment: Sendable { printer.write( "let \(bytesVar) = \(JSGlueVariableScope.reservedTextEncoder).encode(\(value));" ) - printer.write("\(idVar) = \(JSGlueVariableScope.reservedSwift).memory.retain(\(bytesVar));") - printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(bytesVar).length);") + printer.write( + "\(idVar) = \(JSGlueVariableScope.reservedSwift).memory.retain(\(bytesVar));" + ) + printer.write( + "\(JSGlueVariableScope.reservedTmpParamInts).push(\(bytesVar).length);" + ) printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(idVar));") } printer.write("} else {") @@ -2303,107 +2336,169 @@ struct IntrinsicJSFragment: Sendable { printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(0);") } printer.write("}") - printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? 1 : 0);") + printer.write( + "\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? 1 : 0);" + ) cleanup.write("if(\(idVar)) {") cleanup.indent { - cleanup.write("\(JSGlueVariableScope.reservedSwift).memory.release(\(idVar));") + cleanup.write( + "\(JSGlueVariableScope.reservedSwift).memory.release(\(idVar));" + ) } cleanup.write("}") - case .int, .uint: - printer.write( - "\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? (\(value) | 0) : 0);" - ) - printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? 1 : 0);") - case .bool: - printer.write( - "\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? (\(value) ? 1 : 0) : 0);" - ) - printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? 1 : 0);") case .float: printer.write( "\(JSGlueVariableScope.reservedTmpParamF32s).push(\(isSomeVar) ? Math.fround(\(value)) : 0.0);" ) - printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? 1 : 0);") + printer.write( + "\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? 1 : 0);" + ) case .double: printer.write( "\(JSGlueVariableScope.reservedTmpParamF64s).push(\(isSomeVar) ? \(value) : 0.0);" ) - printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? 1 : 0);") + printer.write( + "\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? 1 : 0);" + ) default: - printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? 1 : 0);") + printer.write( + "\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? (\(value) | 0) : 0);" + ) + printer.write( + "\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? 1 : 0);" + ) } - - return [] - } - ) - default: - return IntrinsicJSFragment( - parameters: [], - printCode: { arguments, scope, printer, cleanup in - return [] + case .swiftStruct(let structName): + let structBase = structName.components(separatedBy: ".").last ?? structName + let nestedCleanupVar = scope.variable("nestedCleanup") + printer.write("let \(nestedCleanupVar);") + printer.write("if (\(isSomeVar)) {") + printer.indent { + let structResultVar = scope.variable("structResult") + printer.write( + "const \(structResultVar) = \(JSGlueVariableScope.reservedStructHelpers).\(structBase).lower(\(value));" + ) + printer.write("\(nestedCleanupVar) = \(structResultVar).cleanup;") + } + printer.write("}") + printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? 1 : 0);") + cleanup.write("if (\(nestedCleanupVar)) { \(nestedCleanupVar)(); }") + case .swiftHeapObject: + printer.write("if (\(isSomeVar)) {") + printer.indent { + printer.write("\(JSGlueVariableScope.reservedTmpParamPointers).push(\(value).pointer);") + } + printer.write("} else {") + printer.indent { + printer.write("\(JSGlueVariableScope.reservedTmpParamPointers).push(0);") + } + printer.write("}") + printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? 1 : 0);") + case .jsObject: + let idVar = scope.variable("id") + printer.write("let \(idVar);") + printer.write("if (\(isSomeVar)) {") + printer.indent { + printer.write("\(idVar) = \(JSGlueVariableScope.reservedSwift).memory.retain(\(value));") + printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(idVar));") + } + printer.write("} else {") + printer.indent { + printer.write("\(idVar) = undefined;") + printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(0);") + } + printer.write("}") + printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? 1 : 0);") + case .associatedValueEnum(let enumName): + let base = enumName.components(separatedBy: ".").last ?? enumName + let caseIdVar = scope.variable("enumCaseId") + let enumCleanupVar = scope.variable("enumCleanup") + printer.write("let \(caseIdVar), \(enumCleanupVar);") + printer.write("if (\(isSomeVar)) {") + printer.indent { + let enumResultVar = scope.variable("enumResult") + printer.write( + "const \(enumResultVar) = \(JSGlueVariableScope.reservedEnumHelpers).\(base).lower(\(value));" + ) + printer.write("\(caseIdVar) = \(enumResultVar).caseId;") + printer.write("\(enumCleanupVar) = \(enumResultVar).cleanup;") + printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(caseIdVar));") + } + printer.write("} else {") + printer.indent { + printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(0);") + } + printer.write("}") + printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? 1 : 0);") + cleanup.write("if (\(enumCleanupVar)) { \(enumCleanupVar)(); }") + case .array(let elementType): + // Array cleanup references variables declared inside the if block, + // so capture cleanup into a variable declared at the outer scope. + let arrCleanupVar = scope.variable("arrCleanup") + printer.write("let \(arrCleanupVar);") + printer.write("if (\(isSomeVar)) {") + printer.indent { + let localCleanup = CodeFragmentPrinter() + let arrFragment = try! arrayLower(elementType: elementType) + _ = arrFragment.printCode([value], scope, printer, localCleanup) + let cleanupLines = localCleanup.lines.filter { + !$0.trimmingCharacters(in: .whitespaces).isEmpty + } + if !cleanupLines.isEmpty { + printer.write("\(arrCleanupVar) = () => {") + printer.indent { + for line in cleanupLines { + printer.write(line) + } + } + printer.write("};") + } + } + printer.write("}") + printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? 1 : 0);") + cleanup.write("if (\(arrCleanupVar)) { \(arrCleanupVar)(); }") + default: + printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? 1 : 0);") } - ) - } + + return [] + } + ) } private static func associatedValuePopPayload(type: BridgeType) -> IntrinsicJSFragment { switch type { - case .string: - return IntrinsicJSFragment( - parameters: [], - printCode: { arguments, scope, printer, cleanup in - let strVar = scope.variable("string") - printer.write("const \(strVar) = \(JSGlueVariableScope.reservedTmpRetStrings).pop();") - return [strVar] - } - ) - case .bool: - return IntrinsicJSFragment( - parameters: [], - printCode: { arguments, scope, printer, cleanup in - let bVar = scope.variable("bool") - printer.write("const \(bVar) = \(JSGlueVariableScope.reservedTmpRetInts).pop();") - return [bVar] - } - ) - case .int, .uint: - return IntrinsicJSFragment( - parameters: [], - printCode: { arguments, scope, printer, cleanup in - let iVar = scope.variable("int") - printer.write("const \(iVar) = \(JSGlueVariableScope.reservedTmpRetInts).pop();") - return [iVar] - } - ) - case .float: - return IntrinsicJSFragment( - parameters: [], - printCode: { arguments, scope, printer, cleanup in - let fVar = scope.variable("f32") - printer.write("const \(fVar) = \(JSGlueVariableScope.reservedTmpRetF32s).pop();") - return [fVar] - } - ) - case .double: - return IntrinsicJSFragment( - parameters: [], - printCode: { arguments, scope, printer, cleanup in - let dVar = scope.variable("f64") - printer.write("const \(dVar) = \(JSGlueVariableScope.reservedTmpRetF64s).pop();") - return [dVar] - } - ) case .nullable(let wrappedType, let kind): - return IntrinsicJSFragment( - parameters: [], - printCode: { arguments, scope, printer, cleanup in - let optVar = scope.variable("optional") - let isSomeVar = scope.variable("isSome") + return associatedValueOptionalPopPayload(wrappedType: wrappedType, kind: kind) + default: + return try! stackLiftFragment(elementType: type) + } + } - printer.write("const \(isSomeVar) = \(JSGlueVariableScope.reservedTmpRetInts).pop();") - printer.write("let \(optVar);") - printer.write("if (\(isSomeVar)) {") - printer.indent { + private static func associatedValueOptionalPopPayload( + wrappedType: BridgeType, + kind: JSOptionalKind + ) -> IntrinsicJSFragment { + return IntrinsicJSFragment( + parameters: [], + printCode: { arguments, scope, printer, cleanup in + let optVar = scope.variable("optional") + let isSomeVar = scope.variable("isSome") + + printer.write("const \(isSomeVar) = \(JSGlueVariableScope.reservedTmpRetInts).pop();") + printer.write("let \(optVar);") + printer.write("if (\(isSomeVar)) {") + printer.indent { + // For optional associated value enums, Swift uses bridgeJSLowerParameter() + // which pushes caseId to tmpRetInts (not tmpRetTag like bridgeJSLowerReturn()). + if case .associatedValueEnum(let fullName) = wrappedType { + let base = fullName.components(separatedBy: ".").last ?? fullName + let caseIdVar = scope.variable("caseId") + printer.write("const \(caseIdVar) = \(JSGlueVariableScope.reservedTmpRetInts).pop();") + printer.write( + "\(optVar) = \(JSGlueVariableScope.reservedEnumHelpers).\(base).lift(\(caseIdVar), \(JSGlueVariableScope.reservedTmpRetStrings), \(JSGlueVariableScope.reservedTmpRetInts), \(JSGlueVariableScope.reservedTmpRetF32s), \(JSGlueVariableScope.reservedTmpRetF64s), \(JSGlueVariableScope.reservedTmpRetPointers));" + ) + } else { let wrappedFragment = associatedValuePopPayload(type: wrappedType) let wrappedResults = wrappedFragment.printCode([], scope, printer, cleanup) if let wrappedResult = wrappedResults.first { @@ -2412,23 +2507,16 @@ struct IntrinsicJSFragment: Sendable { printer.write("\(optVar) = undefined;") } } - printer.write("} else {") - printer.indent { - printer.write("\(optVar) = \(kind.absenceLiteral);") - } - printer.write("}") - - return [optVar] } - ) - default: - return IntrinsicJSFragment( - parameters: [], - printCode: { arguments, scope, printer, cleanup in - return ["undefined"] + printer.write("} else {") + printer.indent { + printer.write("\(optVar) = \(kind.absenceLiteral);") } - ) - } + printer.write("}") + + return [optVar] + } + ) } static func swiftStructLowerReturn(fullName: String) -> IntrinsicJSFragment { @@ -2489,7 +2577,7 @@ struct IntrinsicJSFragment: Sendable { let elemVar = scope.variable("elem") printer.write("for (const \(elemVar) of \(arr)) {") printer.indent { - let elementFragment = try! arrayElementLowerFragment(elementType: elementType) + let elementFragment = try! stackLowerFragment(elementType: elementType) let elementCleanup = CodeFragmentPrinter() let _ = elementFragment.printCode([elemVar], scope, printer, elementCleanup) if !elementCleanup.lines.isEmpty { @@ -2523,7 +2611,7 @@ struct IntrinsicJSFragment: Sendable { printer.write("const \(resultVar) = [];") printer.write("for (let \(iVar) = 0; \(iVar) < \(lenVar); \(iVar)++) {") printer.indent { - let elementFragment = try! arrayElementRaiseFragment(elementType: elementType) + let elementFragment = try! stackLiftFragment(elementType: elementType) let elementResults = elementFragment.printCode([], scope, printer, cleanupCode) if let elementExpr = elementResults.first { printer.write("\(resultVar).push(\(elementExpr));") @@ -2536,7 +2624,7 @@ struct IntrinsicJSFragment: Sendable { ) } - private static func arrayElementRaiseFragment(elementType: BridgeType) throws -> IntrinsicJSFragment { + private static func stackLiftFragment(elementType: BridgeType) throws -> IntrinsicJSFragment { switch elementType { case .jsValue: throw BridgeJSLinkError(message: "Array of JSValue is not supported yet") @@ -2592,7 +2680,7 @@ struct IntrinsicJSFragment: Sendable { printCode: { arguments, scope, printer, cleanup in let resultVar = scope.variable("struct") printer.write( - "const \(resultVar) = structHelpers.\(structBase).lift(\(JSGlueVariableScope.reservedTmpRetStrings), \(JSGlueVariableScope.reservedTmpRetInts), \(JSGlueVariableScope.reservedTmpRetF32s), \(JSGlueVariableScope.reservedTmpRetF64s), \(JSGlueVariableScope.reservedTmpRetPointers));" + "const \(resultVar) = \(JSGlueVariableScope.reservedStructHelpers).\(structBase).lift(\(JSGlueVariableScope.reservedTmpRetStrings), \(JSGlueVariableScope.reservedTmpRetInts), \(JSGlueVariableScope.reservedTmpRetF32s), \(JSGlueVariableScope.reservedTmpRetF64s), \(JSGlueVariableScope.reservedTmpRetPointers));" ) return [resultVar] } @@ -2617,6 +2705,24 @@ struct IntrinsicJSFragment: Sendable { return [varName] } ) + case .float: + return IntrinsicJSFragment( + parameters: [], + printCode: { arguments, scope, printer, cleanup in + let varName = scope.variable("rawValue") + printer.write("const \(varName) = \(JSGlueVariableScope.reservedTmpRetF32s).pop();") + return [varName] + } + ) + case .double: + return IntrinsicJSFragment( + parameters: [], + printCode: { arguments, scope, printer, cleanup in + let varName = scope.variable("rawValue") + printer.write("const \(varName) = \(JSGlueVariableScope.reservedTmpRetF64s).pop();") + return [varName] + } + ) default: return IntrinsicJSFragment( parameters: [], @@ -2632,11 +2738,9 @@ struct IntrinsicJSFragment: Sendable { return IntrinsicJSFragment( parameters: [], printCode: { arguments, scope, printer, cleanup in - let caseIdVar = scope.variable("caseId") let resultVar = scope.variable("enumValue") - printer.write("const \(caseIdVar) = \(JSGlueVariableScope.reservedTmpRetInts).pop();") printer.write( - "const \(resultVar) = enumHelpers.\(base).lift(\(caseIdVar), \(JSGlueVariableScope.reservedTmpRetStrings), \(JSGlueVariableScope.reservedTmpRetInts), \(JSGlueVariableScope.reservedTmpRetF32s), \(JSGlueVariableScope.reservedTmpRetF64s));" + "const \(resultVar) = \(JSGlueVariableScope.reservedEnumHelpers).\(base).lift(\(JSGlueVariableScope.reservedTmpRetTag).pop(), \(JSGlueVariableScope.reservedTmpRetStrings), \(JSGlueVariableScope.reservedTmpRetInts), \(JSGlueVariableScope.reservedTmpRetF32s), \(JSGlueVariableScope.reservedTmpRetF64s), \(JSGlueVariableScope.reservedTmpRetPointers));" ) return [resultVar] } @@ -2648,7 +2752,7 @@ struct IntrinsicJSFragment: Sendable { let ptrVar = scope.variable("ptr") let objVar = scope.variable("obj") printer.write("const \(ptrVar) = \(JSGlueVariableScope.reservedTmpRetPointers).pop();") - printer.write("const \(objVar) = \(className).__construct(\(ptrVar));") + printer.write("const \(objVar) = _exports['\(className)'].__construct(\(ptrVar));") return [objVar] } ) @@ -2682,7 +2786,7 @@ struct IntrinsicJSFragment: Sendable { } } - private static func arrayElementLowerFragment(elementType: BridgeType) throws -> IntrinsicJSFragment { + private static func stackLowerFragment(elementType: BridgeType) throws -> IntrinsicJSFragment { switch elementType { case .jsValue: throw BridgeJSLinkError(message: "Array of JSValue is not supported yet") @@ -2693,7 +2797,7 @@ struct IntrinsicJSFragment: Sendable { let value = arguments[0] let bytesVar = scope.variable("bytes") let idVar = scope.variable("id") - printer.write("const \(bytesVar) = textEncoder.encode(\(value));") + printer.write("const \(bytesVar) = \(JSGlueVariableScope.reservedTextEncoder).encode(\(value));") printer.write("const \(idVar) = \(JSGlueVariableScope.reservedSwift).memory.retain(\(bytesVar));") printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(bytesVar).length);") printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(idVar));") @@ -2739,8 +2843,10 @@ struct IntrinsicJSFragment: Sendable { parameters: ["value"], printCode: { arguments, scope, printer, cleanup in let value = arguments[0] - let cleanupVar = scope.variable("cleanup") - printer.write("const { cleanup: \(cleanupVar) } = structHelpers.\(structBase).lower(\(value));") + let cleanupVar = scope.variable("structCleanup") + printer.write( + "const { cleanup: \(cleanupVar) } = \(JSGlueVariableScope.reservedStructHelpers).\(structBase).lower(\(value));" + ) cleanup.write("if (\(cleanupVar)) { \(cleanupVar)(); }") return [] } @@ -2762,7 +2868,9 @@ struct IntrinsicJSFragment: Sendable { let value = arguments[0] let bytesVar = scope.variable("bytes") let idVar = scope.variable("id") - printer.write("const \(bytesVar) = textEncoder.encode(\(value));") + printer.write( + "const \(bytesVar) = \(JSGlueVariableScope.reservedTextEncoder).encode(\(value));" + ) printer.write( "const \(idVar) = \(JSGlueVariableScope.reservedSwift).memory.retain(\(bytesVar));" ) @@ -2772,6 +2880,22 @@ struct IntrinsicJSFragment: Sendable { return [] } ) + case .float: + return IntrinsicJSFragment( + parameters: ["value"], + printCode: { arguments, scope, printer, cleanup in + printer.write("\(JSGlueVariableScope.reservedTmpParamF32s).push(Math.fround(\(arguments[0])));") + return [] + } + ) + case .double: + return IntrinsicJSFragment( + parameters: ["value"], + printCode: { arguments, scope, printer, cleanup in + printer.write("\(JSGlueVariableScope.reservedTmpParamF64s).push(\(arguments[0]));") + return [] + } + ) default: return IntrinsicJSFragment( parameters: ["value"], @@ -2790,7 +2914,7 @@ struct IntrinsicJSFragment: Sendable { let caseIdVar = scope.variable("caseId") let cleanupVar = scope.variable("enumCleanup") printer.write( - "const { caseId: \(caseIdVar), cleanup: \(cleanupVar) } = enumHelpers.\(base).lower(\(value));" + "const { caseId: \(caseIdVar), cleanup: \(cleanupVar) } = \(JSGlueVariableScope.reservedEnumHelpers).\(base).lower(\(value));" ) printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(caseIdVar));") cleanup.write("if (\(cleanupVar)) { \(cleanupVar)(); }") @@ -2867,7 +2991,7 @@ struct IntrinsicJSFragment: Sendable { } printer.write("} else {") printer.indent { - let innerFragment = try! arrayElementRaiseFragment(elementType: wrappedType) + let innerFragment = try! stackLiftFragment(elementType: wrappedType) let innerResults = innerFragment.printCode([], scope, printer, cleanup) if let innerResult = innerResults.first { printer.write("\(resultVar) = \(innerResult);") @@ -2898,7 +3022,7 @@ struct IntrinsicJSFragment: Sendable { let localCleanupWriter = CodeFragmentPrinter() printer.write("if (\(isSomeVar)) {") printer.indent { - let innerFragment = try! arrayElementLowerFragment(elementType: wrappedType) + let innerFragment = try! stackLowerFragment(elementType: wrappedType) let _ = innerFragment.printCode([value], scope, printer, localCleanupWriter) let localCleanupLines = localCleanupWriter.lines.filter { !$0.trimmingCharacters(in: .whitespaces).isEmpty @@ -3065,13 +3189,11 @@ struct IntrinsicJSFragment: Sendable { let methodScope = scope.makeChildScope() let methodCleanup = CodeFragmentPrinter() - // Lower the struct instance (this) using the helper's lower function let structCleanupVar = methodScope.variable("structCleanup") printer.write( "const { cleanup: \(structCleanupVar) } = \(JSGlueVariableScope.reservedStructHelpers).\(structDef.name).lower(this);" ) - // Lower each parameter and collect forwarding expressions var paramForwardings: [String] = [] for param in method.parameters { let fragment = try! IntrinsicJSFragment.lowerParameter(type: param.type) @@ -3079,7 +3201,6 @@ struct IntrinsicJSFragment: Sendable { paramForwardings.append(contentsOf: loweredValues) } - // Call the Swift function with all lowered parameters let callExpr = "instance.exports.\(method.abiName)(\(paramForwardings.joined(separator: ", ")))" if method.returnType == .void { printer.write("\(callExpr);") @@ -3118,61 +3239,6 @@ struct IntrinsicJSFragment: Sendable { switch field.type { case .jsValue: preconditionFailure("Struct field of JSValue is not supported yet") - case .string: - return IntrinsicJSFragment( - parameters: ["value"], - printCode: { arguments, scope, printer, cleanup in - let value = arguments[0] - let bytesVar = scope.variable("bytes") - let idVar = scope.variable("id") - printer.write("const \(bytesVar) = textEncoder.encode(\(value));") - printer.write("const \(idVar) = \(JSGlueVariableScope.reservedSwift).memory.retain(\(bytesVar));") - printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(bytesVar).length);") - printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(idVar));") - cleanup.write("\(JSGlueVariableScope.reservedSwift).memory.release(\(idVar));") - return [idVar] - } - ) - case .bool: - return IntrinsicJSFragment( - parameters: ["value"], - printCode: { arguments, scope, printer, cleanup in - printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(arguments[0]) ? 1 : 0);") - return [] - } - ) - case .int, .uint: - return IntrinsicJSFragment( - parameters: ["value"], - printCode: { arguments, scope, printer, cleanup in - printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push((\(arguments[0]) | 0));") - return [] - } - ) - case .float: - return IntrinsicJSFragment( - parameters: ["value"], - printCode: { arguments, scope, printer, cleanup in - printer.write("\(JSGlueVariableScope.reservedTmpParamF32s).push(Math.fround(\(arguments[0])));") - return [] - } - ) - case .double: - return IntrinsicJSFragment( - parameters: ["value"], - printCode: { arguments, scope, printer, cleanup in - printer.write("\(JSGlueVariableScope.reservedTmpParamF64s).push(\(arguments[0]));") - return [] - } - ) - case .unsafePointer: - return IntrinsicJSFragment( - parameters: ["value"], - printCode: { arguments, scope, printer, cleanup in - printer.write("\(JSGlueVariableScope.reservedTmpParamPointers).push((\(arguments[0]) | 0));") - return [] - } - ) case .jsObject: return IntrinsicJSFragment( parameters: ["value"], @@ -3233,7 +3299,9 @@ struct IntrinsicJSFragment: Sendable { printer.write("if (\(isSomeVar)) {") printer.indent { let bytesVar = scope.variable("bytes") - printer.write("const \(bytesVar) = textEncoder.encode(\(value));") + printer.write( + "const \(bytesVar) = \(JSGlueVariableScope.reservedTextEncoder).encode(\(value));" + ) printer.write( "\(idVar) = \(JSGlueVariableScope.reservedSwift).memory.retain(\(bytesVar));" ) @@ -3326,7 +3394,9 @@ struct IntrinsicJSFragment: Sendable { printer.write("if (\(isSomeVar)) {") printer.indent { let bytesVar = scope.variable("bytes") - printer.write("const \(bytesVar) = textEncoder.encode(\(value));") + printer.write( + "const \(bytesVar) = \(JSGlueVariableScope.reservedTextEncoder).encode(\(value));" + ) printer.write("\(idVar) = \(JSGlueVariableScope.reservedSwift).memory.retain(\(bytesVar));") printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(bytesVar).length);") printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(idVar));") @@ -3369,7 +3439,6 @@ struct IntrinsicJSFragment: Sendable { cleanup.write("}") return [idVar] } else { - // Handle optional primitive types using helper switch wrappedType { case .int, .uint: pushOptionalPrimitive( @@ -3430,7 +3499,6 @@ struct IntrinsicJSFragment: Sendable { printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(isSomeVar) ? 1 : 0);") cleanup.write("if (\(enumCleanupVar)) { \(enumCleanupVar)(); }") default: - // For other types (nested structs, etc.), original logic applies let wrappedFragment = structFieldLowerFragment( field: ExportedProperty( name: field.name, @@ -3464,83 +3532,6 @@ struct IntrinsicJSFragment: Sendable { return [] } ) - case .swiftHeapObject: - return IntrinsicJSFragment( - parameters: ["value"], - printCode: { arguments, scope, printer, cleanup in - let value = arguments[0] - printer.write("\(JSGlueVariableScope.reservedTmpParamPointers).push(\(value).pointer);") - return [] - } - ) - case .associatedValueEnum(let fullName): - let base = fullName.components(separatedBy: ".").last ?? fullName - return IntrinsicJSFragment( - parameters: ["value"], - printCode: { arguments, scope, printer, cleanup in - let value = arguments[0] - let caseIdVar = scope.variable("caseId") - let cleanupVar = scope.variable("enumCleanup") - printer.write( - "const { caseId: \(caseIdVar), cleanup: \(cleanupVar) } = \(JSGlueVariableScope.reservedEnumHelpers).\(base).lower(\(value));" - ) - printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(caseIdVar));") - cleanup.write("if (\(cleanupVar)) { \(cleanupVar)(); }") - return [cleanupVar] - } - ) - case .caseEnum: - return IntrinsicJSFragment( - parameters: ["value"], - printCode: { arguments, scope, printer, cleanup in - printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push((\(arguments[0]) | 0));") - return [] - } - ) - case .rawValueEnum(_, let rawType): - switch rawType { - case .string: - return IntrinsicJSFragment( - parameters: ["value"], - printCode: { arguments, scope, printer, cleanup in - let value = arguments[0] - let bytesVar = scope.variable("bytes") - let idVar = scope.variable("id") - printer.write("const \(bytesVar) = textEncoder.encode(\(value));") - printer.write( - "const \(idVar) = \(JSGlueVariableScope.reservedSwift).memory.retain(\(bytesVar));" - ) - printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(bytesVar).length);") - printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push(\(idVar));") - cleanup.write("\(JSGlueVariableScope.reservedSwift).memory.release(\(idVar));") - return [idVar] - } - ) - case .float: - return IntrinsicJSFragment( - parameters: ["value"], - printCode: { arguments, scope, printer, cleanup in - printer.write("\(JSGlueVariableScope.reservedTmpParamF32s).push(Math.fround(\(arguments[0])));") - return [] - } - ) - case .double: - return IntrinsicJSFragment( - parameters: ["value"], - printCode: { arguments, scope, printer, cleanup in - printer.write("\(JSGlueVariableScope.reservedTmpParamF64s).push(\(arguments[0]));") - return [] - } - ) - default: - return IntrinsicJSFragment( - parameters: ["value"], - printCode: { arguments, scope, printer, cleanup in - printer.write("\(JSGlueVariableScope.reservedTmpParamInts).push((\(arguments[0]) | 0));") - return [] - } - ) - } case .void, .swiftProtocol, .namespaceEnum, .closure: // These types should not appear as struct fields - return error fragment return IntrinsicJSFragment( @@ -3550,8 +3541,8 @@ struct IntrinsicJSFragment: Sendable { return [] } ) - case .array(let elementType): - return try! arrayLower(elementType: elementType) + default: + return try! stackLowerFragment(elementType: field.type) } } @@ -3606,60 +3597,6 @@ struct IntrinsicJSFragment: Sendable { switch field.type { case .jsValue: preconditionFailure("Struct field of JSValue is not supported yet") - case .string: - return IntrinsicJSFragment( - parameters: [], - printCode: { arguments, scope, printer, cleanup in - let strVar = scope.variable("string") - printer.write("const \(strVar) = \(JSGlueVariableScope.reservedTmpRetStrings).pop();") - return [strVar] - } - ) - case .bool: - return IntrinsicJSFragment( - parameters: [], - printCode: { arguments, scope, printer, cleanup in - let bVar = scope.variable("bool") - printer.write("const \(bVar) = \(JSGlueVariableScope.reservedTmpRetInts).pop() !== 0;") - return [bVar] - } - ) - case .int, .uint: - return IntrinsicJSFragment( - parameters: [], - printCode: { arguments, scope, printer, cleanup in - let iVar = scope.variable("int") - printer.write("const \(iVar) = \(JSGlueVariableScope.reservedTmpRetInts).pop();") - return [iVar] - } - ) - case .float: - return IntrinsicJSFragment( - parameters: [], - printCode: { arguments, scope, printer, cleanup in - let fVar = scope.variable("f32") - printer.write("const \(fVar) = \(JSGlueVariableScope.reservedTmpRetF32s).pop();") - return [fVar] - } - ) - case .double: - return IntrinsicJSFragment( - parameters: [], - printCode: { arguments, scope, printer, cleanup in - let dVar = scope.variable("f64") - printer.write("const \(dVar) = \(JSGlueVariableScope.reservedTmpRetF64s).pop();") - return [dVar] - } - ) - case .unsafePointer: - return IntrinsicJSFragment( - parameters: [], - printCode: { arguments, scope, printer, cleanup in - let pVar = scope.variable("pointer") - printer.write("const \(pVar) = \(JSGlueVariableScope.reservedTmpRetPointers).pop();") - return [pVar] - } - ) case .nullable(let wrappedType, let kind): return IntrinsicJSFragment( parameters: [], @@ -3676,7 +3613,7 @@ struct IntrinsicJSFragment: Sendable { let caseIdVar = scope.variable("enumCaseId") printer.write("const \(caseIdVar) = \(JSGlueVariableScope.reservedTmpRetInts).pop();") printer.write( - "\(optVar) = \(JSGlueVariableScope.reservedEnumHelpers).\(base).lift(\(caseIdVar), \(JSGlueVariableScope.reservedTmpRetStrings), \(JSGlueVariableScope.reservedTmpRetInts), \(JSGlueVariableScope.reservedTmpRetF32s), \(JSGlueVariableScope.reservedTmpRetF64s));" + "\(optVar) = \(JSGlueVariableScope.reservedEnumHelpers).\(base).lift(\(caseIdVar), \(JSGlueVariableScope.reservedTmpRetStrings), \(JSGlueVariableScope.reservedTmpRetInts), \(JSGlueVariableScope.reservedTmpRetF32s), \(JSGlueVariableScope.reservedTmpRetF64s), \(JSGlueVariableScope.reservedTmpRetPointers));" ) } else { let wrappedFragment = structFieldLiftFragment( @@ -3715,65 +3652,6 @@ struct IntrinsicJSFragment: Sendable { return [structVar] } ) - case .caseEnum: - return IntrinsicJSFragment( - parameters: [], - printCode: { arguments, scope, printer, cleanup in - let varName = scope.variable("value") - printer.write("const \(varName) = \(JSGlueVariableScope.reservedTmpRetInts).pop();") - return [varName] - } - ) - case .rawValueEnum(_, let rawType): - switch rawType { - case .string: - return IntrinsicJSFragment( - parameters: [], - printCode: { arguments, scope, printer, cleanup in - let varName = scope.variable("value") - printer.write("const \(varName) = \(JSGlueVariableScope.reservedTmpRetStrings).pop();") - return [varName] - } - ) - case .float: - return IntrinsicJSFragment( - parameters: [], - printCode: { arguments, scope, printer, cleanup in - let varName = scope.variable("value") - printer.write("const \(varName) = \(JSGlueVariableScope.reservedTmpRetF32s).pop();") - return [varName] - } - ) - case .double: - return IntrinsicJSFragment( - parameters: [], - printCode: { arguments, scope, printer, cleanup in - let varName = scope.variable("value") - printer.write("const \(varName) = \(JSGlueVariableScope.reservedTmpRetF64s).pop();") - return [varName] - } - ) - default: - return IntrinsicJSFragment( - parameters: [], - printCode: { arguments, scope, printer, cleanup in - let varName = scope.variable("value") - printer.write("const \(varName) = \(JSGlueVariableScope.reservedTmpRetInts).pop();") - return [varName] - } - ) - } - case .swiftHeapObject(let className): - return IntrinsicJSFragment( - parameters: [], - printCode: { arguments, scope, printer, cleanup in - let ptrVar = scope.variable("ptr") - let varName = scope.variable("value") - printer.write("const \(ptrVar) = \(JSGlueVariableScope.reservedTmpRetPointers).pop();") - printer.write("const \(varName) = _exports['\(className)'].__construct(\(ptrVar));") - return [varName] - } - ) case .jsObject: return IntrinsicJSFragment( parameters: [], @@ -3797,18 +3675,6 @@ struct IntrinsicJSFragment: Sendable { return [varName] } ) - case .associatedValueEnum(let fullName): - let base = fullName.components(separatedBy: ".").last ?? fullName - return IntrinsicJSFragment( - parameters: [], - printCode: { arguments, scope, printer, cleanup in - let varName = scope.variable("value") - printer.write( - "const \(varName) = \(JSGlueVariableScope.reservedEnumHelpers).\(base).lift(\(JSGlueVariableScope.reservedTmpRetTag), \(JSGlueVariableScope.reservedTmpRetStrings), \(JSGlueVariableScope.reservedTmpRetInts), \(JSGlueVariableScope.reservedTmpRetF32s), \(JSGlueVariableScope.reservedTmpRetF64s));" - ) - return [varName] - } - ) case .void, .swiftProtocol, .namespaceEnum, .closure: // These types should not appear as struct fields return IntrinsicJSFragment( @@ -3818,8 +3684,8 @@ struct IntrinsicJSFragment: Sendable { return [] } ) - case .array(let elementType): - return try! arrayLift(elementType: elementType) + default: + return try! stackLiftFragment(elementType: field.type) } } } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/EnumAssociatedValue.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/EnumAssociatedValue.swift index efb6cd1b..a0e6cbfe 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/EnumAssociatedValue.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/EnumAssociatedValue.swift @@ -55,3 +55,66 @@ enum APIOptionalResult { } @JS func roundTripOptionalAPIOptionalResult(result: APIOptionalResult?) -> APIOptionalResult? @JS func compareAPIResults(result1: APIOptionalResult?, result2: APIOptionalResult?) -> APIOptionalResult? + +@JS enum Precision: Float { + case rough = 0.1 + case fine = 0.001 +} + +@JS enum CardinalDirection { + case north + case south + case east + case west +} + +@JS +enum TypedPayloadResult { + case precision(Precision) + case direction(CardinalDirection) + case optPrecision(Precision?) + case optDirection(CardinalDirection?) + case empty +} + +@JS func roundTripTypedPayloadResult(_ result: TypedPayloadResult) -> TypedPayloadResult +@JS func roundTripOptionalTypedPayloadResult(_ result: TypedPayloadResult?) -> TypedPayloadResult? + +@JS struct Point { + var x: Double + var y: Double +} + +@JS class User { + var name: String + + init(name: String) { + self.name = name + } +} + +@JS +enum AllTypesResult { + case structPayload(Point) + case classPayload(User) + case jsObjectPayload(JSObject) + case nestedEnum(APIResult) + case arrayPayload([Int]) + case empty +} + +@JS func roundTripAllTypesResult(_ result: AllTypesResult) -> AllTypesResult +@JS func roundTripOptionalAllTypesResult(_ result: AllTypesResult?) -> AllTypesResult? + +@JS +enum OptionalAllTypesResult { + case optStruct(Point?) + case optClass(User?) + case optJSObject(JSObject?) + case optNestedEnum(APIResult?) + case optArray([Int]?) + case empty +} + +@JS func roundTripOptionalPayloadResult(_ result: OptionalAllTypesResult) -> OptionalAllTypesResult +@JS func roundTripOptionalPayloadResultOpt(_ result: OptionalAllTypesResult?) -> OptionalAllTypesResult? diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAssociatedValue.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAssociatedValue.json index ba9ee932..3c624fa1 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAssociatedValue.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAssociatedValue.json @@ -1,7 +1,16 @@ { "exported" : { "classes" : [ + { + "methods" : [ + + ], + "name" : "User", + "properties" : [ + ], + "swiftCallName" : "User" + } ], "enums" : [ { @@ -492,6 +501,346 @@ ], "swiftCallName" : "APIOptionalResult", "tsFullPath" : "APIOptionalResult" + }, + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "rough", + "rawValue" : "0.1" + }, + { + "associatedValues" : [ + + ], + "name" : "fine", + "rawValue" : "0.001" + } + ], + "emitStyle" : "const", + "name" : "Precision", + "rawType" : "Float", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "Precision", + "tsFullPath" : "Precision" + }, + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "north" + }, + { + "associatedValues" : [ + + ], + "name" : "south" + }, + { + "associatedValues" : [ + + ], + "name" : "east" + }, + { + "associatedValues" : [ + + ], + "name" : "west" + } + ], + "emitStyle" : "const", + "name" : "CardinalDirection", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "CardinalDirection", + "tsFullPath" : "CardinalDirection" + }, + { + "cases" : [ + { + "associatedValues" : [ + { + "type" : { + "rawValueEnum" : { + "_0" : "Precision", + "_1" : "Float" + } + } + } + ], + "name" : "precision" + }, + { + "associatedValues" : [ + { + "type" : { + "caseEnum" : { + "_0" : "CardinalDirection" + } + } + } + ], + "name" : "direction" + }, + { + "associatedValues" : [ + { + "type" : { + "nullable" : { + "_0" : { + "rawValueEnum" : { + "_0" : "Precision", + "_1" : "Float" + } + }, + "_1" : "null" + } + } + } + ], + "name" : "optPrecision" + }, + { + "associatedValues" : [ + { + "type" : { + "nullable" : { + "_0" : { + "caseEnum" : { + "_0" : "CardinalDirection" + } + }, + "_1" : "null" + } + } + } + ], + "name" : "optDirection" + }, + { + "associatedValues" : [ + + ], + "name" : "empty" + } + ], + "emitStyle" : "const", + "name" : "TypedPayloadResult", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "TypedPayloadResult", + "tsFullPath" : "TypedPayloadResult" + }, + { + "cases" : [ + { + "associatedValues" : [ + { + "type" : { + "swiftStruct" : { + "_0" : "Point" + } + } + } + ], + "name" : "structPayload" + }, + { + "associatedValues" : [ + { + "type" : { + "swiftHeapObject" : { + "_0" : "User" + } + } + } + ], + "name" : "classPayload" + }, + { + "associatedValues" : [ + { + "type" : { + "jsObject" : { + + } + } + } + ], + "name" : "jsObjectPayload" + }, + { + "associatedValues" : [ + { + "type" : { + "associatedValueEnum" : { + "_0" : "APIResult" + } + } + } + ], + "name" : "nestedEnum" + }, + { + "associatedValues" : [ + { + "type" : { + "array" : { + "_0" : { + "int" : { + + } + } + } + } + } + ], + "name" : "arrayPayload" + }, + { + "associatedValues" : [ + + ], + "name" : "empty" + } + ], + "emitStyle" : "const", + "name" : "AllTypesResult", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "AllTypesResult", + "tsFullPath" : "AllTypesResult" + }, + { + "cases" : [ + { + "associatedValues" : [ + { + "type" : { + "nullable" : { + "_0" : { + "swiftStruct" : { + "_0" : "Point" + } + }, + "_1" : "null" + } + } + } + ], + "name" : "optStruct" + }, + { + "associatedValues" : [ + { + "type" : { + "nullable" : { + "_0" : { + "swiftHeapObject" : { + "_0" : "User" + } + }, + "_1" : "null" + } + } + } + ], + "name" : "optClass" + }, + { + "associatedValues" : [ + { + "type" : { + "nullable" : { + "_0" : { + "jsObject" : { + + } + }, + "_1" : "null" + } + } + } + ], + "name" : "optJSObject" + }, + { + "associatedValues" : [ + { + "type" : { + "nullable" : { + "_0" : { + "associatedValueEnum" : { + "_0" : "APIResult" + } + }, + "_1" : "null" + } + } + } + ], + "name" : "optNestedEnum" + }, + { + "associatedValues" : [ + { + "type" : { + "nullable" : { + "_0" : { + "array" : { + "_0" : { + "int" : { + + } + } + } + }, + "_1" : "null" + } + } + } + ], + "name" : "optArray" + }, + { + "associatedValues" : [ + + ], + "name" : "empty" + } + ], + "emitStyle" : "const", + "name" : "OptionalAllTypesResult", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "OptionalAllTypesResult", + "tsFullPath" : "OptionalAllTypesResult" } ], "exposeToGlobal" : false, @@ -853,13 +1202,221 @@ "_1" : "null" } } + }, + { + "abiName" : "bjs_roundTripTypedPayloadResult", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "roundTripTypedPayloadResult", + "parameters" : [ + { + "label" : "_", + "name" : "result", + "type" : { + "associatedValueEnum" : { + "_0" : "TypedPayloadResult" + } + } + } + ], + "returnType" : { + "associatedValueEnum" : { + "_0" : "TypedPayloadResult" + } + } + }, + { + "abiName" : "bjs_roundTripOptionalTypedPayloadResult", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "roundTripOptionalTypedPayloadResult", + "parameters" : [ + { + "label" : "_", + "name" : "result", + "type" : { + "nullable" : { + "_0" : { + "associatedValueEnum" : { + "_0" : "TypedPayloadResult" + } + }, + "_1" : "null" + } + } + } + ], + "returnType" : { + "nullable" : { + "_0" : { + "associatedValueEnum" : { + "_0" : "TypedPayloadResult" + } + }, + "_1" : "null" + } + } + }, + { + "abiName" : "bjs_roundTripAllTypesResult", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "roundTripAllTypesResult", + "parameters" : [ + { + "label" : "_", + "name" : "result", + "type" : { + "associatedValueEnum" : { + "_0" : "AllTypesResult" + } + } + } + ], + "returnType" : { + "associatedValueEnum" : { + "_0" : "AllTypesResult" + } + } + }, + { + "abiName" : "bjs_roundTripOptionalAllTypesResult", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "roundTripOptionalAllTypesResult", + "parameters" : [ + { + "label" : "_", + "name" : "result", + "type" : { + "nullable" : { + "_0" : { + "associatedValueEnum" : { + "_0" : "AllTypesResult" + } + }, + "_1" : "null" + } + } + } + ], + "returnType" : { + "nullable" : { + "_0" : { + "associatedValueEnum" : { + "_0" : "AllTypesResult" + } + }, + "_1" : "null" + } + } + }, + { + "abiName" : "bjs_roundTripOptionalPayloadResult", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "roundTripOptionalPayloadResult", + "parameters" : [ + { + "label" : "_", + "name" : "result", + "type" : { + "associatedValueEnum" : { + "_0" : "OptionalAllTypesResult" + } + } + } + ], + "returnType" : { + "associatedValueEnum" : { + "_0" : "OptionalAllTypesResult" + } + } + }, + { + "abiName" : "bjs_roundTripOptionalPayloadResultOpt", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "roundTripOptionalPayloadResultOpt", + "parameters" : [ + { + "label" : "_", + "name" : "result", + "type" : { + "nullable" : { + "_0" : { + "associatedValueEnum" : { + "_0" : "OptionalAllTypesResult" + } + }, + "_1" : "null" + } + } + } + ], + "returnType" : { + "nullable" : { + "_0" : { + "associatedValueEnum" : { + "_0" : "OptionalAllTypesResult" + } + }, + "_1" : "null" + } + } } ], "protocols" : [ ], "structs" : [ + { + "methods" : [ + ], + "name" : "Point", + "properties" : [ + { + "isReadonly" : true, + "isStatic" : false, + "name" : "x", + "type" : { + "double" : { + + } + } + }, + { + "isReadonly" : true, + "isStatic" : false, + "name" : "y", + "type" : { + "double" : { + + } + } + } + ], + "swiftCallName" : "Point" + } ] }, "moduleName" : "TestModule" diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAssociatedValue.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAssociatedValue.swift index 0854cba7..26454a2a 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAssociatedValue.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAssociatedValue.swift @@ -55,20 +55,20 @@ extension APIResult: _BridgedSwiftAssociatedValueEnum { @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() { switch self { case .success(let param0): - _swift_js_push_tag(Int32(0)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(0)) case .failure(let param0): - _swift_js_push_tag(Int32(1)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(1)) case .flag(let param0): - _swift_js_push_tag(Int32(2)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(2)) case .rate(let param0): - _swift_js_push_tag(Int32(3)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(3)) case .precise(let param0): - _swift_js_push_tag(Int32(4)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(4)) case .info: _swift_js_push_tag(Int32(5)) } @@ -145,24 +145,23 @@ extension ComplexResult: _BridgedSwiftAssociatedValueEnum { @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() { switch self { case .success(let param0): - _swift_js_push_tag(Int32(0)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(0)) case .error(let param0, let param1): - _swift_js_push_tag(Int32(1)) param0.bridgeJSLowerStackReturn() param1.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(1)) case .status(let param0, let param1, let param2): - _swift_js_push_tag(Int32(2)) param0.bridgeJSLowerStackReturn() param1.bridgeJSLowerStackReturn() param2.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(2)) case .coordinates(let param0, let param1, let param2): - _swift_js_push_tag(Int32(3)) param0.bridgeJSLowerStackReturn() param1.bridgeJSLowerStackReturn() param2.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(3)) 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(4)) param0.bridgeJSLowerStackReturn() param1.bridgeJSLowerStackReturn() param2.bridgeJSLowerStackReturn() @@ -172,6 +171,7 @@ extension ComplexResult: _BridgedSwiftAssociatedValueEnum { param6.bridgeJSLowerStackReturn() param7.bridgeJSLowerStackReturn() param8.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(4)) case .info: _swift_js_push_tag(Int32(5)) } @@ -224,17 +224,17 @@ extension Utilities.Result: _BridgedSwiftAssociatedValueEnum { @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() { switch self { case .success(let param0): - _swift_js_push_tag(Int32(0)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(0)) case .failure(let param0, let param1): - _swift_js_push_tag(Int32(1)) param0.bridgeJSLowerStackReturn() param1.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(1)) case .status(let param0, let param1, let param2): - _swift_js_push_tag(Int32(2)) param0.bridgeJSLowerStackReturn() param1.bridgeJSLowerStackReturn() param2.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(2)) } } } @@ -278,12 +278,12 @@ extension NetworkingResult: _BridgedSwiftAssociatedValueEnum { @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() { switch self { case .success(let param0): - _swift_js_push_tag(Int32(0)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(0)) case .failure(let param0, let param1): - _swift_js_push_tag(Int32(1)) param0.bridgeJSLowerStackReturn() param1.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(1)) } } } @@ -358,14 +358,13 @@ extension APIOptionalResult: _BridgedSwiftAssociatedValueEnum { @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() { switch self { case .success(let param0): - _swift_js_push_tag(Int32(0)) let __bjs_isSome_param0 = param0 != nil if let __bjs_unwrapped_param0 = param0 { __bjs_unwrapped_param0.bridgeJSLowerStackReturn() } _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + _swift_js_push_tag(Int32(0)) case .failure(let param0, let param1): - _swift_js_push_tag(Int32(1)) let __bjs_isSome_param0 = param0 != nil if let __bjs_unwrapped_param0 = param0 { __bjs_unwrapped_param0.bridgeJSLowerStackReturn() @@ -376,8 +375,8 @@ extension APIOptionalResult: _BridgedSwiftAssociatedValueEnum { __bjs_unwrapped_param1.bridgeJSLowerStackReturn() } _swift_js_push_i32(__bjs_isSome_param1 ? 1 : 0) + _swift_js_push_tag(Int32(1)) case .status(let param0, let param1, let param2): - _swift_js_push_tag(Int32(2)) let __bjs_isSome_param0 = param0 != nil if let __bjs_unwrapped_param0 = param0 { __bjs_unwrapped_param0.bridgeJSLowerStackReturn() @@ -393,10 +392,388 @@ extension APIOptionalResult: _BridgedSwiftAssociatedValueEnum { __bjs_unwrapped_param2.bridgeJSLowerStackReturn() } _swift_js_push_i32(__bjs_isSome_param2 ? 1 : 0) + _swift_js_push_tag(Int32(2)) + } + } +} + +extension Precision: _BridgedSwiftEnumNoPayload, _BridgedSwiftRawValueEnum { +} + +extension CardinalDirection: _BridgedSwiftCaseEnum { + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + return bridgeJSRawValue + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Int32) -> CardinalDirection { + return bridgeJSLiftParameter(value) + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Int32) -> CardinalDirection { + return CardinalDirection(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Int32 { + return bridgeJSLowerParameter() + } + + private init?(bridgeJSRawValue: Int32) { + switch bridgeJSRawValue { + case 0: + self = .north + case 1: + self = .south + case 2: + self = .east + case 3: + self = .west + default: + return nil + } + } + + private var bridgeJSRawValue: Int32 { + switch self { + case .north: + return 0 + case .south: + return 1 + case .east: + return 2 + case .west: + return 3 + } + } +} + +extension TypedPayloadResult: _BridgedSwiftAssociatedValueEnum { + private static func _bridgeJSLiftFromCaseId(_ caseId: Int32) -> TypedPayloadResult { + switch caseId { + case 0: + return .precision(Precision.bridgeJSLiftParameter(_swift_js_pop_f32())) + case 1: + return .direction(CardinalDirection.bridgeJSLiftParameter(_swift_js_pop_i32())) + case 2: + return .optPrecision(Optional.bridgeJSLiftParameter()) + case 3: + return .optDirection(Optional.bridgeJSLiftParameter()) + case 4: + return .empty + default: + fatalError("Unknown TypedPayloadResult case ID: \(caseId)") + } + } + + // MARK: Protocol Export + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + switch self { + case .precision(let param0): + param0.bridgeJSLowerStackReturn() + return Int32(0) + case .direction(let param0): + param0.bridgeJSLowerStackReturn() + return Int32(1) + case .optPrecision(let param0): + let __bjs_isSome_param0 = param0 != nil + if let __bjs_unwrapped_param0 = param0 { + __bjs_unwrapped_param0.bridgeJSLowerStackReturn() + } + _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + return Int32(2) + case .optDirection(let param0): + let __bjs_isSome_param0 = param0 != nil + if let __bjs_unwrapped_param0 = param0 { + __bjs_unwrapped_param0.bridgeJSLowerStackReturn() + } + _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + return Int32(3) + case .empty: + return Int32(4) + } + } + + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ caseId: Int32) -> TypedPayloadResult { + return _bridgeJSLiftFromCaseId(caseId) + } + + // MARK: ExportSwift + + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ caseId: Int32) -> TypedPayloadResult { + return _bridgeJSLiftFromCaseId(caseId) + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() { + switch self { + case .precision(let param0): + param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(0)) + case .direction(let param0): + param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(1)) + case .optPrecision(let param0): + let __bjs_isSome_param0 = param0 != nil + if let __bjs_unwrapped_param0 = param0 { + __bjs_unwrapped_param0.bridgeJSLowerStackReturn() + } + _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + _swift_js_push_tag(Int32(2)) + case .optDirection(let param0): + let __bjs_isSome_param0 = param0 != nil + if let __bjs_unwrapped_param0 = param0 { + __bjs_unwrapped_param0.bridgeJSLowerStackReturn() + } + _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + _swift_js_push_tag(Int32(3)) + case .empty: + _swift_js_push_tag(Int32(4)) + } + } +} + +extension AllTypesResult: _BridgedSwiftAssociatedValueEnum { + private static func _bridgeJSLiftFromCaseId(_ caseId: Int32) -> AllTypesResult { + switch caseId { + case 0: + return .structPayload(Point.bridgeJSLiftParameter()) + case 1: + return .classPayload(User.bridgeJSLiftParameter()) + case 2: + return .jsObjectPayload(JSObject.bridgeJSLiftParameter()) + case 3: + return .nestedEnum(APIResult.bridgeJSLiftParameter(_swift_js_pop_i32())) + case 4: + return .arrayPayload([Int].bridgeJSLiftParameter()) + case 5: + return .empty + default: + fatalError("Unknown AllTypesResult case ID: \(caseId)") + } + } + + // MARK: Protocol Export + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + switch self { + case .structPayload(let param0): + param0.bridgeJSLowerReturn() + return Int32(0) + case .classPayload(let param0): + param0.bridgeJSLowerStackReturn() + return Int32(1) + case .jsObjectPayload(let param0): + param0.bridgeJSLowerStackReturn() + return Int32(2) + case .nestedEnum(let param0): + param0.bridgeJSLowerReturn() + return Int32(3) + case .arrayPayload(let param0): + param0.bridgeJSLowerReturn() + return Int32(4) + case .empty: + return Int32(5) + } + } + + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ caseId: Int32) -> AllTypesResult { + return _bridgeJSLiftFromCaseId(caseId) + } + + // MARK: ExportSwift + + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ caseId: Int32) -> AllTypesResult { + return _bridgeJSLiftFromCaseId(caseId) + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() { + switch self { + case .structPayload(let param0): + param0.bridgeJSLowerReturn() + _swift_js_push_tag(Int32(0)) + case .classPayload(let param0): + param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(1)) + case .jsObjectPayload(let param0): + param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(2)) + case .nestedEnum(let param0): + param0.bridgeJSLowerReturn() + _swift_js_push_tag(Int32(3)) + case .arrayPayload(let param0): + param0.bridgeJSLowerReturn() + _swift_js_push_tag(Int32(4)) + case .empty: + _swift_js_push_tag(Int32(5)) } } } +extension OptionalAllTypesResult: _BridgedSwiftAssociatedValueEnum { + private static func _bridgeJSLiftFromCaseId(_ caseId: Int32) -> OptionalAllTypesResult { + switch caseId { + case 0: + return .optStruct(Optional.bridgeJSLiftParameter()) + case 1: + return .optClass(Optional.bridgeJSLiftParameter()) + case 2: + return .optJSObject(Optional.bridgeJSLiftParameter()) + case 3: + return .optNestedEnum(Optional.bridgeJSLiftParameter()) + case 4: + return .optArray({ + let __isSome = _swift_js_pop_i32() + if __isSome == 0 { + return Optional<[Int]>.none + } else { + return [Int].bridgeJSLiftParameter() + } + }()) + case 5: + return .empty + default: + fatalError("Unknown OptionalAllTypesResult case ID: \(caseId)") + } + } + + // MARK: Protocol Export + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + switch self { + case .optStruct(let param0): + let __bjs_isSome_param0 = param0 != nil + if let __bjs_unwrapped_param0 = param0 { + __bjs_unwrapped_param0.bridgeJSLowerReturn() + } + _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + return Int32(0) + case .optClass(let param0): + let __bjs_isSome_param0 = param0 != nil + if let __bjs_unwrapped_param0 = param0 { + __bjs_unwrapped_param0.bridgeJSLowerStackReturn() + } + _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + return Int32(1) + case .optJSObject(let param0): + let __bjs_isSome_param0 = param0 != nil + if let __bjs_unwrapped_param0 = param0 { + __bjs_unwrapped_param0.bridgeJSLowerStackReturn() + } + _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + return Int32(2) + case .optNestedEnum(let param0): + let __bjs_isSome_param0 = param0 != nil + if let __bjs_unwrapped_param0 = param0 { + _swift_js_push_i32(__bjs_unwrapped_param0.bridgeJSLowerParameter()) + } + _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + return Int32(3) + case .optArray(let param0): + let __bjs_isSome_param0 = param0 != nil + if let __bjs_unwrapped_param0 = param0 { + __bjs_unwrapped_param0.bridgeJSLowerReturn() + } + _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + return Int32(4) + case .empty: + return Int32(5) + } + } + + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ caseId: Int32) -> OptionalAllTypesResult { + return _bridgeJSLiftFromCaseId(caseId) + } + + // MARK: ExportSwift + + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ caseId: Int32) -> OptionalAllTypesResult { + return _bridgeJSLiftFromCaseId(caseId) + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() { + switch self { + case .optStruct(let param0): + let __bjs_isSome_param0 = param0 != nil + if let __bjs_unwrapped_param0 = param0 { + __bjs_unwrapped_param0.bridgeJSLowerReturn() + } + _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + _swift_js_push_tag(Int32(0)) + case .optClass(let param0): + let __bjs_isSome_param0 = param0 != nil + if let __bjs_unwrapped_param0 = param0 { + __bjs_unwrapped_param0.bridgeJSLowerStackReturn() + } + _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + _swift_js_push_tag(Int32(1)) + case .optJSObject(let param0): + let __bjs_isSome_param0 = param0 != nil + if let __bjs_unwrapped_param0 = param0 { + __bjs_unwrapped_param0.bridgeJSLowerStackReturn() + } + _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + _swift_js_push_tag(Int32(2)) + case .optNestedEnum(let param0): + let __bjs_isSome_param0 = param0 != nil + if let __bjs_unwrapped_param0 = param0 { + _swift_js_push_i32(__bjs_unwrapped_param0.bridgeJSLowerParameter()) + } + _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + _swift_js_push_tag(Int32(3)) + case .optArray(let param0): + let __bjs_isSome_param0 = param0 != nil + if let __bjs_unwrapped_param0 = param0 { + __bjs_unwrapped_param0.bridgeJSLowerReturn() + } + _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + _swift_js_push_tag(Int32(4)) + case .empty: + _swift_js_push_tag(Int32(5)) + } + } +} + +extension Point: _BridgedSwiftStruct { + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter() -> Point { + let y = Double.bridgeJSLiftParameter() + let x = Double.bridgeJSLiftParameter() + return Point(x: x, y: y) + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() { + self.x.bridgeJSLowerStackReturn() + self.y.bridgeJSLowerStackReturn() + } + + init(unsafelyCopying jsObject: JSObject) { + let __bjs_cleanupId = _bjs_struct_lower_Point(jsObject.bridgeJSLowerParameter()) + defer { + _swift_js_struct_cleanup(__bjs_cleanupId) + } + self = Self.bridgeJSLiftParameter() + } + + func toJSObject() -> JSObject { + let __bjs_self = self + __bjs_self.bridgeJSLowerReturn() + return JSObject(id: UInt32(bitPattern: _bjs_struct_lift_Point())) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_Point") +fileprivate func _bjs_struct_lower_Point(_ objectId: Int32) -> Int32 +#else +fileprivate func _bjs_struct_lower_Point(_ objectId: Int32) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lift_Point") +fileprivate func _bjs_struct_lift_Point() -> Int32 +#else +fileprivate func _bjs_struct_lift_Point() -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif + @_expose(wasm, "bjs_handle") @_cdecl("bjs_handle") public func _bjs_handle(_ result: Int32) -> Void { @@ -527,4 +904,95 @@ public func _bjs_compareAPIResults(_ result1IsSome: Int32, _ result1CaseId: Int3 #else fatalError("Only available on WebAssembly") #endif -} \ No newline at end of file +} + +@_expose(wasm, "bjs_roundTripTypedPayloadResult") +@_cdecl("bjs_roundTripTypedPayloadResult") +public func _bjs_roundTripTypedPayloadResult(_ result: Int32) -> Void { + #if arch(wasm32) + let ret = roundTripTypedPayloadResult(_: TypedPayloadResult.bridgeJSLiftParameter(result)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_roundTripOptionalTypedPayloadResult") +@_cdecl("bjs_roundTripOptionalTypedPayloadResult") +public func _bjs_roundTripOptionalTypedPayloadResult(_ resultIsSome: Int32, _ resultCaseId: Int32) -> Void { + #if arch(wasm32) + let ret = roundTripOptionalTypedPayloadResult(_: Optional.bridgeJSLiftParameter(resultIsSome, resultCaseId)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_roundTripAllTypesResult") +@_cdecl("bjs_roundTripAllTypesResult") +public func _bjs_roundTripAllTypesResult(_ result: Int32) -> Void { + #if arch(wasm32) + let ret = roundTripAllTypesResult(_: AllTypesResult.bridgeJSLiftParameter(result)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_roundTripOptionalAllTypesResult") +@_cdecl("bjs_roundTripOptionalAllTypesResult") +public func _bjs_roundTripOptionalAllTypesResult(_ resultIsSome: Int32, _ resultCaseId: Int32) -> Void { + #if arch(wasm32) + let ret = roundTripOptionalAllTypesResult(_: Optional.bridgeJSLiftParameter(resultIsSome, resultCaseId)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_roundTripOptionalPayloadResult") +@_cdecl("bjs_roundTripOptionalPayloadResult") +public func _bjs_roundTripOptionalPayloadResult(_ result: Int32) -> Void { + #if arch(wasm32) + let ret = roundTripOptionalPayloadResult(_: OptionalAllTypesResult.bridgeJSLiftParameter(result)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_roundTripOptionalPayloadResultOpt") +@_cdecl("bjs_roundTripOptionalPayloadResultOpt") +public func _bjs_roundTripOptionalPayloadResultOpt(_ resultIsSome: Int32, _ resultCaseId: Int32) -> Void { + #if arch(wasm32) + let ret = roundTripOptionalPayloadResultOpt(_: Optional.bridgeJSLiftParameter(resultIsSome, resultCaseId)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_User_deinit") +@_cdecl("bjs_User_deinit") +public func _bjs_User_deinit(_ pointer: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + Unmanaged.fromOpaque(pointer).release() + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension User: ConvertibleToJSValue, _BridgedSwiftHeapObject { + var jsValue: JSValue { + return .object(JSObject(id: UInt32(bitPattern: _bjs_User_wrap(Unmanaged.passRetained(self).toOpaque())))) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_User_wrap") +fileprivate func _bjs_User_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_User_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Protocol.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Protocol.swift index 21178521..3536b53c 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Protocol.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Protocol.swift @@ -400,11 +400,11 @@ extension Result: _BridgedSwiftAssociatedValueEnum { @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() { switch self { case .success(let param0): - _swift_js_push_tag(Int32(0)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(0)) case .failure(let param0): - _swift_js_push_tag(Int32(1)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(1)) } } } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticFunctions.Global.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticFunctions.Global.swift index ed6cb98c..3e5b40de 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticFunctions.Global.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticFunctions.Global.swift @@ -82,11 +82,11 @@ extension APIResult: _BridgedSwiftAssociatedValueEnum { @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() { switch self { case .success(let param0): - _swift_js_push_tag(Int32(0)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(0)) case .failure(let param0): - _swift_js_push_tag(Int32(1)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(1)) } } } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticFunctions.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticFunctions.swift index ed6cb98c..3e5b40de 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticFunctions.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticFunctions.swift @@ -82,11 +82,11 @@ extension APIResult: _BridgedSwiftAssociatedValueEnum { @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() { switch self { case .success(let param0): - _swift_js_push_tag(Int32(0)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(0)) case .failure(let param0): - _swift_js_push_tag(Int32(1)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(1)) } } } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftClosure.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftClosure.swift index df604669..94351dbd 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftClosure.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftClosure.swift @@ -730,20 +730,20 @@ extension APIResult: _BridgedSwiftAssociatedValueEnum { @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() { switch self { case .success(let param0): - _swift_js_push_tag(Int32(0)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(0)) case .failure(let param0): - _swift_js_push_tag(Int32(1)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(1)) case .flag(let param0): - _swift_js_push_tag(Int32(2)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(2)) case .rate(let param0): - _swift_js_push_tag(Int32(3)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(3)) case .precise(let param0): - _swift_js_push_tag(Int32(4)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(4)) case .info: _swift_js_push_tag(Int32(5)) } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayTypes.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayTypes.js index 491fc610..4610d03b 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayTypes.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayTypes.js @@ -31,7 +31,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -98,7 +98,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); @@ -382,9 +382,9 @@ export async function createInstantiator(options, swift) { processPointArray: function bjs_processPointArray(points) { const arrayCleanups = []; for (const elem of points) { - const { cleanup: cleanup } = structHelpers.Point.lower(elem); + const { cleanup: structCleanup } = structHelpers.Point.lower(elem); arrayCleanups.push(() => { - if (cleanup) { cleanup(); } + if (structCleanup) { structCleanup(); } }); } tmpParamInts.push(points.length); @@ -446,9 +446,9 @@ export async function createInstantiator(options, swift) { findFirstPoint: function bjs_findFirstPoint(points, matching) { const arrayCleanups = []; for (const elem of points) { - const { cleanup: cleanup } = structHelpers.Point.lower(elem); + const { cleanup: structCleanup } = structHelpers.Point.lower(elem); arrayCleanups.push(() => { - if (cleanup) { cleanup(); } + if (structCleanup) { structCleanup(); } }); } tmpParamInts.push(points.length); @@ -610,8 +610,8 @@ export async function createInstantiator(options, swift) { for (const elem of points) { const isSome = elem != null ? 1 : 0; if (isSome) { - const { cleanup: cleanup } = structHelpers.Point.lower(elem); - arrayCleanups.push(() => { if (cleanup) { cleanup(); } }); + const { cleanup: structCleanup } = structHelpers.Point.lower(elem); + arrayCleanups.push(() => { if (structCleanup) { structCleanup(); } }); } else { } tmpParamInts.push(isSome); @@ -766,9 +766,9 @@ export async function createInstantiator(options, swift) { for (const elem of points) { const arrayCleanups1 = []; for (const elem1 of elem) { - const { cleanup: cleanup } = structHelpers.Point.lower(elem1); + const { cleanup: structCleanup } = structHelpers.Point.lower(elem1); arrayCleanups1.push(() => { - if (cleanup) { cleanup(); } + if (structCleanup) { structCleanup(); } }); } tmpParamInts.push(elem.length); @@ -805,7 +805,7 @@ export async function createInstantiator(options, swift) { const arrayResult = []; for (let i = 0; i < arrayLen; i++) { const ptr = tmpRetPointers.pop(); - const obj = Item.__construct(ptr); + const obj = _exports['Item'].__construct(ptr); arrayResult.push(obj); } arrayResult.reverse(); @@ -833,7 +833,7 @@ export async function createInstantiator(options, swift) { const arrayResult1 = []; for (let i1 = 0; i1 < arrayLen1; i1++) { const ptr = tmpRetPointers.pop(); - const obj = Item.__construct(ptr); + const obj = _exports['Item'].__construct(ptr); arrayResult1.push(obj); } arrayResult1.reverse(); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.js index d5a19543..0aa9148c 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.js @@ -18,7 +18,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -70,7 +70,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DefaultParameters.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DefaultParameters.js index bc669993..754c47b0 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DefaultParameters.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DefaultParameters.js @@ -24,7 +24,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -123,7 +123,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.d.ts index 20962c38..9ab11701 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.d.ts +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.d.ts @@ -43,6 +43,65 @@ export const APIOptionalResultValues: { export type APIOptionalResultTag = { tag: typeof APIOptionalResultValues.Tag.Success; param0: string | null } | { tag: typeof APIOptionalResultValues.Tag.Failure; param0: number | null; param1: boolean | null } | { tag: typeof APIOptionalResultValues.Tag.Status; param0: boolean | null; param1: number | null; param2: string | null } +export const PrecisionValues: { + readonly Rough: 0.1; + readonly Fine: 0.001; +}; +export type PrecisionTag = typeof PrecisionValues[keyof typeof PrecisionValues]; + +export const CardinalDirectionValues: { + readonly North: 0; + readonly South: 1; + readonly East: 2; + readonly West: 3; +}; +export type CardinalDirectionTag = typeof CardinalDirectionValues[keyof typeof CardinalDirectionValues]; + +export const TypedPayloadResultValues: { + readonly Tag: { + readonly Precision: 0; + readonly Direction: 1; + readonly OptPrecision: 2; + readonly OptDirection: 3; + readonly Empty: 4; + }; +}; + +export type TypedPayloadResultTag = + { tag: typeof TypedPayloadResultValues.Tag.Precision; param0: PrecisionTag } | { tag: typeof TypedPayloadResultValues.Tag.Direction; param0: CardinalDirectionTag } | { tag: typeof TypedPayloadResultValues.Tag.OptPrecision; param0: PrecisionTag | null } | { tag: typeof TypedPayloadResultValues.Tag.OptDirection; param0: CardinalDirectionTag | null } | { tag: typeof TypedPayloadResultValues.Tag.Empty } + +export const AllTypesResultValues: { + readonly Tag: { + readonly StructPayload: 0; + readonly ClassPayload: 1; + readonly JsObjectPayload: 2; + readonly NestedEnum: 3; + readonly ArrayPayload: 4; + readonly Empty: 5; + }; +}; + +export type AllTypesResultTag = + { tag: typeof AllTypesResultValues.Tag.StructPayload; param0: PointTag } | { tag: typeof AllTypesResultValues.Tag.ClassPayload; param0: User } | { tag: typeof AllTypesResultValues.Tag.JsObjectPayload; param0: any } | { tag: typeof AllTypesResultValues.Tag.NestedEnum; param0: APIResultTag } | { tag: typeof AllTypesResultValues.Tag.ArrayPayload; param0: number[] } | { tag: typeof AllTypesResultValues.Tag.Empty } + +export const OptionalAllTypesResultValues: { + readonly Tag: { + readonly OptStruct: 0; + readonly OptClass: 1; + readonly OptJSObject: 2; + readonly OptNestedEnum: 3; + readonly OptArray: 4; + readonly Empty: 5; + }; +}; + +export type OptionalAllTypesResultTag = + { tag: typeof OptionalAllTypesResultValues.Tag.OptStruct; param0: PointTag | null } | { tag: typeof OptionalAllTypesResultValues.Tag.OptClass; param0: User | null } | { tag: typeof OptionalAllTypesResultValues.Tag.OptJSObject; param0: any | null } | { tag: typeof OptionalAllTypesResultValues.Tag.OptNestedEnum; param0: APIResultTag | null } | { tag: typeof OptionalAllTypesResultValues.Tag.OptArray; param0: number[] | null } | { tag: typeof OptionalAllTypesResultValues.Tag.Empty } + +export interface Point { + x: number; + y: number; +} export type APIResultObject = typeof APIResultValues; export type ComplexResultObject = typeof ComplexResultValues; @@ -53,6 +112,16 @@ export type NetworkingResultObject = typeof API.NetworkingResultValues; export type APIOptionalResultObject = typeof APIOptionalResultValues; +export type PrecisionObject = typeof PrecisionValues; + +export type CardinalDirectionObject = typeof CardinalDirectionValues; + +export type TypedPayloadResultObject = typeof TypedPayloadResultValues; + +export type AllTypesResultObject = typeof AllTypesResultValues; + +export type OptionalAllTypesResultObject = typeof OptionalAllTypesResultValues; + export namespace API { const NetworkingResultValues: { readonly Tag: { @@ -74,7 +143,18 @@ export namespace Utilities { type ResultTag = { tag: typeof ResultValues.Tag.Success; param0: string } | { tag: typeof ResultValues.Tag.Failure; param0: string; param1: number } | { tag: typeof ResultValues.Tag.Status; param0: boolean; param1: number; param2: string } } +/// Represents a Swift heap object like a class instance or an actor instance. +export interface SwiftHeapObject { + /// Release the heap object. + /// + /// Note: Calling this method will release the heap object and it will no longer be accessible. + release(): void; +} +export interface User extends SwiftHeapObject { +} export type Exports = { + User: { + } handle(result: APIResultTag): void; getResult(): APIResultTag; roundtripAPIResult(result: APIResultTag): APIResultTag; @@ -87,9 +167,20 @@ export type Exports = { roundTripOptionalNetworkingResult(result: API.NetworkingResultTag | null): API.NetworkingResultTag | null; roundTripOptionalAPIOptionalResult(result: APIOptionalResultTag | null): APIOptionalResultTag | null; compareAPIResults(result1: APIOptionalResultTag | null, result2: APIOptionalResultTag | null): APIOptionalResultTag | null; + roundTripTypedPayloadResult(result: TypedPayloadResultTag): TypedPayloadResultTag; + roundTripOptionalTypedPayloadResult(result: TypedPayloadResultTag | null): TypedPayloadResultTag | null; + roundTripAllTypesResult(result: AllTypesResultTag): AllTypesResultTag; + roundTripOptionalAllTypesResult(result: AllTypesResultTag | null): AllTypesResultTag | null; + roundTripOptionalPayloadResult(result: OptionalAllTypesResultTag): OptionalAllTypesResultTag; + roundTripOptionalPayloadResultOpt(result: OptionalAllTypesResultTag | null): OptionalAllTypesResultTag | null; APIResult: APIResultObject ComplexResult: ComplexResultObject APIOptionalResult: APIOptionalResultObject + Precision: PrecisionObject + CardinalDirection: CardinalDirectionObject + TypedPayloadResult: TypedPayloadResultObject + AllTypesResult: AllTypesResultObject + OptionalAllTypesResult: OptionalAllTypesResultObject API: { NetworkingResult: NetworkingResultObject }, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.js index 6eb4b398..123ba56f 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.js @@ -14,78 +14,6 @@ export const APIResultValues = { Info: 5, }, }; - -const __bjs_createAPIResultValuesHelpers = () => { - return (tmpParamInts, tmpParamF32s, tmpParamF64s, textEncoder, swift) => ({ - lower: (value) => { - const enumTag = value.tag; - switch (enumTag) { - case APIResultValues.Tag.Success: { - const bytes = textEncoder.encode(value.param0); - const id = swift.memory.retain(bytes); - tmpParamInts.push(bytes.length); - tmpParamInts.push(id); - const cleanup = () => { - swift.memory.release(id); - }; - return { caseId: APIResultValues.Tag.Success, cleanup }; - } - case APIResultValues.Tag.Failure: { - tmpParamInts.push((value.param0 | 0)); - const cleanup = undefined; - return { caseId: APIResultValues.Tag.Failure, cleanup }; - } - case APIResultValues.Tag.Flag: { - tmpParamInts.push(value.param0 ? 1 : 0); - const cleanup = undefined; - return { caseId: APIResultValues.Tag.Flag, cleanup }; - } - case APIResultValues.Tag.Rate: { - tmpParamF32s.push(Math.fround(value.param0)); - const cleanup = undefined; - return { caseId: APIResultValues.Tag.Rate, cleanup }; - } - case APIResultValues.Tag.Precise: { - tmpParamF64s.push(value.param0); - const cleanup = undefined; - return { caseId: APIResultValues.Tag.Precise, cleanup }; - } - case APIResultValues.Tag.Info: { - const cleanup = undefined; - return { caseId: APIResultValues.Tag.Info, cleanup }; - } - default: throw new Error("Unknown APIResultValues tag: " + String(enumTag)); - } - }, - lift: (tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s) => { - const tag = tmpRetTag | 0; - switch (tag) { - case APIResultValues.Tag.Success: { - const string = tmpRetStrings.pop(); - return { tag: APIResultValues.Tag.Success, param0: string }; - } - case APIResultValues.Tag.Failure: { - const int = tmpRetInts.pop(); - return { tag: APIResultValues.Tag.Failure, param0: int }; - } - case APIResultValues.Tag.Flag: { - const bool = tmpRetInts.pop(); - return { tag: APIResultValues.Tag.Flag, param0: bool }; - } - case APIResultValues.Tag.Rate: { - const f32 = tmpRetF32s.pop(); - return { tag: APIResultValues.Tag.Rate, param0: f32 }; - } - case APIResultValues.Tag.Precise: { - const f64 = tmpRetF64s.pop(); - return { tag: APIResultValues.Tag.Precise, param0: f64 }; - } - case APIResultValues.Tag.Info: return { tag: APIResultValues.Tag.Info }; - default: throw new Error("Unknown APIResultValues tag returned from Swift: " + String(tag)); - } - } - }); -}; export const ComplexResultValues = { Tag: { Success: 0, @@ -96,127 +24,6 @@ export const ComplexResultValues = { Info: 5, }, }; - -const __bjs_createComplexResultValuesHelpers = () => { - return (tmpParamInts, tmpParamF32s, tmpParamF64s, textEncoder, swift) => ({ - lower: (value) => { - const enumTag = value.tag; - switch (enumTag) { - case ComplexResultValues.Tag.Success: { - const bytes = textEncoder.encode(value.param0); - const id = swift.memory.retain(bytes); - tmpParamInts.push(bytes.length); - tmpParamInts.push(id); - const cleanup = () => { - swift.memory.release(id); - }; - return { caseId: ComplexResultValues.Tag.Success, cleanup }; - } - case ComplexResultValues.Tag.Error: { - tmpParamInts.push((value.param1 | 0)); - const bytes = textEncoder.encode(value.param0); - const id = swift.memory.retain(bytes); - tmpParamInts.push(bytes.length); - tmpParamInts.push(id); - const cleanup = () => { - swift.memory.release(id); - }; - return { caseId: ComplexResultValues.Tag.Error, cleanup }; - } - case ComplexResultValues.Tag.Status: { - const bytes = textEncoder.encode(value.param2); - const id = swift.memory.retain(bytes); - tmpParamInts.push(bytes.length); - tmpParamInts.push(id); - tmpParamInts.push((value.param1 | 0)); - tmpParamInts.push(value.param0 ? 1 : 0); - const cleanup = () => { - swift.memory.release(id); - }; - return { caseId: ComplexResultValues.Tag.Status, cleanup }; - } - case ComplexResultValues.Tag.Coordinates: { - tmpParamF64s.push(value.param2); - tmpParamF64s.push(value.param1); - tmpParamF64s.push(value.param0); - const cleanup = undefined; - return { caseId: ComplexResultValues.Tag.Coordinates, cleanup }; - } - case ComplexResultValues.Tag.Comprehensive: { - const bytes = textEncoder.encode(value.param8); - const id = swift.memory.retain(bytes); - tmpParamInts.push(bytes.length); - tmpParamInts.push(id); - const bytes1 = textEncoder.encode(value.param7); - const id1 = swift.memory.retain(bytes1); - tmpParamInts.push(bytes1.length); - tmpParamInts.push(id1); - const bytes2 = textEncoder.encode(value.param6); - const id2 = swift.memory.retain(bytes2); - tmpParamInts.push(bytes2.length); - tmpParamInts.push(id2); - 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(id); - swift.memory.release(id1); - swift.memory.release(id2); - }; - return { caseId: ComplexResultValues.Tag.Comprehensive, cleanup }; - } - case ComplexResultValues.Tag.Info: { - const cleanup = undefined; - return { caseId: ComplexResultValues.Tag.Info, cleanup }; - } - default: throw new Error("Unknown ComplexResultValues tag: " + String(enumTag)); - } - }, - lift: (tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s) => { - const tag = tmpRetTag | 0; - switch (tag) { - case ComplexResultValues.Tag.Success: { - const string = tmpRetStrings.pop(); - return { tag: ComplexResultValues.Tag.Success, param0: string }; - } - case ComplexResultValues.Tag.Error: { - const int = tmpRetInts.pop(); - const string = tmpRetStrings.pop(); - return { tag: ComplexResultValues.Tag.Error, param0: string, param1: int }; - } - case ComplexResultValues.Tag.Status: { - const string = tmpRetStrings.pop(); - const int = tmpRetInts.pop(); - const bool = tmpRetInts.pop(); - return { tag: ComplexResultValues.Tag.Status, param0: bool, param1: int, param2: string }; - } - case ComplexResultValues.Tag.Coordinates: { - const f64 = tmpRetF64s.pop(); - const f641 = tmpRetF64s.pop(); - const f642 = tmpRetF64s.pop(); - return { tag: ComplexResultValues.Tag.Coordinates, param0: f642, param1: f641, param2: f64 }; - } - case ComplexResultValues.Tag.Comprehensive: { - const string = tmpRetStrings.pop(); - const string1 = tmpRetStrings.pop(); - const string2 = tmpRetStrings.pop(); - const f64 = tmpRetF64s.pop(); - const f641 = tmpRetF64s.pop(); - const int = tmpRetInts.pop(); - const int1 = tmpRetInts.pop(); - const bool = tmpRetInts.pop(); - const bool1 = tmpRetInts.pop(); - return { tag: ComplexResultValues.Tag.Comprehensive, param0: bool1, param1: bool, param2: int1, param3: int, param4: f641, param5: f64, param6: string2, param7: string1, param8: string }; - } - case ComplexResultValues.Tag.Info: return { tag: ComplexResultValues.Tag.Info }; - default: throw new Error("Unknown ComplexResultValues tag returned from Swift: " + String(tag)); - } - } - }); -}; export const ResultValues = { Tag: { Success: 0, @@ -224,124 +31,12 @@ export const ResultValues = { Status: 2, }, }; - -const __bjs_createResultValuesHelpers = () => { - return (tmpParamInts, tmpParamF32s, tmpParamF64s, textEncoder, swift) => ({ - lower: (value) => { - const enumTag = value.tag; - switch (enumTag) { - case ResultValues.Tag.Success: { - const bytes = textEncoder.encode(value.param0); - const id = swift.memory.retain(bytes); - tmpParamInts.push(bytes.length); - tmpParamInts.push(id); - const cleanup = () => { - swift.memory.release(id); - }; - return { caseId: ResultValues.Tag.Success, cleanup }; - } - case ResultValues.Tag.Failure: { - tmpParamInts.push((value.param1 | 0)); - const bytes = textEncoder.encode(value.param0); - const id = swift.memory.retain(bytes); - tmpParamInts.push(bytes.length); - tmpParamInts.push(id); - const cleanup = () => { - swift.memory.release(id); - }; - return { caseId: ResultValues.Tag.Failure, cleanup }; - } - case ResultValues.Tag.Status: { - const bytes = textEncoder.encode(value.param2); - const id = swift.memory.retain(bytes); - tmpParamInts.push(bytes.length); - tmpParamInts.push(id); - tmpParamInts.push((value.param1 | 0)); - tmpParamInts.push(value.param0 ? 1 : 0); - const cleanup = () => { - swift.memory.release(id); - }; - return { caseId: ResultValues.Tag.Status, cleanup }; - } - default: throw new Error("Unknown ResultValues tag: " + String(enumTag)); - } - }, - lift: (tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s) => { - const tag = tmpRetTag | 0; - switch (tag) { - case ResultValues.Tag.Success: { - const string = tmpRetStrings.pop(); - return { tag: ResultValues.Tag.Success, param0: string }; - } - case ResultValues.Tag.Failure: { - const int = tmpRetInts.pop(); - const string = tmpRetStrings.pop(); - return { tag: ResultValues.Tag.Failure, param0: string, param1: int }; - } - case ResultValues.Tag.Status: { - const string = tmpRetStrings.pop(); - const int = tmpRetInts.pop(); - const bool = tmpRetInts.pop(); - return { tag: ResultValues.Tag.Status, param0: bool, param1: int, param2: string }; - } - default: throw new Error("Unknown ResultValues tag returned from Swift: " + String(tag)); - } - } - }); -}; export const NetworkingResultValues = { Tag: { Success: 0, Failure: 1, }, }; - -const __bjs_createNetworkingResultValuesHelpers = () => { - return (tmpParamInts, tmpParamF32s, tmpParamF64s, textEncoder, swift) => ({ - lower: (value) => { - const enumTag = value.tag; - switch (enumTag) { - case NetworkingResultValues.Tag.Success: { - const bytes = textEncoder.encode(value.param0); - const id = swift.memory.retain(bytes); - tmpParamInts.push(bytes.length); - tmpParamInts.push(id); - const cleanup = () => { - swift.memory.release(id); - }; - return { caseId: NetworkingResultValues.Tag.Success, cleanup }; - } - case NetworkingResultValues.Tag.Failure: { - tmpParamInts.push((value.param1 | 0)); - const bytes = textEncoder.encode(value.param0); - const id = swift.memory.retain(bytes); - tmpParamInts.push(bytes.length); - tmpParamInts.push(id); - const cleanup = () => { - swift.memory.release(id); - }; - return { caseId: NetworkingResultValues.Tag.Failure, cleanup }; - } - default: throw new Error("Unknown NetworkingResultValues tag: " + String(enumTag)); - } - }, - lift: (tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s) => { - const tag = tmpRetTag | 0; - switch (tag) { - case NetworkingResultValues.Tag.Success: { - const string = tmpRetStrings.pop(); - return { tag: NetworkingResultValues.Tag.Success, param0: string }; - } - case NetworkingResultValues.Tag.Failure: { - const int = tmpRetInts.pop(); - const string = tmpRetStrings.pop(); - return { tag: NetworkingResultValues.Tag.Failure, param0: string, param1: int }; - } - default: throw new Error("Unknown NetworkingResultValues tag returned from Swift: " + String(tag)); - } - } - }); -}; export const APIOptionalResultValues = { Tag: { Success: 0, @@ -349,135 +44,46 @@ export const APIOptionalResultValues = { Status: 2, }, }; +export const PrecisionValues = { + Rough: 0.1, + Fine: 0.001, +}; -const __bjs_createAPIOptionalResultValuesHelpers = () => { - return (tmpParamInts, tmpParamF32s, tmpParamF64s, textEncoder, swift) => ({ - lower: (value) => { - const enumTag = value.tag; - switch (enumTag) { - case APIOptionalResultValues.Tag.Success: { - const isSome = value.param0 != null; - let id; - if (isSome) { - let bytes = textEncoder.encode(value.param0); - id = swift.memory.retain(bytes); - tmpParamInts.push(bytes.length); - tmpParamInts.push(id); - } else { - tmpParamInts.push(0); - tmpParamInts.push(0); - } - tmpParamInts.push(isSome ? 1 : 0); - const cleanup = () => { - if(id) { - swift.memory.release(id); - } - }; - return { caseId: APIOptionalResultValues.Tag.Success, cleanup }; - } - case APIOptionalResultValues.Tag.Failure: { - const isSome = value.param1 != null; - tmpParamInts.push(isSome ? (value.param1 ? 1 : 0) : 0); - tmpParamInts.push(isSome ? 1 : 0); - const isSome1 = value.param0 != null; - tmpParamInts.push(isSome1 ? (value.param0 | 0) : 0); - tmpParamInts.push(isSome1 ? 1 : 0); - const cleanup = undefined; - return { caseId: APIOptionalResultValues.Tag.Failure, cleanup }; - } - case APIOptionalResultValues.Tag.Status: { - const isSome = value.param2 != null; - let id; - if (isSome) { - let bytes = textEncoder.encode(value.param2); - id = swift.memory.retain(bytes); - tmpParamInts.push(bytes.length); - tmpParamInts.push(id); - } else { - tmpParamInts.push(0); - tmpParamInts.push(0); - } - tmpParamInts.push(isSome ? 1 : 0); - const isSome1 = value.param1 != null; - tmpParamInts.push(isSome1 ? (value.param1 | 0) : 0); - tmpParamInts.push(isSome1 ? 1 : 0); - const isSome2 = value.param0 != null; - tmpParamInts.push(isSome2 ? (value.param0 ? 1 : 0) : 0); - tmpParamInts.push(isSome2 ? 1 : 0); - const cleanup = () => { - if(id) { - swift.memory.release(id); - } - }; - return { caseId: APIOptionalResultValues.Tag.Status, cleanup }; - } - default: throw new Error("Unknown APIOptionalResultValues tag: " + String(enumTag)); - } - }, - lift: (tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s) => { - const tag = tmpRetTag | 0; - switch (tag) { - case APIOptionalResultValues.Tag.Success: { - const isSome = tmpRetInts.pop(); - let optional; - if (isSome) { - const string = tmpRetStrings.pop(); - optional = string; - } else { - optional = null; - } - return { tag: APIOptionalResultValues.Tag.Success, param0: optional }; - } - case APIOptionalResultValues.Tag.Failure: { - const isSome = tmpRetInts.pop(); - let optional; - if (isSome) { - const bool = tmpRetInts.pop(); - optional = bool; - } else { - optional = null; - } - const isSome1 = tmpRetInts.pop(); - let optional1; - if (isSome1) { - const int = tmpRetInts.pop(); - optional1 = int; - } else { - optional1 = null; - } - return { tag: APIOptionalResultValues.Tag.Failure, param0: optional1, param1: optional }; - } - case APIOptionalResultValues.Tag.Status: { - const isSome = tmpRetInts.pop(); - let optional; - if (isSome) { - const string = tmpRetStrings.pop(); - optional = string; - } else { - optional = null; - } - const isSome1 = tmpRetInts.pop(); - let optional1; - if (isSome1) { - const int = tmpRetInts.pop(); - optional1 = int; - } else { - optional1 = null; - } - const isSome2 = tmpRetInts.pop(); - let optional2; - if (isSome2) { - const bool = tmpRetInts.pop(); - optional2 = bool; - } else { - optional2 = null; - } - return { tag: APIOptionalResultValues.Tag.Status, param0: optional2, param1: optional1, param2: optional }; - } - default: throw new Error("Unknown APIOptionalResultValues tag returned from Swift: " + String(tag)); - } - } - }); +export const CardinalDirectionValues = { + North: 0, + South: 1, + East: 2, + West: 3, +}; + +export const TypedPayloadResultValues = { + Tag: { + Precision: 0, + Direction: 1, + OptPrecision: 2, + OptDirection: 3, + Empty: 4, + }, +}; +export const AllTypesResultValues = { + Tag: { + StructPayload: 0, + ClassPayload: 1, + JsObjectPayload: 2, + NestedEnum: 3, + ArrayPayload: 4, + Empty: 5, + }, +}; +export const OptionalAllTypesResultValues = { + Tag: { + OptStruct: 0, + OptClass: 1, + OptJSObject: 2, + OptNestedEnum: 3, + OptArray: 4, + Empty: 5, + }, }; export async function createInstantiator(options, swift) { let instance; @@ -493,7 +99,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -509,6 +115,771 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; + const __bjs_createPointHelpers = () => { + return (tmpParamInts, tmpParamF32s, tmpParamF64s, tmpParamPointers, tmpRetPointers, textEncoder, swift, enumHelpers) => ({ + lower: (value) => { + tmpParamF64s.push(value.x); + tmpParamF64s.push(value.y); + return { cleanup: undefined }; + }, + lift: (tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers) => { + const f64 = tmpRetF64s.pop(); + const f641 = tmpRetF64s.pop(); + return { x: f641, y: f64 }; + } + }); + }; + const __bjs_createAPIResultValuesHelpers = () => { + return (tmpParamInts, tmpParamF32s, tmpParamF64s, tmpParamPointers, tmpRetPointers, textEncoder, swift, structHelpers, enumHelpers) => ({ + lower: (value) => { + const enumTag = value.tag; + switch (enumTag) { + case APIResultValues.Tag.Success: { + const bytes = textEncoder.encode(value.param0); + const id = swift.memory.retain(bytes); + tmpParamInts.push(bytes.length); + tmpParamInts.push(id); + const cleanup = () => { + swift.memory.release(id); + }; + return { caseId: APIResultValues.Tag.Success, cleanup }; + } + case APIResultValues.Tag.Failure: { + tmpParamInts.push((value.param0 | 0)); + const cleanup = undefined; + return { caseId: APIResultValues.Tag.Failure, cleanup }; + } + case APIResultValues.Tag.Flag: { + tmpParamInts.push(value.param0 ? 1 : 0); + const cleanup = undefined; + return { caseId: APIResultValues.Tag.Flag, cleanup }; + } + case APIResultValues.Tag.Rate: { + tmpParamF32s.push(Math.fround(value.param0)); + const cleanup = undefined; + return { caseId: APIResultValues.Tag.Rate, cleanup }; + } + case APIResultValues.Tag.Precise: { + tmpParamF64s.push(value.param0); + const cleanup = undefined; + return { caseId: APIResultValues.Tag.Precise, cleanup }; + } + case APIResultValues.Tag.Info: { + const cleanup = undefined; + return { caseId: APIResultValues.Tag.Info, cleanup }; + } + default: throw new Error("Unknown APIResultValues tag: " + String(enumTag)); + } + }, + lift: (tag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers) => { + tag = tag | 0; + switch (tag) { + case APIResultValues.Tag.Success: { + const string = tmpRetStrings.pop(); + return { tag: APIResultValues.Tag.Success, param0: string }; + } + case APIResultValues.Tag.Failure: { + const int = tmpRetInts.pop(); + return { tag: APIResultValues.Tag.Failure, param0: int }; + } + case APIResultValues.Tag.Flag: { + const bool = tmpRetInts.pop() !== 0; + return { tag: APIResultValues.Tag.Flag, param0: bool }; + } + case APIResultValues.Tag.Rate: { + const f32 = tmpRetF32s.pop(); + return { tag: APIResultValues.Tag.Rate, param0: f32 }; + } + case APIResultValues.Tag.Precise: { + const f64 = tmpRetF64s.pop(); + return { tag: APIResultValues.Tag.Precise, param0: f64 }; + } + case APIResultValues.Tag.Info: return { tag: APIResultValues.Tag.Info }; + default: throw new Error("Unknown APIResultValues tag returned from Swift: " + String(tag)); + } + } + }); + }; + const __bjs_createComplexResultValuesHelpers = () => { + return (tmpParamInts, tmpParamF32s, tmpParamF64s, tmpParamPointers, tmpRetPointers, textEncoder, swift, structHelpers, enumHelpers) => ({ + lower: (value) => { + const enumTag = value.tag; + switch (enumTag) { + case ComplexResultValues.Tag.Success: { + const bytes = textEncoder.encode(value.param0); + const id = swift.memory.retain(bytes); + tmpParamInts.push(bytes.length); + tmpParamInts.push(id); + const cleanup = () => { + swift.memory.release(id); + }; + return { caseId: ComplexResultValues.Tag.Success, cleanup }; + } + case ComplexResultValues.Tag.Error: { + tmpParamInts.push((value.param1 | 0)); + const bytes = textEncoder.encode(value.param0); + const id = swift.memory.retain(bytes); + tmpParamInts.push(bytes.length); + tmpParamInts.push(id); + const cleanup = () => { + swift.memory.release(id); + }; + return { caseId: ComplexResultValues.Tag.Error, cleanup }; + } + case ComplexResultValues.Tag.Status: { + const bytes = textEncoder.encode(value.param2); + const id = swift.memory.retain(bytes); + tmpParamInts.push(bytes.length); + tmpParamInts.push(id); + tmpParamInts.push((value.param1 | 0)); + tmpParamInts.push(value.param0 ? 1 : 0); + const cleanup = () => { + swift.memory.release(id); + }; + return { caseId: ComplexResultValues.Tag.Status, cleanup }; + } + case ComplexResultValues.Tag.Coordinates: { + tmpParamF64s.push(value.param2); + tmpParamF64s.push(value.param1); + tmpParamF64s.push(value.param0); + const cleanup = undefined; + return { caseId: ComplexResultValues.Tag.Coordinates, cleanup }; + } + case ComplexResultValues.Tag.Comprehensive: { + const bytes = textEncoder.encode(value.param8); + const id = swift.memory.retain(bytes); + tmpParamInts.push(bytes.length); + tmpParamInts.push(id); + const bytes1 = textEncoder.encode(value.param7); + const id1 = swift.memory.retain(bytes1); + tmpParamInts.push(bytes1.length); + tmpParamInts.push(id1); + const bytes2 = textEncoder.encode(value.param6); + const id2 = swift.memory.retain(bytes2); + tmpParamInts.push(bytes2.length); + tmpParamInts.push(id2); + 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(id); + swift.memory.release(id1); + swift.memory.release(id2); + }; + return { caseId: ComplexResultValues.Tag.Comprehensive, cleanup }; + } + case ComplexResultValues.Tag.Info: { + const cleanup = undefined; + return { caseId: ComplexResultValues.Tag.Info, cleanup }; + } + default: throw new Error("Unknown ComplexResultValues tag: " + String(enumTag)); + } + }, + lift: (tag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers) => { + tag = tag | 0; + switch (tag) { + case ComplexResultValues.Tag.Success: { + const string = tmpRetStrings.pop(); + return { tag: ComplexResultValues.Tag.Success, param0: string }; + } + case ComplexResultValues.Tag.Error: { + const int = tmpRetInts.pop(); + const string = tmpRetStrings.pop(); + return { tag: ComplexResultValues.Tag.Error, param0: string, param1: int }; + } + case ComplexResultValues.Tag.Status: { + const string = tmpRetStrings.pop(); + const int = tmpRetInts.pop(); + const bool = tmpRetInts.pop() !== 0; + return { tag: ComplexResultValues.Tag.Status, param0: bool, param1: int, param2: string }; + } + case ComplexResultValues.Tag.Coordinates: { + const f64 = tmpRetF64s.pop(); + const f641 = tmpRetF64s.pop(); + const f642 = tmpRetF64s.pop(); + return { tag: ComplexResultValues.Tag.Coordinates, param0: f642, param1: f641, param2: f64 }; + } + case ComplexResultValues.Tag.Comprehensive: { + const string = tmpRetStrings.pop(); + const string1 = tmpRetStrings.pop(); + const string2 = tmpRetStrings.pop(); + const f64 = tmpRetF64s.pop(); + const f641 = tmpRetF64s.pop(); + const int = tmpRetInts.pop(); + const int1 = tmpRetInts.pop(); + const bool = tmpRetInts.pop() !== 0; + const bool1 = tmpRetInts.pop() !== 0; + return { tag: ComplexResultValues.Tag.Comprehensive, param0: bool1, param1: bool, param2: int1, param3: int, param4: f641, param5: f64, param6: string2, param7: string1, param8: string }; + } + case ComplexResultValues.Tag.Info: return { tag: ComplexResultValues.Tag.Info }; + default: throw new Error("Unknown ComplexResultValues tag returned from Swift: " + String(tag)); + } + } + }); + }; + const __bjs_createResultValuesHelpers = () => { + return (tmpParamInts, tmpParamF32s, tmpParamF64s, tmpParamPointers, tmpRetPointers, textEncoder, swift, structHelpers, enumHelpers) => ({ + lower: (value) => { + const enumTag = value.tag; + switch (enumTag) { + case ResultValues.Tag.Success: { + const bytes = textEncoder.encode(value.param0); + const id = swift.memory.retain(bytes); + tmpParamInts.push(bytes.length); + tmpParamInts.push(id); + const cleanup = () => { + swift.memory.release(id); + }; + return { caseId: ResultValues.Tag.Success, cleanup }; + } + case ResultValues.Tag.Failure: { + tmpParamInts.push((value.param1 | 0)); + const bytes = textEncoder.encode(value.param0); + const id = swift.memory.retain(bytes); + tmpParamInts.push(bytes.length); + tmpParamInts.push(id); + const cleanup = () => { + swift.memory.release(id); + }; + return { caseId: ResultValues.Tag.Failure, cleanup }; + } + case ResultValues.Tag.Status: { + const bytes = textEncoder.encode(value.param2); + const id = swift.memory.retain(bytes); + tmpParamInts.push(bytes.length); + tmpParamInts.push(id); + tmpParamInts.push((value.param1 | 0)); + tmpParamInts.push(value.param0 ? 1 : 0); + const cleanup = () => { + swift.memory.release(id); + }; + return { caseId: ResultValues.Tag.Status, cleanup }; + } + default: throw new Error("Unknown ResultValues tag: " + String(enumTag)); + } + }, + lift: (tag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers) => { + tag = tag | 0; + switch (tag) { + case ResultValues.Tag.Success: { + const string = tmpRetStrings.pop(); + return { tag: ResultValues.Tag.Success, param0: string }; + } + case ResultValues.Tag.Failure: { + const int = tmpRetInts.pop(); + const string = tmpRetStrings.pop(); + return { tag: ResultValues.Tag.Failure, param0: string, param1: int }; + } + case ResultValues.Tag.Status: { + const string = tmpRetStrings.pop(); + const int = tmpRetInts.pop(); + const bool = tmpRetInts.pop() !== 0; + return { tag: ResultValues.Tag.Status, param0: bool, param1: int, param2: string }; + } + default: throw new Error("Unknown ResultValues tag returned from Swift: " + String(tag)); + } + } + }); + }; + const __bjs_createNetworkingResultValuesHelpers = () => { + return (tmpParamInts, tmpParamF32s, tmpParamF64s, tmpParamPointers, tmpRetPointers, textEncoder, swift, structHelpers, enumHelpers) => ({ + lower: (value) => { + const enumTag = value.tag; + switch (enumTag) { + case NetworkingResultValues.Tag.Success: { + const bytes = textEncoder.encode(value.param0); + const id = swift.memory.retain(bytes); + tmpParamInts.push(bytes.length); + tmpParamInts.push(id); + const cleanup = () => { + swift.memory.release(id); + }; + return { caseId: NetworkingResultValues.Tag.Success, cleanup }; + } + case NetworkingResultValues.Tag.Failure: { + tmpParamInts.push((value.param1 | 0)); + const bytes = textEncoder.encode(value.param0); + const id = swift.memory.retain(bytes); + tmpParamInts.push(bytes.length); + tmpParamInts.push(id); + const cleanup = () => { + swift.memory.release(id); + }; + return { caseId: NetworkingResultValues.Tag.Failure, cleanup }; + } + default: throw new Error("Unknown NetworkingResultValues tag: " + String(enumTag)); + } + }, + lift: (tag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers) => { + tag = tag | 0; + switch (tag) { + case NetworkingResultValues.Tag.Success: { + const string = tmpRetStrings.pop(); + return { tag: NetworkingResultValues.Tag.Success, param0: string }; + } + case NetworkingResultValues.Tag.Failure: { + const int = tmpRetInts.pop(); + const string = tmpRetStrings.pop(); + return { tag: NetworkingResultValues.Tag.Failure, param0: string, param1: int }; + } + default: throw new Error("Unknown NetworkingResultValues tag returned from Swift: " + String(tag)); + } + } + }); + }; + const __bjs_createAPIOptionalResultValuesHelpers = () => { + return (tmpParamInts, tmpParamF32s, tmpParamF64s, tmpParamPointers, tmpRetPointers, textEncoder, swift, structHelpers, enumHelpers) => ({ + lower: (value) => { + const enumTag = value.tag; + switch (enumTag) { + case APIOptionalResultValues.Tag.Success: { + const isSome = value.param0 != null; + let id; + if (isSome) { + let bytes = textEncoder.encode(value.param0); + id = swift.memory.retain(bytes); + tmpParamInts.push(bytes.length); + tmpParamInts.push(id); + } else { + tmpParamInts.push(0); + tmpParamInts.push(0); + } + tmpParamInts.push(isSome ? 1 : 0); + const cleanup = () => { + if(id) { + swift.memory.release(id); + } + }; + return { caseId: APIOptionalResultValues.Tag.Success, cleanup }; + } + case APIOptionalResultValues.Tag.Failure: { + const isSome = value.param1 != null; + tmpParamInts.push(isSome ? (value.param1 ? 1 : 0) : 0); + tmpParamInts.push(isSome ? 1 : 0); + const isSome1 = value.param0 != null; + tmpParamInts.push(isSome1 ? (value.param0 | 0) : 0); + tmpParamInts.push(isSome1 ? 1 : 0); + const cleanup = undefined; + return { caseId: APIOptionalResultValues.Tag.Failure, cleanup }; + } + case APIOptionalResultValues.Tag.Status: { + const isSome = value.param2 != null; + let id; + if (isSome) { + let bytes = textEncoder.encode(value.param2); + id = swift.memory.retain(bytes); + tmpParamInts.push(bytes.length); + tmpParamInts.push(id); + } else { + tmpParamInts.push(0); + tmpParamInts.push(0); + } + tmpParamInts.push(isSome ? 1 : 0); + const isSome1 = value.param1 != null; + tmpParamInts.push(isSome1 ? (value.param1 | 0) : 0); + tmpParamInts.push(isSome1 ? 1 : 0); + const isSome2 = value.param0 != null; + tmpParamInts.push(isSome2 ? (value.param0 ? 1 : 0) : 0); + tmpParamInts.push(isSome2 ? 1 : 0); + const cleanup = () => { + if(id) { + swift.memory.release(id); + } + }; + return { caseId: APIOptionalResultValues.Tag.Status, cleanup }; + } + default: throw new Error("Unknown APIOptionalResultValues tag: " + String(enumTag)); + } + }, + lift: (tag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers) => { + tag = tag | 0; + switch (tag) { + case APIOptionalResultValues.Tag.Success: { + const isSome = tmpRetInts.pop(); + let optional; + if (isSome) { + const string = tmpRetStrings.pop(); + optional = string; + } else { + optional = null; + } + return { tag: APIOptionalResultValues.Tag.Success, param0: optional }; + } + case APIOptionalResultValues.Tag.Failure: { + const isSome = tmpRetInts.pop(); + let optional; + if (isSome) { + const bool = tmpRetInts.pop() !== 0; + optional = bool; + } else { + optional = null; + } + const isSome1 = tmpRetInts.pop(); + let optional1; + if (isSome1) { + const int = tmpRetInts.pop(); + optional1 = int; + } else { + optional1 = null; + } + return { tag: APIOptionalResultValues.Tag.Failure, param0: optional1, param1: optional }; + } + case APIOptionalResultValues.Tag.Status: { + const isSome = tmpRetInts.pop(); + let optional; + if (isSome) { + const string = tmpRetStrings.pop(); + optional = string; + } else { + optional = null; + } + const isSome1 = tmpRetInts.pop(); + let optional1; + if (isSome1) { + const int = tmpRetInts.pop(); + optional1 = int; + } else { + optional1 = null; + } + const isSome2 = tmpRetInts.pop(); + let optional2; + if (isSome2) { + const bool = tmpRetInts.pop() !== 0; + optional2 = bool; + } else { + optional2 = null; + } + return { tag: APIOptionalResultValues.Tag.Status, param0: optional2, param1: optional1, param2: optional }; + } + default: throw new Error("Unknown APIOptionalResultValues tag returned from Swift: " + String(tag)); + } + } + }); + }; + const __bjs_createTypedPayloadResultValuesHelpers = () => { + return (tmpParamInts, tmpParamF32s, tmpParamF64s, tmpParamPointers, tmpRetPointers, textEncoder, swift, structHelpers, enumHelpers) => ({ + lower: (value) => { + const enumTag = value.tag; + switch (enumTag) { + case TypedPayloadResultValues.Tag.Precision: { + tmpParamF32s.push(Math.fround(value.param0)); + const cleanup = undefined; + return { caseId: TypedPayloadResultValues.Tag.Precision, cleanup }; + } + case TypedPayloadResultValues.Tag.Direction: { + tmpParamInts.push((value.param0 | 0)); + const cleanup = undefined; + return { caseId: TypedPayloadResultValues.Tag.Direction, cleanup }; + } + case TypedPayloadResultValues.Tag.OptPrecision: { + const isSome = value.param0 != null; + tmpParamF32s.push(isSome ? Math.fround(value.param0) : 0.0); + tmpParamInts.push(isSome ? 1 : 0); + const cleanup = undefined; + return { caseId: TypedPayloadResultValues.Tag.OptPrecision, cleanup }; + } + case TypedPayloadResultValues.Tag.OptDirection: { + const isSome = value.param0 != null; + tmpParamInts.push(isSome ? (value.param0 | 0) : 0); + tmpParamInts.push(isSome ? 1 : 0); + const cleanup = undefined; + return { caseId: TypedPayloadResultValues.Tag.OptDirection, cleanup }; + } + case TypedPayloadResultValues.Tag.Empty: { + const cleanup = undefined; + return { caseId: TypedPayloadResultValues.Tag.Empty, cleanup }; + } + default: throw new Error("Unknown TypedPayloadResultValues tag: " + String(enumTag)); + } + }, + lift: (tag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers) => { + tag = tag | 0; + switch (tag) { + case TypedPayloadResultValues.Tag.Precision: { + const rawValue = tmpRetF32s.pop(); + return { tag: TypedPayloadResultValues.Tag.Precision, param0: rawValue }; + } + case TypedPayloadResultValues.Tag.Direction: { + const caseId = tmpRetInts.pop(); + return { tag: TypedPayloadResultValues.Tag.Direction, param0: caseId }; + } + case TypedPayloadResultValues.Tag.OptPrecision: { + const isSome = tmpRetInts.pop(); + let optional; + if (isSome) { + const rawValue = tmpRetF32s.pop(); + optional = rawValue; + } else { + optional = null; + } + return { tag: TypedPayloadResultValues.Tag.OptPrecision, param0: optional }; + } + case TypedPayloadResultValues.Tag.OptDirection: { + const isSome = tmpRetInts.pop(); + let optional; + if (isSome) { + const caseId = tmpRetInts.pop(); + optional = caseId; + } else { + optional = null; + } + return { tag: TypedPayloadResultValues.Tag.OptDirection, param0: optional }; + } + case TypedPayloadResultValues.Tag.Empty: return { tag: TypedPayloadResultValues.Tag.Empty }; + default: throw new Error("Unknown TypedPayloadResultValues tag returned from Swift: " + String(tag)); + } + } + }); + }; + const __bjs_createAllTypesResultValuesHelpers = () => { + return (tmpParamInts, tmpParamF32s, tmpParamF64s, tmpParamPointers, tmpRetPointers, textEncoder, swift, structHelpers, enumHelpers) => ({ + lower: (value) => { + const enumTag = value.tag; + switch (enumTag) { + case AllTypesResultValues.Tag.StructPayload: { + const { cleanup: structCleanup } = structHelpers.Point.lower(value.param0); + const cleanup = () => { + if (structCleanup) { structCleanup(); } + }; + return { caseId: AllTypesResultValues.Tag.StructPayload, cleanup }; + } + case AllTypesResultValues.Tag.ClassPayload: { + tmpParamPointers.push(value.param0.pointer); + const cleanup = undefined; + return { caseId: AllTypesResultValues.Tag.ClassPayload, cleanup }; + } + case AllTypesResultValues.Tag.JsObjectPayload: { + const objId = swift.memory.retain(value.param0); + tmpParamInts.push(objId); + const cleanup = undefined; + return { caseId: AllTypesResultValues.Tag.JsObjectPayload, cleanup }; + } + case AllTypesResultValues.Tag.NestedEnum: { + const { caseId: caseId, cleanup: enumCleanup } = enumHelpers.APIResult.lower(value.param0); + tmpParamInts.push(caseId); + const cleanup = () => { + if (enumCleanup) { enumCleanup(); } + }; + return { caseId: AllTypesResultValues.Tag.NestedEnum, cleanup }; + } + case AllTypesResultValues.Tag.ArrayPayload: { + const arrayCleanups = []; + for (const elem of value.param0) { + tmpParamInts.push((elem | 0)); + } + tmpParamInts.push(value.param0.length); + const cleanup = () => { + for (const cleanup of arrayCleanups) { cleanup(); } + }; + return { caseId: AllTypesResultValues.Tag.ArrayPayload, cleanup }; + } + case AllTypesResultValues.Tag.Empty: { + const cleanup = undefined; + return { caseId: AllTypesResultValues.Tag.Empty, cleanup }; + } + default: throw new Error("Unknown AllTypesResultValues tag: " + String(enumTag)); + } + }, + lift: (tag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers) => { + tag = tag | 0; + switch (tag) { + case AllTypesResultValues.Tag.StructPayload: { + const struct = structHelpers.Point.lift(tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers); + return { tag: AllTypesResultValues.Tag.StructPayload, param0: struct }; + } + case AllTypesResultValues.Tag.ClassPayload: { + const ptr = tmpRetPointers.pop(); + const obj = _exports['User'].__construct(ptr); + return { tag: AllTypesResultValues.Tag.ClassPayload, param0: obj }; + } + case AllTypesResultValues.Tag.JsObjectPayload: { + const objId = tmpRetInts.pop(); + const obj = swift.memory.getObject(objId); + swift.memory.release(objId); + return { tag: AllTypesResultValues.Tag.JsObjectPayload, param0: obj }; + } + case AllTypesResultValues.Tag.NestedEnum: { + const enumValue = enumHelpers.APIResult.lift(tmpRetTag.pop(), tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers); + return { tag: AllTypesResultValues.Tag.NestedEnum, param0: enumValue }; + } + case AllTypesResultValues.Tag.ArrayPayload: { + const arrayLen = tmpRetInts.pop(); + const arrayResult = []; + for (let i = 0; i < arrayLen; i++) { + const int = tmpRetInts.pop(); + arrayResult.push(int); + } + arrayResult.reverse(); + return { tag: AllTypesResultValues.Tag.ArrayPayload, param0: arrayResult }; + } + case AllTypesResultValues.Tag.Empty: return { tag: AllTypesResultValues.Tag.Empty }; + default: throw new Error("Unknown AllTypesResultValues tag returned from Swift: " + String(tag)); + } + } + }); + }; + const __bjs_createOptionalAllTypesResultValuesHelpers = () => { + return (tmpParamInts, tmpParamF32s, tmpParamF64s, tmpParamPointers, tmpRetPointers, textEncoder, swift, structHelpers, enumHelpers) => ({ + lower: (value) => { + const enumTag = value.tag; + switch (enumTag) { + case OptionalAllTypesResultValues.Tag.OptStruct: { + const isSome = value.param0 != null; + let nestedCleanup; + if (isSome) { + const structResult = structHelpers.Point.lower(value.param0); + nestedCleanup = structResult.cleanup; + } + tmpParamInts.push(isSome ? 1 : 0); + const cleanup = () => { + if (nestedCleanup) { nestedCleanup(); } + }; + return { caseId: OptionalAllTypesResultValues.Tag.OptStruct, cleanup }; + } + case OptionalAllTypesResultValues.Tag.OptClass: { + const isSome = value.param0 != null; + if (isSome) { + tmpParamPointers.push(value.param0.pointer); + } else { + tmpParamPointers.push(0); + } + tmpParamInts.push(isSome ? 1 : 0); + const cleanup = undefined; + return { caseId: OptionalAllTypesResultValues.Tag.OptClass, cleanup }; + } + case OptionalAllTypesResultValues.Tag.OptJSObject: { + const isSome = value.param0 != null; + let id; + if (isSome) { + id = swift.memory.retain(value.param0); + tmpParamInts.push(id); + } else { + id = undefined; + tmpParamInts.push(0); + } + tmpParamInts.push(isSome ? 1 : 0); + const cleanup = undefined; + return { caseId: OptionalAllTypesResultValues.Tag.OptJSObject, cleanup }; + } + case OptionalAllTypesResultValues.Tag.OptNestedEnum: { + const isSome = value.param0 != null; + let enumCaseId, enumCleanup; + if (isSome) { + const enumResult = enumHelpers.APIResult.lower(value.param0); + enumCaseId = enumResult.caseId; + enumCleanup = enumResult.cleanup; + tmpParamInts.push(enumCaseId); + } else { + tmpParamInts.push(0); + } + tmpParamInts.push(isSome ? 1 : 0); + const cleanup = () => { + if (enumCleanup) { enumCleanup(); } + }; + return { caseId: OptionalAllTypesResultValues.Tag.OptNestedEnum, cleanup }; + } + case OptionalAllTypesResultValues.Tag.OptArray: { + const isSome = value.param0 != null; + let arrCleanup; + if (isSome) { + const arrayCleanups = []; + for (const elem of value.param0) { + tmpParamInts.push((elem | 0)); + } + tmpParamInts.push(value.param0.length); + arrCleanup = () => { + for (const cleanup of arrayCleanups) { cleanup(); } + }; + } + tmpParamInts.push(isSome ? 1 : 0); + const cleanup = () => { + if (arrCleanup) { arrCleanup(); } + }; + return { caseId: OptionalAllTypesResultValues.Tag.OptArray, cleanup }; + } + case OptionalAllTypesResultValues.Tag.Empty: { + const cleanup = undefined; + return { caseId: OptionalAllTypesResultValues.Tag.Empty, cleanup }; + } + default: throw new Error("Unknown OptionalAllTypesResultValues tag: " + String(enumTag)); + } + }, + lift: (tag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers) => { + tag = tag | 0; + switch (tag) { + case OptionalAllTypesResultValues.Tag.OptStruct: { + const isSome = tmpRetInts.pop(); + let optional; + if (isSome) { + const struct = structHelpers.Point.lift(tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers); + optional = struct; + } else { + optional = null; + } + return { tag: OptionalAllTypesResultValues.Tag.OptStruct, param0: optional }; + } + case OptionalAllTypesResultValues.Tag.OptClass: { + const isSome = tmpRetInts.pop(); + let optional; + if (isSome) { + const ptr = tmpRetPointers.pop(); + const obj = _exports['User'].__construct(ptr); + optional = obj; + } else { + optional = null; + } + return { tag: OptionalAllTypesResultValues.Tag.OptClass, param0: optional }; + } + case OptionalAllTypesResultValues.Tag.OptJSObject: { + const isSome = tmpRetInts.pop(); + let optional; + if (isSome) { + const objId = tmpRetInts.pop(); + const obj = swift.memory.getObject(objId); + swift.memory.release(objId); + optional = obj; + } else { + optional = null; + } + return { tag: OptionalAllTypesResultValues.Tag.OptJSObject, param0: optional }; + } + case OptionalAllTypesResultValues.Tag.OptNestedEnum: { + const isSome = tmpRetInts.pop(); + let optional; + if (isSome) { + const caseId = tmpRetInts.pop(); + optional = enumHelpers.APIResult.lift(caseId, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers); + } else { + optional = null; + } + return { tag: OptionalAllTypesResultValues.Tag.OptNestedEnum, param0: optional }; + } + case OptionalAllTypesResultValues.Tag.OptArray: { + const isSome = tmpRetInts.pop(); + let optional; + if (isSome) { + const arrayLen = tmpRetInts.pop(); + const arrayResult = []; + for (let i = 0; i < arrayLen; i++) { + const int = tmpRetInts.pop(); + arrayResult.push(int); + } + arrayResult.reverse(); + optional = arrayResult; + } else { + optional = null; + } + return { tag: OptionalAllTypesResultValues.Tag.OptArray, param0: optional }; + } + case OptionalAllTypesResultValues.Tag.Empty: return { tag: OptionalAllTypesResultValues.Tag.Empty }; + default: throw new Error("Unknown OptionalAllTypesResultValues tag returned from Swift: " + String(tag)); + } + } + }); + }; return { /** @@ -545,7 +916,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); @@ -586,6 +957,17 @@ export async function createInstantiator(options, swift) { tmpStructCleanups.pop(); } } + bjs["swift_js_struct_lower_Point"] = function(objectId) { + const { cleanup: cleanup } = structHelpers.Point.lower(swift.memory.getObject(objectId)); + if (cleanup) { + return tmpStructCleanups.push(cleanup); + } + return 0; + } + bjs["swift_js_struct_lift_Point"] = function() { + const value = structHelpers.Point.lift(tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers); + return swift.memory.retain(value); + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; @@ -676,34 +1058,80 @@ export async function createInstantiator(options, swift) { tmpRetOptionalHeapObject = undefined; return pointer || 0; } + // Wrapper functions for module: TestModule + if (!importObject["TestModule"]) { + importObject["TestModule"] = {}; + } + importObject["TestModule"]["bjs_User_wrap"] = function(pointer) { + const obj = User.__construct(pointer); + return swift.memory.retain(obj); + }; }, setInstance: (i) => { instance = i; memory = instance.exports.memory; - const APIResultHelpers = __bjs_createAPIResultValuesHelpers()(tmpParamInts, tmpParamF32s, tmpParamF64s, textEncoder, swift); + setException = (error) => { + instance.exports._swift_js_exception.value = swift.memory.retain(error) + } + }, + /** @param {WebAssembly.Instance} instance */ + createExports: (instance) => { + const js = swift.memory.heap; + /// Represents a Swift heap object like a class instance or an actor instance. + class SwiftHeapObject { + static __wrap(pointer, deinit, prototype) { + const obj = Object.create(prototype); + obj.pointer = pointer; + obj.hasReleased = false; + obj.deinit = deinit; + obj.registry = new FinalizationRegistry((pointer) => { + deinit(pointer); + }); + obj.registry.register(this, obj.pointer); + return obj; + } + + release() { + this.registry.unregister(this); + this.deinit(this.pointer); + } + } + class User extends SwiftHeapObject { + static __construct(ptr) { + return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_User_deinit, User.prototype); + } + + } + const PointHelpers = __bjs_createPointHelpers()(tmpParamInts, tmpParamF32s, tmpParamF64s, tmpParamPointers, tmpRetPointers, textEncoder, swift, enumHelpers); + structHelpers.Point = PointHelpers; + + const APIResultHelpers = __bjs_createAPIResultValuesHelpers()(tmpParamInts, tmpParamF32s, tmpParamF64s, tmpParamPointers, tmpRetPointers, textEncoder, swift, structHelpers, enumHelpers); enumHelpers.APIResult = APIResultHelpers; - const ComplexResultHelpers = __bjs_createComplexResultValuesHelpers()(tmpParamInts, tmpParamF32s, tmpParamF64s, textEncoder, swift); + const ComplexResultHelpers = __bjs_createComplexResultValuesHelpers()(tmpParamInts, tmpParamF32s, tmpParamF64s, tmpParamPointers, tmpRetPointers, textEncoder, swift, structHelpers, enumHelpers); enumHelpers.ComplexResult = ComplexResultHelpers; - const ResultHelpers = __bjs_createResultValuesHelpers()(tmpParamInts, tmpParamF32s, tmpParamF64s, textEncoder, swift); + const ResultHelpers = __bjs_createResultValuesHelpers()(tmpParamInts, tmpParamF32s, tmpParamF64s, tmpParamPointers, tmpRetPointers, textEncoder, swift, structHelpers, enumHelpers); enumHelpers.Result = ResultHelpers; - const NetworkingResultHelpers = __bjs_createNetworkingResultValuesHelpers()(tmpParamInts, tmpParamF32s, tmpParamF64s, textEncoder, swift); + const NetworkingResultHelpers = __bjs_createNetworkingResultValuesHelpers()(tmpParamInts, tmpParamF32s, tmpParamF64s, tmpParamPointers, tmpRetPointers, textEncoder, swift, structHelpers, enumHelpers); enumHelpers.NetworkingResult = NetworkingResultHelpers; - const APIOptionalResultHelpers = __bjs_createAPIOptionalResultValuesHelpers()(tmpParamInts, tmpParamF32s, tmpParamF64s, textEncoder, swift); + const APIOptionalResultHelpers = __bjs_createAPIOptionalResultValuesHelpers()(tmpParamInts, tmpParamF32s, tmpParamF64s, tmpParamPointers, tmpRetPointers, textEncoder, swift, structHelpers, enumHelpers); enumHelpers.APIOptionalResult = APIOptionalResultHelpers; - setException = (error) => { - instance.exports._swift_js_exception.value = swift.memory.retain(error) - } - }, - /** @param {WebAssembly.Instance} instance */ - createExports: (instance) => { - const js = swift.memory.heap; + const TypedPayloadResultHelpers = __bjs_createTypedPayloadResultValuesHelpers()(tmpParamInts, tmpParamF32s, tmpParamF64s, tmpParamPointers, tmpRetPointers, textEncoder, swift, structHelpers, enumHelpers); + enumHelpers.TypedPayloadResult = TypedPayloadResultHelpers; + + const AllTypesResultHelpers = __bjs_createAllTypesResultValuesHelpers()(tmpParamInts, tmpParamF32s, tmpParamF64s, tmpParamPointers, tmpRetPointers, textEncoder, swift, structHelpers, enumHelpers); + enumHelpers.AllTypesResult = AllTypesResultHelpers; + + const OptionalAllTypesResultHelpers = __bjs_createOptionalAllTypesResultValuesHelpers()(tmpParamInts, tmpParamF32s, tmpParamF64s, tmpParamPointers, tmpRetPointers, textEncoder, swift, structHelpers, enumHelpers); + enumHelpers.OptionalAllTypesResult = OptionalAllTypesResultHelpers; + const exports = { + User, handle: function bjs_handle(result) { const { caseId: resultCaseId, cleanup: resultCleanup } = enumHelpers.APIResult.lower(result); instance.exports.bjs_handle(resultCaseId); @@ -711,13 +1139,13 @@ export async function createInstantiator(options, swift) { }, getResult: function bjs_getResult() { instance.exports.bjs_getResult(); - const ret = enumHelpers.APIResult.lift(tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s); + const ret = enumHelpers.APIResult.lift(tmpRetTag.pop(), tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers); 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.lift(tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s); + const ret = enumHelpers.APIResult.lift(tmpRetTag.pop(), tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers); if (resultCleanup) { resultCleanup(); } return ret; }, @@ -730,12 +1158,13 @@ export async function createInstantiator(options, swift) { resultCleanup = enumResult.cleanup; } instance.exports.bjs_roundTripOptionalAPIResult(+isSome, isSome ? resultCaseId : 0); - const isNull = (tmpRetTag === -1); + const tag = tmpRetTag.pop(); + const isNull = (tag === -1); let optResult; if (isNull) { optResult = null; } else { - optResult = enumHelpers.APIResult.lift(tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s); + optResult = enumHelpers.APIResult.lift(tag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers); } if (resultCleanup) { resultCleanup(); } return optResult; @@ -747,13 +1176,13 @@ export async function createInstantiator(options, swift) { }, getComplexResult: function bjs_getComplexResult() { instance.exports.bjs_getComplexResult(); - const ret = enumHelpers.ComplexResult.lift(tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s); + const ret = enumHelpers.ComplexResult.lift(tmpRetTag.pop(), tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers); 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.lift(tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s); + const ret = enumHelpers.ComplexResult.lift(tmpRetTag.pop(), tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers); if (resultCleanup) { resultCleanup(); } return ret; }, @@ -766,12 +1195,13 @@ export async function createInstantiator(options, swift) { resultCleanup = enumResult.cleanup; } instance.exports.bjs_roundTripOptionalComplexResult(+isSome, isSome ? resultCaseId : 0); - const isNull = (tmpRetTag === -1); + const tag = tmpRetTag.pop(); + const isNull = (tag === -1); let optResult; if (isNull) { optResult = null; } else { - optResult = enumHelpers.ComplexResult.lift(tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s); + optResult = enumHelpers.ComplexResult.lift(tag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers); } if (resultCleanup) { resultCleanup(); } return optResult; @@ -785,12 +1215,13 @@ export async function createInstantiator(options, swift) { resultCleanup = enumResult.cleanup; } instance.exports.bjs_roundTripOptionalUtilitiesResult(+isSome, isSome ? resultCaseId : 0); - const isNull = (tmpRetTag === -1); + const tag = tmpRetTag.pop(); + const isNull = (tag === -1); let optResult; if (isNull) { optResult = null; } else { - optResult = enumHelpers.Result.lift(tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s); + optResult = enumHelpers.Result.lift(tag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers); } if (resultCleanup) { resultCleanup(); } return optResult; @@ -804,12 +1235,13 @@ export async function createInstantiator(options, swift) { resultCleanup = enumResult.cleanup; } instance.exports.bjs_roundTripOptionalNetworkingResult(+isSome, isSome ? resultCaseId : 0); - const isNull = (tmpRetTag === -1); + const tag = tmpRetTag.pop(); + const isNull = (tag === -1); let optResult; if (isNull) { optResult = null; } else { - optResult = enumHelpers.NetworkingResult.lift(tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s); + optResult = enumHelpers.NetworkingResult.lift(tag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers); } if (resultCleanup) { resultCleanup(); } return optResult; @@ -823,12 +1255,13 @@ export async function createInstantiator(options, swift) { resultCleanup = enumResult.cleanup; } instance.exports.bjs_roundTripOptionalAPIOptionalResult(+isSome, isSome ? resultCaseId : 0); - const isNull = (tmpRetTag === -1); + const tag = tmpRetTag.pop(); + const isNull = (tag === -1); let optResult; if (isNull) { optResult = null; } else { - optResult = enumHelpers.APIOptionalResult.lift(tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s); + optResult = enumHelpers.APIOptionalResult.lift(tag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers); } if (resultCleanup) { resultCleanup(); } return optResult; @@ -849,20 +1282,107 @@ export async function createInstantiator(options, swift) { result2Cleanup = enumResult1.cleanup; } instance.exports.bjs_compareAPIResults(+isSome, isSome ? result1CaseId : 0, +isSome1, isSome1 ? result2CaseId : 0); - const isNull = (tmpRetTag === -1); + const tag = tmpRetTag.pop(); + const isNull = (tag === -1); let optResult; if (isNull) { optResult = null; } else { - optResult = enumHelpers.APIOptionalResult.lift(tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s); + optResult = enumHelpers.APIOptionalResult.lift(tag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers); } if (result1Cleanup) { result1Cleanup(); } if (result2Cleanup) { result2Cleanup(); } return optResult; }, + roundTripTypedPayloadResult: function bjs_roundTripTypedPayloadResult(result) { + const { caseId: resultCaseId, cleanup: resultCleanup } = enumHelpers.TypedPayloadResult.lower(result); + instance.exports.bjs_roundTripTypedPayloadResult(resultCaseId); + const ret = enumHelpers.TypedPayloadResult.lift(tmpRetTag.pop(), tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers); + if (resultCleanup) { resultCleanup(); } + return ret; + }, + roundTripOptionalTypedPayloadResult: function bjs_roundTripOptionalTypedPayloadResult(result) { + const isSome = result != null; + let resultCaseId, resultCleanup; + if (isSome) { + const enumResult = enumHelpers.TypedPayloadResult.lower(result); + resultCaseId = enumResult.caseId; + resultCleanup = enumResult.cleanup; + } + instance.exports.bjs_roundTripOptionalTypedPayloadResult(+isSome, isSome ? resultCaseId : 0); + const tag = tmpRetTag.pop(); + const isNull = (tag === -1); + let optResult; + if (isNull) { + optResult = null; + } else { + optResult = enumHelpers.TypedPayloadResult.lift(tag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers); + } + if (resultCleanup) { resultCleanup(); } + return optResult; + }, + roundTripAllTypesResult: function bjs_roundTripAllTypesResult(result) { + const { caseId: resultCaseId, cleanup: resultCleanup } = enumHelpers.AllTypesResult.lower(result); + instance.exports.bjs_roundTripAllTypesResult(resultCaseId); + const ret = enumHelpers.AllTypesResult.lift(tmpRetTag.pop(), tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers); + if (resultCleanup) { resultCleanup(); } + return ret; + }, + roundTripOptionalAllTypesResult: function bjs_roundTripOptionalAllTypesResult(result) { + const isSome = result != null; + let resultCaseId, resultCleanup; + if (isSome) { + const enumResult = enumHelpers.AllTypesResult.lower(result); + resultCaseId = enumResult.caseId; + resultCleanup = enumResult.cleanup; + } + instance.exports.bjs_roundTripOptionalAllTypesResult(+isSome, isSome ? resultCaseId : 0); + const tag = tmpRetTag.pop(); + const isNull = (tag === -1); + let optResult; + if (isNull) { + optResult = null; + } else { + optResult = enumHelpers.AllTypesResult.lift(tag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers); + } + if (resultCleanup) { resultCleanup(); } + return optResult; + }, + roundTripOptionalPayloadResult: function bjs_roundTripOptionalPayloadResult(result) { + const { caseId: resultCaseId, cleanup: resultCleanup } = enumHelpers.OptionalAllTypesResult.lower(result); + instance.exports.bjs_roundTripOptionalPayloadResult(resultCaseId); + const ret = enumHelpers.OptionalAllTypesResult.lift(tmpRetTag.pop(), tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers); + if (resultCleanup) { resultCleanup(); } + return ret; + }, + roundTripOptionalPayloadResultOpt: function bjs_roundTripOptionalPayloadResultOpt(result) { + const isSome = result != null; + let resultCaseId, resultCleanup; + if (isSome) { + const enumResult = enumHelpers.OptionalAllTypesResult.lower(result); + resultCaseId = enumResult.caseId; + resultCleanup = enumResult.cleanup; + } + instance.exports.bjs_roundTripOptionalPayloadResultOpt(+isSome, isSome ? resultCaseId : 0); + const tag = tmpRetTag.pop(); + const isNull = (tag === -1); + let optResult; + if (isNull) { + optResult = null; + } else { + optResult = enumHelpers.OptionalAllTypesResult.lift(tag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers); + } + if (resultCleanup) { resultCleanup(); } + return optResult; + }, APIResult: APIResultValues, ComplexResult: ComplexResultValues, APIOptionalResult: APIOptionalResultValues, + Precision: PrecisionValues, + CardinalDirection: CardinalDirectionValues, + TypedPayloadResult: TypedPayloadResultValues, + AllTypesResult: AllTypesResultValues, + OptionalAllTypesResult: OptionalAllTypesResultValues, API: { NetworkingResult: NetworkingResultValues, }, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.js index 874b4c4c..9ca596a6 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.js @@ -42,7 +42,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -94,7 +94,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Global.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Global.js index 78f08ffb..a7a2c4b9 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Global.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Global.js @@ -62,7 +62,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -114,7 +114,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.js index cddeac76..b195b694 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.js @@ -43,7 +43,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -95,7 +95,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.js index 315b7426..c906f27f 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.js @@ -93,7 +93,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -146,7 +146,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalGetter.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalGetter.js index b5053b26..ac6170b0 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalGetter.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalGetter.js @@ -18,7 +18,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -71,7 +71,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalThisImports.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalThisImports.js index 0d9eb79c..dc222071 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalThisImports.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalThisImports.js @@ -18,7 +18,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -70,7 +70,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ImportedTypeInExportedInterface.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ImportedTypeInExportedInterface.js index 11aa2b3d..efcbbe2d 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ImportedTypeInExportedInterface.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ImportedTypeInExportedInterface.js @@ -18,7 +18,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -135,7 +135,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/InvalidPropertyNames.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/InvalidPropertyNames.js index 6a11003b..d64ff7e9 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/InvalidPropertyNames.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/InvalidPropertyNames.js @@ -18,7 +18,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -71,7 +71,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClass.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClass.js index b60a698b..096e3a34 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClass.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClass.js @@ -18,7 +18,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -71,7 +71,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClassStaticFunctions.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClassStaticFunctions.js index 214a3229..cacaa87a 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClassStaticFunctions.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClassStaticFunctions.js @@ -18,7 +18,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -71,7 +71,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSValue.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSValue.js index f272b0ff..2bd696c3 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSValue.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSValue.js @@ -18,7 +18,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -160,7 +160,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedGlobal.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedGlobal.js index e1345f94..4ac3b11b 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedGlobal.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedGlobal.js @@ -18,7 +18,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -70,7 +70,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedModules.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedModules.js index 0703be78..9eb55f30 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedModules.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedModules.js @@ -18,7 +18,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -70,7 +70,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedPrivate.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedPrivate.js index 0cc377f4..e81a9566 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedPrivate.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedPrivate.js @@ -18,7 +18,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -70,7 +70,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Global.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Global.js index 630651ae..c8d0b935 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Global.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Global.js @@ -18,7 +18,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -70,7 +70,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.js index b3073da7..bb2c9364 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.js @@ -18,7 +18,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -70,7 +70,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Optionals.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Optionals.js index 27e9c3c6..341fcd96 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Optionals.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Optionals.js @@ -18,7 +18,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -71,7 +71,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.js index 98f50e85..2d754a5c 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.js @@ -18,7 +18,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -71,7 +71,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.js index e68e4e6a..f348869b 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.js @@ -18,7 +18,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -71,7 +71,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PropertyTypes.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PropertyTypes.js index 7bf56510..7be6cd92 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PropertyTypes.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PropertyTypes.js @@ -18,7 +18,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -70,7 +70,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Protocol.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Protocol.js index ce9065ac..7c20130b 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Protocol.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Protocol.js @@ -22,46 +22,6 @@ export const ResultValues = { Failure: 1, }, }; - -const __bjs_createResultValuesHelpers = () => { - return (tmpParamInts, tmpParamF32s, tmpParamF64s, textEncoder, swift) => ({ - lower: (value) => { - const enumTag = value.tag; - switch (enumTag) { - case ResultValues.Tag.Success: { - const bytes = textEncoder.encode(value.param0); - const id = swift.memory.retain(bytes); - tmpParamInts.push(bytes.length); - tmpParamInts.push(id); - const cleanup = () => { - swift.memory.release(id); - }; - return { caseId: ResultValues.Tag.Success, cleanup }; - } - case ResultValues.Tag.Failure: { - tmpParamInts.push((value.param0 | 0)); - const cleanup = undefined; - return { caseId: ResultValues.Tag.Failure, cleanup }; - } - default: throw new Error("Unknown ResultValues tag: " + String(enumTag)); - } - }, - lift: (tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s) => { - const tag = tmpRetTag | 0; - switch (tag) { - case ResultValues.Tag.Success: { - const string = tmpRetStrings.pop(); - return { tag: ResultValues.Tag.Success, param0: string }; - } - case ResultValues.Tag.Failure: { - const int = tmpRetInts.pop(); - return { tag: ResultValues.Tag.Failure, param0: int }; - } - default: throw new Error("Unknown ResultValues tag returned from Swift: " + String(tag)); - } - } - }); -}; export const PriorityValues = { Low: -1, Medium: 0, @@ -82,7 +42,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -98,6 +58,45 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; + const __bjs_createResultValuesHelpers = () => { + return (tmpParamInts, tmpParamF32s, tmpParamF64s, tmpParamPointers, tmpRetPointers, textEncoder, swift, structHelpers, enumHelpers) => ({ + lower: (value) => { + const enumTag = value.tag; + switch (enumTag) { + case ResultValues.Tag.Success: { + const bytes = textEncoder.encode(value.param0); + const id = swift.memory.retain(bytes); + tmpParamInts.push(bytes.length); + tmpParamInts.push(id); + const cleanup = () => { + swift.memory.release(id); + }; + return { caseId: ResultValues.Tag.Success, cleanup }; + } + case ResultValues.Tag.Failure: { + tmpParamInts.push((value.param0 | 0)); + const cleanup = undefined; + return { caseId: ResultValues.Tag.Failure, cleanup }; + } + default: throw new Error("Unknown ResultValues tag: " + String(enumTag)); + } + }, + lift: (tag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers) => { + tag = tag | 0; + switch (tag) { + case ResultValues.Tag.Success: { + const string = tmpRetStrings.pop(); + return { tag: ResultValues.Tag.Success, param0: string }; + } + case ResultValues.Tag.Failure: { + const int = tmpRetInts.pop(); + return { tag: ResultValues.Tag.Failure, param0: int }; + } + default: throw new Error("Unknown ResultValues tag returned from Swift: " + String(tag)); + } + } + }); + }; return { /** @@ -134,7 +133,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); @@ -376,7 +375,7 @@ export async function createInstantiator(options, swift) { } TestModule["bjs_MyViewControllerDelegate_result_set"] = function bjs_MyViewControllerDelegate_result_set(self, value) { try { - const enumValue = enumHelpers.Result.lift(value, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s); + const enumValue = enumHelpers.Result.lift(value, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers); swift.memory.getObject(self).result = enumValue; } catch (error) { setException(error); @@ -400,7 +399,7 @@ export async function createInstantiator(options, swift) { try { let enumValue; if (valueIsSome) { - enumValue = enumHelpers.Result.lift(valueWrappedValue, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s); + enumValue = enumHelpers.Result.lift(valueWrappedValue, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers); } swift.memory.getObject(self).optionalResult = valueIsSome ? enumValue : null; } catch (error) { @@ -557,7 +556,7 @@ export async function createInstantiator(options, swift) { } TestModule["bjs_MyViewControllerDelegate_handleResult"] = function bjs_MyViewControllerDelegate_handleResult(self, result) { try { - const enumValue = enumHelpers.Result.lift(result, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s); + const enumValue = enumHelpers.Result.lift(result, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers); swift.memory.getObject(self).handleResult(enumValue); } catch (error) { setException(error); @@ -577,9 +576,6 @@ export async function createInstantiator(options, swift) { instance = i; memory = instance.exports.memory; - const ResultHelpers = __bjs_createResultValuesHelpers()(tmpParamInts, tmpParamF32s, tmpParamF64s, textEncoder, swift); - enumHelpers.Result = ResultHelpers; - setException = (error) => { instance.exports._swift_js_exception.value = swift.memory.retain(error) } @@ -727,6 +723,9 @@ export async function createInstantiator(options, swift) { for (const cleanup of arrayCleanups) { cleanup(); } } } + const ResultHelpers = __bjs_createResultValuesHelpers()(tmpParamInts, tmpParamF32s, tmpParamF64s, tmpParamPointers, tmpRetPointers, textEncoder, swift, structHelpers, enumHelpers); + enumHelpers.Result = ResultHelpers; + const exports = { Helper, MyViewController, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.Global.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.Global.js index b79c6ebf..391c7167 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.Global.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.Global.js @@ -15,46 +15,6 @@ export const APIResultValues = { Failure: 1, }, }; - -const __bjs_createAPIResultValuesHelpers = () => { - return (tmpParamInts, tmpParamF32s, tmpParamF64s, textEncoder, swift) => ({ - lower: (value) => { - const enumTag = value.tag; - switch (enumTag) { - case APIResultValues.Tag.Success: { - const bytes = textEncoder.encode(value.param0); - const id = swift.memory.retain(bytes); - tmpParamInts.push(bytes.length); - tmpParamInts.push(id); - const cleanup = () => { - swift.memory.release(id); - }; - return { caseId: APIResultValues.Tag.Success, cleanup }; - } - case APIResultValues.Tag.Failure: { - tmpParamInts.push((value.param0 | 0)); - const cleanup = undefined; - return { caseId: APIResultValues.Tag.Failure, cleanup }; - } - default: throw new Error("Unknown APIResultValues tag: " + String(enumTag)); - } - }, - lift: (tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s) => { - const tag = tmpRetTag | 0; - switch (tag) { - case APIResultValues.Tag.Success: { - const string = tmpRetStrings.pop(); - return { tag: APIResultValues.Tag.Success, param0: string }; - } - case APIResultValues.Tag.Failure: { - const int = tmpRetInts.pop(); - return { tag: APIResultValues.Tag.Failure, param0: int }; - } - default: throw new Error("Unknown APIResultValues tag returned from Swift: " + String(tag)); - } - } - }); -}; export async function createInstantiator(options, swift) { let instance; let memory; @@ -69,7 +29,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -85,6 +45,45 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; + const __bjs_createAPIResultValuesHelpers = () => { + return (tmpParamInts, tmpParamF32s, tmpParamF64s, tmpParamPointers, tmpRetPointers, textEncoder, swift, structHelpers, enumHelpers) => ({ + lower: (value) => { + const enumTag = value.tag; + switch (enumTag) { + case APIResultValues.Tag.Success: { + const bytes = textEncoder.encode(value.param0); + const id = swift.memory.retain(bytes); + tmpParamInts.push(bytes.length); + tmpParamInts.push(id); + const cleanup = () => { + swift.memory.release(id); + }; + return { caseId: APIResultValues.Tag.Success, cleanup }; + } + case APIResultValues.Tag.Failure: { + tmpParamInts.push((value.param0 | 0)); + const cleanup = undefined; + return { caseId: APIResultValues.Tag.Failure, cleanup }; + } + default: throw new Error("Unknown APIResultValues tag: " + String(enumTag)); + } + }, + lift: (tag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers) => { + tag = tag | 0; + switch (tag) { + case APIResultValues.Tag.Success: { + const string = tmpRetStrings.pop(); + return { tag: APIResultValues.Tag.Success, param0: string }; + } + case APIResultValues.Tag.Failure: { + const int = tmpRetInts.pop(); + return { tag: APIResultValues.Tag.Failure, param0: int }; + } + default: throw new Error("Unknown APIResultValues tag returned from Swift: " + String(tag)); + } + } + }); + }; return { /** @@ -121,7 +120,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); @@ -265,9 +264,6 @@ export async function createInstantiator(options, swift) { instance = i; memory = instance.exports.memory; - const APIResultHelpers = __bjs_createAPIResultValuesHelpers()(tmpParamInts, tmpParamF32s, tmpParamF64s, textEncoder, swift); - enumHelpers.APIResult = APIResultHelpers; - setException = (error) => { instance.exports._swift_js_exception.value = swift.memory.retain(error) } @@ -316,6 +312,9 @@ export async function createInstantiator(options, swift) { return ret; } } + const APIResultHelpers = __bjs_createAPIResultValuesHelpers()(tmpParamInts, tmpParamF32s, tmpParamF64s, tmpParamPointers, tmpRetPointers, textEncoder, swift, structHelpers, enumHelpers); + enumHelpers.APIResult = APIResultHelpers; + if (typeof globalThis.Utils === 'undefined') { globalThis.Utils = {}; } @@ -336,7 +335,7 @@ export async function createInstantiator(options, swift) { roundtrip: function(value) { const { caseId: valueCaseId, cleanup: valueCleanup } = enumHelpers.APIResult.lower(value); instance.exports.bjs_APIResult_static_roundtrip(valueCaseId); - const ret = enumHelpers.APIResult.lift(tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s); + const ret = enumHelpers.APIResult.lift(tmpRetTag.pop(), tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers); if (valueCleanup) { valueCleanup(); } return ret; } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.js index 2f240c42..b38668c5 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.js @@ -15,46 +15,6 @@ export const APIResultValues = { Failure: 1, }, }; - -const __bjs_createAPIResultValuesHelpers = () => { - return (tmpParamInts, tmpParamF32s, tmpParamF64s, textEncoder, swift) => ({ - lower: (value) => { - const enumTag = value.tag; - switch (enumTag) { - case APIResultValues.Tag.Success: { - const bytes = textEncoder.encode(value.param0); - const id = swift.memory.retain(bytes); - tmpParamInts.push(bytes.length); - tmpParamInts.push(id); - const cleanup = () => { - swift.memory.release(id); - }; - return { caseId: APIResultValues.Tag.Success, cleanup }; - } - case APIResultValues.Tag.Failure: { - tmpParamInts.push((value.param0 | 0)); - const cleanup = undefined; - return { caseId: APIResultValues.Tag.Failure, cleanup }; - } - default: throw new Error("Unknown APIResultValues tag: " + String(enumTag)); - } - }, - lift: (tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s) => { - const tag = tmpRetTag | 0; - switch (tag) { - case APIResultValues.Tag.Success: { - const string = tmpRetStrings.pop(); - return { tag: APIResultValues.Tag.Success, param0: string }; - } - case APIResultValues.Tag.Failure: { - const int = tmpRetInts.pop(); - return { tag: APIResultValues.Tag.Failure, param0: int }; - } - default: throw new Error("Unknown APIResultValues tag returned from Swift: " + String(tag)); - } - } - }); -}; export async function createInstantiator(options, swift) { let instance; let memory; @@ -69,7 +29,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -85,6 +45,45 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; + const __bjs_createAPIResultValuesHelpers = () => { + return (tmpParamInts, tmpParamF32s, tmpParamF64s, tmpParamPointers, tmpRetPointers, textEncoder, swift, structHelpers, enumHelpers) => ({ + lower: (value) => { + const enumTag = value.tag; + switch (enumTag) { + case APIResultValues.Tag.Success: { + const bytes = textEncoder.encode(value.param0); + const id = swift.memory.retain(bytes); + tmpParamInts.push(bytes.length); + tmpParamInts.push(id); + const cleanup = () => { + swift.memory.release(id); + }; + return { caseId: APIResultValues.Tag.Success, cleanup }; + } + case APIResultValues.Tag.Failure: { + tmpParamInts.push((value.param0 | 0)); + const cleanup = undefined; + return { caseId: APIResultValues.Tag.Failure, cleanup }; + } + default: throw new Error("Unknown APIResultValues tag: " + String(enumTag)); + } + }, + lift: (tag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers) => { + tag = tag | 0; + switch (tag) { + case APIResultValues.Tag.Success: { + const string = tmpRetStrings.pop(); + return { tag: APIResultValues.Tag.Success, param0: string }; + } + case APIResultValues.Tag.Failure: { + const int = tmpRetInts.pop(); + return { tag: APIResultValues.Tag.Failure, param0: int }; + } + default: throw new Error("Unknown APIResultValues tag returned from Swift: " + String(tag)); + } + } + }); + }; return { /** @@ -121,7 +120,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); @@ -265,9 +264,6 @@ export async function createInstantiator(options, swift) { instance = i; memory = instance.exports.memory; - const APIResultHelpers = __bjs_createAPIResultValuesHelpers()(tmpParamInts, tmpParamF32s, tmpParamF64s, textEncoder, swift); - enumHelpers.APIResult = APIResultHelpers; - setException = (error) => { instance.exports._swift_js_exception.value = swift.memory.retain(error) } @@ -316,6 +312,9 @@ export async function createInstantiator(options, swift) { return ret; } } + const APIResultHelpers = __bjs_createAPIResultValuesHelpers()(tmpParamInts, tmpParamF32s, tmpParamF64s, tmpParamPointers, tmpRetPointers, textEncoder, swift, structHelpers, enumHelpers); + enumHelpers.APIResult = APIResultHelpers; + const exports = { MathUtils, Calculator: { @@ -330,7 +329,7 @@ export async function createInstantiator(options, swift) { roundtrip: function(value) { const { caseId: valueCaseId, cleanup: valueCleanup } = enumHelpers.APIResult.lower(value); instance.exports.bjs_APIResult_static_roundtrip(valueCaseId); - const ret = enumHelpers.APIResult.lift(tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s); + const ret = enumHelpers.APIResult.lift(tmpRetTag.pop(), tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers); if (valueCleanup) { valueCleanup(); } return ret; } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.Global.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.Global.js index 15edf8c6..293ae4f7 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.Global.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.Global.js @@ -23,7 +23,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -75,7 +75,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.js index d90e96f0..27e3df46 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.js @@ -23,7 +23,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -75,7 +75,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.js index fc67c002..e57c5153 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.js @@ -18,7 +18,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -71,7 +71,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.js index 50edf3b0..74d14023 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.js @@ -18,7 +18,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -71,7 +71,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.js index f3d5cafc..27398d2a 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.js @@ -18,7 +18,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -70,7 +70,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosure.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosure.js index 59512a7e..ff5af72f 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosure.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosure.js @@ -34,78 +34,6 @@ export const APIResultValues = { Info: 5, }, }; - -const __bjs_createAPIResultValuesHelpers = () => { - return (tmpParamInts, tmpParamF32s, tmpParamF64s, textEncoder, swift) => ({ - lower: (value) => { - const enumTag = value.tag; - switch (enumTag) { - case APIResultValues.Tag.Success: { - const bytes = textEncoder.encode(value.param0); - const id = swift.memory.retain(bytes); - tmpParamInts.push(bytes.length); - tmpParamInts.push(id); - const cleanup = () => { - swift.memory.release(id); - }; - return { caseId: APIResultValues.Tag.Success, cleanup }; - } - case APIResultValues.Tag.Failure: { - tmpParamInts.push((value.param0 | 0)); - const cleanup = undefined; - return { caseId: APIResultValues.Tag.Failure, cleanup }; - } - case APIResultValues.Tag.Flag: { - tmpParamInts.push(value.param0 ? 1 : 0); - const cleanup = undefined; - return { caseId: APIResultValues.Tag.Flag, cleanup }; - } - case APIResultValues.Tag.Rate: { - tmpParamF32s.push(Math.fround(value.param0)); - const cleanup = undefined; - return { caseId: APIResultValues.Tag.Rate, cleanup }; - } - case APIResultValues.Tag.Precise: { - tmpParamF64s.push(value.param0); - const cleanup = undefined; - return { caseId: APIResultValues.Tag.Precise, cleanup }; - } - case APIResultValues.Tag.Info: { - const cleanup = undefined; - return { caseId: APIResultValues.Tag.Info, cleanup }; - } - default: throw new Error("Unknown APIResultValues tag: " + String(enumTag)); - } - }, - lift: (tmpRetTag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s) => { - const tag = tmpRetTag | 0; - switch (tag) { - case APIResultValues.Tag.Success: { - const string = tmpRetStrings.pop(); - return { tag: APIResultValues.Tag.Success, param0: string }; - } - case APIResultValues.Tag.Failure: { - const int = tmpRetInts.pop(); - return { tag: APIResultValues.Tag.Failure, param0: int }; - } - case APIResultValues.Tag.Flag: { - const bool = tmpRetInts.pop(); - return { tag: APIResultValues.Tag.Flag, param0: bool }; - } - case APIResultValues.Tag.Rate: { - const f32 = tmpRetF32s.pop(); - return { tag: APIResultValues.Tag.Rate, param0: f32 }; - } - case APIResultValues.Tag.Precise: { - const f64 = tmpRetF64s.pop(); - return { tag: APIResultValues.Tag.Precise, param0: f64 }; - } - case APIResultValues.Tag.Info: return { tag: APIResultValues.Tag.Info }; - default: throw new Error("Unknown APIResultValues tag returned from Swift: " + String(tag)); - } - } - }); -}; export async function createInstantiator(options, swift) { let instance; let memory; @@ -120,7 +48,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -136,6 +64,77 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; + const __bjs_createAPIResultValuesHelpers = () => { + return (tmpParamInts, tmpParamF32s, tmpParamF64s, tmpParamPointers, tmpRetPointers, textEncoder, swift, structHelpers, enumHelpers) => ({ + lower: (value) => { + const enumTag = value.tag; + switch (enumTag) { + case APIResultValues.Tag.Success: { + const bytes = textEncoder.encode(value.param0); + const id = swift.memory.retain(bytes); + tmpParamInts.push(bytes.length); + tmpParamInts.push(id); + const cleanup = () => { + swift.memory.release(id); + }; + return { caseId: APIResultValues.Tag.Success, cleanup }; + } + case APIResultValues.Tag.Failure: { + tmpParamInts.push((value.param0 | 0)); + const cleanup = undefined; + return { caseId: APIResultValues.Tag.Failure, cleanup }; + } + case APIResultValues.Tag.Flag: { + tmpParamInts.push(value.param0 ? 1 : 0); + const cleanup = undefined; + return { caseId: APIResultValues.Tag.Flag, cleanup }; + } + case APIResultValues.Tag.Rate: { + tmpParamF32s.push(Math.fround(value.param0)); + const cleanup = undefined; + return { caseId: APIResultValues.Tag.Rate, cleanup }; + } + case APIResultValues.Tag.Precise: { + tmpParamF64s.push(value.param0); + const cleanup = undefined; + return { caseId: APIResultValues.Tag.Precise, cleanup }; + } + case APIResultValues.Tag.Info: { + const cleanup = undefined; + return { caseId: APIResultValues.Tag.Info, cleanup }; + } + default: throw new Error("Unknown APIResultValues tag: " + String(enumTag)); + } + }, + lift: (tag, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers) => { + tag = tag | 0; + switch (tag) { + case APIResultValues.Tag.Success: { + const string = tmpRetStrings.pop(); + return { tag: APIResultValues.Tag.Success, param0: string }; + } + case APIResultValues.Tag.Failure: { + const int = tmpRetInts.pop(); + return { tag: APIResultValues.Tag.Failure, param0: int }; + } + case APIResultValues.Tag.Flag: { + const bool = tmpRetInts.pop() !== 0; + return { tag: APIResultValues.Tag.Flag, param0: bool }; + } + case APIResultValues.Tag.Rate: { + const f32 = tmpRetF32s.pop(); + return { tag: APIResultValues.Tag.Rate, param0: f32 }; + } + case APIResultValues.Tag.Precise: { + const f64 = tmpRetF64s.pop(); + return { tag: APIResultValues.Tag.Precise, param0: f64 }; + } + case APIResultValues.Tag.Info: return { tag: APIResultValues.Tag.Info }; + default: throw new Error("Unknown APIResultValues tag returned from Swift: " + String(tag)); + } + } + }); + }; return { /** @@ -172,7 +171,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); @@ -423,7 +422,7 @@ export async function createInstantiator(options, swift) { bjs["invoke_js_callback_TestModule_10TestModule9APIResultO_SS"] = function(callbackId, param0Id) { try { const callback = swift.memory.getObject(callbackId); - let param0 = enumHelpers.APIResult.lift(param0Id, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s); + let param0 = enumHelpers.APIResult.lift(param0Id, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers); const result = callback(param0); if (typeof result !== "string") { throw new TypeError("Callback must return a string"); @@ -685,7 +684,7 @@ export async function createInstantiator(options, swift) { const callback = swift.memory.getObject(callbackId); let param0; if (param0IsSome) { - param0 = enumHelpers.APIResult.lift(param0Value, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s); + param0 = enumHelpers.APIResult.lift(param0Value, tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers); } else { param0 = null; } @@ -776,9 +775,6 @@ export async function createInstantiator(options, swift) { instance = i; memory = instance.exports.memory; - const APIResultHelpers = __bjs_createAPIResultValuesHelpers()(tmpParamInts, tmpParamF32s, tmpParamF64s, textEncoder, swift); - enumHelpers.APIResult = APIResultHelpers; - setException = (error) => { instance.exports._swift_js_exception.value = swift.memory.retain(error) } @@ -930,6 +926,9 @@ export async function createInstantiator(options, swift) { return bjs["lower_closure_TestModule_10TestModuleSq9DirectionO_SS"](ret); } } + const APIResultHelpers = __bjs_createAPIResultValuesHelpers()(tmpParamInts, tmpParamF32s, tmpParamF64s, tmpParamPointers, tmpRetPointers, textEncoder, swift, structHelpers, enumHelpers); + enumHelpers.APIResult = APIResultHelpers; + const exports = { Person, TestProcessor, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosureImports.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosureImports.js index 145eeb75..52e12ef7 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosureImports.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosureImports.js @@ -18,7 +18,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -71,7 +71,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStruct.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStruct.js index f389900d..adbe1885 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStruct.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStruct.js @@ -23,7 +23,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -183,9 +183,9 @@ export async function createInstantiator(options, swift) { }, lift: (tmpRetStrings, tmpRetInts, tmpRetF32s, tmpRetF64s, tmpRetPointers) => { const ptr = tmpRetPointers.pop(); - const value = _exports['Greeter'].__construct(ptr); + const obj = _exports['Greeter'].__construct(ptr); const int = tmpRetInts.pop(); - return { id: int, owner: value }; + return { id: int, owner: obj }; } }); }; @@ -207,14 +207,14 @@ export async function createInstantiator(options, swift) { const isSome = tmpRetInts.pop(); let optional; if (isSome) { - const value = tmpRetF32s.pop(); - optional = value; + const rawValue = tmpRetF32s.pop(); + optional = rawValue; } else { optional = null; } - const value1 = tmpRetF32s.pop(); + const rawValue1 = tmpRetF32s.pop(); const f64 = tmpRetF64s.pop(); - return { value: f64, precision: value1, optionalPrecision: optional }; + return { value: f64, precision: rawValue1, optionalPrecision: optional }; } }); }; @@ -328,7 +328,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStructImports.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStructImports.js index afed321c..8f90491d 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStructImports.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStructImports.js @@ -18,7 +18,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -85,7 +85,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Throws.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Throws.js index 8a1c4964..2e2f8bf6 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Throws.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Throws.js @@ -18,7 +18,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -70,7 +70,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/UnsafePointer.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/UnsafePointer.js index 61f6c6cf..bbeeffa0 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/UnsafePointer.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/UnsafePointer.js @@ -18,7 +18,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -90,7 +90,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.js index 053c5567..45374093 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.js @@ -18,7 +18,7 @@ export async function createInstantiator(options, swift) { let tmpRetOptionalFloat; let tmpRetOptionalDouble; let tmpRetOptionalHeapObject; - let tmpRetTag; + let tmpRetTag = []; let tmpRetStrings = []; let tmpRetInts = []; let tmpRetF32s = []; @@ -71,7 +71,7 @@ export async function createInstantiator(options, swift) { swift.memory.release(id); } bjs["swift_js_push_tag"] = function(tag) { - tmpRetTag = tag; + tmpRetTag.push(tag); } bjs["swift_js_push_i32"] = function(v) { tmpRetInts.push(v | 0); 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 3dda2b9c..6fb3afed 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 @@ -509,8 +509,9 @@ This differs from classes, which use reference semantics and share state across | Static functions | ✅ | | Static properties | ✅ | | Associated values: `String`, `Int`, `Bool`, `Float`, `Double` | ✅ | -| Associated values: Custom classes/structs | ❌ | -| Associated values: Other enums | ❌ | -| Associated values: Arrays/Collections | ❌ | -| Associated values: Optionals | ❌ | +| Associated values: Custom classes/structs | ✅ | +| Associated values: Other enums (case, raw value, and associated value) | ✅ | +| Associated values: `JSObject` | ✅ | +| Associated values: Arrays | ✅ | +| Associated values: Optionals of all supported types | ✅ | | Generics | ❌ | diff --git a/Tests/BridgeJSRuntimeTests/ExportAPITests.swift b/Tests/BridgeJSRuntimeTests/ExportAPITests.swift index 345f5dbc..fe73ea6f 100644 --- a/Tests/BridgeJSRuntimeTests/ExportAPITests.swift +++ b/Tests/BridgeJSRuntimeTests/ExportAPITests.swift @@ -586,6 +586,22 @@ typealias OptionalAge = Int? return value } +@JS enum TypedPayloadResult { + case precision(Precision) + case direction(Direction) + case optPrecision(Precision?) + case optDirection(Direction?) + case empty +} + +@JS func roundTripTypedPayloadResult(_ result: TypedPayloadResult) -> TypedPayloadResult { + return result +} + +@JS func roundTripOptionalTypedPayloadResult(_ result: TypedPayloadResult?) -> TypedPayloadResult? { + return result +} + @JS func compareAPIResults(_ r1: APIResult?, _ r2: APIResult?) -> String { let r1Str: String switch r1 { @@ -616,6 +632,44 @@ typealias OptionalAge = Int? return result } +@JS +enum AllTypesResult { + case structPayload(Address) + case classPayload(Greeter) + case jsObjectPayload(JSObject) + case nestedEnum(APIResult) + case arrayPayload([Int]) + case jsClassPayload(Foo) + case empty +} + +@JS func roundTripAllTypesResult(_ result: AllTypesResult) -> AllTypesResult { + return result +} + +@JS func roundTripOptionalAllTypesResult(_ result: AllTypesResult?) -> AllTypesResult? { + return result +} + +@JS +enum OptionalAllTypesResult { + case optStruct(Address?) + case optClass(Greeter?) + case optJSObject(JSObject?) + case optNestedEnum(APIResult?) + case optArray([Int]?) + case optJsClass(Foo?) + case empty +} + +@JS func roundTripOptionalPayloadResult(_ result: OptionalAllTypesResult) -> OptionalAllTypesResult { + return result +} + +@JS func roundTripOptionalPayloadResultOpt(_ result: OptionalAllTypesResult?) -> OptionalAllTypesResult? { + return result +} + @JS func roundTripOptionalClass(value: Greeter?) -> Greeter? { return value } diff --git a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift index ee9f9750..0e06c7ed 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift +++ b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift @@ -1561,20 +1561,20 @@ extension APIResult: _BridgedSwiftAssociatedValueEnum { @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() { switch self { case .success(let param0): - _swift_js_push_tag(Int32(0)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(0)) case .failure(let param0): - _swift_js_push_tag(Int32(1)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(1)) case .flag(let param0): - _swift_js_push_tag(Int32(2)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(2)) case .rate(let param0): - _swift_js_push_tag(Int32(3)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(3)) case .precise(let param0): - _swift_js_push_tag(Int32(4)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(4)) case .info: _swift_js_push_tag(Int32(5)) } @@ -1658,29 +1658,28 @@ extension ComplexResult: _BridgedSwiftAssociatedValueEnum { @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() { switch self { case .success(let param0): - _swift_js_push_tag(Int32(0)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(0)) case .error(let param0, let param1): - _swift_js_push_tag(Int32(1)) param0.bridgeJSLowerStackReturn() param1.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(1)) case .location(let param0, let param1, let param2): - _swift_js_push_tag(Int32(2)) param0.bridgeJSLowerStackReturn() param1.bridgeJSLowerStackReturn() param2.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(2)) case .status(let param0, let param1, let param2): - _swift_js_push_tag(Int32(3)) param0.bridgeJSLowerStackReturn() param1.bridgeJSLowerStackReturn() param2.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(3)) case .coordinates(let param0, let param1, let param2): - _swift_js_push_tag(Int32(4)) param0.bridgeJSLowerStackReturn() param1.bridgeJSLowerStackReturn() param2.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(4)) 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)) param0.bridgeJSLowerStackReturn() param1.bridgeJSLowerStackReturn() param2.bridgeJSLowerStackReturn() @@ -1690,6 +1689,7 @@ extension ComplexResult: _BridgedSwiftAssociatedValueEnum { param6.bridgeJSLowerStackReturn() param7.bridgeJSLowerStackReturn() param8.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(5)) case .info: _swift_js_push_tag(Int32(6)) } @@ -1742,17 +1742,17 @@ extension Utilities.Result: _BridgedSwiftAssociatedValueEnum { @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() { switch self { case .success(let param0): - _swift_js_push_tag(Int32(0)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(0)) case .failure(let param0, let param1): - _swift_js_push_tag(Int32(1)) param0.bridgeJSLowerStackReturn() param1.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(1)) case .status(let param0, let param1, let param2): - _swift_js_push_tag(Int32(2)) param0.bridgeJSLowerStackReturn() param1.bridgeJSLowerStackReturn() param2.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(2)) } } } @@ -1796,12 +1796,324 @@ extension API.NetworkingResult: _BridgedSwiftAssociatedValueEnum { @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() { switch self { case .success(let param0): - _swift_js_push_tag(Int32(0)) param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(0)) case .failure(let param0, let param1): - _swift_js_push_tag(Int32(1)) param0.bridgeJSLowerStackReturn() param1.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(1)) + } + } +} + +extension TypedPayloadResult: _BridgedSwiftAssociatedValueEnum { + private static func _bridgeJSLiftFromCaseId(_ caseId: Int32) -> TypedPayloadResult { + switch caseId { + case 0: + return .precision(Precision.bridgeJSLiftParameter(_swift_js_pop_f32())) + case 1: + return .direction(Direction.bridgeJSLiftParameter(_swift_js_pop_i32())) + case 2: + return .optPrecision(Optional.bridgeJSLiftParameter()) + case 3: + return .optDirection(Optional.bridgeJSLiftParameter()) + case 4: + return .empty + default: + fatalError("Unknown TypedPayloadResult case ID: \(caseId)") + } + } + + // MARK: Protocol Export + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + switch self { + case .precision(let param0): + param0.bridgeJSLowerStackReturn() + return Int32(0) + case .direction(let param0): + param0.bridgeJSLowerStackReturn() + return Int32(1) + case .optPrecision(let param0): + let __bjs_isSome_param0 = param0 != nil + if let __bjs_unwrapped_param0 = param0 { + __bjs_unwrapped_param0.bridgeJSLowerStackReturn() + } + _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + return Int32(2) + case .optDirection(let param0): + let __bjs_isSome_param0 = param0 != nil + if let __bjs_unwrapped_param0 = param0 { + __bjs_unwrapped_param0.bridgeJSLowerStackReturn() + } + _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + return Int32(3) + case .empty: + return Int32(4) + } + } + + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ caseId: Int32) -> TypedPayloadResult { + return _bridgeJSLiftFromCaseId(caseId) + } + + // MARK: ExportSwift + + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ caseId: Int32) -> TypedPayloadResult { + return _bridgeJSLiftFromCaseId(caseId) + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() { + switch self { + case .precision(let param0): + param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(0)) + case .direction(let param0): + param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(1)) + case .optPrecision(let param0): + let __bjs_isSome_param0 = param0 != nil + if let __bjs_unwrapped_param0 = param0 { + __bjs_unwrapped_param0.bridgeJSLowerStackReturn() + } + _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + _swift_js_push_tag(Int32(2)) + case .optDirection(let param0): + let __bjs_isSome_param0 = param0 != nil + if let __bjs_unwrapped_param0 = param0 { + __bjs_unwrapped_param0.bridgeJSLowerStackReturn() + } + _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + _swift_js_push_tag(Int32(3)) + case .empty: + _swift_js_push_tag(Int32(4)) + } + } +} + +extension AllTypesResult: _BridgedSwiftAssociatedValueEnum { + private static func _bridgeJSLiftFromCaseId(_ caseId: Int32) -> AllTypesResult { + switch caseId { + case 0: + return .structPayload(Address.bridgeJSLiftParameter()) + case 1: + return .classPayload(Greeter.bridgeJSLiftParameter()) + case 2: + return .jsObjectPayload(JSObject.bridgeJSLiftParameter()) + case 3: + return .nestedEnum(APIResult.bridgeJSLiftParameter(_swift_js_pop_i32())) + case 4: + return .arrayPayload([Int].bridgeJSLiftParameter()) + case 5: + return .jsClassPayload(Foo(unsafelyWrapping: JSObject.bridgeJSLiftParameter())) + case 6: + return .empty + default: + fatalError("Unknown AllTypesResult case ID: \(caseId)") + } + } + + // MARK: Protocol Export + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + switch self { + case .structPayload(let param0): + param0.bridgeJSLowerReturn() + return Int32(0) + case .classPayload(let param0): + param0.bridgeJSLowerStackReturn() + return Int32(1) + case .jsObjectPayload(let param0): + param0.bridgeJSLowerStackReturn() + return Int32(2) + case .nestedEnum(let param0): + param0.bridgeJSLowerReturn() + return Int32(3) + case .arrayPayload(let param0): + param0.bridgeJSLowerReturn() + return Int32(4) + case .jsClassPayload(let param0): + param0.jsObject.bridgeJSLowerStackReturn() + return Int32(5) + case .empty: + return Int32(6) + } + } + + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ caseId: Int32) -> AllTypesResult { + return _bridgeJSLiftFromCaseId(caseId) + } + + // MARK: ExportSwift + + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ caseId: Int32) -> AllTypesResult { + return _bridgeJSLiftFromCaseId(caseId) + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() { + switch self { + case .structPayload(let param0): + param0.bridgeJSLowerReturn() + _swift_js_push_tag(Int32(0)) + case .classPayload(let param0): + param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(1)) + case .jsObjectPayload(let param0): + param0.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(2)) + case .nestedEnum(let param0): + param0.bridgeJSLowerReturn() + _swift_js_push_tag(Int32(3)) + case .arrayPayload(let param0): + param0.bridgeJSLowerReturn() + _swift_js_push_tag(Int32(4)) + case .jsClassPayload(let param0): + param0.jsObject.bridgeJSLowerStackReturn() + _swift_js_push_tag(Int32(5)) + case .empty: + _swift_js_push_tag(Int32(6)) + } + } +} + +extension OptionalAllTypesResult: _BridgedSwiftAssociatedValueEnum { + private static func _bridgeJSLiftFromCaseId(_ caseId: Int32) -> OptionalAllTypesResult { + switch caseId { + case 0: + return .optStruct(Optional
.bridgeJSLiftParameter()) + case 1: + return .optClass(Optional.bridgeJSLiftParameter()) + case 2: + return .optJSObject(Optional.bridgeJSLiftParameter()) + case 3: + return .optNestedEnum(Optional.bridgeJSLiftParameter()) + case 4: + return .optArray({ + let __isSome = _swift_js_pop_i32() + if __isSome == 0 { + return Optional<[Int]>.none + } else { + return [Int].bridgeJSLiftParameter() + } + }()) + case 5: + return .optJsClass(Optional.bridgeJSLiftParameter().map { + Foo(unsafelyWrapping: $0) + }) + case 6: + return .empty + default: + fatalError("Unknown OptionalAllTypesResult case ID: \(caseId)") + } + } + + // MARK: Protocol Export + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + switch self { + case .optStruct(let param0): + let __bjs_isSome_param0 = param0 != nil + if let __bjs_unwrapped_param0 = param0 { + __bjs_unwrapped_param0.bridgeJSLowerReturn() + } + _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + return Int32(0) + case .optClass(let param0): + let __bjs_isSome_param0 = param0 != nil + if let __bjs_unwrapped_param0 = param0 { + __bjs_unwrapped_param0.bridgeJSLowerStackReturn() + } + _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + return Int32(1) + case .optJSObject(let param0): + let __bjs_isSome_param0 = param0 != nil + if let __bjs_unwrapped_param0 = param0 { + __bjs_unwrapped_param0.bridgeJSLowerStackReturn() + } + _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + return Int32(2) + case .optNestedEnum(let param0): + let __bjs_isSome_param0 = param0 != nil + if let __bjs_unwrapped_param0 = param0 { + _swift_js_push_i32(__bjs_unwrapped_param0.bridgeJSLowerParameter()) + } + _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + return Int32(3) + case .optArray(let param0): + let __bjs_isSome_param0 = param0 != nil + if let __bjs_unwrapped_param0 = param0 { + __bjs_unwrapped_param0.bridgeJSLowerReturn() + } + _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + return Int32(4) + case .optJsClass(let param0): + let __bjs_isSome_param0 = param0 != nil + if let __bjs_unwrapped_param0 = param0 { + __bjs_unwrapped_param0.jsObject.bridgeJSLowerStackReturn() + } + _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + return Int32(5) + case .empty: + return Int32(6) + } + } + + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ caseId: Int32) -> OptionalAllTypesResult { + return _bridgeJSLiftFromCaseId(caseId) + } + + // MARK: ExportSwift + + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ caseId: Int32) -> OptionalAllTypesResult { + return _bridgeJSLiftFromCaseId(caseId) + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() { + switch self { + case .optStruct(let param0): + let __bjs_isSome_param0 = param0 != nil + if let __bjs_unwrapped_param0 = param0 { + __bjs_unwrapped_param0.bridgeJSLowerReturn() + } + _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + _swift_js_push_tag(Int32(0)) + case .optClass(let param0): + let __bjs_isSome_param0 = param0 != nil + if let __bjs_unwrapped_param0 = param0 { + __bjs_unwrapped_param0.bridgeJSLowerStackReturn() + } + _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + _swift_js_push_tag(Int32(1)) + case .optJSObject(let param0): + let __bjs_isSome_param0 = param0 != nil + if let __bjs_unwrapped_param0 = param0 { + __bjs_unwrapped_param0.bridgeJSLowerStackReturn() + } + _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + _swift_js_push_tag(Int32(2)) + case .optNestedEnum(let param0): + let __bjs_isSome_param0 = param0 != nil + if let __bjs_unwrapped_param0 = param0 { + _swift_js_push_i32(__bjs_unwrapped_param0.bridgeJSLowerParameter()) + } + _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + _swift_js_push_tag(Int32(3)) + case .optArray(let param0): + let __bjs_isSome_param0 = param0 != nil + if let __bjs_unwrapped_param0 = param0 { + __bjs_unwrapped_param0.bridgeJSLowerReturn() + } + _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + _swift_js_push_tag(Int32(4)) + case .optJsClass(let param0): + let __bjs_isSome_param0 = param0 != nil + if let __bjs_unwrapped_param0 = param0 { + __bjs_unwrapped_param0.jsObject.bridgeJSLowerStackReturn() + } + _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + _swift_js_push_tag(Int32(5)) + case .empty: + _swift_js_push_tag(Int32(6)) } } } @@ -1876,14 +2188,13 @@ extension APIOptionalResult: _BridgedSwiftAssociatedValueEnum { @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() { switch self { case .success(let param0): - _swift_js_push_tag(Int32(0)) let __bjs_isSome_param0 = param0 != nil if let __bjs_unwrapped_param0 = param0 { __bjs_unwrapped_param0.bridgeJSLowerStackReturn() } _swift_js_push_i32(__bjs_isSome_param0 ? 1 : 0) + _swift_js_push_tag(Int32(0)) case .failure(let param0, let param1): - _swift_js_push_tag(Int32(1)) let __bjs_isSome_param0 = param0 != nil if let __bjs_unwrapped_param0 = param0 { __bjs_unwrapped_param0.bridgeJSLowerStackReturn() @@ -1894,8 +2205,8 @@ extension APIOptionalResult: _BridgedSwiftAssociatedValueEnum { __bjs_unwrapped_param1.bridgeJSLowerStackReturn() } _swift_js_push_i32(__bjs_isSome_param1 ? 1 : 0) + _swift_js_push_tag(Int32(1)) case .status(let param0, let param1, let param2): - _swift_js_push_tag(Int32(2)) let __bjs_isSome_param0 = param0 != nil if let __bjs_unwrapped_param0 = param0 { __bjs_unwrapped_param0.bridgeJSLowerStackReturn() @@ -1911,6 +2222,7 @@ extension APIOptionalResult: _BridgedSwiftAssociatedValueEnum { __bjs_unwrapped_param2.bridgeJSLowerStackReturn() } _swift_js_push_i32(__bjs_isSome_param2 ? 1 : 0) + _swift_js_push_tag(Int32(2)) } } } @@ -4451,6 +4763,28 @@ public func _bjs_roundTripOptionalAPIResult(_ valueIsSome: Int32, _ valueCaseId: #endif } +@_expose(wasm, "bjs_roundTripTypedPayloadResult") +@_cdecl("bjs_roundTripTypedPayloadResult") +public func _bjs_roundTripTypedPayloadResult(_ result: Int32) -> Void { + #if arch(wasm32) + let ret = roundTripTypedPayloadResult(_: TypedPayloadResult.bridgeJSLiftParameter(result)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_roundTripOptionalTypedPayloadResult") +@_cdecl("bjs_roundTripOptionalTypedPayloadResult") +public func _bjs_roundTripOptionalTypedPayloadResult(_ resultIsSome: Int32, _ resultCaseId: Int32) -> Void { + #if arch(wasm32) + let ret = roundTripOptionalTypedPayloadResult(_: Optional.bridgeJSLiftParameter(resultIsSome, resultCaseId)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + @_expose(wasm, "bjs_compareAPIResults") @_cdecl("bjs_compareAPIResults") public func _bjs_compareAPIResults(_ r1IsSome: Int32, _ r1CaseId: Int32, _ r2IsSome: Int32, _ r2CaseId: Int32) -> Void { @@ -4475,6 +4809,50 @@ public func _bjs_roundTripOptionalComplexResult(_ resultIsSome: Int32, _ resultC #endif } +@_expose(wasm, "bjs_roundTripAllTypesResult") +@_cdecl("bjs_roundTripAllTypesResult") +public func _bjs_roundTripAllTypesResult(_ result: Int32) -> Void { + #if arch(wasm32) + let ret = roundTripAllTypesResult(_: AllTypesResult.bridgeJSLiftParameter(result)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_roundTripOptionalAllTypesResult") +@_cdecl("bjs_roundTripOptionalAllTypesResult") +public func _bjs_roundTripOptionalAllTypesResult(_ resultIsSome: Int32, _ resultCaseId: Int32) -> Void { + #if arch(wasm32) + let ret = roundTripOptionalAllTypesResult(_: Optional.bridgeJSLiftParameter(resultIsSome, resultCaseId)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_roundTripOptionalPayloadResult") +@_cdecl("bjs_roundTripOptionalPayloadResult") +public func _bjs_roundTripOptionalPayloadResult(_ result: Int32) -> Void { + #if arch(wasm32) + let ret = roundTripOptionalPayloadResult(_: OptionalAllTypesResult.bridgeJSLiftParameter(result)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_roundTripOptionalPayloadResultOpt") +@_cdecl("bjs_roundTripOptionalPayloadResultOpt") +public func _bjs_roundTripOptionalPayloadResultOpt(_ resultIsSome: Int32, _ resultCaseId: Int32) -> Void { + #if arch(wasm32) + let ret = roundTripOptionalPayloadResultOpt(_: Optional.bridgeJSLiftParameter(resultIsSome, resultCaseId)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + @_expose(wasm, "bjs_roundTripOptionalClass") @_cdecl("bjs_roundTripOptionalClass") public func _bjs_roundTripOptionalClass(_ valueIsSome: Int32, _ valueValue: UnsafeMutableRawPointer) -> Void { diff --git a/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json b/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json index e2877ee7..41d2ccf8 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json +++ b/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json @@ -4357,6 +4357,308 @@ "swiftCallName" : "API.NetworkingResult", "tsFullPath" : "API.NetworkingResult" }, + { + "cases" : [ + { + "associatedValues" : [ + { + "type" : { + "rawValueEnum" : { + "_0" : "Precision", + "_1" : "Float" + } + } + } + ], + "name" : "precision" + }, + { + "associatedValues" : [ + { + "type" : { + "caseEnum" : { + "_0" : "Direction" + } + } + } + ], + "name" : "direction" + }, + { + "associatedValues" : [ + { + "type" : { + "nullable" : { + "_0" : { + "rawValueEnum" : { + "_0" : "Precision", + "_1" : "Float" + } + }, + "_1" : "null" + } + } + } + ], + "name" : "optPrecision" + }, + { + "associatedValues" : [ + { + "type" : { + "nullable" : { + "_0" : { + "caseEnum" : { + "_0" : "Direction" + } + }, + "_1" : "null" + } + } + } + ], + "name" : "optDirection" + }, + { + "associatedValues" : [ + + ], + "name" : "empty" + } + ], + "emitStyle" : "const", + "name" : "TypedPayloadResult", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "TypedPayloadResult", + "tsFullPath" : "TypedPayloadResult" + }, + { + "cases" : [ + { + "associatedValues" : [ + { + "type" : { + "swiftStruct" : { + "_0" : "Address" + } + } + } + ], + "name" : "structPayload" + }, + { + "associatedValues" : [ + { + "type" : { + "swiftHeapObject" : { + "_0" : "Greeter" + } + } + } + ], + "name" : "classPayload" + }, + { + "associatedValues" : [ + { + "type" : { + "jsObject" : { + + } + } + } + ], + "name" : "jsObjectPayload" + }, + { + "associatedValues" : [ + { + "type" : { + "associatedValueEnum" : { + "_0" : "APIResult" + } + } + } + ], + "name" : "nestedEnum" + }, + { + "associatedValues" : [ + { + "type" : { + "array" : { + "_0" : { + "int" : { + + } + } + } + } + } + ], + "name" : "arrayPayload" + }, + { + "associatedValues" : [ + { + "type" : { + "jsObject" : { + "_0" : "Foo" + } + } + } + ], + "name" : "jsClassPayload" + }, + { + "associatedValues" : [ + + ], + "name" : "empty" + } + ], + "emitStyle" : "const", + "name" : "AllTypesResult", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "AllTypesResult", + "tsFullPath" : "AllTypesResult" + }, + { + "cases" : [ + { + "associatedValues" : [ + { + "type" : { + "nullable" : { + "_0" : { + "swiftStruct" : { + "_0" : "Address" + } + }, + "_1" : "null" + } + } + } + ], + "name" : "optStruct" + }, + { + "associatedValues" : [ + { + "type" : { + "nullable" : { + "_0" : { + "swiftHeapObject" : { + "_0" : "Greeter" + } + }, + "_1" : "null" + } + } + } + ], + "name" : "optClass" + }, + { + "associatedValues" : [ + { + "type" : { + "nullable" : { + "_0" : { + "jsObject" : { + + } + }, + "_1" : "null" + } + } + } + ], + "name" : "optJSObject" + }, + { + "associatedValues" : [ + { + "type" : { + "nullable" : { + "_0" : { + "associatedValueEnum" : { + "_0" : "APIResult" + } + }, + "_1" : "null" + } + } + } + ], + "name" : "optNestedEnum" + }, + { + "associatedValues" : [ + { + "type" : { + "nullable" : { + "_0" : { + "array" : { + "_0" : { + "int" : { + + } + } + } + }, + "_1" : "null" + } + } + } + ], + "name" : "optArray" + }, + { + "associatedValues" : [ + { + "type" : { + "nullable" : { + "_0" : { + "jsObject" : { + "_0" : "Foo" + } + }, + "_1" : "null" + } + } + } + ], + "name" : "optJsClass" + }, + { + "associatedValues" : [ + + ], + "name" : "empty" + } + ], + "emitStyle" : "const", + "name" : "OptionalAllTypesResult", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "OptionalAllTypesResult", + "tsFullPath" : "OptionalAllTypesResult" + }, { "cases" : [ { @@ -7557,6 +7859,66 @@ } } }, + { + "abiName" : "bjs_roundTripTypedPayloadResult", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "roundTripTypedPayloadResult", + "parameters" : [ + { + "label" : "_", + "name" : "result", + "type" : { + "associatedValueEnum" : { + "_0" : "TypedPayloadResult" + } + } + } + ], + "returnType" : { + "associatedValueEnum" : { + "_0" : "TypedPayloadResult" + } + } + }, + { + "abiName" : "bjs_roundTripOptionalTypedPayloadResult", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "roundTripOptionalTypedPayloadResult", + "parameters" : [ + { + "label" : "_", + "name" : "result", + "type" : { + "nullable" : { + "_0" : { + "associatedValueEnum" : { + "_0" : "TypedPayloadResult" + } + }, + "_1" : "null" + } + } + } + ], + "returnType" : { + "nullable" : { + "_0" : { + "associatedValueEnum" : { + "_0" : "TypedPayloadResult" + } + }, + "_1" : "null" + } + } + }, { "abiName" : "bjs_compareAPIResults", "effects" : { @@ -7636,6 +7998,126 @@ } } }, + { + "abiName" : "bjs_roundTripAllTypesResult", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "roundTripAllTypesResult", + "parameters" : [ + { + "label" : "_", + "name" : "result", + "type" : { + "associatedValueEnum" : { + "_0" : "AllTypesResult" + } + } + } + ], + "returnType" : { + "associatedValueEnum" : { + "_0" : "AllTypesResult" + } + } + }, + { + "abiName" : "bjs_roundTripOptionalAllTypesResult", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "roundTripOptionalAllTypesResult", + "parameters" : [ + { + "label" : "_", + "name" : "result", + "type" : { + "nullable" : { + "_0" : { + "associatedValueEnum" : { + "_0" : "AllTypesResult" + } + }, + "_1" : "null" + } + } + } + ], + "returnType" : { + "nullable" : { + "_0" : { + "associatedValueEnum" : { + "_0" : "AllTypesResult" + } + }, + "_1" : "null" + } + } + }, + { + "abiName" : "bjs_roundTripOptionalPayloadResult", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "roundTripOptionalPayloadResult", + "parameters" : [ + { + "label" : "_", + "name" : "result", + "type" : { + "associatedValueEnum" : { + "_0" : "OptionalAllTypesResult" + } + } + } + ], + "returnType" : { + "associatedValueEnum" : { + "_0" : "OptionalAllTypesResult" + } + } + }, + { + "abiName" : "bjs_roundTripOptionalPayloadResultOpt", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "roundTripOptionalPayloadResultOpt", + "parameters" : [ + { + "label" : "_", + "name" : "result", + "type" : { + "nullable" : { + "_0" : { + "associatedValueEnum" : { + "_0" : "OptionalAllTypesResult" + } + }, + "_1" : "null" + } + } + } + ], + "returnType" : { + "nullable" : { + "_0" : { + "associatedValueEnum" : { + "_0" : "OptionalAllTypesResult" + } + }, + "_1" : "null" + } + } + }, { "abiName" : "bjs_roundTripOptionalClass", "effects" : { diff --git a/Tests/prelude.mjs b/Tests/prelude.mjs index 6a8dd58a..cc21a864 100644 --- a/Tests/prelude.mjs +++ b/Tests/prelude.mjs @@ -1,7 +1,7 @@ // @ts-check import { - DirectionValues, StatusValues, ThemeValues, HttpStatusValues, TSDirection, TSTheme, APIResultValues, ComplexResultValues, APIOptionalResultValues, StaticCalculatorValues, StaticPropertyEnumValues + DirectionValues, StatusValues, ThemeValues, HttpStatusValues, TSDirection, TSTheme, APIResultValues, ComplexResultValues, APIOptionalResultValues, StaticCalculatorValues, StaticPropertyEnumValues, PrecisionValues, TypedPayloadResultValues, AllTypesResultValues, OptionalAllTypesResultValues } from '../.build/plugins/PackageToJS/outputs/PackageTests/bridge-js.js'; /** @type {import('../.build/plugins/PackageToJS/outputs/PackageTests/test.d.ts').SetupOptionsFn} */ @@ -781,6 +781,129 @@ function BridgeJSRuntimeTests_runJsWorks(instance, exports) { assert.deepEqual(exports.roundTripOptionalAPIOptionalResult(aor10), aor10); assert.equal(exports.roundTripOptionalAPIOptionalResult(null), null); + // TypedPayloadResult — rawValueEnum and caseEnum as associated value payloads + assert.equal(exports.Precision.Rough, 0.1); + assert.equal(exports.Precision.Fine, 0.001); + + const tpr_precision = { tag: exports.TypedPayloadResult.Tag.Precision, param0: Math.fround(0.1) }; + assert.deepEqual(exports.roundTripTypedPayloadResult(tpr_precision), tpr_precision); + + const tpr_direction = { tag: exports.TypedPayloadResult.Tag.Direction, param0: exports.Direction.North }; + assert.deepEqual(exports.roundTripTypedPayloadResult(tpr_direction), tpr_direction); + + const tpr_dirSouth = { tag: exports.TypedPayloadResult.Tag.Direction, param0: exports.Direction.South }; + assert.deepEqual(exports.roundTripTypedPayloadResult(tpr_dirSouth), tpr_dirSouth); + + const tpr_optPrecisionSome = { tag: exports.TypedPayloadResult.Tag.OptPrecision, param0: Math.fround(0.001) }; + assert.deepEqual(exports.roundTripTypedPayloadResult(tpr_optPrecisionSome), tpr_optPrecisionSome); + + const tpr_optPrecisionNull = { tag: exports.TypedPayloadResult.Tag.OptPrecision, param0: null }; + assert.deepEqual(exports.roundTripTypedPayloadResult(tpr_optPrecisionNull), tpr_optPrecisionNull); + + const tpr_optDirectionSome = { tag: exports.TypedPayloadResult.Tag.OptDirection, param0: exports.Direction.East }; + assert.deepEqual(exports.roundTripTypedPayloadResult(tpr_optDirectionSome), tpr_optDirectionSome); + + const tpr_optDirectionNull = { tag: exports.TypedPayloadResult.Tag.OptDirection, param0: null }; + assert.deepEqual(exports.roundTripTypedPayloadResult(tpr_optDirectionNull), tpr_optDirectionNull); + + const tpr_empty = { tag: exports.TypedPayloadResult.Tag.Empty }; + assert.deepEqual(exports.roundTripTypedPayloadResult(tpr_empty), tpr_empty); + + // Optional TypedPayloadResult roundtrip + assert.deepEqual(exports.roundTripOptionalTypedPayloadResult(tpr_precision), tpr_precision); + assert.deepEqual(exports.roundTripOptionalTypedPayloadResult(tpr_direction), tpr_direction); + assert.deepEqual(exports.roundTripOptionalTypedPayloadResult(tpr_optPrecisionSome), tpr_optPrecisionSome); + assert.deepEqual(exports.roundTripOptionalTypedPayloadResult(tpr_optPrecisionNull), tpr_optPrecisionNull); + assert.deepEqual(exports.roundTripOptionalTypedPayloadResult(tpr_empty), tpr_empty); + assert.equal(exports.roundTripOptionalTypedPayloadResult(null), null); + + // AllTypesResult — struct, class, JSObject, nested enum, array as associated value payloads + const atr_struct = { tag: AllTypesResultValues.Tag.StructPayload, param0: { street: "100 Main St", city: "Boston", zipCode: 2101 } }; + assert.deepEqual(exports.roundTripAllTypesResult(atr_struct), atr_struct); + + const atr_class = { tag: AllTypesResultValues.Tag.ClassPayload, param0: new exports.Greeter("EnumUser") }; + const atr_class_result = exports.roundTripAllTypesResult(atr_class); + assert.equal(atr_class_result.tag, AllTypesResultValues.Tag.ClassPayload); + assert.equal(atr_class_result.param0.name, "EnumUser"); + + const atr_jsObject = { tag: AllTypesResultValues.Tag.JsObjectPayload, param0: { custom: "data", value: 42 } }; + const atr_jsObject_result = exports.roundTripAllTypesResult(atr_jsObject); + assert.equal(atr_jsObject_result.tag, AllTypesResultValues.Tag.JsObjectPayload); + assert.equal(atr_jsObject_result.param0.custom, "data"); + assert.equal(atr_jsObject_result.param0.value, 42); + + const atr_nestedEnum = { tag: AllTypesResultValues.Tag.NestedEnum, param0: { tag: APIResultValues.Tag.Success, param0: "nested!" } }; + assert.deepEqual(exports.roundTripAllTypesResult(atr_nestedEnum), atr_nestedEnum); + + const atr_array = { tag: AllTypesResultValues.Tag.ArrayPayload, param0: [10, 20, 30] }; + assert.deepEqual(exports.roundTripAllTypesResult(atr_array), atr_array); + + const atr_jsClass = { tag: AllTypesResultValues.Tag.JsClassPayload, param0: new ImportedFoo("enumFoo") }; + const atr_jsClass_result = exports.roundTripAllTypesResult(atr_jsClass); + assert.equal(atr_jsClass_result.tag, AllTypesResultValues.Tag.JsClassPayload); + assert.equal(atr_jsClass_result.param0.value, "enumFoo"); + + const atr_empty = { tag: AllTypesResultValues.Tag.Empty }; + assert.deepEqual(exports.roundTripAllTypesResult(atr_empty), atr_empty); + + // Optional AllTypesResult roundtrip + assert.deepEqual(exports.roundTripOptionalAllTypesResult(atr_struct), atr_struct); + assert.deepEqual(exports.roundTripOptionalAllTypesResult(atr_array), atr_array); + assert.deepEqual(exports.roundTripOptionalAllTypesResult(atr_empty), atr_empty); + assert.equal(exports.roundTripOptionalAllTypesResult(null), null); + + // OptionalAllTypesResult — optional struct, class, JSObject, nested enum, array as associated value payloads + const oatr_structSome = { tag: OptionalAllTypesResultValues.Tag.OptStruct, param0: { street: "200 Oak St", city: "Denver", zipCode: null } }; + assert.deepEqual(exports.roundTripOptionalPayloadResult(oatr_structSome), oatr_structSome); + + const oatr_structNone = { tag: OptionalAllTypesResultValues.Tag.OptStruct, param0: null }; + assert.deepEqual(exports.roundTripOptionalPayloadResult(oatr_structNone), oatr_structNone); + + const oatr_classSome = { tag: OptionalAllTypesResultValues.Tag.OptClass, param0: new exports.Greeter("OptEnumUser") }; + const oatr_classSome_result = exports.roundTripOptionalPayloadResult(oatr_classSome); + assert.equal(oatr_classSome_result.tag, OptionalAllTypesResultValues.Tag.OptClass); + assert.equal(oatr_classSome_result.param0.name, "OptEnumUser"); + + const oatr_classNone = { tag: OptionalAllTypesResultValues.Tag.OptClass, param0: null }; + assert.deepEqual(exports.roundTripOptionalPayloadResult(oatr_classNone), oatr_classNone); + + const oatr_jsObjectSome = { tag: OptionalAllTypesResultValues.Tag.OptJSObject, param0: { key: "value" } }; + const oatr_jsObjectSome_result = exports.roundTripOptionalPayloadResult(oatr_jsObjectSome); + assert.equal(oatr_jsObjectSome_result.tag, OptionalAllTypesResultValues.Tag.OptJSObject); + assert.equal(oatr_jsObjectSome_result.param0.key, "value"); + + const oatr_jsObjectNone = { tag: OptionalAllTypesResultValues.Tag.OptJSObject, param0: null }; + assert.deepEqual(exports.roundTripOptionalPayloadResult(oatr_jsObjectNone), oatr_jsObjectNone); + + const oatr_nestedEnumSome = { tag: OptionalAllTypesResultValues.Tag.OptNestedEnum, param0: { tag: APIResultValues.Tag.Failure, param0: 404 } }; + assert.deepEqual(exports.roundTripOptionalPayloadResult(oatr_nestedEnumSome), oatr_nestedEnumSome); + + const oatr_nestedEnumNone = { tag: OptionalAllTypesResultValues.Tag.OptNestedEnum, param0: null }; + assert.deepEqual(exports.roundTripOptionalPayloadResult(oatr_nestedEnumNone), oatr_nestedEnumNone); + + const oatr_arraySome = { tag: OptionalAllTypesResultValues.Tag.OptArray, param0: [1, 2, 3] }; + assert.deepEqual(exports.roundTripOptionalPayloadResult(oatr_arraySome), oatr_arraySome); + + const oatr_arrayNone = { tag: OptionalAllTypesResultValues.Tag.OptArray, param0: null }; + assert.deepEqual(exports.roundTripOptionalPayloadResult(oatr_arrayNone), oatr_arrayNone); + + const oatr_jsClassSome = { tag: OptionalAllTypesResultValues.Tag.OptJsClass, param0: new ImportedFoo("optEnumFoo") }; + const oatr_jsClassSome_result = exports.roundTripOptionalPayloadResult(oatr_jsClassSome); + assert.equal(oatr_jsClassSome_result.tag, OptionalAllTypesResultValues.Tag.OptJsClass); + assert.equal(oatr_jsClassSome_result.param0.value, "optEnumFoo"); + + const oatr_jsClassNone = { tag: OptionalAllTypesResultValues.Tag.OptJsClass, param0: null }; + assert.deepEqual(exports.roundTripOptionalPayloadResult(oatr_jsClassNone), oatr_jsClassNone); + + const oatr_empty = { tag: OptionalAllTypesResultValues.Tag.Empty }; + assert.deepEqual(exports.roundTripOptionalPayloadResult(oatr_empty), oatr_empty); + + // Optional OptionalAllTypesResult roundtrip + assert.deepEqual(exports.roundTripOptionalPayloadResultOpt(oatr_structSome), oatr_structSome); + assert.deepEqual(exports.roundTripOptionalPayloadResultOpt(oatr_structNone), oatr_structNone); + assert.deepEqual(exports.roundTripOptionalPayloadResultOpt(oatr_empty), oatr_empty); + assert.equal(exports.roundTripOptionalPayloadResultOpt(null), null); + assert.equal(exports.MathUtils.add(2147483647, 0), 2147483647); assert.equal(exports.StaticCalculator.roundtrip(42), 42); assert.equal(StaticCalculatorValues.Scientific, 0);