diff --git a/Benchmarks/Sources/Generated/BridgeJS.swift b/Benchmarks/Sources/Generated/BridgeJS.swift index 384ca35a2..5e3e11db8 100644 --- a/Benchmarks/Sources/Generated/BridgeJS.swift +++ b/Benchmarks/Sources/Generated/BridgeJS.swift @@ -2179,6 +2179,34 @@ fileprivate func _bjs_ArrayRoundtrip_wrap_extern(_ pointer: UnsafeMutableRawPoin return _bjs_ArrayRoundtrip_wrap_extern(pointer) } +extension SimpleStruct: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = SimpleStruct.bridgeJSMakeTypeHandle() +} + +extension Address: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Address.bridgeJSMakeTypeHandle() +} + +extension Person: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Person.bridgeJSMakeTypeHandle() +} + +extension ComplexStruct: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = ComplexStruct.bridgeJSMakeTypeHandle() +} + +extension Point: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Point.bridgeJSMakeTypeHandle() +} + +extension APIResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = APIResult.bridgeJSMakeTypeHandle() +} + +extension ComplexResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = ComplexResult.bridgeJSMakeTypeHandle() +} + #if arch(wasm32) @_extern(wasm, module: "Benchmarks", name: "bjs_benchmarkHelperNoop") fileprivate func bjs_benchmarkHelperNoop_extern() -> Void @@ -2238,4 +2266,25 @@ func _$benchmarkRunner(_ name: String, _ body: JSObject) throws(JSException) -> if let error = _swift_js_take_exception() { throw error } -} \ No newline at end of file +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_Benchmarks_register_type_handles") +fileprivate func _bjs_Benchmarks_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_Benchmarks_register_type_handles") +public func _bjs_Benchmarks_register_type_handles() { + let typeIds: [Int32] = [ + SimpleStruct.bridgeJSTypeID, + Address.bridgeJSTypeID, + Person.bridgeJSTypeID, + ComplexStruct.bridgeJSTypeID, + Point.bridgeJSTypeID, + APIResult.bridgeJSTypeID, + ComplexResult.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_Benchmarks_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Examples/Embedded/Package.swift b/Examples/Embedded/Package.swift index 42702394a..1f88a8947 100644 --- a/Examples/Embedded/Package.swift +++ b/Examples/Embedded/Package.swift @@ -16,6 +16,9 @@ let package = Package( swiftSettings: [ .enableExperimentalFeature("Extern") ], + plugins: [ + .plugin(name: "BridgeJS", package: "JavaScriptKit") + ] ) ], swiftLanguageModes: [.v5] diff --git a/Examples/Embedded/Sources/EmbeddedApp/main.swift b/Examples/Embedded/Sources/EmbeddedApp/main.swift index 5e7f01a3c..c3e0dd3cd 100644 --- a/Examples/Embedded/Sources/EmbeddedApp/main.swift +++ b/Examples/Embedded/Sources/EmbeddedApp/main.swift @@ -1,5 +1,12 @@ import JavaScriptKit +@JS struct CounterLabel { + var count: Int + var text: String +} + +@JSFunction func echoValue(_ value: T) throws(JSException) -> T + let alert = JSObject.global.alert.object! let document = JSObject.global.document @@ -46,6 +53,17 @@ _ = encoderContainer.appendChild(textInputElement) _ = encoderContainer.appendChild(encodeResultElement) _ = document.body.appendChild(encoderContainer) +let genericResultElement = document.createElement("pre") +do { + let number = try echoValue(42) + let text = try echoValue("hello") + let label = try echoValue(CounterLabel(count: number, text: text)) + genericResultElement.innerText = .string("Generic import round-trip: \(label.text) \(label.count)") +} catch { + genericResultElement.innerText = "Generic import round-trip failed" +} +_ = document.body.appendChild(genericResultElement) + func print(_ message: String) { _ = JSObject.global.console.log(message) } diff --git a/Examples/Embedded/index.html b/Examples/Embedded/index.html index 93868214d..d280d7067 100644 --- a/Examples/Embedded/index.html +++ b/Examples/Embedded/index.html @@ -8,7 +8,13 @@ diff --git a/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/BridgeJS.swift b/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/BridgeJS.swift index 10976f793..328ae0610 100644 --- a/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/BridgeJS.swift +++ b/Examples/PlayBridgeJS/Sources/PlayBridgeJS/Generated/BridgeJS.swift @@ -231,6 +231,18 @@ fileprivate func _bjs_PlayBridgeJS_wrap_extern(_ pointer: UnsafeMutableRawPointe return _bjs_PlayBridgeJS_wrap_extern(pointer) } +extension PlayBridgeJSOutput: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = PlayBridgeJSOutput.bridgeJSMakeTypeHandle() +} + +extension PlayBridgeJSDiagnostic: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = PlayBridgeJSDiagnostic.bridgeJSMakeTypeHandle() +} + +extension PlayBridgeJSResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = PlayBridgeJSResult.bridgeJSMakeTypeHandle() +} + #if arch(wasm32) @_extern(wasm, module: "PlayBridgeJS", name: "bjs_createTS2Swift") fileprivate func bjs_createTS2Swift_extern() -> Int32 @@ -274,4 +286,21 @@ func _$TS2Swift_convert(_ self: JSObject, _ ts: String) throws(JSException) -> S throw error } return String.bridgeJSLiftReturn(ret) -} \ No newline at end of file +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_PlayBridgeJS_register_type_handles") +fileprivate func _bjs_PlayBridgeJS_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_PlayBridgeJS_register_type_handles") +public func _bjs_PlayBridgeJS_register_type_handles() { + let typeIds: [Int32] = [ + PlayBridgeJSOutput.bridgeJSTypeID, + PlayBridgeJSDiagnostic.bridgeJSTypeID, + PlayBridgeJSResult.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_PlayBridgeJS_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/README.md b/Plugins/BridgeJS/README.md index 9e1e0aa08..0905695c5 100644 --- a/Plugins/BridgeJS/README.md +++ b/Plugins/BridgeJS/README.md @@ -98,7 +98,7 @@ graph LR | `Dictionary` | `Record` | - | [#495](https://github.com/swiftwasm/JavaScriptKit/issues/495) | | `Set` | `Set` | - | [#397](https://github.com/swiftwasm/JavaScriptKit/issues/397) | | `Foundation.URL` | `string` | - | [#496](https://github.com/swiftwasm/JavaScriptKit/issues/496) | -| Generics | - | - | [#398](https://github.com/swiftwasm/JavaScriptKit/issues/398) | +| Generic function or method (`T`, `[T]`, `T?`, `[String: T]`) | `(value: T): T` | Depends on `T` | ✅ imports only ([#398](https://github.com/swiftwasm/JavaScriptKit/issues/398) for exports) | ### Import-specific (TypeScript -> Swift) diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift index 2cc551857..55b5889fe 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift @@ -91,6 +91,13 @@ public class ExportSwift { } } + withSpan("Render Generic Bridgeable Conformances") { [self] in + let genericConformanceCodegen = GenericConformanceCodegen() + for entry in skeleton.genericBridgeableTypeEntries { + decls.append(contentsOf: genericConformanceCodegen.renderConformance(typeName: entry.swiftName)) + } + } + try withSpan("Render Async Promise Helpers") { [self] in let asyncResolveTypes = skeleton.asyncPromiseResolveReturnTypes if !asyncResolveTypes.isEmpty { @@ -875,6 +882,57 @@ public class ExportSwift { } } +// MARK: - GenericConformanceCodegen + +struct GenericConformanceCodegen { + func renderConformance(typeName: String) -> [DeclSyntax] { + let printer = CodeFragmentPrinter() + printer.write("extension \(typeName): BridgedSwiftGenericBridgeable {") + printer.indent { + printer.write( + "@_spi(BridgeJS) public static let bridgeJSTypeHandle = \(typeName).bridgeJSMakeTypeHandle()" + ) + } + printer.write("}") + return ["\(raw: printer.lines.joined(separator: "\n"))"] + } +} + +// MARK: - GenericTypeRegistrationCodegen + +public struct GenericTypeRegistrationCodegen { + public init() {} + + public func render(for skeleton: BridgeJSSkeleton) -> String? { + guard let entries = skeleton.typeRegistrationEntries else { return nil } + let abiName = ABINameGenerator.typeRegistrationFunctionName(moduleName: skeleton.moduleName) + let printer = CodeFragmentPrinter() + printer.write("#if arch(wasm32)") + printer.write("@_extern(wasm, module: \"bjs\", name: \"\(abiName)\")") + printer.write("fileprivate func _\(abiName)_extern(_ base: UnsafePointer?, _ count: Int32)") + printer.nextLine() + printer.write("@_expose(wasm, \"\(abiName)\")") + printer.write("public func _\(abiName)() {") + printer.indent { + printer.write("let typeIds: [Int32] = [") + printer.indent { + for entry in entries { + printer.write("\(entry.swiftName).bridgeJSTypeID,") + } + } + printer.write("]") + printer.write("typeIds.withUnsafeBufferPointer { buffer in") + printer.indent { + printer.write("_\(abiName)_extern(buffer.baseAddress, Int32(buffer.count))") + } + printer.write("}") + } + printer.write("}") + printer.write("#endif") + return printer.lines.joined(separator: "\n") + } +} + // MARK: - StackCodegen /// Helper for stack-based lifting and lowering operations. @@ -896,6 +954,10 @@ struct StackCodegen { return "JSObject.bridgeJSStackPop()" case .void, .namespaceEnum: return "()" + case .generic: + fatalError( + "Generic parameters are only supported on imported declarations, not exported concrete-type codegen" + ) } } @@ -908,7 +970,7 @@ struct StackCodegen { return "\(raw: typeName)<\(raw: wrappedType.swiftType)>.bridgeJSStackPop()" case .jsObject(let className?): return "\(raw: typeName).bridgeJSStackPop().map { \(raw: className)(unsafelyWrapping: $0) }" - case .nullable, .void, .namespaceEnum, .closure, .unsafePointer, .swiftProtocol: + case .nullable, .void, .namespaceEnum, .closure, .unsafePointer, .swiftProtocol, .generic: fatalError("Invalid nullable wrapped type: \(wrappedType)") } } @@ -941,6 +1003,10 @@ struct StackCodegen { return lowerArrayStatements(elementType: elementType, accessor: accessor, varPrefix: varPrefix) case .dictionary(let valueType): return lowerDictionaryStatements(valueType: valueType, accessor: accessor, varPrefix: varPrefix) + case .generic: + fatalError( + "Generic parameters are only supported on imported declarations, not exported concrete-type codegen" + ) } } @@ -1596,12 +1662,34 @@ extension BridgeType { case .associatedValueEnum: return ["_BridgedSwiftAssociatedValueEnum"] case .rawValueEnum, .void, .unsafePointer, .namespaceEnum, - .swiftProtocol, .closure, .nullable, .array, .dictionary, .alias: + .swiftProtocol, .closure, .nullable, .array, .dictionary, .alias, .generic: // Not supported yet. return nil } } + /// Stack expressions for bare `T` and `T?`, the only generic shapes that + /// cannot reuse the concrete emission: `bridgeJSLowerParameter()` names + /// per-type members that the generic constraint erases to the stack, so + /// `bridgeJSStackPush()`/`bridgeJSStackPop()` is the shared spelling. + /// `[T]` and `[String: T]` go through the ordinary paths via the `Array` + /// and `Dictionary` stack conformances. + var genericStackPopExpression: String? { + switch self { + case .generic(let name): return "\(name).bridgeJSStackPop()" + case .nullable(.generic(let name), _): return "Optional<\(name)>.bridgeJSStackPop()" + default: return nil + } + } + + func genericStackPushStatement(value: String) -> String? { + switch self { + case .generic, .nullable(.generic, _): + return "\(value).bridgeJSStackPush()" + default: return nil + } + } + var swiftType: String { switch self { case .bool: return "Bool" @@ -1631,6 +1719,7 @@ extension BridgeType { let closureType = "(\(paramTypes))\(effectsStr) -> \(signature.returnType.swiftType)" return useJSTypedClosure ? "JSTypedClosure<\(closureType)>" : closureType case .alias(let name, _): return name + case .generic(let name): return name } } @@ -1717,6 +1806,10 @@ extension BridgeType { return LiftingIntrinsicInfo(parameters: []) case .alias(_, let underlying): return try underlying.liftParameterInfo() + case .generic: + throw BridgeJSCoreError( + "Generic parameters are only supported on imported declarations, not exported concrete-type codegen" + ) } } @@ -1770,6 +1863,10 @@ extension BridgeType { return .array case .alias(_, let underlying): return try underlying.loweringReturnInfo() + case .generic: + throw BridgeJSCoreError( + "Generic parameters are only supported on imported declarations, not exported concrete-type codegen" + ) } } } diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift index 286352915..cff1aa979 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift @@ -143,6 +143,11 @@ public struct ImportTS { } func lowerParameter(param: Parameter) throws { + if let genericPush = param.type.genericStackPushStatement(value: param.name) { + stackLoweringStmts.insert(genericPush, at: 0) + return + } + let loweringInfo = try param.type.loweringParameterInfo(context: context) switch param.type { @@ -237,6 +242,18 @@ public struct ImportTS { abiParameterForwardings.insert(contentsOf: ["resolveRef", "rejectRef"], at: 0) } + private func appendTypeIDParameter(index: Int, genericParameterName: String) { + let abiParamName = ABINameGenerator.genericTypeIdParameterName(index: index) + abiParameterSignatures.append((abiParamName, .i32)) + abiParameterForwardings.append("\(genericParameterName).bridgeJSTypeID") + } + + func appendTypeIDParameters(_ genericParameterNames: [String]) { + for (index, name) in genericParameterNames.enumerated() { + appendTypeIDParameter(index: index, genericParameterName: name) + } + } + func call() throws { for stmt in stackLoweringStmts { body.write(stmt.description) @@ -293,14 +310,18 @@ public struct ImportTS { body.write("return \(returnType.swiftType).bridgeJSLiftReturnFromSideChannel()") } else { let liftExpr: String - switch returnType { - case .closure(let signature, _): - liftExpr = "_BJS_Closure_\(signature.mangleName).bridgeJSLift(ret)" - default: - if liftingInfo.valueToLift != nil { - liftExpr = "\(returnType.swiftType).bridgeJSLiftReturn(ret)" - } else { - liftExpr = "\(returnType.swiftType).bridgeJSLiftReturn()" + if let genericPop = returnType.genericStackPopExpression { + liftExpr = genericPop + } else { + switch returnType { + case .closure(let signature, _): + liftExpr = "_BJS_Closure_\(signature.mangleName).bridgeJSLift(ret)" + default: + if liftingInfo.valueToLift != nil { + liftExpr = "\(returnType.swiftType).bridgeJSLiftReturn(ret)" + } else { + liftExpr = "\(returnType.swiftType).bridgeJSLiftReturn()" + } } } body.write("return \(liftExpr)") @@ -359,7 +380,8 @@ public struct ImportTS { name: String, parameters: [Parameter], returnType: BridgeType, - effects: Effects + effects: Effects, + genericParameters: [String] = [] ) -> DeclSyntax { let printer = CodeFragmentPrinter() let signature = SwiftSignatureBuilder.buildFunctionSignature( @@ -368,7 +390,12 @@ public struct ImportTS { effects: effects, useWildcardLabels: true ) - printer.write("func \(name.backtickIfNeeded())\(signature) {") + let genericClause = + genericParameters.isEmpty + ? "" + : "<" + genericParameters.map { "\($0): BridgedSwiftGenericBridgeable" }.joined(separator: ", ") + + ">" + printer.write("func \(name.backtickIfNeeded())\(genericClause)\(signature) {") printer.indent { printer.write(lines: body.lines) } @@ -428,6 +455,7 @@ public struct ImportTS { for param in function.parameters { try builder.lowerParameter(param: param) } + builder.appendTypeIDParameters(function.genericParameterNames) try builder.call() try builder.liftReturnValue() topLevelDecls.append(builder.renderImportDecl()) @@ -436,7 +464,8 @@ public struct ImportTS { name: Self.thunkName(function: function), parameters: function.parameters, returnType: function.returnType, - effects: function.effects + effects: function.effects, + genericParameters: function.genericParameterNames ) .with(\.leadingTrivia, Self.renderDocumentation(documentation: function.documentation)) ] @@ -457,6 +486,7 @@ public struct ImportTS { for param in method.parameters { try builder.lowerParameter(param: param) } + builder.appendTypeIDParameters(method.genericParameterNames) try builder.call() try builder.liftReturnValue() topLevelDecls.append(builder.renderImportDecl()) @@ -465,7 +495,8 @@ public struct ImportTS { name: Self.thunkName(type: type, method: method), parameters: [selfParameter] + method.parameters, returnType: method.returnType, - effects: method.effects + effects: method.effects, + genericParameters: method.genericParameterNames ) ] } @@ -481,6 +512,7 @@ public struct ImportTS { for param in method.parameters { try builder.lowerParameter(param: param) } + builder.appendTypeIDParameters(method.genericParameterNames) try builder.call() try builder.liftReturnValue() topLevelDecls.append(builder.renderImportDecl()) @@ -489,7 +521,8 @@ public struct ImportTS { name: Self.thunkName(type: type, method: method), parameters: method.parameters, returnType: method.returnType, - effects: method.effects + effects: method.effects, + genericParameters: method.genericParameterNames ) ] } @@ -505,6 +538,7 @@ public struct ImportTS { for param in constructor.parameters { try builder.lowerParameter(param: param) } + builder.appendTypeIDParameters(constructor.genericParameterNames) try builder.call() try builder.liftReturnValue() topLevelDecls.append(builder.renderImportDecl()) @@ -513,7 +547,8 @@ public struct ImportTS { name: Self.thunkName(type: type), parameters: constructor.parameters, returnType: .jsObject(nil), - effects: effects + effects: effects, + genericParameters: constructor.genericParameterNames ) ] } @@ -932,17 +967,20 @@ extension BridgeType { return LoweringParameterInfo(loweredParameters: [("value", wasmType)]) case .associatedValueEnum: return LoweringParameterInfo(loweredParameters: [("caseId", .i32)]) - case .swiftStruct: - // `@JS struct` parameters always use the stack ABI (same as arrays/dictionaries). - return LoweringParameterInfo(loweredParameters: []) case .namespaceEnum: throw BridgeJSCoreError("Namespace enums cannot be used as parameters") case .nullable(let wrappedType, _): let wrappedInfo = try wrappedType.loweringParameterInfo(context: context) + if wrappedInfo.loweredParameters.isEmpty { + return LoweringParameterInfo(loweredParameters: []) + } var params = [("isSome", WasmCoreType.i32)] params.append(contentsOf: wrappedInfo.loweredParameters) return LoweringParameterInfo(loweredParameters: params, useBorrowing: wrappedInfo.useBorrowing) - case .array, .dictionary: + case .swiftStruct: + // `@JS struct` parameters always use the stack ABI (same as arrays/dictionaries). + return LoweringParameterInfo(loweredParameters: []) + case .array, .dictionary, .generic: return LoweringParameterInfo(loweredParameters: []) case .alias: preconditionFailure("`.alias` must be resolved by `.unaliased` before reaching loweringParameterInfo") @@ -995,9 +1033,6 @@ extension BridgeType { return LiftingReturnInfo(valueToLift: wasmType) case .associatedValueEnum: return LiftingReturnInfo(valueToLift: .i32) - case .swiftStruct: - // `@JS struct` returns always use the stack ABI (same as arrays/dictionaries). - return LiftingReturnInfo(valueToLift: nil) case .namespaceEnum: throw BridgeJSCoreError("Namespace enums cannot be used as return values") case .nullable(let wrappedType, _): @@ -1008,7 +1043,10 @@ extension BridgeType { } let wrappedInfo = try wrappedType.liftingReturnInfo(context: context) return LiftingReturnInfo(valueToLift: wrappedInfo.valueToLift) - case .array, .dictionary: + case .swiftStruct: + // `@JS struct` returns always use the stack ABI (same as arrays/dictionaries). + return LiftingReturnInfo(valueToLift: nil) + case .array, .dictionary, .generic: return LiftingReturnInfo(valueToLift: nil) case .alias: preconditionFailure("`.alias` must be resolved by `.unaliased` before reaching liftingReturnInfo") diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/SwiftToSkeleton.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/SwiftToSkeleton.swift index d327de307..937ec5c41 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/SwiftToSkeleton.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/SwiftToSkeleton.swift @@ -7,6 +7,79 @@ import BridgeJSUtilities import BridgeJSSkeleton #endif +/// Outcome of attempting to resolve a type as a reference to a generic parameter. +enum GenericParameterResolution { + case resolved(BridgeType) + /// A non-nil message is a hard diagnostic; `nil` means the type isn't generic + /// and the caller should fall back to normal type resolution. + case rejected(String?) +} + +func resolveGenericTypeReference( + for type: TypeSyntax, + genericParameterNames: [String] +) -> GenericParameterResolution { + if let identifier = type.as(IdentifierTypeSyntax.self), + identifier.genericArgumentClause == nil, + genericParameterNames.contains(identifier.name.text) + { + return .resolved(.generic(identifier.name.text)) + } + if let wrapped = wrappedGenericBridgeType(for: type, genericParameterNames: genericParameterNames) { + return .resolved(wrapped) + } + if !genericParameterNames.isEmpty, + let wrapped = wrappedGenericParameter(in: type, genericParameterNames: genericParameterNames) + { + return .rejected( + "Generic parameter '\(wrapped)' may only be used as a bare type; wrapping it beyond 'T?', '[T]' and '[String: T]' is not supported." + ) + } + return .rejected(nil) +} + +private func wrappedGenericParameter( + in type: TypeSyntax, + genericParameterNames: [String] +) -> String? { + for token in type.tokens(viewMode: .sourceAccurate) { + if case .identifier(let text) = token.tokenKind, genericParameterNames.contains(text) { + return text + } + } + return nil +} + +private func wrappedGenericBridgeType( + for type: TypeSyntax, + genericParameterNames: [String] +) -> BridgeType? { + func bareGenericName(_ inner: TypeSyntax) -> String? { + guard let identifier = inner.as(IdentifierTypeSyntax.self), + identifier.genericArgumentClause == nil, + genericParameterNames.contains(identifier.name.text) + else { + return nil + } + return identifier.name.text + } + if let arrayType = type.as(ArrayTypeSyntax.self), let name = bareGenericName(arrayType.element) { + return .array(.generic(name)) + } + if let optionalType = type.as(OptionalTypeSyntax.self), let name = bareGenericName(optionalType.wrappedType) { + return .nullable(.generic(name), .null) + } + if let dictType = type.as(DictionaryTypeSyntax.self), + let keyIdentifier = dictType.key.as(IdentifierTypeSyntax.self), + keyIdentifier.genericArgumentClause == nil, + keyIdentifier.name.text == "String", + let name = bareGenericName(dictType.value) + { + return .dictionary(.generic(name)) + } + return nil +} + /// Builds BridgeJS skeletons from Swift source files using SwiftSyntax walk for API collection. /// /// This is a shared entry point for producing: @@ -149,15 +222,14 @@ public final class SwiftToSkeleton { validatedJavaScriptModulePaths.insert(path) } - let exportErrors = exportCollector.errors.filter { $0.severity == .error } let importErrorsFatal = importCollector.errors.filter { $0.severity == .error && !$0.message.contains("Unsupported type '") } - let fileWarnings = (exportCollector.errors + importCollector.errors).filter { $0.severity == .warning } + let fileWarnings = importCollector.errors.filter { $0.severity == .warning } warnings.append(contentsOf: fileWarnings.map { (file: inputFilePath, diagnostic: $0) }) - if !exportErrors.isEmpty || !importErrorsFatal.isEmpty { + if !importErrorsFatal.isEmpty { perSourceErrors.append( - (inputFilePath: inputFilePath, errors: exportErrors + importErrorsFatal) + (inputFilePath: inputFilePath, errors: importErrorsFatal) ) } @@ -176,6 +248,18 @@ public final class SwiftToSkeleton { source.resolveDeferredExtensions(against: exportCollectors) } + // We have to collect diagnostics after all deferred extensions are resolved, since they could generate some. + for ((_, inputFilePath), exportCollector) in zip(sourceFiles, exportCollectors) { + let exportErrors = exportCollector.errors.filter { $0.severity == .error } + let fileWarnings = exportCollector.errors.filter { $0.severity == .warning } + warnings.append(contentsOf: fileWarnings.map { (file: inputFilePath, diagnostic: $0) }) + if !exportErrors.isEmpty { + perSourceErrors.append( + (inputFilePath: inputFilePath, errors: exportErrors) + ) + } + } + for collector in exportCollectors { collector.finalize(&exported) } @@ -731,6 +815,28 @@ public final class SwiftToSkeleton { return String(name.dropFirst().dropLast()) } + fileprivate static func isValidJSIdentifier(_ name: String) -> Bool { + func isIdentifierPart(_ scalar: Unicode.Scalar, isStart: Bool) -> Bool { + switch scalar { + case "a"..."z", "A"..."Z", "_", "$": + return true + case "0"..."9": + return !isStart + default: + return false + } + } + guard let first = name.unicodeScalars.first, isIdentifierPart(first, isStart: true) else { + return false + } + return name.unicodeScalars.dropFirst().allSatisfy { isIdentifierPart($0, isStart: false) } + } + + fileprivate static func isBridgeableGenericConstraint(_ constraint: String?) -> Bool { + constraint == "BridgedSwiftGenericBridgeable" + || constraint == "JavaScriptKit.BridgedSwiftGenericBridgeable" + } + } private enum ExportSwiftConstants { @@ -763,6 +869,17 @@ extension AttributeListSyntax { } } +private final class JSAttributeFinder: SyntaxVisitor { + private(set) var found = false + + override func visit(_ node: AttributeSyntax) -> SyntaxVisitorContinueKind { + if node.attributeNameText == "JS" { + found = true + } + return .skipChildren + } +} + private final class ExportSwiftAPICollector: SyntaxAnyVisitor { var exportedFunctions: [ExportedFunction] = [] /// The names of the exported classes, in the order they were written in the source file @@ -1202,10 +1319,6 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { diagnoseNestedOptional(node: param.type, type: param.type.trimmedDescription) continue } - if case .nullable(let wrappedType, _) = type, wrappedType.isOptional { - diagnoseNestedOptional(node: param.type, type: param.type.trimmedDescription) - continue - } let name = param.secondName?.text ?? param.firstName.text let label = param.firstName.text @@ -1290,7 +1403,17 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { return nil } + if let genericClause = node.genericParameterClause, let firstGenericParam = genericClause.parameters.first { + diagnose( + node: firstGenericParam, + message: + "Generic parameters on exported @JS functions are not supported yet. Generic functions are currently only supported on imported @JSFunction declarations." + ) + return nil + } + let name = node.name.text + let jsName = extractValidatedJSName(from: jsAttribute) let attributeNamespace = extractNamespace(from: jsAttribute) let computedNamespace = computeNamespace(for: node) @@ -1378,7 +1501,7 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { classNameForABI = nil } abiName = ABINameGenerator.generateABIName( - baseName: name, + baseName: jsName ?? name, namespace: finalNamespace, staticContext: isStatic ? staticContext : nil, className: classNameForABI @@ -1390,6 +1513,7 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { return ExportedFunction( name: name, + jsName: jsName, abiName: abiName, parameters: parameters, returnType: returnType, @@ -1469,6 +1593,45 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { return Effects(isAsync: isAsync, isThrows: isThrows, isStatic: isStatic) } + private func extractJSName( + from jsAttribute: AttributeSyntax + ) -> String? { + guard let arguments = jsAttribute.arguments?.as(LabeledExprListSyntax.self), + let nameArg = arguments.first, + nameArg.label == nil, + let stringLiteral = nameArg.expression.as(StringLiteralExprSyntax.self), + stringLiteral.segments.count == 1, + let name = stringLiteral.segments.first?.as(StringSegmentSyntax.self)?.content.text + else { + return nil + } + return name + } + + private func extractValidatedJSName( + from jsAttribute: AttributeSyntax + ) -> String? { + guard let jsName = extractJSName(from: jsAttribute) else { return nil } + guard SwiftToSkeleton.isValidJSIdentifier(jsName) else { + diagnose( + node: jsAttribute, + message: "`\(jsName)` is not a valid JavaScript identifier" + ) + return nil + } + return jsName + } + + private func diagnoseUnsupportedJSName( + from jsAttribute: AttributeSyntax + ) { + guard extractJSName(from: jsAttribute) != nil else { return } + diagnose( + node: jsAttribute, + message: "A separate name for JavaScript is not supported here" + ) + } + private func extractNamespace( from jsAttribute: AttributeSyntax ) -> [String]? { @@ -1515,6 +1678,8 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { override func visit(_ node: InitializerDeclSyntax) -> SyntaxVisitorContinueKind { guard let jsAttribute = node.attributes.firstJSAttribute else { return .skipChildren } + diagnoseUnsupportedJSName(from: jsAttribute) + switch state { case .classBody(_, let classKey): if extractNamespace(from: jsAttribute) != nil { @@ -1636,6 +1801,15 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { } } + let jsName = extractValidatedJSName(from: jsAttribute) + if jsName != nil, node.bindings.count > 1 { + diagnose( + node: jsAttribute, + message: "Name targets declaration with multiple bindings", + hint: "Declare each property with a different JS name separately" + ) + } + // Process each binding (variable declaration) for binding in node.bindings { guard let pattern = binding.pattern.as(IdentifierPatternSyntax.self) else { @@ -1663,6 +1837,7 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { let exportedProperty = ExportedProperty( name: propertyName, + jsName: jsName, type: propertyType, isReadonly: isReadonly, isStatic: isStatic, @@ -1693,6 +1868,8 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { return .skipChildren } + diagnoseUnsupportedJSName(from: jsAttribute) + if let aliasTarget = parent.extractAliasTarget(from: jsAttribute) { recordAlias(node: node, jsAttribute: jsAttribute, aliasTarget: aliasTarget) return .skipChildren @@ -1712,6 +1889,7 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { message: "Class visibility must be at least internal" ) let classIdentityMode = extractIdentityMode(from: jsAttribute) + let isFinal = node.modifiers.contains { $0.name.tokenKind == .keyword(.final) } ? true : nil let exportedClass = ExportedClass( name: name, swiftCallName: swiftCallName, @@ -1721,7 +1899,8 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { properties: [], namespace: effectiveNamespace, identityMode: classIdentityMode, - documentation: extractDocumentation(from: node) + documentation: extractDocumentation(from: node), + isFinal: isFinal ) let uniqueKey = makeKey(name: name, namespace: effectiveNamespace) @@ -1753,7 +1932,7 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { break } } - if !resolved { + if !resolved, containsJSAnnotatedDeclaration(ext.memberBlock.members) { diagnose( node: ext.extendedType, message: "Unsupported type '\(ext.extendedType.trimmedDescription)'.", @@ -1763,6 +1942,12 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { } } + private func containsJSAnnotatedDeclaration(_ members: MemberBlockItemListSyntax) -> Bool { + let finder = JSAttributeFinder(viewMode: .sourceAccurate) + finder.walk(members) + return finder.found + } + /// Walks extension members under the matching type’s state, returning whether the type was found. /// /// Note: The lookup scans dictionaries keyed by `makeKey(name:namespace:)`, matching only by @@ -1843,6 +2028,8 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { return .skipChildren } + diagnoseUnsupportedJSName(from: jsAttribute) + if let aliasTarget = parent.extractAliasTarget(from: jsAttribute) { recordAlias(node: node, jsAttribute: jsAttribute, aliasTarget: aliasTarget) return .skipChildren @@ -1968,6 +2155,8 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { return .skipChildren } + diagnoseUnsupportedJSName(from: jsAttribute) + let name = node.name.text let namespaceResult = resolveNamespace(from: jsAttribute, for: node, declarationType: "protocol") @@ -2031,6 +2220,8 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { return .skipChildren } + diagnoseUnsupportedJSName(from: jsAttribute) + if let aliasTarget = parent.extractAliasTarget(from: jsAttribute) { recordAlias(node: node, jsAttribute: jsAttribute, aliasTarget: aliasTarget) return .skipChildren @@ -2169,6 +2360,10 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { protocolName: String, namespace: [String]? ) -> ExportedFunction? { + if let jsAttribute = node.attributes.firstJSAttribute { + diagnoseUnsupportedJSName(from: jsAttribute) + } + let name = node.name.text let parameters = parseParameters(from: node.signature.parameterClause, allowDefaults: false) @@ -2215,6 +2410,10 @@ private final class ExportSwiftAPICollector: SyntaxAnyVisitor { protocolName: String, protocolKey: String ) -> SyntaxVisitorContinueKind { + if let jsAttribute = node.attributes.firstJSAttribute { + diagnoseUnsupportedJSName(from: jsAttribute) + } + for binding in node.bindings { guard let pattern = binding.pattern.as(IdentifierPatternSyntax.self) else { diagnose(node: binding.pattern, message: "Complex patterns not supported for protocol properties") @@ -3118,24 +3317,101 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor { // MARK: - Parsing Methods + /// Validates and collects the generic parameter names of an imported + /// `@JSFunction` declaration (function, method or initializer). + /// + /// Returns `nil` when a diagnostic was emitted; an empty array when the + /// declaration is not generic. + private func parseGenericParameterNames( + genericParameterClause: GenericParameterClauseSyntax?, + genericWhereClause: GenericWhereClauseSyntax?, + node: Syntax + ) -> [String]? { + var genericParameterNames: [String] = [] + if let genericParameterClause { + for genericParam in genericParameterClause.parameters { + let paramName = genericParam.name.text + let constraintText = genericParam.inheritedType?.trimmedDescription + guard SwiftToSkeleton.isBridgeableGenericConstraint(constraintText) else { + errors.append( + DiagnosticError( + node: Syntax(genericParam), + message: + "Generic parameter '\(paramName)' must be constrained to 'BridgedSwiftGenericBridgeable' to be used with @JSFunction." + ) + ) + return nil + } + genericParameterNames.append(paramName) + } + } + if genericWhereClause != nil { + errors.append( + DiagnosticError( + node: node, + message: "'where' clauses are not supported on @JSFunction declarations." + ) + ) + return nil + } + return genericParameterNames + } + private func parseConstructor( _ initializer: InitializerDeclSyntax, typeName: String ) -> ImportedConstructorSkeleton? { guard - validateEffects(initializer.signature.effectSpecifiers, node: initializer, attributeName: "JSFunction") - != nil + let effects = validateEffects( + initializer.signature.effectSpecifiers, + node: initializer, + attributeName: "JSFunction" + ) + else { + return nil + } + guard + let genericParameterNames = parseGenericParameterNames( + genericParameterClause: initializer.genericParameterClause, + genericWhereClause: initializer.genericWhereClause, + node: Syntax(initializer) + ) else { return nil } + if !genericParameterNames.isEmpty && effects.isAsync { + errors.append( + DiagnosticError( + node: Syntax(initializer), + message: "Generic @JSFunction declarations cannot be 'async' yet." + ) + ) + return nil + } + let parameters = parseParameters( + from: initializer.signature.parameterClause, + genericParameterNames: genericParameterNames + ) + for genericName in genericParameterNames + where !parameters.contains(where: { $0.type.referencedGenericName == genericName }) { + errors.append( + DiagnosticError( + node: Syntax(initializer), + message: + "The generic parameter '\(genericName)' must be used in a parameter of a generic @JSFunction initializer." + ) + ) + return nil + } // Initializers without an explicit modifier inherit access from the // enclosing `@JSClass` (the user's example pattern: `public init(...)` // inside `public struct JSDocument`). let parentLevel = currentType?.accessLevel ?? .internal let accessLevel = Self.bridgeAccessLevel(from: initializer.modifiers, default: parentLevel) return ImportedConstructorSkeleton( - parameters: parseParameters(from: initializer.signature.parameterClause), - accessLevel: accessLevel + parameters: parameters, + accessLevel: accessLevel, + genericParameters: genericParameterNames.isEmpty ? nil : genericParameterNames ) } @@ -3153,6 +3429,16 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor { return nil } + guard + let genericParameterNames = parseGenericParameterNames( + genericParameterClause: node.genericParameterClause, + genericWhereClause: node.genericWhereClause, + node: Syntax(node) + ) + else { + return nil + } + let baseName = SwiftToSkeleton.normalizeIdentifier(node.name.text) let extractedJSName = extractJSName(from: jsFunction) let from = extractJSImportFrom(from: jsFunction) @@ -3160,16 +3446,51 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor { let jsName = extractedJSName?.memberName let name = baseName - let parameters = parseParameters(from: node.signature.parameterClause) + let parameters = parseParameters( + from: node.signature.parameterClause, + genericParameterNames: genericParameterNames + ) let returnType: BridgeType if let returnTypeSyntax = node.signature.returnClause?.type { - guard let resolved = withLookupErrors({ parent.lookupType(for: returnTypeSyntax, errors: &$0) }) else { + guard + let resolved = lookupTypeWithGenerics( + for: returnTypeSyntax, + genericParameterNames: genericParameterNames + ) + else { return nil } returnType = resolved } else { returnType = .void } + + if !genericParameterNames.isEmpty { + if effects.isAsync { + errors.append( + DiagnosticError( + node: node, + message: "Generic @JSFunction declarations cannot be 'async' yet." + ) + ) + return nil + } + for genericName in genericParameterNames { + let usedInParameter = parameters.contains { $0.type.referencedGenericName == genericName } + let usedInReturn = returnType.referencedGenericName == genericName + if !usedInParameter && !usedInReturn { + errors.append( + DiagnosticError( + node: node, + message: + "The generic parameter '\(genericName)' must be used in a parameter or return type of a generic @JSFunction declaration." + ) + ) + return nil + } + } + } + let accessLevel = Self.bridgeAccessLevel(from: node.modifiers) return ImportedFunctionSkeleton( name: name, @@ -3179,7 +3500,8 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor { returnType: returnType, effects: effects, documentation: nil, - accessLevel: accessLevel + accessLevel: accessLevel, + genericParameters: genericParameterNames.isEmpty ? nil : genericParameterNames ) } @@ -3256,7 +3578,26 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor { // MARK: - Type and Parameter Parsing - private func parseParameters(from clause: FunctionParameterClauseSyntax) -> [Parameter] { + private func lookupTypeWithGenerics( + for type: TypeSyntax, + genericParameterNames: [String] + ) -> BridgeType? { + switch resolveGenericTypeReference(for: type, genericParameterNames: genericParameterNames) { + case .resolved(let bridgeType): + return bridgeType + case .rejected(let message): + if let message { + errors.append(DiagnosticError(node: Syntax(type), message: message)) + return nil + } + return withLookupErrors { parent.lookupType(for: type, errors: &$0) } + } + } + + private func parseParameters( + from clause: FunctionParameterClauseSyntax, + genericParameterNames: [String] = [] + ) -> [Parameter] { clause.parameters.compactMap { param in let type = param.type if type.is(MissingTypeSyntax.self) { @@ -3268,7 +3609,8 @@ private final class ImportSwiftMacrosAPICollector: SyntaxAnyVisitor { ) return nil } - guard let bridgeType = withLookupErrors({ parent.lookupType(for: type, errors: &$0) }) else { + guard let bridgeType = lookupTypeWithGenerics(for: type, genericParameterNames: genericParameterNames) + else { return nil } let nameToken = param.secondName ?? param.firstName diff --git a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift index 1b6300595..8b46af1b4 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift @@ -31,6 +31,10 @@ public struct BridgeJSLink { skeletons.compactMap(\.exported).compactMap(\.identityMode).first ?? "none" } + var hasGenerics: Bool { + skeletons.contains { $0.imported?.hasGenericDeclarations ?? false } + } + /// Whether a class should use identity caching based on its annotation and the config default. private func shouldUseIdentityCache(for klass: ExportedClass) -> Bool { // Per-class annotation takes priority @@ -235,7 +239,7 @@ public struct BridgeJSLink { for function in skeleton.functions { if function.namespace == nil { var (js, dts) = try renderExportedFunction(function: function) - js[0] = "\(function.name): " + js[0] + js[0] = "\(function.resolvedJSName): " + js[0] js[js.count - 1] += "," data.exportsLines.append(contentsOf: js) data.dtsExportLines.append(contentsOf: dts) @@ -311,7 +315,7 @@ public struct BridgeJSLink { } private func generateVariableDeclarations() -> [String] { - return [ + var declarations: [String] = [ "let \(JSGlueVariableScope.reservedInstance);", "let \(JSGlueVariableScope.reservedMemory);", "let \(JSGlueVariableScope.reservedSetException);", @@ -335,10 +339,32 @@ public struct BridgeJSLink { "let \(JSGlueVariableScope.reservedTaStack) = [];", "const \(JSGlueVariableScope.reservedEnumHelpers) = {};", "const \(JSGlueVariableScope.reservedStructHelpers) = {};", + ] + if hasGenerics { + declarations.append("const \(JSGlueVariableScope.reservedCodecByTypeId) = new Map();") + declarations.append("let __bjs_typeHandlesRegistered = false;") + declarations.append("function __bjs_registerTypeHandles() {") + declarations.append(" if (__bjs_typeHandlesRegistered) {") + declarations.append(" return;") + declarations.append(" }") + declarations.append(" __bjs_typeHandlesRegistered = true;") + declarations.append( + " \(JSGlueVariableScope.reservedInstance).exports[\"\(ABINameGenerator.coreTypeRegistrationFunctionName)\"]();" + ) + for skeleton in skeletons { + guard skeleton.typeRegistrationEntries != nil else { continue } + let name = ABINameGenerator.typeRegistrationFunctionName(moduleName: skeleton.moduleName) + declarations.append(" \(JSGlueVariableScope.reservedInstance).exports[\"\(name)\"]();") + } + declarations.append("}") + declarations.append(contentsOf: GenericJSCodegen.runtimeHelperDeclarations()) + } + declarations.append(contentsOf: [ "", "let _exports = null;", "let bjs = null;", - ] + ]) + return declarations } /// JS const (in the import glue scope) holding the `Symbol` under which a promise's @@ -375,9 +401,83 @@ public struct BridgeJSLink { printer.write(lines: lines) } + private func makeCodecPrintContext(printer: CodeFragmentPrinter) -> IntrinsicJSFragment.PrintCodeContext { + IntrinsicJSFragment.PrintCodeContext( + scope: JSGlueVariableScope(intrinsicRegistry: intrinsicRegistry), + printer: printer, + hasDirectAccessToSwiftClass: false, + classNamespaces: intrinsicRegistry.classNamespaces + ) + } + + private func genericCodecReference(type: BridgeType, into printer: CodeFragmentPrinter) throws -> String { + try ContainerCodecJS.codecExpression(for: type, context: makeCodecPrintContext(printer: printer)) + } + + private func writeTypeHandleRegistrationBody(into printer: CodeFragmentPrinter) { + printer.write( + "const typeIds = new Int32Array(\(JSGlueVariableScope.reservedMemory).buffer, base >>> 0, count >>> 0);" + ) + printer.write("for (let i = 0; i < count; i++) {") + printer.indent { + printer.write("\(JSGlueVariableScope.reservedCodecByTypeId).set(typeIds[i], codecs[i]);") + } + printer.write("}") + } + + private func generateCoreTypeRegistrationHook(into printer: CodeFragmentPrinter) throws { + let hookName = ABINameGenerator.coreTypeRegistrationFunctionName + guard hasGenerics else { + printer.write("bjs[\"\(hookName)\"] = function() {};") + return + } + try ContainerCodecJS.registerPrimitiveCodecs(context: makeCodecPrintContext(printer: printer)) + printer.write("bjs[\"\(hookName)\"] = function(base, count) {") + printer.indent { + printer.write("const codecs = [") + printer.indent { + for primitive in BridgeType.genericBridgeablePrimitives { + printer.write("\(JSGlueVariableScope.reservedPrimitiveCodecs).\(primitive.token),") + } + } + printer.write("];") + writeTypeHandleRegistrationBody(into: printer) + } + printer.write("}") + } + + private func generateTypeRegistrationHooks(into printer: CodeFragmentPrinter) throws { + try generateCoreTypeRegistrationHook(into: printer) + for skeleton in skeletons { + guard let moduleEntries = skeleton.typeRegistrationEntries else { continue } + let hookName = ABINameGenerator.typeRegistrationFunctionName(moduleName: skeleton.moduleName) + guard hasGenerics else { + printer.write("bjs[\"\(hookName)\"] = function() {};") + continue + } + printer.write("bjs[\"\(hookName)\"] = function(base, count) {") + try printer.indent { + let codecNames = try moduleEntries.map { + try genericCodecReference(type: $0.bridgeType, into: printer) + } + printer.write("const codecs = [") + printer.indent { + for name in codecNames { + printer.write("\(name),") + } + } + printer.write("];") + writeTypeHandleRegistrationBody(into: printer) + } + printer.write("}") + } + } + private func generateAddImports(needsImportsObject: Bool) throws -> CodeFragmentPrinter { let printer = CodeFragmentPrinter() - let allStructs = skeletons.compactMap { $0.exported?.structs }.flatMap { $0 } + let allStructs = skeletons.flatMap { unified in + (unified.exported?.structs ?? []).map { (moduleName: unified.moduleName, structDef: $0) } + } printer.write("return {") try printer.indent { printer.write(lines: [ @@ -525,11 +625,12 @@ public struct BridgeJSLink { } printer.write("}") if !allStructs.isEmpty { - for structDef in allStructs { + for (moduleName, structDef) in allStructs { + let key = HelperNaming.type(module: moduleName, swiftName: structDef.swiftCallName) printer.write("bjs[\"swift_js_struct_lower_\(structDef.abiName)\"] = function(objectId) {") printer.indent { printer.write( - "\(JSGlueVariableScope.reservedStructHelpers).\(structDef.abiName).lower(\(JSGlueVariableScope.reservedSwift).memory.getObject(objectId));" + "\(JSGlueVariableScope.reservedStructHelpers).\(key).lower(\(JSGlueVariableScope.reservedSwift).memory.getObject(objectId));" ) } printer.write("}") @@ -537,13 +638,14 @@ public struct BridgeJSLink { printer.write("bjs[\"swift_js_struct_lift_\(structDef.abiName)\"] = function() {") printer.indent { printer.write( - "const value = \(JSGlueVariableScope.reservedStructHelpers).\(structDef.abiName).lift();" + "const value = \(JSGlueVariableScope.reservedStructHelpers).\(key).lift();" ) printer.write("return \(JSGlueVariableScope.reservedSwift).memory.retain(value);") } printer.write("}") } } + try generateTypeRegistrationHooks(into: printer) // Always provided: the runtime's `_bjs_makePromise` imports it unconditionally. // The settlers are stored under a Symbol to avoid clashing with promise fields. @@ -973,13 +1075,15 @@ public struct BridgeJSLink { ) ) printer.write( - "\(function.name)\(renderTSSignature(parameters: function.parameters, returnType: function.returnType, effects: function.effects));" + "\(function.resolvedJSName)\(renderTSSignature(parameters: function.parameters, returnType: function.returnType, effects: function.effects));" ) } for property in enumDefinition.staticProperties { let readonly = property.isReadonly ? "readonly " : "" printer.write(lines: renderJSDoc(documentation: property.documentation, parameters: [])) - printer.write("\(readonly)\(property.name): \(resolveTypeScriptType(property.type));") + printer.write( + "\(readonly)\(property.resolvedJSName): \(resolveTypeScriptType(property.type));" + ) } } printer.write("};") @@ -1023,15 +1127,15 @@ public struct BridgeJSLink { self.renderExportedStructExportEntry(structDef) }, renderFunctionEntry: { function in - self.renderJSDoc(documentation: function.documentation, parameters: function.parameters) + return self.renderJSDoc(documentation: function.documentation, parameters: function.parameters) + [ - "\(function.name)\(self.renderTSSignature(parameters: function.parameters, returnType: function.returnType, effects: function.effects));" + "\(function.resolvedJSName)\(self.renderTSSignature(parameters: function.parameters, returnType: function.returnType, effects: function.effects));" ] }, renderPropertyEntry: { property in let readonly = property.isReadonly ? "readonly " : "" return self.renderJSDoc(documentation: property.documentation, parameters: []) - + ["\(readonly)\(property.name): \(property.type.tsType);"] + + ["\(readonly)\(property.resolvedJSName): \(property.type.tsType);"] } ) printer.write("export type Exports = {") @@ -1107,12 +1211,18 @@ public struct BridgeJSLink { let bodyPrinter = CodeFragmentPrinter() let allStructs = exportedSkeletons.flatMap { $0.structs } - for structDef in allStructs { + for (moduleName, structDef) in skeletons.flatMap({ unified in + (unified.exported?.structs ?? []).map { (unified.moduleName, $0) } + }) { let structPrinter = CodeFragmentPrinter() let structScope = JSGlueVariableScope(intrinsicRegistry: intrinsicRegistry) - let fragment = IntrinsicJSFragment.structHelper(structDefinition: structDef, allStructs: allStructs) + let fragment = IntrinsicJSFragment.structHelper( + structDefinition: structDef, + allStructs: allStructs, + moduleName: moduleName + ) _ = try fragment.printCode( - [structDef.abiName], + [], IntrinsicJSFragment.PrintCodeContext( scope: structScope, printer: structPrinter, @@ -1123,13 +1233,16 @@ public struct BridgeJSLink { bodyPrinter.write(lines: structPrinter.lines) } - let allAssocEnums = exportedSkeletons.flatMap { - $0.enums.filter { $0.enumType == .associatedValue } - } - for enumDef in allAssocEnums { + for (moduleName, enumDef) in skeletons.flatMap({ unified in + (unified.exported?.enums ?? []).filter { $0.enumType == .associatedValue } + .map { (unified.moduleName, $0) } + }) { let enumPrinter = CodeFragmentPrinter() let enumScope = JSGlueVariableScope(intrinsicRegistry: intrinsicRegistry) - let fragment = IntrinsicJSFragment.associatedValueEnumHelperFactory(enumDefinition: enumDef) + let fragment = IntrinsicJSFragment.associatedValueEnumHelperFactory( + enumDefinition: enumDef, + moduleName: moduleName + ) _ = try fragment.printCode( [enumDef.valuesName], IntrinsicJSFragment.PrintCodeContext( @@ -1149,6 +1262,11 @@ public struct BridgeJSLink { printer.nextLine() } + if intrinsicRegistry.hasNamedCodecs { + printer.write(lines: intrinsicRegistry.emitNamedCodecLines()) + printer.nextLine() + } + printer.write(lines: bodyPrinter.lines) } printer.indent() @@ -1239,21 +1357,55 @@ public struct BridgeJSLink { } } } + intrinsicRegistry.typeOwnerModules = collectTypeOwnerModules() let data = try collectLinkData() let outputJs = try generateJavaScript(data: data) let outputDts = generateTypeScript(data: data) return (outputJs, outputDts) } + private func collectTypeOwnerModules() -> [String: String] { + var result: [String: String] = [:] + func record(_ name: String, _ moduleName: String) { + if result[name] == nil { + result[name] = moduleName + } + } + for unified in skeletons { + let moduleName = unified.moduleName + if let skeleton = unified.exported { + for structDef in skeleton.structs { + record(structDef.name, moduleName) + record(structDef.abiName, moduleName) + record(structDef.swiftCallName, moduleName) + } + for klass in skeleton.classes { + record(klass.name, moduleName) + record(klass.abiName, moduleName) + } + for enumDef in skeleton.enums { + record(enumDef.name, moduleName) + record(enumDef.abiName, moduleName) + record(enumDef.swiftCallName, moduleName) + } + for protocolDef in skeleton.protocols { + record(protocolDef.name, moduleName) + } + } + } + return result + } + private func enumHelperAssignments() -> CodeFragmentPrinter { let printer = CodeFragmentPrinter() - for skeleton in skeletons.compactMap(\.exported) { + for unified in skeletons { + guard let skeleton = unified.exported else { continue } for enumDef in skeleton.enums where enumDef.enumType == .associatedValue { - printer.write( - "const \(enumDef.name)Helpers = __bjs_create\(enumDef.valuesName)Helpers();" - ) - printer.write("\(JSGlueVariableScope.reservedEnumHelpers).\(enumDef.name) = \(enumDef.name)Helpers;") + let key = HelperNaming.type(module: unified.moduleName, swiftName: enumDef.swiftCallName) + let local = HelperNaming.helperConstant(key) + printer.write("const \(local) = \(HelperNaming.enumHelperFactory(key))();") + printer.write("\(JSGlueVariableScope.reservedEnumHelpers).\(key) = \(local);") printer.nextLine() } } @@ -1264,14 +1416,13 @@ public struct BridgeJSLink { private func structHelperAssignments() -> CodeFragmentPrinter { let printer = CodeFragmentPrinter() - for skeleton in skeletons.compactMap(\.exported) { + for unified in skeletons { + guard let skeleton = unified.exported else { continue } for structDef in skeleton.structs { - printer.write( - "const \(structDef.abiName)Helpers = __bjs_create\(structDef.abiName)Helpers();" - ) - printer.write( - "\(JSGlueVariableScope.reservedStructHelpers).\(structDef.abiName) = \(structDef.abiName)Helpers;" - ) + let key = HelperNaming.type(module: unified.moduleName, swiftName: structDef.swiftCallName) + let local = HelperNaming.helperConstant(key) + printer.write("const \(local) = \(HelperNaming.structHelperFactory(key))();") + printer.write("\(JSGlueVariableScope.reservedStructHelpers).\(key) = \(local);") printer.nextLine() } } @@ -1370,18 +1521,19 @@ public struct BridgeJSLink { // Add methods for method in type.methods { - let methodName = method.jsName ?? method.name + let methodName = method.resolvedJSName + let genericClause = renderGenericClause(method.genericParameterNames) let methodSignature = - "\(renderTSPropertyName(methodName))\(renderTSSignature(parameters: method.parameters, returnType: method.returnType, effects: method.effects));" + "\(renderTSPropertyName(methodName))\(genericClause)\(renderTSSignature(parameters: method.parameters, returnType: method.returnType, effects: method.effects));" printer.write(methodSignature) } // Add properties from getters var propertyNames = Set() for getter in type.getters { - let propertyName = getter.jsName ?? getter.name + let propertyName = getter.resolvedJSName propertyNames.insert(propertyName) - let hasSetter = type.setters.contains { ($0.jsName ?? $0.name) == propertyName } + let hasSetter = type.setters.contains { $0.resolvedJSName == propertyName } let propertySignature = hasSetter ? "\(renderTSPropertyName(propertyName)): \(resolveTypeScriptType(getter.type));" @@ -1390,7 +1542,7 @@ public struct BridgeJSLink { } // Add setters that don't have corresponding getters for setter in type.setters { - let propertyName = setter.jsName ?? setter.name + let propertyName = setter.resolvedJSName guard !propertyNames.contains(propertyName) else { continue } printer.write("\(renderTSPropertyName(propertyName)): \(resolveTypeScriptType(setter.type));") } @@ -1587,6 +1739,10 @@ public struct BridgeJSLink { return "(\(parameterSignatures.joined(separator: ", "))): \(returnTypeWithEffect)" } + private func renderGenericClause(_ genericParameterNames: [String]) -> String { + genericParameterNames.isEmpty ? "" : "<\(genericParameterNames.joined(separator: ", "))>" + } + private func renderTSPropertyName(_ name: String) -> String { // TypeScript allows quoted property names for keys that aren't valid identifiers. if name.range(of: #"^[$A-Z_][0-9A-Z_$]*$"#, options: [.regularExpression, .caseInsensitive]) != nil { @@ -1628,7 +1784,7 @@ public struct BridgeJSLink { returnType: method.returnType, effects: method.effects ) - dtsTypePrinter.write("\(method.name)\(signature);") + dtsTypePrinter.write("\(method.resolvedJSName)\(signature);") } } dtsTypePrinter.write("}") @@ -1649,13 +1805,15 @@ public struct BridgeJSLink { for property in structDefinition.properties where property.isStatic { let readonly = property.isReadonly ? "readonly " : "" dtsExportEntryPrinter.write(lines: renderJSDoc(documentation: property.documentation, parameters: [])) - dtsExportEntryPrinter.write("\(readonly)\(property.name): \(resolveTypeScriptType(property.type));") + dtsExportEntryPrinter.write( + "\(readonly)\(property.resolvedJSName): \(resolveTypeScriptType(property.type));" + ) } for method in structDefinition.methods where method.effects.isStatic { let jsDocLines = renderJSDoc(documentation: method.documentation, parameters: method.parameters) dtsExportEntryPrinter.write(lines: jsDocLines) dtsExportEntryPrinter.write( - "\(method.name)\(renderTSSignature(parameters: method.parameters, returnType: method.returnType, effects: method.effects));" + "\(method.resolvedJSName)\(renderTSSignature(parameters: method.parameters, returnType: method.returnType, effects: method.effects));" ) } @@ -1914,7 +2072,7 @@ extension BridgeJSLink { dtsLines.append(contentsOf: renderJSDoc(documentation: function.documentation, parameters: function.parameters)) dtsLines.append( - "\(function.name)\(renderTSSignature(parameters: function.parameters, returnType: function.returnType, effects: function.effects));" + "\(function.resolvedJSName)\(renderTSSignature(parameters: function.parameters, returnType: function.returnType, effects: function.effects));" ) return (funcLines, dtsLines) @@ -1955,7 +2113,7 @@ extension BridgeJSLink { let returnExpr = try thunkBuilder.call(abiName: function.abiName, returnType: function.returnType) let funcLines = thunkBuilder.renderFunction( - name: function.name, + name: function.resolvedJSName, parameters: function.parameters, returnExpr: returnExpr, declarationPrefixKeyword: "static" @@ -1966,7 +2124,7 @@ extension BridgeJSLink { dtsLines.append(contentsOf: renderJSDoc(documentation: function.documentation, parameters: function.parameters)) dtsLines.append( - "static \(function.name)\(renderTSSignature(parameters: function.parameters, returnType: function.returnType, effects: function.effects));" + "static \(function.resolvedJSName)\(renderTSSignature(parameters: function.parameters, returnType: function.returnType, effects: function.effects));" ) return (funcLines, dtsLines) @@ -1986,7 +2144,7 @@ extension BridgeJSLink { let returnExpr = try thunkBuilder.call(abiName: function.abiName, returnType: function.returnType) let printer = CodeFragmentPrinter() - printer.write("\(function.name)(\(DefaultValueUtils.formatParameterList(function.parameters))) {") + printer.write("\(function.resolvedJSName)(\(DefaultValueUtils.formatParameterList(function.parameters))) {") printer.indent { thunkBuilder.renderFunctionBody(into: printer, returnExpr: returnExpr) } @@ -1997,7 +2155,7 @@ extension BridgeJSLink { dtsLines.append(contentsOf: renderJSDoc(documentation: function.documentation, parameters: function.parameters)) dtsLines.append( - "\(function.name)\(renderTSSignature(parameters: function.parameters, returnType: function.returnType, effects: function.effects));" + "\(function.resolvedJSName)\(renderTSSignature(parameters: function.parameters, returnType: function.returnType, effects: function.effects));" ) return (printer.lines, dtsLines) @@ -2043,7 +2201,7 @@ extension BridgeJSLink { let methodPrinter = CodeFragmentPrinter() methodPrinter.write( - "\(method.name): function(\(DefaultValueUtils.formatParameterList(method.parameters))) {" + "\(method.resolvedJSName): function(\(DefaultValueUtils.formatParameterList(method.parameters))) {" ) methodPrinter.indent { thunkBuilder.renderFunctionBody(into: methodPrinter, returnExpr: returnExpr) @@ -2071,7 +2229,7 @@ extension BridgeJSLink { returnType: property.type ) - propertyPrinter.write("get \(property.name)() {") + propertyPrinter.write("get \(property.resolvedJSName)() {") propertyPrinter.indent { getterThunkBuilder.renderFunctionBody(into: propertyPrinter, returnExpr: getterReturnExpr) } @@ -2093,7 +2251,7 @@ extension BridgeJSLink { returnType: .void ) - propertyPrinter.write("set \(property.name)(value) {") + propertyPrinter.write("set \(property.resolvedJSName)(value) {") propertyPrinter.indent { setterThunkBuilder.renderFunctionBody(into: propertyPrinter, returnExpr: nil) } @@ -2177,7 +2335,7 @@ extension BridgeJSLink { jsPrinter.indent { jsPrinter.write( lines: thunkBuilder.renderFunction( - name: method.name, + name: method.resolvedJSName, parameters: method.parameters, returnExpr: returnExpr, declarationPrefixKeyword: "static" @@ -2198,7 +2356,7 @@ extension BridgeJSLink { jsPrinter.indent { jsPrinter.write( lines: thunkBuilder.renderFunction( - name: method.name, + name: method.resolvedJSName, parameters: method.parameters, returnExpr: returnExpr, declarationPrefixKeyword: nil @@ -2214,7 +2372,7 @@ extension BridgeJSLink { dtsTypePrinter.write(line) } dtsTypePrinter.write( - "\(method.name)\(renderTSSignature(parameters: method.parameters, returnType: method.returnType, effects: method.effects));" + "\(method.resolvedJSName)\(renderTSSignature(parameters: method.parameters, returnType: method.returnType, effects: method.effects));" ) } } @@ -2252,13 +2410,13 @@ extension BridgeJSLink { for method in klass.methods where method.effects.isStatic { printer.write(lines: renderJSDoc(documentation: method.documentation, parameters: method.parameters)) printer.write( - "\(method.name)\(renderTSSignature(parameters: method.parameters, returnType: method.returnType, effects: method.effects));" + "\(method.resolvedJSName)\(renderTSSignature(parameters: method.parameters, returnType: method.returnType, effects: method.effects));" ) } for property in klass.properties where property.isStatic { let readonly = property.isReadonly ? "readonly " : "" printer.write(lines: renderJSDoc(documentation: property.documentation, parameters: [])) - printer.write("\(readonly)\(property.name): \(resolveTypeScriptType(property.type));") + printer.write("\(readonly)\(property.resolvedJSName): \(resolveTypeScriptType(property.type));") } return printer.lines } @@ -2280,18 +2438,20 @@ extension BridgeJSLink { ) printer.write("constructor(\(paramSignatures.joined(separator: ", ")));") } - for method in klass.methods.sorted(by: { $0.name < $1.name }) { + for method in klass.methods.sorted(by: { $0.resolvedJSName < $1.resolvedJSName }) { let staticKeyword = method.effects.isStatic ? "static " : "" printer.write(lines: renderJSDoc(documentation: method.documentation, parameters: method.parameters)) printer.write( - "\(staticKeyword)\(method.name)\(renderTSSignature(parameters: method.parameters, returnType: method.returnType, effects: method.effects));" + "\(staticKeyword)\(method.resolvedJSName)\(renderTSSignature(parameters: method.parameters, returnType: method.returnType, effects: method.effects));" ) } - for property in klass.properties.sorted(by: { $0.name < $1.name }) { + for property in klass.properties.sorted(by: { $0.resolvedJSName < $1.resolvedJSName }) { let staticKeyword = property.isStatic ? "static " : "" let readonly = property.isReadonly ? "readonly " : "" printer.write(lines: renderJSDoc(documentation: property.documentation, parameters: [])) - printer.write("\(staticKeyword)\(readonly)\(property.name): \(resolveTypeScriptType(property.type));") + printer.write( + "\(staticKeyword)\(readonly)\(property.resolvedJSName): \(resolveTypeScriptType(property.type));" + ) } printer.write("release(): void;") } @@ -2321,7 +2481,7 @@ extension BridgeJSLink { jsPrinter.indent { jsPrinter.write( lines: getterThunkBuilder.renderFunction( - name: property.name, + name: property.resolvedJSName, parameters: [], returnExpr: getterReturnExpr, declarationPrefixKeyword: getterKeyword @@ -2349,7 +2509,7 @@ extension BridgeJSLink { jsPrinter.indent { jsPrinter.write( lines: setterThunkBuilder.renderFunction( - name: property.name, + name: property.resolvedJSName, parameters: [.init(label: nil, name: "value", type: property.type)], returnExpr: nil, declarationPrefixKeyword: setterKeyword @@ -2365,7 +2525,7 @@ extension BridgeJSLink { for line in renderJSDoc(documentation: property.documentation, parameters: []) { dtsPrinter.write(line) } - dtsPrinter.write("\(readonly)\(property.name): \(resolveTypeScriptType(property.type));") + dtsPrinter.write("\(readonly)\(property.resolvedJSName): \(resolveTypeScriptType(property.type));") } } } @@ -2379,6 +2539,8 @@ extension BridgeJSLink { var parameterNames: [String] = [] var parameterForwardings: [String] = [] var returnExpr: String? + var genericCodecVariables: [String: String] = [:] + var genericTypeIdParameters: [String: String] = [:] let printContext: IntrinsicJSFragment.PrintCodeContext init( @@ -2404,7 +2566,34 @@ extension BridgeJSLink { parameterNames.append("self") } + func declareGenericCodecs(genericParameters: [String]) { + if !genericParameters.isEmpty { + ContainerCodecJS.registerCombinators(scope: scope) + } + for genericParam in genericParameters { + let typeIdParam = scope.variable("\(genericParam.lowercased())TypeId") + let codecVar = scope.variable("codec\(genericParam)") + body.write("const \(codecVar) = __bjs_codecForTypeId(\(typeIdParam));") + genericCodecVariables[genericParam] = codecVar + genericTypeIdParameters[genericParam] = typeIdParam + } + } + func liftParameter(param: Parameter) throws { + if let name = param.type.referencedGenericName { + guard let codecVar = genericCodecVariables[name] else { + throw BridgeJSLinkError( + message: "Generic codec for '\(name)' was not declared before lifting parameter '\(param.name)'" + ) + } + let valueVar = scope.variable(param.name) + let liftExpr = + GenericJSCodegen.genericCodecLiftExpression(type: param.type, codec: codecVar) + ?? "\(codecVar).lift()" + body.write("const \(valueVar) = \(liftExpr);") + parameterForwardings.append(valueVar) + return + } let liftingFragment = try IntrinsicJSFragment.liftParameter(type: param.type, context: context) let valuesToLift: [String] if liftingFragment.parameters.count == 0 { @@ -2421,6 +2610,16 @@ extension BridgeJSLink { parameterForwardings.append(contentsOf: liftedValues) } + func liftParametersAndGenericTypeIds(_ parameters: [Parameter], genericParameters: [String]) throws { + declareGenericCodecs(genericParameters: genericParameters) + for param in parameters { + try liftParameter(param: param) + } + for genericParam in genericParameters { + parameterNames.append(genericTypeIdParameters[genericParam] ?? genericParam) + } + } + func renderFunction(name: String?) -> [String] { if effects.isAsync { return renderAsyncFunction(name: name) @@ -2497,6 +2696,25 @@ extension BridgeJSLink { body.write("\(callExpr).then(resolve, reject);") return } + if let name = returnType.referencedGenericName { + guard let codecVar = genericCodecVariables[name] else { + throw BridgeJSLinkError( + message: "Generic codec for return type '\(name)' was not declared before the call" + ) + } + let resultVariable = scope.variable("ret") + body.write("let \(resultVariable) = \(callExpr);") + let lowerStmt = + GenericJSCodegen.genericCodecLowerStatement( + type: returnType, + codec: codecVar, + value: resultVariable + ) + ?? "\(codecVar).lower(\(resultVariable));" + body.write(lowerStmt) + self.returnExpr = nil + return + } let loweringFragment = try IntrinsicJSFragment.lowerReturn(type: returnType, context: context) let returnExpr: String? if loweringFragment.parameters.count == 0 { @@ -2738,7 +2956,7 @@ extension BridgeJSLink { for function in skeleton.functions where function.namespace != nil { let namespacePath = function.namespace!.joined(separator: ".") printer.write( - "globalThis.\(namespacePath).\(function.name) = exports.\(namespacePath).\(function.name);" + "globalThis.\(namespacePath).\(function.resolvedJSName) = exports.\(namespacePath).\(function.resolvedJSName);" ) } for enumDef in skeleton.enums where enumDef.enumType == .namespace { @@ -2746,7 +2964,7 @@ extension BridgeJSLink { let fullNamespace = (enumDef.namespace ?? []) + [enumDef.name] let namespacePath = fullNamespace.joined(separator: ".") printer.write( - "globalThis.\(namespacePath).\(function.name) = exports.\(namespacePath).\(function.name);" + "globalThis.\(namespacePath).\(function.resolvedJSName) = exports.\(namespacePath).\(function.resolvedJSName);" ) } for property in enumDef.staticProperties { @@ -2754,11 +2972,13 @@ extension BridgeJSLink { let namespacePath = fullNamespace.joined(separator: ".") let exportsPath = "exports.\(namespacePath)" - printer.write("Object.defineProperty(globalThis.\(namespacePath), '\(property.name)', {") + printer.write( + "Object.defineProperty(globalThis.\(namespacePath), '\(property.resolvedJSName)', {" + ) printer.indent { - printer.write("get: () => \(exportsPath).\(property.name),") + printer.write("get: () => \(exportsPath).\(property.resolvedJSName),") if !property.isReadonly { - printer.write("set: (value) => { \(exportsPath).\(property.name) = value; }") + printer.write("set: (value) => { \(exportsPath).\(property.resolvedJSName) = value; }") } } printer.write("});") @@ -2940,7 +3160,7 @@ extension BridgeJSLink { renderPropertyEntry: (ExportedProperty) -> [String] ) { for function in node.content.functions { - node.content.functionDtsLines.append((function.name, renderFunctionEntry(function))) + node.content.functionDtsLines.append((function.resolvedJSName, renderFunctionEntry(function))) } switch node.content.declaration { @@ -2953,7 +3173,7 @@ extension BridgeJSLink { } for property in node.content.staticProperties { - node.content.staticPropertyDtsLines.append((property.name, renderPropertyEntry(property))) + node.content.staticPropertyDtsLines.append((property.resolvedJSName, renderPropertyEntry(property))) } for enumDef in node.content.enums { @@ -3005,7 +3225,7 @@ extension BridgeJSLink { ) throws { for function in node.content.functions { let impl = try renderFunctionImpl(function) - node.content.functionJsLines.append((function.name, impl)) + node.content.functionJsLines.append((function.resolvedJSName, impl)) } switch node.content.declaration { @@ -3039,7 +3259,7 @@ extension BridgeJSLink { ) let getterPrinter = CodeFragmentPrinter() - getterPrinter.write("get \(property.name)() {") + getterPrinter.write("get \(property.resolvedJSName)() {") getterPrinter.indent { getterPrinter.write(contentsOf: getterThunkBuilder.body) getterPrinter.write(lines: getterThunkBuilder.checkExceptionLines()) @@ -3066,7 +3286,7 @@ extension BridgeJSLink { ) let setterPrinter = CodeFragmentPrinter() - setterPrinter.write("set \(property.name)(value) {") + setterPrinter.write("set \(property.resolvedJSName)(value) {") setterPrinter.indent { setterPrinter.write(contentsOf: setterThunkBuilder.body) setterPrinter.write(lines: setterThunkBuilder.checkExceptionLines()) @@ -3431,18 +3651,22 @@ extension BridgeJSLink { // Only include functions and properties when exposeToGlobal is true if exposeToGlobal { - let sortedFunctions = childNode.content.functions.sorted { $0.name < $1.name } + let sortedFunctions = childNode.content.functions.sorted { + $0.resolvedJSName < $1.resolvedJSName + } for function in sortedFunctions { let signature = - "function \(function.name)\(renderTSSignatureCallback(function.parameters, function.returnType, function.effects));" + "function \(function.resolvedJSName)\(renderTSSignatureCallback(function.parameters, function.returnType, function.effects));" printer.write(lines: renderDocCallback(function.documentation, function.parameters)) printer.write(signature) } - let sortedProperties = childNode.content.staticProperties.sorted { $0.name < $1.name } + let sortedProperties = childNode.content.staticProperties.sorted { + $0.resolvedJSName < $1.resolvedJSName + } for property in sortedProperties { let readonly = property.isReadonly ? "var " : "let " printer.write(lines: renderDocCallback(property.documentation, [])) - printer.write("\(readonly)\(property.name): \(property.type.tsType);") + printer.write("\(readonly)\(property.resolvedJSName): \(property.type.tsType);") } } @@ -3476,10 +3700,12 @@ extension BridgeJSLink { returnType: function.returnType, intrinsicRegistry: intrinsicRegistry ) - for param in function.parameters { - try thunkBuilder.liftParameter(param: param) - } - let jsName = function.jsName ?? function.name + let genericParameters = function.genericParameterNames + try thunkBuilder.liftParametersAndGenericTypeIds( + function.parameters, + genericParameters: genericParameters + ) + let jsName = function.resolvedJSName let calleeExpr = try importedModuleRegistry.memberExpression( swiftModuleName: importObjectBuilder.moduleName, from: function.from, @@ -3489,9 +3715,10 @@ extension BridgeJSLink { try thunkBuilder.call(calleeExpr: calleeExpr) let funcLines = thunkBuilder.renderFunction(name: function.abiName(context: nil)) if function.from == nil { + let genericClause = renderGenericClause(genericParameters) importObjectBuilder.appendDts( [ - "\(renderTSPropertyName(jsName))\(renderTSSignature(parameters: function.parameters, returnType: function.returnType, effects: function.effects));" + "\(renderTSPropertyName(jsName))\(genericClause)\(renderTSSignature(parameters: function.parameters, returnType: function.returnType, effects: function.effects));" ] ) } @@ -3507,7 +3734,7 @@ extension BridgeJSLink { returnType: getter.type, intrinsicRegistry: intrinsicRegistry ) - let jsName = getter.jsName ?? getter.name + let jsName = getter.resolvedJSName let accessExpr = try importedModuleRegistry.memberExpression( swiftModuleName: importObjectBuilder.moduleName, from: getter.from, @@ -3542,7 +3769,7 @@ extension BridgeJSLink { getter: getter, abiName: getterAbiName, emitCall: { thunkBuilder in - return try thunkBuilder.callPropertyGetter(name: getter.jsName ?? getter.name) + return try thunkBuilder.callPropertyGetter(name: getter.resolvedJSName) } ) importObjectBuilder.assignToImportObject(name: getterAbiName, function: js) @@ -3558,7 +3785,7 @@ extension BridgeJSLink { try thunkBuilder.liftParameter( param: Parameter(label: nil, name: "newValue", type: setter.type) ) - thunkBuilder.callPropertySetter(name: setter.jsName ?? setter.name) + thunkBuilder.callPropertySetter(name: setter.resolvedJSName) } ) importObjectBuilder.assignToImportObject(name: setterAbiName, function: js) @@ -3580,14 +3807,16 @@ extension BridgeJSLink { dtsPrinter.indent { if let constructor = type.constructor { let returnType = BridgeType.jsObject(type.name) + let genericClause = renderGenericClause(constructor.genericParameterNames) dtsPrinter.write( - "new\(renderTSSignature(parameters: constructor.parameters, returnType: returnType, effects: Effects(isAsync: false, isThrows: false)));" + "new\(genericClause)\(renderTSSignature(parameters: constructor.parameters, returnType: returnType, effects: Effects(isAsync: false, isThrows: false)));" ) } for method in type.staticMethods { - let methodName = method.jsName ?? method.name + let methodName = method.resolvedJSName + let genericClause = renderGenericClause(method.genericParameterNames) let signature = - "\(renderTSPropertyName(methodName))\(renderTSSignature(parameters: method.parameters, returnType: method.returnType, effects: method.effects));" + "\(renderTSPropertyName(methodName))\(genericClause)\(renderTSSignature(parameters: method.parameters, returnType: method.returnType, effects: method.effects));" dtsPrinter.write(signature) } } @@ -3611,13 +3840,14 @@ extension BridgeJSLink { returnType: BridgeType.jsObject(type.name), intrinsicRegistry: intrinsicRegistry ) - for param in constructor.parameters { - try thunkBuilder.liftParameter(param: param) - } + try thunkBuilder.liftParametersAndGenericTypeIds( + constructor.parameters, + genericParameters: constructor.genericParameterNames + ) let ctorExpr = try importedModuleRegistry.memberExpression( swiftModuleName: importObjectBuilder.moduleName, from: type.from, - memberName: type.jsName ?? type.name + memberName: type.resolvedJSName ) try thunkBuilder.callConstructor( ctorExpr: ctorExpr, @@ -3670,16 +3900,17 @@ extension BridgeJSLink { returnType: method.returnType, intrinsicRegistry: intrinsicRegistry ) - for param in method.parameters { - try thunkBuilder.liftParameter(param: param) - } + try thunkBuilder.liftParametersAndGenericTypeIds( + method.parameters, + genericParameters: method.genericParameterNames + ) let constructorExpr = try importedModuleRegistry.memberExpression( swiftModuleName: swiftModuleName, from: context.from, - memberName: context.jsName ?? context.name + memberName: context.resolvedJSName ) - try thunkBuilder.callStaticMethod(on: constructorExpr, name: method.jsName ?? method.name) + try thunkBuilder.callStaticMethod(on: constructorExpr, name: method.resolvedJSName) let funcLines = thunkBuilder.renderFunction(name: method.abiName(context: context, operation: "static")) return (funcLines, []) } @@ -3694,11 +3925,13 @@ extension BridgeJSLink { intrinsicRegistry: intrinsicRegistry ) thunkBuilder.liftSelf() - for param in method.parameters { - try thunkBuilder.liftParameter(param: param) - } + let genericParameters = method.genericParameterNames + try thunkBuilder.liftParametersAndGenericTypeIds( + method.parameters, + genericParameters: genericParameters + ) - try thunkBuilder.callMethod(name: method.jsName ?? method.name) + try thunkBuilder.callMethod(name: method.resolvedJSName) let funcLines = thunkBuilder.renderFunction(name: method.abiName(context: context)) return (funcLines, []) } @@ -4040,6 +4273,8 @@ extension BridgeType { return "Record" case .alias(_, let underlying): return underlying.tsType + case .generic(let name): + return name } } diff --git a/Plugins/BridgeJS/Sources/BridgeJSLink/ImportedJSModuleRegistry.swift b/Plugins/BridgeJS/Sources/BridgeJSLink/ImportedJSModuleRegistry.swift index 96efcd1d4..daf220d7f 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSLink/ImportedJSModuleRegistry.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSLink/ImportedJSModuleRegistry.swift @@ -133,14 +133,14 @@ final class ImportedJSModuleRegistry { } for file in skeleton.imported?.children ?? [] { for function in file.functions { - visit(from: function.from, memberName: function.jsName ?? function.name) + visit(from: function.from, memberName: function.resolvedJSName) } for getter in file.globalGetters { - visit(from: getter.from, memberName: getter.jsName ?? getter.name) + visit(from: getter.from, memberName: getter.resolvedJSName) } for type in file.types { guard type.constructor != nil || !type.staticMethods.isEmpty else { continue } - visit(from: type.from, memberName: type.jsName ?? type.name) + visit(from: type.from, memberName: type.resolvedJSName) } } } diff --git a/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift b/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift index 1cf0fa298..3f8530c55 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift @@ -35,6 +35,11 @@ final class JSGlueVariableScope { static let reservedSwiftClosureRegistry = "swiftClosureRegistry" static let reservedMakeSwiftClosure = "makeClosure" static let reservedTaStack = "taStack" + static let reservedCodecByTypeId = "__bjs_codecByTypeId" + static let reservedPrimitiveCodecs = "__bjs_primitiveCodecs" + static let reservedStringCodec = "__bjs_stringCodec" + static let reservedTypeHandlesRegistered = "__bjs_typeHandlesRegistered" + static let reservedRegisterTypeHandles = "__bjs_registerTypeHandles" private let intrinsicRegistry: JSIntrinsicRegistry @@ -65,6 +70,11 @@ final class JSGlueVariableScope { reservedSwiftClosureRegistry, reservedMakeSwiftClosure, reservedTaStack, + reservedCodecByTypeId, + reservedPrimitiveCodecs, + reservedStringCodec, + reservedTypeHandlesRegistered, + reservedRegisterTypeHandles, ] init(intrinsicRegistry: JSIntrinsicRegistry) { @@ -92,12 +102,62 @@ final class JSGlueVariableScope { try intrinsicRegistry.register(name: name, build: build) } + func registerNamedCodec(_ name: String, build: (CodeFragmentPrinter) throws -> Void) rethrows { + try intrinsicRegistry.registerNamedCodec(name: name, build: build) + } + + func moduleName(declaringType typeName: String) -> String? { + intrinsicRegistry.typeOwnerModules[typeName] + } + func makeChildScope() -> JSGlueVariableScope { JSGlueVariableScope(intrinsicRegistry: intrinsicRegistry) } } +extension JSGlueVariableScope { + func helperKey(forTypeNamed fullName: String) -> String { + HelperNaming.type( + module: moduleName(declaringType: fullName), + swiftName: fullName + ) + } +} + +enum HelperNaming { + static func identifierComponent(_ name: String) -> String { + name.utf8.map { byte in + switch byte { + case 48...57, 65...90, 97...122: + return String(UnicodeScalar(byte)) + default: + return "_\(String(byte, radix: 16))_" + } + }.joined() + } + + static func type(module: String?, swiftName: String) -> String { + let module = module.map { "M\($0.utf8.count)\(identifierComponent($0))" } ?? "" + let type = swiftName.split(separator: ".").map { component in + "T\(component.utf8.count)\(identifierComponent(String(component)))" + }.joined() + return module + type + } + + static func structHelperFactory(_ qualifiedKey: String) -> String { + "__bjs_createStructHelpers_\(qualifiedKey)" + } + + static func enumHelperFactory(_ qualifiedKey: String) -> String { + "__bjs_createEnumHelpers_\(qualifiedKey)" + } + + static func helperConstant(_ qualifiedKey: String) -> String { + "__bjs_helpers_\(qualifiedKey)" + } +} + extension JSGlueVariableScope { // MARK: Parameter @@ -138,6 +198,327 @@ extension JSGlueVariableScope { } } +enum GenericJSCodegen { + static func genericCodecExpression(type: BridgeType, codec: String) -> String? { + switch type { + case .generic: return codec + case .array(.generic): return "\(ContainerCodecJS.arrayCodec)(\(codec))" + case .nullable(.generic, let kind): + return ContainerCodecJS.optionalCodecExpression(elementCodec: codec, kind: kind) + case .dictionary(.generic): return "\(ContainerCodecJS.dictCodec)(\(codec))" + default: return nil + } + } + + static func genericCodecLowerStatement(type: BridgeType, codec: String, value: String) -> String? { + genericCodecExpression(type: type, codec: codec).map { "\($0).lower(\(value));" } + } + + static func genericCodecLiftExpression(type: BridgeType, codec: String) -> String? { + genericCodecExpression(type: type, codec: codec).map { "\($0).lift()" } + } + + static func runtimeHelperDeclarations() -> [String] { + let codecByTypeId = JSGlueVariableScope.reservedCodecByTypeId + return [ + "function __bjs_codecForTypeId(typeId) {", + " __bjs_registerTypeHandles();", + " const codec = \(codecByTypeId).get(typeId);", + " if (!codec) {", + " throw new Error(\"BridgeJS: no codec registered for type ID \" + typeId);", + " }", + " return codec;", + "}", + ] + } +} + +enum ContainerCodecJS { + static let arrayCodec = "__bjs_arrayCodec" + static let optionalCodec = "__bjs_optionalCodec" + static let dictCodec = "__bjs_dictCodec" + + static let namedCodecPrefix = "__bjs_codec_" + + private static let combinatorIntrinsicName = "containerCodecCombinators" + private static let primitiveCodecIntrinsicName = "containerPrimitiveCodecs" + + static func combinatorDeclarations() -> [String] { + let i32 = JSGlueVariableScope.reservedI32Stack + let stringCodec = JSGlueVariableScope.reservedStringCodec + return [ + "const \(arrayCodec)Cache = new WeakMap();", + "function \(arrayCodec)(elementCodec) {", + " let codec = \(arrayCodec)Cache.get(elementCodec);", + " if (codec !== undefined) {", + " return codec;", + " }", + " codec = {", + " lower(value) {", + " for (let i = 0; i < value.length; i++) {", + " elementCodec.lower(value[i]);", + " }", + " \(i32).push(value.length);", + " },", + " lift() {", + " const count = \(i32).pop();", + " if (count === -1) {", + " return \(JSGlueVariableScope.reservedTaStack).pop();", + " }", + " const result = new Array(count);", + " for (let i = count - 1; i >= 0; i--) {", + " result[i] = elementCodec.lift();", + " }", + " return result;", + " },", + " };", + " \(arrayCodec)Cache.set(elementCodec, codec);", + " return codec;", + "}", + "const \(optionalCodec)Cache = new WeakMap();", + "const \(optionalCodec)UndefinedOrCache = new WeakMap();", + "function \(optionalCodec)(elementCodec, isUndefinedOr = false) {", + " const cache = isUndefinedOr ? \(optionalCodec)UndefinedOrCache : \(optionalCodec)Cache;", + " let codec = cache.get(elementCodec);", + " if (codec !== undefined) {", + " return codec;", + " }", + " codec = {", + " lower(value) {", + " const isSome = isUndefinedOr ? value !== undefined : value != null;", + " if (isSome) {", + " elementCodec.lower(value);", + " \(i32).push(1);", + " } else {", + " \(i32).push(0);", + " }", + " },", + " lift() {", + " if (\(i32).pop() === 0) {", + " return isUndefinedOr ? undefined : null;", + " }", + " return elementCodec.lift();", + " },", + " };", + " cache.set(elementCodec, codec);", + " return codec;", + "}", + "const \(dictCodec)Cache = new WeakMap();", + "function \(dictCodec)(valueCodec) {", + " let codec = \(dictCodec)Cache.get(valueCodec);", + " if (codec !== undefined) {", + " return codec;", + " }", + " codec = {", + " lower(value) {", + " const keys = Object.keys(value);", + " for (let i = 0; i < keys.length; i++) {", + " \(stringCodec).lower(keys[i]);", + " valueCodec.lower(value[keys[i]]);", + " }", + " \(i32).push(keys.length);", + " },", + " lift() {", + " const count = \(i32).pop();", + " const result = {};", + " for (let i = 0; i < count; i++) {", + " const value = valueCodec.lift();", + " const key = \(stringCodec).lift();", + " result[key] = value;", + " }", + " return result;", + " },", + " };", + " \(dictCodec)Cache.set(valueCodec, codec);", + " return codec;", + "}", + ] + } + + static func optionalCodecExpression(elementCodec: String, kind: JSOptionalKind) -> String { + switch kind { + case .null: return "\(optionalCodec)(\(elementCodec))" + case .undefined: return "\(optionalCodec)(\(elementCodec), true)" + } + } + + static func registerCombinators(scope: JSGlueVariableScope) { + scope.registerIntrinsic(combinatorIntrinsicName) { printer in + printer.write(lines: combinatorDeclarations()) + } + } + + static func registerPrimitiveCodecs(context: IntrinsicJSFragment.PrintCodeContext) throws { + try context.scope.registerIntrinsic(primitiveCodecIntrinsicName) { printer in + let stringCodec = JSGlueVariableScope.reservedStringCodec + try writeCodecLiteral( + type: .string, + into: printer, + context: context, + prefix: "const \(stringCodec) = ", + suffix: ";" + ) + printer.write("const \(JSGlueVariableScope.reservedPrimitiveCodecs) = {") + try printer.indent { + for primitive in BridgeType.genericBridgeablePrimitives { + if case .string = primitive.type { + printer.write("\(primitive.token): \(stringCodec),") + } else { + try writeCodecLiteral( + type: primitive.type, + into: printer, + context: context, + prefix: "\(primitive.token): ", + suffix: "," + ) + } + } + } + printer.write("};") + } + } + + static func writeCodecLiteral( + type: BridgeType, + into printer: CodeFragmentPrinter, + context: IntrinsicJSFragment.PrintCodeContext, + prefix: String = "", + suffix: String = "," + ) throws { + func literalContext() -> IntrinsicJSFragment.PrintCodeContext { + context.with(\.printer, printer).with(\.scope, context.scope.makeChildScope()) + } + let lowerFragment = try IntrinsicJSFragment.stackLowerFragment(elementType: type) + let liftFragment = try IntrinsicJSFragment.stackLiftFragment(elementType: type) + printer.write("\(prefix){") + try printer.indent { + printer.write("lower: (v) => {") + try printer.indent { + _ = try lowerFragment.printCode(["v"], literalContext()) + } + printer.write("},") + printer.write("lift: () => {") + try printer.indent { + let results = try liftFragment.printCode([], literalContext()) + printer.write("return \(results[0]);") + } + printer.write("},") + } + printer.write("}\(suffix)") + } + + struct NamedCodec { + let expression: String + let token: String + } + + static func codecExpression( + for elementType: BridgeType, + context: IntrinsicJSFragment.PrintCodeContext + ) throws -> String { + try namedCodec(for: elementType, context: context).expression + } + + static func namedCodec( + for elementType: BridgeType, + context: IntrinsicJSFragment.PrintCodeContext + ) throws -> NamedCodec { + registerCombinators(scope: context.scope) + try registerPrimitiveCodecs(context: context) + let type = elementType.unaliased + switch type { + case .array(let element): + let element = try namedCodec(for: element, context: context) + return composedCodec( + token: "Array_\(element.token)", + factory: "\(arrayCodec)(\(element.expression))", + context: context + ) + case .dictionary(let value): + let value = try namedCodec(for: value, context: context) + return composedCodec( + token: "Dict_\(value.token)", + factory: "\(dictCodec)(\(value.expression))", + context: context + ) + case .nullable(let wrapped, let kind): + let wrapped = try namedCodec(for: wrapped, context: context) + let prefix = kind == .null ? "Optional" : "UndefinedOr" + return composedCodec( + token: "\(prefix)_\(wrapped.token)", + factory: optionalCodecExpression(elementCodec: wrapped.expression, kind: kind), + context: context + ) + case .string, .rawValueEnum(_, .string): + return NamedCodec(expression: JSGlueVariableScope.reservedStringCodec, token: "String") + default: + if let token = BridgeType.genericBridgeablePrimitives.first(where: { $0.type == type })?.token { + return NamedCodec( + expression: "\(JSGlueVariableScope.reservedPrimitiveCodecs).\(token)", + token: token + ) + } + return try leafCodec(for: type, context: context) + } + } + + private static func composedCodec( + token: String, + factory: String, + context: IntrinsicJSFragment.PrintCodeContext + ) -> NamedCodec { + let name = "\(namedCodecPrefix)\(token)" + context.scope.registerNamedCodec(name) { printer in + printer.write("const \(name) = \(factory);") + } + return NamedCodec(expression: name, token: token) + } + + private static func leafCodec( + for type: BridgeType, + context: IntrinsicJSFragment.PrintCodeContext + ) throws -> NamedCodec { + let token = leafToken(for: type, scope: context.scope) + let name = "\(namedCodecPrefix)\(token)" + let hoistedContext = context.with(\.hasDirectAccessToSwiftClass, false) + try context.scope.registerNamedCodec(name) { printer in + try writeCodecLiteral( + type: type, + into: printer, + context: hoistedContext, + prefix: "const \(name) = ", + suffix: ";" + ) + } + return NamedCodec(expression: name, token: token) + } + + private static func leafToken(for type: BridgeType, scope: JSGlueVariableScope) -> String { + func identifierComponent(_ name: String) -> String { + HelperNaming.identifierComponent(name) + } + func qualified(_ name: String) -> String { + scope.helperKey(forTypeNamed: name) + } + switch type { + case .jsObject(nil): + return "JSObject" + case .jsObject(let name?): + return identifierComponent(name) + case .swiftStruct(let name), + .swiftHeapObject(let name), + .swiftProtocol(let name), + .caseEnum(let name), + .rawValueEnum(let name, _), + .associatedValueEnum(let name), + .namespaceEnum(let name): + return qualified(name) + default: + return identifierComponent(type.mangleTypeName) + } + } +} + /// A fragment of JS code used to convert a value between Swift and JS. /// /// See `BridgeJSIntrinsics.swift` in the main JavaScriptKit module for Swift side lowering/lifting implementation. @@ -615,12 +996,13 @@ struct IntrinsicJSFragment: Sendable { // MARK: - Associated Enum Fragments - static func associatedEnumLowerParameter(enumBase: String) -> IntrinsicJSFragment { + static func associatedEnumLowerParameter(enumName: String) -> IntrinsicJSFragment { IntrinsicJSFragment( parameters: ["value"], printCode: { arguments, context in let (scope, printer) = (context.scope, context.printer) let value = arguments[0] + let enumBase = scope.helperKey(forTypeNamed: enumName) let caseIdName = scope.variable("\(value)CaseId") printer.write( "const \(caseIdName) = \(JSGlueVariableScope.reservedEnumHelpers).\(enumBase).lower(\(value));" @@ -630,11 +1012,12 @@ struct IntrinsicJSFragment: Sendable { ) } - static func associatedEnumLiftReturn(enumBase: String) -> IntrinsicJSFragment { + static func associatedEnumLiftReturn(enumName: String) -> IntrinsicJSFragment { IntrinsicJSFragment( parameters: [], printCode: { _, context in let (scope, printer) = (context.scope, context.printer) + let enumBase = scope.helperKey(forTypeNamed: enumName) let retName = scope.variable("ret") printer.write( "const \(retName) = \(JSGlueVariableScope.reservedEnumHelpers).\(enumBase).lift(\(scope.popI32()));" @@ -668,40 +1051,35 @@ struct IntrinsicJSFragment: Sendable { ) } - let innerFragment = - if wrappedType.optionalParameterUsesStackABI { - try stackLiftFragment(elementType: wrappedType) - } else { - try liftParameter(type: wrappedType, context: bridgeContext) - } + if wrappedType.optionalParameterUsesStackABI { + return try optionalElementRaiseFragment(wrappedType: wrappedType, kind: kind) + } return compositeOptionalLiftParameter( wrappedType: wrappedType, kind: kind, - innerFragment: innerFragment + innerFragment: try liftParameter(type: wrappedType, context: bridgeContext) ) } + /// Lift an optional parameter whose presence flag arrives as a wasm + /// parameter (not on the i32 stack), with the payload either in further + /// wasm parameters or on the stacks. The shared optional codec combinator + /// pops its flag from the i32 stack, so this ABI cannot go through it; + /// stack-convention payloads still lift through the shared container + /// codecs via `stackLiftFragment`. private static func compositeOptionalLiftParameter( wrappedType: BridgeType, kind: JSOptionalKind, innerFragment: IntrinsicJSFragment ) -> IntrinsicJSFragment { - let isStackConvention = wrappedType.optionalParameterUsesStackABI let absenceLiteral = kind.absenceLiteral - let outerParams: [String] - if isStackConvention { - outerParams = ["isSome"] - } else { - outerParams = ["isSome"] + innerFragment.parameters - } - return IntrinsicJSFragment( - parameters: outerParams, + parameters: ["isSome"] + innerFragment.parameters, printCode: { arguments, context in let (scope, printer) = (context.scope, context.printer) let isSome = arguments[0] - let innerArgs = isStackConvention ? [] : Array(arguments.dropFirst()) + let innerArgs = Array(arguments.dropFirst()) let bufferPrinter = CodeFragmentPrinter() let innerResults = try innerFragment.printCode( @@ -761,26 +1139,26 @@ struct IntrinsicJSFragment: Sendable { ) } - let innerFragment = - if wrappedType.optionalParameterUsesStackABI { - try stackLowerFragment(elementType: wrappedType) - } else { - try lowerParameter(type: wrappedType) - } + if wrappedType.optionalParameterUsesStackABI { + // Stack convention: the conditional flag-plus-payload protocol is + // the shared optional codec's stack ABI. + return try optionalElementLowerFragment(wrappedType: wrappedType, kind: kind) + } return try compositeOptionalLowerParameter( wrappedType: wrappedType, kind: kind, - innerFragment: innerFragment + innerFragment: try lowerParameter(type: wrappedType) ) } + /// Lower an optional parameter using the direct `(isSome, ...payload)` wasm + /// parameter ABI with zero placeholders for nil. This is not the container + /// stack ABI, so it cannot go through the shared optional codec combinator. private static func compositeOptionalLowerParameter( wrappedType: BridgeType, kind: JSOptionalKind, innerFragment: IntrinsicJSFragment ) throws -> IntrinsicJSFragment { - let isStackConvention = wrappedType.optionalParameterUsesStackABI - return IntrinsicJSFragment( parameters: ["value"], printCode: { arguments, context in @@ -797,7 +1175,7 @@ struct IntrinsicJSFragment: Sendable { let resultVars = innerResults.map { _ in scope.variable("result") } assert( - isStackConvention || resultVars.count == wrappedType.wasmParams.count, + resultVars.count == wrappedType.wasmParams.count, "Inner fragment result count (\(resultVars.count)) must match wasmParams count (\(wrappedType.wasmParams.count)) for \(wrappedType)" ) if !resultVars.isEmpty { @@ -814,8 +1192,7 @@ struct IntrinsicJSFragment: Sendable { } } - let hasPlaceholders = !isStackConvention && !wrappedType.wasmParams.isEmpty - if hasPlaceholders { + if !wrappedType.wasmParams.isEmpty { printer.write("} else {") printer.indent { for (resultVar, param) in zip(resultVars, wrappedType.wasmParams) { @@ -825,12 +1202,7 @@ struct IntrinsicJSFragment: Sendable { } printer.write("}") - if isStackConvention { - scope.emitPushI32Parameter("+\(isSomeVar)", printer: printer) - return [] - } else { - return ["+\(isSomeVar)"] + resultVars - } + return ["+\(isSomeVar)"] + resultVars } ) } @@ -848,6 +1220,9 @@ struct IntrinsicJSFragment: Sendable { ) } + /// Lift an optional return whose presence flag travels on the i32 stack but + /// whose payload uses the wrapped type's regular (non-stack) return ABI, so + /// it cannot go through the shared optional codec combinator. private static func optionalLiftReturnWithPresenceFlag( wrappedType: BridgeType, kind: JSOptionalKind @@ -860,12 +1235,7 @@ struct IntrinsicJSFragment: Sendable { let isSomeVar = scope.variable("isSome") printer.write("const \(isSomeVar) = \(scope.popI32());") - let innerFragment = - if wrappedType.optionalConvention == .stackABI { - try stackLiftFragment(elementType: wrappedType) - } else { - try liftReturn(type: wrappedType) - } + let innerFragment = try liftReturn(type: wrappedType) let innerPrinter = CodeFragmentPrinter() let innerResults = try innerFragment.printCode([], context.with(\.printer, innerPrinter)) @@ -898,12 +1268,12 @@ struct IntrinsicJSFragment: Sendable { fullName: String, kind: JSOptionalKind ) -> IntrinsicJSFragment { - let base = fullName.components(separatedBy: ".").last ?? fullName let absenceLiteral = kind.absenceLiteral return IntrinsicJSFragment( parameters: [], printCode: { _, context in let (scope, printer) = (context.scope, context.printer) + let base = scope.helperKey(forTypeNamed: fullName) let resultVar = scope.variable("optResult") let tagVar = scope.variable("tag") printer.write("const \(tagVar) = \(scope.popI32());") @@ -942,31 +1312,13 @@ struct IntrinsicJSFragment: Sendable { ) } - private static func optionalLiftReturnStruct( - fullName: String, - kind: JSOptionalKind - ) -> IntrinsicJSFragment { - let base = fullName.replacingOccurrences(of: ".", with: "_") - let absenceLiteral = kind.absenceLiteral - return IntrinsicJSFragment( - parameters: [], - printCode: { _, context in - let (scope, printer) = (context.scope, context.printer) - let isSomeVar = scope.variable("isSome") - let resultVar = scope.variable("optResult") - printer.write("const \(isSomeVar) = \(scope.popI32());") - printer.write( - "const \(resultVar) = \(isSomeVar) ? \(JSGlueVariableScope.reservedStructHelpers).\(base).lift() : \(absenceLiteral);" - ) - return [resultVar] - } - ) - } - static func optionalLiftReturn( wrappedType: BridgeType, kind: JSOptionalKind - ) -> IntrinsicJSFragment { + ) throws -> IntrinsicJSFragment { + // Side-channel optionals deliver their payload through dedicated + // storage/imports instead of the bridge stacks, so they cannot go + // through the shared optional codec combinator. if let scalarKind = wrappedType.optionalScalarKind { return optionalLiftReturnFromStorage(storage: scalarKind.storageName) } @@ -974,18 +1326,21 @@ struct IntrinsicJSFragment: Sendable { return optionalLiftReturnFromStorage(storage: JSGlueVariableScope.reservedStorageToReturnString) } + // Heap object optionals use the tmpRetOptionalHeapObject side channel. if case .swiftHeapObject(let className) = wrappedType { return optionalLiftReturnHeapObject(className: className, kind: kind) } - if case .swiftStruct(let fullName) = wrappedType { - return optionalLiftReturnStruct(fullName: fullName, kind: kind) - } - + // Sentinel optionals encode nil in-band (tag -1), with no presence flag. if wrappedType.nilSentinel.hasSentinel, case .associatedValueEnum(let fullName) = wrappedType { return optionalLiftReturnAssociatedEnum(fullName: fullName, kind: kind) } + if wrappedType.optionalConvention == .stackABI { + // Stack convention: route through the shared optional codec combinator. + return try optionalElementRaiseFragment(wrappedType: wrappedType, kind: kind) + } + return optionalLiftReturnWithPresenceFlag(wrappedType: wrappedType, kind: kind) } @@ -1111,12 +1466,8 @@ struct IntrinsicJSFragment: Sendable { } if wrappedType.optionalConvention == .stackABI { - let innerFragment = try stackLowerFragment(elementType: wrappedType) - return stackOptionalLower( - wrappedType: wrappedType, - kind: kind, - innerFragment: innerFragment - ) + // Stack convention: route through the shared optional codec combinator. + return try optionalElementLowerFragment(wrappedType: wrappedType, kind: kind) } if wrappedType.nilSentinel.hasSentinel { @@ -1248,39 +1599,6 @@ struct IntrinsicJSFragment: Sendable { } } - /// Lower an optional value to the stack using the **conditional** protocol: - /// push isSome flag, then conditionally push the payload (no placeholders for nil). - private static func stackOptionalLower( - wrappedType: BridgeType, - kind: JSOptionalKind, - innerFragment: IntrinsicJSFragment - ) -> IntrinsicJSFragment { - IntrinsicJSFragment( - parameters: ["value"], - printCode: { arguments, context in - let (scope, printer) = (context.scope, context.printer) - let value = arguments[0] - let isSomeVar = scope.variable("isSome") - printer.write("const \(isSomeVar) = \(kind.presenceCheck(value: value));") - - let ifBodyPrinter = CodeFragmentPrinter() - try ifBodyPrinter.indent { - let _ = try innerFragment.printCode( - [value], - context.with(\.printer, ifBodyPrinter) - ) - } - printer.write("if (\(isSomeVar)) {") - for line in ifBodyPrinter.lines { - printer.write(line) - } - printer.write("}") - scope.emitPushI32Parameter("\(isSomeVar) ? 1 : 0", printer: printer) - return [] - } - ) - } - // MARK: - ExportSwift /// Returns a fragment that lowers a JS value to Wasm core values for parameters @@ -1300,11 +1618,9 @@ struct IntrinsicJSFragment: Sendable { return try .optionalLowerParameter(wrappedType: wrappedType, kind: kind) case .rawValueEnum(_, .string): return .stringLowerParameter case .associatedValueEnum(let fullName): - let base = fullName.components(separatedBy: ".").last ?? fullName - return .associatedEnumLowerParameter(enumBase: base) + return .associatedEnumLowerParameter(enumName: fullName) case .swiftStruct(let fullName): - let base = fullName.replacingOccurrences(of: ".", with: "_") - return swiftStructLowerParameter(structBase: base) + return swiftStructLowerParameter(structName: fullName) case .closure: return IntrinsicJSFragment( parameters: ["closure"], @@ -1357,14 +1673,12 @@ struct IntrinsicJSFragment: Sendable { case .swiftProtocol: return .jsObjectLiftReturn case .void: return .void case .nullable(let wrappedType, let kind): - return .optionalLiftReturn(wrappedType: wrappedType, kind: kind) + return try .optionalLiftReturn(wrappedType: wrappedType, kind: kind) case .rawValueEnum(_, .string): return .stringLiftReturn case .associatedValueEnum(let fullName): - let base = fullName.components(separatedBy: ".").last ?? fullName - return .associatedEnumLiftReturn(enumBase: base) + return .associatedEnumLiftReturn(enumName: fullName) case .swiftStruct(let fullName): - let base = fullName.replacingOccurrences(of: ".", with: "_") - return swiftStructLiftReturn(structBase: base) + return swiftStructLiftReturn(structName: fullName) case .closure: return IntrinsicJSFragment( parameters: ["funcRef"], @@ -1423,11 +1737,11 @@ struct IntrinsicJSFragment: Sendable { return try .optionalLiftParameter(wrappedType: wrappedType, kind: kind, context: context) case .rawValueEnum(_, .string): return .stringLiftParameter case .associatedValueEnum(let fullName): - let base = fullName.components(separatedBy: ".").last ?? fullName return IntrinsicJSFragment( parameters: ["caseId"], printCode: { arguments, context in let (scope, printer) = (context.scope, context.printer) + let base = scope.helperKey(forTypeNamed: fullName) let caseId = arguments[0] let resultVar = scope.variable("enumValue") printer.write( @@ -1437,11 +1751,11 @@ struct IntrinsicJSFragment: Sendable { } ) case .swiftStruct(let fullName): - let base = fullName.replacingOccurrences(of: ".", with: "_") return IntrinsicJSFragment( parameters: [], printCode: { arguments, context in let (scope, printer) = (context.scope, context.printer) + let base = scope.helperKey(forTypeNamed: fullName) let resultVar = scope.variable("structValue") printer.write( "const \(resultVar) = \(JSGlueVariableScope.reservedStructHelpers).\(base).lift();" @@ -1523,11 +1837,11 @@ struct IntrinsicJSFragment: Sendable { // MARK: - Enums Payload Fragments static func associatedValueLowerReturn(fullName: String) -> IntrinsicJSFragment { - let base = fullName.components(separatedBy: ".").last ?? fullName return IntrinsicJSFragment( parameters: ["value"], printCode: { arguments, context in let (scope, printer) = (context.scope, context.printer) + let base = scope.helperKey(forTypeNamed: fullName) let value = arguments[0] let caseIdVar = scope.variable("caseId") printer.write( @@ -1566,17 +1880,20 @@ struct IntrinsicJSFragment: Sendable { ) } - /// 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 { + static func associatedValueEnumHelperFactory( + enumDefinition: ExportedEnum, + moduleName: String + ) -> IntrinsicJSFragment { + let factoryName = HelperNaming.enumHelperFactory( + HelperNaming.type(module: moduleName, swiftName: enumDefinition.swiftCallName) + ) return IntrinsicJSFragment( parameters: ["enumName"], printCode: { arguments, context in let (scope, printer) = (context.scope, context.printer) let enumName = arguments[0] - printer.write("const __bjs_create\(enumName)Helpers = () => ({") + printer.write("const \(factoryName) = () => ({") try printer.indent { printer.write("lower: (value) => {") try printer.indent { @@ -1769,11 +2086,12 @@ struct IntrinsicJSFragment: Sendable { } } - private static func swiftStructLower(structBase: String) -> IntrinsicJSFragment { + private static func swiftStructLower(structName: String) -> IntrinsicJSFragment { IntrinsicJSFragment( parameters: ["value"], printCode: { arguments, context in let printer = context.printer + let structBase = context.scope.helperKey(forTypeNamed: structName) let value = arguments[0] printer.write( "\(JSGlueVariableScope.reservedStructHelpers).\(structBase).lower(\(value));" @@ -1784,18 +2102,19 @@ struct IntrinsicJSFragment: Sendable { } static func swiftStructLowerReturn(fullName: String) -> IntrinsicJSFragment { - swiftStructLower(structBase: fullName.replacingOccurrences(of: ".", with: "_")) + swiftStructLower(structName: fullName) } - static func swiftStructLowerParameter(structBase: String) -> IntrinsicJSFragment { - swiftStructLower(structBase: structBase) + static func swiftStructLowerParameter(structName: String) -> IntrinsicJSFragment { + swiftStructLower(structName: structName) } - static func swiftStructLiftReturn(structBase: String) -> IntrinsicJSFragment { + static func swiftStructLiftReturn(structName: String) -> IntrinsicJSFragment { return IntrinsicJSFragment( parameters: [], printCode: { arguments, context in let (scope, printer) = (context.scope, context.printer) + let structBase = scope.helperKey(forTypeNamed: structName) let resultVar = scope.variable("structValue") printer.write( "const \(resultVar) = \(JSGlueVariableScope.reservedStructHelpers).\(structBase).lift();" @@ -1807,133 +2126,53 @@ struct IntrinsicJSFragment: Sendable { // MARK: - Array Helpers - /// Lowers an array from JS to Swift by iterating elements and pushing to stacks static func arrayLower(elementType: BridgeType) throws -> IntrinsicJSFragment { return IntrinsicJSFragment( parameters: ["arr"], printCode: { arguments, context in - let (scope, printer) = (context.scope, context.printer) - let arr = arguments[0] - - let elemVar = scope.variable("elem") - printer.write("for (const \(elemVar) of \(arr)) {") - try printer.indent { - let elementFragment = try stackLowerFragment(elementType: elementType) - let _ = try elementFragment.printCode( - [elemVar], - context - ) - } - printer.write("}") - scope.emitPushI32Parameter("\(arr).length", printer: printer) + let codec = try ContainerCodecJS.codecExpression(for: .array(elementType), context: context) + context.printer.write("\(codec).lower(\(arguments[0]));") return [] } ) } - /// Lowers a dictionary from JS to Swift by iterating entries and pushing to stacks static func dictionaryLower(valueType: BridgeType) throws -> IntrinsicJSFragment { return IntrinsicJSFragment( parameters: ["dict"], printCode: { arguments, context in - let (scope, printer) = (context.scope, context.printer) - let dict = arguments[0] - - let entriesVar = scope.variable("entries") - let entryVar = scope.variable("entry") - printer.write("const \(entriesVar) = Object.entries(\(dict));") - printer.write("for (const \(entryVar) of \(entriesVar)) {") - try printer.indent { - let keyVar = scope.variable("key") - let valueVar = scope.variable("value") - printer.write("const [\(keyVar), \(valueVar)] = \(entryVar);") - - let keyFragment = try stackLowerFragment(elementType: .string) - let _ = try keyFragment.printCode( - [keyVar], - context - ) - - let valueFragment = try stackLowerFragment(elementType: valueType) - let _ = try valueFragment.printCode( - [valueVar], - context - ) - } - printer.write("}") - scope.emitPushI32Parameter("\(entriesVar).length", printer: printer) + let codec = try ContainerCodecJS.codecExpression(for: .dictionary(valueType), context: context) + context.printer.write("\(codec).lower(\(arguments[0]));") return [] } ) } - /// Lifts an array from Swift to JS by popping elements from stacks static func arrayLift(elementType: BridgeType) throws -> IntrinsicJSFragment { return IntrinsicJSFragment( parameters: [], - printCode: { arguments, context in - let (scope, printer) = (context.scope, context.printer) - let resultVar = scope.variable("arrayResult") - let lenVar = scope.variable("arrayLen") - - printer.write("const \(lenVar) = \(scope.popI32());") - printer.write("let \(resultVar);") - printer.write("if (\(lenVar) === -1) {") - printer.indent { - // Bulk path: Swift pushed a typed array onto the typed-array stack - printer.write("\(resultVar) = \(JSGlueVariableScope.reservedTaStack).pop();") - } - printer.write("} else {") - try printer.indent { - // Element-by-element path (original behavior) - let iVar = scope.variable("i") - printer.write("\(resultVar) = [];") - printer.write("for (let \(iVar) = 0; \(iVar) < \(lenVar); \(iVar)++) {") - try printer.indent { - let elementFragment = try stackLiftFragment(elementType: elementType) - let elementResults = try elementFragment.printCode([], context) - if let elementExpr = elementResults.first { - printer.write("\(resultVar).push(\(elementExpr));") - } - } - printer.write("}") - printer.write("\(resultVar).reverse();") - } - printer.write("}") + printCode: { _, context in + let codec = try ContainerCodecJS.codecExpression(for: .array(elementType), context: context) + let resultVar = context.scope.variable("arrayResult") + context.printer.write("const \(resultVar) = \(codec).lift();") return [resultVar] } ) } - /// Lifts a dictionary from Swift to JS by popping key/value pairs from stacks static func dictionaryLift(valueType: BridgeType) throws -> IntrinsicJSFragment { return IntrinsicJSFragment( parameters: [], - printCode: { arguments, context in - let (scope, printer) = (context.scope, context.printer) - let resultVar = scope.variable("dictResult") - let lenVar = scope.variable("dictLen") - let iVar = scope.variable("i") - - printer.write("const \(lenVar) = \(scope.popI32());") - printer.write("const \(resultVar) = {};") - printer.write("for (let \(iVar) = 0; \(iVar) < \(lenVar); \(iVar)++) {") - try printer.indent { - let valueFragment = try stackLiftFragment(elementType: valueType) - let valueResults = try valueFragment.printCode([], context) - let keyFragment = try stackLiftFragment(elementType: .string) - let keyResults = try keyFragment.printCode([], context) - if let keyExpr = keyResults.first, let valueExpr = valueResults.first { - printer.write("\(resultVar)[\(keyExpr)] = \(valueExpr);") - } - } - printer.write("}") + printCode: { _, context in + let codec = try ContainerCodecJS.codecExpression(for: .dictionary(valueType), context: context) + let resultVar = context.scope.variable("dictResult") + context.printer.write("const \(resultVar) = \(codec).lift();") return [resultVar] } ) } - private static func stackLiftFragment(elementType: BridgeType) throws -> IntrinsicJSFragment { + static func stackLiftFragment(elementType: BridgeType) throws -> IntrinsicJSFragment { if case .nullable(let wrappedType, let kind) = elementType { return try optionalElementRaiseFragment(wrappedType: wrappedType, kind: kind) } @@ -1998,11 +2237,11 @@ struct IntrinsicJSFragment: Sendable { } ) case .swiftStruct(let fullName): - let structBase = fullName.replacingOccurrences(of: ".", with: "_") return IntrinsicJSFragment( parameters: [], printCode: { arguments, context in let (scope, printer) = (context.scope, context.printer) + let structBase = scope.helperKey(forTypeNamed: fullName) let resultVar = scope.variable("struct") printer.write( "const \(resultVar) = \(JSGlueVariableScope.reservedStructHelpers).\(structBase).lift();" @@ -2011,11 +2250,11 @@ struct IntrinsicJSFragment: Sendable { } ) case .associatedValueEnum(let fullName): - let base = fullName.components(separatedBy: ".").last ?? fullName return IntrinsicJSFragment( parameters: [], printCode: { arguments, context in let (scope, printer) = (context.scope, context.printer) + let base = scope.helperKey(forTypeNamed: fullName) let resultVar = scope.variable("enumValue") printer.write( "const \(resultVar) = \(JSGlueVariableScope.reservedEnumHelpers).\(base).lift(\(scope.popI32()));" @@ -2060,7 +2299,7 @@ struct IntrinsicJSFragment: Sendable { } } - private static func stackLowerFragment(elementType: BridgeType) throws -> IntrinsicJSFragment { + static func stackLowerFragment(elementType: BridgeType) throws -> IntrinsicJSFragment { if case .nullable(let wrappedType, let kind) = elementType { return try optionalElementLowerFragment(wrappedType: wrappedType, kind: kind) } @@ -2120,11 +2359,11 @@ struct IntrinsicJSFragment: Sendable { } ) case .swiftStruct(let fullName): - let structBase = fullName.replacingOccurrences(of: ".", with: "_") return IntrinsicJSFragment( parameters: ["value"], printCode: { arguments, context in let printer = context.printer + let structBase = context.scope.helperKey(forTypeNamed: fullName) let value = arguments[0] printer.write( "\(JSGlueVariableScope.reservedStructHelpers).\(structBase).lower(\(value));" @@ -2134,11 +2373,11 @@ struct IntrinsicJSFragment: Sendable { ) case .associatedValueEnum(let fullName): - let base = fullName.components(separatedBy: ".").last ?? fullName return IntrinsicJSFragment( parameters: ["value"], printCode: { arguments, context in let (scope, printer) = (context.scope, context.printer) + let base = scope.helperKey(forTypeNamed: fullName) let value = arguments[0] let caseIdVar = scope.variable("caseId") printer.write( @@ -2185,39 +2424,20 @@ struct IntrinsicJSFragment: Sendable { wrappedType: BridgeType, kind: JSOptionalKind ) throws -> IntrinsicJSFragment { - let absenceLiteral = kind.absenceLiteral return IntrinsicJSFragment( parameters: [], - printCode: { arguments, context in - let (scope, printer) = (context.scope, context.printer) - let isSomeVar = scope.variable("isSome") - let resultVar = scope.variable("optValue") - - printer.write("const \(isSomeVar) = \(scope.popI32());") - printer.write("let \(resultVar);") - printer.write("if (\(isSomeVar) === 0) {") - printer.indent { - printer.write("\(resultVar) = \(absenceLiteral);") - } - printer.write("} else {") - try printer.indent { - let innerFragment = try stackLiftFragment(elementType: wrappedType) - let innerResults = try innerFragment.printCode([], context) - if let innerResult = innerResults.first { - printer.write("\(resultVar) = \(innerResult);") - } else { - printer.write("\(resultVar) = undefined;") - } - } - printer.write("}") - + printCode: { _, context in + let codec = try ContainerCodecJS.codecExpression( + for: .nullable(wrappedType, kind), + context: context + ) + let resultVar = context.scope.variable("optValue") + context.printer.write("const \(resultVar) = \(codec).lift();") return [resultVar] } ) } - /// Lower an optional element to the stack using the **conditional** protocol: - /// push isSome flag, then conditionally push the payload (no placeholders for nil). private static func optionalElementLowerFragment( wrappedType: BridgeType, kind: JSOptionalKind @@ -2225,23 +2445,11 @@ struct IntrinsicJSFragment: Sendable { return IntrinsicJSFragment( parameters: ["value"], printCode: { arguments, context in - let (scope, printer) = (context.scope, context.printer) - let value = arguments[0] - let isSomeVar = scope.variable("isSome") - - let presenceExpr = kind.presenceCheck(value: value) - printer.write("const \(isSomeVar) = \(presenceExpr) ? 1 : 0;") - printer.write("if (\(isSomeVar)) {") - try printer.indent { - let innerFragment = try stackLowerFragment(elementType: wrappedType) - let _ = try innerFragment.printCode( - [value], - context - ) - } - printer.write("}") - scope.emitPushI32Parameter(isSomeVar, printer: printer) - + let codec = try ContainerCodecJS.codecExpression( + for: .nullable(wrappedType, kind), + context: context + ) + context.printer.write("\(codec).lower(\(arguments[0]));") return [] } ) @@ -2249,16 +2457,22 @@ struct IntrinsicJSFragment: Sendable { // MARK: - Struct Helpers - static func structHelper(structDefinition: ExportedStruct, allStructs: [ExportedStruct]) -> IntrinsicJSFragment { + static func structHelper( + structDefinition: ExportedStruct, + allStructs: [ExportedStruct], + moduleName: String + ) -> IntrinsicJSFragment { + let factoryName = HelperNaming.structHelperFactory( + HelperNaming.type(module: moduleName, swiftName: structDefinition.swiftCallName) + ) return IntrinsicJSFragment( - parameters: ["structName"], + parameters: [], printCode: { arguments, context in let printer = context.printer - let structName = arguments[0] let capturedStructDef = structDefinition let capturedAllStructs = allStructs - printer.write("const __bjs_create\(structName)Helpers = () => ({") + printer.write("const \(factoryName) = () => ({") try printer.indent { printer.write("lower: (value) => {") try printer.indent { @@ -2353,11 +2567,11 @@ struct IntrinsicJSFragment: Sendable { for method in structDef.methods where !method.effects.isStatic { let paramList = DefaultValueUtils.formatParameterList(method.parameters) printer.write( - "\(instanceVar).\(method.name) = function(\(paramList)) {" + "\(instanceVar).\(method.resolvedJSName) = function(\(paramList)) {" ) try printer.indent { printer.write( - "\(JSGlueVariableScope.reservedStructHelpers).\(structDef.abiName).lower(this);" + "\(JSGlueVariableScope.reservedStructHelpers).\(context.scope.helperKey(forTypeNamed: structDef.swiftCallName)).lower(this);" ) var paramForwardings: [String] = [] @@ -2428,9 +2642,10 @@ struct IntrinsicJSFragment: Sendable { parameters: ["value"], printCode: { arguments, context in let printer = context.printer + let nestedBase = context.scope.helperKey(forTypeNamed: nestedName) let value = arguments[0] printer.write( - "\(JSGlueVariableScope.reservedStructHelpers).\(nestedName.replacingOccurrences(of: ".", with: "_")).lower(\(value));" + "\(JSGlueVariableScope.reservedStructHelpers).\(nestedBase).lower(\(value));" ) return [] } @@ -2467,9 +2682,10 @@ struct IntrinsicJSFragment: Sendable { parameters: [], printCode: { arguments, context in let (scope, printer) = (context.scope, context.printer) + let nestedBase = scope.helperKey(forTypeNamed: nestedName) let structVar = scope.variable("struct") printer.write( - "const \(structVar) = \(JSGlueVariableScope.reservedStructHelpers).\(nestedName.replacingOccurrences(of: ".", with: "_")).lift();" + "const \(structVar) = \(JSGlueVariableScope.reservedStructHelpers).\(nestedBase).lift();" ) return [structVar] } @@ -2608,7 +2824,7 @@ private extension BridgeType { return .inlineFlag case .closure: return .inlineFlag - case .swiftStruct, .array, .dictionary, .void, .namespaceEnum: + case .swiftStruct, .array, .dictionary, .void, .namespaceEnum, .generic: return .stackABI case .nullable(let wrapped, _): return wrapped.optionalConvention @@ -2706,7 +2922,7 @@ private extension BridgeType { return [("caseId", .i32)] case .closure: return [("funcRef", .i32)] - case .void, .namespaceEnum, .swiftStruct, .array, .dictionary: + case .void, .namespaceEnum, .swiftStruct, .array, .dictionary, .generic: return [] case .nullable(let wrapped, _): return wrapped.wasmParams diff --git a/Plugins/BridgeJS/Sources/BridgeJSLink/JSIntrinsicRegistry.swift b/Plugins/BridgeJS/Sources/BridgeJSLink/JSIntrinsicRegistry.swift index e3654e89f..d0bf2781f 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSLink/JSIntrinsicRegistry.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSLink/JSIntrinsicRegistry.swift @@ -7,6 +7,11 @@ final class JSIntrinsicRegistry { private var entries: [String: [String]] = [:] var classNamespaces: [String: [String]] = [:] + var typeOwnerModules: [String: String] = [:] + + private var codecNameOrder: [String] = [] + private var codecBodies: [String: [String]] = [:] + var isEmpty: Bool { entries.isEmpty } @@ -18,9 +23,29 @@ final class JSIntrinsicRegistry { entries[name] = printer.lines } + func registerNamedCodec(name: String, build: (CodeFragmentPrinter) throws -> Void) rethrows { + guard codecBodies[name] == nil else { return } + let printer = CodeFragmentPrinter() + try build(printer) + guard codecBodies[name] == nil else { return } + codecBodies[name] = printer.lines + codecNameOrder.append(name) + } + + var hasNamedCodecs: Bool { + !codecNameOrder.isEmpty + } + + func emitNamedCodecLines() -> [String] { + codecNameOrder.flatMap { codecBodies[$0] ?? [] } + } + func reset() { entries.removeAll() classNamespaces.removeAll() + typeOwnerModules.removeAll() + codecNameOrder.removeAll() + codecBodies.removeAll() } func emitLines() -> [String] { diff --git a/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift b/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift index 5507f39c2..ed7dee420 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift @@ -22,6 +22,14 @@ extension NamespacedExportedType { public struct ABINameGenerator { static let prefixComponent = "bjs" + public static func genericTypeIdParameterName(index: Int) -> String { "_generic\(index)TypeId" } + + public static func typeRegistrationFunctionName(moduleName: String) -> String { + "bjs_\(moduleName)_register_type_handles" + } + + public static let coreTypeRegistrationFunctionName = "bjs_core_register_type_handles" + /// Generates ABI name using standardized namespace + context pattern public static func generateABIName( baseName: String, @@ -273,10 +281,104 @@ public enum BridgeType: Codable, Equatable, Hashable, Sendable { case namespaceEnum(String) case swiftProtocol(String) case swiftStruct(String) + case generic(String) indirect case closure(ClosureSignature, useJSTypedClosure: Bool) indirect case alias(name: String, underlying: BridgeType) } +extension BridgeType { + public var referencedGenericName: String? { + switch self { + case .generic(let name): return name + case .array(.generic(let name)): return name + case .nullable(.generic(let name), _): return name + case .dictionary(.generic(let name)): return name + default: return nil + } + } + + public static let genericBridgeablePrimitives: [(token: String, type: BridgeType)] = [ + ("Bool", .bool), + ("Int", .integer(.int)), + ("Int8", .integer(.int8)), + ("UInt8", .integer(.uint8)), + ("Int16", .integer(.int16)), + ("UInt16", .integer(.uint16)), + ("Int32", .integer(.int32)), + ("UInt32", .integer(.uint32)), + ("UInt", .integer(.uint)), + ("Int64", .integer(.int64)), + ("UInt64", .integer(.uint64)), + ("Float", .float), + ("Double", .double), + ("String", .string), + ("JSValue", .jsValue), + ] + +} + +public struct GenericBridgeableTypeEntry: Sendable { + public let swiftName: String + public let bridgeType: BridgeType + + public init(swiftName: String, bridgeType: BridgeType) { + self.swiftName = swiftName + self.bridgeType = bridgeType + } +} + +extension ExportedEnum { + public var genericBridgeType: BridgeType? { + switch enumType { + case .simple: + return .caseEnum(swiftCallName) + case .rawValue: + guard let rawType = rawType else { return nil } + return .rawValueEnum(swiftCallName, rawType) + case .associatedValue: + return .associatedValueEnum(swiftCallName) + case .namespace: + return nil + } + } +} + +extension ExportedSkeleton { + /// Keep this order in sync with the generated registration codec array. + public var genericBridgeableTypeEntries: [GenericBridgeableTypeEntry] { + var entries: [GenericBridgeableTypeEntry] = [] + for structDef in structs { + entries.append( + GenericBridgeableTypeEntry( + swiftName: structDef.swiftCallName, + bridgeType: .swiftStruct(structDef.swiftCallName) + ) + ) + } + for klass in classes where klass.isFinal == true { + entries.append( + GenericBridgeableTypeEntry( + swiftName: klass.swiftCallName, + bridgeType: .swiftHeapObject(klass.swiftCallName) + ) + ) + } + for enumDef in enums { + guard let bridgeType = enumDef.genericBridgeType else { continue } + entries.append(GenericBridgeableTypeEntry(swiftName: enumDef.swiftCallName, bridgeType: bridgeType)) + } + return entries + } +} + +extension BridgeJSSkeleton { + public var typeRegistrationEntries: [GenericBridgeableTypeEntry]? { + let exportedEntries = exported?.genericBridgeableTypeEntries ?? [] + guard !exportedEntries.isEmpty else { return nil } + return exportedEntries + } +} + public enum WasmCoreType: String, Codable, Sendable { case i32, i64, f32, f64, pointer } @@ -861,6 +963,7 @@ public struct ExportedProtocol: Codable, Equatable { public struct ExportedFunction: Codable, Equatable, Sendable { public var name: String + public var jsName: String? public var abiName: String public var parameters: [Parameter] public var returnType: BridgeType @@ -869,8 +972,11 @@ public struct ExportedFunction: Codable, Equatable, Sendable { public var staticContext: StaticContext? public var documentation: String? + public var resolvedJSName: String { jsName ?? name } + public init( name: String, + jsName: String? = nil, abiName: String, parameters: [Parameter], returnType: BridgeType, @@ -880,6 +986,7 @@ public struct ExportedFunction: Codable, Equatable, Sendable { documentation: String? = nil ) { self.name = name + self.jsName = jsName self.abiName = abiName self.parameters = parameters self.returnType = returnType @@ -900,6 +1007,7 @@ public struct ExportedClass: Codable, NamespacedExportedType { public var namespace: [String]? public var identityMode: Bool? // nil = use config default, true/false = override public var documentation: String? + public var isFinal: Bool? public init( name: String, @@ -910,7 +1018,8 @@ public struct ExportedClass: Codable, NamespacedExportedType { properties: [ExportedProperty] = [], namespace: [String]? = nil, identityMode: Bool? = nil, - documentation: String? = nil + documentation: String? = nil, + isFinal: Bool? = nil ) { self.name = name self.swiftCallName = swiftCallName @@ -921,6 +1030,7 @@ public struct ExportedClass: Codable, NamespacedExportedType { self.namespace = namespace self.identityMode = identityMode self.documentation = documentation + self.isFinal = isFinal } } @@ -948,6 +1058,7 @@ public struct ExportedConstructor: Codable, Equatable, Sendable { public struct ExportedProperty: Codable, Equatable, Sendable { public var name: String + public var jsName: String? public var type: BridgeType public var isReadonly: Bool public var isStatic: Bool @@ -955,8 +1066,11 @@ public struct ExportedProperty: Codable, Equatable, Sendable { public var staticContext: StaticContext? public var documentation: String? + public var resolvedJSName: String { jsName ?? name } + public init( name: String, + jsName: String? = nil, type: BridgeType, isReadonly: Bool = false, isStatic: Bool = false, @@ -965,6 +1079,7 @@ public struct ExportedProperty: Codable, Equatable, Sendable { documentation: String? = nil ) { self.name = name + self.jsName = jsName self.type = type self.isReadonly = isReadonly self.isStatic = isStatic @@ -1244,6 +1359,11 @@ public struct ImportedFunctionSkeleton: Codable { /// determine the access level of bridge-generated helpers (e.g. typed /// closure inits) that surface through this function's signature. public let accessLevel: BridgeJSAccessLevel + public let genericParameters: [String]? + public var genericParameterNames: [String] { genericParameters ?? [] } + public var isGeneric: Bool { !genericParameterNames.isEmpty } + + public var resolvedJSName: String { jsName ?? name } public init( name: String, @@ -1253,7 +1373,8 @@ public struct ImportedFunctionSkeleton: Codable { returnType: BridgeType, effects: Effects = Effects(isAsync: false, isThrows: true), documentation: String? = nil, - accessLevel: BridgeJSAccessLevel = .internal + accessLevel: BridgeJSAccessLevel = .internal, + genericParameters: [String]? = nil ) { self.name = name self.jsName = jsName @@ -1263,10 +1384,11 @@ public struct ImportedFunctionSkeleton: Codable { self.effects = effects self.documentation = documentation self.accessLevel = accessLevel + self.genericParameters = genericParameters } private enum CodingKeys: String, CodingKey { - case name, jsName, from, parameters, returnType, effects, documentation, accessLevel + case name, jsName, from, parameters, returnType, effects, documentation, accessLevel, genericParameters } public init(from decoder: any Decoder) throws { @@ -1279,6 +1401,7 @@ public struct ImportedFunctionSkeleton: Codable { self.effects = try container.decode(Effects.self, forKey: .effects) self.documentation = try container.decodeIfPresent(String.self, forKey: .documentation) self.accessLevel = try container.decodeIfPresent(BridgeJSAccessLevel.self, forKey: .accessLevel) ?? .internal + self.genericParameters = try container.decodeIfPresent([String].self, forKey: .genericParameters) } public func abiName(context: ImportedTypeSkeleton?) -> String { @@ -1299,20 +1422,29 @@ public struct ImportedConstructorSkeleton: Codable { /// Source access level of the originating Swift `init`. Inherits from the /// enclosing `@JSClass` type when not annotated explicitly. public let accessLevel: BridgeJSAccessLevel + public let genericParameters: [String]? + public var genericParameterNames: [String] { genericParameters ?? [] } + public var isGeneric: Bool { !genericParameterNames.isEmpty } - public init(parameters: [Parameter], accessLevel: BridgeJSAccessLevel = .internal) { + public init( + parameters: [Parameter], + accessLevel: BridgeJSAccessLevel = .internal, + genericParameters: [String]? = nil + ) { self.parameters = parameters self.accessLevel = accessLevel + self.genericParameters = genericParameters } private enum CodingKeys: String, CodingKey { - case parameters, accessLevel + case parameters, accessLevel, genericParameters } public init(from decoder: any Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) self.parameters = try container.decode([Parameter].self, forKey: .parameters) self.accessLevel = try container.decodeIfPresent(BridgeJSAccessLevel.self, forKey: .accessLevel) ?? .internal + self.genericParameters = try container.decodeIfPresent([String].self, forKey: .genericParameters) } public func abiName(context: ImportedTypeSkeleton) -> String { @@ -1336,6 +1468,8 @@ public struct ImportedGetterSkeleton: Codable { /// Source access level of the originating Swift declaration. public let accessLevel: BridgeJSAccessLevel + public var resolvedJSName: String { jsName ?? name } + public init( name: String, jsName: String? = nil, @@ -1396,6 +1530,8 @@ public struct ImportedSetterSkeleton: Codable { /// Source access level of the originating Swift declaration. public let accessLevel: BridgeJSAccessLevel + public var resolvedJSName: String { jsName ?? name } + public init( name: String, jsName: String? = nil, @@ -1458,6 +1594,8 @@ public struct ImportedTypeSkeleton: Codable { /// Source access level of the originating Swift `@JSClass` declaration. public let accessLevel: BridgeJSAccessLevel + public var resolvedJSName: String { jsName ?? name } + public init( name: String, jsName: String? = nil, @@ -1553,6 +1691,17 @@ public struct ImportedFileSkeleton: Codable { } } +extension ImportedFileSkeleton { + public var hasGenericDeclarations: Bool { + functions.contains(where: \.isGeneric) + || types.contains { + $0.methods.contains(where: \.isGeneric) + || $0.staticMethods.contains(where: \.isGeneric) + || ($0.constructor?.isGeneric ?? false) + } + } +} + public struct ImportedModuleSkeleton: Codable { public var children: [ImportedFileSkeleton] @@ -1561,6 +1710,12 @@ public struct ImportedModuleSkeleton: Codable { } } +extension ImportedModuleSkeleton { + public var hasGenericDeclarations: Bool { + children.contains { $0.hasGenericDeclarations } + } +} + // MARK: - Closure signature collection visitor public struct ClosureSignatureCollectorVisitor: BridgeSkeletonVisitor { @@ -1735,7 +1890,7 @@ extension BridgeType { case .bool, .integer, .float, .double, .string, .jsValue, .jsObject, .swiftHeapObject, .unsafePointer, .swiftProtocol, .void, .caseEnum, .rawValueEnum, .associatedValueEnum, .swiftStruct, - .namespaceEnum, .closure: + .namespaceEnum, .closure, .generic: return self } } @@ -1782,6 +1937,8 @@ extension BridgeType { return nil case .alias(_, let underlying): return underlying.abiReturnType + case .generic: + return nil } } @@ -1873,6 +2030,8 @@ extension BridgeType { // `name` is the namespace-qualified swiftCallName (unique), so the underlying // representation isn't mangled in - aliases bridge via their JS type's ABI. return "Al\(name.count)\(name)" + case .generic(let name): + return "\(name.count)\(name)T" } } diff --git a/Plugins/BridgeJS/Sources/BridgeJSTool/BridgeJSTool.swift b/Plugins/BridgeJS/Sources/BridgeJSTool/BridgeJSTool.swift index 140ebda63..96d9c4705 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSTool/BridgeJSTool.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSTool/BridgeJSTool.swift @@ -240,9 +240,12 @@ import BridgeJSUtilities return try exporter?.finalize() } + // Type-handle registration is shared by exported types and generic imports. + let typeRegistration = GenericTypeRegistrationCodegen().render(for: skeleton) + // Combine and write unified Swift output let outputSwiftURL = outputDirectory.appending(path: "BridgeJS.swift") - let combinedSwift = [closureSupport, exportResult, importResult].compactMap { $0 } + let combinedSwift = [closureSupport, exportResult, importResult, typeRegistration].compactMap { $0 } let outputSwift = combineGeneratedSwift( combinedSwift, importingExternalModules: skeleton.usedExternalModules diff --git a/Plugins/BridgeJS/Sources/BridgeJSToolInternal/BridgeJSToolInternal.swift b/Plugins/BridgeJS/Sources/BridgeJSToolInternal/BridgeJSToolInternal.swift index cb6a5481c..971c9608e 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSToolInternal/BridgeJSToolInternal.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSToolInternal/BridgeJSToolInternal.swift @@ -98,7 +98,8 @@ import ArgumentParser skeleton: $0 ).finalize() } - let combinedSwift = [exported, imported].compactMap { $0 } + let typeRegistration = GenericTypeRegistrationCodegen().render(for: skeleton) + let combinedSwift = [exported, imported, typeRegistration].compactMap { $0 } print(combinedSwift.joined(separator: "\n\n")) } } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/BridgeJSCodegenTests.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/BridgeJSCodegenTests.swift index 60b2fd485..6d2f3d453 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/BridgeJSCodegenTests.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/BridgeJSCodegenTests.swift @@ -141,6 +141,9 @@ import Testing swiftParts.append(s) } } + if let typeRegistration = GenericTypeRegistrationCodegen().render(for: skeleton) { + swiftParts.append(typeRegistration) + } let combinedSwift = swiftParts .map { $0.trimmingCharacters(in: .newlines) } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/BridgeJSLinkTests.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/BridgeJSLinkTests.swift index 642debedc..cab2aca6f 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/BridgeJSLinkTests.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/BridgeJSLinkTests.swift @@ -139,6 +139,26 @@ import Testing try snapshot(bridgeJSLink: bridgeJSLink, name: "MixedModules") } + private func linkedJS(forFixture input: String) throws -> String { + let url = Self.inputsDirectory.appendingPathComponent(input) + let name = url.deletingPathExtension().lastPathComponent + let sourceFile = Parser.parse(source: try String(contentsOf: url, encoding: .utf8)) + let importSwift = SwiftToSkeleton( + progress: .silent, + moduleName: "TestModule", + exposeToGlobal: false, + externalModuleIndex: .empty + ) + importSwift.addSourceFile(sourceFile, inputFilePath: "\(name).swift") + let importResult = try importSwift.finalize() + var bridgeJSLink = BridgeJSLink(sharedMemory: false) + let encoder = JSONEncoder() + encoder.outputFormatting = [.prettyPrinted, .sortedKeys] + let unifiedData = try encoder.encode(importResult) + try bridgeJSLink.addSkeletonFile(data: unifiedData) + return try bridgeJSLink.link().0 + } + @Test func perClassIdentityModeFromAnnotation() throws { let url = Self.inputsDirectory.appendingPathComponent("IdentityModeClass.swift") diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/CodegenTestSupport.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/CodegenTestSupport.swift new file mode 100644 index 000000000..b66a5ba6f --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/CodegenTestSupport.swift @@ -0,0 +1,40 @@ +import Foundation +import SwiftParser +import SwiftSyntax +import Testing + +@testable import BridgeJSLink +@testable import BridgeJSCore +@testable import BridgeJSSkeleton + +func makeSkeleton( + _ source: String, + moduleName: String = "TestModule", + dependencies: [(moduleName: String, skeleton: BridgeJSSkeleton)] = [] +) throws -> BridgeJSSkeleton { + let swiftAPI = SwiftToSkeleton( + progress: .silent, + moduleName: moduleName, + exposeToGlobal: false, + externalModuleIndex: ExternalModuleIndex(dependencies: dependencies) + ) + swiftAPI.addSourceFile(Parser.parse(source: source), inputFilePath: "\(moduleName).swift") + return try swiftAPI.finalize() +} + +func expectDiagnostic( + source: String, + moduleName: String = "App", + contains message: String, + sourceLocation: Testing.SourceLocation = #_sourceLocation +) { + do { + _ = try makeSkeleton(source, moduleName: moduleName) + Issue.record("Expected diagnostic but resolution succeeded", sourceLocation: sourceLocation) + } catch let error as BridgeJSCoreDiagnosticError { + let combined = error.diagnostics.map(\.diagnostic.message).joined(separator: "\n") + #expect(combined.contains(message), sourceLocation: sourceLocation) + } catch { + Issue.record("Unexpected error: \(error)", sourceLocation: sourceLocation) + } +} diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/DiagnosticsTests.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/DiagnosticsTests.swift index 316d51b41..4f45a9880 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/DiagnosticsTests.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/DiagnosticsTests.swift @@ -26,6 +26,44 @@ import Testing } } + @Test + func extensionOfUnknownTypeWithJSMemberProducesDiagnostic() throws { + let source = """ + extension Unknown { + @JS func bridged() -> Int { 42 } + } + """ + let diagnostics = try #require(moduleDiagnostics(source: source)) + #expect(diagnostics.description.contains("Unsupported type 'Unknown'")) + } + + @Test + func extensionWithoutJSMembersIsIgnored() throws { + let source = """ + extension String { + func helper() -> Int { 42 } + } + """ + #expect(moduleDiagnostics(source: source) == nil) + } + + @Test + func invalidJSMemberInsideExtensionProducesDiagnostic() throws { + let source = """ + @JS class Host { + @JS init() {} + } + + extension Host { + @JS struct Bad { + var field = 1 + } + } + """ + let diagnostics = try #require(moduleDiagnostics(source: source)) + #expect(diagnostics.description.contains("Struct field must have explicit type annotation")) + } + @Test func missingJavaScriptModuleProducesDiagnostic() throws { let source = """ @@ -658,6 +696,87 @@ import Testing } } + @Test + func jsNameOnClassDiagnostic() throws { + let source = """ + @JS("Renamed") class Box { @JS init() {} } + """ + let diagnostics = try #require(moduleDiagnostics(source: source)) + #expect(diagnostics.description.contains("A separate name for JavaScript is not supported here")) + } + + @Test + func jsNameOnStructDiagnostic() throws { + let source = """ + @JS("Renamed") struct Box { var x: Int } + """ + let diagnostics = try #require(moduleDiagnostics(source: source)) + #expect(diagnostics.description.contains("A separate name for JavaScript is not supported here")) + } + + @Test + func jsNameOnEnumDiagnostic() throws { + let source = """ + @JS("Renamed") enum Box { case a } + """ + let diagnostics = try #require(moduleDiagnostics(source: source)) + #expect(diagnostics.description.contains("A separate name for JavaScript is not supported here")) + } + + @Test + func jsNameOnProtocolDiagnostic() throws { + let source = """ + @JS("Renamed") protocol Box { func run() } + """ + let diagnostics = try #require(moduleDiagnostics(source: source)) + #expect(diagnostics.description.contains("A separate name for JavaScript is not supported here")) + } + + @Test + func jsNameOnInitializerDiagnostic() throws { + let source = """ + @JS class Box { @JS("create") init() {} } + """ + let diagnostics = try #require(moduleDiagnostics(source: source)) + #expect(diagnostics.description.contains("A separate name for JavaScript is not supported here")) + } + + @Test + func jsNameOnProtocolRequirementDiagnostic() throws { + let source = """ + @JS protocol Box { @JS("run") func run() } + """ + let diagnostics = try #require(moduleDiagnostics(source: source)) + #expect(diagnostics.description.contains("A separate name for JavaScript is not supported here")) + } + + @Test + func invalidJSNameDiagnostic() throws { + let source = """ + @JS("1notAnIdentifier") func a() -> Int { 42 } + @JS("has space") func b() -> Int { 42 } + @JS("has-dash") func c() -> Int { 42 } + @JS("") func d() -> Int { 42 } + """ + let diagnostics = try #require(moduleDiagnostics(source: source)) + #expect(diagnostics.description.contains("`1notAnIdentifier` is not a valid JavaScript identifier")) + #expect(diagnostics.description.contains("`has space` is not a valid JavaScript identifier")) + #expect(diagnostics.description.contains("`has-dash` is not a valid JavaScript identifier")) + #expect(diagnostics.description.contains("`` is not a valid JavaScript identifier")) + } + + @Test + func jsNameOnMultipleBindingsDiagnostic() throws { + let source = """ + @JS class Box { + @JS init() {} + @JS("renamed") var first: Int = 1, second: Int = 2 + } + """ + let diagnostics = try #require(moduleDiagnostics(source: source)) + #expect(diagnostics.description.contains("Name targets declaration with multiple bindings")) + } + @Test func omitsNextLineWhenErrorIsOnLastLine() throws { let source = """ diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/GenericExportDiagnosticsTests.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/GenericExportDiagnosticsTests.swift new file mode 100644 index 000000000..37f2a0318 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/GenericExportDiagnosticsTests.swift @@ -0,0 +1,63 @@ +import Testing + +@Suite struct GenericExportDiagnosticsTests { + + @Test + func genericExportedFunctionRejected() { + expectDiagnostic( + source: """ + @JS public func identity(_ value: T) -> T { value } + """, + contains: "Generic parameters on exported @JS functions are not supported yet" + ) + } + + @Test + func genericMethodOnExportedClassRejected() { + expectDiagnostic( + source: """ + @JS final class Box { + @JS init() {} + @JS func wrap(_ value: T) -> T { value } + } + """, + contains: "Generic parameters on exported @JS functions are not supported yet" + ) + } + + @Test + func genericMethodOnExportedStructRejected() { + expectDiagnostic( + source: """ + @JS struct Pair { + @JS init() {} + @JS func first(_ value: T) -> T { value } + } + """, + contains: "Generic parameters on exported @JS functions are not supported yet" + ) + } + + @Test + func genericStaticMethodOnExportedEnumRejected() { + expectDiagnostic( + source: """ + @JS enum Factory { + case primary + @JS static func one(_ value: T) -> T { value } + } + """, + contains: "Generic parameters on exported @JS functions are not supported yet" + ) + } + + @Test + func unconstrainedGenericExportedFunctionRejected() { + expectDiagnostic( + source: """ + @JS public func identity(_ value: T) -> T { value } + """, + contains: "Generic parameters on exported @JS functions are not supported yet" + ) + } +} diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/GenericImportDiagnosticsTests.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/GenericImportDiagnosticsTests.swift new file mode 100644 index 000000000..4a421b73b --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/GenericImportDiagnosticsTests.swift @@ -0,0 +1,210 @@ +import Testing + +@testable import BridgeJSSkeleton + +@Suite struct GenericImportDiagnosticsTests { + + @Test + func genericParameterRequiresBridgeableConstraint() { + expectDiagnostic( + source: """ + @JSFunction func identity(_ value: T) throws(JSException) -> T + """, + contains: "Generic parameter 'T' must be constrained to 'BridgedSwiftGenericBridgeable'" + ) + } + + @Test + func genericWhereClauseUnsupported() { + expectDiagnostic( + source: """ + @JSFunction func identity(_ value: T) throws(JSException) -> T where T: Sendable + """, + contains: "'where' clauses are not supported on @JSFunction" + ) + } + + @Test + func asyncGenericImportUnsupported() { + expectDiagnostic( + source: """ + @JSFunction func identityAsync(_ value: T) async throws(JSException) -> T + """, + contains: "Generic @JSFunction declarations cannot be 'async' yet." + ) + } + + @Test + func genericImportedMethodIsParsed() throws { + let skeleton = try makeSkeleton( + """ + @JSClass struct Box { + @JSFunction func member(_ value: T) throws(JSException) -> T + } + """, + moduleName: "App" + ) + let imported = try #require(skeleton.imported) + let types = imported.children.flatMap { $0.types } + let box = try #require(types.first { $0.name == "Box" }) + let method = try #require(box.methods.first { $0.name == "member" }) + #expect(method.genericParameters == ["T"]) + } + + @Test + func genericImportedConstructorIsParsed() throws { + let skeleton = try makeSkeleton( + """ + @JSClass struct Box { + @JSFunction init(_ value: T) throws(JSException) + } + """, + moduleName: "App" + ) + let imported = try #require(skeleton.imported) + let types = imported.children.flatMap { $0.types } + let box = try #require(types.first { $0.name == "Box" }) + let constructor = try #require(box.constructor) + #expect(constructor.genericParameters == ["T"]) + #expect(constructor.parameters.map(\.type) == [.generic("T")]) + } + + @Test + func genericImportedConstructorUnconstrainedParamIsRejected() { + expectDiagnostic( + source: """ + @JSClass struct Box { + @JSFunction init(_ value: T) throws(JSException) + } + """, + contains: + "Generic parameter 'T' must be constrained to 'BridgedSwiftGenericBridgeable' to be used with @JSFunction." + ) + } + + @Test + func genericImportedConstructorUnusedTypeParamIsRejected() { + expectDiagnostic( + source: """ + @JSClass struct Box { + @JSFunction init(_ value: Int) throws(JSException) + } + """, + contains: + "The generic parameter 'T' must be used in a parameter of a generic @JSFunction initializer." + ) + } + + @Test + func genericImportedConstructorAsyncIsRejected() { + expectDiagnostic( + source: """ + @JSClass struct Box { + @JSFunction init(_ value: T) async throws(JSException) + } + """, + contains: "Generic @JSFunction declarations cannot be 'async' yet." + ) + } + + @Test + func genericImportedConstructorUnsupportedWrapperFormIsRejected() { + expectDiagnostic( + source: """ + @JSClass struct Box { + @JSFunction init(_ value: [[T]]) throws(JSException) + } + """, + contains: "may only be used as a bare type" + ) + } + + @Test(arguments: [ + ("[[T]]", "@JSFunction func f(_ v: [[T]]) throws(JSException)"), + ("[T?]", "@JSFunction func f(_ v: [T?]) throws(JSException)"), + ("T??", "@JSFunction func f(_ v: T??) throws(JSException)"), + ("[Int: T]", "@JSFunction func f(_ v: [Int: T]) throws(JSException)"), + ]) + func unsupportedGenericWrapperFormsInParameter(label: String, source: String) { + expectDiagnostic( + source: source, + contains: "may only be used as a bare type" + ) + } + + @Test(arguments: [ + ("[[T]]", "@JSFunction func f(_ v: T) throws(JSException) -> [[T]]"), + ("[T?]", "@JSFunction func f(_ v: T) throws(JSException) -> [T?]"), + ("T??", "@JSFunction func f(_ v: T) throws(JSException) -> T??"), + ("[Int: T]", "@JSFunction func f(_ v: T) throws(JSException) -> [Int: T]"), + ]) + func unsupportedGenericWrapperFormsInReturn(label: String, source: String) { + expectDiagnostic( + source: source, + contains: "may only be used as a bare type" + ) + } + + @Test + func genericImportedMethodAsyncIsRejected() { + expectDiagnostic( + source: """ + @JSClass struct Box { + @JSFunction func member(_ value: T) async throws(JSException) -> T + } + """, + contains: "Generic @JSFunction declarations cannot be 'async' yet." + ) + } + + @Test + func genericImportedMethodUnconstrainedParamIsRejected() { + expectDiagnostic( + source: """ + @JSClass struct Box { + @JSFunction func member(_ value: T) throws(JSException) -> T + } + """, + contains: + "Generic parameter 'T' must be constrained to 'BridgedSwiftGenericBridgeable' to be used with @JSFunction." + ) + } + + @Test + func genericImportedFunctionUnusedTypeParamIsRejected() { + expectDiagnostic( + source: """ + @JSFunction func unused() throws(JSException) -> Int + """, + contains: + "The generic parameter 'T' must be used in a parameter or return type of a generic @JSFunction declaration." + ) + } + + @Test + func genericImportedMethodUnusedTypeParamIsRejected() { + expectDiagnostic( + source: """ + @JSClass struct Box { + @JSFunction func member() throws(JSException) -> Int + } + """, + contains: + "The generic parameter 'T' must be used in a parameter or return type of a generic @JSFunction declaration." + ) + } + + @Test + func genericImportedReturnOnlyTypeParamIsAllowed() throws { + let skeleton = try makeSkeleton( + """ + @JSFunction func make() throws(JSException) -> T + """, + moduleName: "App" + ) + let imported = try #require(skeleton.imported) + let functions = imported.children.flatMap { $0.functions } + let function = try #require(functions.first { $0.name == "make" }) + #expect(function.genericParameters == ["T"]) + } +} diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/GenericImports.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/GenericImports.swift new file mode 100644 index 000000000..5fd3d0226 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/GenericImports.swift @@ -0,0 +1,74 @@ +@JS +struct GenericPoint { + var x: Int + var y: Int +} + +@JS enum GenericColor { + case red + case green +} + +@JS enum GenericMode: String { + case light + case dark +} + +@JS enum GenericTagged { + case number(value: Int) + case text(value: String) +} + +@JS final class GenericImportBox { + @JS var value: Int + @JS init(value: Int) { + self.value = value + } + @JS func get() -> Int { + value + } +} + +@JSFunction func genericRoundTrip(_ value: T) throws(JSException) -> T + +@JSFunction func genericParse(_ json: String) throws(JSException) -> T + +@JSFunction func importGenericCombine( + _ a: T, + _ b: U +) throws(JSException) -> U + +@JSFunction func importGenericCaseDistinct( + _ a: T, + _ b: t +) throws(JSException) -> T + +@JSFunction func importGenericArray(_ values: [T]) throws(JSException) -> [T] + +@JSFunction func importGenericOptional(_ value: T?) throws(JSException) -> T? + +@JSFunction func importGenericDictionary( + _ values: [String: T] +) throws(JSException) -> [String: T] + +// A generic parameter alongside another parameter that pushes onto the shared +// stacks: both are lowered in reverse declaration order. +@JSFunction func importGenericAfterOptionalArray( + _ values: [Int]?, + _ value: T +) throws(JSException) -> T + +@JSClass struct GenericPairFactory { + @JSFunction init( + _ tag: String, + _ first: T, + _ second: U + ) throws(JSException) +} + +@JSClass struct GenericConsumer { + @JSFunction init(_ value: T) throws(JSException) + @JSFunction func accept(_ value: T) throws(JSException) + @JSFunction func identity(_ value: T) throws(JSException) -> T + @JSFunction static func box(_ value: T) throws(JSException) -> T +} diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/JSNameOverride.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/JSNameOverride.swift new file mode 100644 index 000000000..fc5777a15 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/MacroSwift/JSNameOverride.swift @@ -0,0 +1,40 @@ +@JS("makeGreeting") func renderGreeting(name: String) -> String + +@JS("greetName") func greet(_ name: String) -> String + +@JS("greetCount") func greet(_ count: Int) -> String + +@JS("namespacedRenamed", namespace: "Utils.Text") func namespacedFunction() -> Int + +@JS class RenamedMembers { + @JS("label") var title: String + @JS("total") let count: Int + @JS("sharedTotal") nonisolated(unsafe) static var sharedCount: Int = 0 + @JS("readOnlyLimit") static let limit: Int = 10 + + @JS init(title: String, count: Int) + @JS("makeGreeting") func greet() -> String + @JS("makeDefault") static func createDefault() -> RenamedMembers +} + +@JS struct RenamedVector { + var dx: Double + var dy: Double + + @JS("originVector") static let origin: RenamedVector = RenamedVector(dx: 0, dy: 0) + @JS("magnitude") func length() -> Double + @JS("fromPolar") static func polar(radius: Double, angle: Double) -> RenamedVector +} + +@JS enum RenamedEnumMembers { + case active + case inactive + + @JS("describeCase") static func describe() -> String + @JS("currentDefault") nonisolated(unsafe) static var defaultValue: String = "active" +} + +@JS enum RenamedNamespaceMembers { + @JS("plus") static func add(_ a: Int, _ b: Int) -> Int + @JS("theAnswer") nonisolated(unsafe) static var answer: Int = 42 +} diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Alias.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Alias.json index bcdc43375..b47afb905 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Alias.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Alias.json @@ -79,6 +79,7 @@ } ] }, + "isFinal" : true, "methods" : [ { "abiName" : "bjs_PolygonReference_snapshot", @@ -196,6 +197,7 @@ } ] }, + "isFinal" : true, "methods" : [ ], diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Alias.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Alias.swift index a9252e57f..4483de428 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Alias.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Alias.swift @@ -257,6 +257,18 @@ fileprivate func _bjs_TagReference_wrap_extern(_ pointer: UnsafeMutableRawPointe return _bjs_TagReference_wrap_extern(pointer) } +extension PolygonReference: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = PolygonReference.bridgeJSMakeTypeHandle() +} + +extension TagReference: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = TagReference.bridgeJSMakeTypeHandle() +} + +extension InnerTag: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = InnerTag.bridgeJSMakeTypeHandle() +} + extension Polygon: _BridgedSwiftAlias, _BridgedSwiftStackType {} extension Tag: _BridgedSwiftAlias, _BridgedSwiftStackType {} @@ -394,4 +406,21 @@ func _$Surface_label_get(_ self: JSObject) throws(JSException) -> String { throw error } return String.bridgeJSLiftReturn(ret) -} \ No newline at end of file +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + PolygonReference.bridgeJSTypeID, + TagReference.bridgeJSTypeID, + InnerTag.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/AliasInClosure.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/AliasInClosure.json index d76761e0b..c9107133d 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/AliasInClosure.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/AliasInClosure.json @@ -34,6 +34,7 @@ } ] }, + "isFinal" : true, "methods" : [ ], diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/AliasInClosure.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/AliasInClosure.swift index 3c87bcdcc..0a208bf70 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/AliasInClosure.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/AliasInClosure.swift @@ -187,4 +187,23 @@ fileprivate func _bjs_PolygonReference_wrap_extern(_ pointer: UnsafeMutableRawPo return _bjs_PolygonReference_wrap_extern(pointer) } -extension Polygon: _BridgedSwiftAlias, _BridgedSwiftStackType {} \ No newline at end of file +extension PolygonReference: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = PolygonReference.bridgeJSMakeTypeHandle() +} + +extension Polygon: _BridgedSwiftAlias, _BridgedSwiftStackType {} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + PolygonReference.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ArrayTypes.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ArrayTypes.swift index 51c6911bd..94b8eb208 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ArrayTypes.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ArrayTypes.swift @@ -501,6 +501,18 @@ fileprivate func _bjs_MultiArrayContainer_wrap_extern(_ pointer: UnsafeMutableRa return _bjs_MultiArrayContainer_wrap_extern(pointer) } +extension Point: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Point.bridgeJSMakeTypeHandle() +} + +extension Direction: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Direction.bridgeJSMakeTypeHandle() +} + +extension Status: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Status.bridgeJSMakeTypeHandle() +} + #if arch(wasm32) @_extern(wasm, module: "TestModule", name: "bjs_checkArray") fileprivate func bjs_checkArray_extern(_ a: Int32) -> Void @@ -643,4 +655,21 @@ func _$importProcessBooleans(_ values: [Bool]) throws(JSException) -> [Bool] { throw error } return [Bool].bridgeJSLiftReturn() -} \ No newline at end of file +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Point.bridgeJSTypeID, + Direction.bridgeJSTypeID, + Status.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Async.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Async.swift index f2223ee7c..35618554c 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Async.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Async.swift @@ -335,6 +335,18 @@ public func _bjs_asyncRoundTripEnumDictionary() -> Int32 { #endif } +extension AsyncPoint: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = AsyncPoint.bridgeJSMakeTypeHandle() +} + +extension AsyncDirection: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = AsyncDirection.bridgeJSMakeTypeHandle() +} + +extension AsyncTheme: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = AsyncTheme.bridgeJSMakeTypeHandle() +} + @JSFunction func Promise_reject(_ promise: JSObject, _ value: JSValue) throws(JSException) #if arch(wasm32) @@ -614,20 +626,20 @@ func _$Promise_resolve_Sq10AsyncThemeO(_ promise: JSObject, _ value: Optional Void +fileprivate func promise_resolve_TestModule_Sq10AsyncPointV_extern(_ promise: Int32) -> Void #else -fileprivate func promise_resolve_TestModule_Sq10AsyncPointV_extern(_ promise: Int32, _ value: Int32) -> Void { +fileprivate func promise_resolve_TestModule_Sq10AsyncPointV_extern(_ promise: Int32) -> Void { fatalError("Only available on WebAssembly") } #endif -@inline(never) fileprivate func promise_resolve_TestModule_Sq10AsyncPointV(_ promise: Int32, _ value: Int32) -> Void { - return promise_resolve_TestModule_Sq10AsyncPointV_extern(promise, value) +@inline(never) fileprivate func promise_resolve_TestModule_Sq10AsyncPointV(_ promise: Int32) -> Void { + return promise_resolve_TestModule_Sq10AsyncPointV_extern(promise) } func _$Promise_resolve_Sq10AsyncPointV(_ promise: JSObject, _ value: Optional) throws(JSException) -> Void { - let valueIsSome = value.bridgeJSLowerParameter() + let _ = value.bridgeJSLowerParameter() let promiseValue = promise.bridgeJSLowerParameter() - promise_resolve_TestModule_Sq10AsyncPointV(promiseValue, valueIsSome) + promise_resolve_TestModule_Sq10AsyncPointV(promiseValue) if let error = _swift_js_take_exception() { throw error } } @@ -713,4 +725,21 @@ func _$Promise_resolve_SD14AsyncDirectionO(_ promise: JSObject, _ value: [String let promiseValue = promise.bridgeJSLowerParameter() promise_resolve_TestModule_SD14AsyncDirectionO(promiseValue) if let error = _swift_js_take_exception() { throw error } -} \ No newline at end of file +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + AsyncPoint.bridgeJSTypeID, + AsyncDirection.bridgeJSTypeID, + AsyncTheme.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/AsyncAssociatedValueEnum.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/AsyncAssociatedValueEnum.swift index 3208eda33..6776998bc 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/AsyncAssociatedValueEnum.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/AsyncAssociatedValueEnum.swift @@ -52,6 +52,10 @@ public func _bjs_asyncRoundTripOptionalAssociatedValueEnum(_ valueIsSome: Int32, #endif } +extension AsyncPayloadResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = AsyncPayloadResult.bridgeJSMakeTypeHandle() +} + @JSFunction func Promise_reject(_ promise: JSObject, _ value: JSValue) throws(JSException) #if arch(wasm32) @@ -113,4 +117,19 @@ func _$Promise_resolve_Sq18AsyncPayloadResultO(_ promise: JSObject, _ value: Opt let promiseValue = promise.bridgeJSLowerParameter() promise_resolve_TestModule_Sq18AsyncPayloadResultO(promiseValue, valueIsSome, valueCaseId) if let error = _swift_js_take_exception() { throw error } -} \ No newline at end of file +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + AsyncPayloadResult.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ClassWithNestedTypes.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ClassWithNestedTypes.swift index 52c633045..c9c291317 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ClassWithNestedTypes.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ClassWithNestedTypes.swift @@ -174,4 +174,28 @@ fileprivate func _bjs_Account_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> #endif @inline(never) fileprivate func _bjs_Account_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { return _bjs_Account_wrap_extern(pointer) -} \ No newline at end of file +} + +extension Account.Credentials: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Account.Credentials.bridgeJSMakeTypeHandle() +} + +extension Account.Role: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Account.Role.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Account.Credentials.bridgeJSTypeID, + Account.Role.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DefaultParameters.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DefaultParameters.swift index 507827646..e2e74e532 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DefaultParameters.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DefaultParameters.swift @@ -636,4 +636,33 @@ fileprivate func _bjs_ConstructorDefaults_wrap_extern(_ pointer: UnsafeMutableRa #endif @inline(never) fileprivate func _bjs_ConstructorDefaults_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { return _bjs_ConstructorDefaults_wrap_extern(pointer) -} \ No newline at end of file +} + +extension Config: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Config.bridgeJSMakeTypeHandle() +} + +extension MathOperations: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = MathOperations.bridgeJSMakeTypeHandle() +} + +extension Status: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Status.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Config.bridgeJSTypeID, + MathOperations.bridgeJSTypeID, + Status.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DictionaryTypes.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DictionaryTypes.swift index 26a4c087e..2990eeabe 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DictionaryTypes.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DictionaryTypes.swift @@ -149,6 +149,10 @@ fileprivate func _bjs_Box_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int return _bjs_Box_wrap_extern(pointer) } +extension Counters: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Counters.bridgeJSMakeTypeHandle() +} + #if arch(wasm32) @_extern(wasm, module: "TestModule", name: "bjs_importMirrorDictionary") fileprivate func bjs_importMirrorDictionary_extern() -> Void @@ -168,4 +172,19 @@ func _$importMirrorDictionary(_ values: [String: Double]) throws(JSException) -> throw error } return [String: Double].bridgeJSLiftReturn() -} \ No newline at end of file +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Counters.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DocComments.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DocComments.swift index f91df6c26..fab694b18 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DocComments.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DocComments.swift @@ -314,4 +314,28 @@ fileprivate func _bjs_Greeter_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> #endif @inline(never) fileprivate func _bjs_Greeter_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { return _bjs_Greeter_wrap_extern(pointer) -} \ No newline at end of file +} + +extension Point: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Point.bridgeJSMakeTypeHandle() +} + +extension Color: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Color.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Point.bridgeJSTypeID, + Color.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAlias.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAlias.json index 0d63db899..c876db410 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAlias.json +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAlias.json @@ -31,6 +31,7 @@ } ] }, + "isFinal" : true, "methods" : [ ], diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAlias.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAlias.swift index 1e74a127b..5689b143f 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAlias.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAlias.swift @@ -51,4 +51,23 @@ fileprivate func _bjs_ColorBox_wrap_extern(_ pointer: UnsafeMutableRawPointer) - return _bjs_ColorBox_wrap_extern(pointer) } -extension Color: _BridgedSwiftAlias, _BridgedSwiftStackType {} \ No newline at end of file +extension ColorBox: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = ColorBox.bridgeJSMakeTypeHandle() +} + +extension Color: _BridgedSwiftAlias, _BridgedSwiftStackType {} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + ColorBox.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAssociatedValue.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAssociatedValue.swift index 6d5549699..4ca3236f8 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAssociatedValue.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAssociatedValue.swift @@ -631,4 +631,73 @@ fileprivate func _bjs_User_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> In #endif @inline(never) fileprivate func _bjs_User_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { return _bjs_User_wrap_extern(pointer) -} \ No newline at end of file +} + +extension Point: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Point.bridgeJSMakeTypeHandle() +} + +extension APIResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = APIResult.bridgeJSMakeTypeHandle() +} + +extension ComplexResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = ComplexResult.bridgeJSMakeTypeHandle() +} + +extension Utilities.Result: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Utilities.Result.bridgeJSMakeTypeHandle() +} + +extension NetworkingResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = NetworkingResult.bridgeJSMakeTypeHandle() +} + +extension APIOptionalResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = APIOptionalResult.bridgeJSMakeTypeHandle() +} + +extension Precision: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Precision.bridgeJSMakeTypeHandle() +} + +extension CardinalDirection: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = CardinalDirection.bridgeJSMakeTypeHandle() +} + +extension TypedPayloadResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = TypedPayloadResult.bridgeJSMakeTypeHandle() +} + +extension AllTypesResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = AllTypesResult.bridgeJSMakeTypeHandle() +} + +extension OptionalAllTypesResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = OptionalAllTypesResult.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Point.bridgeJSTypeID, + APIResult.bridgeJSTypeID, + ComplexResult.bridgeJSTypeID, + Utilities.Result.bridgeJSTypeID, + NetworkingResult.bridgeJSTypeID, + APIOptionalResult.bridgeJSTypeID, + Precision.bridgeJSTypeID, + CardinalDirection.bridgeJSTypeID, + TypedPayloadResult.bridgeJSTypeID, + AllTypesResult.bridgeJSTypeID, + OptionalAllTypesResult.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAssociatedValueImport.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAssociatedValueImport.swift index 55d1992a3..2c275a7a3 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAssociatedValueImport.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumAssociatedValueImport.swift @@ -26,6 +26,10 @@ extension PayloadSignal: _BridgedSwiftAssociatedValueEnum { } } +extension PayloadSignal: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = PayloadSignal.bridgeJSMakeTypeHandle() +} + #if arch(wasm32) @_extern(wasm, module: "TestModule", name: "bjs_PayloadSignalControls_roundTrip_static") fileprivate func bjs_PayloadSignalControls_roundTrip_static_extern(_ signal: Int32) -> Int32 @@ -109,4 +113,19 @@ func _$PayloadSignalControls_roundTripOptional(_ self: JSObject, _ signal: Optio throw error } return Optional.bridgeJSLiftReturn(ret) -} \ No newline at end of file +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + PayloadSignal.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumCase.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumCase.swift index 66692ee14..dab981312 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumCase.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumCase.swift @@ -227,4 +227,38 @@ public func _bjs_roundTripOptionalTSDirection(_ inputIsSome: Int32, _ inputValue #else fatalError("Only available on WebAssembly") #endif -} \ No newline at end of file +} + +extension Direction: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Direction.bridgeJSMakeTypeHandle() +} + +extension Status: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Status.bridgeJSMakeTypeHandle() +} + +extension TSDirection: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = TSDirection.bridgeJSMakeTypeHandle() +} + +extension PublicStatus: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = PublicStatus.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Direction.bridgeJSTypeID, + Status.bridgeJSTypeID, + TSDirection.bridgeJSTypeID, + PublicStatus.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumCaseImport.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumCaseImport.swift index f297e1620..6ed293525 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumCaseImport.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumCaseImport.swift @@ -33,6 +33,10 @@ extension Signal: _BridgedSwiftCaseEnum { } } +extension Signal: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Signal.bridgeJSMakeTypeHandle() +} + #if arch(wasm32) @_extern(wasm, module: "TestModule", name: "bjs_SignalControls_roundTrip_static") fileprivate func bjs_SignalControls_roundTrip_static_extern(_ signal: Int32) -> Int32 @@ -94,4 +98,19 @@ func _$SignalControls_current(_ self: JSObject) throws(JSException) -> Signal { throw error } return Signal.bridgeJSLiftReturn(ret) -} \ No newline at end of file +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Signal.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumNamespace.Global.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumNamespace.Global.swift index 4f588f6c7..9d6908bcc 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumNamespace.Global.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumNamespace.Global.swift @@ -358,4 +358,38 @@ fileprivate func _bjs_Formatting_Converter_wrap_extern(_ pointer: UnsafeMutableR #endif @inline(never) fileprivate func _bjs_Formatting_Converter_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { return _bjs_Formatting_Converter_wrap_extern(pointer) -} \ No newline at end of file +} + +extension Networking.API.Method: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Networking.API.Method.bridgeJSMakeTypeHandle() +} + +extension Configuration.LogLevel: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Configuration.LogLevel.bridgeJSMakeTypeHandle() +} + +extension Configuration.Port: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Configuration.Port.bridgeJSMakeTypeHandle() +} + +extension Internal.SupportedMethod: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Internal.SupportedMethod.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Networking.API.Method.bridgeJSTypeID, + Configuration.LogLevel.bridgeJSTypeID, + Configuration.Port.bridgeJSTypeID, + Internal.SupportedMethod.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumNamespace.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumNamespace.swift index 4f588f6c7..9d6908bcc 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumNamespace.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumNamespace.swift @@ -358,4 +358,38 @@ fileprivate func _bjs_Formatting_Converter_wrap_extern(_ pointer: UnsafeMutableR #endif @inline(never) fileprivate func _bjs_Formatting_Converter_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { return _bjs_Formatting_Converter_wrap_extern(pointer) -} \ No newline at end of file +} + +extension Networking.API.Method: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Networking.API.Method.bridgeJSMakeTypeHandle() +} + +extension Configuration.LogLevel: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Configuration.LogLevel.bridgeJSMakeTypeHandle() +} + +extension Configuration.Port: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Configuration.Port.bridgeJSMakeTypeHandle() +} + +extension Internal.SupportedMethod: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Internal.SupportedMethod.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Networking.API.Method.bridgeJSTypeID, + Configuration.LogLevel.bridgeJSTypeID, + Configuration.Port.bridgeJSTypeID, + Internal.SupportedMethod.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumRawType.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumRawType.swift index e70a6b0aa..2dbb21422 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumRawType.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/EnumRawType.swift @@ -451,6 +451,54 @@ public func _bjs_validateSession(_ session: Int64) -> Void { #endif } +extension Theme: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Theme.bridgeJSMakeTypeHandle() +} + +extension TSTheme: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = TSTheme.bridgeJSMakeTypeHandle() +} + +extension FeatureFlag: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = FeatureFlag.bridgeJSMakeTypeHandle() +} + +extension HttpStatus: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = HttpStatus.bridgeJSMakeTypeHandle() +} + +extension TSHttpStatus: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = TSHttpStatus.bridgeJSMakeTypeHandle() +} + +extension Priority: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Priority.bridgeJSMakeTypeHandle() +} + +extension FileSize: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = FileSize.bridgeJSMakeTypeHandle() +} + +extension UserId: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = UserId.bridgeJSMakeTypeHandle() +} + +extension TokenId: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = TokenId.bridgeJSMakeTypeHandle() +} + +extension SessionId: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = SessionId.bridgeJSMakeTypeHandle() +} + +extension Precision: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Precision.bridgeJSMakeTypeHandle() +} + +extension Ratio: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Ratio.bridgeJSMakeTypeHandle() +} + #if arch(wasm32) @_extern(wasm, module: "TestModule", name: "bjs_takesFeatureFlag") fileprivate func bjs_takesFeatureFlag_extern(_ flagBytes: Int32, _ flagLength: Int32) -> Void @@ -490,4 +538,30 @@ func _$returnsFeatureFlag() throws(JSException) -> FeatureFlag { throw error } return FeatureFlag.bridgeJSLiftReturn(ret) -} \ No newline at end of file +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Theme.bridgeJSTypeID, + TSTheme.bridgeJSTypeID, + FeatureFlag.bridgeJSTypeID, + HttpStatus.bridgeJSTypeID, + TSHttpStatus.bridgeJSTypeID, + Priority.bridgeJSTypeID, + FileSize.bridgeJSTypeID, + UserId.bridgeJSTypeID, + TokenId.bridgeJSTypeID, + SessionId.bridgeJSTypeID, + Precision.bridgeJSTypeID, + Ratio.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/GenericImports.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/GenericImports.json new file mode 100644 index 000000000..c7f3e98ae --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/GenericImports.json @@ -0,0 +1,669 @@ +{ + "exported" : { + "aliases" : [ + + ], + "classes" : [ + { + "constructor" : { + "abiName" : "bjs_GenericImportBox_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + { + "label" : "value", + "name" : "value", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ] + }, + "isFinal" : true, + "methods" : [ + { + "abiName" : "bjs_GenericImportBox_get", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "get", + "parameters" : [ + + ], + "returnType" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "name" : "GenericImportBox", + "properties" : [ + { + "isReadonly" : false, + "isStatic" : false, + "name" : "value", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "swiftCallName" : "GenericImportBox" + } + ], + "enums" : [ + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "red" + }, + { + "associatedValues" : [ + + ], + "name" : "green" + } + ], + "emitStyle" : "const", + "name" : "GenericColor", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "GenericColor", + "tsFullPath" : "GenericColor" + }, + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "light" + }, + { + "associatedValues" : [ + + ], + "name" : "dark" + } + ], + "emitStyle" : "const", + "name" : "GenericMode", + "rawType" : "String", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "GenericMode", + "tsFullPath" : "GenericMode" + }, + { + "cases" : [ + { + "associatedValues" : [ + { + "label" : "value", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "name" : "number" + }, + { + "associatedValues" : [ + { + "label" : "value", + "type" : { + "string" : { + + } + } + } + ], + "name" : "text" + } + ], + "emitStyle" : "const", + "name" : "GenericTagged", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "GenericTagged", + "tsFullPath" : "GenericTagged" + } + ], + "exposeToGlobal" : false, + "functions" : [ + + ], + "protocols" : [ + + ], + "structs" : [ + { + "methods" : [ + + ], + "name" : "GenericPoint", + "properties" : [ + { + "isReadonly" : true, + "isStatic" : false, + "name" : "x", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + }, + { + "isReadonly" : true, + "isStatic" : false, + "name" : "y", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "swiftCallName" : "GenericPoint" + } + ] + }, + "imported" : { + "children" : [ + { + "functions" : [ + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "genericRoundTrip", + "parameters" : [ + { + "name" : "value", + "type" : { + "generic" : { + "_0" : "T" + } + } + } + ], + "returnType" : { + "generic" : { + "_0" : "T" + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "genericParse", + "parameters" : [ + { + "name" : "json", + "type" : { + "string" : { + + } + } + } + ], + "returnType" : { + "generic" : { + "_0" : "T" + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T", + "U" + ], + "name" : "importGenericCombine", + "parameters" : [ + { + "name" : "a", + "type" : { + "generic" : { + "_0" : "T" + } + } + }, + { + "name" : "b", + "type" : { + "generic" : { + "_0" : "U" + } + } + } + ], + "returnType" : { + "generic" : { + "_0" : "U" + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T", + "t" + ], + "name" : "importGenericCaseDistinct", + "parameters" : [ + { + "name" : "a", + "type" : { + "generic" : { + "_0" : "T" + } + } + }, + { + "name" : "b", + "type" : { + "generic" : { + "_0" : "t" + } + } + } + ], + "returnType" : { + "generic" : { + "_0" : "T" + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "importGenericArray", + "parameters" : [ + { + "name" : "values", + "type" : { + "array" : { + "_0" : { + "generic" : { + "_0" : "T" + } + } + } + } + } + ], + "returnType" : { + "array" : { + "_0" : { + "generic" : { + "_0" : "T" + } + } + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "importGenericOptional", + "parameters" : [ + { + "name" : "value", + "type" : { + "nullable" : { + "_0" : { + "generic" : { + "_0" : "T" + } + }, + "_1" : "null" + } + } + } + ], + "returnType" : { + "nullable" : { + "_0" : { + "generic" : { + "_0" : "T" + } + }, + "_1" : "null" + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "importGenericDictionary", + "parameters" : [ + { + "name" : "values", + "type" : { + "dictionary" : { + "_0" : { + "generic" : { + "_0" : "T" + } + } + } + } + } + ], + "returnType" : { + "dictionary" : { + "_0" : { + "generic" : { + "_0" : "T" + } + } + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "importGenericAfterOptionalArray", + "parameters" : [ + { + "name" : "values", + "type" : { + "nullable" : { + "_0" : { + "array" : { + "_0" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + }, + "_1" : "null" + } + } + }, + { + "name" : "value", + "type" : { + "generic" : { + "_0" : "T" + } + } + } + ], + "returnType" : { + "generic" : { + "_0" : "T" + } + } + } + ], + "types" : [ + { + "accessLevel" : "internal", + "constructor" : { + "accessLevel" : "internal", + "genericParameters" : [ + "T", + "U" + ], + "parameters" : [ + { + "name" : "tag", + "type" : { + "string" : { + + } + } + }, + { + "name" : "first", + "type" : { + "generic" : { + "_0" : "T" + } + } + }, + { + "name" : "second", + "type" : { + "generic" : { + "_0" : "U" + } + } + } + ] + }, + "getters" : [ + + ], + "methods" : [ + + ], + "name" : "GenericPairFactory", + "setters" : [ + + ], + "staticMethods" : [ + + ] + }, + { + "accessLevel" : "internal", + "constructor" : { + "accessLevel" : "internal", + "genericParameters" : [ + "T" + ], + "parameters" : [ + { + "name" : "value", + "type" : { + "generic" : { + "_0" : "T" + } + } + } + ] + }, + "getters" : [ + + ], + "methods" : [ + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "accept", + "parameters" : [ + { + "name" : "value", + "type" : { + "generic" : { + "_0" : "T" + } + } + } + ], + "returnType" : { + "void" : { + + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "identity", + "parameters" : [ + { + "name" : "value", + "type" : { + "generic" : { + "_0" : "T" + } + } + } + ], + "returnType" : { + "generic" : { + "_0" : "T" + } + } + } + ], + "name" : "GenericConsumer", + "setters" : [ + + ], + "staticMethods" : [ + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "box", + "parameters" : [ + { + "name" : "value", + "type" : { + "generic" : { + "_0" : "T" + } + } + } + ], + "returnType" : { + "generic" : { + "_0" : "T" + } + } + } + ] + } + ] + } + ] + }, + "moduleName" : "TestModule", + "usedExternalModules" : [ + + ] +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/GenericImports.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/GenericImports.swift new file mode 100644 index 000000000..01ed6196e --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/GenericImports.swift @@ -0,0 +1,505 @@ +extension GenericColor: _BridgedSwiftCaseEnum { + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + return bridgeJSRawValue + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Int32) -> GenericColor { + return bridgeJSLiftParameter(value) + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Int32) -> GenericColor { + return GenericColor(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Int32 { + return bridgeJSLowerParameter() + } + + @_spi(BridgeJS) @usableFromInline init?(bridgeJSRawValue: Int32) { + switch bridgeJSRawValue { + case 0: + self = .red + case 1: + self = .green + default: + return nil + } + } + + @_spi(BridgeJS) @usableFromInline var bridgeJSRawValue: Int32 { + switch self { + case .red: + return 0 + case .green: + return 1 + } + } +} + +extension GenericMode: _BridgedSwiftEnumNoPayload, _BridgedSwiftRawValueEnum { +} + +extension GenericTagged: _BridgedSwiftAssociatedValueEnum { + @_spi(BridgeJS) @_transparent public static func bridgeJSStackPopPayload(_ caseId: Int32) -> GenericTagged { + switch caseId { + case 0: + return .number(value: Int.bridgeJSStackPop()) + case 1: + return .text(value: String.bridgeJSStackPop()) + default: + fatalError("Unknown GenericTagged case ID: \(caseId)") + } + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPushPayload() -> Int32 { + switch self { + case .number(let value): + value.bridgeJSStackPush() + return Int32(0) + case .text(let value): + value.bridgeJSStackPush() + return Int32(1) + } + } +} + +extension GenericPoint: _BridgedSwiftStruct { + @_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> GenericPoint { + let y = Int.bridgeJSStackPop() + let x = Int.bridgeJSStackPop() + return GenericPoint(x: x, y: y) + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPush() { + self.x.bridgeJSStackPush() + self.y.bridgeJSStackPush() + } + + init(unsafelyCopying jsObject: JSObject) { + _bjs_struct_lower_GenericPoint(jsObject.bridgeJSLowerParameter()) + self = Self.bridgeJSStackPop() + } + + func toJSObject() -> JSObject { + let __bjs_self = self + __bjs_self.bridgeJSStackPush() + return JSObject(id: UInt32(bitPattern: _bjs_struct_lift_GenericPoint())) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_GenericPoint") +fileprivate func _bjs_struct_lower_GenericPoint_extern(_ objectId: Int32) -> Void +#else +fileprivate func _bjs_struct_lower_GenericPoint_extern(_ objectId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lower_GenericPoint(_ objectId: Int32) -> Void { + return _bjs_struct_lower_GenericPoint_extern(objectId) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lift_GenericPoint") +fileprivate func _bjs_struct_lift_GenericPoint_extern() -> Int32 +#else +fileprivate func _bjs_struct_lift_GenericPoint_extern() -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lift_GenericPoint() -> Int32 { + return _bjs_struct_lift_GenericPoint_extern() +} + +@_expose(wasm, "bjs_GenericImportBox_init") +@_cdecl("bjs_GenericImportBox_init") +public func _bjs_GenericImportBox_init(_ value: Int32) -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = GenericImportBox(value: Int.bridgeJSLiftParameter(value)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_GenericImportBox_get") +@_cdecl("bjs_GenericImportBox_get") +public func _bjs_GenericImportBox_get(_ _self: UnsafeMutableRawPointer) -> Int32 { + #if arch(wasm32) + let ret = GenericImportBox.bridgeJSLiftParameter(_self).get() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_GenericImportBox_value_get") +@_cdecl("bjs_GenericImportBox_value_get") +public func _bjs_GenericImportBox_value_get(_ _self: UnsafeMutableRawPointer) -> Int32 { + #if arch(wasm32) + let ret = GenericImportBox.bridgeJSLiftParameter(_self).value + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_GenericImportBox_value_set") +@_cdecl("bjs_GenericImportBox_value_set") +public func _bjs_GenericImportBox_value_set(_ _self: UnsafeMutableRawPointer, _ value: Int32) -> Void { + #if arch(wasm32) + GenericImportBox.bridgeJSLiftParameter(_self).value = Int.bridgeJSLiftParameter(value) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_GenericImportBox_deinit") +@_cdecl("bjs_GenericImportBox_deinit") +public func _bjs_GenericImportBox_deinit(_ pointer: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + Unmanaged.fromOpaque(pointer).release() + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension GenericImportBox: ConvertibleToJSValue, _BridgedSwiftHeapObject, _BridgedSwiftProtocolExportable { + var jsValue: JSValue { + return .object(JSObject(id: UInt32(bitPattern: _bjs_GenericImportBox_wrap(Unmanaged.passRetained(self).toOpaque())))) + } + consuming func bridgeJSLowerAsProtocolReturn() -> Int32 { + _bjs_GenericImportBox_wrap(Unmanaged.passRetained(self).toOpaque()) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_GenericImportBox_wrap") +fileprivate func _bjs_GenericImportBox_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_GenericImportBox_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_GenericImportBox_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { + return _bjs_GenericImportBox_wrap_extern(pointer) +} + +extension GenericPoint: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = GenericPoint.bridgeJSMakeTypeHandle() +} + +extension GenericImportBox: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = GenericImportBox.bridgeJSMakeTypeHandle() +} + +extension GenericColor: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = GenericColor.bridgeJSMakeTypeHandle() +} + +extension GenericMode: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = GenericMode.bridgeJSMakeTypeHandle() +} + +extension GenericTagged: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = GenericTagged.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_genericRoundTrip") +fileprivate func bjs_genericRoundTrip_extern(_ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_genericRoundTrip_extern(_ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_genericRoundTrip(_ _generic0TypeId: Int32) -> Void { + return bjs_genericRoundTrip_extern(_generic0TypeId) +} + +func _$genericRoundTrip(_ value: T) throws(JSException) -> T { + value.bridgeJSStackPush() + bjs_genericRoundTrip(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return T.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_genericParse") +fileprivate func bjs_genericParse_extern(_ jsonBytes: Int32, _ jsonLength: Int32, _ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_genericParse_extern(_ jsonBytes: Int32, _ jsonLength: Int32, _ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_genericParse(_ jsonBytes: Int32, _ jsonLength: Int32, _ _generic0TypeId: Int32) -> Void { + return bjs_genericParse_extern(jsonBytes, jsonLength, _generic0TypeId) +} + +func _$genericParse(_ json: String) throws(JSException) -> T { + json.bridgeJSWithLoweredParameter { (jsonBytes, jsonLength) in + bjs_genericParse(jsonBytes, jsonLength, T.bridgeJSTypeID) + } + if let error = _swift_js_take_exception() { + throw error + } + return T.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_importGenericCombine") +fileprivate func bjs_importGenericCombine_extern(_ _generic0TypeId: Int32, _ _generic1TypeId: Int32) -> Void +#else +fileprivate func bjs_importGenericCombine_extern(_ _generic0TypeId: Int32, _ _generic1TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_importGenericCombine(_ _generic0TypeId: Int32, _ _generic1TypeId: Int32) -> Void { + return bjs_importGenericCombine_extern(_generic0TypeId, _generic1TypeId) +} + +func _$importGenericCombine(_ a: T, _ b: U) throws(JSException) -> U { + b.bridgeJSStackPush() + a.bridgeJSStackPush() + bjs_importGenericCombine(T.bridgeJSTypeID, U.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return U.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_importGenericCaseDistinct") +fileprivate func bjs_importGenericCaseDistinct_extern(_ _generic0TypeId: Int32, _ _generic1TypeId: Int32) -> Void +#else +fileprivate func bjs_importGenericCaseDistinct_extern(_ _generic0TypeId: Int32, _ _generic1TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_importGenericCaseDistinct(_ _generic0TypeId: Int32, _ _generic1TypeId: Int32) -> Void { + return bjs_importGenericCaseDistinct_extern(_generic0TypeId, _generic1TypeId) +} + +func _$importGenericCaseDistinct(_ a: T, _ b: t) throws(JSException) -> T { + b.bridgeJSStackPush() + a.bridgeJSStackPush() + bjs_importGenericCaseDistinct(T.bridgeJSTypeID, t.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return T.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_importGenericArray") +fileprivate func bjs_importGenericArray_extern(_ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_importGenericArray_extern(_ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_importGenericArray(_ _generic0TypeId: Int32) -> Void { + return bjs_importGenericArray_extern(_generic0TypeId) +} + +func _$importGenericArray(_ values: [T]) throws(JSException) -> [T] { + let _ = values.bridgeJSLowerParameter() + bjs_importGenericArray(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return [T].bridgeJSLiftReturn() +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_importGenericOptional") +fileprivate func bjs_importGenericOptional_extern(_ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_importGenericOptional_extern(_ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_importGenericOptional(_ _generic0TypeId: Int32) -> Void { + return bjs_importGenericOptional_extern(_generic0TypeId) +} + +func _$importGenericOptional(_ value: Optional) throws(JSException) -> Optional { + value.bridgeJSStackPush() + bjs_importGenericOptional(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return Optional.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_importGenericDictionary") +fileprivate func bjs_importGenericDictionary_extern(_ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_importGenericDictionary_extern(_ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_importGenericDictionary(_ _generic0TypeId: Int32) -> Void { + return bjs_importGenericDictionary_extern(_generic0TypeId) +} + +func _$importGenericDictionary(_ values: [String: T]) throws(JSException) -> [String: T] { + let _ = values.bridgeJSLowerParameter() + bjs_importGenericDictionary(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return [String: T].bridgeJSLiftReturn() +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_importGenericAfterOptionalArray") +fileprivate func bjs_importGenericAfterOptionalArray_extern(_ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_importGenericAfterOptionalArray_extern(_ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_importGenericAfterOptionalArray(_ _generic0TypeId: Int32) -> Void { + return bjs_importGenericAfterOptionalArray_extern(_generic0TypeId) +} + +func _$importGenericAfterOptionalArray(_ values: Optional<[Int]>, _ value: T) throws(JSException) -> T { + value.bridgeJSStackPush() + let _ = values.bridgeJSLowerParameter() + bjs_importGenericAfterOptionalArray(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return T.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_GenericPairFactory_init") +fileprivate func bjs_GenericPairFactory_init_extern(_ tagBytes: Int32, _ tagLength: Int32, _ _generic0TypeId: Int32, _ _generic1TypeId: Int32) -> Int32 +#else +fileprivate func bjs_GenericPairFactory_init_extern(_ tagBytes: Int32, _ tagLength: Int32, _ _generic0TypeId: Int32, _ _generic1TypeId: Int32) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_GenericPairFactory_init(_ tagBytes: Int32, _ tagLength: Int32, _ _generic0TypeId: Int32, _ _generic1TypeId: Int32) -> Int32 { + return bjs_GenericPairFactory_init_extern(tagBytes, tagLength, _generic0TypeId, _generic1TypeId) +} + +func _$GenericPairFactory_init(_ tag: String, _ first: T, _ second: U) throws(JSException) -> JSObject { + let ret0 = tag.bridgeJSWithLoweredParameter { (tagBytes, tagLength) in + second.bridgeJSStackPush() + first.bridgeJSStackPush() + let ret = bjs_GenericPairFactory_init(tagBytes, tagLength, T.bridgeJSTypeID, U.bridgeJSTypeID) + return ret + } + let ret = ret0 + if let error = _swift_js_take_exception() { + throw error + } + return JSObject.bridgeJSLiftReturn(ret) +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_GenericConsumer_init") +fileprivate func bjs_GenericConsumer_init_extern(_ _generic0TypeId: Int32) -> Int32 +#else +fileprivate func bjs_GenericConsumer_init_extern(_ _generic0TypeId: Int32) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_GenericConsumer_init(_ _generic0TypeId: Int32) -> Int32 { + return bjs_GenericConsumer_init_extern(_generic0TypeId) +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_GenericConsumer_box_static") +fileprivate func bjs_GenericConsumer_box_static_extern(_ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_GenericConsumer_box_static_extern(_ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_GenericConsumer_box_static(_ _generic0TypeId: Int32) -> Void { + return bjs_GenericConsumer_box_static_extern(_generic0TypeId) +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_GenericConsumer_accept") +fileprivate func bjs_GenericConsumer_accept_extern(_ self: Int32, _ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_GenericConsumer_accept_extern(_ self: Int32, _ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_GenericConsumer_accept(_ self: Int32, _ _generic0TypeId: Int32) -> Void { + return bjs_GenericConsumer_accept_extern(self, _generic0TypeId) +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_GenericConsumer_identity") +fileprivate func bjs_GenericConsumer_identity_extern(_ self: Int32, _ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_GenericConsumer_identity_extern(_ self: Int32, _ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_GenericConsumer_identity(_ self: Int32, _ _generic0TypeId: Int32) -> Void { + return bjs_GenericConsumer_identity_extern(self, _generic0TypeId) +} + +func _$GenericConsumer_init(_ value: T) throws(JSException) -> JSObject { + value.bridgeJSStackPush() + let ret = bjs_GenericConsumer_init(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return JSObject.bridgeJSLiftReturn(ret) +} + +func _$GenericConsumer_box(_ value: T) throws(JSException) -> T { + value.bridgeJSStackPush() + bjs_GenericConsumer_box_static(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return T.bridgeJSStackPop() +} + +func _$GenericConsumer_accept(_ self: JSObject, _ value: T) throws(JSException) -> Void { + value.bridgeJSStackPush() + let selfValue = self.bridgeJSLowerParameter() + bjs_GenericConsumer_accept(selfValue, T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } +} + +func _$GenericConsumer_identity(_ self: JSObject, _ value: T) throws(JSException) -> T { + value.bridgeJSStackPush() + let selfValue = self.bridgeJSLowerParameter() + bjs_GenericConsumer_identity(selfValue, T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return T.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + GenericPoint.bridgeJSTypeID, + GenericImportBox.bridgeJSTypeID, + GenericColor.bridgeJSTypeID, + GenericMode.bridgeJSTypeID, + GenericTagged.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ImportArray.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ImportArray.swift index 9c4b49e3c..12abbd1e6 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ImportArray.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ImportArray.swift @@ -41,20 +41,20 @@ func _$logStrings(_ items: [String]) throws(JSException) -> Void { #if arch(wasm32) @_extern(wasm, module: "TestModule", name: "bjs_optionalArrayThenArray") -fileprivate func bjs_optionalArrayThenArray_extern(_ a: Int32) -> Int32 +fileprivate func bjs_optionalArrayThenArray_extern() -> Int32 #else -fileprivate func bjs_optionalArrayThenArray_extern(_ a: Int32) -> Int32 { +fileprivate func bjs_optionalArrayThenArray_extern() -> Int32 { fatalError("Only available on WebAssembly") } #endif -@inline(never) fileprivate func bjs_optionalArrayThenArray(_ a: Int32) -> Int32 { - return bjs_optionalArrayThenArray_extern(a) +@inline(never) fileprivate func bjs_optionalArrayThenArray() -> Int32 { + return bjs_optionalArrayThenArray_extern() } func _$optionalArrayThenArray(_ a: Optional<[Int]>, _ b: [Int]) throws(JSException) -> Int { let _ = b.bridgeJSLowerParameter() - let aIsSome = a.bridgeJSLowerParameter() - let ret = bjs_optionalArrayThenArray(aIsSome) + let _ = a.bridgeJSLowerParameter() + let ret = bjs_optionalArrayThenArray() if let error = _swift_js_take_exception() { throw error } @@ -63,21 +63,21 @@ func _$optionalArrayThenArray(_ a: Optional<[Int]>, _ b: [Int]) throws(JSExcepti #if arch(wasm32) @_extern(wasm, module: "TestModule", name: "bjs_borrowedStringAroundStackParams") -fileprivate func bjs_borrowedStringAroundStackParams_extern(_ sBytes: Int32, _ sLength: Int32, _ a: Int32) -> Int32 +fileprivate func bjs_borrowedStringAroundStackParams_extern(_ sBytes: Int32, _ sLength: Int32) -> Int32 #else -fileprivate func bjs_borrowedStringAroundStackParams_extern(_ sBytes: Int32, _ sLength: Int32, _ a: Int32) -> Int32 { +fileprivate func bjs_borrowedStringAroundStackParams_extern(_ sBytes: Int32, _ sLength: Int32) -> Int32 { fatalError("Only available on WebAssembly") } #endif -@inline(never) fileprivate func bjs_borrowedStringAroundStackParams(_ sBytes: Int32, _ sLength: Int32, _ a: Int32) -> Int32 { - return bjs_borrowedStringAroundStackParams_extern(sBytes, sLength, a) +@inline(never) fileprivate func bjs_borrowedStringAroundStackParams(_ sBytes: Int32, _ sLength: Int32) -> Int32 { + return bjs_borrowedStringAroundStackParams_extern(sBytes, sLength) } func _$borrowedStringAroundStackParams(_ s: String, _ a: Optional<[Int]>, _ b: [Int]) throws(JSException) -> Int { let ret0 = s.bridgeJSWithLoweredParameter { (sBytes, sLength) in let _ = b.bridgeJSLowerParameter() - let aIsSome = a.bridgeJSLowerParameter() - let ret = bjs_borrowedStringAroundStackParams(sBytes, sLength, aIsSome) + let _ = a.bridgeJSLowerParameter() + let ret = bjs_borrowedStringAroundStackParams(sBytes, sLength) return ret } let ret = ret0 diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ImportedTypeInExportedInterface.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ImportedTypeInExportedInterface.swift index 62f9a3b68..b9fddf706 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ImportedTypeInExportedInterface.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ImportedTypeInExportedInterface.swift @@ -104,6 +104,10 @@ public func _bjs_roundtripFooContainer() -> Void { #endif } +extension FooContainer: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = FooContainer.bridgeJSMakeTypeHandle() +} + #if arch(wasm32) @_extern(wasm, module: "TestModule", name: "bjs_Foo_init") fileprivate func bjs_Foo_init_extern() -> Int32 @@ -122,4 +126,19 @@ func _$Foo_init() throws(JSException) -> JSObject { throw error } return JSObject.bridgeJSLiftReturn(ret) -} \ No newline at end of file +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + FooContainer.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/JSNameOverride.json b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/JSNameOverride.json new file mode 100644 index 000000000..c5cd01631 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/JSNameOverride.json @@ -0,0 +1,524 @@ +{ + "exported" : { + "aliases" : [ + + ], + "classes" : [ + { + "constructor" : { + "abiName" : "bjs_RenamedMembers_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + { + "label" : "title", + "name" : "title", + "type" : { + "string" : { + + } + } + }, + { + "label" : "count", + "name" : "count", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ] + }, + "methods" : [ + { + "abiName" : "bjs_RenamedMembers_makeGreeting", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "jsName" : "makeGreeting", + "name" : "greet", + "parameters" : [ + + ], + "returnType" : { + "string" : { + + } + } + }, + { + "abiName" : "bjs_RenamedMembers_static_makeDefault", + "effects" : { + "isAsync" : false, + "isStatic" : true, + "isThrows" : false + }, + "jsName" : "makeDefault", + "name" : "createDefault", + "parameters" : [ + + ], + "returnType" : { + "swiftHeapObject" : { + "_0" : "RenamedMembers" + } + }, + "staticContext" : { + "className" : { + "_0" : "RenamedMembers" + } + } + } + ], + "name" : "RenamedMembers", + "properties" : [ + { + "isReadonly" : false, + "isStatic" : false, + "jsName" : "label", + "name" : "title", + "type" : { + "string" : { + + } + } + }, + { + "isReadonly" : true, + "isStatic" : false, + "jsName" : "total", + "name" : "count", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + }, + { + "isReadonly" : false, + "isStatic" : true, + "jsName" : "sharedTotal", + "name" : "sharedCount", + "staticContext" : { + "className" : { + "_0" : "RenamedMembers" + } + }, + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + }, + { + "isReadonly" : true, + "isStatic" : true, + "jsName" : "readOnlyLimit", + "name" : "limit", + "staticContext" : { + "className" : { + "_0" : "RenamedMembers" + } + }, + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "swiftCallName" : "RenamedMembers" + } + ], + "enums" : [ + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "active" + }, + { + "associatedValues" : [ + + ], + "name" : "inactive" + } + ], + "emitStyle" : "const", + "name" : "RenamedEnumMembers", + "staticMethods" : [ + { + "abiName" : "bjs_RenamedEnumMembers_static_describeCase", + "effects" : { + "isAsync" : false, + "isStatic" : true, + "isThrows" : false + }, + "jsName" : "describeCase", + "name" : "describe", + "parameters" : [ + + ], + "returnType" : { + "string" : { + + } + }, + "staticContext" : { + "enumName" : { + "_0" : "RenamedEnumMembers" + } + } + } + ], + "staticProperties" : [ + { + "isReadonly" : false, + "isStatic" : true, + "jsName" : "currentDefault", + "name" : "defaultValue", + "staticContext" : { + "enumName" : { + "_0" : "RenamedEnumMembers" + } + }, + "type" : { + "string" : { + + } + } + } + ], + "swiftCallName" : "RenamedEnumMembers", + "tsFullPath" : "RenamedEnumMembers" + }, + { + "cases" : [ + + ], + "emitStyle" : "const", + "name" : "RenamedNamespaceMembers", + "staticMethods" : [ + { + "abiName" : "bjs_RenamedNamespaceMembers_static_plus", + "effects" : { + "isAsync" : false, + "isStatic" : true, + "isThrows" : false + }, + "jsName" : "plus", + "name" : "add", + "namespace" : [ + "RenamedNamespaceMembers" + ], + "parameters" : [ + { + "label" : "_", + "name" : "a", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + }, + { + "label" : "_", + "name" : "b", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "returnType" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + }, + "staticContext" : { + "namespaceEnum" : { + "_0" : "RenamedNamespaceMembers" + } + } + } + ], + "staticProperties" : [ + { + "isReadonly" : false, + "isStatic" : true, + "jsName" : "theAnswer", + "name" : "answer", + "namespace" : [ + "RenamedNamespaceMembers" + ], + "staticContext" : { + "namespaceEnum" : { + "_0" : "RenamedNamespaceMembers" + } + }, + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "swiftCallName" : "RenamedNamespaceMembers", + "tsFullPath" : "RenamedNamespaceMembers" + } + ], + "exposeToGlobal" : false, + "functions" : [ + { + "abiName" : "bjs_makeGreeting", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "jsName" : "makeGreeting", + "name" : "renderGreeting", + "parameters" : [ + { + "label" : "name", + "name" : "name", + "type" : { + "string" : { + + } + } + } + ], + "returnType" : { + "string" : { + + } + } + }, + { + "abiName" : "bjs_greetName", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "jsName" : "greetName", + "name" : "greet", + "parameters" : [ + { + "label" : "_", + "name" : "name", + "type" : { + "string" : { + + } + } + } + ], + "returnType" : { + "string" : { + + } + } + }, + { + "abiName" : "bjs_greetCount", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "jsName" : "greetCount", + "name" : "greet", + "parameters" : [ + { + "label" : "_", + "name" : "count", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "returnType" : { + "string" : { + + } + } + }, + { + "abiName" : "bjs_Utils_Text_namespacedRenamed", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "jsName" : "namespacedRenamed", + "name" : "namespacedFunction", + "namespace" : [ + "Utils", + "Text" + ], + "parameters" : [ + + ], + "returnType" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "protocols" : [ + + ], + "structs" : [ + { + "methods" : [ + { + "abiName" : "bjs_RenamedVector_magnitude", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "jsName" : "magnitude", + "name" : "length", + "parameters" : [ + + ], + "returnType" : { + "double" : { + + } + } + }, + { + "abiName" : "bjs_RenamedVector_static_fromPolar", + "effects" : { + "isAsync" : false, + "isStatic" : true, + "isThrows" : false + }, + "jsName" : "fromPolar", + "name" : "polar", + "parameters" : [ + { + "label" : "radius", + "name" : "radius", + "type" : { + "double" : { + + } + } + }, + { + "label" : "angle", + "name" : "angle", + "type" : { + "double" : { + + } + } + } + ], + "returnType" : { + "swiftStruct" : { + "_0" : "RenamedVector" + } + }, + "staticContext" : { + "structName" : { + "_0" : "RenamedVector" + } + } + } + ], + "name" : "RenamedVector", + "properties" : [ + { + "isReadonly" : true, + "isStatic" : false, + "name" : "dx", + "type" : { + "double" : { + + } + } + }, + { + "isReadonly" : true, + "isStatic" : false, + "name" : "dy", + "type" : { + "double" : { + + } + } + }, + { + "isReadonly" : true, + "isStatic" : true, + "jsName" : "originVector", + "name" : "origin", + "staticContext" : { + "structName" : { + "_0" : "RenamedVector" + } + }, + "type" : { + "swiftStruct" : { + "_0" : "RenamedVector" + } + } + } + ], + "swiftCallName" : "RenamedVector" + } + ] + }, + "moduleName" : "TestModule", + "usedExternalModules" : [ + + ] +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/JSNameOverride.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/JSNameOverride.swift new file mode 100644 index 000000000..8e01bca22 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/JSNameOverride.swift @@ -0,0 +1,375 @@ +extension RenamedEnumMembers: _BridgedSwiftCaseEnum { + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + return bridgeJSRawValue + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Int32) -> RenamedEnumMembers { + return bridgeJSLiftParameter(value) + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Int32) -> RenamedEnumMembers { + return RenamedEnumMembers(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Int32 { + return bridgeJSLowerParameter() + } + + @_spi(BridgeJS) @usableFromInline init?(bridgeJSRawValue: Int32) { + switch bridgeJSRawValue { + case 0: + self = .active + case 1: + self = .inactive + default: + return nil + } + } + + @_spi(BridgeJS) @usableFromInline var bridgeJSRawValue: Int32 { + switch self { + case .active: + return 0 + case .inactive: + return 1 + } + } +} + +@_expose(wasm, "bjs_RenamedEnumMembers_static_describeCase") +@_cdecl("bjs_RenamedEnumMembers_static_describeCase") +public func _bjs_RenamedEnumMembers_static_describeCase() -> Void { + #if arch(wasm32) + let ret = RenamedEnumMembers.describe() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedEnumMembers_static_defaultValue_get") +@_cdecl("bjs_RenamedEnumMembers_static_defaultValue_get") +public func _bjs_RenamedEnumMembers_static_defaultValue_get() -> Void { + #if arch(wasm32) + let ret = RenamedEnumMembers.defaultValue + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedEnumMembers_static_defaultValue_set") +@_cdecl("bjs_RenamedEnumMembers_static_defaultValue_set") +public func _bjs_RenamedEnumMembers_static_defaultValue_set(_ valueBytes: Int32, _ valueLength: Int32) -> Void { + #if arch(wasm32) + RenamedEnumMembers.defaultValue = String.bridgeJSLiftParameter(valueBytes, valueLength) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedNamespaceMembers_static_plus") +@_cdecl("bjs_RenamedNamespaceMembers_static_plus") +public func _bjs_RenamedNamespaceMembers_static_plus(_ a: Int32, _ b: Int32) -> Int32 { + #if arch(wasm32) + let ret = RenamedNamespaceMembers.add(_: Int.bridgeJSLiftParameter(a), _: Int.bridgeJSLiftParameter(b)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedNamespaceMembers_static_answer_get") +@_cdecl("bjs_RenamedNamespaceMembers_static_answer_get") +public func _bjs_RenamedNamespaceMembers_static_answer_get() -> Int32 { + #if arch(wasm32) + let ret = RenamedNamespaceMembers.answer + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedNamespaceMembers_static_answer_set") +@_cdecl("bjs_RenamedNamespaceMembers_static_answer_set") +public func _bjs_RenamedNamespaceMembers_static_answer_set(_ value: Int32) -> Void { + #if arch(wasm32) + RenamedNamespaceMembers.answer = Int.bridgeJSLiftParameter(value) + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension RenamedVector: _BridgedSwiftStruct { + @_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> RenamedVector { + let dy = Double.bridgeJSStackPop() + let dx = Double.bridgeJSStackPop() + return RenamedVector(dx: dx, dy: dy) + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPush() { + self.dx.bridgeJSStackPush() + self.dy.bridgeJSStackPush() + } + + init(unsafelyCopying jsObject: JSObject) { + _bjs_struct_lower_RenamedVector(jsObject.bridgeJSLowerParameter()) + self = Self.bridgeJSStackPop() + } + + func toJSObject() -> JSObject { + let __bjs_self = self + __bjs_self.bridgeJSStackPush() + return JSObject(id: UInt32(bitPattern: _bjs_struct_lift_RenamedVector())) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_RenamedVector") +fileprivate func _bjs_struct_lower_RenamedVector_extern(_ objectId: Int32) -> Void +#else +fileprivate func _bjs_struct_lower_RenamedVector_extern(_ objectId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lower_RenamedVector(_ objectId: Int32) -> Void { + return _bjs_struct_lower_RenamedVector_extern(objectId) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lift_RenamedVector") +fileprivate func _bjs_struct_lift_RenamedVector_extern() -> Int32 +#else +fileprivate func _bjs_struct_lift_RenamedVector_extern() -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lift_RenamedVector() -> Int32 { + return _bjs_struct_lift_RenamedVector_extern() +} + +@_expose(wasm, "bjs_RenamedVector_static_origin_get") +@_cdecl("bjs_RenamedVector_static_origin_get") +public func _bjs_RenamedVector_static_origin_get() -> Void { + #if arch(wasm32) + let ret = RenamedVector.origin + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedVector_magnitude") +@_cdecl("bjs_RenamedVector_magnitude") +public func _bjs_RenamedVector_magnitude() -> Float64 { + #if arch(wasm32) + let ret = RenamedVector.bridgeJSLiftParameter().length() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedVector_static_fromPolar") +@_cdecl("bjs_RenamedVector_static_fromPolar") +public func _bjs_RenamedVector_static_fromPolar(_ radius: Float64, _ angle: Float64) -> Void { + #if arch(wasm32) + let ret = RenamedVector.polar(radius: Double.bridgeJSLiftParameter(radius), angle: Double.bridgeJSLiftParameter(angle)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_makeGreeting") +@_cdecl("bjs_makeGreeting") +public func _bjs_makeGreeting(_ nameBytes: Int32, _ nameLength: Int32) -> Void { + #if arch(wasm32) + let ret = renderGreeting(name: String.bridgeJSLiftParameter(nameBytes, nameLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_greetName") +@_cdecl("bjs_greetName") +public func _bjs_greetName(_ nameBytes: Int32, _ nameLength: Int32) -> Void { + #if arch(wasm32) + let ret = greet(_: String.bridgeJSLiftParameter(nameBytes, nameLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_greetCount") +@_cdecl("bjs_greetCount") +public func _bjs_greetCount(_ count: Int32) -> Void { + #if arch(wasm32) + let ret = greet(_: Int.bridgeJSLiftParameter(count)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_Utils_Text_namespacedRenamed") +@_cdecl("bjs_Utils_Text_namespacedRenamed") +public func _bjs_Utils_Text_namespacedRenamed() -> Int32 { + #if arch(wasm32) + let ret = namespacedFunction() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedMembers_init") +@_cdecl("bjs_RenamedMembers_init") +public func _bjs_RenamedMembers_init(_ titleBytes: Int32, _ titleLength: Int32, _ count: Int32) -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = RenamedMembers(title: String.bridgeJSLiftParameter(titleBytes, titleLength), count: Int.bridgeJSLiftParameter(count)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedMembers_makeGreeting") +@_cdecl("bjs_RenamedMembers_makeGreeting") +public func _bjs_RenamedMembers_makeGreeting(_ _self: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + let ret = RenamedMembers.bridgeJSLiftParameter(_self).greet() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedMembers_static_makeDefault") +@_cdecl("bjs_RenamedMembers_static_makeDefault") +public func _bjs_RenamedMembers_static_makeDefault() -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = RenamedMembers.createDefault() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedMembers_title_get") +@_cdecl("bjs_RenamedMembers_title_get") +public func _bjs_RenamedMembers_title_get(_ _self: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + let ret = RenamedMembers.bridgeJSLiftParameter(_self).title + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedMembers_title_set") +@_cdecl("bjs_RenamedMembers_title_set") +public func _bjs_RenamedMembers_title_set(_ _self: UnsafeMutableRawPointer, _ valueBytes: Int32, _ valueLength: Int32) -> Void { + #if arch(wasm32) + RenamedMembers.bridgeJSLiftParameter(_self).title = String.bridgeJSLiftParameter(valueBytes, valueLength) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedMembers_count_get") +@_cdecl("bjs_RenamedMembers_count_get") +public func _bjs_RenamedMembers_count_get(_ _self: UnsafeMutableRawPointer) -> Int32 { + #if arch(wasm32) + let ret = RenamedMembers.bridgeJSLiftParameter(_self).count + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedMembers_static_sharedCount_get") +@_cdecl("bjs_RenamedMembers_static_sharedCount_get") +public func _bjs_RenamedMembers_static_sharedCount_get() -> Int32 { + #if arch(wasm32) + let ret = RenamedMembers.sharedCount + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedMembers_static_sharedCount_set") +@_cdecl("bjs_RenamedMembers_static_sharedCount_set") +public func _bjs_RenamedMembers_static_sharedCount_set(_ value: Int32) -> Void { + #if arch(wasm32) + RenamedMembers.sharedCount = Int.bridgeJSLiftParameter(value) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedMembers_static_limit_get") +@_cdecl("bjs_RenamedMembers_static_limit_get") +public func _bjs_RenamedMembers_static_limit_get() -> Int32 { + #if arch(wasm32) + let ret = RenamedMembers.limit + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_RenamedMembers_deinit") +@_cdecl("bjs_RenamedMembers_deinit") +public func _bjs_RenamedMembers_deinit(_ pointer: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + Unmanaged.fromOpaque(pointer).release() + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension RenamedMembers: ConvertibleToJSValue, _BridgedSwiftHeapObject, _BridgedSwiftProtocolExportable { + var jsValue: JSValue { + return .object(JSObject(id: UInt32(bitPattern: _bjs_RenamedMembers_wrap(Unmanaged.passRetained(self).toOpaque())))) + } + consuming func bridgeJSLowerAsProtocolReturn() -> Int32 { + _bjs_RenamedMembers_wrap(Unmanaged.passRetained(self).toOpaque()) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "TestModule", name: "bjs_RenamedMembers_wrap") +fileprivate func _bjs_RenamedMembers_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_RenamedMembers_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_RenamedMembers_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { + return _bjs_RenamedMembers_wrap_extern(pointer) +} + +extension RenamedVector: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = RenamedVector.bridgeJSMakeTypeHandle() +} + +extension RenamedEnumMembers: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = RenamedEnumMembers.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + RenamedVector.bridgeJSTypeID, + RenamedEnumMembers.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/NestedType.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/NestedType.swift index ed1a080e9..9e1b0e0f6 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/NestedType.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/NestedType.swift @@ -176,4 +176,28 @@ fileprivate func _bjs_Player_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> #endif @inline(never) fileprivate func _bjs_Player_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { return _bjs_Player_wrap_extern(pointer) -} \ No newline at end of file +} + +extension User.Stats: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = User.Stats.bridgeJSMakeTypeHandle() +} + +extension Player.Stats: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Player.Stats.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + User.Stats.bridgeJSTypeID, + Player.Stats.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#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 cfda92ac0..7c2db9a98 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Protocol.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/Protocol.swift @@ -1043,4 +1043,38 @@ fileprivate func _bjs_DelegateManager_wrap_extern(_ pointer: UnsafeMutableRawPoi #endif @inline(never) fileprivate func _bjs_DelegateManager_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { return _bjs_DelegateManager_wrap_extern(pointer) -} \ No newline at end of file +} + +extension Direction: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Direction.bridgeJSMakeTypeHandle() +} + +extension ExampleEnum: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = ExampleEnum.bridgeJSMakeTypeHandle() +} + +extension Result: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Result.bridgeJSMakeTypeHandle() +} + +extension Priority: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Priority.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Direction.bridgeJSTypeID, + ExampleEnum.bridgeJSTypeID, + Result.bridgeJSTypeID, + Priority.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticFunctions.Global.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticFunctions.Global.swift index 896258915..2d5a93c54 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticFunctions.Global.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticFunctions.Global.swift @@ -207,4 +207,28 @@ fileprivate func _bjs_MathUtils_wrap_extern(_ pointer: UnsafeMutableRawPointer) #endif @inline(never) fileprivate func _bjs_MathUtils_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { return _bjs_MathUtils_wrap_extern(pointer) -} \ No newline at end of file +} + +extension Calculator: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Calculator.bridgeJSMakeTypeHandle() +} + +extension APIResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = APIResult.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Calculator.bridgeJSTypeID, + APIResult.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticFunctions.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticFunctions.swift index 896258915..2d5a93c54 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticFunctions.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticFunctions.swift @@ -207,4 +207,28 @@ fileprivate func _bjs_MathUtils_wrap_extern(_ pointer: UnsafeMutableRawPointer) #endif @inline(never) fileprivate func _bjs_MathUtils_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { return _bjs_MathUtils_wrap_extern(pointer) -} \ No newline at end of file +} + +extension Calculator: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Calculator.bridgeJSMakeTypeHandle() +} + +extension APIResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = APIResult.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Calculator.bridgeJSTypeID, + APIResult.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticProperties.Global.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticProperties.Global.swift index ded55dbd4..721c5335a 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticProperties.Global.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticProperties.Global.swift @@ -338,4 +338,23 @@ fileprivate func _bjs_PropertyClass_wrap_extern(_ pointer: UnsafeMutableRawPoint #endif @inline(never) fileprivate func _bjs_PropertyClass_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { return _bjs_PropertyClass_wrap_extern(pointer) -} \ No newline at end of file +} + +extension PropertyEnum: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = PropertyEnum.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + PropertyEnum.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticProperties.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticProperties.swift index ded55dbd4..721c5335a 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticProperties.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StaticProperties.swift @@ -338,4 +338,23 @@ fileprivate func _bjs_PropertyClass_wrap_extern(_ pointer: UnsafeMutableRawPoint #endif @inline(never) fileprivate func _bjs_PropertyClass_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { return _bjs_PropertyClass_wrap_extern(pointer) -} \ No newline at end of file +} + +extension PropertyEnum: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = PropertyEnum.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + PropertyEnum.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StructWithNestedTypes.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StructWithNestedTypes.swift index ad99f0a03..8fc6db1a7 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StructWithNestedTypes.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/StructWithNestedTypes.swift @@ -246,4 +246,53 @@ public func _bjs_Widget_Bounds_static_zero() -> Void { #else fatalError("Only available on WebAssembly") #endif -} \ No newline at end of file +} + +extension Shape: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Shape.bridgeJSMakeTypeHandle() +} + +extension Widget: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Widget.bridgeJSMakeTypeHandle() +} + +extension Widget.Layout: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Widget.Layout.bridgeJSMakeTypeHandle() +} + +extension Widget.Bounds: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Widget.Bounds.bridgeJSMakeTypeHandle() +} + +extension Shape.Kind: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Shape.Kind.bridgeJSMakeTypeHandle() +} + +extension Widget.Variant: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Widget.Variant.bridgeJSMakeTypeHandle() +} + +extension Widget.Layout.Alignment: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Widget.Layout.Alignment.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Shape.bridgeJSTypeID, + Widget.bridgeJSTypeID, + Widget.Layout.bridgeJSTypeID, + Widget.Bounds.bridgeJSTypeID, + Shape.Kind.bridgeJSTypeID, + Widget.Variant.bridgeJSTypeID, + Widget.Layout.Alignment.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftClosure.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftClosure.swift index c7ac02fb1..c2844aa9c 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftClosure.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftClosure.swift @@ -992,14 +992,14 @@ public func _invoke_swift_closure_TestModule_10TestModuleSq5ThemeO_Sq5ThemeO(_ b #if arch(wasm32) @_extern(wasm, module: "bjs", name: "invoke_js_callback_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV") -fileprivate func invoke_js_callback_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV_extern(_ callback: Int32, _ param0: Int32) -> Void +fileprivate func invoke_js_callback_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV_extern(_ callback: Int32) -> Void #else -fileprivate func invoke_js_callback_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV_extern(_ callback: Int32, _ param0: Int32) -> Void { +fileprivate func invoke_js_callback_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV_extern(_ callback: Int32) -> Void { fatalError("Only available on WebAssembly") } #endif -@inline(never) fileprivate func invoke_js_callback_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV(_ callback: Int32, _ param0: Int32) -> Void { - return invoke_js_callback_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV_extern(callback, param0) +@inline(never) fileprivate func invoke_js_callback_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV(_ callback: Int32) -> Void { + return invoke_js_callback_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV_extern(callback) } #if arch(wasm32) @@ -1019,9 +1019,9 @@ private enum _BJS_Closure_10TestModuleSq6AnimalV_Sq6AnimalV { let callback = JSObject.bridgeJSLiftParameter(callbackId) return { [callback] param0 in #if arch(wasm32) - let param0IsSome = param0.bridgeJSLowerParameter() + let _ = param0.bridgeJSLowerParameter() let callbackValue = callback.bridgeJSLowerParameter() - invoke_js_callback_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV(callbackValue, param0IsSome) + invoke_js_callback_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV(callbackValue) return Optional.bridgeJSLiftReturn() #else fatalError("Only available on WebAssembly") @@ -2637,6 +2637,26 @@ fileprivate func _bjs_TestProcessor_wrap_extern(_ pointer: UnsafeMutableRawPoint return _bjs_TestProcessor_wrap_extern(pointer) } +extension Animal: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Animal.bridgeJSMakeTypeHandle() +} + +extension Direction: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Direction.bridgeJSMakeTypeHandle() +} + +extension Theme: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Theme.bridgeJSMakeTypeHandle() +} + +extension HttpStatus: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = HttpStatus.bridgeJSMakeTypeHandle() +} + +extension APIResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = APIResult.bridgeJSMakeTypeHandle() +} + @JSFunction func Promise_reject(_ promise: JSObject, _ value: JSValue) throws(JSException) #if arch(wasm32) @@ -2720,4 +2740,23 @@ func _$Promise_resolve_9APIResultO(_ promise: JSObject, _ value: APIResult) thro let promiseValue = promise.bridgeJSLowerParameter() promise_resolve_TestModule_9APIResultO(promiseValue, valueCaseId) if let error = _swift_js_take_exception() { throw error } -} \ No newline at end of file +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Animal.bridgeJSTypeID, + Direction.bridgeJSTypeID, + Theme.bridgeJSTypeID, + HttpStatus.bridgeJSTypeID, + APIResult.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftStruct.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftStruct.swift index f98038b45..b4e54961c 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftStruct.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftStruct.swift @@ -630,4 +630,63 @@ fileprivate func _bjs_Greeter_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> #endif @inline(never) fileprivate func _bjs_Greeter_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { return _bjs_Greeter_wrap_extern(pointer) -} \ No newline at end of file +} + +extension DataPoint: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = DataPoint.bridgeJSMakeTypeHandle() +} + +extension Address: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Address.bridgeJSMakeTypeHandle() +} + +extension Person: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Person.bridgeJSMakeTypeHandle() +} + +extension Session: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Session.bridgeJSMakeTypeHandle() +} + +extension Measurement: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Measurement.bridgeJSMakeTypeHandle() +} + +extension ConfigStruct: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = ConfigStruct.bridgeJSMakeTypeHandle() +} + +extension Container: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Container.bridgeJSMakeTypeHandle() +} + +extension Vector2D: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Vector2D.bridgeJSMakeTypeHandle() +} + +extension Precision: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Precision.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + DataPoint.bridgeJSTypeID, + Address.bridgeJSTypeID, + Person.bridgeJSTypeID, + Session.bridgeJSTypeID, + Measurement.bridgeJSTypeID, + ConfigStruct.bridgeJSTypeID, + Container.bridgeJSTypeID, + Vector2D.bridgeJSTypeID, + Precision.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftStructImports.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftStructImports.swift index 38ec94c0d..0d77ebe47 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftStructImports.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/SwiftStructImports.swift @@ -46,6 +46,10 @@ fileprivate func _bjs_struct_lift_Point_extern() -> Int32 { return _bjs_struct_lift_Point_extern() } +extension Point: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Point.bridgeJSMakeTypeHandle() +} + #if arch(wasm32) @_extern(wasm, module: "TestModule", name: "bjs_translate") fileprivate func bjs_translate_extern(_ dx: Int32, _ dy: Int32) -> Void @@ -71,21 +75,36 @@ func _$translate(_ point: Point, _ dx: Int, _ dy: Int) throws(JSException) -> Po #if arch(wasm32) @_extern(wasm, module: "TestModule", name: "bjs_roundTripOptional") -fileprivate func bjs_roundTripOptional_extern(_ point: Int32) -> Void +fileprivate func bjs_roundTripOptional_extern() -> Void #else -fileprivate func bjs_roundTripOptional_extern(_ point: Int32) -> Void { +fileprivate func bjs_roundTripOptional_extern() -> Void { fatalError("Only available on WebAssembly") } #endif -@inline(never) fileprivate func bjs_roundTripOptional(_ point: Int32) -> Void { - return bjs_roundTripOptional_extern(point) +@inline(never) fileprivate func bjs_roundTripOptional() -> Void { + return bjs_roundTripOptional_extern() } func _$roundTripOptional(_ point: Optional) throws(JSException) -> Optional { - let pointIsSome = point.bridgeJSLowerParameter() - bjs_roundTripOptional(pointIsSome) + let _ = point.bridgeJSLowerParameter() + bjs_roundTripOptional() if let error = _swift_js_take_exception() { throw error } return Optional.bridgeJSLiftReturn() -} \ No newline at end of file +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + Point.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/UnsafePointer.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/UnsafePointer.swift index b97729084..69011da18 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/UnsafePointer.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/UnsafePointer.swift @@ -177,4 +177,23 @@ public func _bjs_roundTripPointerFields() -> Void { #else fatalError("Only available on WebAssembly") #endif -} \ No newline at end of file +} + +extension PointerFields: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = PointerFields.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_TestModule_register_type_handles") +fileprivate func _bjs_TestModule_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_TestModule_register_type_handles") +public func _bjs_TestModule_register_type_handles() { + let typeIds: [Int32] = [ + PointerFields.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_TestModule_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Alias.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Alias.js index 92fb5a109..b1cfb68aa 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Alias.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Alias.js @@ -37,7 +37,367 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createInnerTagValuesHelpers = () => ({ + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + + function __bjs_jsValueLower(value) { + let kind; + let payload1; + let payload2; + if (value === null) { + kind = 4; + payload1 = 0; + payload2 = 0; + } else { + switch (typeof value) { + case "boolean": + kind = 0; + payload1 = value ? 1 : 0; + payload2 = 0; + break; + case "number": + kind = 2; + payload1 = 0; + payload2 = value; + break; + case "string": + kind = 1; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "undefined": + kind = 5; + payload1 = 0; + payload2 = 0; + break; + case "object": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "function": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "symbol": + kind = 7; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "bigint": + kind = 8; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + default: + throw new TypeError("Unsupported JSValue type"); + } + } + return [kind, payload1, payload2]; + } + function __bjs_jsValueLift(kind, payload1, payload2) { + let jsValue; + switch (kind) { + case 0: + jsValue = payload1 !== 0; + break; + case 1: + jsValue = swift.memory.getObject(payload1); + break; + case 2: + jsValue = payload2; + break; + case 3: + jsValue = swift.memory.getObject(payload1); + break; + case 4: + jsValue = null; + break; + case 5: + jsValue = undefined; + break; + case 7: + jsValue = swift.memory.getObject(payload1); + break; + case 8: + jsValue = swift.memory.getObject(payload1); + break; + default: + throw new TypeError("Unsupported JSValue kind " + kind); + } + return jsValue; + } + + const __bjs_codec_M10TestModuleT16PolygonReference = { + lower: (v) => { + ptrStack.push(v.pointer); + }, + lift: () => { + const ptr = ptrStack.pop(); + const obj = _exports['PolygonReference'].__construct(ptr); + return obj; + }, + }; + const __bjs_codec_Array_M10TestModuleT16PolygonReference = __bjs_arrayCodec(__bjs_codec_M10TestModuleT16PolygonReference); + const __bjs_codec_M10TestModuleT8InnerTag = { + lower: (v) => { + const caseId = enumHelpers.M10TestModuleT8InnerTag.lower(v); + i32Stack.push(caseId); + }, + lift: () => { + const enumValue = enumHelpers.M10TestModuleT8InnerTag.lift(i32Stack.pop()); + return enumValue; + }, + }; + const __bjs_codec_Optional_M10TestModuleT8InnerTag = __bjs_optionalCodec(__bjs_codec_M10TestModuleT8InnerTag); + const __bjs_codec_Array_Optional_M10TestModuleT8InnerTag = __bjs_arrayCodec(__bjs_codec_Optional_M10TestModuleT8InnerTag); + const __bjs_codec_Surface = { + lower: (v) => { + const objId = swift.memory.retain(v); + i32Stack.push(objId); + }, + lift: () => { + const objId = i32Stack.pop(); + const obj = swift.memory.getObject(objId); + swift.memory.release(objId); + return obj; + }, + }; + const __bjs_codec_Optional_Surface = __bjs_optionalCodec(__bjs_codec_Surface); + + const __bjs_createEnumHelpers_M10TestModuleT8InnerTag = () => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { @@ -139,6 +499,8 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -284,12 +646,7 @@ export async function createInstantiator(options, swift) { TestModule["bjs_produceOptionalCanvas"] = function bjs_produceOptionalCanvas() { try { let ret = imports.produceOptionalCanvas(); - const isSome = ret != null; - if (isSome) { - const objId = swift.memory.retain(ret); - i32Stack.push(objId); - } - i32Stack.push(isSome ? 1 : 0); + __bjs_codec_Optional_Surface.lower(ret); } catch (error) { setException(error); } @@ -417,8 +774,8 @@ export async function createInstantiator(options, swift) { return TagReference.__construct(ret); } } - const InnerTagHelpers = __bjs_createInnerTagValuesHelpers(); - enumHelpers.InnerTag = InnerTagHelpers; + const __bjs_helpers_M10TestModuleT8InnerTag = __bjs_createEnumHelpers_M10TestModuleT8InnerTag(); + enumHelpers.M10TestModuleT8InnerTag = __bjs_helpers_M10TestModuleT8InnerTag; const exports = { roundtripPolygon: function bjs_roundtripPolygon(polygon) { @@ -440,24 +797,9 @@ export async function createInstantiator(options, swift) { return optResult; }, polygonArray: function bjs_polygonArray(polygons) { - for (const elem of polygons) { - ptrStack.push(elem.pointer); - } - i32Stack.push(polygons.length); + __bjs_codec_Array_M10TestModuleT16PolygonReference.lower(polygons); instance.exports.bjs_polygonArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const ptr = ptrStack.pop(); - const obj = PolygonReference.__construct(ptr); - arrayResult.push(obj); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_M10TestModuleT16PolygonReference.lift(); return arrayResult; }, validatePolygon: function bjs_validatePolygon(polygon) { @@ -477,35 +819,9 @@ export async function createInstantiator(options, swift) { return TagReference.__construct(ret); }, roundtripTags: function bjs_roundtripTags(xs) { - for (const elem of xs) { - const isSome = elem != null ? 1 : 0; - if (isSome) { - const caseId = enumHelpers.InnerTag.lower(elem); - i32Stack.push(caseId); - } - i32Stack.push(isSome); - } - i32Stack.push(xs.length); + __bjs_codec_Array_Optional_M10TestModuleT8InnerTag.lower(xs); instance.exports.bjs_roundtripTags(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const isSome1 = i32Stack.pop(); - let optValue; - if (isSome1 === 0) { - optValue = null; - } else { - const enumValue = enumHelpers.InnerTag.lift(i32Stack.pop()); - optValue = enumValue; - } - arrayResult.push(optValue); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Optional_M10TestModuleT8InnerTag.lift(); return arrayResult; }, describeUser: function bjs_describeUser(owner) { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AliasInClosure.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AliasInClosure.js index a38fa118e..fa9095cd8 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AliasInClosure.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AliasInClosure.js @@ -131,6 +131,8 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayTypes.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayTypes.js index 419cf15d5..6d3992ce5 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayTypes.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayTypes.js @@ -44,7 +44,438 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createPointHelpers = () => ({ + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + + function __bjs_jsValueLower(value) { + let kind; + let payload1; + let payload2; + if (value === null) { + kind = 4; + payload1 = 0; + payload2 = 0; + } else { + switch (typeof value) { + case "boolean": + kind = 0; + payload1 = value ? 1 : 0; + payload2 = 0; + break; + case "number": + kind = 2; + payload1 = 0; + payload2 = value; + break; + case "string": + kind = 1; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "undefined": + kind = 5; + payload1 = 0; + payload2 = 0; + break; + case "object": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "function": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "symbol": + kind = 7; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "bigint": + kind = 8; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + default: + throw new TypeError("Unsupported JSValue type"); + } + } + return [kind, payload1, payload2]; + } + function __bjs_jsValueLift(kind, payload1, payload2) { + let jsValue; + switch (kind) { + case 0: + jsValue = payload1 !== 0; + break; + case 1: + jsValue = swift.memory.getObject(payload1); + break; + case 2: + jsValue = payload2; + break; + case 3: + jsValue = swift.memory.getObject(payload1); + break; + case 4: + jsValue = null; + break; + case 5: + jsValue = undefined; + break; + case 7: + jsValue = swift.memory.getObject(payload1); + break; + case 8: + jsValue = swift.memory.getObject(payload1); + break; + default: + throw new TypeError("Unsupported JSValue kind " + kind); + } + return jsValue; + } + + const __bjs_codec_Array_Int = __bjs_arrayCodec(__bjs_primitiveCodecs.Int); + const __bjs_codec_Array_String = __bjs_arrayCodec(__bjs_stringCodec); + const __bjs_codec_Array_Double = __bjs_arrayCodec(__bjs_primitiveCodecs.Double); + const __bjs_codec_Array_Bool = __bjs_arrayCodec(__bjs_primitiveCodecs.Bool); + const __bjs_codec_M10TestModuleT5Point = { + lower: (v) => { + structHelpers.M10TestModuleT5Point.lower(v); + }, + lift: () => { + const struct = structHelpers.M10TestModuleT5Point.lift(); + return struct; + }, + }; + const __bjs_codec_Array_M10TestModuleT5Point = __bjs_arrayCodec(__bjs_codec_M10TestModuleT5Point); + const __bjs_codec_M10TestModuleT9Direction = { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const caseId = i32Stack.pop(); + return caseId; + }, + }; + const __bjs_codec_Array_M10TestModuleT9Direction = __bjs_arrayCodec(__bjs_codec_M10TestModuleT9Direction); + const __bjs_codec_M10TestModuleT6Status = { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const rawValue = i32Stack.pop(); + return rawValue; + }, + }; + const __bjs_codec_Array_M10TestModuleT6Status = __bjs_arrayCodec(__bjs_codec_M10TestModuleT6Status); + const __bjs_codec_Surp = { + lower: (v) => { + ptrStack.push((v | 0)); + }, + lift: () => { + const pointer = ptrStack.pop(); + return pointer; + }, + }; + const __bjs_codec_Array_Surp = __bjs_arrayCodec(__bjs_codec_Surp); + const __bjs_codec_Sumrp = { + lower: (v) => { + ptrStack.push((v | 0)); + }, + lift: () => { + const pointer = ptrStack.pop(); + return pointer; + }, + }; + const __bjs_codec_Array_Sumrp = __bjs_arrayCodec(__bjs_codec_Sumrp); + const __bjs_codec_Sop = { + lower: (v) => { + ptrStack.push((v | 0)); + }, + lift: () => { + const pointer = ptrStack.pop(); + return pointer; + }, + }; + const __bjs_codec_Array_Sop = __bjs_arrayCodec(__bjs_codec_Sop); + const __bjs_codec_Optional_Int = __bjs_optionalCodec(__bjs_primitiveCodecs.Int); + const __bjs_codec_Array_Optional_Int = __bjs_arrayCodec(__bjs_codec_Optional_Int); + const __bjs_codec_Optional_String = __bjs_optionalCodec(__bjs_stringCodec); + const __bjs_codec_Array_Optional_String = __bjs_arrayCodec(__bjs_codec_Optional_String); + const __bjs_codec_Optional_Array_Int = __bjs_optionalCodec(__bjs_codec_Array_Int); + const __bjs_codec_Optional_M10TestModuleT5Point = __bjs_optionalCodec(__bjs_codec_M10TestModuleT5Point); + const __bjs_codec_Array_Optional_M10TestModuleT5Point = __bjs_arrayCodec(__bjs_codec_Optional_M10TestModuleT5Point); + const __bjs_codec_Optional_M10TestModuleT9Direction = __bjs_optionalCodec(__bjs_codec_M10TestModuleT9Direction); + const __bjs_codec_Array_Optional_M10TestModuleT9Direction = __bjs_arrayCodec(__bjs_codec_Optional_M10TestModuleT9Direction); + const __bjs_codec_Optional_M10TestModuleT6Status = __bjs_optionalCodec(__bjs_codec_M10TestModuleT6Status); + const __bjs_codec_Array_Optional_M10TestModuleT6Status = __bjs_arrayCodec(__bjs_codec_Optional_M10TestModuleT6Status); + const __bjs_codec_Array_Array_Int = __bjs_arrayCodec(__bjs_codec_Array_Int); + const __bjs_codec_Array_Array_String = __bjs_arrayCodec(__bjs_codec_Array_String); + const __bjs_codec_Array_Array_M10TestModuleT5Point = __bjs_arrayCodec(__bjs_codec_Array_M10TestModuleT5Point); + const __bjs_codec_M10TestModuleT4Item = { + lower: (v) => { + ptrStack.push(v.pointer); + }, + lift: () => { + const ptr = ptrStack.pop(); + const obj = _exports['Item'].__construct(ptr); + return obj; + }, + }; + const __bjs_codec_Array_M10TestModuleT4Item = __bjs_arrayCodec(__bjs_codec_M10TestModuleT4Item); + const __bjs_codec_Array_Array_M10TestModuleT4Item = __bjs_arrayCodec(__bjs_codec_Array_M10TestModuleT4Item); + const __bjs_codec_JSObject = { + lower: (v) => { + const objId = swift.memory.retain(v); + i32Stack.push(objId); + }, + lift: () => { + const objId = i32Stack.pop(); + const obj = swift.memory.getObject(objId); + swift.memory.release(objId); + return obj; + }, + }; + const __bjs_codec_Array_JSObject = __bjs_arrayCodec(__bjs_codec_JSObject); + const __bjs_codec_Optional_JSObject = __bjs_optionalCodec(__bjs_codec_JSObject); + const __bjs_codec_Array_Optional_JSObject = __bjs_arrayCodec(__bjs_codec_Optional_JSObject); + const __bjs_codec_Array_Array_JSObject = __bjs_arrayCodec(__bjs_codec_Array_JSObject); + const __bjs_codec_Optional_Array_String = __bjs_optionalCodec(__bjs_codec_Array_String); + + const __bjs_createStructHelpers_M10TestModuleT5Point = () => ({ lower: (value) => { f64Stack.push(value.x); f64Stack.push(value.y); @@ -132,12 +563,14 @@ export async function createInstantiator(options, swift) { taStack.push(Array.from(new Ctor(copy))); } bjs["swift_js_struct_lower_Point"] = function(objectId) { - structHelpers.Point.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT5Point.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Point"] = function() { - const value = structHelpers.Point.lift(); + const value = structHelpers.M10TestModuleT5Point.lift(); return swift.memory.retain(value); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -264,18 +697,7 @@ export async function createInstantiator(options, swift) { } TestModule["bjs_importProcessNumbers"] = function bjs_importProcessNumbers() { try { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const f64 = f64Stack.pop(); - arrayResult.push(f64); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Double.lift(); imports.importProcessNumbers(arrayResult); } catch (error) { setException(error); @@ -284,82 +706,34 @@ export async function createInstantiator(options, swift) { TestModule["bjs_importGetNumbers"] = function bjs_importGetNumbers() { try { let ret = imports.importGetNumbers(); - for (const elem of ret) { - f64Stack.push(elem); - } - i32Stack.push(ret.length); + __bjs_codec_Array_Double.lower(ret); } catch (error) { setException(error); } } TestModule["bjs_importTransformNumbers"] = function bjs_importTransformNumbers() { try { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const f64 = f64Stack.pop(); - arrayResult.push(f64); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Double.lift(); let ret = imports.importTransformNumbers(arrayResult); - for (const elem of ret) { - f64Stack.push(elem); - } - i32Stack.push(ret.length); + __bjs_codec_Array_Double.lower(ret); } catch (error) { setException(error); } } TestModule["bjs_importProcessStrings"] = function bjs_importProcessStrings() { try { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const string = strStack.pop(); - arrayResult.push(string); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_String.lift(); let ret = imports.importProcessStrings(arrayResult); - for (const elem of ret) { - const bytes = textEncoder.encode(elem); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - } - i32Stack.push(ret.length); + __bjs_codec_Array_String.lower(ret); } catch (error) { setException(error); } } TestModule["bjs_importProcessBooleans"] = function bjs_importProcessBooleans() { try { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const bool = i32Stack.pop() !== 0; - arrayResult.push(bool); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Bool.lift(); let ret = imports.importProcessBooleans(arrayResult); - for (const elem of ret) { - i32Stack.push(elem ? 1 : 0); - } - i32Stack.push(ret.length); + __bjs_codec_Array_Bool.lower(ret); } catch (error) { setException(error); } @@ -442,758 +816,192 @@ export async function createInstantiator(options, swift) { } constructor(nums, strs) { - for (const elem of nums) { - i32Stack.push((elem | 0)); - } - i32Stack.push(nums.length); - for (const elem1 of strs) { - const bytes = textEncoder.encode(elem1); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - } - i32Stack.push(strs.length); + __bjs_codec_Array_Int.lower(nums); + __bjs_codec_Array_String.lower(strs); const ret = instance.exports.bjs_MultiArrayContainer_init(); return MultiArrayContainer.__construct(ret); } get numbers() { instance.exports.bjs_MultiArrayContainer_numbers_get(this.pointer); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const int = i32Stack.pop(); - arrayResult.push(int); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Int.lift(); return arrayResult; } get strings() { instance.exports.bjs_MultiArrayContainer_strings_get(this.pointer); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const string = strStack.pop(); - arrayResult.push(string); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_String.lift(); return arrayResult; } } - const PointHelpers = __bjs_createPointHelpers(); - structHelpers.Point = PointHelpers; + const __bjs_helpers_M10TestModuleT5Point = __bjs_createStructHelpers_M10TestModuleT5Point(); + structHelpers.M10TestModuleT5Point = __bjs_helpers_M10TestModuleT5Point; const exports = { processIntArray: function bjs_processIntArray(values) { - for (const elem of values) { - i32Stack.push((elem | 0)); - } - i32Stack.push(values.length); + __bjs_codec_Array_Int.lower(values); instance.exports.bjs_processIntArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const int = i32Stack.pop(); - arrayResult.push(int); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Int.lift(); return arrayResult; }, processStringArray: function bjs_processStringArray(values) { - for (const elem of values) { - const bytes = textEncoder.encode(elem); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - } - i32Stack.push(values.length); + __bjs_codec_Array_String.lower(values); instance.exports.bjs_processStringArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const string = strStack.pop(); - arrayResult.push(string); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_String.lift(); return arrayResult; }, processDoubleArray: function bjs_processDoubleArray(values) { - for (const elem of values) { - f64Stack.push(elem); - } - i32Stack.push(values.length); + __bjs_codec_Array_Double.lower(values); instance.exports.bjs_processDoubleArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const f64 = f64Stack.pop(); - arrayResult.push(f64); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Double.lift(); return arrayResult; }, processBoolArray: function bjs_processBoolArray(values) { - for (const elem of values) { - i32Stack.push(elem ? 1 : 0); - } - i32Stack.push(values.length); + __bjs_codec_Array_Bool.lower(values); instance.exports.bjs_processBoolArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const bool = i32Stack.pop() !== 0; - arrayResult.push(bool); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Bool.lift(); return arrayResult; }, processPointArray: function bjs_processPointArray(points) { - for (const elem of points) { - structHelpers.Point.lower(elem); - } - i32Stack.push(points.length); + __bjs_codec_Array_M10TestModuleT5Point.lower(points); instance.exports.bjs_processPointArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const struct = structHelpers.Point.lift(); - arrayResult.push(struct); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_M10TestModuleT5Point.lift(); return arrayResult; }, processDirectionArray: function bjs_processDirectionArray(directions) { - for (const elem of directions) { - i32Stack.push((elem | 0)); - } - i32Stack.push(directions.length); + __bjs_codec_Array_M10TestModuleT9Direction.lower(directions); instance.exports.bjs_processDirectionArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const caseId = i32Stack.pop(); - arrayResult.push(caseId); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_M10TestModuleT9Direction.lift(); return arrayResult; }, processStatusArray: function bjs_processStatusArray(statuses) { - for (const elem of statuses) { - i32Stack.push((elem | 0)); - } - i32Stack.push(statuses.length); + __bjs_codec_Array_M10TestModuleT6Status.lower(statuses); instance.exports.bjs_processStatusArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const rawValue = i32Stack.pop(); - arrayResult.push(rawValue); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_M10TestModuleT6Status.lift(); return arrayResult; }, sumIntArray: function bjs_sumIntArray(values) { - for (const elem of values) { - i32Stack.push((elem | 0)); - } - i32Stack.push(values.length); + __bjs_codec_Array_Int.lower(values); const ret = instance.exports.bjs_sumIntArray(); return ret; }, findFirstPoint: function bjs_findFirstPoint(points, matching) { - for (const elem of points) { - structHelpers.Point.lower(elem); - } - i32Stack.push(points.length); + __bjs_codec_Array_M10TestModuleT5Point.lower(points); const matchingBytes = textEncoder.encode(matching); const matchingId = swift.memory.retain(matchingBytes); instance.exports.bjs_findFirstPoint(matchingId, matchingBytes.length); - const structValue = structHelpers.Point.lift(); + const structValue = structHelpers.M10TestModuleT5Point.lift(); return structValue; }, processUnsafeRawPointerArray: function bjs_processUnsafeRawPointerArray(values) { - for (const elem of values) { - ptrStack.push((elem | 0)); - } - i32Stack.push(values.length); + __bjs_codec_Array_Surp.lower(values); instance.exports.bjs_processUnsafeRawPointerArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const pointer = ptrStack.pop(); - arrayResult.push(pointer); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Surp.lift(); return arrayResult; }, processUnsafeMutableRawPointerArray: function bjs_processUnsafeMutableRawPointerArray(values) { - for (const elem of values) { - ptrStack.push((elem | 0)); - } - i32Stack.push(values.length); + __bjs_codec_Array_Sumrp.lower(values); instance.exports.bjs_processUnsafeMutableRawPointerArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const pointer = ptrStack.pop(); - arrayResult.push(pointer); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Sumrp.lift(); return arrayResult; }, processOpaquePointerArray: function bjs_processOpaquePointerArray(values) { - for (const elem of values) { - ptrStack.push((elem | 0)); - } - i32Stack.push(values.length); + __bjs_codec_Array_Sop.lower(values); instance.exports.bjs_processOpaquePointerArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const pointer = ptrStack.pop(); - arrayResult.push(pointer); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Sop.lift(); return arrayResult; }, processOptionalIntArray: function bjs_processOptionalIntArray(values) { - for (const elem of values) { - const isSome = elem != null ? 1 : 0; - if (isSome) { - i32Stack.push((elem | 0)); - } - i32Stack.push(isSome); - } - i32Stack.push(values.length); + __bjs_codec_Array_Optional_Int.lower(values); instance.exports.bjs_processOptionalIntArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const isSome1 = i32Stack.pop(); - let optValue; - if (isSome1 === 0) { - optValue = null; - } else { - const int = i32Stack.pop(); - optValue = int; - } - arrayResult.push(optValue); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Optional_Int.lift(); return arrayResult; }, processOptionalStringArray: function bjs_processOptionalStringArray(values) { - for (const elem of values) { - const isSome = elem != null ? 1 : 0; - if (isSome) { - const bytes = textEncoder.encode(elem); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - } - i32Stack.push(isSome); - } - i32Stack.push(values.length); + __bjs_codec_Array_Optional_String.lower(values); instance.exports.bjs_processOptionalStringArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const isSome1 = i32Stack.pop(); - let optValue; - if (isSome1 === 0) { - optValue = null; - } else { - const string = strStack.pop(); - optValue = string; - } - arrayResult.push(optValue); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Optional_String.lift(); return arrayResult; }, processOptionalArray: function bjs_processOptionalArray(values) { - const isSome = values != null; - if (isSome) { - for (const elem of values) { - i32Stack.push((elem | 0)); - } - i32Stack.push(values.length); - } - i32Stack.push(+isSome); + __bjs_codec_Optional_Array_Int.lower(values); instance.exports.bjs_processOptionalArray(); - const isSome1 = i32Stack.pop(); - let optResult; - if (isSome1) { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const int = i32Stack.pop(); - arrayResult.push(int); - } - arrayResult.reverse(); - } - optResult = arrayResult; - } else { - optResult = null; - } - return optResult; + const optValue = __bjs_codec_Optional_Array_Int.lift(); + return optValue; }, processOptionalPointArray: function bjs_processOptionalPointArray(points) { - for (const elem of points) { - const isSome = elem != null ? 1 : 0; - if (isSome) { - structHelpers.Point.lower(elem); - } - i32Stack.push(isSome); - } - i32Stack.push(points.length); + __bjs_codec_Array_Optional_M10TestModuleT5Point.lower(points); instance.exports.bjs_processOptionalPointArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const isSome1 = i32Stack.pop(); - let optValue; - if (isSome1 === 0) { - optValue = null; - } else { - const struct = structHelpers.Point.lift(); - optValue = struct; - } - arrayResult.push(optValue); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Optional_M10TestModuleT5Point.lift(); return arrayResult; }, processOptionalDirectionArray: function bjs_processOptionalDirectionArray(directions) { - for (const elem of directions) { - const isSome = elem != null ? 1 : 0; - if (isSome) { - i32Stack.push((elem | 0)); - } - i32Stack.push(isSome); - } - i32Stack.push(directions.length); + __bjs_codec_Array_Optional_M10TestModuleT9Direction.lower(directions); instance.exports.bjs_processOptionalDirectionArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const isSome1 = i32Stack.pop(); - let optValue; - if (isSome1 === 0) { - optValue = null; - } else { - const caseId = i32Stack.pop(); - optValue = caseId; - } - arrayResult.push(optValue); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Optional_M10TestModuleT9Direction.lift(); return arrayResult; }, processOptionalStatusArray: function bjs_processOptionalStatusArray(statuses) { - for (const elem of statuses) { - const isSome = elem != null ? 1 : 0; - if (isSome) { - i32Stack.push((elem | 0)); - } - i32Stack.push(isSome); - } - i32Stack.push(statuses.length); + __bjs_codec_Array_Optional_M10TestModuleT6Status.lower(statuses); instance.exports.bjs_processOptionalStatusArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const isSome1 = i32Stack.pop(); - let optValue; - if (isSome1 === 0) { - optValue = null; - } else { - const rawValue = i32Stack.pop(); - optValue = rawValue; - } - arrayResult.push(optValue); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Optional_M10TestModuleT6Status.lift(); return arrayResult; }, processNestedIntArray: function bjs_processNestedIntArray(values) { - for (const elem of values) { - for (const elem1 of elem) { - i32Stack.push((elem1 | 0)); - } - i32Stack.push(elem.length); - } - i32Stack.push(values.length); + __bjs_codec_Array_Array_Int.lower(values); instance.exports.bjs_processNestedIntArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const arrayLen1 = i32Stack.pop(); - let arrayResult1; - if (arrayLen1 === -1) { - arrayResult1 = taStack.pop(); - } else { - arrayResult1 = []; - for (let i1 = 0; i1 < arrayLen1; i1++) { - const int = i32Stack.pop(); - arrayResult1.push(int); - } - arrayResult1.reverse(); - } - arrayResult.push(arrayResult1); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Array_Int.lift(); return arrayResult; }, processNestedStringArray: function bjs_processNestedStringArray(values) { - for (const elem of values) { - for (const elem1 of elem) { - const bytes = textEncoder.encode(elem1); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - } - i32Stack.push(elem.length); - } - i32Stack.push(values.length); + __bjs_codec_Array_Array_String.lower(values); instance.exports.bjs_processNestedStringArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const arrayLen1 = i32Stack.pop(); - let arrayResult1; - if (arrayLen1 === -1) { - arrayResult1 = taStack.pop(); - } else { - arrayResult1 = []; - for (let i1 = 0; i1 < arrayLen1; i1++) { - const string = strStack.pop(); - arrayResult1.push(string); - } - arrayResult1.reverse(); - } - arrayResult.push(arrayResult1); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Array_String.lift(); return arrayResult; }, processNestedPointArray: function bjs_processNestedPointArray(points) { - for (const elem of points) { - for (const elem1 of elem) { - structHelpers.Point.lower(elem1); - } - i32Stack.push(elem.length); - } - i32Stack.push(points.length); + __bjs_codec_Array_Array_M10TestModuleT5Point.lower(points); instance.exports.bjs_processNestedPointArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const arrayLen1 = i32Stack.pop(); - let arrayResult1; - if (arrayLen1 === -1) { - arrayResult1 = taStack.pop(); - } else { - arrayResult1 = []; - for (let i1 = 0; i1 < arrayLen1; i1++) { - const struct = structHelpers.Point.lift(); - arrayResult1.push(struct); - } - arrayResult1.reverse(); - } - arrayResult.push(arrayResult1); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Array_M10TestModuleT5Point.lift(); return arrayResult; }, processItemArray: function bjs_processItemArray(items) { - for (const elem of items) { - ptrStack.push(elem.pointer); - } - i32Stack.push(items.length); + __bjs_codec_Array_M10TestModuleT4Item.lower(items); instance.exports.bjs_processItemArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const ptr = ptrStack.pop(); - const obj = Item.__construct(ptr); - arrayResult.push(obj); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_M10TestModuleT4Item.lift(); return arrayResult; }, processNestedItemArray: function bjs_processNestedItemArray(items) { - for (const elem of items) { - for (const elem1 of elem) { - ptrStack.push(elem1.pointer); - } - i32Stack.push(elem.length); - } - i32Stack.push(items.length); + __bjs_codec_Array_Array_M10TestModuleT4Item.lower(items); instance.exports.bjs_processNestedItemArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const arrayLen1 = i32Stack.pop(); - let arrayResult1; - if (arrayLen1 === -1) { - arrayResult1 = taStack.pop(); - } else { - arrayResult1 = []; - for (let i1 = 0; i1 < arrayLen1; i1++) { - const ptr = ptrStack.pop(); - const obj = Item.__construct(ptr); - arrayResult1.push(obj); - } - arrayResult1.reverse(); - } - arrayResult.push(arrayResult1); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Array_M10TestModuleT4Item.lift(); return arrayResult; }, processJSObjectArray: function bjs_processJSObjectArray(objects) { - for (const elem of objects) { - const objId = swift.memory.retain(elem); - i32Stack.push(objId); - } - i32Stack.push(objects.length); + __bjs_codec_Array_JSObject.lower(objects); instance.exports.bjs_processJSObjectArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const objId1 = i32Stack.pop(); - const obj = swift.memory.getObject(objId1); - swift.memory.release(objId1); - arrayResult.push(obj); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_JSObject.lift(); return arrayResult; }, processOptionalJSObjectArray: function bjs_processOptionalJSObjectArray(objects) { - for (const elem of objects) { - const isSome = elem != null ? 1 : 0; - if (isSome) { - const objId = swift.memory.retain(elem); - i32Stack.push(objId); - } - i32Stack.push(isSome); - } - i32Stack.push(objects.length); + __bjs_codec_Array_Optional_JSObject.lower(objects); instance.exports.bjs_processOptionalJSObjectArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const isSome1 = i32Stack.pop(); - let optValue; - if (isSome1 === 0) { - optValue = null; - } else { - const objId1 = i32Stack.pop(); - const obj = swift.memory.getObject(objId1); - swift.memory.release(objId1); - optValue = obj; - } - arrayResult.push(optValue); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Optional_JSObject.lift(); return arrayResult; }, processNestedJSObjectArray: function bjs_processNestedJSObjectArray(objects) { - for (const elem of objects) { - for (const elem1 of elem) { - const objId = swift.memory.retain(elem1); - i32Stack.push(objId); - } - i32Stack.push(elem.length); - } - i32Stack.push(objects.length); + __bjs_codec_Array_Array_JSObject.lower(objects); instance.exports.bjs_processNestedJSObjectArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const arrayLen1 = i32Stack.pop(); - let arrayResult1; - if (arrayLen1 === -1) { - arrayResult1 = taStack.pop(); - } else { - arrayResult1 = []; - for (let i1 = 0; i1 < arrayLen1; i1++) { - const objId1 = i32Stack.pop(); - const obj = swift.memory.getObject(objId1); - swift.memory.release(objId1); - arrayResult1.push(obj); - } - arrayResult1.reverse(); - } - arrayResult.push(arrayResult1); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Array_JSObject.lift(); return arrayResult; }, multiArrayParams: function bjs_multiArrayParams(nums, strs) { - for (const elem of nums) { - i32Stack.push((elem | 0)); - } - i32Stack.push(nums.length); - for (const elem1 of strs) { - const bytes = textEncoder.encode(elem1); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - } - i32Stack.push(strs.length); + __bjs_codec_Array_Int.lower(nums); + __bjs_codec_Array_String.lower(strs); const ret = instance.exports.bjs_multiArrayParams(); return ret; }, multiOptionalArrayParams: function bjs_multiOptionalArrayParams(a, b) { - const isSome = a != null; - if (isSome) { - for (const elem of a) { - i32Stack.push((elem | 0)); - } - i32Stack.push(a.length); - } - i32Stack.push(+isSome); - const isSome1 = b != null; - if (isSome1) { - for (const elem1 of b) { - const bytes = textEncoder.encode(elem1); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - } - i32Stack.push(b.length); - } - i32Stack.push(+isSome1); + __bjs_codec_Optional_Array_Int.lower(a); + __bjs_codec_Optional_Array_String.lower(b); const ret = instance.exports.bjs_multiOptionalArrayParams(); return ret; }, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.js index 9f2faf589..c025cf4f0 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.js @@ -41,6 +41,240 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + function __bjs_jsValueLower(value) { let kind; let payload1; @@ -130,7 +364,31 @@ export async function createInstantiator(options, swift) { return jsValue; } - const __bjs_createAsyncPointHelpers = () => ({ + const __bjs_codec_M10TestModuleT10AsyncPoint = { + lower: (v) => { + structHelpers.M10TestModuleT10AsyncPoint.lower(v); + }, + lift: () => { + const struct = structHelpers.M10TestModuleT10AsyncPoint.lift(); + return struct; + }, + }; + const __bjs_codec_Optional_M10TestModuleT10AsyncPoint = __bjs_optionalCodec(__bjs_codec_M10TestModuleT10AsyncPoint); + const __bjs_codec_Array_M10TestModuleT10AsyncPoint = __bjs_arrayCodec(__bjs_codec_M10TestModuleT10AsyncPoint); + const __bjs_codec_M10TestModuleT14AsyncDirection = { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const caseId = i32Stack.pop(); + return caseId; + }, + }; + const __bjs_codec_Array_M10TestModuleT14AsyncDirection = __bjs_arrayCodec(__bjs_codec_M10TestModuleT14AsyncDirection); + const __bjs_codec_Dict_M10TestModuleT10AsyncPoint = __bjs_dictCodec(__bjs_codec_M10TestModuleT10AsyncPoint); + const __bjs_codec_Dict_M10TestModuleT14AsyncDirection = __bjs_dictCodec(__bjs_codec_M10TestModuleT14AsyncDirection); + + const __bjs_createStructHelpers_M10TestModuleT10AsyncPoint = () => ({ lower: (value) => { i32Stack.push((value.x | 0)); i32Stack.push((value.y | 0)); @@ -217,12 +475,14 @@ export async function createInstantiator(options, swift) { taStack.push(Array.from(new Ctor(copy))); } bjs["swift_js_struct_lower_AsyncPoint"] = function(objectId) { - structHelpers.AsyncPoint.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT10AsyncPoint.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_AsyncPoint"] = function() { - const value = structHelpers.AsyncPoint.lift(); + const value = structHelpers.M10TestModuleT10AsyncPoint.lift(); return swift.memory.retain(value); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -282,7 +542,7 @@ export async function createInstantiator(options, swift) { } bjs["promise_resolve_TestModule_10AsyncPointV"] = function(promise) { try { - const structValue = structHelpers.AsyncPoint.lift(); + const structValue = structHelpers.M10TestModuleT10AsyncPoint.lift(); swift.memory.getObject(promise)[__bjs_promiseSettlers].resolve(structValue); } catch (error) { setException(error); @@ -324,34 +584,17 @@ export async function createInstantiator(options, swift) { setException(error); } } - bjs["promise_resolve_TestModule_Sq10AsyncPointV"] = function(promise, value) { + bjs["promise_resolve_TestModule_Sq10AsyncPointV"] = function(promise) { try { - let optResult; - if (value) { - const struct = structHelpers.AsyncPoint.lift(); - optResult = struct; - } else { - optResult = null; - } - swift.memory.getObject(promise)[__bjs_promiseSettlers].resolve(optResult); + const optValue = __bjs_codec_Optional_M10TestModuleT10AsyncPoint.lift(); + swift.memory.getObject(promise)[__bjs_promiseSettlers].resolve(optValue); } catch (error) { setException(error); } } bjs["promise_resolve_TestModule_Sa10AsyncPointV"] = function(promise) { try { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const struct = structHelpers.AsyncPoint.lift(); - arrayResult.push(struct); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_M10TestModuleT10AsyncPoint.lift(); swift.memory.getObject(promise)[__bjs_promiseSettlers].resolve(arrayResult); } catch (error) { setException(error); @@ -359,18 +602,7 @@ export async function createInstantiator(options, swift) { } bjs["promise_resolve_TestModule_Sa14AsyncDirectionO"] = function(promise) { try { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const caseId = i32Stack.pop(); - arrayResult.push(caseId); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_M10TestModuleT14AsyncDirection.lift(); swift.memory.getObject(promise)[__bjs_promiseSettlers].resolve(arrayResult); } catch (error) { setException(error); @@ -378,13 +610,7 @@ export async function createInstantiator(options, swift) { } bjs["promise_resolve_TestModule_SD10AsyncPointV"] = function(promise) { try { - const dictLen = i32Stack.pop(); - const dictResult = {}; - for (let i = 0; i < dictLen; i++) { - const struct = structHelpers.AsyncPoint.lift(); - const string = strStack.pop(); - dictResult[string] = struct; - } + const dictResult = __bjs_codec_Dict_M10TestModuleT10AsyncPoint.lift(); swift.memory.getObject(promise)[__bjs_promiseSettlers].resolve(dictResult); } catch (error) { setException(error); @@ -392,13 +618,7 @@ export async function createInstantiator(options, swift) { } bjs["promise_resolve_TestModule_SD14AsyncDirectionO"] = function(promise) { try { - const dictLen = i32Stack.pop(); - const dictResult = {}; - for (let i = 0; i < dictLen; i++) { - const caseId = i32Stack.pop(); - const string = strStack.pop(); - dictResult[string] = caseId; - } + const dictResult = __bjs_codec_Dict_M10TestModuleT14AsyncDirection.lift(); swift.memory.getObject(promise)[__bjs_promiseSettlers].resolve(dictResult); } catch (error) { setException(error); @@ -516,8 +736,8 @@ export async function createInstantiator(options, swift) { /** @param {WebAssembly.Instance} instance */ createExports: (instance) => { const js = swift.memory.heap; - const AsyncPointHelpers = __bjs_createAsyncPointHelpers(); - structHelpers.AsyncPoint = AsyncPointHelpers; + const __bjs_helpers_M10TestModuleT10AsyncPoint = __bjs_createStructHelpers_M10TestModuleT10AsyncPoint(); + structHelpers.M10TestModuleT10AsyncPoint = __bjs_helpers_M10TestModuleT10AsyncPoint; const exports = { asyncReturnVoid: function bjs_asyncReturnVoid() { @@ -565,14 +785,14 @@ export async function createInstantiator(options, swift) { return ret1; }, asyncRoundTripStruct: function bjs_asyncRoundTripStruct(v) { - structHelpers.AsyncPoint.lower(v); + structHelpers.M10TestModuleT10AsyncPoint.lower(v); const ret = instance.exports.bjs_asyncRoundTripStruct(); const ret1 = swift.memory.getObject(ret); swift.memory.release(ret); return ret1; }, asyncRoundTripStructThrows: function bjs_asyncRoundTripStructThrows(v) { - structHelpers.AsyncPoint.lower(v); + structHelpers.M10TestModuleT10AsyncPoint.lower(v); const ret = instance.exports.bjs_asyncRoundTripStructThrows(); const ret1 = swift.memory.getObject(ret); swift.memory.release(ret); @@ -597,8 +817,8 @@ export async function createInstantiator(options, swift) { return ret1; }, asyncCombineStructs: function bjs_asyncCombineStructs(a, b) { - structHelpers.AsyncPoint.lower(a); - structHelpers.AsyncPoint.lower(b); + structHelpers.M10TestModuleT10AsyncPoint.lower(a); + structHelpers.M10TestModuleT10AsyncPoint.lower(b); const ret = instance.exports.bjs_asyncCombineStructs(); const ret1 = swift.memory.getObject(ret); swift.memory.release(ret); @@ -643,63 +863,35 @@ export async function createInstantiator(options, swift) { return ret1; }, asyncRoundTripOptionalStruct: function bjs_asyncRoundTripOptionalStruct(v) { - const isSome = v != null; - if (isSome) { - structHelpers.AsyncPoint.lower(v); - } - i32Stack.push(+isSome); + __bjs_codec_Optional_M10TestModuleT10AsyncPoint.lower(v); const ret = instance.exports.bjs_asyncRoundTripOptionalStruct(); const ret1 = swift.memory.getObject(ret); swift.memory.release(ret); return ret1; }, asyncRoundTripStructArray: function bjs_asyncRoundTripStructArray(v) { - for (const elem of v) { - structHelpers.AsyncPoint.lower(elem); - } - i32Stack.push(v.length); + __bjs_codec_Array_M10TestModuleT10AsyncPoint.lower(v); const ret = instance.exports.bjs_asyncRoundTripStructArray(); const ret1 = swift.memory.getObject(ret); swift.memory.release(ret); return ret1; }, asyncRoundTripEnumArray: function bjs_asyncRoundTripEnumArray(v) { - for (const elem of v) { - i32Stack.push((elem | 0)); - } - i32Stack.push(v.length); + __bjs_codec_Array_M10TestModuleT14AsyncDirection.lower(v); const ret = instance.exports.bjs_asyncRoundTripEnumArray(); const ret1 = swift.memory.getObject(ret); swift.memory.release(ret); return ret1; }, asyncRoundTripStructDictionary: function bjs_asyncRoundTripStructDictionary(v) { - const entries = Object.entries(v); - for (const entry of entries) { - const [key, value] = entry; - const bytes = textEncoder.encode(key); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - structHelpers.AsyncPoint.lower(value); - } - i32Stack.push(entries.length); + __bjs_codec_Dict_M10TestModuleT10AsyncPoint.lower(v); const ret = instance.exports.bjs_asyncRoundTripStructDictionary(); const ret1 = swift.memory.getObject(ret); swift.memory.release(ret); return ret1; }, asyncRoundTripEnumDictionary: function bjs_asyncRoundTripEnumDictionary(v) { - const entries = Object.entries(v); - for (const entry of entries) { - const [key, value] = entry; - const bytes = textEncoder.encode(key); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - i32Stack.push((value | 0)); - } - i32Stack.push(entries.length); + __bjs_codec_Dict_M10TestModuleT14AsyncDirection.lower(v); const ret = instance.exports.bjs_asyncRoundTripEnumDictionary(); const ret1 = swift.memory.getObject(ret); swift.memory.release(ret); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncAssociatedValueEnum.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncAssociatedValueEnum.js index 98c0aff46..49b2ff88b 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncAssociatedValueEnum.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncAssociatedValueEnum.js @@ -127,7 +127,7 @@ export async function createInstantiator(options, swift) { return jsValue; } - const __bjs_createAsyncPayloadResultValuesHelpers = () => ({ + const __bjs_createEnumHelpers_M10TestModuleT18AsyncPayloadResult = () => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { @@ -239,6 +239,8 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -248,7 +250,7 @@ export async function createInstantiator(options, swift) { } bjs["promise_resolve_TestModule_18AsyncPayloadResultO"] = function(promise, value) { try { - const enumValue = enumHelpers.AsyncPayloadResult.lift(value); + const enumValue = enumHelpers.M10TestModuleT18AsyncPayloadResult.lift(value); swift.memory.getObject(promise)[__bjs_promiseSettlers].resolve(enumValue); } catch (error) { setException(error); @@ -258,7 +260,7 @@ export async function createInstantiator(options, swift) { try { let optResult; if (valueIsSome) { - const enumValue = enumHelpers.AsyncPayloadResult.lift(valueCaseId); + const enumValue = enumHelpers.M10TestModuleT18AsyncPayloadResult.lift(valueCaseId); optResult = enumValue; } else { optResult = null; @@ -380,12 +382,12 @@ export async function createInstantiator(options, swift) { /** @param {WebAssembly.Instance} instance */ createExports: (instance) => { const js = swift.memory.heap; - const AsyncPayloadResultHelpers = __bjs_createAsyncPayloadResultValuesHelpers(); - enumHelpers.AsyncPayloadResult = AsyncPayloadResultHelpers; + const __bjs_helpers_M10TestModuleT18AsyncPayloadResult = __bjs_createEnumHelpers_M10TestModuleT18AsyncPayloadResult(); + enumHelpers.M10TestModuleT18AsyncPayloadResult = __bjs_helpers_M10TestModuleT18AsyncPayloadResult; const exports = { asyncRoundTripAssociatedValueEnum: function bjs_asyncRoundTripAssociatedValueEnum(value) { - const valueCaseId = enumHelpers.AsyncPayloadResult.lower(value); + const valueCaseId = enumHelpers.M10TestModuleT18AsyncPayloadResult.lower(value); const ret = instance.exports.bjs_asyncRoundTripAssociatedValueEnum(valueCaseId); const ret1 = swift.memory.getObject(ret); swift.memory.release(ret); @@ -395,7 +397,7 @@ export async function createInstantiator(options, swift) { const isSome = value != null; let result; if (isSome) { - const valueCaseId = enumHelpers.AsyncPayloadResult.lower(value); + const valueCaseId = enumHelpers.M10TestModuleT18AsyncPayloadResult.lower(value); result = valueCaseId; } else { result = 0; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncImport.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncImport.js index fa50b23f2..96c0d11e8 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncImport.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncImport.js @@ -221,6 +221,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncStaticImport.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncStaticImport.js index c359886b3..47dd161a2 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncStaticImport.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncStaticImport.js @@ -220,6 +220,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ClassWithNestedTypes.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ClassWithNestedTypes.js index 272bb8c49..ecdb0b059 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ClassWithNestedTypes.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ClassWithNestedTypes.js @@ -36,7 +36,7 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createAccount_CredentialsHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT7AccountT11Credentials = () => ({ lower: (value) => { const bytes = textEncoder.encode(value.token); const id = swift.memory.retain(bytes); @@ -124,12 +124,14 @@ export async function createInstantiator(options, swift) { taStack.push(Array.from(new Ctor(copy))); } bjs["swift_js_struct_lower_Account_Credentials"] = function(objectId) { - structHelpers.Account_Credentials.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT7AccountT11Credentials.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Account_Credentials"] = function() { - const value = structHelpers.Account_Credentials.lift(); + const value = structHelpers.M10TestModuleT7AccountT11Credentials.lift(); return swift.memory.retain(value); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -342,8 +344,8 @@ export async function createInstantiator(options, swift) { return ret; } } - const Account_CredentialsHelpers = __bjs_createAccount_CredentialsHelpers(); - structHelpers.Account_Credentials = Account_CredentialsHelpers; + const __bjs_helpers_M10TestModuleT7AccountT11Credentials = __bjs_createStructHelpers_M10TestModuleT7AccountT11Credentials(); + structHelpers.M10TestModuleT7AccountT11Credentials = __bjs_helpers_M10TestModuleT7AccountT11Credentials; const exports = { Account: Object.assign(Account, { @@ -353,7 +355,7 @@ export async function createInstantiator(options, swift) { const tokenBytes = textEncoder.encode(token); const tokenId = swift.memory.retain(tokenBytes); instance.exports.bjs_Account_Credentials_init(tokenId, tokenBytes.length); - const structValue = structHelpers.Account_Credentials.lift(); + const structValue = structHelpers.M10TestModuleT7AccountT11Credentials.lift(); return structValue; }, get maxLength() { @@ -362,7 +364,7 @@ export async function createInstantiator(options, swift) { }, empty: function() { instance.exports.bjs_Account_Credentials_static_empty(); - const structValue = structHelpers.Account_Credentials.lift(); + const structValue = structHelpers.M10TestModuleT7AccountT11Credentials.lift(); return structValue; }, }, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DefaultParameters.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DefaultParameters.js index ba2b7cc77..fe1fa7b54 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DefaultParameters.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DefaultParameters.js @@ -37,7 +37,345 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createConfigHelpers = () => ({ + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + + function __bjs_jsValueLower(value) { + let kind; + let payload1; + let payload2; + if (value === null) { + kind = 4; + payload1 = 0; + payload2 = 0; + } else { + switch (typeof value) { + case "boolean": + kind = 0; + payload1 = value ? 1 : 0; + payload2 = 0; + break; + case "number": + kind = 2; + payload1 = 0; + payload2 = value; + break; + case "string": + kind = 1; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "undefined": + kind = 5; + payload1 = 0; + payload2 = 0; + break; + case "object": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "function": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "symbol": + kind = 7; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "bigint": + kind = 8; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + default: + throw new TypeError("Unsupported JSValue type"); + } + } + return [kind, payload1, payload2]; + } + function __bjs_jsValueLift(kind, payload1, payload2) { + let jsValue; + switch (kind) { + case 0: + jsValue = payload1 !== 0; + break; + case 1: + jsValue = swift.memory.getObject(payload1); + break; + case 2: + jsValue = payload2; + break; + case 3: + jsValue = swift.memory.getObject(payload1); + break; + case 4: + jsValue = null; + break; + case 5: + jsValue = undefined; + break; + case 7: + jsValue = swift.memory.getObject(payload1); + break; + case 8: + jsValue = swift.memory.getObject(payload1); + break; + default: + throw new TypeError("Unsupported JSValue kind " + kind); + } + return jsValue; + } + + const __bjs_codec_M10TestModuleT6Config = { + lower: (v) => { + structHelpers.M10TestModuleT6Config.lower(v); + }, + lift: () => { + const struct = structHelpers.M10TestModuleT6Config.lift(); + return struct; + }, + }; + const __bjs_codec_Optional_M10TestModuleT6Config = __bjs_optionalCodec(__bjs_codec_M10TestModuleT6Config); + const __bjs_codec_Array_Int = __bjs_arrayCodec(__bjs_primitiveCodecs.Int); + const __bjs_codec_Array_String = __bjs_arrayCodec(__bjs_stringCodec); + const __bjs_codec_Array_Double = __bjs_arrayCodec(__bjs_primitiveCodecs.Double); + const __bjs_codec_Array_Bool = __bjs_arrayCodec(__bjs_primitiveCodecs.Bool); + + const __bjs_createStructHelpers_M10TestModuleT6Config = () => ({ lower: (value) => { const bytes = textEncoder.encode(value.name); const id = swift.memory.retain(bytes); @@ -53,7 +391,7 @@ export async function createInstantiator(options, swift) { return { name: string, value: int, enabled: bool }; } }); - const __bjs_createMathOperationsHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT14MathOperations = () => ({ lower: (value) => { f64Stack.push(value.baseValue); }, @@ -61,12 +399,12 @@ export async function createInstantiator(options, swift) { const f64 = f64Stack.pop(); const instance1 = { baseValue: f64 }; instance1.add = function(a, b = 10.0) { - structHelpers.MathOperations.lower(this); + structHelpers.M10TestModuleT14MathOperations.lower(this); const ret = instance.exports.bjs_MathOperations_add(a, b); return ret; }.bind(instance1); instance1.multiply = function(a, b) { - structHelpers.MathOperations.lower(this); + structHelpers.M10TestModuleT14MathOperations.lower(this); const ret1 = instance.exports.bjs_MathOperations_multiply(a, b); return ret1; }.bind(instance1); @@ -149,19 +487,21 @@ export async function createInstantiator(options, swift) { taStack.push(Array.from(new Ctor(copy))); } bjs["swift_js_struct_lower_Config"] = function(objectId) { - structHelpers.Config.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT6Config.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Config"] = function() { - const value = structHelpers.Config.lift(); + const value = structHelpers.M10TestModuleT6Config.lift(); return swift.memory.retain(value); } bjs["swift_js_struct_lower_MathOperations"] = function(objectId) { - structHelpers.MathOperations.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT14MathOperations.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_MathOperations"] = function() { - const value = structHelpers.MathOperations.lift(); + const value = structHelpers.M10TestModuleT14MathOperations.lift(); return swift.memory.retain(value); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -449,11 +789,11 @@ export async function createInstantiator(options, swift) { instance.exports.bjs_ConstructorDefaults_tag_set(this.pointer, +isSome, result, result1); } } - const ConfigHelpers = __bjs_createConfigHelpers(); - structHelpers.Config = ConfigHelpers; + const __bjs_helpers_M10TestModuleT6Config = __bjs_createStructHelpers_M10TestModuleT6Config(); + structHelpers.M10TestModuleT6Config = __bjs_helpers_M10TestModuleT6Config; - const MathOperationsHelpers = __bjs_createMathOperationsHelpers(); - structHelpers.MathOperations = MathOperationsHelpers; + const __bjs_helpers_M10TestModuleT14MathOperations = __bjs_createStructHelpers_M10TestModuleT14MathOperations(); + structHelpers.M10TestModuleT14MathOperations = __bjs_helpers_M10TestModuleT14MathOperations; const exports = { testStringDefault: function bjs_testStringDefault(message = "Hello World") { @@ -535,137 +875,51 @@ export async function createInstantiator(options, swift) { return EmptyGreeter.__construct(ret); }, testOptionalStructDefault: function bjs_testOptionalStructDefault(point = null) { - const isSome = point != null; - if (isSome) { - structHelpers.Config.lower(point); - } - i32Stack.push(+isSome); + __bjs_codec_Optional_M10TestModuleT6Config.lower(point); instance.exports.bjs_testOptionalStructDefault(); - const isSome1 = i32Stack.pop(); - const optResult = isSome1 ? structHelpers.Config.lift() : null; - return optResult; + const optValue = __bjs_codec_Optional_M10TestModuleT6Config.lift(); + return optValue; }, testOptionalStructWithValueDefault: function bjs_testOptionalStructWithValueDefault(point = { name: "default", value: 42, enabled: true }) { - const isSome = point != null; - if (isSome) { - structHelpers.Config.lower(point); - } - i32Stack.push(+isSome); + __bjs_codec_Optional_M10TestModuleT6Config.lower(point); instance.exports.bjs_testOptionalStructWithValueDefault(); - const isSome1 = i32Stack.pop(); - const optResult = isSome1 ? structHelpers.Config.lift() : null; - return optResult; + const optValue = __bjs_codec_Optional_M10TestModuleT6Config.lift(); + return optValue; }, testIntArrayDefault: function bjs_testIntArrayDefault(values = [1, 2, 3]) { - for (const elem of values) { - i32Stack.push((elem | 0)); - } - i32Stack.push(values.length); + __bjs_codec_Array_Int.lower(values); instance.exports.bjs_testIntArrayDefault(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const int = i32Stack.pop(); - arrayResult.push(int); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Int.lift(); return arrayResult; }, testStringArrayDefault: function bjs_testStringArrayDefault(names = ["a", "b", "c"]) { - for (const elem of names) { - const bytes = textEncoder.encode(elem); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - } - i32Stack.push(names.length); + __bjs_codec_Array_String.lower(names); instance.exports.bjs_testStringArrayDefault(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const string = strStack.pop(); - arrayResult.push(string); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_String.lift(); return arrayResult; }, testDoubleArrayDefault: function bjs_testDoubleArrayDefault(values = [1.5, 2.5, 3.5]) { - for (const elem of values) { - f64Stack.push(elem); - } - i32Stack.push(values.length); + __bjs_codec_Array_Double.lower(values); instance.exports.bjs_testDoubleArrayDefault(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const f64 = f64Stack.pop(); - arrayResult.push(f64); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Double.lift(); return arrayResult; }, testBoolArrayDefault: function bjs_testBoolArrayDefault(flags = [true, false, true]) { - for (const elem of flags) { - i32Stack.push(elem ? 1 : 0); - } - i32Stack.push(flags.length); + __bjs_codec_Array_Bool.lower(flags); instance.exports.bjs_testBoolArrayDefault(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const bool = i32Stack.pop() !== 0; - arrayResult.push(bool); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Bool.lift(); return arrayResult; }, testEmptyArrayDefault: function bjs_testEmptyArrayDefault(items = []) { - for (const elem of items) { - i32Stack.push((elem | 0)); - } - i32Stack.push(items.length); + __bjs_codec_Array_Int.lower(items); instance.exports.bjs_testEmptyArrayDefault(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const int = i32Stack.pop(); - arrayResult.push(int); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Int.lift(); return arrayResult; }, testMixedWithArrayDefault: function bjs_testMixedWithArrayDefault(name = "test", values = [10, 20, 30], enabled = true) { const nameBytes = textEncoder.encode(name); const nameId = swift.memory.retain(nameBytes); - for (const elem of values) { - i32Stack.push((elem | 0)); - } - i32Stack.push(values.length); + __bjs_codec_Array_Int.lower(values); instance.exports.bjs_testMixedWithArrayDefault(nameId, nameBytes.length, enabled); const ret = tmpRetString; tmpRetString = undefined; @@ -678,7 +932,7 @@ export async function createInstantiator(options, swift) { MathOperations: { init: function(baseValue = 0.0) { instance.exports.bjs_MathOperations_init(baseValue); - const structValue = structHelpers.MathOperations.lift(); + const structValue = structHelpers.M10TestModuleT14MathOperations.lift(); return structValue; }, subtract: function(a, b = 5.0) { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DictionaryTypes.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DictionaryTypes.js index d0ac5307f..8ccda3c19 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DictionaryTypes.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DictionaryTypes.js @@ -31,44 +31,363 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createCountersHelpers = () => ({ + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + + function __bjs_jsValueLower(value) { + let kind; + let payload1; + let payload2; + if (value === null) { + kind = 4; + payload1 = 0; + payload2 = 0; + } else { + switch (typeof value) { + case "boolean": + kind = 0; + payload1 = value ? 1 : 0; + payload2 = 0; + break; + case "number": + kind = 2; + payload1 = 0; + payload2 = value; + break; + case "string": + kind = 1; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "undefined": + kind = 5; + payload1 = 0; + payload2 = 0; + break; + case "object": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "function": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "symbol": + kind = 7; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "bigint": + kind = 8; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + default: + throw new TypeError("Unsupported JSValue type"); + } + } + return [kind, payload1, payload2]; + } + function __bjs_jsValueLift(kind, payload1, payload2) { + let jsValue; + switch (kind) { + case 0: + jsValue = payload1 !== 0; + break; + case 1: + jsValue = swift.memory.getObject(payload1); + break; + case 2: + jsValue = payload2; + break; + case 3: + jsValue = swift.memory.getObject(payload1); + break; + case 4: + jsValue = null; + break; + case 5: + jsValue = undefined; + break; + case 7: + jsValue = swift.memory.getObject(payload1); + break; + case 8: + jsValue = swift.memory.getObject(payload1); + break; + default: + throw new TypeError("Unsupported JSValue kind " + kind); + } + return jsValue; + } + + const __bjs_codec_Dict_Int = __bjs_dictCodec(__bjs_primitiveCodecs.Int); + const __bjs_codec_Dict_String = __bjs_dictCodec(__bjs_stringCodec); + const __bjs_codec_Optional_Dict_String = __bjs_optionalCodec(__bjs_codec_Dict_String); + const __bjs_codec_Array_Int = __bjs_arrayCodec(__bjs_primitiveCodecs.Int); + const __bjs_codec_Dict_Array_Int = __bjs_dictCodec(__bjs_codec_Array_Int); + const __bjs_codec_M10TestModuleT3Box = { + lower: (v) => { + ptrStack.push(v.pointer); + }, + lift: () => { + const ptr = ptrStack.pop(); + const obj = _exports['Box'].__construct(ptr); + return obj; + }, + }; + const __bjs_codec_Dict_M10TestModuleT3Box = __bjs_dictCodec(__bjs_codec_M10TestModuleT3Box); + const __bjs_codec_Optional_M10TestModuleT3Box = __bjs_optionalCodec(__bjs_codec_M10TestModuleT3Box); + const __bjs_codec_Dict_Optional_M10TestModuleT3Box = __bjs_dictCodec(__bjs_codec_Optional_M10TestModuleT3Box); + const __bjs_codec_Dict_Double = __bjs_dictCodec(__bjs_primitiveCodecs.Double); + const __bjs_codec_Optional_Int = __bjs_optionalCodec(__bjs_primitiveCodecs.Int); + const __bjs_codec_Dict_Optional_Int = __bjs_dictCodec(__bjs_codec_Optional_Int); + + const __bjs_createStructHelpers_M10TestModuleT8Counters = () => ({ lower: (value) => { const bytes = textEncoder.encode(value.name); const id = swift.memory.retain(bytes); i32Stack.push(bytes.length); i32Stack.push(id); - const entries = Object.entries(value.counts); - for (const entry of entries) { - const [key, value] = entry; - const bytes1 = textEncoder.encode(key); - const id1 = swift.memory.retain(bytes1); - i32Stack.push(bytes1.length); - i32Stack.push(id1); - const isSome = value != null ? 1 : 0; - if (isSome) { - i32Stack.push((value | 0)); - } - i32Stack.push(isSome); - } - i32Stack.push(entries.length); + __bjs_codec_Dict_Optional_Int.lower(value.counts); }, lift: () => { - const dictLen = i32Stack.pop(); - const dictResult = {}; - for (let i = 0; i < dictLen; i++) { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const int = i32Stack.pop(); - optValue = int; - } - const string = strStack.pop(); - dictResult[string] = optValue; - } - const string1 = strStack.pop(); - return { name: string1, counts: dictResult }; + const dictResult = __bjs_codec_Dict_Optional_Int.lift(); + const string = strStack.pop(); + return { name: string, counts: dictResult }; } }); @@ -148,12 +467,14 @@ export async function createInstantiator(options, swift) { taStack.push(Array.from(new Ctor(copy))); } bjs["swift_js_struct_lower_Counters"] = function(objectId) { - structHelpers.Counters.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT8Counters.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Counters"] = function() { - const value = structHelpers.Counters.lift(); + const value = structHelpers.M10TestModuleT8Counters.lift(); return swift.memory.retain(value); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -262,24 +583,9 @@ export async function createInstantiator(options, swift) { const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_importMirrorDictionary"] = function bjs_importMirrorDictionary() { try { - const dictLen = i32Stack.pop(); - const dictResult = {}; - for (let i = 0; i < dictLen; i++) { - const f64 = f64Stack.pop(); - const string = strStack.pop(); - dictResult[string] = f64; - } + const dictResult = __bjs_codec_Dict_Double.lift(); let ret = imports.importMirrorDictionary(dictResult); - const entries = Object.entries(ret); - for (const entry of entries) { - const [key, value] = entry; - const bytes = textEncoder.encode(key); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - f64Stack.push(value); - } - i32Stack.push(entries.length); + __bjs_codec_Dict_Double.lower(ret); } catch (error) { setException(error); } @@ -356,160 +662,44 @@ export async function createInstantiator(options, swift) { } } - const CountersHelpers = __bjs_createCountersHelpers(); - structHelpers.Counters = CountersHelpers; + const __bjs_helpers_M10TestModuleT8Counters = __bjs_createStructHelpers_M10TestModuleT8Counters(); + structHelpers.M10TestModuleT8Counters = __bjs_helpers_M10TestModuleT8Counters; const exports = { mirrorDictionary: function bjs_mirrorDictionary(values) { - const entries = Object.entries(values); - for (const entry of entries) { - const [key, value] = entry; - const bytes = textEncoder.encode(key); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - i32Stack.push((value | 0)); - } - i32Stack.push(entries.length); + __bjs_codec_Dict_Int.lower(values); instance.exports.bjs_mirrorDictionary(); - const dictLen = i32Stack.pop(); - const dictResult = {}; - for (let i = 0; i < dictLen; i++) { - const int = i32Stack.pop(); - const string = strStack.pop(); - dictResult[string] = int; - } + const dictResult = __bjs_codec_Dict_Int.lift(); return dictResult; }, optionalDictionary: function bjs_optionalDictionary(values) { - const isSome = values != null; - if (isSome) { - const entries = Object.entries(values); - for (const entry of entries) { - const [key, value] = entry; - const bytes = textEncoder.encode(key); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - const bytes1 = textEncoder.encode(value); - const id1 = swift.memory.retain(bytes1); - i32Stack.push(bytes1.length); - i32Stack.push(id1); - } - i32Stack.push(entries.length); - } - i32Stack.push(+isSome); + __bjs_codec_Optional_Dict_String.lower(values); instance.exports.bjs_optionalDictionary(); - const isSome1 = i32Stack.pop(); - let optResult; - if (isSome1) { - const dictLen = i32Stack.pop(); - const dictResult = {}; - for (let i = 0; i < dictLen; i++) { - const string = strStack.pop(); - const string1 = strStack.pop(); - dictResult[string1] = string; - } - optResult = dictResult; - } else { - optResult = null; - } - return optResult; + const optValue = __bjs_codec_Optional_Dict_String.lift(); + return optValue; }, nestedDictionary: function bjs_nestedDictionary(values) { - const entries = Object.entries(values); - for (const entry of entries) { - const [key, value] = entry; - const bytes = textEncoder.encode(key); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - for (const elem of value) { - i32Stack.push((elem | 0)); - } - i32Stack.push(value.length); - } - i32Stack.push(entries.length); + __bjs_codec_Dict_Array_Int.lower(values); instance.exports.bjs_nestedDictionary(); - const dictLen = i32Stack.pop(); - const dictResult = {}; - for (let i = 0; i < dictLen; i++) { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i1 = 0; i1 < arrayLen; i1++) { - const int = i32Stack.pop(); - arrayResult.push(int); - } - arrayResult.reverse(); - } - const string = strStack.pop(); - dictResult[string] = arrayResult; - } + const dictResult = __bjs_codec_Dict_Array_Int.lift(); return dictResult; }, boxDictionary: function bjs_boxDictionary(boxes) { - const entries = Object.entries(boxes); - for (const entry of entries) { - const [key, value] = entry; - const bytes = textEncoder.encode(key); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - ptrStack.push(value.pointer); - } - i32Stack.push(entries.length); + __bjs_codec_Dict_M10TestModuleT3Box.lower(boxes); instance.exports.bjs_boxDictionary(); - const dictLen = i32Stack.pop(); - const dictResult = {}; - for (let i = 0; i < dictLen; i++) { - const ptr = ptrStack.pop(); - const obj = Box.__construct(ptr); - const string = strStack.pop(); - dictResult[string] = obj; - } + const dictResult = __bjs_codec_Dict_M10TestModuleT3Box.lift(); return dictResult; }, optionalBoxDictionary: function bjs_optionalBoxDictionary(boxes) { - const entries = Object.entries(boxes); - for (const entry of entries) { - const [key, value] = entry; - const bytes = textEncoder.encode(key); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - const isSome = value != null ? 1 : 0; - if (isSome) { - ptrStack.push(value.pointer); - } - i32Stack.push(isSome); - } - i32Stack.push(entries.length); + __bjs_codec_Dict_Optional_M10TestModuleT3Box.lower(boxes); instance.exports.bjs_optionalBoxDictionary(); - const dictLen = i32Stack.pop(); - const dictResult = {}; - for (let i = 0; i < dictLen; i++) { - const isSome1 = i32Stack.pop(); - let optValue; - if (isSome1 === 0) { - optValue = null; - } else { - const ptr = ptrStack.pop(); - const obj = Box.__construct(ptr); - optValue = obj; - } - const string = strStack.pop(); - dictResult[string] = optValue; - } + const dictResult = __bjs_codec_Dict_Optional_M10TestModuleT3Box.lift(); return dictResult; }, roundtripCounters: function bjs_roundtripCounters(counters) { - structHelpers.Counters.lower(counters); + structHelpers.M10TestModuleT8Counters.lower(counters); instance.exports.bjs_roundtripCounters(); - const structValue = structHelpers.Counters.lift(); + const structValue = structHelpers.M10TestModuleT8Counters.lift(); return structValue; }, Box, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DocComments.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DocComments.js index f29814675..6d23d394f 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DocComments.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DocComments.js @@ -37,7 +37,7 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createPointHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT5Point = () => ({ lower: (value) => { f64Stack.push(value.x); f64Stack.push(value.y); @@ -124,12 +124,14 @@ export async function createInstantiator(options, swift) { taStack.push(Array.from(new Ctor(copy))); } bjs["swift_js_struct_lower_Point"] = function(objectId) { - structHelpers.Point.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT5Point.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Point"] = function() { - const value = structHelpers.Point.lift(); + const value = structHelpers.M10TestModuleT5Point.lift(); return swift.memory.retain(value); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -347,8 +349,8 @@ export async function createInstantiator(options, swift) { instance.exports.bjs_Greeter_name_set(this.pointer, valueId, valueBytes.length); } } - const PointHelpers = __bjs_createPointHelpers(); - structHelpers.Point = PointHelpers; + const __bjs_helpers_M10TestModuleT5Point = __bjs_createStructHelpers_M10TestModuleT5Point(); + structHelpers.M10TestModuleT5Point = __bjs_helpers_M10TestModuleT5Point; const exports = { greet: function bjs_greet(name, greeting = "Hello") { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAlias.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAlias.js index 42f3fd958..d8bc06fcf 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAlias.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAlias.js @@ -106,6 +106,8 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.js index 36683fd58..66f85760c 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.js @@ -112,7 +112,401 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createPointHelpers = () => ({ + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + + function __bjs_jsValueLower(value) { + let kind; + let payload1; + let payload2; + if (value === null) { + kind = 4; + payload1 = 0; + payload2 = 0; + } else { + switch (typeof value) { + case "boolean": + kind = 0; + payload1 = value ? 1 : 0; + payload2 = 0; + break; + case "number": + kind = 2; + payload1 = 0; + payload2 = value; + break; + case "string": + kind = 1; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "undefined": + kind = 5; + payload1 = 0; + payload2 = 0; + break; + case "object": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "function": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "symbol": + kind = 7; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "bigint": + kind = 8; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + default: + throw new TypeError("Unsupported JSValue type"); + } + } + return [kind, payload1, payload2]; + } + function __bjs_jsValueLift(kind, payload1, payload2) { + let jsValue; + switch (kind) { + case 0: + jsValue = payload1 !== 0; + break; + case 1: + jsValue = swift.memory.getObject(payload1); + break; + case 2: + jsValue = payload2; + break; + case 3: + jsValue = swift.memory.getObject(payload1); + break; + case 4: + jsValue = null; + break; + case 5: + jsValue = undefined; + break; + case 7: + jsValue = swift.memory.getObject(payload1); + break; + case 8: + jsValue = swift.memory.getObject(payload1); + break; + default: + throw new TypeError("Unsupported JSValue kind " + kind); + } + return jsValue; + } + + const __bjs_codec_Optional_String = __bjs_optionalCodec(__bjs_stringCodec); + const __bjs_codec_Optional_Bool = __bjs_optionalCodec(__bjs_primitiveCodecs.Bool); + const __bjs_codec_Optional_Int = __bjs_optionalCodec(__bjs_primitiveCodecs.Int); + const __bjs_codec_M10TestModuleT9Precision = { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const rawValue = f32Stack.pop(); + return rawValue; + }, + }; + const __bjs_codec_Optional_M10TestModuleT9Precision = __bjs_optionalCodec(__bjs_codec_M10TestModuleT9Precision); + const __bjs_codec_M10TestModuleT17CardinalDirection = { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const caseId = i32Stack.pop(); + return caseId; + }, + }; + const __bjs_codec_Optional_M10TestModuleT17CardinalDirection = __bjs_optionalCodec(__bjs_codec_M10TestModuleT17CardinalDirection); + const __bjs_codec_Array_Int = __bjs_arrayCodec(__bjs_primitiveCodecs.Int); + const __bjs_codec_M10TestModuleT5Point = { + lower: (v) => { + structHelpers.M10TestModuleT5Point.lower(v); + }, + lift: () => { + const struct = structHelpers.M10TestModuleT5Point.lift(); + return struct; + }, + }; + const __bjs_codec_Optional_M10TestModuleT5Point = __bjs_optionalCodec(__bjs_codec_M10TestModuleT5Point); + const __bjs_codec_M10TestModuleT4User = { + lower: (v) => { + ptrStack.push(v.pointer); + }, + lift: () => { + const ptr = ptrStack.pop(); + const obj = _exports['User'].__construct(ptr); + return obj; + }, + }; + const __bjs_codec_Optional_M10TestModuleT4User = __bjs_optionalCodec(__bjs_codec_M10TestModuleT4User); + const __bjs_codec_JSObject = { + lower: (v) => { + const objId = swift.memory.retain(v); + i32Stack.push(objId); + }, + lift: () => { + const objId = i32Stack.pop(); + const obj = swift.memory.getObject(objId); + swift.memory.release(objId); + return obj; + }, + }; + const __bjs_codec_Optional_JSObject = __bjs_optionalCodec(__bjs_codec_JSObject); + const __bjs_codec_M10TestModuleT9APIResult = { + lower: (v) => { + const caseId = enumHelpers.M10TestModuleT9APIResult.lower(v); + i32Stack.push(caseId); + }, + lift: () => { + const enumValue = enumHelpers.M10TestModuleT9APIResult.lift(i32Stack.pop()); + return enumValue; + }, + }; + const __bjs_codec_Optional_M10TestModuleT9APIResult = __bjs_optionalCodec(__bjs_codec_M10TestModuleT9APIResult); + const __bjs_codec_Optional_Array_Int = __bjs_optionalCodec(__bjs_codec_Array_Int); + + const __bjs_createStructHelpers_M10TestModuleT5Point = () => ({ lower: (value) => { f64Stack.push(value.x); f64Stack.push(value.y); @@ -123,7 +517,7 @@ export async function createInstantiator(options, swift) { return { x: f641, y: f64 }; } }); - const __bjs_createAPIResultValuesHelpers = () => ({ + const __bjs_createEnumHelpers_M10TestModuleT9APIResult = () => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { @@ -184,7 +578,7 @@ export async function createInstantiator(options, swift) { } } }); - const __bjs_createComplexResultValuesHelpers = () => ({ + const __bjs_createEnumHelpers_M10TestModuleT13ComplexResult = () => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { @@ -286,7 +680,7 @@ export async function createInstantiator(options, swift) { } } }); - const __bjs_createResultValuesHelpers = () => ({ + const __bjs_createEnumHelpers_M10TestModuleT9UtilitiesT6Result = () => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { @@ -339,7 +733,7 @@ export async function createInstantiator(options, swift) { } } }); - const __bjs_createNetworkingResultValuesHelpers = () => ({ + const __bjs_createEnumHelpers_M10TestModuleT16NetworkingResult = () => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { @@ -377,53 +771,23 @@ export async function createInstantiator(options, swift) { } } }); - const __bjs_createAPIOptionalResultValuesHelpers = () => ({ + const __bjs_createEnumHelpers_M10TestModuleT17APIOptionalResult = () => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { case APIOptionalResultValues.Tag.Success: { - const isSome = value.param0 != null ? 1 : 0; - if (isSome) { - const bytes = textEncoder.encode(value.param0); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - } - i32Stack.push(isSome); + __bjs_codec_Optional_String.lower(value.param0); return APIOptionalResultValues.Tag.Success; } case APIOptionalResultValues.Tag.Failure: { - const isSome = value.param1 != null ? 1 : 0; - if (isSome) { - i32Stack.push(value.param1 ? 1 : 0); - } - i32Stack.push(isSome); - const isSome1 = value.param0 != null ? 1 : 0; - if (isSome1) { - i32Stack.push((value.param0 | 0)); - } - i32Stack.push(isSome1); + __bjs_codec_Optional_Bool.lower(value.param1); + __bjs_codec_Optional_Int.lower(value.param0); return APIOptionalResultValues.Tag.Failure; } case APIOptionalResultValues.Tag.Status: { - const isSome = value.param2 != null ? 1 : 0; - if (isSome) { - const bytes = textEncoder.encode(value.param2); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - } - i32Stack.push(isSome); - const isSome1 = value.param1 != null ? 1 : 0; - if (isSome1) { - i32Stack.push((value.param1 | 0)); - } - i32Stack.push(isSome1); - const isSome2 = value.param0 != null ? 1 : 0; - if (isSome2) { - i32Stack.push(value.param0 ? 1 : 0); - } - i32Stack.push(isSome2); + __bjs_codec_Optional_String.lower(value.param2); + __bjs_codec_Optional_Int.lower(value.param1); + __bjs_codec_Optional_Bool.lower(value.param0); return APIOptionalResultValues.Tag.Status; } default: throw new Error("Unknown APIOptionalResultValues tag: " + String(enumTag)); @@ -433,67 +797,25 @@ export async function createInstantiator(options, swift) { tag = tag | 0; switch (tag) { case APIOptionalResultValues.Tag.Success: { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const string = strStack.pop(); - optValue = string; - } + const optValue = __bjs_codec_Optional_String.lift(); return { tag: APIOptionalResultValues.Tag.Success, param0: optValue }; } case APIOptionalResultValues.Tag.Failure: { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const bool = i32Stack.pop() !== 0; - optValue = bool; - } - const isSome1 = i32Stack.pop(); - let optValue1; - if (isSome1 === 0) { - optValue1 = null; - } else { - const int = i32Stack.pop(); - optValue1 = int; - } + const optValue = __bjs_codec_Optional_Bool.lift(); + const optValue1 = __bjs_codec_Optional_Int.lift(); return { tag: APIOptionalResultValues.Tag.Failure, param0: optValue1, param1: optValue }; } case APIOptionalResultValues.Tag.Status: { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const string = strStack.pop(); - optValue = string; - } - const isSome1 = i32Stack.pop(); - let optValue1; - if (isSome1 === 0) { - optValue1 = null; - } else { - const int = i32Stack.pop(); - optValue1 = int; - } - const isSome2 = i32Stack.pop(); - let optValue2; - if (isSome2 === 0) { - optValue2 = null; - } else { - const bool = i32Stack.pop() !== 0; - optValue2 = bool; - } + const optValue = __bjs_codec_Optional_String.lift(); + const optValue1 = __bjs_codec_Optional_Int.lift(); + const optValue2 = __bjs_codec_Optional_Bool.lift(); return { tag: APIOptionalResultValues.Tag.Status, param0: optValue2, param1: optValue1, param2: optValue }; } default: throw new Error("Unknown APIOptionalResultValues tag returned from Swift: " + String(tag)); } } }); - const __bjs_createTypedPayloadResultValuesHelpers = () => ({ + const __bjs_createEnumHelpers_M10TestModuleT18TypedPayloadResult = () => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { @@ -506,19 +828,11 @@ export async function createInstantiator(options, swift) { return TypedPayloadResultValues.Tag.Direction; } case TypedPayloadResultValues.Tag.OptPrecision: { - const isSome = value.param0 != null ? 1 : 0; - if (isSome) { - f32Stack.push(Math.fround(value.param0)); - } - i32Stack.push(isSome); + __bjs_codec_Optional_M10TestModuleT9Precision.lower(value.param0); return TypedPayloadResultValues.Tag.OptPrecision; } case TypedPayloadResultValues.Tag.OptDirection: { - const isSome = value.param0 != null ? 1 : 0; - if (isSome) { - i32Stack.push((value.param0 | 0)); - } - i32Stack.push(isSome); + __bjs_codec_Optional_M10TestModuleT17CardinalDirection.lower(value.param0); return TypedPayloadResultValues.Tag.OptDirection; } case TypedPayloadResultValues.Tag.Empty: { @@ -539,25 +853,11 @@ export async function createInstantiator(options, swift) { return { tag: TypedPayloadResultValues.Tag.Direction, param0: caseId }; } case TypedPayloadResultValues.Tag.OptPrecision: { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const rawValue = f32Stack.pop(); - optValue = rawValue; - } + const optValue = __bjs_codec_Optional_M10TestModuleT9Precision.lift(); return { tag: TypedPayloadResultValues.Tag.OptPrecision, param0: optValue }; } case TypedPayloadResultValues.Tag.OptDirection: { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const caseId = i32Stack.pop(); - optValue = caseId; - } + const optValue = __bjs_codec_Optional_M10TestModuleT17CardinalDirection.lift(); return { tag: TypedPayloadResultValues.Tag.OptDirection, param0: optValue }; } case TypedPayloadResultValues.Tag.Empty: return { tag: TypedPayloadResultValues.Tag.Empty }; @@ -565,12 +865,12 @@ export async function createInstantiator(options, swift) { } } }); - const __bjs_createAllTypesResultValuesHelpers = () => ({ + const __bjs_createEnumHelpers_M10TestModuleT14AllTypesResult = () => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { case AllTypesResultValues.Tag.StructPayload: { - structHelpers.Point.lower(value.param0); + structHelpers.M10TestModuleT5Point.lower(value.param0); return AllTypesResultValues.Tag.StructPayload; } case AllTypesResultValues.Tag.ClassPayload: { @@ -583,15 +883,12 @@ export async function createInstantiator(options, swift) { return AllTypesResultValues.Tag.JsObjectPayload; } case AllTypesResultValues.Tag.NestedEnum: { - const caseId = enumHelpers.APIResult.lower(value.param0); + const caseId = enumHelpers.M10TestModuleT9APIResult.lower(value.param0); i32Stack.push(caseId); return AllTypesResultValues.Tag.NestedEnum; } case AllTypesResultValues.Tag.ArrayPayload: { - for (const elem of value.param0) { - i32Stack.push((elem | 0)); - } - i32Stack.push(value.param0.length); + __bjs_codec_Array_Int.lower(value.param0); return AllTypesResultValues.Tag.ArrayPayload; } case AllTypesResultValues.Tag.Empty: { @@ -604,7 +901,7 @@ export async function createInstantiator(options, swift) { tag = tag | 0; switch (tag) { case AllTypesResultValues.Tag.StructPayload: { - const struct = structHelpers.Point.lift(); + const struct = structHelpers.M10TestModuleT5Point.lift(); return { tag: AllTypesResultValues.Tag.StructPayload, param0: struct }; } case AllTypesResultValues.Tag.ClassPayload: { @@ -619,22 +916,11 @@ export async function createInstantiator(options, swift) { return { tag: AllTypesResultValues.Tag.JsObjectPayload, param0: obj }; } case AllTypesResultValues.Tag.NestedEnum: { - const enumValue = enumHelpers.APIResult.lift(i32Stack.pop()); + const enumValue = enumHelpers.M10TestModuleT9APIResult.lift(i32Stack.pop()); return { tag: AllTypesResultValues.Tag.NestedEnum, param0: enumValue }; } case AllTypesResultValues.Tag.ArrayPayload: { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const int = i32Stack.pop(); - arrayResult.push(int); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Int.lift(); return { tag: AllTypesResultValues.Tag.ArrayPayload, param0: arrayResult }; } case AllTypesResultValues.Tag.Empty: return { tag: AllTypesResultValues.Tag.Empty }; @@ -642,53 +928,28 @@ export async function createInstantiator(options, swift) { } } }); - const __bjs_createOptionalAllTypesResultValuesHelpers = () => ({ + const __bjs_createEnumHelpers_M10TestModuleT22OptionalAllTypesResult = () => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { case OptionalAllTypesResultValues.Tag.OptStruct: { - const isSome = value.param0 != null ? 1 : 0; - if (isSome) { - structHelpers.Point.lower(value.param0); - } - i32Stack.push(isSome); + __bjs_codec_Optional_M10TestModuleT5Point.lower(value.param0); return OptionalAllTypesResultValues.Tag.OptStruct; } case OptionalAllTypesResultValues.Tag.OptClass: { - const isSome = value.param0 != null ? 1 : 0; - if (isSome) { - ptrStack.push(value.param0.pointer); - } - i32Stack.push(isSome); + __bjs_codec_Optional_M10TestModuleT4User.lower(value.param0); return OptionalAllTypesResultValues.Tag.OptClass; } case OptionalAllTypesResultValues.Tag.OptJSObject: { - const isSome = value.param0 != null ? 1 : 0; - if (isSome) { - const objId = swift.memory.retain(value.param0); - i32Stack.push(objId); - } - i32Stack.push(isSome); + __bjs_codec_Optional_JSObject.lower(value.param0); return OptionalAllTypesResultValues.Tag.OptJSObject; } case OptionalAllTypesResultValues.Tag.OptNestedEnum: { - const isSome = value.param0 != null ? 1 : 0; - if (isSome) { - const caseId = enumHelpers.APIResult.lower(value.param0); - i32Stack.push(caseId); - } - i32Stack.push(isSome); + __bjs_codec_Optional_M10TestModuleT9APIResult.lower(value.param0); return OptionalAllTypesResultValues.Tag.OptNestedEnum; } case OptionalAllTypesResultValues.Tag.OptArray: { - const isSome = value.param0 != null ? 1 : 0; - if (isSome) { - for (const elem of value.param0) { - i32Stack.push((elem | 0)); - } - i32Stack.push(value.param0.length); - } - i32Stack.push(isSome); + __bjs_codec_Optional_Array_Int.lower(value.param0); return OptionalAllTypesResultValues.Tag.OptArray; } case OptionalAllTypesResultValues.Tag.Empty: { @@ -701,72 +962,23 @@ export async function createInstantiator(options, swift) { tag = tag | 0; switch (tag) { case OptionalAllTypesResultValues.Tag.OptStruct: { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const struct = structHelpers.Point.lift(); - optValue = struct; - } + const optValue = __bjs_codec_Optional_M10TestModuleT5Point.lift(); return { tag: OptionalAllTypesResultValues.Tag.OptStruct, param0: optValue }; } case OptionalAllTypesResultValues.Tag.OptClass: { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const ptr = ptrStack.pop(); - const obj = _exports['User'].__construct(ptr); - optValue = obj; - } + const optValue = __bjs_codec_Optional_M10TestModuleT4User.lift(); return { tag: OptionalAllTypesResultValues.Tag.OptClass, param0: optValue }; } case OptionalAllTypesResultValues.Tag.OptJSObject: { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const objId = i32Stack.pop(); - const obj = swift.memory.getObject(objId); - swift.memory.release(objId); - optValue = obj; - } + const optValue = __bjs_codec_Optional_JSObject.lift(); return { tag: OptionalAllTypesResultValues.Tag.OptJSObject, param0: optValue }; } case OptionalAllTypesResultValues.Tag.OptNestedEnum: { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const enumValue = enumHelpers.APIResult.lift(i32Stack.pop()); - optValue = enumValue; - } + const optValue = __bjs_codec_Optional_M10TestModuleT9APIResult.lift(); return { tag: OptionalAllTypesResultValues.Tag.OptNestedEnum, param0: optValue }; } case OptionalAllTypesResultValues.Tag.OptArray: { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const int = i32Stack.pop(); - arrayResult.push(int); - } - arrayResult.reverse(); - } - optValue = arrayResult; - } + const optValue = __bjs_codec_Optional_Array_Int.lift(); return { tag: OptionalAllTypesResultValues.Tag.OptArray, param0: optValue }; } case OptionalAllTypesResultValues.Tag.Empty: return { tag: OptionalAllTypesResultValues.Tag.Empty }; @@ -850,12 +1062,14 @@ export async function createInstantiator(options, swift) { taStack.push(Array.from(new Ctor(copy))); } bjs["swift_js_struct_lower_Point"] = function(objectId) { - structHelpers.Point.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT5Point.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Point"] = function() { - const value = structHelpers.Point.lift(); + const value = structHelpers.M10TestModuleT5Point.lift(); return swift.memory.retain(value); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -1033,139 +1247,139 @@ export async function createInstantiator(options, swift) { } } - const PointHelpers = __bjs_createPointHelpers(); - structHelpers.Point = PointHelpers; + const __bjs_helpers_M10TestModuleT5Point = __bjs_createStructHelpers_M10TestModuleT5Point(); + structHelpers.M10TestModuleT5Point = __bjs_helpers_M10TestModuleT5Point; - const APIResultHelpers = __bjs_createAPIResultValuesHelpers(); - enumHelpers.APIResult = APIResultHelpers; + const __bjs_helpers_M10TestModuleT9APIResult = __bjs_createEnumHelpers_M10TestModuleT9APIResult(); + enumHelpers.M10TestModuleT9APIResult = __bjs_helpers_M10TestModuleT9APIResult; - const ComplexResultHelpers = __bjs_createComplexResultValuesHelpers(); - enumHelpers.ComplexResult = ComplexResultHelpers; + const __bjs_helpers_M10TestModuleT13ComplexResult = __bjs_createEnumHelpers_M10TestModuleT13ComplexResult(); + enumHelpers.M10TestModuleT13ComplexResult = __bjs_helpers_M10TestModuleT13ComplexResult; - const ResultHelpers = __bjs_createResultValuesHelpers(); - enumHelpers.Result = ResultHelpers; + const __bjs_helpers_M10TestModuleT9UtilitiesT6Result = __bjs_createEnumHelpers_M10TestModuleT9UtilitiesT6Result(); + enumHelpers.M10TestModuleT9UtilitiesT6Result = __bjs_helpers_M10TestModuleT9UtilitiesT6Result; - const NetworkingResultHelpers = __bjs_createNetworkingResultValuesHelpers(); - enumHelpers.NetworkingResult = NetworkingResultHelpers; + const __bjs_helpers_M10TestModuleT16NetworkingResult = __bjs_createEnumHelpers_M10TestModuleT16NetworkingResult(); + enumHelpers.M10TestModuleT16NetworkingResult = __bjs_helpers_M10TestModuleT16NetworkingResult; - const APIOptionalResultHelpers = __bjs_createAPIOptionalResultValuesHelpers(); - enumHelpers.APIOptionalResult = APIOptionalResultHelpers; + const __bjs_helpers_M10TestModuleT17APIOptionalResult = __bjs_createEnumHelpers_M10TestModuleT17APIOptionalResult(); + enumHelpers.M10TestModuleT17APIOptionalResult = __bjs_helpers_M10TestModuleT17APIOptionalResult; - const TypedPayloadResultHelpers = __bjs_createTypedPayloadResultValuesHelpers(); - enumHelpers.TypedPayloadResult = TypedPayloadResultHelpers; + const __bjs_helpers_M10TestModuleT18TypedPayloadResult = __bjs_createEnumHelpers_M10TestModuleT18TypedPayloadResult(); + enumHelpers.M10TestModuleT18TypedPayloadResult = __bjs_helpers_M10TestModuleT18TypedPayloadResult; - const AllTypesResultHelpers = __bjs_createAllTypesResultValuesHelpers(); - enumHelpers.AllTypesResult = AllTypesResultHelpers; + const __bjs_helpers_M10TestModuleT14AllTypesResult = __bjs_createEnumHelpers_M10TestModuleT14AllTypesResult(); + enumHelpers.M10TestModuleT14AllTypesResult = __bjs_helpers_M10TestModuleT14AllTypesResult; - const OptionalAllTypesResultHelpers = __bjs_createOptionalAllTypesResultValuesHelpers(); - enumHelpers.OptionalAllTypesResult = OptionalAllTypesResultHelpers; + const __bjs_helpers_M10TestModuleT22OptionalAllTypesResult = __bjs_createEnumHelpers_M10TestModuleT22OptionalAllTypesResult(); + enumHelpers.M10TestModuleT22OptionalAllTypesResult = __bjs_helpers_M10TestModuleT22OptionalAllTypesResult; const exports = { handle: function bjs_handle(result) { - const resultCaseId = enumHelpers.APIResult.lower(result); + const resultCaseId = enumHelpers.M10TestModuleT9APIResult.lower(result); instance.exports.bjs_handle(resultCaseId); }, getResult: function bjs_getResult() { instance.exports.bjs_getResult(); - const ret = enumHelpers.APIResult.lift(i32Stack.pop()); + const ret = enumHelpers.M10TestModuleT9APIResult.lift(i32Stack.pop()); return ret; }, roundtripAPIResult: function bjs_roundtripAPIResult(result) { - const resultCaseId = enumHelpers.APIResult.lower(result); + const resultCaseId = enumHelpers.M10TestModuleT9APIResult.lower(result); instance.exports.bjs_roundtripAPIResult(resultCaseId); - const ret = enumHelpers.APIResult.lift(i32Stack.pop()); + const ret = enumHelpers.M10TestModuleT9APIResult.lift(i32Stack.pop()); return ret; }, roundTripOptionalAPIResult: function bjs_roundTripOptionalAPIResult(result) { const isSome = result != null; let result1; if (isSome) { - const resultCaseId = enumHelpers.APIResult.lower(result); + const resultCaseId = enumHelpers.M10TestModuleT9APIResult.lower(result); result1 = resultCaseId; } else { result1 = 0; } instance.exports.bjs_roundTripOptionalAPIResult(+isSome, result1); const tag = i32Stack.pop(); - const optResult = tag === -1 ? null : enumHelpers.APIResult.lift(tag); + const optResult = tag === -1 ? null : enumHelpers.M10TestModuleT9APIResult.lift(tag); return optResult; }, handleComplex: function bjs_handleComplex(result) { - const resultCaseId = enumHelpers.ComplexResult.lower(result); + const resultCaseId = enumHelpers.M10TestModuleT13ComplexResult.lower(result); instance.exports.bjs_handleComplex(resultCaseId); }, getComplexResult: function bjs_getComplexResult() { instance.exports.bjs_getComplexResult(); - const ret = enumHelpers.ComplexResult.lift(i32Stack.pop()); + const ret = enumHelpers.M10TestModuleT13ComplexResult.lift(i32Stack.pop()); return ret; }, roundtripComplexResult: function bjs_roundtripComplexResult(result) { - const resultCaseId = enumHelpers.ComplexResult.lower(result); + const resultCaseId = enumHelpers.M10TestModuleT13ComplexResult.lower(result); instance.exports.bjs_roundtripComplexResult(resultCaseId); - const ret = enumHelpers.ComplexResult.lift(i32Stack.pop()); + const ret = enumHelpers.M10TestModuleT13ComplexResult.lift(i32Stack.pop()); return ret; }, roundTripOptionalComplexResult: function bjs_roundTripOptionalComplexResult(result) { const isSome = result != null; let result1; if (isSome) { - const resultCaseId = enumHelpers.ComplexResult.lower(result); + const resultCaseId = enumHelpers.M10TestModuleT13ComplexResult.lower(result); result1 = resultCaseId; } else { result1 = 0; } instance.exports.bjs_roundTripOptionalComplexResult(+isSome, result1); const tag = i32Stack.pop(); - const optResult = tag === -1 ? null : enumHelpers.ComplexResult.lift(tag); + const optResult = tag === -1 ? null : enumHelpers.M10TestModuleT13ComplexResult.lift(tag); return optResult; }, roundTripOptionalUtilitiesResult: function bjs_roundTripOptionalUtilitiesResult(result) { const isSome = result != null; let result1; if (isSome) { - const resultCaseId = enumHelpers.Result.lower(result); + const resultCaseId = enumHelpers.M10TestModuleT9UtilitiesT6Result.lower(result); result1 = resultCaseId; } else { result1 = 0; } instance.exports.bjs_roundTripOptionalUtilitiesResult(+isSome, result1); const tag = i32Stack.pop(); - const optResult = tag === -1 ? null : enumHelpers.Result.lift(tag); + const optResult = tag === -1 ? null : enumHelpers.M10TestModuleT9UtilitiesT6Result.lift(tag); return optResult; }, roundTripOptionalNetworkingResult: function bjs_roundTripOptionalNetworkingResult(result) { const isSome = result != null; let result1; if (isSome) { - const resultCaseId = enumHelpers.NetworkingResult.lower(result); + const resultCaseId = enumHelpers.M10TestModuleT16NetworkingResult.lower(result); result1 = resultCaseId; } else { result1 = 0; } instance.exports.bjs_roundTripOptionalNetworkingResult(+isSome, result1); const tag = i32Stack.pop(); - const optResult = tag === -1 ? null : enumHelpers.NetworkingResult.lift(tag); + const optResult = tag === -1 ? null : enumHelpers.M10TestModuleT16NetworkingResult.lift(tag); return optResult; }, roundTripOptionalAPIOptionalResult: function bjs_roundTripOptionalAPIOptionalResult(result) { const isSome = result != null; let result1; if (isSome) { - const resultCaseId = enumHelpers.APIOptionalResult.lower(result); + const resultCaseId = enumHelpers.M10TestModuleT17APIOptionalResult.lower(result); result1 = resultCaseId; } else { result1 = 0; } instance.exports.bjs_roundTripOptionalAPIOptionalResult(+isSome, result1); const tag = i32Stack.pop(); - const optResult = tag === -1 ? null : enumHelpers.APIOptionalResult.lift(tag); + const optResult = tag === -1 ? null : enumHelpers.M10TestModuleT17APIOptionalResult.lift(tag); return optResult; }, compareAPIResults: function bjs_compareAPIResults(result1, result2) { const isSome = result1 != null; let result; if (isSome) { - const result1CaseId = enumHelpers.APIOptionalResult.lower(result1); + const result1CaseId = enumHelpers.M10TestModuleT17APIOptionalResult.lower(result1); result = result1CaseId; } else { result = 0; @@ -1173,74 +1387,74 @@ export async function createInstantiator(options, swift) { const isSome1 = result2 != null; let result3; if (isSome1) { - const result2CaseId = enumHelpers.APIOptionalResult.lower(result2); + const result2CaseId = enumHelpers.M10TestModuleT17APIOptionalResult.lower(result2); result3 = result2CaseId; } else { result3 = 0; } instance.exports.bjs_compareAPIResults(+isSome, result, +isSome1, result3); const tag = i32Stack.pop(); - const optResult = tag === -1 ? null : enumHelpers.APIOptionalResult.lift(tag); + const optResult = tag === -1 ? null : enumHelpers.M10TestModuleT17APIOptionalResult.lift(tag); return optResult; }, roundTripTypedPayloadResult: function bjs_roundTripTypedPayloadResult(result) { - const resultCaseId = enumHelpers.TypedPayloadResult.lower(result); + const resultCaseId = enumHelpers.M10TestModuleT18TypedPayloadResult.lower(result); instance.exports.bjs_roundTripTypedPayloadResult(resultCaseId); - const ret = enumHelpers.TypedPayloadResult.lift(i32Stack.pop()); + const ret = enumHelpers.M10TestModuleT18TypedPayloadResult.lift(i32Stack.pop()); return ret; }, roundTripOptionalTypedPayloadResult: function bjs_roundTripOptionalTypedPayloadResult(result) { const isSome = result != null; let result1; if (isSome) { - const resultCaseId = enumHelpers.TypedPayloadResult.lower(result); + const resultCaseId = enumHelpers.M10TestModuleT18TypedPayloadResult.lower(result); result1 = resultCaseId; } else { result1 = 0; } instance.exports.bjs_roundTripOptionalTypedPayloadResult(+isSome, result1); const tag = i32Stack.pop(); - const optResult = tag === -1 ? null : enumHelpers.TypedPayloadResult.lift(tag); + const optResult = tag === -1 ? null : enumHelpers.M10TestModuleT18TypedPayloadResult.lift(tag); return optResult; }, roundTripAllTypesResult: function bjs_roundTripAllTypesResult(result) { - const resultCaseId = enumHelpers.AllTypesResult.lower(result); + const resultCaseId = enumHelpers.M10TestModuleT14AllTypesResult.lower(result); instance.exports.bjs_roundTripAllTypesResult(resultCaseId); - const ret = enumHelpers.AllTypesResult.lift(i32Stack.pop()); + const ret = enumHelpers.M10TestModuleT14AllTypesResult.lift(i32Stack.pop()); return ret; }, roundTripOptionalAllTypesResult: function bjs_roundTripOptionalAllTypesResult(result) { const isSome = result != null; let result1; if (isSome) { - const resultCaseId = enumHelpers.AllTypesResult.lower(result); + const resultCaseId = enumHelpers.M10TestModuleT14AllTypesResult.lower(result); result1 = resultCaseId; } else { result1 = 0; } instance.exports.bjs_roundTripOptionalAllTypesResult(+isSome, result1); const tag = i32Stack.pop(); - const optResult = tag === -1 ? null : enumHelpers.AllTypesResult.lift(tag); + const optResult = tag === -1 ? null : enumHelpers.M10TestModuleT14AllTypesResult.lift(tag); return optResult; }, roundTripOptionalPayloadResult: function bjs_roundTripOptionalPayloadResult(result) { - const resultCaseId = enumHelpers.OptionalAllTypesResult.lower(result); + const resultCaseId = enumHelpers.M10TestModuleT22OptionalAllTypesResult.lower(result); instance.exports.bjs_roundTripOptionalPayloadResult(resultCaseId); - const ret = enumHelpers.OptionalAllTypesResult.lift(i32Stack.pop()); + const ret = enumHelpers.M10TestModuleT22OptionalAllTypesResult.lift(i32Stack.pop()); return ret; }, roundTripOptionalPayloadResultOpt: function bjs_roundTripOptionalPayloadResultOpt(result) { const isSome = result != null; let result1; if (isSome) { - const resultCaseId = enumHelpers.OptionalAllTypesResult.lower(result); + const resultCaseId = enumHelpers.M10TestModuleT22OptionalAllTypesResult.lower(result); result1 = resultCaseId; } else { result1 = 0; } instance.exports.bjs_roundTripOptionalPayloadResultOpt(+isSome, result1); const tag = i32Stack.pop(); - const optResult = tag === -1 ? null : enumHelpers.OptionalAllTypesResult.lift(tag); + const optResult = tag === -1 ? null : enumHelpers.M10TestModuleT22OptionalAllTypesResult.lift(tag); return optResult; }, APIResult: APIResultValues, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValueImport.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValueImport.js index de374bd70..07fe91654 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValueImport.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValueImport.js @@ -38,7 +38,7 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createPayloadSignalValuesHelpers = () => ({ + const __bjs_createEnumHelpers_M10TestModuleT13PayloadSignal = () => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { @@ -150,6 +150,8 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -250,9 +252,9 @@ export async function createInstantiator(options, swift) { const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_PayloadSignalControls_roundTrip_static"] = function bjs_PayloadSignalControls_roundTrip_static(signal) { try { - const enumValue = enumHelpers.PayloadSignal.lift(signal); + const enumValue = enumHelpers.M10TestModuleT13PayloadSignal.lift(signal); let ret = imports.PayloadSignalControls.roundTrip(enumValue); - const caseId = enumHelpers.PayloadSignal.lower(ret); + const caseId = enumHelpers.M10TestModuleT13PayloadSignal.lower(ret); return caseId; } catch (error) { setException(error); @@ -260,7 +262,7 @@ export async function createInstantiator(options, swift) { } TestModule["bjs_PayloadSignalControls_send"] = function bjs_PayloadSignalControls_send(self, signal) { try { - const enumValue = enumHelpers.PayloadSignal.lift(signal); + const enumValue = enumHelpers.M10TestModuleT13PayloadSignal.lift(signal); swift.memory.getObject(self).send(enumValue); } catch (error) { setException(error); @@ -269,7 +271,7 @@ export async function createInstantiator(options, swift) { TestModule["bjs_PayloadSignalControls_current"] = function bjs_PayloadSignalControls_current(self) { try { let ret = swift.memory.getObject(self).current(); - const caseId = enumHelpers.PayloadSignal.lower(ret); + const caseId = enumHelpers.M10TestModuleT13PayloadSignal.lower(ret); return caseId; } catch (error) { setException(error); @@ -279,7 +281,7 @@ export async function createInstantiator(options, swift) { try { let optResult; if (signalIsSome) { - const enumValue = enumHelpers.PayloadSignal.lift(signalCaseId); + const enumValue = enumHelpers.M10TestModuleT13PayloadSignal.lift(signalCaseId); optResult = enumValue; } else { optResult = null; @@ -287,7 +289,7 @@ export async function createInstantiator(options, swift) { let ret = swift.memory.getObject(self).roundTripOptional(optResult); const isSome = ret != null; if (isSome) { - const caseId = enumHelpers.PayloadSignal.lower(ret); + const caseId = enumHelpers.M10TestModuleT13PayloadSignal.lower(ret); return caseId; } else { return -1; @@ -310,8 +312,8 @@ export async function createInstantiator(options, swift) { /** @param {WebAssembly.Instance} instance */ createExports: (instance) => { const js = swift.memory.heap; - const PayloadSignalHelpers = __bjs_createPayloadSignalValuesHelpers(); - enumHelpers.PayloadSignal = PayloadSignalHelpers; + const __bjs_helpers_M10TestModuleT13PayloadSignal = __bjs_createEnumHelpers_M10TestModuleT13PayloadSignal(); + enumHelpers.M10TestModuleT13PayloadSignal = __bjs_helpers_M10TestModuleT13PayloadSignal; const exports = { PayloadSignal: PayloadSignalValues, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.js index c2ae031bb..838e3062b 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.js @@ -130,6 +130,8 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCaseImport.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCaseImport.js index f2d6b8750..b4e67b6b8 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCaseImport.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCaseImport.js @@ -111,6 +111,8 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Global.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Global.js index 6c45f0333..0a691374b 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Global.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Global.js @@ -150,6 +150,8 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.js index 2a9e7948a..03f0a8d9a 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.js @@ -131,6 +131,8 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.js index 9e18a8d80..09e03e44a 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.js @@ -106,6 +106,350 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + + function __bjs_jsValueLower(value) { + let kind; + let payload1; + let payload2; + if (value === null) { + kind = 4; + payload1 = 0; + payload2 = 0; + } else { + switch (typeof value) { + case "boolean": + kind = 0; + payload1 = value ? 1 : 0; + payload2 = 0; + break; + case "number": + kind = 2; + payload1 = 0; + payload2 = value; + break; + case "string": + kind = 1; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "undefined": + kind = 5; + payload1 = 0; + payload2 = 0; + break; + case "object": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "function": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "symbol": + kind = 7; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "bigint": + kind = 8; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + default: + throw new TypeError("Unsupported JSValue type"); + } + } + return [kind, payload1, payload2]; + } + function __bjs_jsValueLift(kind, payload1, payload2) { + let jsValue; + switch (kind) { + case 0: + jsValue = payload1 !== 0; + break; + case 1: + jsValue = swift.memory.getObject(payload1); + break; + case 2: + jsValue = payload2; + break; + case 3: + jsValue = swift.memory.getObject(payload1); + break; + case 4: + jsValue = null; + break; + case 5: + jsValue = undefined; + break; + case 7: + jsValue = swift.memory.getObject(payload1); + break; + case 8: + jsValue = swift.memory.getObject(payload1); + break; + default: + throw new TypeError("Unsupported JSValue kind " + kind); + } + return jsValue; + } + + const __bjs_codec_M10TestModuleT8FileSize = { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const rawValue = i64Stack.pop(); + return rawValue; + }, + }; + const __bjs_codec_Optional_M10TestModuleT8FileSize = __bjs_optionalCodec(__bjs_codec_M10TestModuleT8FileSize); + const __bjs_codec_M10TestModuleT9SessionId = { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const rawValue = i64Stack.pop(); + return rawValue; + }, + }; + const __bjs_codec_Optional_M10TestModuleT9SessionId = __bjs_optionalCodec(__bjs_codec_M10TestModuleT9SessionId); + return { /** @@ -182,6 +526,8 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -448,15 +794,8 @@ export async function createInstantiator(options, swift) { roundTripOptionalFileSize: function bjs_roundTripOptionalFileSize(input) { const isSome = input != null; instance.exports.bjs_roundTripOptionalFileSize(+isSome, isSome ? input : 0n); - const isSome1 = i32Stack.pop(); - let optResult; - if (isSome1) { - const rawValue = i64Stack.pop(); - optResult = rawValue; - } else { - optResult = null; - } - return optResult; + const optValue = __bjs_codec_Optional_M10TestModuleT8FileSize.lift(); + return optValue; }, setUserId: function bjs_setUserId(id) { instance.exports.bjs_setUserId(id); @@ -496,15 +835,8 @@ export async function createInstantiator(options, swift) { roundTripOptionalSessionId: function bjs_roundTripOptionalSessionId(input) { const isSome = input != null; instance.exports.bjs_roundTripOptionalSessionId(+isSome, isSome ? input : 0n); - const isSome1 = i32Stack.pop(); - let optResult; - if (isSome1) { - const rawValue = i64Stack.pop(); - optResult = rawValue; - } else { - optResult = null; - } - return optResult; + const optValue = __bjs_codec_Optional_M10TestModuleT9SessionId.lift(); + return optValue; }, setPrecision: function bjs_setPrecision(precision) { instance.exports.bjs_setPrecision(precision); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/FixedWidthIntegers.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/FixedWidthIntegers.js index a009f8d71..56a31b784 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/FixedWidthIntegers.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/FixedWidthIntegers.js @@ -107,6 +107,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GenericImports.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GenericImports.d.ts new file mode 100644 index 000000000..026713ce3 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GenericImports.d.ts @@ -0,0 +1,87 @@ +// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit, +// DO NOT EDIT. +// +// To update this file, just rebuild your project or run +// `swift package bridge-js`. + +export const GenericColorValues: { + readonly Red: 0; + readonly Green: 1; +}; +export type GenericColorTag = typeof GenericColorValues[keyof typeof GenericColorValues]; + +export const GenericModeValues: { + readonly Light: "light"; + readonly Dark: "dark"; +}; +export type GenericModeTag = typeof GenericModeValues[keyof typeof GenericModeValues]; + +export const GenericTaggedValues: { + readonly Tag: { + readonly Number: 0; + readonly Text: 1; + }; +}; + +export type GenericTaggedTag = + { tag: typeof GenericTaggedValues.Tag.Number; value: number } | { tag: typeof GenericTaggedValues.Tag.Text; value: string } + +export interface GenericPoint { + x: number; + y: number; +} +export type GenericColorObject = typeof GenericColorValues; + +export type GenericModeObject = typeof GenericModeValues; + +export type GenericTaggedObject = typeof GenericTaggedValues; + +/// 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 GenericImportBox extends SwiftHeapObject { + get(): number; + value: number; +} +export interface GenericPairFactory { +} +export interface GenericConsumer { + accept(value: T): void; + identity(value: T): T; +} +export type Exports = { + GenericColor: GenericColorObject + GenericMode: GenericModeObject + GenericTagged: GenericTaggedObject + GenericImportBox: { + new(value: number): GenericImportBox; + }, +} +export type Imports = { + genericRoundTrip(value: T): T; + genericParse(json: string): T; + importGenericCombine(a: T, b: U): U; + importGenericCaseDistinct(a: T, b: t): T; + importGenericArray(values: T[]): T[]; + importGenericOptional(value: T | null): T | null; + importGenericDictionary(values: Record): Record; + importGenericAfterOptionalArray(values: number[] | null, value: T): T; + GenericPairFactory: { + new(tag: string, first: T, second: U): GenericPairFactory; + } + GenericConsumer: { + new(value: T): GenericConsumer; + box(value: T): T; + } +} +export function createInstantiator(options: { + imports: Imports; +}, swift: any): Promise<{ + addImports: (importObject: WebAssembly.Imports) => void; + setInstance: (instance: WebAssembly.Instance) => void; + createExports: (instance: WebAssembly.Instance) => Exports; +}>; \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GenericImports.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GenericImports.js new file mode 100644 index 000000000..d8b1fdf15 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GenericImports.js @@ -0,0 +1,941 @@ +// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit, +// DO NOT EDIT. +// +// To update this file, just rebuild your project or run +// `swift package bridge-js`. + +export const GenericColorValues = { + Red: 0, + Green: 1, +}; + +export const GenericModeValues = { + Light: "light", + Dark: "dark", +}; + +export const GenericTaggedValues = { + Tag: { + Number: 0, + Text: 1, + }, +}; +export async function createInstantiator(options, swift) { + let instance; + let memory; + let setException; + let decodeString; + const textDecoder = new TextDecoder("utf-8"); + const textEncoder = new TextEncoder("utf-8"); + let tmpRetString; + let tmpRetBytes; + let tmpRetException; + let tmpRetOptionalBool; + let tmpRetOptionalInt; + let tmpRetOptionalFloat; + let tmpRetOptionalDouble; + let tmpRetOptionalHeapObject; + let strStack = []; + let i32Stack = []; + let i64Stack = []; + let f32Stack = []; + let f64Stack = []; + let ptrStack = []; + let taStack = []; + const enumHelpers = {}; + const structHelpers = {}; + const __bjs_codecByTypeId = new Map(); + let __bjs_typeHandlesRegistered = false; + function __bjs_registerTypeHandles() { + if (__bjs_typeHandlesRegistered) { + return; + } + __bjs_typeHandlesRegistered = true; + instance.exports["bjs_core_register_type_handles"](); + instance.exports["bjs_TestModule_register_type_handles"](); + } + function __bjs_codecForTypeId(typeId) { + __bjs_registerTypeHandles(); + const codec = __bjs_codecByTypeId.get(typeId); + if (!codec) { + throw new Error("BridgeJS: no codec registered for type ID " + typeId); + } + return codec; + } + + let _exports = null; + let bjs = null; + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + + function __bjs_jsValueLower(value) { + let kind; + let payload1; + let payload2; + if (value === null) { + kind = 4; + payload1 = 0; + payload2 = 0; + } else { + switch (typeof value) { + case "boolean": + kind = 0; + payload1 = value ? 1 : 0; + payload2 = 0; + break; + case "number": + kind = 2; + payload1 = 0; + payload2 = value; + break; + case "string": + kind = 1; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "undefined": + kind = 5; + payload1 = 0; + payload2 = 0; + break; + case "object": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "function": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "symbol": + kind = 7; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "bigint": + kind = 8; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + default: + throw new TypeError("Unsupported JSValue type"); + } + } + return [kind, payload1, payload2]; + } + function __bjs_jsValueLift(kind, payload1, payload2) { + let jsValue; + switch (kind) { + case 0: + jsValue = payload1 !== 0; + break; + case 1: + jsValue = swift.memory.getObject(payload1); + break; + case 2: + jsValue = payload2; + break; + case 3: + jsValue = swift.memory.getObject(payload1); + break; + case 4: + jsValue = null; + break; + case 5: + jsValue = undefined; + break; + case 7: + jsValue = swift.memory.getObject(payload1); + break; + case 8: + jsValue = swift.memory.getObject(payload1); + break; + default: + throw new TypeError("Unsupported JSValue kind " + kind); + } + return jsValue; + } + + const __bjs_codec_Array_Int = __bjs_arrayCodec(__bjs_primitiveCodecs.Int); + const __bjs_codec_Optional_Array_Int = __bjs_optionalCodec(__bjs_codec_Array_Int); + const __bjs_codec_M10TestModuleT12GenericPoint = { + lower: (v) => { + structHelpers.M10TestModuleT12GenericPoint.lower(v); + }, + lift: () => { + const struct = structHelpers.M10TestModuleT12GenericPoint.lift(); + return struct; + }, + }; + const __bjs_codec_M10TestModuleT16GenericImportBox = { + lower: (v) => { + ptrStack.push(v.pointer); + }, + lift: () => { + const ptr = ptrStack.pop(); + const obj = _exports['GenericImportBox'].__construct(ptr); + return obj; + }, + }; + const __bjs_codec_M10TestModuleT12GenericColor = { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const caseId = i32Stack.pop(); + return caseId; + }, + }; + const __bjs_codec_M10TestModuleT13GenericTagged = { + lower: (v) => { + const caseId = enumHelpers.M10TestModuleT13GenericTagged.lower(v); + i32Stack.push(caseId); + }, + lift: () => { + const enumValue = enumHelpers.M10TestModuleT13GenericTagged.lift(i32Stack.pop()); + return enumValue; + }, + }; + + const __bjs_createStructHelpers_M10TestModuleT12GenericPoint = () => ({ + lower: (value) => { + i32Stack.push((value.x | 0)); + i32Stack.push((value.y | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + const int1 = i32Stack.pop(); + return { x: int1, y: int }; + } + }); + const __bjs_createEnumHelpers_M10TestModuleT13GenericTagged = () => ({ + lower: (value) => { + const enumTag = value.tag; + switch (enumTag) { + case GenericTaggedValues.Tag.Number: { + i32Stack.push((value.value | 0)); + return GenericTaggedValues.Tag.Number; + } + case GenericTaggedValues.Tag.Text: { + const bytes = textEncoder.encode(value.value); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + return GenericTaggedValues.Tag.Text; + } + default: throw new Error("Unknown GenericTaggedValues tag: " + String(enumTag)); + } + }, + lift: (tag) => { + tag = tag | 0; + switch (tag) { + case GenericTaggedValues.Tag.Number: { + const int = i32Stack.pop(); + return { tag: GenericTaggedValues.Tag.Number, value: int }; + } + case GenericTaggedValues.Tag.Text: { + const string = strStack.pop(); + return { tag: GenericTaggedValues.Tag.Text, value: string }; + } + default: throw new Error("Unknown GenericTaggedValues tag returned from Swift: " + String(tag)); + } + } + }); + + return { + /** + * @param {WebAssembly.Imports} importObject + */ + addImports: (importObject, importsContext) => { + bjs = {}; + importObject["bjs"] = bjs; + const imports = options.getImports(importsContext); + bjs["swift_js_return_string"] = function(ptr, len) { + tmpRetString = decodeString(ptr, len); + } + bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const bytes = new Uint8Array(memory.buffer, bytesPtr >>> 0); + bytes.set(source); + } + bjs["swift_js_make_js_string"] = function(ptr, len) { + return swift.memory.retain(decodeString(ptr, len)); + } + bjs["swift_js_init_memory_with_result"] = function(ptr, len) { + const target = new Uint8Array(memory.buffer, ptr >>> 0, len >>> 0); + target.set(tmpRetBytes); + tmpRetBytes = undefined; + } + bjs["swift_js_throw"] = function(id) { + tmpRetException = swift.memory.retainByRef(id); + } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } + bjs["swift_js_push_i32"] = function(v) { + i32Stack.push(v | 0); + } + bjs["swift_js_push_f32"] = function(v) { + f32Stack.push(Math.fround(v)); + } + bjs["swift_js_push_f64"] = function(v) { + f64Stack.push(v); + } + bjs["swift_js_push_string"] = function(ptr, len) { + const value = decodeString(ptr, len); + strStack.push(value); + } + bjs["swift_js_pop_i32"] = function() { + return i32Stack.pop(); + } + bjs["swift_js_pop_f32"] = function() { + return f32Stack.pop(); + } + bjs["swift_js_pop_f64"] = function() { + return f64Stack.pop(); + } + bjs["swift_js_push_pointer"] = function(pointer) { + ptrStack.push(pointer); + } + bjs["swift_js_pop_pointer"] = function() { + return ptrStack.pop(); + } + bjs["swift_js_push_i64"] = function(v) { + i64Stack.push(v); + } + bjs["swift_js_pop_i64"] = function() { + return i64Stack.pop(); + } + const taCtors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array]; + bjs["swift_js_push_typed_array"] = function(kind, ptr, count) { + const Ctor = taCtors[kind]; + const byteLen = count * Ctor.BYTES_PER_ELEMENT; + const copy = memory.buffer.slice(ptr, ptr + byteLen); + taStack.push(Array.from(new Ctor(copy))); + } + bjs["swift_js_struct_lower_GenericPoint"] = function(objectId) { + structHelpers.M10TestModuleT12GenericPoint.lower(swift.memory.getObject(objectId)); + } + bjs["swift_js_struct_lift_GenericPoint"] = function() { + const value = structHelpers.M10TestModuleT12GenericPoint.lift(); + return swift.memory.retain(value); + } + bjs["bjs_core_register_type_handles"] = function(base, count) { + const codecs = [ + __bjs_primitiveCodecs.Bool, + __bjs_primitiveCodecs.Int, + __bjs_primitiveCodecs.Int8, + __bjs_primitiveCodecs.UInt8, + __bjs_primitiveCodecs.Int16, + __bjs_primitiveCodecs.UInt16, + __bjs_primitiveCodecs.Int32, + __bjs_primitiveCodecs.UInt32, + __bjs_primitiveCodecs.UInt, + __bjs_primitiveCodecs.Int64, + __bjs_primitiveCodecs.UInt64, + __bjs_primitiveCodecs.Float, + __bjs_primitiveCodecs.Double, + __bjs_primitiveCodecs.String, + __bjs_primitiveCodecs.JSValue, + ]; + const typeIds = new Int32Array(memory.buffer, base >>> 0, count >>> 0); + for (let i = 0; i < count; i++) { + __bjs_codecByTypeId.set(typeIds[i], codecs[i]); + } + } + bjs["bjs_TestModule_register_type_handles"] = function(base, count) { + const codecs = [ + __bjs_codec_M10TestModuleT12GenericPoint, + __bjs_codec_M10TestModuleT16GenericImportBox, + __bjs_codec_M10TestModuleT12GenericColor, + __bjs_stringCodec, + __bjs_codec_M10TestModuleT13GenericTagged, + ]; + const typeIds = new Int32Array(memory.buffer, base >>> 0, count >>> 0); + for (let i = 0; i < count; i++) { + __bjs_codecByTypeId.set(typeIds[i], codecs[i]); + } + } + const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); + bjs["swift_js_make_promise"] = function() { + let resolve, reject; + const promise = new Promise((res, rej) => { resolve = res; reject = rej; }); + promise[__bjs_promiseSettlers] = { resolve, reject }; + return swift.memory.retain(promise); + } + bjs["swift_js_return_optional_bool"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalBool = null; + } else { + tmpRetOptionalBool = value !== 0; + } + } + bjs["swift_js_return_optional_int"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalInt = null; + } else { + tmpRetOptionalInt = value | 0; + } + } + bjs["swift_js_return_optional_float"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalFloat = null; + } else { + tmpRetOptionalFloat = Math.fround(value); + } + } + bjs["swift_js_return_optional_double"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalDouble = null; + } else { + tmpRetOptionalDouble = value; + } + } + bjs["swift_js_return_optional_string"] = function(isSome, ptr, len) { + if (isSome === 0) { + tmpRetString = null; + } else { + tmpRetString = decodeString(ptr, len); + } + } + bjs["swift_js_return_optional_object"] = function(isSome, objectId) { + if (isSome === 0) { + tmpRetString = null; + } else { + tmpRetString = swift.memory.getObject(objectId); + } + } + bjs["swift_js_return_optional_heap_object"] = function(isSome, pointer) { + if (isSome === 0) { + tmpRetOptionalHeapObject = null; + } else { + tmpRetOptionalHeapObject = pointer; + } + } + bjs["swift_js_get_optional_int_presence"] = function() { + return tmpRetOptionalInt != null ? 1 : 0; + } + bjs["swift_js_get_optional_int_value"] = function() { + const value = tmpRetOptionalInt; + tmpRetOptionalInt = undefined; + return value; + } + bjs["swift_js_get_optional_string"] = function() { + const str = tmpRetString; + tmpRetString = undefined; + if (str == null) { + return -1; + } else { + const bytes = textEncoder.encode(str); + tmpRetBytes = bytes; + return bytes.length; + } + } + bjs["swift_js_get_optional_float_presence"] = function() { + return tmpRetOptionalFloat != null ? 1 : 0; + } + bjs["swift_js_get_optional_float_value"] = function() { + const value = tmpRetOptionalFloat; + tmpRetOptionalFloat = undefined; + return value; + } + bjs["swift_js_get_optional_double_presence"] = function() { + return tmpRetOptionalDouble != null ? 1 : 0; + } + bjs["swift_js_get_optional_double_value"] = function() { + const value = tmpRetOptionalDouble; + tmpRetOptionalDouble = undefined; + return value; + } + bjs["swift_js_get_optional_heap_object_pointer"] = function() { + const pointer = tmpRetOptionalHeapObject; + tmpRetOptionalHeapObject = undefined; + return pointer || 0; + } + bjs["swift_js_closure_unregister"] = function(funcRef) {} + // Wrapper functions for module: TestModule + if (!importObject["TestModule"]) { + importObject["TestModule"] = {}; + } + importObject["TestModule"]["bjs_GenericImportBox_wrap"] = function(pointer) { + const obj = _exports['GenericImportBox'].__construct(pointer); + return swift.memory.retain(obj); + }; + const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; + TestModule["bjs_genericRoundTrip"] = function bjs_genericRoundTrip(tTypeId) { + try { + const codecT = __bjs_codecForTypeId(tTypeId); + const value = codecT.lift(); + let ret = imports.genericRoundTrip(value); + codecT.lower(ret); + } catch (error) { + setException(error); + } + } + TestModule["bjs_genericParse"] = function bjs_genericParse(jsonBytes, jsonCount, tTypeId) { + try { + const codecT = __bjs_codecForTypeId(tTypeId); + const string = decodeString(jsonBytes, jsonCount); + let ret = imports.genericParse(string); + codecT.lower(ret); + } catch (error) { + setException(error); + } + } + TestModule["bjs_importGenericCombine"] = function bjs_importGenericCombine(tTypeId, uTypeId) { + try { + const codecT = __bjs_codecForTypeId(tTypeId); + const codecU = __bjs_codecForTypeId(uTypeId); + const a = codecT.lift(); + const b = codecU.lift(); + let ret = imports.importGenericCombine(a, b); + codecU.lower(ret); + } catch (error) { + setException(error); + } + } + TestModule["bjs_importGenericCaseDistinct"] = function bjs_importGenericCaseDistinct(tTypeId, tTypeId1) { + try { + const codecT = __bjs_codecForTypeId(tTypeId); + const codect = __bjs_codecForTypeId(tTypeId1); + const a = codecT.lift(); + const b = codect.lift(); + let ret = imports.importGenericCaseDistinct(a, b); + codecT.lower(ret); + } catch (error) { + setException(error); + } + } + TestModule["bjs_importGenericArray"] = function bjs_importGenericArray(tTypeId) { + try { + const codecT = __bjs_codecForTypeId(tTypeId); + const values = __bjs_arrayCodec(codecT).lift(); + let ret = imports.importGenericArray(values); + __bjs_arrayCodec(codecT).lower(ret); + } catch (error) { + setException(error); + } + } + TestModule["bjs_importGenericOptional"] = function bjs_importGenericOptional(tTypeId) { + try { + const codecT = __bjs_codecForTypeId(tTypeId); + const value = __bjs_optionalCodec(codecT).lift(); + let ret = imports.importGenericOptional(value); + __bjs_optionalCodec(codecT).lower(ret); + } catch (error) { + setException(error); + } + } + TestModule["bjs_importGenericDictionary"] = function bjs_importGenericDictionary(tTypeId) { + try { + const codecT = __bjs_codecForTypeId(tTypeId); + const values = __bjs_dictCodec(codecT).lift(); + let ret = imports.importGenericDictionary(values); + __bjs_dictCodec(codecT).lower(ret); + } catch (error) { + setException(error); + } + } + TestModule["bjs_importGenericAfterOptionalArray"] = function bjs_importGenericAfterOptionalArray(tTypeId) { + try { + const codecT = __bjs_codecForTypeId(tTypeId); + const optValue = __bjs_codec_Optional_Array_Int.lift(); + const value = codecT.lift(); + let ret = imports.importGenericAfterOptionalArray(optValue, value); + codecT.lower(ret); + } catch (error) { + setException(error); + } + } + TestModule["bjs_GenericPairFactory_init"] = function bjs_GenericPairFactory_init(tagBytes, tagCount, tTypeId, uTypeId) { + try { + const codecT = __bjs_codecForTypeId(tTypeId); + const codecU = __bjs_codecForTypeId(uTypeId); + const string = decodeString(tagBytes, tagCount); + const first = codecT.lift(); + const second = codecU.lift(); + return swift.memory.retain(new imports.GenericPairFactory(string, first, second)); + } catch (error) { + setException(error); + return 0 + } + } + TestModule["bjs_GenericConsumer_init"] = function bjs_GenericConsumer_init(tTypeId) { + try { + const codecT = __bjs_codecForTypeId(tTypeId); + const value = codecT.lift(); + return swift.memory.retain(new imports.GenericConsumer(value)); + } catch (error) { + setException(error); + return 0 + } + } + TestModule["bjs_GenericConsumer_box_static"] = function bjs_GenericConsumer_box_static(tTypeId) { + try { + const codecT = __bjs_codecForTypeId(tTypeId); + const value = codecT.lift(); + let ret = imports.GenericConsumer.box(value); + codecT.lower(ret); + } catch (error) { + setException(error); + } + } + TestModule["bjs_GenericConsumer_accept"] = function bjs_GenericConsumer_accept(self, tTypeId) { + try { + const codecT = __bjs_codecForTypeId(tTypeId); + const value = codecT.lift(); + swift.memory.getObject(self).accept(value); + } catch (error) { + setException(error); + } + } + TestModule["bjs_GenericConsumer_identity"] = function bjs_GenericConsumer_identity(self, tTypeId) { + try { + const codecT = __bjs_codecForTypeId(tTypeId); + const value = codecT.lift(); + let ret = swift.memory.getObject(self).identity(value); + codecT.lower(ret); + } catch (error) { + setException(error); + } + } + }, + setInstance: (i) => { + instance = i; + memory = instance.exports.memory; + + decodeString = (ptr, len) => { const bytes = new Uint8Array(memory.buffer, ptr >>> 0, len >>> 0); return textDecoder.decode(bytes); } + + setException = (error) => { + instance.exports._swift_js_exception.value = swift.memory.retain(error) + } + }, + /** @param {WebAssembly.Instance} instance */ + createExports: (instance) => { + const js = swift.memory.heap; + const swiftHeapObjectFinalizationRegistry = (typeof FinalizationRegistry === "undefined") ? { register: () => {}, unregister: () => {} } : new FinalizationRegistry((state) => { + if (state.hasReleased) { + return; + } + state.hasReleased = true; + state.identityMap?.delete(state.pointer); + state.deinit(state.pointer); + }); + + /// Represents a Swift heap object like a class instance or an actor instance. + class SwiftHeapObject { + static __wrap(pointer, deinit, prototype, identityCache) { + pointer = pointer >>> 0; + const makeFresh = (identityMap) => { + const obj = Object.create(prototype); + const state = { pointer, deinit, hasReleased: false, identityMap }; + obj.pointer = pointer; + obj.__swiftHeapObjectState = state; + swiftHeapObjectFinalizationRegistry.register(obj, state, state); + if (identityMap) { + identityMap.set(pointer, new WeakRef(obj)); + } + return obj; + }; + + if (!identityCache) { + return makeFresh(null); + } + + const cached = identityCache.get(pointer)?.deref(); + if (cached && !cached.__swiftHeapObjectState.hasReleased) { + deinit(pointer); + return cached; + } + if (identityCache.has(pointer)) { + identityCache.delete(pointer); + } + + return makeFresh(identityCache); + } + + release() { + const state = this.__swiftHeapObjectState; + if (state.hasReleased) { + return; + } + state.hasReleased = true; + swiftHeapObjectFinalizationRegistry.unregister(state); + state.identityMap?.delete(state.pointer); + state.deinit(state.pointer); + } + } + class GenericImportBox extends SwiftHeapObject { + static __construct(ptr) { + return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_GenericImportBox_deinit, GenericImportBox.prototype, null); + } + + constructor(value) { + const ret = instance.exports.bjs_GenericImportBox_init(value); + return GenericImportBox.__construct(ret); + } + get() { + const ret = instance.exports.bjs_GenericImportBox_get(this.pointer); + return ret; + } + get value() { + const ret = instance.exports.bjs_GenericImportBox_value_get(this.pointer); + return ret; + } + set value(value) { + instance.exports.bjs_GenericImportBox_value_set(this.pointer, value); + } + } + const __bjs_helpers_M10TestModuleT12GenericPoint = __bjs_createStructHelpers_M10TestModuleT12GenericPoint(); + structHelpers.M10TestModuleT12GenericPoint = __bjs_helpers_M10TestModuleT12GenericPoint; + + const __bjs_helpers_M10TestModuleT13GenericTagged = __bjs_createEnumHelpers_M10TestModuleT13GenericTagged(); + enumHelpers.M10TestModuleT13GenericTagged = __bjs_helpers_M10TestModuleT13GenericTagged; + + const exports = { + GenericColor: GenericColorValues, + GenericMode: GenericModeValues, + GenericTagged: GenericTaggedValues, + GenericImportBox, + }; + _exports = exports; + return exports; + }, + } +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalGetter.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalGetter.js index b1d830768..adb70913c 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalGetter.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalGetter.js @@ -107,6 +107,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalThisImports.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalThisImports.js index 6f43c2d9c..760a6b50c 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalThisImports.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalThisImports.js @@ -106,6 +106,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.ConfigPointer.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.ConfigPointer.js index 83f53d8a6..1e1d14696 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.ConfigPointer.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.ConfigPointer.js @@ -106,6 +106,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.PerClass.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.PerClass.js index bb6f36902..c85aee3af 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.PerClass.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.PerClass.js @@ -106,6 +106,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.js index bb6f36902..c85aee3af 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.js @@ -106,6 +106,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ImportArray.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ImportArray.js index 07341894e..c92ea6ad3 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ImportArray.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ImportArray.js @@ -31,6 +31,333 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + + function __bjs_jsValueLower(value) { + let kind; + let payload1; + let payload2; + if (value === null) { + kind = 4; + payload1 = 0; + payload2 = 0; + } else { + switch (typeof value) { + case "boolean": + kind = 0; + payload1 = value ? 1 : 0; + payload2 = 0; + break; + case "number": + kind = 2; + payload1 = 0; + payload2 = value; + break; + case "string": + kind = 1; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "undefined": + kind = 5; + payload1 = 0; + payload2 = 0; + break; + case "object": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "function": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "symbol": + kind = 7; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "bigint": + kind = 8; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + default: + throw new TypeError("Unsupported JSValue type"); + } + } + return [kind, payload1, payload2]; + } + function __bjs_jsValueLift(kind, payload1, payload2) { + let jsValue; + switch (kind) { + case 0: + jsValue = payload1 !== 0; + break; + case 1: + jsValue = swift.memory.getObject(payload1); + break; + case 2: + jsValue = payload2; + break; + case 3: + jsValue = swift.memory.getObject(payload1); + break; + case 4: + jsValue = null; + break; + case 5: + jsValue = undefined; + break; + case 7: + jsValue = swift.memory.getObject(payload1); + break; + case 8: + jsValue = swift.memory.getObject(payload1); + break; + default: + throw new TypeError("Unsupported JSValue kind " + kind); + } + return jsValue; + } + + const __bjs_codec_Array_Int = __bjs_arrayCodec(__bjs_primitiveCodecs.Int); + const __bjs_codec_Array_String = __bjs_arrayCodec(__bjs_stringCodec); + const __bjs_codec_Optional_Array_Int = __bjs_optionalCodec(__bjs_codec_Array_Int); + return { /** @@ -107,6 +434,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -207,119 +535,38 @@ export async function createInstantiator(options, swift) { const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_roundtrip"] = function bjs_roundtrip() { try { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const int = i32Stack.pop(); - arrayResult.push(int); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Int.lift(); let ret = imports.roundtrip(arrayResult); - for (const elem of ret) { - i32Stack.push((elem | 0)); - } - i32Stack.push(ret.length); + __bjs_codec_Array_Int.lower(ret); } catch (error) { setException(error); } } TestModule["bjs_logStrings"] = function bjs_logStrings() { try { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const string = strStack.pop(); - arrayResult.push(string); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_String.lift(); imports.logStrings(arrayResult); } catch (error) { setException(error); } } - TestModule["bjs_optionalArrayThenArray"] = function bjs_optionalArrayThenArray(a) { + TestModule["bjs_optionalArrayThenArray"] = function bjs_optionalArrayThenArray() { try { - let optResult; - if (a) { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const int = i32Stack.pop(); - arrayResult.push(int); - } - arrayResult.reverse(); - } - optResult = arrayResult; - } else { - optResult = null; - } - const arrayLen1 = i32Stack.pop(); - let arrayResult1; - if (arrayLen1 === -1) { - arrayResult1 = taStack.pop(); - } else { - arrayResult1 = []; - for (let i1 = 0; i1 < arrayLen1; i1++) { - const int1 = i32Stack.pop(); - arrayResult1.push(int1); - } - arrayResult1.reverse(); - } - let ret = imports.optionalArrayThenArray(optResult, arrayResult1); + const optValue = __bjs_codec_Optional_Array_Int.lift(); + const arrayResult = __bjs_codec_Array_Int.lift(); + let ret = imports.optionalArrayThenArray(optValue, arrayResult); return ret; } catch (error) { setException(error); return 0 } } - TestModule["bjs_borrowedStringAroundStackParams"] = function bjs_borrowedStringAroundStackParams(sBytes, sCount, a) { + TestModule["bjs_borrowedStringAroundStackParams"] = function bjs_borrowedStringAroundStackParams(sBytes, sCount) { try { const string = decodeString(sBytes, sCount); - let optResult; - if (a) { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const int = i32Stack.pop(); - arrayResult.push(int); - } - arrayResult.reverse(); - } - optResult = arrayResult; - } else { - optResult = null; - } - const arrayLen1 = i32Stack.pop(); - let arrayResult1; - if (arrayLen1 === -1) { - arrayResult1 = taStack.pop(); - } else { - arrayResult1 = []; - for (let i1 = 0; i1 < arrayLen1; i1++) { - const int1 = i32Stack.pop(); - arrayResult1.push(int1); - } - arrayResult1.reverse(); - } - let ret = imports.borrowedStringAroundStackParams(string, optResult, arrayResult1); + const optValue = __bjs_codec_Optional_Array_Int.lift(); + const arrayResult = __bjs_codec_Array_Int.lift(); + let ret = imports.borrowedStringAroundStackParams(string, optValue, arrayResult); return ret; } catch (error) { setException(error); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ImportedTypeInExportedInterface.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ImportedTypeInExportedInterface.js index 4328e4d4e..363f6c595 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ImportedTypeInExportedInterface.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ImportedTypeInExportedInterface.js @@ -31,7 +31,346 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createFooContainerHelpers = () => ({ + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + + function __bjs_jsValueLower(value) { + let kind; + let payload1; + let payload2; + if (value === null) { + kind = 4; + payload1 = 0; + payload2 = 0; + } else { + switch (typeof value) { + case "boolean": + kind = 0; + payload1 = value ? 1 : 0; + payload2 = 0; + break; + case "number": + kind = 2; + payload1 = 0; + payload2 = value; + break; + case "string": + kind = 1; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "undefined": + kind = 5; + payload1 = 0; + payload2 = 0; + break; + case "object": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "function": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "symbol": + kind = 7; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "bigint": + kind = 8; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + default: + throw new TypeError("Unsupported JSValue type"); + } + } + return [kind, payload1, payload2]; + } + function __bjs_jsValueLift(kind, payload1, payload2) { + let jsValue; + switch (kind) { + case 0: + jsValue = payload1 !== 0; + break; + case 1: + jsValue = swift.memory.getObject(payload1); + break; + case 2: + jsValue = payload2; + break; + case 3: + jsValue = swift.memory.getObject(payload1); + break; + case 4: + jsValue = null; + break; + case 5: + jsValue = undefined; + break; + case 7: + jsValue = swift.memory.getObject(payload1); + break; + case 8: + jsValue = swift.memory.getObject(payload1); + break; + default: + throw new TypeError("Unsupported JSValue kind " + kind); + } + return jsValue; + } + + const __bjs_codec_Foo = { + lower: (v) => { + const objId = swift.memory.retain(v); + i32Stack.push(objId); + }, + lift: () => { + const objId = i32Stack.pop(); + const obj = swift.memory.getObject(objId); + swift.memory.release(objId); + return obj; + }, + }; + const __bjs_codec_Array_Foo = __bjs_arrayCodec(__bjs_codec_Foo); + const __bjs_codec_Optional_Foo = __bjs_optionalCodec(__bjs_codec_Foo); + const __bjs_codec_Array_Optional_Foo = __bjs_arrayCodec(__bjs_codec_Optional_Foo); + + const __bjs_createStructHelpers_M10TestModuleT12FooContainer = () => ({ lower: (value) => { let id; if (value.foo != null) { @@ -40,24 +379,10 @@ export async function createInstantiator(options, swift) { id = undefined; } i32Stack.push(id !== undefined ? id : 0); - const isSome = value.optionalFoo != null ? 1 : 0; - if (isSome) { - const objId = swift.memory.retain(value.optionalFoo); - i32Stack.push(objId); - } - i32Stack.push(isSome); + __bjs_codec_Optional_Foo.lower(value.optionalFoo); }, lift: () => { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const objId = i32Stack.pop(); - const obj = swift.memory.getObject(objId); - swift.memory.release(objId); - optValue = obj; - } + const optValue = __bjs_codec_Optional_Foo.lift(); const objectId = i32Stack.pop(); let value; if (objectId !== 0) { @@ -146,12 +471,14 @@ export async function createInstantiator(options, swift) { taStack.push(Array.from(new Ctor(copy))); } bjs["swift_js_struct_lower_FooContainer"] = function(objectId) { - structHelpers.FooContainer.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT12FooContainer.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_FooContainer"] = function() { - const value = structHelpers.FooContainer.lift(); + const value = structHelpers.M10TestModuleT12FooContainer.lift(); return swift.memory.retain(value); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -272,8 +599,8 @@ export async function createInstantiator(options, swift) { /** @param {WebAssembly.Instance} instance */ createExports: (instance) => { const js = swift.memory.heap; - const FooContainerHelpers = __bjs_createFooContainerHelpers(); - structHelpers.FooContainer = FooContainerHelpers; + const __bjs_helpers_M10TestModuleT12FooContainer = __bjs_createStructHelpers_M10TestModuleT12FooContainer(); + structHelpers.M10TestModuleT12FooContainer = __bjs_helpers_M10TestModuleT12FooContainer; const exports = { makeFoo: function bjs_makeFoo() { @@ -289,66 +616,21 @@ export async function createInstantiator(options, swift) { return ret1; }, processFooArray: function bjs_processFooArray(foos) { - for (const elem of foos) { - const objId = swift.memory.retain(elem); - i32Stack.push(objId); - } - i32Stack.push(foos.length); + __bjs_codec_Array_Foo.lower(foos); instance.exports.bjs_processFooArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const objId1 = i32Stack.pop(); - const obj = swift.memory.getObject(objId1); - swift.memory.release(objId1); - arrayResult.push(obj); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Foo.lift(); return arrayResult; }, processOptionalFooArray: function bjs_processOptionalFooArray(foos) { - for (const elem of foos) { - const isSome = elem != null ? 1 : 0; - if (isSome) { - const objId = swift.memory.retain(elem); - i32Stack.push(objId); - } - i32Stack.push(isSome); - } - i32Stack.push(foos.length); + __bjs_codec_Array_Optional_Foo.lower(foos); instance.exports.bjs_processOptionalFooArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const isSome1 = i32Stack.pop(); - let optValue; - if (isSome1 === 0) { - optValue = null; - } else { - const objId1 = i32Stack.pop(); - const obj = swift.memory.getObject(objId1); - swift.memory.release(objId1); - optValue = obj; - } - arrayResult.push(optValue); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_Optional_Foo.lift(); return arrayResult; }, roundtripFooContainer: function bjs_roundtripFooContainer(container) { - structHelpers.FooContainer.lower(container); + structHelpers.M10TestModuleT12FooContainer.lower(container); instance.exports.bjs_roundtripFooContainer(); - const structValue = structHelpers.FooContainer.lift(); + const structValue = structHelpers.M10TestModuleT12FooContainer.lift(); return structValue; }, }; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/InvalidPropertyNames.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/InvalidPropertyNames.js index 8d1ac2698..e8fe5ec10 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/InvalidPropertyNames.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/InvalidPropertyNames.js @@ -107,6 +107,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClass.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClass.js index 08215f159..15b48d4b9 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClass.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClass.js @@ -107,6 +107,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClassStaticFunctions.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClassStaticFunctions.js index a38b0a391..5eaba3c8f 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClassStaticFunctions.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClassStaticFunctions.js @@ -107,6 +107,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSImportBareModule.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSImportBareModule.js index 1c995923a..6d1b1b6fb 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSImportBareModule.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSImportBareModule.js @@ -112,6 +112,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSImportBareModuleFallback.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSImportBareModuleFallback.js index 038374240..9428698be 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSImportBareModuleFallback.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSImportBareModuleFallback.js @@ -109,6 +109,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSImportModule.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSImportModule.js index e03dcbab4..aacf5e61a 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSImportModule.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSImportModule.js @@ -109,6 +109,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSNameOverride.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSNameOverride.d.ts new file mode 100644 index 000000000..d31aeebe3 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSNameOverride.d.ts @@ -0,0 +1,68 @@ +// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit, +// DO NOT EDIT. +// +// To update this file, just rebuild your project or run +// `swift package bridge-js`. + +export const RenamedEnumMembersValues: { + readonly Active: 0; + readonly Inactive: 1; +}; +export type RenamedEnumMembersTag = typeof RenamedEnumMembersValues[keyof typeof RenamedEnumMembersValues]; + +export interface RenamedVector { + dx: number; + dy: number; + magnitude(): number; +} +export type RenamedEnumMembersObject = typeof RenamedEnumMembersValues & { + describeCase(): string; + currentDefault: 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 RenamedMembers extends SwiftHeapObject { + makeGreeting(): string; + label: string; + readonly total: number; +} +export type Exports = { + makeGreeting(name: string): string; + greetName(name: string): string; + greetCount(count: number): string; + RenamedEnumMembers: RenamedEnumMembersObject + RenamedMembers: { + new(title: string, count: number): RenamedMembers; + makeDefault(): RenamedMembers; + sharedTotal: number; + readonly readOnlyLimit: number; + }, + RenamedNamespaceMembers: { + theAnswer: number; + plus(a: number, b: number): number; + }, + RenamedVector: { + readonly originVector: RenamedVector; + fromPolar(radius: number, angle: number): RenamedVector; + }, + Utils: { + Text: { + namespacedRenamed(): number; + }, + }, +} +export type Imports = { +} +export function createInstantiator(options: { + imports: Imports; +}, swift: any): Promise<{ + addImports: (importObject: WebAssembly.Imports) => void; + setInstance: (instance: WebAssembly.Instance) => void; + createExports: (instance: WebAssembly.Instance) => Exports; +}>; \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSNameOverride.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSNameOverride.js new file mode 100644 index 000000000..68ac11976 --- /dev/null +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSNameOverride.js @@ -0,0 +1,444 @@ +// NOTICE: This is auto-generated code by BridgeJS from JavaScriptKit, +// DO NOT EDIT. +// +// To update this file, just rebuild your project or run +// `swift package bridge-js`. + +export const RenamedEnumMembersValues = { + Active: 0, + Inactive: 1, +}; + +export async function createInstantiator(options, swift) { + let instance; + let memory; + let setException; + let decodeString; + const textDecoder = new TextDecoder("utf-8"); + const textEncoder = new TextEncoder("utf-8"); + let tmpRetString; + let tmpRetBytes; + let tmpRetException; + let tmpRetOptionalBool; + let tmpRetOptionalInt; + let tmpRetOptionalFloat; + let tmpRetOptionalDouble; + let tmpRetOptionalHeapObject; + let strStack = []; + let i32Stack = []; + let i64Stack = []; + let f32Stack = []; + let f64Stack = []; + let ptrStack = []; + let taStack = []; + const enumHelpers = {}; + const structHelpers = {}; + + let _exports = null; + let bjs = null; + const __bjs_createStructHelpers_M10TestModuleT13RenamedVector = () => ({ + lower: (value) => { + f64Stack.push(value.dx); + f64Stack.push(value.dy); + }, + lift: () => { + const f64 = f64Stack.pop(); + const f641 = f64Stack.pop(); + const instance1 = { dx: f641, dy: f64 }; + instance1.magnitude = function() { + structHelpers.M10TestModuleT13RenamedVector.lower(this); + const ret = instance.exports.bjs_RenamedVector_magnitude(); + return ret; + }.bind(instance1); + return instance1; + } + }); + + return { + /** + * @param {WebAssembly.Imports} importObject + */ + addImports: (importObject, importsContext) => { + bjs = {}; + importObject["bjs"] = bjs; + bjs["swift_js_return_string"] = function(ptr, len) { + tmpRetString = decodeString(ptr, len); + } + bjs["swift_js_init_memory"] = function(sourceId, bytesPtr) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const bytes = new Uint8Array(memory.buffer, bytesPtr >>> 0); + bytes.set(source); + } + bjs["swift_js_make_js_string"] = function(ptr, len) { + return swift.memory.retain(decodeString(ptr, len)); + } + bjs["swift_js_init_memory_with_result"] = function(ptr, len) { + const target = new Uint8Array(memory.buffer, ptr >>> 0, len >>> 0); + target.set(tmpRetBytes); + tmpRetBytes = undefined; + } + bjs["swift_js_throw"] = function(id) { + tmpRetException = swift.memory.retainByRef(id); + } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } + bjs["swift_js_push_i32"] = function(v) { + i32Stack.push(v | 0); + } + bjs["swift_js_push_f32"] = function(v) { + f32Stack.push(Math.fround(v)); + } + bjs["swift_js_push_f64"] = function(v) { + f64Stack.push(v); + } + bjs["swift_js_push_string"] = function(ptr, len) { + const value = decodeString(ptr, len); + strStack.push(value); + } + bjs["swift_js_pop_i32"] = function() { + return i32Stack.pop(); + } + bjs["swift_js_pop_f32"] = function() { + return f32Stack.pop(); + } + bjs["swift_js_pop_f64"] = function() { + return f64Stack.pop(); + } + bjs["swift_js_push_pointer"] = function(pointer) { + ptrStack.push(pointer); + } + bjs["swift_js_pop_pointer"] = function() { + return ptrStack.pop(); + } + bjs["swift_js_push_i64"] = function(v) { + i64Stack.push(v); + } + bjs["swift_js_pop_i64"] = function() { + return i64Stack.pop(); + } + const taCtors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array]; + bjs["swift_js_push_typed_array"] = function(kind, ptr, count) { + const Ctor = taCtors[kind]; + const byteLen = count * Ctor.BYTES_PER_ELEMENT; + const copy = memory.buffer.slice(ptr, ptr + byteLen); + taStack.push(Array.from(new Ctor(copy))); + } + bjs["swift_js_struct_lower_RenamedVector"] = function(objectId) { + structHelpers.M10TestModuleT13RenamedVector.lower(swift.memory.getObject(objectId)); + } + bjs["swift_js_struct_lift_RenamedVector"] = function() { + const value = structHelpers.M10TestModuleT13RenamedVector.lift(); + return swift.memory.retain(value); + } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; + const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); + bjs["swift_js_make_promise"] = function() { + let resolve, reject; + const promise = new Promise((res, rej) => { resolve = res; reject = rej; }); + promise[__bjs_promiseSettlers] = { resolve, reject }; + return swift.memory.retain(promise); + } + bjs["swift_js_return_optional_bool"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalBool = null; + } else { + tmpRetOptionalBool = value !== 0; + } + } + bjs["swift_js_return_optional_int"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalInt = null; + } else { + tmpRetOptionalInt = value | 0; + } + } + bjs["swift_js_return_optional_float"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalFloat = null; + } else { + tmpRetOptionalFloat = Math.fround(value); + } + } + bjs["swift_js_return_optional_double"] = function(isSome, value) { + if (isSome === 0) { + tmpRetOptionalDouble = null; + } else { + tmpRetOptionalDouble = value; + } + } + bjs["swift_js_return_optional_string"] = function(isSome, ptr, len) { + if (isSome === 0) { + tmpRetString = null; + } else { + tmpRetString = decodeString(ptr, len); + } + } + bjs["swift_js_return_optional_object"] = function(isSome, objectId) { + if (isSome === 0) { + tmpRetString = null; + } else { + tmpRetString = swift.memory.getObject(objectId); + } + } + bjs["swift_js_return_optional_heap_object"] = function(isSome, pointer) { + if (isSome === 0) { + tmpRetOptionalHeapObject = null; + } else { + tmpRetOptionalHeapObject = pointer; + } + } + bjs["swift_js_get_optional_int_presence"] = function() { + return tmpRetOptionalInt != null ? 1 : 0; + } + bjs["swift_js_get_optional_int_value"] = function() { + const value = tmpRetOptionalInt; + tmpRetOptionalInt = undefined; + return value; + } + bjs["swift_js_get_optional_string"] = function() { + const str = tmpRetString; + tmpRetString = undefined; + if (str == null) { + return -1; + } else { + const bytes = textEncoder.encode(str); + tmpRetBytes = bytes; + return bytes.length; + } + } + bjs["swift_js_get_optional_float_presence"] = function() { + return tmpRetOptionalFloat != null ? 1 : 0; + } + bjs["swift_js_get_optional_float_value"] = function() { + const value = tmpRetOptionalFloat; + tmpRetOptionalFloat = undefined; + return value; + } + bjs["swift_js_get_optional_double_presence"] = function() { + return tmpRetOptionalDouble != null ? 1 : 0; + } + bjs["swift_js_get_optional_double_value"] = function() { + const value = tmpRetOptionalDouble; + tmpRetOptionalDouble = undefined; + return value; + } + bjs["swift_js_get_optional_heap_object_pointer"] = function() { + const pointer = tmpRetOptionalHeapObject; + tmpRetOptionalHeapObject = undefined; + return pointer || 0; + } + bjs["swift_js_closure_unregister"] = function(funcRef) {} + // Wrapper functions for module: TestModule + if (!importObject["TestModule"]) { + importObject["TestModule"] = {}; + } + importObject["TestModule"]["bjs_RenamedMembers_wrap"] = function(pointer) { + const obj = _exports['RenamedMembers'].__construct(pointer); + return swift.memory.retain(obj); + }; + }, + setInstance: (i) => { + instance = i; + memory = instance.exports.memory; + + decodeString = (ptr, len) => { const bytes = new Uint8Array(memory.buffer, ptr >>> 0, len >>> 0); return textDecoder.decode(bytes); } + + setException = (error) => { + instance.exports._swift_js_exception.value = swift.memory.retain(error) + } + }, + /** @param {WebAssembly.Instance} instance */ + createExports: (instance) => { + const js = swift.memory.heap; + const swiftHeapObjectFinalizationRegistry = (typeof FinalizationRegistry === "undefined") ? { register: () => {}, unregister: () => {} } : new FinalizationRegistry((state) => { + if (state.hasReleased) { + return; + } + state.hasReleased = true; + state.identityMap?.delete(state.pointer); + state.deinit(state.pointer); + }); + + /// Represents a Swift heap object like a class instance or an actor instance. + class SwiftHeapObject { + static __wrap(pointer, deinit, prototype, identityCache) { + pointer = pointer >>> 0; + const makeFresh = (identityMap) => { + const obj = Object.create(prototype); + const state = { pointer, deinit, hasReleased: false, identityMap }; + obj.pointer = pointer; + obj.__swiftHeapObjectState = state; + swiftHeapObjectFinalizationRegistry.register(obj, state, state); + if (identityMap) { + identityMap.set(pointer, new WeakRef(obj)); + } + return obj; + }; + + if (!identityCache) { + return makeFresh(null); + } + + const cached = identityCache.get(pointer)?.deref(); + if (cached && !cached.__swiftHeapObjectState.hasReleased) { + deinit(pointer); + return cached; + } + if (identityCache.has(pointer)) { + identityCache.delete(pointer); + } + + return makeFresh(identityCache); + } + + release() { + const state = this.__swiftHeapObjectState; + if (state.hasReleased) { + return; + } + state.hasReleased = true; + swiftHeapObjectFinalizationRegistry.unregister(state); + state.identityMap?.delete(state.pointer); + state.deinit(state.pointer); + } + } + class RenamedMembers extends SwiftHeapObject { + static __construct(ptr) { + return SwiftHeapObject.__wrap(ptr, instance.exports.bjs_RenamedMembers_deinit, RenamedMembers.prototype, null); + } + + constructor(title, count) { + const titleBytes = textEncoder.encode(title); + const titleId = swift.memory.retain(titleBytes); + const ret = instance.exports.bjs_RenamedMembers_init(titleId, titleBytes.length, count); + return RenamedMembers.__construct(ret); + } + makeGreeting() { + instance.exports.bjs_RenamedMembers_makeGreeting(this.pointer); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + } + static makeDefault() { + const ret = instance.exports.bjs_RenamedMembers_static_makeDefault(); + return RenamedMembers.__construct(ret); + } + get label() { + instance.exports.bjs_RenamedMembers_title_get(this.pointer); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + } + set label(value) { + const valueBytes = textEncoder.encode(value); + const valueId = swift.memory.retain(valueBytes); + instance.exports.bjs_RenamedMembers_title_set(this.pointer, valueId, valueBytes.length); + } + get total() { + const ret = instance.exports.bjs_RenamedMembers_count_get(this.pointer); + return ret; + } + static get sharedTotal() { + const ret = instance.exports.bjs_RenamedMembers_static_sharedCount_get(); + return ret; + } + static set sharedTotal(value) { + instance.exports.bjs_RenamedMembers_static_sharedCount_set(value); + } + static get readOnlyLimit() { + const ret = instance.exports.bjs_RenamedMembers_static_limit_get(); + return ret; + } + } + const __bjs_helpers_M10TestModuleT13RenamedVector = __bjs_createStructHelpers_M10TestModuleT13RenamedVector(); + structHelpers.M10TestModuleT13RenamedVector = __bjs_helpers_M10TestModuleT13RenamedVector; + + const exports = { + makeGreeting: function bjs_makeGreeting(name) { + const nameBytes = textEncoder.encode(name); + const nameId = swift.memory.retain(nameBytes); + instance.exports.bjs_makeGreeting(nameId, nameBytes.length); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + }, + greetName: function bjs_greetName(name) { + const nameBytes = textEncoder.encode(name); + const nameId = swift.memory.retain(nameBytes); + instance.exports.bjs_greetName(nameId, nameBytes.length); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + }, + greetCount: function bjs_greetCount(count) { + instance.exports.bjs_greetCount(count); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + }, + RenamedEnumMembers: { + ...RenamedEnumMembersValues, + describeCase: function() { + instance.exports.bjs_RenamedEnumMembers_static_describeCase(); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + }, + get currentDefault() { + instance.exports.bjs_RenamedEnumMembers_static_defaultValue_get(); + const ret = tmpRetString; + tmpRetString = undefined; + return ret; + }, + set currentDefault(value) { + const valueBytes = textEncoder.encode(value); + const valueId = swift.memory.retain(valueBytes); + instance.exports.bjs_RenamedEnumMembers_static_defaultValue_set(valueId, valueBytes.length); + } + }, + RenamedMembers, + RenamedNamespaceMembers: { + get theAnswer() { + const ret = instance.exports.bjs_RenamedNamespaceMembers_static_answer_get(); + return ret; + }, + set theAnswer(value) { + instance.exports.bjs_RenamedNamespaceMembers_static_answer_set(value); + }, + plus: function bjs_RenamedNamespaceMembers_static_plus(a, b) { + const ret = instance.exports.bjs_RenamedNamespaceMembers_static_plus(a, b); + return ret; + }, + }, + RenamedVector: { + get originVector() { + instance.exports.bjs_RenamedVector_static_origin_get(); + const structValue = structHelpers.M10TestModuleT13RenamedVector.lift(); + return structValue; + }, + fromPolar: function(radius, angle) { + instance.exports.bjs_RenamedVector_static_fromPolar(radius, angle); + const structValue = structHelpers.M10TestModuleT13RenamedVector.lift(); + return structValue; + }, + }, + Utils: { + Text: { + namespacedRenamed: function bjs_Utils_Text_namespacedRenamed() { + const ret = instance.exports.bjs_Utils_Text_namespacedRenamed(); + return ret; + }, + }, + }, + }; + _exports = exports; + return exports; + }, + } +} \ No newline at end of file diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSTypedArrayTypes.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSTypedArrayTypes.js index 5c713cc78..f02f6bcf2 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSTypedArrayTypes.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSTypedArrayTypes.js @@ -106,6 +106,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSValue.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSValue.js index ae59008ba..9fe12ff47 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSValue.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSValue.js @@ -31,6 +31,240 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + function __bjs_jsValueLower(value) { let kind; let payload1; @@ -120,6 +354,9 @@ export async function createInstantiator(options, swift) { return jsValue; } + const __bjs_codec_Array_JSValue = __bjs_arrayCodec(__bjs_primitiveCodecs.JSValue); + const __bjs_codec_Optional_Array_JSValue = __bjs_optionalCodec(__bjs_codec_Array_JSValue); + return { /** @@ -196,6 +433,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -316,29 +554,9 @@ export async function createInstantiator(options, swift) { } TestModule["bjs_jsEchoJSValueArray"] = function bjs_jsEchoJSValueArray() { try { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const jsValuePayload2 = f64Stack.pop(); - const jsValuePayload1 = i32Stack.pop(); - const jsValueKind = i32Stack.pop(); - const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); - arrayResult.push(jsValue); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_JSValue.lift(); let ret = imports.jsEchoJSValueArray(arrayResult); - for (const elem of ret) { - const [elemKind, elemPayload1, elemPayload2] = __bjs_jsValueLower(elem); - i32Stack.push(elemKind); - i32Stack.push(elemPayload1); - f64Stack.push(elemPayload2); - } - i32Stack.push(ret.length); + __bjs_codec_Array_JSValue.lower(ret); } catch (error) { setException(error); } @@ -564,67 +782,16 @@ export async function createInstantiator(options, swift) { return optResult; }, roundTripJSValueArray: function bjs_roundTripJSValueArray(values) { - for (const elem of values) { - const [elemKind, elemPayload1, elemPayload2] = __bjs_jsValueLower(elem); - i32Stack.push(elemKind); - i32Stack.push(elemPayload1); - f64Stack.push(elemPayload2); - } - i32Stack.push(values.length); + __bjs_codec_Array_JSValue.lower(values); instance.exports.bjs_roundTripJSValueArray(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const jsValuePayload2 = f64Stack.pop(); - const jsValuePayload1 = i32Stack.pop(); - const jsValueKind = i32Stack.pop(); - const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); - arrayResult.push(jsValue); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_JSValue.lift(); return arrayResult; }, roundTripOptionalJSValueArray: function bjs_roundTripOptionalJSValueArray(values) { - const isSome = values != null; - if (isSome) { - for (const elem of values) { - const [elemKind, elemPayload1, elemPayload2] = __bjs_jsValueLower(elem); - i32Stack.push(elemKind); - i32Stack.push(elemPayload1); - f64Stack.push(elemPayload2); - } - i32Stack.push(values.length); - } - i32Stack.push(+isSome); + __bjs_codec_Optional_Array_JSValue.lower(values); instance.exports.bjs_roundTripOptionalJSValueArray(); - const isSome1 = i32Stack.pop(); - let optResult; - if (isSome1) { - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const jsValuePayload2 = f64Stack.pop(); - const jsValuePayload1 = i32Stack.pop(); - const jsValueKind = i32Stack.pop(); - const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); - arrayResult.push(jsValue); - } - arrayResult.reverse(); - } - optResult = arrayResult; - } else { - optResult = null; - } - return optResult; + const optValue = __bjs_codec_Optional_Array_JSValue.lift(); + return optValue; }, JSValueHolder, }; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedGlobal.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedGlobal.js index 39ecf8d99..5db38dde5 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedGlobal.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedGlobal.js @@ -106,6 +106,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedModules.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedModules.js index 62d7651e8..66818952b 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedModules.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedModules.js @@ -106,6 +106,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedPrivate.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedPrivate.js index 69bfe5ff1..a732808a6 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedPrivate.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedPrivate.js @@ -106,6 +106,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Global.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Global.js index aa5e3dbb4..ea49220de 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Global.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Global.js @@ -31,6 +31,341 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + + function __bjs_jsValueLower(value) { + let kind; + let payload1; + let payload2; + if (value === null) { + kind = 4; + payload1 = 0; + payload2 = 0; + } else { + switch (typeof value) { + case "boolean": + kind = 0; + payload1 = value ? 1 : 0; + payload2 = 0; + break; + case "number": + kind = 2; + payload1 = 0; + payload2 = value; + break; + case "string": + kind = 1; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "undefined": + kind = 5; + payload1 = 0; + payload2 = 0; + break; + case "object": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "function": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "symbol": + kind = 7; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "bigint": + kind = 8; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + default: + throw new TypeError("Unsupported JSValue type"); + } + } + return [kind, payload1, payload2]; + } + function __bjs_jsValueLift(kind, payload1, payload2) { + let jsValue; + switch (kind) { + case 0: + jsValue = payload1 !== 0; + break; + case 1: + jsValue = swift.memory.getObject(payload1); + break; + case 2: + jsValue = payload2; + break; + case 3: + jsValue = swift.memory.getObject(payload1); + break; + case 4: + jsValue = null; + break; + case 5: + jsValue = undefined; + break; + case 7: + jsValue = swift.memory.getObject(payload1); + break; + case 8: + jsValue = swift.memory.getObject(payload1); + break; + default: + throw new TypeError("Unsupported JSValue kind " + kind); + } + return jsValue; + } + + const __bjs_codec_M10TestModuleT7Greeter = { + lower: (v) => { + ptrStack.push(v.pointer); + }, + lift: () => { + const ptr = ptrStack.pop(); + const obj = _exports.__Swift.Foundation.Greeter.__construct(ptr); + return obj; + }, + }; + const __bjs_codec_Array_M10TestModuleT7Greeter = __bjs_arrayCodec(__bjs_codec_M10TestModuleT7Greeter); + return { /** @@ -106,6 +441,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -356,19 +692,7 @@ export async function createInstantiator(options, swift) { } getItems() { instance.exports.bjs_Collections_Container_getItems(this.pointer); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const ptr = ptrStack.pop(); - const obj = Greeter.__construct(ptr); - arrayResult.push(obj); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_M10TestModuleT7Greeter.lift(); return arrayResult; } addItem(item) { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.js index 9a5c6473e..25bd44d05 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.js @@ -31,6 +31,341 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + + function __bjs_jsValueLower(value) { + let kind; + let payload1; + let payload2; + if (value === null) { + kind = 4; + payload1 = 0; + payload2 = 0; + } else { + switch (typeof value) { + case "boolean": + kind = 0; + payload1 = value ? 1 : 0; + payload2 = 0; + break; + case "number": + kind = 2; + payload1 = 0; + payload2 = value; + break; + case "string": + kind = 1; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "undefined": + kind = 5; + payload1 = 0; + payload2 = 0; + break; + case "object": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "function": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "symbol": + kind = 7; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "bigint": + kind = 8; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + default: + throw new TypeError("Unsupported JSValue type"); + } + } + return [kind, payload1, payload2]; + } + function __bjs_jsValueLift(kind, payload1, payload2) { + let jsValue; + switch (kind) { + case 0: + jsValue = payload1 !== 0; + break; + case 1: + jsValue = swift.memory.getObject(payload1); + break; + case 2: + jsValue = payload2; + break; + case 3: + jsValue = swift.memory.getObject(payload1); + break; + case 4: + jsValue = null; + break; + case 5: + jsValue = undefined; + break; + case 7: + jsValue = swift.memory.getObject(payload1); + break; + case 8: + jsValue = swift.memory.getObject(payload1); + break; + default: + throw new TypeError("Unsupported JSValue kind " + kind); + } + return jsValue; + } + + const __bjs_codec_M10TestModuleT7Greeter = { + lower: (v) => { + ptrStack.push(v.pointer); + }, + lift: () => { + const ptr = ptrStack.pop(); + const obj = _exports.__Swift.Foundation.Greeter.__construct(ptr); + return obj; + }, + }; + const __bjs_codec_Array_M10TestModuleT7Greeter = __bjs_arrayCodec(__bjs_codec_M10TestModuleT7Greeter); + return { /** @@ -106,6 +441,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -356,19 +692,7 @@ export async function createInstantiator(options, swift) { } getItems() { instance.exports.bjs_Collections_Container_getItems(this.pointer); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const ptr = ptrStack.pop(); - const obj = Greeter.__construct(ptr); - arrayResult.push(obj); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_M10TestModuleT7Greeter.lift(); return arrayResult; } addItem(item) { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/NestedType.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/NestedType.js index 972f9ae74..f57c4007b 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/NestedType.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/NestedType.js @@ -31,7 +31,7 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createUser_StatsHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT4UserT5Stats = () => ({ lower: (value) => { i32Stack.push((value.health | 0)); f64Stack.push(value.score); @@ -42,7 +42,7 @@ export async function createInstantiator(options, swift) { return { health: int, score: f64 }; } }); - const __bjs_createPlayer_StatsHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT6PlayerT5Stats = () => ({ lower: (value) => { i32Stack.push((value.level | 0)); const bytes = textEncoder.encode(value.rating); @@ -132,19 +132,21 @@ export async function createInstantiator(options, swift) { taStack.push(Array.from(new Ctor(copy))); } bjs["swift_js_struct_lower_User_Stats"] = function(objectId) { - structHelpers.User_Stats.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT4UserT5Stats.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_User_Stats"] = function() { - const value = structHelpers.User_Stats.lift(); + const value = structHelpers.M10TestModuleT4UserT5Stats.lift(); return swift.memory.retain(value); } bjs["swift_js_struct_lower_Player_Stats"] = function(objectId) { - structHelpers.Player_Stats.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT6PlayerT5Stats.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Player_Stats"] = function() { - const value = structHelpers.Player_Stats.lift(); + const value = structHelpers.M10TestModuleT6PlayerT5Stats.lift(); return swift.memory.retain(value); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -344,11 +346,11 @@ export async function createInstantiator(options, swift) { return ret; } } - const User_StatsHelpers = __bjs_createUser_StatsHelpers(); - structHelpers.User_Stats = User_StatsHelpers; + const __bjs_helpers_M10TestModuleT4UserT5Stats = __bjs_createStructHelpers_M10TestModuleT4UserT5Stats(); + structHelpers.M10TestModuleT4UserT5Stats = __bjs_helpers_M10TestModuleT4UserT5Stats; - const Player_StatsHelpers = __bjs_createPlayer_StatsHelpers(); - structHelpers.Player_Stats = Player_StatsHelpers; + const __bjs_helpers_M10TestModuleT6PlayerT5Stats = __bjs_createStructHelpers_M10TestModuleT6PlayerT5Stats(); + structHelpers.M10TestModuleT6PlayerT5Stats = __bjs_helpers_M10TestModuleT6PlayerT5Stats; const exports = { Player, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Optionals.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Optionals.js index 5a253cdc0..b63f360e9 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Optionals.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Optionals.js @@ -31,6 +31,356 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + + function __bjs_jsValueLower(value) { + let kind; + let payload1; + let payload2; + if (value === null) { + kind = 4; + payload1 = 0; + payload2 = 0; + } else { + switch (typeof value) { + case "boolean": + kind = 0; + payload1 = value ? 1 : 0; + payload2 = 0; + break; + case "number": + kind = 2; + payload1 = 0; + payload2 = value; + break; + case "string": + kind = 1; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "undefined": + kind = 5; + payload1 = 0; + payload2 = 0; + break; + case "object": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "function": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "symbol": + kind = 7; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "bigint": + kind = 8; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + default: + throw new TypeError("Unsupported JSValue type"); + } + } + return [kind, payload1, payload2]; + } + function __bjs_jsValueLift(kind, payload1, payload2) { + let jsValue; + switch (kind) { + case 0: + jsValue = payload1 !== 0; + break; + case 1: + jsValue = swift.memory.getObject(payload1); + break; + case 2: + jsValue = payload2; + break; + case 3: + jsValue = swift.memory.getObject(payload1); + break; + case 4: + jsValue = null; + break; + case 5: + jsValue = undefined; + break; + case 7: + jsValue = swift.memory.getObject(payload1); + break; + case 8: + jsValue = swift.memory.getObject(payload1); + break; + default: + throw new TypeError("Unsupported JSValue kind " + kind); + } + return jsValue; + } + + const __bjs_codec_JSObject = { + lower: (v) => { + const objId = swift.memory.retain(v); + i32Stack.push(objId); + }, + lift: () => { + const objId = i32Stack.pop(); + const obj = swift.memory.getObject(objId); + swift.memory.release(objId); + return obj; + }, + }; + const __bjs_codec_Optional_JSObject = __bjs_optionalCodec(__bjs_codec_JSObject); + const __bjs_codec_WithOptionalJSClass = { + lower: (v) => { + const objId = swift.memory.retain(v); + i32Stack.push(objId); + }, + lift: () => { + const objId = i32Stack.pop(); + const obj = swift.memory.getObject(objId); + swift.memory.release(objId); + return obj; + }, + }; + const __bjs_codec_Optional_WithOptionalJSClass = __bjs_optionalCodec(__bjs_codec_WithOptionalJSClass); + return { /** @@ -107,6 +457,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -314,12 +665,7 @@ export async function createInstantiator(options, swift) { TestModule["bjs_WithOptionalJSClass_childOrNull_get"] = function bjs_WithOptionalJSClass_childOrNull_get(self) { try { let ret = swift.memory.getObject(self).childOrNull; - const isSome = ret != null; - if (isSome) { - const objId = swift.memory.retain(ret); - i32Stack.push(objId); - } - i32Stack.push(isSome ? 1 : 0); + __bjs_codec_Optional_WithOptionalJSClass.lower(ret); } catch (error) { setException(error); } @@ -490,12 +836,7 @@ export async function createInstantiator(options, swift) { TestModule["bjs_WithOptionalJSClass_roundTripChildOrNull"] = function bjs_WithOptionalJSClass_roundTripChildOrNull(self, valueIsSome, valueObjectId) { try { let ret = swift.memory.getObject(self).roundTripChildOrNull(valueIsSome ? swift.memory.getObject(valueObjectId) : null); - const isSome = ret != null; - if (isSome) { - const objId = swift.memory.retain(ret); - i32Stack.push(objId); - } - i32Stack.push(isSome ? 1 : 0); + __bjs_codec_Optional_WithOptionalJSClass.lower(ret); } catch (error) { setException(error); } @@ -722,17 +1063,8 @@ export async function createInstantiator(options, swift) { result = 0; } instance.exports.bjs_roundTripExportedOptionalJSObject(+isSome, result); - const isSome1 = i32Stack.pop(); - let optResult; - if (isSome1) { - const objId = i32Stack.pop(); - const obj = swift.memory.getObject(objId); - swift.memory.release(objId); - optResult = obj; - } else { - optResult = null; - } - return optResult; + const optValue = __bjs_codec_Optional_JSObject.lift(); + return optValue; }, roundTripExportedOptionalJSClass: function bjs_roundTripExportedOptionalJSClass(value) { const isSome = value != null; @@ -743,17 +1075,8 @@ export async function createInstantiator(options, swift) { result = 0; } instance.exports.bjs_roundTripExportedOptionalJSClass(+isSome, result); - const isSome1 = i32Stack.pop(); - let optResult; - if (isSome1) { - const objId = i32Stack.pop(); - const obj = swift.memory.getObject(objId); - swift.memory.release(objId); - optResult = obj; - } else { - optResult = null; - } - return optResult; + const optValue = __bjs_codec_Optional_WithOptionalJSClass.lift(); + return optValue; }, roundTripString: function bjs_roundTripString(name) { const isSome = name != null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.js index 46d57d793..d4480a65c 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.js @@ -107,6 +107,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.js index bb4e8552d..e9b298fb2 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.js @@ -107,6 +107,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PropertyTypes.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PropertyTypes.js index 61560134a..beb9417df 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PropertyTypes.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PropertyTypes.js @@ -106,6 +106,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Protocol.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Protocol.js index b2a894ffa..f0c2d3fae 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Protocol.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Protocol.js @@ -55,7 +55,345 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createResultValuesHelpers = () => ({ + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + + function __bjs_jsValueLower(value) { + let kind; + let payload1; + let payload2; + if (value === null) { + kind = 4; + payload1 = 0; + payload2 = 0; + } else { + switch (typeof value) { + case "boolean": + kind = 0; + payload1 = value ? 1 : 0; + payload2 = 0; + break; + case "number": + kind = 2; + payload1 = 0; + payload2 = value; + break; + case "string": + kind = 1; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "undefined": + kind = 5; + payload1 = 0; + payload2 = 0; + break; + case "object": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "function": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "symbol": + kind = 7; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "bigint": + kind = 8; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + default: + throw new TypeError("Unsupported JSValue type"); + } + } + return [kind, payload1, payload2]; + } + function __bjs_jsValueLift(kind, payload1, payload2) { + let jsValue; + switch (kind) { + case 0: + jsValue = payload1 !== 0; + break; + case 1: + jsValue = swift.memory.getObject(payload1); + break; + case 2: + jsValue = payload2; + break; + case 3: + jsValue = swift.memory.getObject(payload1); + break; + case 4: + jsValue = null; + break; + case 5: + jsValue = undefined; + break; + case 7: + jsValue = swift.memory.getObject(payload1); + break; + case 8: + jsValue = swift.memory.getObject(payload1); + break; + default: + throw new TypeError("Unsupported JSValue kind " + kind); + } + return jsValue; + } + + const __bjs_codec_M10TestModuleT24MyViewControllerDelegate = { + lower: (v) => { + const objId = swift.memory.retain(v); + i32Stack.push(objId); + }, + lift: () => { + const objId = i32Stack.pop(); + const obj = swift.memory.getObject(objId); + swift.memory.release(objId); + return obj; + }, + }; + const __bjs_codec_Array_M10TestModuleT24MyViewControllerDelegate = __bjs_arrayCodec(__bjs_codec_M10TestModuleT24MyViewControllerDelegate); + const __bjs_codec_Dict_M10TestModuleT24MyViewControllerDelegate = __bjs_dictCodec(__bjs_codec_M10TestModuleT24MyViewControllerDelegate); + + const __bjs_createEnumHelpers_M10TestModuleT6Result = () => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { @@ -163,6 +501,8 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -366,7 +706,7 @@ export async function createInstantiator(options, swift) { TestModule["bjs_MyViewControllerDelegate_result_get"] = function bjs_MyViewControllerDelegate_result_get(self) { try { let ret = swift.memory.getObject(self).result; - const caseId = enumHelpers.Result.lower(ret); + const caseId = enumHelpers.M10TestModuleT6Result.lower(ret); return caseId; } catch (error) { setException(error); @@ -374,7 +714,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); + const enumValue = enumHelpers.M10TestModuleT6Result.lift(value); swift.memory.getObject(self).result = enumValue; } catch (error) { setException(error); @@ -385,7 +725,7 @@ export async function createInstantiator(options, swift) { let ret = swift.memory.getObject(self).optionalResult; const isSome = ret != null; if (isSome) { - const caseId = enumHelpers.Result.lower(ret); + const caseId = enumHelpers.M10TestModuleT6Result.lower(ret); return caseId; } else { return -1; @@ -398,7 +738,7 @@ export async function createInstantiator(options, swift) { try { let optResult; if (valueIsSome) { - const enumValue = enumHelpers.Result.lift(valueCaseId); + const enumValue = enumHelpers.M10TestModuleT6Result.lift(valueCaseId); optResult = enumValue; } else { optResult = null; @@ -556,7 +896,7 @@ export async function createInstantiator(options, swift) { } TestModule["bjs_MyViewControllerDelegate_handleResult"] = function bjs_MyViewControllerDelegate_handleResult(self, result) { try { - const enumValue = enumHelpers.Result.lift(result); + const enumValue = enumHelpers.M10TestModuleT6Result.lift(result); swift.memory.getObject(self).handleResult(enumValue); } catch (error) { setException(error); @@ -565,7 +905,7 @@ export async function createInstantiator(options, swift) { TestModule["bjs_MyViewControllerDelegate_getResult"] = function bjs_MyViewControllerDelegate_getResult(self) { try { let ret = swift.memory.getObject(self).getResult(); - const caseId = enumHelpers.Result.lower(ret); + const caseId = enumHelpers.M10TestModuleT6Result.lower(ret); return caseId; } catch (error) { setException(error); @@ -724,11 +1064,7 @@ export async function createInstantiator(options, swift) { } constructor(delegates) { - for (const elem of delegates) { - const objId = swift.memory.retain(elem); - i32Stack.push(objId); - } - i32Stack.push(delegates.length); + __bjs_codec_Array_M10TestModuleT24MyViewControllerDelegate.lower(delegates); const ret = instance.exports.bjs_DelegateManager_init(); return DelegateManager.__construct(ret); } @@ -737,107 +1073,37 @@ export async function createInstantiator(options, swift) { } get delegates() { instance.exports.bjs_DelegateManager_delegates_get(this.pointer); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const objId = i32Stack.pop(); - const obj = swift.memory.getObject(objId); - swift.memory.release(objId); - arrayResult.push(obj); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_M10TestModuleT24MyViewControllerDelegate.lift(); return arrayResult; } set delegates(value) { - for (const elem of value) { - const objId = swift.memory.retain(elem); - i32Stack.push(objId); - } - i32Stack.push(value.length); + __bjs_codec_Array_M10TestModuleT24MyViewControllerDelegate.lower(value); instance.exports.bjs_DelegateManager_delegates_set(this.pointer); } get delegatesByName() { instance.exports.bjs_DelegateManager_delegatesByName_get(this.pointer); - const dictLen = i32Stack.pop(); - const dictResult = {}; - for (let i = 0; i < dictLen; i++) { - const objId = i32Stack.pop(); - const obj = swift.memory.getObject(objId); - swift.memory.release(objId); - const string = strStack.pop(); - dictResult[string] = obj; - } + const dictResult = __bjs_codec_Dict_M10TestModuleT24MyViewControllerDelegate.lift(); return dictResult; } set delegatesByName(value) { - const entries = Object.entries(value); - for (const entry of entries) { - const [key, value1] = entry; - const bytes = textEncoder.encode(key); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - const objId = swift.memory.retain(value1); - i32Stack.push(objId); - } - i32Stack.push(entries.length); + __bjs_codec_Dict_M10TestModuleT24MyViewControllerDelegate.lower(value); instance.exports.bjs_DelegateManager_delegatesByName_set(this.pointer); } } - const ResultHelpers = __bjs_createResultValuesHelpers(); - enumHelpers.Result = ResultHelpers; + const __bjs_helpers_M10TestModuleT6Result = __bjs_createEnumHelpers_M10TestModuleT6Result(); + enumHelpers.M10TestModuleT6Result = __bjs_helpers_M10TestModuleT6Result; const exports = { processDelegates: function bjs_processDelegates(delegates) { - for (const elem of delegates) { - const objId = swift.memory.retain(elem); - i32Stack.push(objId); - } - i32Stack.push(delegates.length); + __bjs_codec_Array_M10TestModuleT24MyViewControllerDelegate.lower(delegates); instance.exports.bjs_processDelegates(); - const arrayLen = i32Stack.pop(); - let arrayResult; - if (arrayLen === -1) { - arrayResult = taStack.pop(); - } else { - arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const objId1 = i32Stack.pop(); - const obj = swift.memory.getObject(objId1); - swift.memory.release(objId1); - arrayResult.push(obj); - } - arrayResult.reverse(); - } + const arrayResult = __bjs_codec_Array_M10TestModuleT24MyViewControllerDelegate.lift(); return arrayResult; }, processDelegatesByName: function bjs_processDelegatesByName(delegates) { - const entries = Object.entries(delegates); - for (const entry of entries) { - const [key, value] = entry; - const bytes = textEncoder.encode(key); - const id = swift.memory.retain(bytes); - i32Stack.push(bytes.length); - i32Stack.push(id); - const objId = swift.memory.retain(value); - i32Stack.push(objId); - } - i32Stack.push(entries.length); + __bjs_codec_Dict_M10TestModuleT24MyViewControllerDelegate.lower(delegates); instance.exports.bjs_processDelegatesByName(); - const dictLen = i32Stack.pop(); - const dictResult = {}; - for (let i = 0; i < dictLen; i++) { - const objId1 = i32Stack.pop(); - const obj = swift.memory.getObject(objId1); - swift.memory.release(objId1); - const string = strStack.pop(); - dictResult[string] = obj; - } + const dictResult = __bjs_codec_Dict_M10TestModuleT24MyViewControllerDelegate.lift(); return dictResult; }, Direction: DirectionValues, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ProtocolInClosure.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ProtocolInClosure.js index 01f9fe0e1..eed26c581 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ProtocolInClosure.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ProtocolInClosure.js @@ -131,6 +131,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.Global.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.Global.js index 25f989a00..f46f42d10 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.Global.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.Global.js @@ -42,7 +42,7 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createAPIResultValuesHelpers = () => ({ + const __bjs_createEnumHelpers_M10TestModuleT9APIResult = () => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { @@ -150,6 +150,8 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -351,8 +353,8 @@ export async function createInstantiator(options, swift) { return ret; } } - const APIResultHelpers = __bjs_createAPIResultValuesHelpers(); - enumHelpers.APIResult = APIResultHelpers; + const __bjs_helpers_M10TestModuleT9APIResult = __bjs_createEnumHelpers_M10TestModuleT9APIResult(); + enumHelpers.M10TestModuleT9APIResult = __bjs_helpers_M10TestModuleT9APIResult; if (typeof globalThis.Utils === 'undefined') { globalThis.Utils = {}; @@ -381,9 +383,9 @@ export async function createInstantiator(options, swift) { APIResult: { ...APIResultValues, roundtrip: function(value) { - const valueCaseId = enumHelpers.APIResult.lower(value); + const valueCaseId = enumHelpers.M10TestModuleT9APIResult.lower(value); instance.exports.bjs_APIResult_static_roundtrip(valueCaseId); - const ret = enumHelpers.APIResult.lift(i32Stack.pop()); + const ret = enumHelpers.M10TestModuleT9APIResult.lift(i32Stack.pop()); return ret; } }, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.js index ca4093992..37d3415a4 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.js @@ -42,7 +42,7 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createAPIResultValuesHelpers = () => ({ + const __bjs_createEnumHelpers_M10TestModuleT9APIResult = () => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { @@ -150,6 +150,8 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -351,8 +353,8 @@ export async function createInstantiator(options, swift) { return ret; } } - const APIResultHelpers = __bjs_createAPIResultValuesHelpers(); - enumHelpers.APIResult = APIResultHelpers; + const __bjs_helpers_M10TestModuleT9APIResult = __bjs_createEnumHelpers_M10TestModuleT9APIResult(); + enumHelpers.M10TestModuleT9APIResult = __bjs_helpers_M10TestModuleT9APIResult; const exports = { Calculator: { @@ -375,9 +377,9 @@ export async function createInstantiator(options, swift) { APIResult: { ...APIResultValues, roundtrip: function(value) { - const valueCaseId = enumHelpers.APIResult.lower(value); + const valueCaseId = enumHelpers.M10TestModuleT9APIResult.lower(value); instance.exports.bjs_APIResult_static_roundtrip(valueCaseId); - const ret = enumHelpers.APIResult.lift(i32Stack.pop()); + const ret = enumHelpers.M10TestModuleT9APIResult.lift(i32Stack.pop()); 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 63dd9cba5..e2a9093b6 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.Global.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.Global.js @@ -111,6 +111,8 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.js index b5680b9b0..f442745e5 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.js @@ -111,6 +111,8 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.js index 2c3da5f26..ebddbefd2 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.js @@ -107,6 +107,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.js index 057bf9658..d2dfa204f 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.js @@ -107,6 +107,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StructWithNestedTypes.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StructWithNestedTypes.js index ee5cc0a3e..9104e2084 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StructWithNestedTypes.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StructWithNestedTypes.js @@ -46,7 +46,7 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createShapeHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT5Shape = () => ({ lower: (value) => { const bytes = textEncoder.encode(value.label); const id = swift.memory.retain(bytes); @@ -58,7 +58,7 @@ export async function createInstantiator(options, swift) { return { label: string }; } }); - const __bjs_createWidgetHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT6Widget = () => ({ lower: (value) => { const bytes = textEncoder.encode(value.name); const id = swift.memory.retain(bytes); @@ -70,7 +70,7 @@ export async function createInstantiator(options, swift) { return { name: string }; } }); - const __bjs_createWidget_LayoutHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT6WidgetT6Layout = () => ({ lower: (value) => { i32Stack.push((value.padding | 0)); }, @@ -79,7 +79,7 @@ export async function createInstantiator(options, swift) { return { padding: int }; } }); - const __bjs_createWidget_BoundsHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT6WidgetT6Bounds = () => ({ lower: (value) => { i32Stack.push((value.width | 0)); i32Stack.push((value.height | 0)); @@ -166,33 +166,35 @@ export async function createInstantiator(options, swift) { taStack.push(Array.from(new Ctor(copy))); } bjs["swift_js_struct_lower_Shape"] = function(objectId) { - structHelpers.Shape.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT5Shape.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Shape"] = function() { - const value = structHelpers.Shape.lift(); + const value = structHelpers.M10TestModuleT5Shape.lift(); return swift.memory.retain(value); } bjs["swift_js_struct_lower_Widget"] = function(objectId) { - structHelpers.Widget.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT6Widget.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Widget"] = function() { - const value = structHelpers.Widget.lift(); + const value = structHelpers.M10TestModuleT6Widget.lift(); return swift.memory.retain(value); } bjs["swift_js_struct_lower_Widget_Layout"] = function(objectId) { - structHelpers.Widget_Layout.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT6WidgetT6Layout.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Widget_Layout"] = function() { - const value = structHelpers.Widget_Layout.lift(); + const value = structHelpers.M10TestModuleT6WidgetT6Layout.lift(); return swift.memory.retain(value); } bjs["swift_js_struct_lower_Widget_Bounds"] = function(objectId) { - structHelpers.Widget_Bounds.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT6WidgetT6Bounds.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Widget_Bounds"] = function() { - const value = structHelpers.Widget_Bounds.lift(); + const value = structHelpers.M10TestModuleT6WidgetT6Bounds.lift(); return swift.memory.retain(value); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -304,17 +306,17 @@ export async function createInstantiator(options, swift) { /** @param {WebAssembly.Instance} instance */ createExports: (instance) => { const js = swift.memory.heap; - const ShapeHelpers = __bjs_createShapeHelpers(); - structHelpers.Shape = ShapeHelpers; + const __bjs_helpers_M10TestModuleT5Shape = __bjs_createStructHelpers_M10TestModuleT5Shape(); + structHelpers.M10TestModuleT5Shape = __bjs_helpers_M10TestModuleT5Shape; - const WidgetHelpers = __bjs_createWidgetHelpers(); - structHelpers.Widget = WidgetHelpers; + const __bjs_helpers_M10TestModuleT6Widget = __bjs_createStructHelpers_M10TestModuleT6Widget(); + structHelpers.M10TestModuleT6Widget = __bjs_helpers_M10TestModuleT6Widget; - const Widget_LayoutHelpers = __bjs_createWidget_LayoutHelpers(); - structHelpers.Widget_Layout = Widget_LayoutHelpers; + const __bjs_helpers_M10TestModuleT6WidgetT6Layout = __bjs_createStructHelpers_M10TestModuleT6WidgetT6Layout(); + structHelpers.M10TestModuleT6WidgetT6Layout = __bjs_helpers_M10TestModuleT6WidgetT6Layout; - const Widget_BoundsHelpers = __bjs_createWidget_BoundsHelpers(); - structHelpers.Widget_Bounds = Widget_BoundsHelpers; + const __bjs_helpers_M10TestModuleT6WidgetT6Bounds = __bjs_createStructHelpers_M10TestModuleT6WidgetT6Bounds(); + structHelpers.M10TestModuleT6WidgetT6Bounds = __bjs_helpers_M10TestModuleT6WidgetT6Bounds; const exports = { Shape: { @@ -322,7 +324,7 @@ export async function createInstantiator(options, swift) { const labelBytes = textEncoder.encode(label); const labelId = swift.memory.retain(labelBytes); instance.exports.bjs_Shape_init(labelId, labelBytes.length); - const structValue = structHelpers.Shape.lift(); + const structValue = structHelpers.M10TestModuleT5Shape.lift(); return structValue; }, Kind: KindValues, @@ -332,14 +334,14 @@ export async function createInstantiator(options, swift) { const nameBytes = textEncoder.encode(name); const nameId = swift.memory.retain(nameBytes); instance.exports.bjs_Widget_init(nameId, nameBytes.length); - const structValue = structHelpers.Widget.lift(); + const structValue = structHelpers.M10TestModuleT6Widget.lift(); return structValue; }, Variant: VariantValues, Bounds: { init: function(width, height) { instance.exports.bjs_Widget_Bounds_init(width, height); - const structValue = structHelpers.Widget_Bounds.lift(); + const structValue = structHelpers.M10TestModuleT6WidgetT6Bounds.lift(); return structValue; }, get dimensions() { @@ -348,7 +350,7 @@ export async function createInstantiator(options, swift) { }, zero: function() { instance.exports.bjs_Widget_Bounds_static_zero(); - const structValue = structHelpers.Widget_Bounds.lift(); + const structValue = structHelpers.M10TestModuleT6WidgetT6Bounds.lift(); return structValue; }, }, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.js index be63f59be..92ef435fb 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.js @@ -107,6 +107,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosure.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosure.js index 62c2de8c6..279a9d3c6 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosure.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosure.js @@ -61,6 +61,240 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + function __bjs_jsValueLower(value) { let kind; let payload1; @@ -175,7 +409,18 @@ export async function createInstantiator(options, swift) { return swift.memory.retain(real); }; - const __bjs_createAnimalHelpers = () => ({ + const __bjs_codec_M10TestModuleT6Animal = { + lower: (v) => { + structHelpers.M10TestModuleT6Animal.lower(v); + }, + lift: () => { + const struct = structHelpers.M10TestModuleT6Animal.lift(); + return struct; + }, + }; + const __bjs_codec_Optional_M10TestModuleT6Animal = __bjs_optionalCodec(__bjs_codec_M10TestModuleT6Animal); + + const __bjs_createStructHelpers_M10TestModuleT6Animal = () => ({ lower: (value) => { const bytes = textEncoder.encode(value.type); const id = swift.memory.retain(bytes); @@ -187,7 +432,7 @@ export async function createInstantiator(options, swift) { return { type: string }; } }); - const __bjs_createAPIResultValuesHelpers = () => ({ + const __bjs_createEnumHelpers_M10TestModuleT9APIResult = () => ({ lower: (value) => { const enumTag = value.tag; switch (enumTag) { @@ -324,12 +569,14 @@ export async function createInstantiator(options, swift) { taStack.push(Array.from(new Ctor(copy))); } bjs["swift_js_struct_lower_Animal"] = function(objectId) { - structHelpers.Animal.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT6Animal.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Animal"] = function() { - const value = structHelpers.Animal.lift(); + const value = structHelpers.M10TestModuleT6Animal.lift(); return swift.memory.retain(value); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -347,7 +594,7 @@ export async function createInstantiator(options, swift) { } bjs["promise_resolve_TestModule_6AnimalV"] = function(promise) { try { - const structValue = structHelpers.Animal.lift(); + const structValue = structHelpers.M10TestModuleT6Animal.lift(); swift.memory.getObject(promise)[__bjs_promiseSettlers].resolve(structValue); } catch (error) { setException(error); @@ -355,7 +602,7 @@ export async function createInstantiator(options, swift) { } bjs["promise_resolve_TestModule_9APIResultO"] = function(promise, value) { try { - const enumValue = enumHelpers.APIResult.lift(value); + const enumValue = enumHelpers.M10TestModuleT9APIResult.lift(value); swift.memory.getObject(promise)[__bjs_promiseSettlers].resolve(enumValue); } catch (error) { setException(error); @@ -517,18 +764,18 @@ export async function createInstantiator(options, swift) { bjs["invoke_js_callback_TestModule_10TestModule6AnimalV_6AnimalV"] = function(callbackId) { try { const callback = swift.memory.getObject(callbackId); - const structValue = structHelpers.Animal.lift(); + const structValue = structHelpers.M10TestModuleT6Animal.lift(); let ret = callback(structValue); - structHelpers.Animal.lower(ret); + structHelpers.M10TestModuleT6Animal.lower(ret); } catch (error) { setException(error); } } bjs["make_swift_closure_TestModule_10TestModule6AnimalV_6AnimalV"] = function(boxPtr, file, line) { const lower_closure_TestModule_10TestModule6AnimalV_6AnimalV = function(param0) { - structHelpers.Animal.lower(param0); + structHelpers.M10TestModuleT6Animal.lower(param0); instance.exports.invoke_swift_closure_TestModule_10TestModule6AnimalV_6AnimalV(boxPtr); - const structValue = structHelpers.Animal.lift(); + const structValue = structHelpers.M10TestModuleT6Animal.lift(); if (tmpRetException) { const error = swift.memory.getObject(tmpRetException); swift.memory.release(tmpRetException); @@ -565,9 +812,9 @@ export async function createInstantiator(options, swift) { bjs["invoke_js_callback_TestModule_10TestModule9APIResultO_9APIResultO"] = function(callbackId, param0) { try { const callback = swift.memory.getObject(callbackId); - const enumValue = enumHelpers.APIResult.lift(param0); + const enumValue = enumHelpers.M10TestModuleT9APIResult.lift(param0); let ret = callback(enumValue); - const caseId = enumHelpers.APIResult.lower(ret); + const caseId = enumHelpers.M10TestModuleT9APIResult.lower(ret); return caseId; } catch (error) { setException(error); @@ -575,9 +822,9 @@ export async function createInstantiator(options, swift) { } bjs["make_swift_closure_TestModule_10TestModule9APIResultO_9APIResultO"] = function(boxPtr, file, line) { const lower_closure_TestModule_10TestModule9APIResultO_9APIResultO = function(param0) { - const param0CaseId = enumHelpers.APIResult.lower(param0); + const param0CaseId = enumHelpers.M10TestModuleT9APIResult.lower(param0); instance.exports.invoke_swift_closure_TestModule_10TestModule9APIResultO_9APIResultO(boxPtr, param0CaseId); - const ret = enumHelpers.APIResult.lift(i32Stack.pop()); + const ret = enumHelpers.M10TestModuleT9APIResult.lift(i32Stack.pop()); if (tmpRetException) { const error = swift.memory.getObject(tmpRetException); swift.memory.release(tmpRetException); @@ -852,43 +1099,28 @@ export async function createInstantiator(options, swift) { }; return makeClosure(boxPtr, file, line, lower_closure_TestModule_10TestModuleSq5ThemeO_Sq5ThemeO); } - bjs["invoke_js_callback_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV"] = function(callbackId, param0) { + bjs["invoke_js_callback_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV"] = function(callbackId) { try { const callback = swift.memory.getObject(callbackId); - let optResult; - if (param0) { - const struct = structHelpers.Animal.lift(); - optResult = struct; - } else { - optResult = null; - } - let ret = callback(optResult); - const isSome = ret != null; - if (isSome) { - structHelpers.Animal.lower(ret); - } - i32Stack.push(isSome ? 1 : 0); + const optValue = __bjs_codec_Optional_M10TestModuleT6Animal.lift(); + let ret = callback(optValue); + __bjs_codec_Optional_M10TestModuleT6Animal.lower(ret); } catch (error) { setException(error); } } bjs["make_swift_closure_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV"] = function(boxPtr, file, line) { const lower_closure_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV = function(param0) { - const isSome = param0 != null; - if (isSome) { - structHelpers.Animal.lower(param0); - } - i32Stack.push(+isSome); + __bjs_codec_Optional_M10TestModuleT6Animal.lower(param0); instance.exports.invoke_swift_closure_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV(boxPtr); - const isSome1 = i32Stack.pop(); - const optResult = isSome1 ? structHelpers.Animal.lift() : null; + const optValue = __bjs_codec_Optional_M10TestModuleT6Animal.lift(); if (tmpRetException) { const error = swift.memory.getObject(tmpRetException); swift.memory.release(tmpRetException); tmpRetException = undefined; throw error; } - return optResult; + return optValue; }; return makeClosure(boxPtr, file, line, lower_closure_TestModule_10TestModuleSq6AnimalV_Sq6AnimalV); } @@ -930,7 +1162,7 @@ export async function createInstantiator(options, swift) { const callback = swift.memory.getObject(callbackId); let optResult; if (param0IsSome) { - const enumValue = enumHelpers.APIResult.lift(param0CaseId); + const enumValue = enumHelpers.M10TestModuleT9APIResult.lift(param0CaseId); optResult = enumValue; } else { optResult = null; @@ -938,7 +1170,7 @@ export async function createInstantiator(options, swift) { let ret = callback(optResult); const isSome = ret != null; if (isSome) { - const caseId = enumHelpers.APIResult.lower(ret); + const caseId = enumHelpers.M10TestModuleT9APIResult.lower(ret); return caseId; } else { return -1; @@ -952,14 +1184,14 @@ export async function createInstantiator(options, swift) { const isSome = param0 != null; let result; if (isSome) { - const param0CaseId = enumHelpers.APIResult.lower(param0); + const param0CaseId = enumHelpers.M10TestModuleT9APIResult.lower(param0); result = param0CaseId; } else { result = 0; } instance.exports.invoke_swift_closure_TestModule_10TestModuleSq9APIResultO_Sq9APIResultO(boxPtr, +isSome, result); const tag = i32Stack.pop(); - const optResult = tag === -1 ? null : enumHelpers.APIResult.lift(tag); + const optResult = tag === -1 ? null : enumHelpers.M10TestModuleT9APIResult.lift(tag); if (tmpRetException) { const error = swift.memory.getObject(tmpRetException); swift.memory.release(tmpRetException); @@ -1227,7 +1459,7 @@ export async function createInstantiator(options, swift) { bjs["invoke_js_callback_TestModule_10TestModules6AnimalV_y"] = function(callbackId) { try { const callback = swift.memory.getObject(callbackId); - const structValue = structHelpers.Animal.lift(); + const structValue = structHelpers.M10TestModuleT6Animal.lift(); callback(structValue); } catch (error) { setException(error); @@ -1235,7 +1467,7 @@ export async function createInstantiator(options, swift) { } bjs["make_swift_closure_TestModule_10TestModules6AnimalV_y"] = function(boxPtr, file, line) { const lower_closure_TestModule_10TestModules6AnimalV_y = function(param0) { - structHelpers.Animal.lower(param0); + structHelpers.M10TestModuleT6Animal.lower(param0); instance.exports.invoke_swift_closure_TestModule_10TestModules6AnimalV_y(boxPtr); if (tmpRetException) { const error = swift.memory.getObject(tmpRetException); @@ -1271,7 +1503,7 @@ export async function createInstantiator(options, swift) { bjs["invoke_js_callback_TestModule_10TestModules9APIResultO_y"] = function(callbackId, param0) { try { const callback = swift.memory.getObject(callbackId); - const enumValue = enumHelpers.APIResult.lift(param0); + const enumValue = enumHelpers.M10TestModuleT9APIResult.lift(param0); callback(enumValue); } catch (error) { setException(error); @@ -1279,7 +1511,7 @@ export async function createInstantiator(options, swift) { } bjs["make_swift_closure_TestModule_10TestModules9APIResultO_y"] = function(boxPtr, file, line) { const lower_closure_TestModule_10TestModules9APIResultO_y = function(param0) { - const param0CaseId = enumHelpers.APIResult.lower(param0); + const param0CaseId = enumHelpers.M10TestModuleT9APIResult.lower(param0); instance.exports.invoke_swift_closure_TestModule_10TestModules9APIResultO_y(boxPtr, param0CaseId); if (tmpRetException) { const error = swift.memory.getObject(tmpRetException); @@ -1414,11 +1646,11 @@ export async function createInstantiator(options, swift) { return TestProcessor.__construct(ret); } } - const AnimalHelpers = __bjs_createAnimalHelpers(); - structHelpers.Animal = AnimalHelpers; + const __bjs_helpers_M10TestModuleT6Animal = __bjs_createStructHelpers_M10TestModuleT6Animal(); + structHelpers.M10TestModuleT6Animal = __bjs_helpers_M10TestModuleT6Animal; - const APIResultHelpers = __bjs_createAPIResultValuesHelpers(); - enumHelpers.APIResult = APIResultHelpers; + const __bjs_helpers_M10TestModuleT9APIResult = __bjs_createEnumHelpers_M10TestModuleT9APIResult(); + enumHelpers.M10TestModuleT9APIResult = __bjs_helpers_M10TestModuleT9APIResult; const exports = { roundtripAnimal: function bjs_roundtripAnimal(animalClosure) { @@ -1569,7 +1801,7 @@ export async function createInstantiator(options, swift) { const typeBytes = textEncoder.encode(type); const typeId = swift.memory.retain(typeBytes); instance.exports.bjs_Animal_init(typeId, typeBytes.length); - const structValue = structHelpers.Animal.lift(); + const structValue = structHelpers.M10TestModuleT6Animal.lift(); return structValue; }, }, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosureImports.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosureImports.js index d03915f87..96c78dd22 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosureImports.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosureImports.js @@ -221,6 +221,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStruct.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStruct.js index 92a99becb..fc3d9ddbb 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStruct.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStruct.js @@ -36,7 +36,357 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createDataPointHelpers = () => ({ + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + + function __bjs_jsValueLower(value) { + let kind; + let payload1; + let payload2; + if (value === null) { + kind = 4; + payload1 = 0; + payload2 = 0; + } else { + switch (typeof value) { + case "boolean": + kind = 0; + payload1 = value ? 1 : 0; + payload2 = 0; + break; + case "number": + kind = 2; + payload1 = 0; + payload2 = value; + break; + case "string": + kind = 1; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "undefined": + kind = 5; + payload1 = 0; + payload2 = 0; + break; + case "object": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "function": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "symbol": + kind = 7; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "bigint": + kind = 8; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + default: + throw new TypeError("Unsupported JSValue type"); + } + } + return [kind, payload1, payload2]; + } + function __bjs_jsValueLift(kind, payload1, payload2) { + let jsValue; + switch (kind) { + case 0: + jsValue = payload1 !== 0; + break; + case 1: + jsValue = swift.memory.getObject(payload1); + break; + case 2: + jsValue = payload2; + break; + case 3: + jsValue = swift.memory.getObject(payload1); + break; + case 4: + jsValue = null; + break; + case 5: + jsValue = undefined; + break; + case 7: + jsValue = swift.memory.getObject(payload1); + break; + case 8: + jsValue = swift.memory.getObject(payload1); + break; + default: + throw new TypeError("Unsupported JSValue kind " + kind); + } + return jsValue; + } + + const __bjs_codec_Optional_Int = __bjs_optionalCodec(__bjs_primitiveCodecs.Int); + const __bjs_codec_Optional_Bool = __bjs_optionalCodec(__bjs_primitiveCodecs.Bool); + const __bjs_codec_Optional_String = __bjs_optionalCodec(__bjs_stringCodec); + const __bjs_codec_M10TestModuleT9Precision = { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const rawValue = f32Stack.pop(); + return rawValue; + }, + }; + const __bjs_codec_Optional_M10TestModuleT9Precision = __bjs_optionalCodec(__bjs_codec_M10TestModuleT9Precision); + const __bjs_codec_JSObject = { + lower: (v) => { + const objId = swift.memory.retain(v); + i32Stack.push(objId); + }, + lift: () => { + const objId = i32Stack.pop(); + const obj = swift.memory.getObject(objId); + swift.memory.release(objId); + return obj; + }, + }; + const __bjs_codec_Optional_JSObject = __bjs_optionalCodec(__bjs_codec_JSObject); + + const __bjs_createStructHelpers_M10TestModuleT9DataPoint = () => ({ lower: (value) => { f64Stack.push(value.x); f64Stack.push(value.y); @@ -44,41 +394,19 @@ export async function createInstantiator(options, swift) { const id = swift.memory.retain(bytes); i32Stack.push(bytes.length); i32Stack.push(id); - const isSome = value.optCount != null ? 1 : 0; - if (isSome) { - i32Stack.push((value.optCount | 0)); - } - i32Stack.push(isSome); - const isSome1 = value.optFlag != null ? 1 : 0; - if (isSome1) { - i32Stack.push(value.optFlag ? 1 : 0); - } - i32Stack.push(isSome1); + __bjs_codec_Optional_Int.lower(value.optCount); + __bjs_codec_Optional_Bool.lower(value.optFlag); }, lift: () => { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const bool = i32Stack.pop() !== 0; - optValue = bool; - } - const isSome1 = i32Stack.pop(); - let optValue1; - if (isSome1 === 0) { - optValue1 = null; - } else { - const int = i32Stack.pop(); - optValue1 = int; - } + const optValue = __bjs_codec_Optional_Bool.lift(); + const optValue1 = __bjs_codec_Optional_Int.lift(); const string = strStack.pop(); const f64 = f64Stack.pop(); const f641 = f64Stack.pop(); return { x: f641, y: f64, label: string, optCount: optValue1, optFlag: optValue }; } }); - const __bjs_createAddressHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT7Address = () => ({ lower: (value) => { const bytes = textEncoder.encode(value.street); const id = swift.memory.retain(bytes); @@ -88,59 +416,34 @@ export async function createInstantiator(options, swift) { const id1 = swift.memory.retain(bytes1); i32Stack.push(bytes1.length); i32Stack.push(id1); - const isSome = value.zipCode != null ? 1 : 0; - if (isSome) { - i32Stack.push((value.zipCode | 0)); - } - i32Stack.push(isSome); + __bjs_codec_Optional_Int.lower(value.zipCode); }, lift: () => { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const int = i32Stack.pop(); - optValue = int; - } + const optValue = __bjs_codec_Optional_Int.lift(); const string = strStack.pop(); const string1 = strStack.pop(); return { street: string1, city: string, zipCode: optValue }; } }); - const __bjs_createPersonHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT6Person = () => ({ lower: (value) => { const bytes = textEncoder.encode(value.name); const id = swift.memory.retain(bytes); i32Stack.push(bytes.length); i32Stack.push(id); i32Stack.push((value.age | 0)); - structHelpers.Address.lower(value.address); - const isSome = value.email != null ? 1 : 0; - if (isSome) { - const bytes1 = textEncoder.encode(value.email); - const id1 = swift.memory.retain(bytes1); - i32Stack.push(bytes1.length); - i32Stack.push(id1); - } - i32Stack.push(isSome); + structHelpers.M10TestModuleT7Address.lower(value.address); + __bjs_codec_Optional_String.lower(value.email); }, lift: () => { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const string = strStack.pop(); - optValue = string; - } - const struct = structHelpers.Address.lift(); + const optValue = __bjs_codec_Optional_String.lift(); + const struct = structHelpers.M10TestModuleT7Address.lift(); const int = i32Stack.pop(); - const string1 = strStack.pop(); - return { name: string1, age: int, address: struct, email: optValue }; + const string = strStack.pop(); + return { name: string, age: int, address: struct, email: optValue }; } }); - const __bjs_createSessionHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT7Session = () => ({ lower: (value) => { i32Stack.push((value.id | 0)); ptrStack.push(value.owner.pointer); @@ -152,38 +455,27 @@ export async function createInstantiator(options, swift) { return { id: int, owner: obj }; } }); - const __bjs_createMeasurementHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT11Measurement = () => ({ lower: (value) => { f64Stack.push(value.value); f32Stack.push(Math.fround(value.precision)); - const isSome = value.optionalPrecision != null ? 1 : 0; - if (isSome) { - f32Stack.push(Math.fround(value.optionalPrecision)); - } - i32Stack.push(isSome); + __bjs_codec_Optional_M10TestModuleT9Precision.lower(value.optionalPrecision); }, lift: () => { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const rawValue = f32Stack.pop(); - optValue = rawValue; - } - const rawValue1 = f32Stack.pop(); + const optValue = __bjs_codec_Optional_M10TestModuleT9Precision.lift(); + const rawValue = f32Stack.pop(); const f64 = f64Stack.pop(); - return { value: f64, precision: rawValue1, optionalPrecision: optValue }; + return { value: f64, precision: rawValue, optionalPrecision: optValue }; } }); - const __bjs_createConfigStructHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT12ConfigStruct = () => ({ lower: (value) => { }, lift: () => { return { }; } }); - const __bjs_createContainerHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT9Container = () => ({ lower: (value) => { let id; if (value.object != null) { @@ -192,24 +484,10 @@ export async function createInstantiator(options, swift) { id = undefined; } i32Stack.push(id !== undefined ? id : 0); - const isSome = value.optionalObject != null ? 1 : 0; - if (isSome) { - const objId = swift.memory.retain(value.optionalObject); - i32Stack.push(objId); - } - i32Stack.push(isSome); + __bjs_codec_Optional_JSObject.lower(value.optionalObject); }, lift: () => { - const isSome = i32Stack.pop(); - let optValue; - if (isSome === 0) { - optValue = null; - } else { - const objId = i32Stack.pop(); - const obj = swift.memory.getObject(objId); - swift.memory.release(objId); - optValue = obj; - } + const optValue = __bjs_codec_Optional_JSObject.lift(); const objectId = i32Stack.pop(); let value; if (objectId !== 0) { @@ -221,7 +499,7 @@ export async function createInstantiator(options, swift) { return { object: value, optionalObject: optValue }; } }); - const __bjs_createVector2DHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT8Vector2D = () => ({ lower: (value) => { f64Stack.push(value.dx); f64Stack.push(value.dy); @@ -231,18 +509,18 @@ export async function createInstantiator(options, swift) { const f641 = f64Stack.pop(); const instance1 = { dx: f641, dy: f64 }; instance1.magnitude = function() { - structHelpers.Vector2D.lower(this); + structHelpers.M10TestModuleT8Vector2D.lower(this); const ret = instance.exports.bjs_Vector2D_magnitude(); return ret; }.bind(instance1); instance1.scaled = function(factor) { - structHelpers.Vector2D.lower(this); + structHelpers.M10TestModuleT8Vector2D.lower(this); const ret1 = instance.exports.bjs_Vector2D_scaled(factor); - const structValue = structHelpers.Vector2D.lift(); + const structValue = structHelpers.M10TestModuleT8Vector2D.lift(); return structValue; }.bind(instance1); instance1.describe = function() { - structHelpers.Vector2D.lower(this); + structHelpers.M10TestModuleT8Vector2D.lower(this); const ret2 = instance.exports.bjs_Vector2D_describe(); const ret3 = tmpRetString; tmpRetString = undefined; @@ -327,61 +605,63 @@ export async function createInstantiator(options, swift) { taStack.push(Array.from(new Ctor(copy))); } bjs["swift_js_struct_lower_DataPoint"] = function(objectId) { - structHelpers.DataPoint.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT9DataPoint.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_DataPoint"] = function() { - const value = structHelpers.DataPoint.lift(); + const value = structHelpers.M10TestModuleT9DataPoint.lift(); return swift.memory.retain(value); } bjs["swift_js_struct_lower_Address"] = function(objectId) { - structHelpers.Address.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT7Address.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Address"] = function() { - const value = structHelpers.Address.lift(); + const value = structHelpers.M10TestModuleT7Address.lift(); return swift.memory.retain(value); } bjs["swift_js_struct_lower_Person"] = function(objectId) { - structHelpers.Person.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT6Person.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Person"] = function() { - const value = structHelpers.Person.lift(); + const value = structHelpers.M10TestModuleT6Person.lift(); return swift.memory.retain(value); } bjs["swift_js_struct_lower_Session"] = function(objectId) { - structHelpers.Session.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT7Session.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Session"] = function() { - const value = structHelpers.Session.lift(); + const value = structHelpers.M10TestModuleT7Session.lift(); return swift.memory.retain(value); } bjs["swift_js_struct_lower_Measurement"] = function(objectId) { - structHelpers.Measurement.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT11Measurement.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Measurement"] = function() { - const value = structHelpers.Measurement.lift(); + const value = structHelpers.M10TestModuleT11Measurement.lift(); return swift.memory.retain(value); } bjs["swift_js_struct_lower_ConfigStruct"] = function(objectId) { - structHelpers.ConfigStruct.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT12ConfigStruct.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_ConfigStruct"] = function() { - const value = structHelpers.ConfigStruct.lift(); + const value = structHelpers.M10TestModuleT12ConfigStruct.lift(); return swift.memory.retain(value); } bjs["swift_js_struct_lower_Container"] = function(objectId) { - structHelpers.Container.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT9Container.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Container"] = function() { - const value = structHelpers.Container.lift(); + const value = structHelpers.M10TestModuleT9Container.lift(); return swift.memory.retain(value); } bjs["swift_js_struct_lower_Vector2D"] = function(objectId) { - structHelpers.Vector2D.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT8Vector2D.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Vector2D"] = function() { - const value = structHelpers.Vector2D.lift(); + const value = structHelpers.M10TestModuleT8Vector2D.lift(); return swift.memory.retain(value); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -582,41 +862,41 @@ export async function createInstantiator(options, swift) { instance.exports.bjs_Greeter_name_set(this.pointer, valueId, valueBytes.length); } } - const DataPointHelpers = __bjs_createDataPointHelpers(); - structHelpers.DataPoint = DataPointHelpers; + const __bjs_helpers_M10TestModuleT9DataPoint = __bjs_createStructHelpers_M10TestModuleT9DataPoint(); + structHelpers.M10TestModuleT9DataPoint = __bjs_helpers_M10TestModuleT9DataPoint; - const AddressHelpers = __bjs_createAddressHelpers(); - structHelpers.Address = AddressHelpers; + const __bjs_helpers_M10TestModuleT7Address = __bjs_createStructHelpers_M10TestModuleT7Address(); + structHelpers.M10TestModuleT7Address = __bjs_helpers_M10TestModuleT7Address; - const PersonHelpers = __bjs_createPersonHelpers(); - structHelpers.Person = PersonHelpers; + const __bjs_helpers_M10TestModuleT6Person = __bjs_createStructHelpers_M10TestModuleT6Person(); + structHelpers.M10TestModuleT6Person = __bjs_helpers_M10TestModuleT6Person; - const SessionHelpers = __bjs_createSessionHelpers(); - structHelpers.Session = SessionHelpers; + const __bjs_helpers_M10TestModuleT7Session = __bjs_createStructHelpers_M10TestModuleT7Session(); + structHelpers.M10TestModuleT7Session = __bjs_helpers_M10TestModuleT7Session; - const MeasurementHelpers = __bjs_createMeasurementHelpers(); - structHelpers.Measurement = MeasurementHelpers; + const __bjs_helpers_M10TestModuleT11Measurement = __bjs_createStructHelpers_M10TestModuleT11Measurement(); + structHelpers.M10TestModuleT11Measurement = __bjs_helpers_M10TestModuleT11Measurement; - const ConfigStructHelpers = __bjs_createConfigStructHelpers(); - structHelpers.ConfigStruct = ConfigStructHelpers; + const __bjs_helpers_M10TestModuleT12ConfigStruct = __bjs_createStructHelpers_M10TestModuleT12ConfigStruct(); + structHelpers.M10TestModuleT12ConfigStruct = __bjs_helpers_M10TestModuleT12ConfigStruct; - const ContainerHelpers = __bjs_createContainerHelpers(); - structHelpers.Container = ContainerHelpers; + const __bjs_helpers_M10TestModuleT9Container = __bjs_createStructHelpers_M10TestModuleT9Container(); + structHelpers.M10TestModuleT9Container = __bjs_helpers_M10TestModuleT9Container; - const Vector2DHelpers = __bjs_createVector2DHelpers(); - structHelpers.Vector2D = Vector2DHelpers; + const __bjs_helpers_M10TestModuleT8Vector2D = __bjs_createStructHelpers_M10TestModuleT8Vector2D(); + structHelpers.M10TestModuleT8Vector2D = __bjs_helpers_M10TestModuleT8Vector2D; const exports = { roundtrip: function bjs_roundtrip(session) { - structHelpers.Person.lower(session); + structHelpers.M10TestModuleT6Person.lower(session); instance.exports.bjs_roundtrip(); - const structValue = structHelpers.Person.lift(); + const structValue = structHelpers.M10TestModuleT6Person.lift(); return structValue; }, roundtripContainer: function bjs_roundtripContainer(container) { - structHelpers.Container.lower(container); + structHelpers.M10TestModuleT9Container.lower(container); instance.exports.bjs_roundtripContainer(); - const structValue = structHelpers.Container.lift(); + const structValue = structHelpers.M10TestModuleT9Container.lift(); return structValue; }, Precision: PrecisionValues, @@ -661,7 +941,7 @@ export async function createInstantiator(options, swift) { const isSome = optCount != null; const isSome1 = optFlag != null; instance.exports.bjs_DataPoint_init(x, y, labelId, labelBytes.length, +isSome, isSome ? optCount : 0, +isSome1, isSome1 ? optFlag ? 1 : 0 : 0); - const structValue = structHelpers.DataPoint.lift(); + const structValue = structHelpers.M10TestModuleT9DataPoint.lift(); return structValue; }, get dimensions() { @@ -670,7 +950,7 @@ export async function createInstantiator(options, swift) { }, origin: function() { instance.exports.bjs_DataPoint_static_origin(); - const structValue = structHelpers.DataPoint.lift(); + const structValue = structHelpers.M10TestModuleT9DataPoint.lift(); return structValue; }, }, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStructImports.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStructImports.js index 4a2e18d6b..134d7c28e 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStructImports.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStructImports.js @@ -31,7 +31,341 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createPointHelpers = () => ({ + const __bjs_arrayCodecCache = new WeakMap(); + function __bjs_arrayCodec(elementCodec) { + let codec = __bjs_arrayCodecCache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + for (let i = 0; i < value.length; i++) { + elementCodec.lower(value[i]); + } + i32Stack.push(value.length); + }, + lift() { + const count = i32Stack.pop(); + if (count === -1) { + return taStack.pop(); + } + const result = new Array(count); + for (let i = count - 1; i >= 0; i--) { + result[i] = elementCodec.lift(); + } + return result; + }, + }; + __bjs_arrayCodecCache.set(elementCodec, codec); + return codec; + } + const __bjs_optionalCodecCache = new WeakMap(); + const __bjs_optionalCodecUndefinedOrCache = new WeakMap(); + function __bjs_optionalCodec(elementCodec, isUndefinedOr = false) { + const cache = isUndefinedOr ? __bjs_optionalCodecUndefinedOrCache : __bjs_optionalCodecCache; + let codec = cache.get(elementCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const isSome = isUndefinedOr ? value !== undefined : value != null; + if (isSome) { + elementCodec.lower(value); + i32Stack.push(1); + } else { + i32Stack.push(0); + } + }, + lift() { + if (i32Stack.pop() === 0) { + return isUndefinedOr ? undefined : null; + } + return elementCodec.lift(); + }, + }; + cache.set(elementCodec, codec); + return codec; + } + const __bjs_dictCodecCache = new WeakMap(); + function __bjs_dictCodec(valueCodec) { + let codec = __bjs_dictCodecCache.get(valueCodec); + if (codec !== undefined) { + return codec; + } + codec = { + lower(value) { + const keys = Object.keys(value); + for (let i = 0; i < keys.length; i++) { + __bjs_stringCodec.lower(keys[i]); + valueCodec.lower(value[keys[i]]); + } + i32Stack.push(keys.length); + }, + lift() { + const count = i32Stack.pop(); + const result = {}; + for (let i = 0; i < count; i++) { + const value = valueCodec.lift(); + const key = __bjs_stringCodec.lift(); + result[key] = value; + } + return result; + }, + }; + __bjs_dictCodecCache.set(valueCodec, codec); + return codec; + } + + const __bjs_stringCodec = { + lower: (v) => { + const bytes = textEncoder.encode(v); + const id = swift.memory.retain(bytes); + i32Stack.push(bytes.length); + i32Stack.push(id); + }, + lift: () => { + const string = strStack.pop(); + return string; + }, + }; + const __bjs_primitiveCodecs = { + Bool: { + lower: (v) => { + i32Stack.push(v ? 1 : 0); + }, + lift: () => { + const bool = i32Stack.pop() !== 0; + return bool; + }, + }, + Int: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + Int8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt8: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt16: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop(); + return int; + }, + }, + UInt32: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + UInt: { + lower: (v) => { + i32Stack.push((v | 0)); + }, + lift: () => { + const int = i32Stack.pop() >>> 0; + return int; + }, + }, + Int64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + UInt64: { + lower: (v) => { + i64Stack.push(v); + }, + lift: () => { + const int = i64Stack.pop(); + return int; + }, + }, + Float: { + lower: (v) => { + f32Stack.push(Math.fround(v)); + }, + lift: () => { + const f32 = f32Stack.pop(); + return f32; + }, + }, + Double: { + lower: (v) => { + f64Stack.push(v); + }, + lift: () => { + const f64 = f64Stack.pop(); + return f64; + }, + }, + String: __bjs_stringCodec, + JSValue: { + lower: (v) => { + const [vKind, vPayload1, vPayload2] = __bjs_jsValueLower(v); + i32Stack.push(vKind); + i32Stack.push(vPayload1); + f64Stack.push(vPayload2); + }, + lift: () => { + const jsValuePayload2 = f64Stack.pop(); + const jsValuePayload1 = i32Stack.pop(); + const jsValueKind = i32Stack.pop(); + const jsValue = __bjs_jsValueLift(jsValueKind, jsValuePayload1, jsValuePayload2); + return jsValue; + }, + }, + }; + + function __bjs_jsValueLower(value) { + let kind; + let payload1; + let payload2; + if (value === null) { + kind = 4; + payload1 = 0; + payload2 = 0; + } else { + switch (typeof value) { + case "boolean": + kind = 0; + payload1 = value ? 1 : 0; + payload2 = 0; + break; + case "number": + kind = 2; + payload1 = 0; + payload2 = value; + break; + case "string": + kind = 1; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "undefined": + kind = 5; + payload1 = 0; + payload2 = 0; + break; + case "object": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "function": + kind = 3; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "symbol": + kind = 7; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + case "bigint": + kind = 8; + payload1 = swift.memory.retain(value); + payload2 = 0; + break; + default: + throw new TypeError("Unsupported JSValue type"); + } + } + return [kind, payload1, payload2]; + } + function __bjs_jsValueLift(kind, payload1, payload2) { + let jsValue; + switch (kind) { + case 0: + jsValue = payload1 !== 0; + break; + case 1: + jsValue = swift.memory.getObject(payload1); + break; + case 2: + jsValue = payload2; + break; + case 3: + jsValue = swift.memory.getObject(payload1); + break; + case 4: + jsValue = null; + break; + case 5: + jsValue = undefined; + break; + case 7: + jsValue = swift.memory.getObject(payload1); + break; + case 8: + jsValue = swift.memory.getObject(payload1); + break; + default: + throw new TypeError("Unsupported JSValue kind " + kind); + } + return jsValue; + } + + const __bjs_codec_M10TestModuleT5Point = { + lower: (v) => { + structHelpers.M10TestModuleT5Point.lower(v); + }, + lift: () => { + const struct = structHelpers.M10TestModuleT5Point.lift(); + return struct; + }, + }; + const __bjs_codec_Optional_M10TestModuleT5Point = __bjs_optionalCodec(__bjs_codec_M10TestModuleT5Point); + + const __bjs_createStructHelpers_M10TestModuleT5Point = () => ({ lower: (value) => { i32Stack.push((value.x | 0)); i32Stack.push((value.y | 0)); @@ -119,12 +453,14 @@ export async function createInstantiator(options, swift) { taStack.push(Array.from(new Ctor(copy))); } bjs["swift_js_struct_lower_Point"] = function(objectId) { - structHelpers.Point.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT5Point.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_Point"] = function() { - const value = structHelpers.Point.lift(); + const value = structHelpers.M10TestModuleT5Point.lift(); return swift.memory.retain(value); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -225,28 +561,18 @@ export async function createInstantiator(options, swift) { const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_translate"] = function bjs_translate(dx, dy) { try { - const structValue = structHelpers.Point.lift(); + const structValue = structHelpers.M10TestModuleT5Point.lift(); let ret = imports.translate(structValue, dx, dy); - structHelpers.Point.lower(ret); + structHelpers.M10TestModuleT5Point.lower(ret); } catch (error) { setException(error); } } - TestModule["bjs_roundTripOptional"] = function bjs_roundTripOptional(point) { + TestModule["bjs_roundTripOptional"] = function bjs_roundTripOptional() { try { - let optResult; - if (point) { - const struct = structHelpers.Point.lift(); - optResult = struct; - } else { - optResult = null; - } - let ret = imports.roundTripOptional(optResult); - const isSome = ret != null; - if (isSome) { - structHelpers.Point.lower(ret); - } - i32Stack.push(isSome ? 1 : 0); + const optValue = __bjs_codec_Optional_M10TestModuleT5Point.lift(); + let ret = imports.roundTripOptional(optValue); + __bjs_codec_Optional_M10TestModuleT5Point.lower(ret); } catch (error) { setException(error); } @@ -265,8 +591,8 @@ export async function createInstantiator(options, swift) { /** @param {WebAssembly.Instance} instance */ createExports: (instance) => { const js = swift.memory.heap; - const PointHelpers = __bjs_createPointHelpers(); - structHelpers.Point = PointHelpers; + const __bjs_helpers_M10TestModuleT5Point = __bjs_createStructHelpers_M10TestModuleT5Point(); + structHelpers.M10TestModuleT5Point = __bjs_helpers_M10TestModuleT5Point; const exports = { }; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftTypedClosureAccess.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftTypedClosureAccess.js index 66d6494fd..500a005a3 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftTypedClosureAccess.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftTypedClosureAccess.js @@ -131,6 +131,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Throws.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Throws.js index 6ff126525..58ff6a85a 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Throws.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Throws.js @@ -106,6 +106,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/UnsafePointer.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/UnsafePointer.js index 457bfa973..416e5c281 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/UnsafePointer.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/UnsafePointer.js @@ -31,7 +31,7 @@ export async function createInstantiator(options, swift) { let _exports = null; let bjs = null; - const __bjs_createPointerFieldsHelpers = () => ({ + const __bjs_createStructHelpers_M10TestModuleT13PointerFields = () => ({ lower: (value) => { ptrStack.push((value.raw | 0)); ptrStack.push((value.mutRaw | 0)); @@ -124,12 +124,14 @@ export async function createInstantiator(options, swift) { taStack.push(Array.from(new Ctor(copy))); } bjs["swift_js_struct_lower_PointerFields"] = function(objectId) { - structHelpers.PointerFields.lower(swift.memory.getObject(objectId)); + structHelpers.M10TestModuleT13PointerFields.lower(swift.memory.getObject(objectId)); } bjs["swift_js_struct_lift_PointerFields"] = function() { - const value = structHelpers.PointerFields.lift(); + const value = structHelpers.M10TestModuleT13PointerFields.lift(); return swift.memory.retain(value); } + bjs["bjs_core_register_type_handles"] = function() {}; + bjs["bjs_TestModule_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; @@ -241,8 +243,8 @@ export async function createInstantiator(options, swift) { /** @param {WebAssembly.Instance} instance */ createExports: (instance) => { const js = swift.memory.heap; - const PointerFieldsHelpers = __bjs_createPointerFieldsHelpers(); - structHelpers.PointerFields = PointerFieldsHelpers; + const __bjs_helpers_M10TestModuleT13PointerFields = __bjs_createStructHelpers_M10TestModuleT13PointerFields(); + structHelpers.M10TestModuleT13PointerFields = __bjs_helpers_M10TestModuleT13PointerFields; const exports = { takeUnsafeRawPointer: function bjs_takeUnsafeRawPointer(p) { @@ -281,15 +283,15 @@ export async function createInstantiator(options, swift) { return ret; }, roundTripPointerFields: function bjs_roundTripPointerFields(value) { - structHelpers.PointerFields.lower(value); + structHelpers.M10TestModuleT13PointerFields.lower(value); instance.exports.bjs_roundTripPointerFields(); - const structValue = structHelpers.PointerFields.lift(); + const structValue = structHelpers.M10TestModuleT13PointerFields.lift(); return structValue; }, PointerFields: { init: function(raw, mutRaw, opaque, ptr, mutPtr) { instance.exports.bjs_PointerFields_init(raw, mutRaw, opaque, ptr, mutPtr); - const structValue = structHelpers.PointerFields.lift(); + const structValue = structHelpers.M10TestModuleT13PointerFields.lift(); return structValue; }, }, diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.js index 3c75771c5..81b09eaf4 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.js @@ -107,6 +107,7 @@ export async function createInstantiator(options, swift) { const copy = memory.buffer.slice(ptr, ptr + byteLen); taStack.push(Array.from(new Ctor(copy))); } + bjs["bjs_core_register_type_handles"] = function() {}; const __bjs_promiseSettlers = Symbol("JavaScriptKit.promiseSettlers"); bjs["swift_js_make_promise"] = function() { let resolve, reject; diff --git a/Plugins/PackageToJS/Templates/instantiate.js b/Plugins/PackageToJS/Templates/instantiate.js index 36d840099..7ceafe715 100644 --- a/Plugins/PackageToJS/Templates/instantiate.js +++ b/Plugins/PackageToJS/Templates/instantiate.js @@ -70,6 +70,7 @@ async function createInstantiator(options, swift) { swift_js_closure_unregister: unexpectedBjsCall, swift_js_push_typed_array: unexpectedBjsCall, swift_js_make_promise: unexpectedBjsCall, + bjs_core_register_type_handles: unexpectedBjsCall, }; }, /** @param {WebAssembly.Instance} instance */ @@ -84,7 +85,7 @@ async function createInstantiator(options, swift) { /** @type {import('./instantiate.d').instantiate} */ export async function instantiate(options) { - const result = await _instantiate(options); + const { instantiator, ...result } = await _instantiate(options); /* #if IS_WASI */ options.wasi.initialize(result.instance); /* #endif */ @@ -94,7 +95,7 @@ export async function instantiate(options) { /** @type {import('./instantiate.d').instantiateForThread} */ export async function instantiateForThread(tid, startArg, options) { - const result = await _instantiate(options); + const { instantiator, ...result } = await _instantiate(options); /* #if IS_WASI */ options.wasi.setInstance(result.instance); /* #endif */ @@ -102,7 +103,7 @@ export async function instantiateForThread(tid, startArg, options) { return result; } -/** @type {import('./instantiate.d').instantiate} */ +/** @param {import('./instantiate.d').InstantiateOptions} options */ async function _instantiate(options) { const _WebAssembly = options.WebAssembly || WebAssembly; const moduleSource = options.module; @@ -184,5 +185,6 @@ async function _instantiate(options) { instance, swift, exports, + instantiator, }; } diff --git a/Sources/JavaScriptKit/BridgeJSIntrinsics.swift b/Sources/JavaScriptKit/BridgeJSIntrinsics.swift index 4eeae4dac..ab0a9f4f0 100644 --- a/Sources/JavaScriptKit/BridgeJSIntrinsics.swift +++ b/Sources/JavaScriptKit/BridgeJSIntrinsics.swift @@ -204,6 +204,45 @@ extension _BridgedSwiftStackType { } } +/// A type usable as a generic argument of an imported `@JSFunction`. +public protocol BridgedSwiftGenericBridgeable: _BridgedSwiftStackType +where StackLiftResult == Self { + @_spi(BridgeJS) static var bridgeJSTypeHandle: BridgeJSTypeHandle { get } +} + +extension BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static var bridgeJSTypeID: Int32 { bridgeJSTypeHandle.typeID } + + @_spi(BridgeJS) public static func bridgeJSMakeTypeHandle() -> BridgeJSTypeHandle { + #if hasFeature(Embedded) + return BridgeJSTypeHandle() + #else + return BridgeJSTypeHandle(Self.self) + #endif + } +} + +/// A per-type identity token for generic bridging. +public final class BridgeJSTypeHandle: Sendable { + #if hasFeature(Embedded) + public init() {} + #else + public nonisolated(unsafe) let type: any BridgedSwiftGenericBridgeable.Type + + public init(_ type: any BridgedSwiftGenericBridgeable.Type) { + self.type = type + } + #endif + + @_spi(BridgeJS) public var typeID: Int32 { + #if arch(wasm32) + return Int32(bitPattern: UInt32(UInt(bitPattern: Unmanaged.passUnretained(self).toOpaque()))) + #else + _onlyAvailableOnWasm() + #endif + } +} + /// Types that bridge with the same (isSome, value) ABI as Optional. /// Used by JSUndefinedOr so all bridge methods delegate to Optional. public protocol _BridgedAsOptional { @@ -808,6 +847,49 @@ extension String: _BridgedSwiftStackType { } } +extension Bool: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Bool.bridgeJSMakeTypeHandle() +} +extension Int: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Int.bridgeJSMakeTypeHandle() +} +extension Float: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Float.bridgeJSMakeTypeHandle() +} +extension Double: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Double.bridgeJSMakeTypeHandle() +} +extension String: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = String.bridgeJSMakeTypeHandle() +} +extension UInt: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = UInt.bridgeJSMakeTypeHandle() +} +extension Int8: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Int8.bridgeJSMakeTypeHandle() +} +extension UInt8: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = UInt8.bridgeJSMakeTypeHandle() +} +extension Int16: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Int16.bridgeJSMakeTypeHandle() +} +extension UInt16: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = UInt16.bridgeJSMakeTypeHandle() +} +extension Int32: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Int32.bridgeJSMakeTypeHandle() +} +extension UInt32: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = UInt32.bridgeJSMakeTypeHandle() +} +extension Int64: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Int64.bridgeJSMakeTypeHandle() +} +extension UInt64: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = UInt64.bridgeJSMakeTypeHandle() +} + extension JSObject: _BridgedSwiftStackType { // JSObject is a non-final class, so we must explicitly specify the associated type // rather than relying on the default `Self` (which Swift requires for covariant returns). @@ -914,6 +996,42 @@ extension JSValue: _BridgedSwiftStackType { } } +extension JSValue: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = JSValue.bridgeJSMakeTypeHandle() +} + +// Keep this order in sync with BridgeType.genericBridgeablePrimitives. +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_core_register_type_handles") +private func _bjs_core_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_core_register_type_handles") +public func _bjs_core_register_type_handles() { + // BEGIN bjs_core_type_handles + let typeIds: [Int32] = [ + Bool.bridgeJSTypeID, + Int.bridgeJSTypeID, + Int8.bridgeJSTypeID, + UInt8.bridgeJSTypeID, + Int16.bridgeJSTypeID, + UInt16.bridgeJSTypeID, + Int32.bridgeJSTypeID, + UInt32.bridgeJSTypeID, + UInt.bridgeJSTypeID, + Int64.bridgeJSTypeID, + UInt64.bridgeJSTypeID, + Float.bridgeJSTypeID, + Double.bridgeJSTypeID, + String.bridgeJSTypeID, + JSValue.bridgeJSTypeID, + ] + // END bjs_core_type_handles + typeIds.withUnsafeBufferPointer { buffer in + _bjs_core_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif + /// A protocol that Swift heap objects exposed to JavaScript via `@JS class` must conform to. /// /// The conformance is automatically synthesized by the BridgeJS code generator. @@ -1945,14 +2063,8 @@ extension _BridgedAsOptional where Wrapped: _BridgedSwiftStackType, Wrapped.Stac extension _BridgedAsOptional where Wrapped: _BridgedSwiftStackType, Wrapped.StackLiftResult == Wrapped, Wrapped: _BridgedSwiftTypeLoweredIntoVoidType { - @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { - switch asOptional { - case .none: - return 0 - case .some(let array): - array.bridgeJSLowerReturn() - return 1 - } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() { + Wrapped.bridgeJSStackPushAsOptional(asOptional) } @_spi(BridgeJS) public consuming func bridgeJSLowerReturn() -> Void { @@ -2369,24 +2481,6 @@ extension _BridgedAsOptional where Wrapped: _BridgedSwiftAssociatedValueEnum { } } -extension _BridgedAsOptional where Wrapped: _BridgedSwiftStruct { - @_spi(BridgeJS) public static func bridgeJSLiftParameter(_ isSome: Int32) -> Self { - if isSome == 0 { - return Self(optional: nil) - } else { - return Self(optional: Wrapped.bridgeJSStackPop()) - } - } - - @_spi(BridgeJS) public consuming func bridgeJSLowerReturn() -> Void { - Wrapped.bridgeJSStackPushAsOptional(asOptional) - } - - @_spi(BridgeJS) public static func bridgeJSLiftParameter() -> Self { - Self.bridgeJSStackPop() - } -} - // MARK: - Array Support extension Array: _BridgedSwiftTypeLoweredIntoVoidType @@ -2462,41 +2556,6 @@ where Key == String, Value: _BridgedSwiftStackType, Value.StackLiftResult == Val } } -extension _BridgedAsOptional { - @_spi(BridgeJS) public consuming func bridgeJSLowerParameter() -> Int32 - where Wrapped == Dictionary, Value: _BridgedSwiftStackType, Value.StackLiftResult == Value { - switch asOptional { - case .none: - return 0 - case .some(let dict): - dict.bridgeJSStackPush() - return 1 - } - } - - @_spi(BridgeJS) public static func bridgeJSLiftParameter(_ isSome: Int32) -> Self - where Wrapped == Dictionary, Value: _BridgedSwiftStackType, Value.StackLiftResult == Value { - if isSome == 0 { - return Self(optional: nil) - } - return Self(optional: Dictionary.bridgeJSStackPop()) - } - - @_spi(BridgeJS) public static func bridgeJSLiftReturn() -> Self - where Wrapped == Dictionary, Value: _BridgedSwiftStackType, Value.StackLiftResult == Value { - let isSome = _swift_js_pop_i32() - if isSome == 0 { - return Self(optional: nil) - } - return Self(optional: Dictionary.bridgeJSStackPop()) - } - - @_spi(BridgeJS) public consuming func bridgeJSLowerReturn() -> Void - where Wrapped == Dictionary, Value: _BridgedSwiftStackType, Value.StackLiftResult == Value { - Wrapped.bridgeJSStackPushAsOptional(asOptional) - } -} - // MARK: Async Promise Awaiting /// Protocol for type-erasing `JSTypedClosure` in `_bjs_awaitPromise`. diff --git a/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Exporting-Swift/Exporting-Swift-Function.md b/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Exporting-Swift/Exporting-Swift-Function.md index c26841041..098a931af 100644 --- a/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Exporting-Swift/Exporting-Swift-Function.md +++ b/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Exporting-Swift/Exporting-Swift-Function.md @@ -37,6 +37,27 @@ export type Exports = { } ``` +### Renaming functions in JavaScript + +If a different name is more appropriate in JavaScript or to export multiple overloaded Swift functions with distinct JavaScript names, you can pass a JavaScript identifier as the first argument to `@JS`. + +```swift +import JavaScriptKit + +@JS("greetName") public func greet(_ name: String) -> String { + return "Hello, \(name)!" +} + +@JS("greetPerson") public func greet(_ person: Person) -> String { + return "Hello, \(person.name)!" +} +``` + +```javascript +exports.greetName("World"); +exports.greetPerson({ name: "World" }); +``` + ### Throwing functions Swift functions can throw JavaScript errors using `throws(JSException)`. diff --git a/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Generating-from-TypeScript.md b/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Generating-from-TypeScript.md index 9c0a80dc1..5a47746d6 100644 --- a/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Generating-from-TypeScript.md +++ b/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Generating-from-TypeScript.md @@ -416,4 +416,4 @@ When a TypeScript name is not a valid Swift identifier (e.g. contains dashes, sp ## Limitations - No first-class support for async/Promise-returning functions;. -- No generic type parameter can appear on a bridged function signature. \ No newline at end of file +- No generic type parameter can appear on a bridged function signature generated from TypeScript; a type parameter is lowered to `JSObject`. Generic imports are available only through `@JSFunction` declarations written in Swift — see . \ No newline at end of file diff --git a/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Importing-JavaScript/Importing-JS-Function.md b/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Importing-JavaScript/Importing-JS-Function.md index 1b2be6cb0..ebc9ac857 100644 --- a/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Importing-JavaScript/Importing-JS-Function.md +++ b/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Importing-JavaScript/Importing-JS-Function.md @@ -77,11 +77,23 @@ If you used `from: .global` or `.module`, do not pass the function in `getImport Bound functions are `throws(JSException)`. Call them with `try` or `try?`; they throw when the JavaScript implementation throws. +## Generic functions + +A `@JSFunction` can be generic over a type parameter constrained to `BridgedSwiftGenericBridgeable`, so one declaration serves every bridged type: + +```swift +@JSFunction func parse(_ json: String) throws(JSException) -> T + +let user: User = try parse(jsonString) // T inferred from the call site +``` + +`T` can be any supported primitive, `String`, `JSValue`, or a `@JS` struct, `@JS` enum, or `final @JS class` (see ), used bare or wrapped as `[T]`, `T?`, or `[String: T]`. A function may declare multiple type parameters, and a return-only generic (`func make() -> T`) works too. Generic initializers, methods, and static methods on `@JSClass` types are supported the same way. `async` generic functions and `where` clauses are not supported. + ## Supported features | Feature | Status | |:--|:--| | Primitive parameter/result types (e.g. `Double`, `Bool`) | ✅ | | `String` parameter/result type | ✅ | +| Generic parameter/result types (constrained to `BridgedSwiftGenericBridgeable`) | ✅ | | Async function | ❌ | -| Generics | ❌ | diff --git a/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Supported-Types.md b/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Supported-Types.md index 5c609ab72..539f7ce15 100644 --- a/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Supported-Types.md +++ b/Sources/JavaScriptKit/Documentation.docc/Articles/BridgeJS/Supported-Types.md @@ -31,6 +31,10 @@ When using `JSTypedArray` (or convenience typealiases) in `@JS` signatures, t See for usage details. +## Generic type parameters + +An imported `@JSFunction` can be generic over a type parameter constrained to `BridgedSwiftGenericBridgeable` (see ); exported `@JS` functions cannot yet. The constraint is satisfied by all supported primitives, `String`, `JSValue`, and any `@JS` struct, `@JS` enum, or `final @JS class`, including ones from another linked module. Do not write the conformance by hand; marking the type `@JS` is what provides it, together with the JavaScript side of the bridge. + ## See Also - diff --git a/Sources/JavaScriptKit/Macros.swift b/Sources/JavaScriptKit/Macros.swift index 2750f8268..a1cdc0c44 100644 --- a/Sources/JavaScriptKit/Macros.swift +++ b/Sources/JavaScriptKit/Macros.swift @@ -140,6 +140,7 @@ public enum JSName: ExpressibleByStringLiteral { /// /// For detailed usage information, see the article . /// +/// - Parameter name: A different name to use in the exported JavaScript. /// - Parameter namespace: A dot-separated string that defines the namespace hierarchy in JavaScript. /// Each segment becomes a nested object in the resulting JavaScript structure. /// - Parameter enumStyle: Controls how enums are emitted to TypeScript for this declaration: @@ -151,6 +152,7 @@ public enum JSName: ExpressibleByStringLiteral { /// - Important: This feature is still experimental. No API stability is guaranteed, and the API may change in future releases. @attached(peer) public macro JS( + _ name: String? = nil, as aliasOf: Any.Type? = nil, namespace: String? = nil, enumStyle: JSEnumStyle = .const, diff --git a/Tests/BridgeJSGlobalTests/Generated/BridgeJS.swift b/Tests/BridgeJSGlobalTests/Generated/BridgeJS.swift index 4e35a1c9f..91638a428 100644 --- a/Tests/BridgeJSGlobalTests/Generated/BridgeJS.swift +++ b/Tests/BridgeJSGlobalTests/Generated/BridgeJS.swift @@ -353,4 +353,38 @@ fileprivate func _bjs_GlobalUtils_PublicConverter_wrap_extern(_ pointer: UnsafeM #endif @inline(never) fileprivate func _bjs_GlobalUtils_PublicConverter_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { return _bjs_GlobalUtils_PublicConverter_wrap_extern(pointer) -} \ No newline at end of file +} + +extension GlobalNetworking.API.CallMethod: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = GlobalNetworking.API.CallMethod.bridgeJSMakeTypeHandle() +} + +extension GlobalConfiguration.PublicLogLevel: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = GlobalConfiguration.PublicLogLevel.bridgeJSMakeTypeHandle() +} + +extension GlobalConfiguration.AvailablePort: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = GlobalConfiguration.AvailablePort.bridgeJSMakeTypeHandle() +} + +extension Internal.SupportedServerMethod: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Internal.SupportedServerMethod.bridgeJSMakeTypeHandle() +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "bjs_BridgeJSGlobalTests_register_type_handles") +fileprivate func _bjs_BridgeJSGlobalTests_register_type_handles_extern(_ base: UnsafePointer?, _ count: Int32) + +@_expose(wasm, "bjs_BridgeJSGlobalTests_register_type_handles") +public func _bjs_BridgeJSGlobalTests_register_type_handles() { + let typeIds: [Int32] = [ + GlobalNetworking.API.CallMethod.bridgeJSTypeID, + GlobalConfiguration.PublicLogLevel.bridgeJSTypeID, + GlobalConfiguration.AvailablePort.bridgeJSTypeID, + Internal.SupportedServerMethod.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_BridgeJSGlobalTests_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift index ad6f3fa24..e453e3534 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift +++ b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift @@ -5991,6 +5991,75 @@ extension ImportedPayloadSignal: _BridgedSwiftAssociatedValueEnum { } } +extension GenericRTColor: _BridgedSwiftCaseEnum { + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerParameter() -> Int32 { + return bridgeJSRawValue + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftReturn(_ value: Int32) -> GenericRTColor { + return bridgeJSLiftParameter(value) + } + @_spi(BridgeJS) @_transparent public static func bridgeJSLiftParameter(_ value: Int32) -> GenericRTColor { + return GenericRTColor(bridgeJSRawValue: value)! + } + @_spi(BridgeJS) @_transparent public consuming func bridgeJSLowerReturn() -> Int32 { + return bridgeJSLowerParameter() + } + + @_spi(BridgeJS) @usableFromInline init?(bridgeJSRawValue: Int32) { + switch bridgeJSRawValue { + case 0: + self = .red + case 1: + self = .green + case 2: + self = .blue + default: + return nil + } + } + + @_spi(BridgeJS) @usableFromInline var bridgeJSRawValue: Int32 { + switch self { + case .red: + return 0 + case .green: + return 1 + case .blue: + return 2 + } + } +} + +extension GenericRTMode: _BridgedSwiftEnumNoPayload, _BridgedSwiftRawValueEnum { +} + +extension GenericRTLevel: _BridgedSwiftEnumNoPayload, _BridgedSwiftRawValueEnum { +} + +extension GenericRTOutcome: _BridgedSwiftAssociatedValueEnum { + @_spi(BridgeJS) @_transparent public static func bridgeJSStackPopPayload(_ caseId: Int32) -> GenericRTOutcome { + switch caseId { + case 0: + return .ok(code: Int.bridgeJSStackPop()) + case 1: + return .fail(message: String.bridgeJSStackPop()) + default: + fatalError("Unknown GenericRTOutcome case ID: \(caseId)") + } + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPushPayload() -> Int32 { + switch self { + case .ok(let code): + code.bridgeJSStackPush() + return Int32(0) + case .fail(let message): + message.bridgeJSStackPush() + return Int32(1) + } + } +} + @_expose(wasm, "bjs_IntegerTypesSupportExports_static_roundTripInt") @_cdecl("bjs_IntegerTypesSupportExports_static_roundTripInt") public func _bjs_IntegerTypesSupportExports_static_roundTripInt(_ v: Int32) -> Int32 { @@ -6779,6 +6848,102 @@ public func _bjs_NestedTypeHost_Label_static_untitled() -> Void { #endif } +extension GenericRTPoint: _BridgedSwiftStruct { + @_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> GenericRTPoint { + let y = Int.bridgeJSStackPop() + let x = Int.bridgeJSStackPop() + return GenericRTPoint(x: x, y: y) + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPush() { + self.x.bridgeJSStackPush() + self.y.bridgeJSStackPush() + } + + init(unsafelyCopying jsObject: JSObject) { + _bjs_struct_lower_GenericRTPoint(jsObject.bridgeJSLowerParameter()) + self = Self.bridgeJSStackPop() + } + + func toJSObject() -> JSObject { + let __bjs_self = self + __bjs_self.bridgeJSStackPush() + return JSObject(id: UInt32(bitPattern: _bjs_struct_lift_GenericRTPoint())) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_GenericRTPoint") +fileprivate func _bjs_struct_lower_GenericRTPoint_extern(_ objectId: Int32) -> Void +#else +fileprivate func _bjs_struct_lower_GenericRTPoint_extern(_ objectId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lower_GenericRTPoint(_ objectId: Int32) -> Void { + return _bjs_struct_lower_GenericRTPoint_extern(objectId) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lift_GenericRTPoint") +fileprivate func _bjs_struct_lift_GenericRTPoint_extern() -> Int32 +#else +fileprivate func _bjs_struct_lift_GenericRTPoint_extern() -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lift_GenericRTPoint() -> Int32 { + return _bjs_struct_lift_GenericRTPoint_extern() +} + +extension GenericRTNamespace.Metadata: _BridgedSwiftStruct { + @_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> GenericRTNamespace.Metadata { + let count = Int.bridgeJSStackPop() + let label = String.bridgeJSStackPop() + return GenericRTNamespace.Metadata(label: label, count: count) + } + + @_spi(BridgeJS) @_transparent public consuming func bridgeJSStackPush() { + self.label.bridgeJSStackPush() + self.count.bridgeJSStackPush() + } + + init(unsafelyCopying jsObject: JSObject) { + _bjs_struct_lower_GenericRTNamespace_Metadata(jsObject.bridgeJSLowerParameter()) + self = Self.bridgeJSStackPop() + } + + func toJSObject() -> JSObject { + let __bjs_self = self + __bjs_self.bridgeJSStackPush() + return JSObject(id: UInt32(bitPattern: _bjs_struct_lift_GenericRTNamespace_Metadata())) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lower_GenericRTNamespace_Metadata") +fileprivate func _bjs_struct_lower_GenericRTNamespace_Metadata_extern(_ objectId: Int32) -> Void +#else +fileprivate func _bjs_struct_lower_GenericRTNamespace_Metadata_extern(_ objectId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lower_GenericRTNamespace_Metadata(_ objectId: Int32) -> Void { + return _bjs_struct_lower_GenericRTNamespace_Metadata_extern(objectId) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_struct_lift_GenericRTNamespace_Metadata") +fileprivate func _bjs_struct_lift_GenericRTNamespace_Metadata_extern() -> Int32 +#else +fileprivate func _bjs_struct_lift_GenericRTNamespace_Metadata_extern() -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_struct_lift_GenericRTNamespace_Metadata() -> Int32 { + return _bjs_struct_lift_GenericRTNamespace_Metadata_extern() +} + extension Point: _BridgedSwiftStruct { @_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> Point { let y = Int.bridgeJSStackPop() @@ -7861,6 +8026,17 @@ public func _bjs_Vector2D_scaled(_ factor: Float64) -> Void { #endif } +@_expose(wasm, "bjs_Vector2D_describe") +@_cdecl("bjs_Vector2D_describe") +public func _bjs_Vector2D_describe() -> Void { + #if arch(wasm32) + let ret = Vector2D.bridgeJSLiftParameter().describe() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + extension JSObjectContainer: _BridgedSwiftStruct { @_spi(BridgeJS) @_transparent public static func bridgeJSStackPop() -> JSObjectContainer { let optionalObject = Optional.bridgeJSStackPop() @@ -9814,6 +9990,39 @@ public func _bjs_makeAdder(_ base: Int32) -> Int32 { #endif } +@_expose(wasm, "bjs_renamedEcho") +@_cdecl("bjs_renamedEcho") +public func _bjs_renamedEcho(_ valueBytes: Int32, _ valueLength: Int32) -> Void { + #if arch(wasm32) + let ret = jsNameEcho(_: String.bridgeJSLiftParameter(valueBytes, valueLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_greetName") +@_cdecl("bjs_greetName") +public func _bjs_greetName(_ nameBytes: Int32, _ nameLength: Int32) -> Void { + #if arch(wasm32) + let ret = greet(_: String.bridgeJSLiftParameter(nameBytes, nameLength)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_greetCount") +@_cdecl("bjs_greetCount") +public func _bjs_greetCount(_ count: Int32) -> Void { + #if arch(wasm32) + let ret = greet(_: Int.bridgeJSLiftParameter(count)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + @_expose(wasm, "bjs_roundTripPointerFields") @_cdecl("bjs_roundTripPointerFields") public func _bjs_roundTripPointerFields() -> Void { @@ -13162,6 +13371,165 @@ fileprivate func _bjs_NestedTypeHost_wrap_extern(_ pointer: UnsafeMutableRawPoin return _bjs_NestedTypeHost_wrap_extern(pointer) } +@_expose(wasm, "bjs_ImportGenericBox_init") +@_cdecl("bjs_ImportGenericBox_init") +public func _bjs_ImportGenericBox_init(_ value: Int32) -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = ImportGenericBox(value: Int.bridgeJSLiftParameter(value)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_ImportGenericBox_get") +@_cdecl("bjs_ImportGenericBox_get") +public func _bjs_ImportGenericBox_get(_ _self: UnsafeMutableRawPointer) -> Int32 { + #if arch(wasm32) + let ret = ImportGenericBox.bridgeJSLiftParameter(_self).get() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_ImportGenericBox_value_get") +@_cdecl("bjs_ImportGenericBox_value_get") +public func _bjs_ImportGenericBox_value_get(_ _self: UnsafeMutableRawPointer) -> Int32 { + #if arch(wasm32) + let ret = ImportGenericBox.bridgeJSLiftParameter(_self).value + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_ImportGenericBox_value_set") +@_cdecl("bjs_ImportGenericBox_value_set") +public func _bjs_ImportGenericBox_value_set(_ _self: UnsafeMutableRawPointer, _ value: Int32) -> Void { + #if arch(wasm32) + ImportGenericBox.bridgeJSLiftParameter(_self).value = Int.bridgeJSLiftParameter(value) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_ImportGenericBox_deinit") +@_cdecl("bjs_ImportGenericBox_deinit") +public func _bjs_ImportGenericBox_deinit(_ pointer: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + Unmanaged.fromOpaque(pointer).release() + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension ImportGenericBox: ConvertibleToJSValue, _BridgedSwiftHeapObject, _BridgedSwiftProtocolExportable { + var jsValue: JSValue { + return .object(JSObject(id: UInt32(bitPattern: _bjs_ImportGenericBox_wrap(Unmanaged.passRetained(self).toOpaque())))) + } + consuming func bridgeJSLowerAsProtocolReturn() -> Int32 { + _bjs_ImportGenericBox_wrap(Unmanaged.passRetained(self).toOpaque()) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_ImportGenericBox_wrap") +fileprivate func _bjs_ImportGenericBox_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_ImportGenericBox_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_ImportGenericBox_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { + return _bjs_ImportGenericBox_wrap_extern(pointer) +} + +@_expose(wasm, "bjs_JSNameRenamedClass_init") +@_cdecl("bjs_JSNameRenamedClass_init") +public func _bjs_JSNameRenamedClass_init(_ value: Int32) -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = JSNameRenamedClass(value: Int.bridgeJSLiftParameter(value)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_JSNameRenamedClass_doubled") +@_cdecl("bjs_JSNameRenamedClass_doubled") +public func _bjs_JSNameRenamedClass_doubled(_ _self: UnsafeMutableRawPointer) -> Int32 { + #if arch(wasm32) + let ret = JSNameRenamedClass.bridgeJSLiftParameter(_self).timesTwo() + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_JSNameRenamedClass_static_makeWithValue") +@_cdecl("bjs_JSNameRenamedClass_static_makeWithValue") +public func _bjs_JSNameRenamedClass_static_makeWithValue(_ value: Int32) -> UnsafeMutableRawPointer { + #if arch(wasm32) + let ret = JSNameRenamedClass.create(value: Int.bridgeJSLiftParameter(value)) + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_JSNameRenamedClass_value_get") +@_cdecl("bjs_JSNameRenamedClass_value_get") +public func _bjs_JSNameRenamedClass_value_get(_ _self: UnsafeMutableRawPointer) -> Int32 { + #if arch(wasm32) + let ret = JSNameRenamedClass.bridgeJSLiftParameter(_self).value + return ret.bridgeJSLowerReturn() + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_JSNameRenamedClass_value_set") +@_cdecl("bjs_JSNameRenamedClass_value_set") +public func _bjs_JSNameRenamedClass_value_set(_ _self: UnsafeMutableRawPointer, _ value: Int32) -> Void { + #if arch(wasm32) + JSNameRenamedClass.bridgeJSLiftParameter(_self).value = Int.bridgeJSLiftParameter(value) + #else + fatalError("Only available on WebAssembly") + #endif +} + +@_expose(wasm, "bjs_JSNameRenamedClass_deinit") +@_cdecl("bjs_JSNameRenamedClass_deinit") +public func _bjs_JSNameRenamedClass_deinit(_ pointer: UnsafeMutableRawPointer) -> Void { + #if arch(wasm32) + Unmanaged.fromOpaque(pointer).release() + #else + fatalError("Only available on WebAssembly") + #endif +} + +extension JSNameRenamedClass: ConvertibleToJSValue, _BridgedSwiftHeapObject, _BridgedSwiftProtocolExportable { + var jsValue: JSValue { + return .object(JSObject(id: UInt32(bitPattern: _bjs_JSNameRenamedClass_wrap(Unmanaged.passRetained(self).toOpaque())))) + } + consuming func bridgeJSLowerAsProtocolReturn() -> Int32 { + _bjs_JSNameRenamedClass_wrap(Unmanaged.passRetained(self).toOpaque()) + } +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_JSNameRenamedClass_wrap") +fileprivate func _bjs_JSNameRenamedClass_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 +#else +fileprivate func _bjs_JSNameRenamedClass_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func _bjs_JSNameRenamedClass_wrap(_ pointer: UnsafeMutableRawPointer) -> Int32 { + return _bjs_JSNameRenamedClass_wrap_extern(pointer) +} + @_expose(wasm, "bjs_OptionalHolder_init") @_cdecl("bjs_OptionalHolder_init") public func _bjs_OptionalHolder_init(_ nullableGreeterIsSome: Int32, _ nullableGreeterValue: UnsafeMutableRawPointer, _ undefinedNumberIsSome: Int32, _ undefinedNumberValue: Float64) -> UnsafeMutableRawPointer { @@ -13479,18 +13847,286 @@ fileprivate func _bjs_LeakCheck_wrap_extern(_ pointer: UnsafeMutableRawPointer) return _bjs_LeakCheck_wrap_extern(pointer) } -@JSFunction func Promise_reject(_ promise: JSObject, _ value: JSValue) throws(JSException) +extension JSCoordinate: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = JSCoordinate.bridgeJSMakeTypeHandle() +} -#if arch(wasm32) -@_extern(wasm, module: "bjs", name: "promise_reject_BridgeJSRuntimeTests") -fileprivate func promise_reject_BridgeJSRuntimeTests_extern(_ promise: Int32, _ valueKind: Int32, _ valuePayload1: Int32, _ valuePayload2: Float64) -> Void -#else -fileprivate func promise_reject_BridgeJSRuntimeTests_extern(_ promise: Int32, _ valueKind: Int32, _ valuePayload1: Int32, _ valuePayload2: Float64) -> Void { - fatalError("Only available on WebAssembly") +extension NestedStructGroupA.Metadata: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = NestedStructGroupA.Metadata.bridgeJSMakeTypeHandle() } -#endif -@inline(never) fileprivate func promise_reject_BridgeJSRuntimeTests(_ promise: Int32, _ valueKind: Int32, _ valuePayload1: Int32, _ valuePayload2: Float64) -> Void { - return promise_reject_BridgeJSRuntimeTests_extern(promise, valueKind, valuePayload1, valuePayload2) + +extension NestedStructGroupB.Metadata: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = NestedStructGroupB.Metadata.bridgeJSMakeTypeHandle() +} + +extension NestedTypeHost.Label: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = NestedTypeHost.Label.bridgeJSMakeTypeHandle() +} + +extension GenericRTPoint: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = GenericRTPoint.bridgeJSMakeTypeHandle() +} + +extension GenericRTNamespace.Metadata: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = GenericRTNamespace.Metadata.bridgeJSMakeTypeHandle() +} + +extension Point: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Point.bridgeJSMakeTypeHandle() +} + +extension PointerFields: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = PointerFields.bridgeJSMakeTypeHandle() +} + +extension DataPoint: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = DataPoint.bridgeJSMakeTypeHandle() +} + +extension PublicPoint: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = PublicPoint.bridgeJSMakeTypeHandle() +} + +extension Address: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Address.bridgeJSMakeTypeHandle() +} + +extension Contact: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Contact.bridgeJSMakeTypeHandle() +} + +extension Config: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Config.bridgeJSMakeTypeHandle() +} + +extension SessionData: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = SessionData.bridgeJSMakeTypeHandle() +} + +extension ValidationReport: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = ValidationReport.bridgeJSMakeTypeHandle() +} + +extension AdvancedConfig: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = AdvancedConfig.bridgeJSMakeTypeHandle() +} + +extension MeasurementConfig: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = MeasurementConfig.bridgeJSMakeTypeHandle() +} + +extension MathOperations: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = MathOperations.bridgeJSMakeTypeHandle() +} + +extension CopyableCart: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = CopyableCart.bridgeJSMakeTypeHandle() +} + +extension CopyableCartItem: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = CopyableCartItem.bridgeJSMakeTypeHandle() +} + +extension CopyableNestedCart: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = CopyableNestedCart.bridgeJSMakeTypeHandle() +} + +extension ConfigStruct: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = ConfigStruct.bridgeJSMakeTypeHandle() +} + +extension Vector2D: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Vector2D.bridgeJSMakeTypeHandle() +} + +extension JSObjectContainer: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = JSObjectContainer.bridgeJSMakeTypeHandle() +} + +extension FooContainer: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = FooContainer.bridgeJSMakeTypeHandle() +} + +extension ArrayMembers: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = ArrayMembers.bridgeJSMakeTypeHandle() +} + +extension PolygonReference: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = PolygonReference.bridgeJSMakeTypeHandle() +} + +extension TagReference: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = TagReference.bridgeJSMakeTypeHandle() +} + +extension TagHolderReference: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = TagHolderReference.bridgeJSMakeTypeHandle() +} + +extension PriorityReference: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = PriorityReference.bridgeJSMakeTypeHandle() +} + +extension ImportGenericBox: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = ImportGenericBox.bridgeJSMakeTypeHandle() +} + +extension Severity: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Severity.bridgeJSMakeTypeHandle() +} + +extension Shape: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Shape.bridgeJSMakeTypeHandle() +} + +extension InnerTag: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = InnerTag.bridgeJSMakeTypeHandle() +} + +extension AsyncImportedPayloadResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = AsyncImportedPayloadResult.bridgeJSMakeTypeHandle() +} + +extension Direction: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Direction.bridgeJSMakeTypeHandle() +} + +extension Status: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Status.bridgeJSMakeTypeHandle() +} + +extension Theme: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Theme.bridgeJSMakeTypeHandle() +} + +extension HttpStatus: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = HttpStatus.bridgeJSMakeTypeHandle() +} + +extension FileSize: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = FileSize.bridgeJSMakeTypeHandle() +} + +extension SessionId: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = SessionId.bridgeJSMakeTypeHandle() +} + +extension Precision: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Precision.bridgeJSMakeTypeHandle() +} + +extension Ratio: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Ratio.bridgeJSMakeTypeHandle() +} + +extension TSDirection: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = TSDirection.bridgeJSMakeTypeHandle() +} + +extension TSTheme: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = TSTheme.bridgeJSMakeTypeHandle() +} + +extension AsyncPayloadResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = AsyncPayloadResult.bridgeJSMakeTypeHandle() +} + +extension Networking.API.Method: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Networking.API.Method.bridgeJSMakeTypeHandle() +} + +extension Configuration.LogLevel: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Configuration.LogLevel.bridgeJSMakeTypeHandle() +} + +extension Configuration.Port: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Configuration.Port.bridgeJSMakeTypeHandle() +} + +extension Internal.SupportedMethod: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Internal.SupportedMethod.bridgeJSMakeTypeHandle() +} + +extension APIResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = APIResult.bridgeJSMakeTypeHandle() +} + +extension ComplexResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = ComplexResult.bridgeJSMakeTypeHandle() +} + +extension Utilities.Result: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = Utilities.Result.bridgeJSMakeTypeHandle() +} + +extension API.NetworkingResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = API.NetworkingResult.bridgeJSMakeTypeHandle() +} + +extension AllTypesResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = AllTypesResult.bridgeJSMakeTypeHandle() +} + +extension TypedPayloadResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = TypedPayloadResult.bridgeJSMakeTypeHandle() +} + +extension StaticCalculator: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = StaticCalculator.bridgeJSMakeTypeHandle() +} + +extension StaticPropertyEnum: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = StaticPropertyEnum.bridgeJSMakeTypeHandle() +} + +extension NestedTypeHost.Variant: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = NestedTypeHost.Variant.bridgeJSMakeTypeHandle() +} + +extension LightColor: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = LightColor.bridgeJSMakeTypeHandle() +} + +extension ImportedPayloadSignal: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = ImportedPayloadSignal.bridgeJSMakeTypeHandle() +} + +extension GenericRTColor: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = GenericRTColor.bridgeJSMakeTypeHandle() +} + +extension GenericRTMode: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = GenericRTMode.bridgeJSMakeTypeHandle() +} + +extension GenericRTLevel: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = GenericRTLevel.bridgeJSMakeTypeHandle() +} + +extension GenericRTOutcome: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = GenericRTOutcome.bridgeJSMakeTypeHandle() +} + +extension OptionalAllTypesResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = OptionalAllTypesResult.bridgeJSMakeTypeHandle() +} + +extension APIOptionalResult: BridgedSwiftGenericBridgeable { + @_spi(BridgeJS) public static let bridgeJSTypeHandle = APIOptionalResult.bridgeJSMakeTypeHandle() +} + +@JSFunction func Promise_reject(_ promise: JSObject, _ value: JSValue) throws(JSException) + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "promise_reject_BridgeJSRuntimeTests") +fileprivate func promise_reject_BridgeJSRuntimeTests_extern(_ promise: Int32, _ valueKind: Int32, _ valuePayload1: Int32, _ valuePayload2: Float64) -> Void +#else +fileprivate func promise_reject_BridgeJSRuntimeTests_extern(_ promise: Int32, _ valueKind: Int32, _ valuePayload1: Int32, _ valuePayload2: Float64) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func promise_reject_BridgeJSRuntimeTests(_ promise: Int32, _ valueKind: Int32, _ valuePayload1: Int32, _ valuePayload2: Float64) -> Void { + return promise_reject_BridgeJSRuntimeTests_extern(promise, valueKind, valuePayload1, valuePayload2) } func _$Promise_reject(_ promise: JSObject, _ value: JSValue) throws(JSException) -> Void { @@ -13989,20 +14625,20 @@ func _$Promise_resolve_Sa11PublicPointV(_ promise: JSObject, _ value: [PublicPoi #if arch(wasm32) @_extern(wasm, module: "bjs", name: "promise_resolve_BridgeJSRuntimeTests_Sq11PublicPointV") -fileprivate func promise_resolve_BridgeJSRuntimeTests_Sq11PublicPointV_extern(_ promise: Int32, _ value: Int32) -> Void +fileprivate func promise_resolve_BridgeJSRuntimeTests_Sq11PublicPointV_extern(_ promise: Int32) -> Void #else -fileprivate func promise_resolve_BridgeJSRuntimeTests_Sq11PublicPointV_extern(_ promise: Int32, _ value: Int32) -> Void { +fileprivate func promise_resolve_BridgeJSRuntimeTests_Sq11PublicPointV_extern(_ promise: Int32) -> Void { fatalError("Only available on WebAssembly") } #endif -@inline(never) fileprivate func promise_resolve_BridgeJSRuntimeTests_Sq11PublicPointV(_ promise: Int32, _ value: Int32) -> Void { - return promise_resolve_BridgeJSRuntimeTests_Sq11PublicPointV_extern(promise, value) +@inline(never) fileprivate func promise_resolve_BridgeJSRuntimeTests_Sq11PublicPointV(_ promise: Int32) -> Void { + return promise_resolve_BridgeJSRuntimeTests_Sq11PublicPointV_extern(promise) } func _$Promise_resolve_Sq11PublicPointV(_ promise: JSObject, _ value: Optional) throws(JSException) -> Void { - let valueIsSome = value.bridgeJSLowerParameter() + let _ = value.bridgeJSLowerParameter() let promiseValue = promise.bridgeJSLowerParameter() - promise_resolve_BridgeJSRuntimeTests_Sq11PublicPointV(promiseValue, valueIsSome) + promise_resolve_BridgeJSRuntimeTests_Sq11PublicPointV(promiseValue) if let error = _swift_js_take_exception() { throw error } } @@ -16598,20 +17234,20 @@ func _$jsRoundTripOptionalImportedPayloadSignal(_ value: Optional Int32 +fileprivate func bjs_jsJoinOptionalArrayThenArray_extern() -> Int32 #else -fileprivate func bjs_jsJoinOptionalArrayThenArray_extern(_ a: Int32) -> Int32 { +fileprivate func bjs_jsJoinOptionalArrayThenArray_extern() -> Int32 { fatalError("Only available on WebAssembly") } #endif -@inline(never) fileprivate func bjs_jsJoinOptionalArrayThenArray(_ a: Int32) -> Int32 { - return bjs_jsJoinOptionalArrayThenArray_extern(a) +@inline(never) fileprivate func bjs_jsJoinOptionalArrayThenArray() -> Int32 { + return bjs_jsJoinOptionalArrayThenArray_extern() } func _$jsJoinOptionalArrayThenArray(_ a: Optional<[Int]>, _ b: [Int]) throws(JSException) -> String { let _ = b.bridgeJSLowerParameter() - let aIsSome = a.bridgeJSLowerParameter() - let ret = bjs_jsJoinOptionalArrayThenArray(aIsSome) + let _ = a.bridgeJSLowerParameter() + let ret = bjs_jsJoinOptionalArrayThenArray() if let error = _swift_js_take_exception() { throw error } @@ -16620,20 +17256,20 @@ func _$jsJoinOptionalArrayThenArray(_ a: Optional<[Int]>, _ b: [Int]) throws(JSE #if arch(wasm32) @_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsJoinOptionalStructThenArray") -fileprivate func bjs_jsJoinOptionalStructThenArray_extern(_ a: Int32) -> Int32 +fileprivate func bjs_jsJoinOptionalStructThenArray_extern() -> Int32 #else -fileprivate func bjs_jsJoinOptionalStructThenArray_extern(_ a: Int32) -> Int32 { +fileprivate func bjs_jsJoinOptionalStructThenArray_extern() -> Int32 { fatalError("Only available on WebAssembly") } #endif -@inline(never) fileprivate func bjs_jsJoinOptionalStructThenArray(_ a: Int32) -> Int32 { - return bjs_jsJoinOptionalStructThenArray_extern(a) +@inline(never) fileprivate func bjs_jsJoinOptionalStructThenArray() -> Int32 { + return bjs_jsJoinOptionalStructThenArray_extern() } func _$jsJoinOptionalStructThenArray(_ a: Optional, _ b: [Int]) throws(JSException) -> String { let _ = b.bridgeJSLowerParameter() - let aIsSome = a.bridgeJSLowerParameter() - let ret = bjs_jsJoinOptionalStructThenArray(aIsSome) + let _ = a.bridgeJSLowerParameter() + let ret = bjs_jsJoinOptionalStructThenArray() if let error = _swift_js_take_exception() { throw error } @@ -16664,21 +17300,21 @@ func _$jsJoinEnumThenArray(_ a: ImportedPayloadSignal, _ b: [Int]) throws(JSExce #if arch(wasm32) @_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsJoinStringThenStackParams") -fileprivate func bjs_jsJoinStringThenStackParams_extern(_ sBytes: Int32, _ sLength: Int32, _ a: Int32) -> Int32 +fileprivate func bjs_jsJoinStringThenStackParams_extern(_ sBytes: Int32, _ sLength: Int32) -> Int32 #else -fileprivate func bjs_jsJoinStringThenStackParams_extern(_ sBytes: Int32, _ sLength: Int32, _ a: Int32) -> Int32 { +fileprivate func bjs_jsJoinStringThenStackParams_extern(_ sBytes: Int32, _ sLength: Int32) -> Int32 { fatalError("Only available on WebAssembly") } #endif -@inline(never) fileprivate func bjs_jsJoinStringThenStackParams(_ sBytes: Int32, _ sLength: Int32, _ a: Int32) -> Int32 { - return bjs_jsJoinStringThenStackParams_extern(sBytes, sLength, a) +@inline(never) fileprivate func bjs_jsJoinStringThenStackParams(_ sBytes: Int32, _ sLength: Int32) -> Int32 { + return bjs_jsJoinStringThenStackParams_extern(sBytes, sLength) } func _$jsJoinStringThenStackParams(_ s: String, _ a: Optional<[Int]>, _ b: [Int]) throws(JSException) -> String { let ret0 = s.bridgeJSWithLoweredParameter { (sBytes, sLength) in let _ = b.bridgeJSLowerParameter() - let aIsSome = a.bridgeJSLowerParameter() - let ret = bjs_jsJoinStringThenStackParams(sBytes, sLength, aIsSome) + let _ = a.bridgeJSLowerParameter() + let ret = bjs_jsJoinStringThenStackParams(sBytes, sLength) return ret } let ret = ret0 @@ -16688,6 +17324,346 @@ func _$jsJoinStringThenStackParams(_ s: String, _ a: Optional<[Int]>, _ b: [Int] return String.bridgeJSLiftReturn(ret) } +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsGenericRoundTrip") +fileprivate func bjs_jsGenericRoundTrip_extern(_ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_jsGenericRoundTrip_extern(_ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_jsGenericRoundTrip(_ _generic0TypeId: Int32) -> Void { + return bjs_jsGenericRoundTrip_extern(_generic0TypeId) +} + +func _$jsGenericRoundTrip(_ value: T) throws(JSException) -> T { + value.bridgeJSStackPush() + bjs_jsGenericRoundTrip(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return T.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsGenericRoundTripClass") +fileprivate func bjs_jsGenericRoundTripClass_extern(_ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_jsGenericRoundTripClass_extern(_ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_jsGenericRoundTripClass(_ _generic0TypeId: Int32) -> Void { + return bjs_jsGenericRoundTripClass_extern(_generic0TypeId) +} + +func _$jsGenericRoundTripClass(_ value: T) throws(JSException) -> T { + value.bridgeJSStackPush() + bjs_jsGenericRoundTripClass(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return T.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsGenericParsePoint") +fileprivate func bjs_jsGenericParsePoint_extern(_ jsonBytes: Int32, _ jsonLength: Int32, _ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_jsGenericParsePoint_extern(_ jsonBytes: Int32, _ jsonLength: Int32, _ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_jsGenericParsePoint(_ jsonBytes: Int32, _ jsonLength: Int32, _ _generic0TypeId: Int32) -> Void { + return bjs_jsGenericParsePoint_extern(jsonBytes, jsonLength, _generic0TypeId) +} + +func _$jsGenericParsePoint(_ json: String) throws(JSException) -> T { + json.bridgeJSWithLoweredParameter { (jsonBytes, jsonLength) in + bjs_jsGenericParsePoint(jsonBytes, jsonLength, T.bridgeJSTypeID) + } + if let error = _swift_js_take_exception() { + throw error + } + return T.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsImportPickFirst") +fileprivate func bjs_jsImportPickFirst_extern(_ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_jsImportPickFirst_extern(_ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_jsImportPickFirst(_ _generic0TypeId: Int32) -> Void { + return bjs_jsImportPickFirst_extern(_generic0TypeId) +} + +func _$jsImportPickFirst(_ a: T, _ b: T) throws(JSException) -> T { + b.bridgeJSStackPush() + a.bridgeJSStackPush() + bjs_jsImportPickFirst(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return T.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsImportMakeInt") +fileprivate func bjs_jsImportMakeInt_extern(_ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_jsImportMakeInt_extern(_ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_jsImportMakeInt(_ _generic0TypeId: Int32) -> Void { + return bjs_jsImportMakeInt_extern(_generic0TypeId) +} + +func _$jsImportMakeInt() throws(JSException) -> T { + bjs_jsImportMakeInt(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return T.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsImportCombineSecond") +fileprivate func bjs_jsImportCombineSecond_extern(_ _generic0TypeId: Int32, _ _generic1TypeId: Int32) -> Void +#else +fileprivate func bjs_jsImportCombineSecond_extern(_ _generic0TypeId: Int32, _ _generic1TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_jsImportCombineSecond(_ _generic0TypeId: Int32, _ _generic1TypeId: Int32) -> Void { + return bjs_jsImportCombineSecond_extern(_generic0TypeId, _generic1TypeId) +} + +func _$jsImportCombineSecond(_ a: T, _ b: U) throws(JSException) -> U { + b.bridgeJSStackPush() + a.bridgeJSStackPush() + bjs_jsImportCombineSecond(T.bridgeJSTypeID, U.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return U.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsGenericArrayRoundTrip") +fileprivate func bjs_jsGenericArrayRoundTrip_extern(_ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_jsGenericArrayRoundTrip_extern(_ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_jsGenericArrayRoundTrip(_ _generic0TypeId: Int32) -> Void { + return bjs_jsGenericArrayRoundTrip_extern(_generic0TypeId) +} + +func _$jsGenericArrayRoundTrip(_ values: [T]) throws(JSException) -> [T] { + let _ = values.bridgeJSLowerParameter() + bjs_jsGenericArrayRoundTrip(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return [T].bridgeJSLiftReturn() +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsGenericOptionalRoundTrip") +fileprivate func bjs_jsGenericOptionalRoundTrip_extern(_ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_jsGenericOptionalRoundTrip_extern(_ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_jsGenericOptionalRoundTrip(_ _generic0TypeId: Int32) -> Void { + return bjs_jsGenericOptionalRoundTrip_extern(_generic0TypeId) +} + +func _$jsGenericOptionalRoundTrip(_ value: Optional) throws(JSException) -> Optional { + value.bridgeJSStackPush() + bjs_jsGenericOptionalRoundTrip(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return Optional.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsGenericDictRoundTrip") +fileprivate func bjs_jsGenericDictRoundTrip_extern(_ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_jsGenericDictRoundTrip_extern(_ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_jsGenericDictRoundTrip(_ _generic0TypeId: Int32) -> Void { + return bjs_jsGenericDictRoundTrip_extern(_generic0TypeId) +} + +func _$jsGenericDictRoundTrip(_ values: [String: T]) throws(JSException) -> [String: T] { + let _ = values.bridgeJSLowerParameter() + bjs_jsGenericDictRoundTrip(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return [String: T].bridgeJSLiftReturn() +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsGenericAfterOptionalArray") +fileprivate func bjs_jsGenericAfterOptionalArray_extern(_ _generic0TypeId: Int32) -> Int32 +#else +fileprivate func bjs_jsGenericAfterOptionalArray_extern(_ _generic0TypeId: Int32) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_jsGenericAfterOptionalArray(_ _generic0TypeId: Int32) -> Int32 { + return bjs_jsGenericAfterOptionalArray_extern(_generic0TypeId) +} + +func _$jsGenericAfterOptionalArray(_ values: Optional<[Int]>, _ value: T) throws(JSException) -> String { + value.bridgeJSStackPush() + let _ = values.bridgeJSLowerParameter() + let ret = bjs_jsGenericAfterOptionalArray(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return String.bridgeJSLiftReturn(ret) +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsGenericThrowOrRoundTrip") +fileprivate func bjs_jsGenericThrowOrRoundTrip_extern(_ shouldThrow: Int32, _ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_jsGenericThrowOrRoundTrip_extern(_ shouldThrow: Int32, _ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_jsGenericThrowOrRoundTrip(_ shouldThrow: Int32, _ _generic0TypeId: Int32) -> Void { + return bjs_jsGenericThrowOrRoundTrip_extern(shouldThrow, _generic0TypeId) +} + +func _$jsGenericThrowOrRoundTrip(_ shouldThrow: Bool, _ value: T) throws(JSException) -> T { + value.bridgeJSStackPush() + let shouldThrowValue = shouldThrow.bridgeJSLowerParameter() + bjs_jsGenericThrowOrRoundTrip(shouldThrowValue, T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return T.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_ImportGenericConsumer_init") +fileprivate func bjs_ImportGenericConsumer_init_extern() -> Int32 +#else +fileprivate func bjs_ImportGenericConsumer_init_extern() -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_ImportGenericConsumer_init() -> Int32 { + return bjs_ImportGenericConsumer_init_extern() +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_ImportGenericConsumer_box_static") +fileprivate func bjs_ImportGenericConsumer_box_static_extern(_ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_ImportGenericConsumer_box_static_extern(_ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_ImportGenericConsumer_box_static(_ _generic0TypeId: Int32) -> Void { + return bjs_ImportGenericConsumer_box_static_extern(_generic0TypeId) +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_ImportGenericConsumer_identity") +fileprivate func bjs_ImportGenericConsumer_identity_extern(_ self: Int32, _ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_ImportGenericConsumer_identity_extern(_ self: Int32, _ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_ImportGenericConsumer_identity(_ self: Int32, _ _generic0TypeId: Int32) -> Void { + return bjs_ImportGenericConsumer_identity_extern(self, _generic0TypeId) +} + +func _$ImportGenericConsumer_init() throws(JSException) -> JSObject { + let ret = bjs_ImportGenericConsumer_init() + if let error = _swift_js_take_exception() { + throw error + } + return JSObject.bridgeJSLiftReturn(ret) +} + +func _$ImportGenericConsumer_box(_ value: T) throws(JSException) -> T { + value.bridgeJSStackPush() + bjs_ImportGenericConsumer_box_static(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return T.bridgeJSStackPop() +} + +func _$ImportGenericConsumer_identity(_ self: JSObject, _ value: T) throws(JSException) -> T { + value.bridgeJSStackPush() + let selfValue = self.bridgeJSLowerParameter() + bjs_ImportGenericConsumer_identity(selfValue, T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return T.bridgeJSStackPop() +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_ImportGenericBoxed_init") +fileprivate func bjs_ImportGenericBoxed_init_extern(_ _generic0TypeId: Int32) -> Int32 +#else +fileprivate func bjs_ImportGenericBoxed_init_extern(_ _generic0TypeId: Int32) -> Int32 { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_ImportGenericBoxed_init(_ _generic0TypeId: Int32) -> Int32 { + return bjs_ImportGenericBoxed_init_extern(_generic0TypeId) +} + +#if arch(wasm32) +@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_ImportGenericBoxed_unwrap") +fileprivate func bjs_ImportGenericBoxed_unwrap_extern(_ self: Int32, _ _generic0TypeId: Int32) -> Void +#else +fileprivate func bjs_ImportGenericBoxed_unwrap_extern(_ self: Int32, _ _generic0TypeId: Int32) -> Void { + fatalError("Only available on WebAssembly") +} +#endif +@inline(never) fileprivate func bjs_ImportGenericBoxed_unwrap(_ self: Int32, _ _generic0TypeId: Int32) -> Void { + return bjs_ImportGenericBoxed_unwrap_extern(self, _generic0TypeId) +} + +func _$ImportGenericBoxed_init(_ value: T) throws(JSException) -> JSObject { + value.bridgeJSStackPush() + let ret = bjs_ImportGenericBoxed_init(T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return JSObject.bridgeJSLiftReturn(ret) +} + +func _$ImportGenericBoxed_unwrap(_ self: JSObject) throws(JSException) -> T { + let selfValue = self.bridgeJSLowerParameter() + bjs_ImportGenericBoxed_unwrap(selfValue, T.bridgeJSTypeID) + if let error = _swift_js_take_exception() { + throw error + } + return T.bridgeJSStackPop() +} + #if arch(wasm32) @_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsTranslatePoint") fileprivate func bjs_jsTranslatePoint_extern(_ dx: Int32, _ dy: Int32) -> Void @@ -16713,19 +17689,19 @@ func _$jsTranslatePoint(_ point: Point, _ dx: Int, _ dy: Int) throws(JSException #if arch(wasm32) @_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsRoundTripOptionalPoint") -fileprivate func bjs_jsRoundTripOptionalPoint_extern(_ point: Int32) -> Void +fileprivate func bjs_jsRoundTripOptionalPoint_extern() -> Void #else -fileprivate func bjs_jsRoundTripOptionalPoint_extern(_ point: Int32) -> Void { +fileprivate func bjs_jsRoundTripOptionalPoint_extern() -> Void { fatalError("Only available on WebAssembly") } #endif -@inline(never) fileprivate func bjs_jsRoundTripOptionalPoint(_ point: Int32) -> Void { - return bjs_jsRoundTripOptionalPoint_extern(point) +@inline(never) fileprivate func bjs_jsRoundTripOptionalPoint() -> Void { + return bjs_jsRoundTripOptionalPoint_extern() } func _$jsRoundTripOptionalPoint(_ point: Optional) throws(JSException) -> Optional { - let pointIsSome = point.bridgeJSLowerParameter() - bjs_jsRoundTripOptionalPoint(pointIsSome) + let _ = point.bridgeJSLowerParameter() + bjs_jsRoundTripOptionalPoint() if let error = _swift_js_take_exception() { throw error } @@ -17782,50 +18758,50 @@ fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalStringUndefined_s #if arch(wasm32) @_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayNull_static") -fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayNull_static_extern(_ v: Int32) -> Void +fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayNull_static_extern() -> Void #else -fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayNull_static_extern(_ v: Int32) -> Void { +fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayNull_static_extern() -> Void { fatalError("Only available on WebAssembly") } #endif -@inline(never) fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayNull_static(_ v: Int32) -> Void { - return bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayNull_static_extern(v) +@inline(never) fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayNull_static() -> Void { + return bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayNull_static_extern() } #if arch(wasm32) @_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayUndefined_static") -fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayUndefined_static_extern(_ v: Int32) -> Void +fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayUndefined_static_extern() -> Void #else -fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayUndefined_static_extern(_ v: Int32) -> Void { +fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayUndefined_static_extern() -> Void { fatalError("Only available on WebAssembly") } #endif -@inline(never) fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayUndefined_static(_ v: Int32) -> Void { - return bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayUndefined_static_extern(v) +@inline(never) fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayUndefined_static() -> Void { + return bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayUndefined_static_extern() } #if arch(wasm32) @_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryNull_static") -fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryNull_static_extern(_ v: Int32) -> Void +fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryNull_static_extern() -> Void #else -fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryNull_static_extern(_ v: Int32) -> Void { +fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryNull_static_extern() -> Void { fatalError("Only available on WebAssembly") } #endif -@inline(never) fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryNull_static(_ v: Int32) -> Void { - return bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryNull_static_extern(v) +@inline(never) fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryNull_static() -> Void { + return bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryNull_static_extern() } #if arch(wasm32) @_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryUndefined_static") -fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryUndefined_static_extern(_ v: Int32) -> Void +fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryUndefined_static_extern() -> Void #else -fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryUndefined_static_extern(_ v: Int32) -> Void { +fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryUndefined_static_extern() -> Void { fatalError("Only available on WebAssembly") } #endif -@inline(never) fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryUndefined_static(_ v: Int32) -> Void { - return bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryUndefined_static_extern(v) +@inline(never) fileprivate func bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryUndefined_static() -> Void { + return bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryUndefined_static_extern() } #if arch(wasm32) @@ -17891,8 +18867,8 @@ func _$OptionalSupportImports_jsRoundTripOptionalStringUndefined(_ name: JSUndef } func _$OptionalSupportImports_jsRoundTripOptionalJSValueArrayNull(_ v: Optional<[JSValue]>) throws(JSException) -> Optional<[JSValue]> { - let vIsSome = v.bridgeJSLowerParameter() - bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayNull_static(vIsSome) + let _ = v.bridgeJSLowerParameter() + bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayNull_static() if let error = _swift_js_take_exception() { throw error } @@ -17900,8 +18876,8 @@ func _$OptionalSupportImports_jsRoundTripOptionalJSValueArrayNull(_ v: Optional< } func _$OptionalSupportImports_jsRoundTripOptionalJSValueArrayUndefined(_ v: JSUndefinedOr<[JSValue]>) throws(JSException) -> JSUndefinedOr<[JSValue]> { - let vIsSome = v.bridgeJSLowerParameter() - bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayUndefined_static(vIsSome) + let _ = v.bridgeJSLowerParameter() + bjs_OptionalSupportImports_jsRoundTripOptionalJSValueArrayUndefined_static() if let error = _swift_js_take_exception() { throw error } @@ -17909,8 +18885,8 @@ func _$OptionalSupportImports_jsRoundTripOptionalJSValueArrayUndefined(_ v: JSUn } func _$OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryNull(_ v: Optional<[String: String]>) throws(JSException) -> Optional<[String: String]> { - let vIsSome = v.bridgeJSLowerParameter() - bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryNull_static(vIsSome) + let _ = v.bridgeJSLowerParameter() + bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryNull_static() if let error = _swift_js_take_exception() { throw error } @@ -17918,8 +18894,8 @@ func _$OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryNull(_ } func _$OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryUndefined(_ v: JSUndefinedOr<[String: String]>) throws(JSException) -> JSUndefinedOr<[String: String]> { - let vIsSome = v.bridgeJSLowerParameter() - bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryUndefined_static(vIsSome) + let _ = v.bridgeJSLowerParameter() + bjs_OptionalSupportImports_jsRoundTripOptionalStringToStringDictionaryUndefined_static() if let error = _swift_js_take_exception() { throw error } @@ -18062,4 +19038,85 @@ func _$SwiftClassSupportImports_jsConsumeOptionalLeakCheck(_ value: Optional?, _ count: Int32) + +@_expose(wasm, "bjs_BridgeJSRuntimeTests_register_type_handles") +public func _bjs_BridgeJSRuntimeTests_register_type_handles() { + let typeIds: [Int32] = [ + JSCoordinate.bridgeJSTypeID, + NestedStructGroupA.Metadata.bridgeJSTypeID, + NestedStructGroupB.Metadata.bridgeJSTypeID, + NestedTypeHost.Label.bridgeJSTypeID, + GenericRTPoint.bridgeJSTypeID, + GenericRTNamespace.Metadata.bridgeJSTypeID, + Point.bridgeJSTypeID, + PointerFields.bridgeJSTypeID, + DataPoint.bridgeJSTypeID, + PublicPoint.bridgeJSTypeID, + Address.bridgeJSTypeID, + Contact.bridgeJSTypeID, + Config.bridgeJSTypeID, + SessionData.bridgeJSTypeID, + ValidationReport.bridgeJSTypeID, + AdvancedConfig.bridgeJSTypeID, + MeasurementConfig.bridgeJSTypeID, + MathOperations.bridgeJSTypeID, + CopyableCart.bridgeJSTypeID, + CopyableCartItem.bridgeJSTypeID, + CopyableNestedCart.bridgeJSTypeID, + ConfigStruct.bridgeJSTypeID, + Vector2D.bridgeJSTypeID, + JSObjectContainer.bridgeJSTypeID, + FooContainer.bridgeJSTypeID, + ArrayMembers.bridgeJSTypeID, + PolygonReference.bridgeJSTypeID, + TagReference.bridgeJSTypeID, + TagHolderReference.bridgeJSTypeID, + PriorityReference.bridgeJSTypeID, + ImportGenericBox.bridgeJSTypeID, + Severity.bridgeJSTypeID, + Shape.bridgeJSTypeID, + InnerTag.bridgeJSTypeID, + AsyncImportedPayloadResult.bridgeJSTypeID, + Direction.bridgeJSTypeID, + Status.bridgeJSTypeID, + Theme.bridgeJSTypeID, + HttpStatus.bridgeJSTypeID, + FileSize.bridgeJSTypeID, + SessionId.bridgeJSTypeID, + Precision.bridgeJSTypeID, + Ratio.bridgeJSTypeID, + TSDirection.bridgeJSTypeID, + TSTheme.bridgeJSTypeID, + AsyncPayloadResult.bridgeJSTypeID, + Networking.API.Method.bridgeJSTypeID, + Configuration.LogLevel.bridgeJSTypeID, + Configuration.Port.bridgeJSTypeID, + Internal.SupportedMethod.bridgeJSTypeID, + APIResult.bridgeJSTypeID, + ComplexResult.bridgeJSTypeID, + Utilities.Result.bridgeJSTypeID, + API.NetworkingResult.bridgeJSTypeID, + AllTypesResult.bridgeJSTypeID, + TypedPayloadResult.bridgeJSTypeID, + StaticCalculator.bridgeJSTypeID, + StaticPropertyEnum.bridgeJSTypeID, + NestedTypeHost.Variant.bridgeJSTypeID, + LightColor.bridgeJSTypeID, + ImportedPayloadSignal.bridgeJSTypeID, + GenericRTColor.bridgeJSTypeID, + GenericRTMode.bridgeJSTypeID, + GenericRTLevel.bridgeJSTypeID, + GenericRTOutcome.bridgeJSTypeID, + OptionalAllTypesResult.bridgeJSTypeID, + APIOptionalResult.bridgeJSTypeID, + ] + typeIds.withUnsafeBufferPointer { buffer in + _bjs_BridgeJSRuntimeTests_register_type_handles_extern(buffer.baseAddress, Int32(buffer.count)) + } +} +#endif \ No newline at end of file diff --git a/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json b/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json index e2a8575e1..8622b1cc9 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json +++ b/Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json @@ -127,6 +127,7 @@ } ] }, + "isFinal" : true, "methods" : [ { "abiName" : "bjs_PolygonReference_vertexCount", @@ -265,6 +266,7 @@ "swiftCallName" : "PolygonReference" }, { + "isFinal" : true, "methods" : [ { "abiName" : "bjs_TagReference_describe", @@ -327,6 +329,7 @@ } ] }, + "isFinal" : true, "methods" : [ { "abiName" : "bjs_TagHolderReference_describe", @@ -380,6 +383,7 @@ "swiftCallName" : "TagHolderReference" }, { + "isFinal" : true, "methods" : [ { "abiName" : "bjs_PriorityReference_describe", @@ -4840,6 +4844,169 @@ ], "swiftCallName" : "NestedTypeHost" }, + { + "constructor" : { + "abiName" : "bjs_ImportGenericBox_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + { + "label" : "value", + "name" : "value", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ] + }, + "isFinal" : true, + "methods" : [ + { + "abiName" : "bjs_ImportGenericBox_get", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "get", + "parameters" : [ + + ], + "returnType" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "name" : "ImportGenericBox", + "properties" : [ + { + "isReadonly" : false, + "isStatic" : false, + "name" : "value", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "swiftCallName" : "ImportGenericBox" + }, + { + "constructor" : { + "abiName" : "bjs_JSNameRenamedClass_init", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "parameters" : [ + { + "label" : "value", + "name" : "value", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ] + }, + "methods" : [ + { + "abiName" : "bjs_JSNameRenamedClass_doubled", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "jsName" : "doubled", + "name" : "timesTwo", + "parameters" : [ + + ], + "returnType" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + }, + { + "abiName" : "bjs_JSNameRenamedClass_static_makeWithValue", + "effects" : { + "isAsync" : false, + "isStatic" : true, + "isThrows" : false + }, + "jsName" : "makeWithValue", + "name" : "create", + "parameters" : [ + { + "label" : "value", + "name" : "value", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "returnType" : { + "swiftHeapObject" : { + "_0" : "JSNameRenamedClass" + } + }, + "staticContext" : { + "className" : { + "_0" : "JSNameRenamedClass" + } + } + } + ], + "name" : "JSNameRenamedClass", + "properties" : [ + { + "isReadonly" : false, + "isStatic" : false, + "jsName" : "current", + "name" : "value", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "swiftCallName" : "JSNameRenamedClass" + }, { "constructor" : { "abiName" : "bjs_OptionalHolder_init", @@ -10246,23 +10413,110 @@ ], "emitStyle" : "const", - "name" : "IntegerTypesSupportExports", + "name" : "GenericRTNamespace", "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "GenericRTNamespace", + "tsFullPath" : "GenericRTNamespace" + }, + { + "cases" : [ { - "abiName" : "bjs_IntegerTypesSupportExports_static_roundTripInt", - "effects" : { - "isAsync" : false, - "isStatic" : true, - "isThrows" : false - }, - "name" : "roundTripInt", - "namespace" : [ - "IntegerTypesSupportExports" + "associatedValues" : [ + ], - "parameters" : [ + "name" : "red" + }, + { + "associatedValues" : [ + + ], + "name" : "green" + }, + { + "associatedValues" : [ + + ], + "name" : "blue" + } + ], + "emitStyle" : "const", + "name" : "GenericRTColor", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "GenericRTColor", + "tsFullPath" : "GenericRTColor" + }, + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "light" + }, + { + "associatedValues" : [ + + ], + "name" : "dark" + } + ], + "emitStyle" : "const", + "name" : "GenericRTMode", + "rawType" : "String", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "GenericRTMode", + "tsFullPath" : "GenericRTMode" + }, + { + "cases" : [ + { + "associatedValues" : [ + + ], + "name" : "low", + "rawValue" : "1" + }, + { + "associatedValues" : [ + + ], + "name" : "high", + "rawValue" : "9" + } + ], + "emitStyle" : "const", + "name" : "GenericRTLevel", + "rawType" : "Int", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "GenericRTLevel", + "tsFullPath" : "GenericRTLevel" + }, + { + "cases" : [ + { + "associatedValues" : [ { - "label" : "_", - "name" : "v", + "label" : "code", "type" : { "integer" : { "_0" : { @@ -10273,24 +10527,83 @@ } } ], - "returnType" : { - "integer" : { - "_0" : { - "isSigned" : true, - "width" : "word" - } - } - }, - "staticContext" : { - "namespaceEnum" : { - "_0" : "IntegerTypesSupportExports" - } - } + "name" : "ok" }, { - "abiName" : "bjs_IntegerTypesSupportExports_static_roundTripUInt", - "effects" : { - "isAsync" : false, + "associatedValues" : [ + { + "label" : "message", + "type" : { + "string" : { + + } + } + } + ], + "name" : "fail" + } + ], + "emitStyle" : "const", + "name" : "GenericRTOutcome", + "staticMethods" : [ + + ], + "staticProperties" : [ + + ], + "swiftCallName" : "GenericRTOutcome", + "tsFullPath" : "GenericRTOutcome" + }, + { + "cases" : [ + + ], + "emitStyle" : "const", + "name" : "IntegerTypesSupportExports", + "staticMethods" : [ + { + "abiName" : "bjs_IntegerTypesSupportExports_static_roundTripInt", + "effects" : { + "isAsync" : false, + "isStatic" : true, + "isThrows" : false + }, + "name" : "roundTripInt", + "namespace" : [ + "IntegerTypesSupportExports" + ], + "parameters" : [ + { + "label" : "_", + "name" : "v", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "returnType" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + }, + "staticContext" : { + "namespaceEnum" : { + "_0" : "IntegerTypesSupportExports" + } + } + }, + { + "abiName" : "bjs_IntegerTypesSupportExports_static_roundTripUInt", + "effects" : { + "isAsync" : false, "isStatic" : true, "isThrows" : false }, @@ -16832,6 +17145,87 @@ } } }, + { + "abiName" : "bjs_renamedEcho", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "jsName" : "renamedEcho", + "name" : "jsNameEcho", + "parameters" : [ + { + "label" : "_", + "name" : "value", + "type" : { + "string" : { + + } + } + } + ], + "returnType" : { + "string" : { + + } + } + }, + { + "abiName" : "bjs_greetName", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "jsName" : "greetName", + "name" : "greet", + "parameters" : [ + { + "label" : "_", + "name" : "name", + "type" : { + "string" : { + + } + } + } + ], + "returnType" : { + "string" : { + + } + } + }, + { + "abiName" : "bjs_greetCount", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "jsName" : "greetCount", + "name" : "greet", + "parameters" : [ + { + "label" : "_", + "name" : "count", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "returnType" : { + "string" : { + + } + } + }, { "abiName" : "bjs_roundTripPointerFields", "effects" : { @@ -18288,6 +18682,82 @@ { "methods" : [ + ], + "name" : "GenericRTPoint", + "properties" : [ + { + "isReadonly" : true, + "isStatic" : false, + "name" : "x", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + }, + { + "isReadonly" : true, + "isStatic" : false, + "name" : "y", + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "swiftCallName" : "GenericRTPoint" + }, + { + "methods" : [ + + ], + "name" : "Metadata", + "namespace" : [ + "GenericRTNamespace" + ], + "properties" : [ + { + "isReadonly" : true, + "isStatic" : false, + "name" : "label", + "namespace" : [ + "GenericRTNamespace" + ], + "type" : { + "string" : { + + } + } + }, + { + "isReadonly" : true, + "isStatic" : false, + "name" : "count", + "namespace" : [ + "GenericRTNamespace" + ], + "type" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + ], + "swiftCallName" : "GenericRTNamespace.Metadata" + }, + { + "methods" : [ + ], "name" : "Point", "properties" : [ @@ -19680,6 +20150,23 @@ "_0" : "Vector2D" } } + }, + { + "abiName" : "bjs_Vector2D_describe", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : false + }, + "name" : "describe", + "parameters" : [ + + ], + "returnType" : { + "string" : { + + } + } } ], "name" : "Vector2D", @@ -23578,6 +24065,498 @@ ] }, + { + "functions" : [ + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "jsGenericRoundTrip", + "parameters" : [ + { + "name" : "value", + "type" : { + "generic" : { + "_0" : "T" + } + } + } + ], + "returnType" : { + "generic" : { + "_0" : "T" + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "jsGenericRoundTripClass", + "parameters" : [ + { + "name" : "value", + "type" : { + "generic" : { + "_0" : "T" + } + } + } + ], + "returnType" : { + "generic" : { + "_0" : "T" + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "jsGenericParsePoint", + "parameters" : [ + { + "name" : "json", + "type" : { + "string" : { + + } + } + } + ], + "returnType" : { + "generic" : { + "_0" : "T" + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "jsImportPickFirst", + "parameters" : [ + { + "name" : "a", + "type" : { + "generic" : { + "_0" : "T" + } + } + }, + { + "name" : "b", + "type" : { + "generic" : { + "_0" : "T" + } + } + } + ], + "returnType" : { + "generic" : { + "_0" : "T" + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "jsImportMakeInt", + "parameters" : [ + + ], + "returnType" : { + "generic" : { + "_0" : "T" + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T", + "U" + ], + "name" : "jsImportCombineSecond", + "parameters" : [ + { + "name" : "a", + "type" : { + "generic" : { + "_0" : "T" + } + } + }, + { + "name" : "b", + "type" : { + "generic" : { + "_0" : "U" + } + } + } + ], + "returnType" : { + "generic" : { + "_0" : "U" + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "jsGenericArrayRoundTrip", + "parameters" : [ + { + "name" : "values", + "type" : { + "array" : { + "_0" : { + "generic" : { + "_0" : "T" + } + } + } + } + } + ], + "returnType" : { + "array" : { + "_0" : { + "generic" : { + "_0" : "T" + } + } + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "jsGenericOptionalRoundTrip", + "parameters" : [ + { + "name" : "value", + "type" : { + "nullable" : { + "_0" : { + "generic" : { + "_0" : "T" + } + }, + "_1" : "null" + } + } + } + ], + "returnType" : { + "nullable" : { + "_0" : { + "generic" : { + "_0" : "T" + } + }, + "_1" : "null" + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "jsGenericDictRoundTrip", + "parameters" : [ + { + "name" : "values", + "type" : { + "dictionary" : { + "_0" : { + "generic" : { + "_0" : "T" + } + } + } + } + } + ], + "returnType" : { + "dictionary" : { + "_0" : { + "generic" : { + "_0" : "T" + } + } + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "jsGenericAfterOptionalArray", + "parameters" : [ + { + "name" : "values", + "type" : { + "nullable" : { + "_0" : { + "array" : { + "_0" : { + "integer" : { + "_0" : { + "isSigned" : true, + "width" : "word" + } + } + } + } + }, + "_1" : "null" + } + } + }, + { + "name" : "value", + "type" : { + "generic" : { + "_0" : "T" + } + } + } + ], + "returnType" : { + "string" : { + + } + } + }, + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "jsGenericThrowOrRoundTrip", + "parameters" : [ + { + "name" : "shouldThrow", + "type" : { + "bool" : { + + } + } + }, + { + "name" : "value", + "type" : { + "generic" : { + "_0" : "T" + } + } + } + ], + "returnType" : { + "generic" : { + "_0" : "T" + } + } + } + ], + "types" : [ + { + "accessLevel" : "internal", + "constructor" : { + "accessLevel" : "internal", + "parameters" : [ + + ] + }, + "getters" : [ + + ], + "methods" : [ + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "identity", + "parameters" : [ + { + "name" : "value", + "type" : { + "generic" : { + "_0" : "T" + } + } + } + ], + "returnType" : { + "generic" : { + "_0" : "T" + } + } + } + ], + "name" : "ImportGenericConsumer", + "setters" : [ + + ], + "staticMethods" : [ + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "box", + "parameters" : [ + { + "name" : "value", + "type" : { + "generic" : { + "_0" : "T" + } + } + } + ], + "returnType" : { + "generic" : { + "_0" : "T" + } + } + } + ] + }, + { + "accessLevel" : "internal", + "constructor" : { + "accessLevel" : "internal", + "genericParameters" : [ + "T" + ], + "parameters" : [ + { + "name" : "value", + "type" : { + "generic" : { + "_0" : "T" + } + } + } + ] + }, + "getters" : [ + + ], + "methods" : [ + { + "accessLevel" : "internal", + "effects" : { + "isAsync" : false, + "isStatic" : false, + "isThrows" : true + }, + "genericParameters" : [ + "T" + ], + "name" : "unwrap", + "parameters" : [ + + ], + "returnType" : { + "generic" : { + "_0" : "T" + } + } + } + ], + "name" : "ImportGenericBoxed", + "setters" : [ + + ], + "staticMethods" : [ + + ] + } + ] + }, { "functions" : [ { diff --git a/Tests/BridgeJSRuntimeTests/ImportGenericAPIs.swift b/Tests/BridgeJSRuntimeTests/ImportGenericAPIs.swift new file mode 100644 index 000000000..bfd63839f --- /dev/null +++ b/Tests/BridgeJSRuntimeTests/ImportGenericAPIs.swift @@ -0,0 +1,280 @@ +import Testing +import JavaScriptKit + +@JS struct GenericRTPoint { + var x: Int + var y: Int +} + +@JS enum GenericRTNamespace { + @JS struct Metadata { + var label: String + var count: Int + } +} + +@JS enum GenericRTColor { + case red + case green + case blue +} + +@JS enum GenericRTMode: String { + case light + case dark +} + +@JS enum GenericRTLevel: Int { + case low = 1 + case high = 9 +} + +@JS enum GenericRTOutcome { + case ok(code: Int) + case fail(message: String) +} + +@JS final class ImportGenericBox { + @JS var value: Int + @JS init(value: Int) { + self.value = value + } + @JS func get() -> Int { + value + } +} + +@JSFunction func jsGenericRoundTrip(_ value: T) throws(JSException) -> T +@JSFunction func jsGenericRoundTripClass(_ value: T) throws(JSException) -> T +@JSFunction func jsGenericParsePoint(_ json: String) throws(JSException) -> T +@JSFunction func jsImportPickFirst(_ a: T, _ b: T) throws(JSException) -> T +@JSFunction func jsImportMakeInt() throws(JSException) -> T +@JSFunction func jsImportCombineSecond( + _ a: T, + _ b: U +) throws(JSException) -> U +@JSFunction func jsGenericArrayRoundTrip(_ values: [T]) throws(JSException) -> [T] +@JSFunction func jsGenericOptionalRoundTrip(_ value: T?) throws(JSException) -> T? +@JSFunction func jsGenericDictRoundTrip( + _ values: [String: T] +) throws(JSException) -> [String: T] +@JSFunction func jsGenericAfterOptionalArray( + _ values: [Int]?, + _ value: T +) throws(JSException) -> String + +@JSClass struct ImportGenericConsumer { + @JSFunction init() throws(JSException) + @JSFunction func identity(_ value: T) throws(JSException) -> T + @JSFunction static func box(_ value: T) throws(JSException) -> T +} + +@JSFunction func jsGenericThrowOrRoundTrip( + _ shouldThrow: Bool, + _ value: T +) throws(JSException) -> T + +@JSClass struct ImportGenericBoxed { + @JSFunction init(_ value: T) throws(JSException) + @JSFunction func unwrap() throws(JSException) -> T +} + +@Suite struct ImportGenericAPITests { + @Test func genericRoundTripScalars() throws { + #expect(try jsGenericRoundTrip(42) == 42) + #expect(try jsGenericRoundTrip(-7) == -7) + #expect(try jsGenericRoundTrip(3.5) == 3.5) + #expect(try jsGenericRoundTrip(Float(1.25)) == Float(1.25)) + #expect(try jsGenericRoundTrip(true) == true) + #expect(try jsGenericRoundTrip(false) == false) + #expect(try jsGenericRoundTrip("hello") == "hello") + #expect(try jsGenericRoundTrip("") == "") + } + + @Test func genericRoundTripNumerics() throws { + #expect(try jsGenericRoundTrip(Int8(-5)) == Int8(-5)) + #expect(try jsGenericRoundTrip(Int8.min) == Int8.min) + #expect(try jsGenericRoundTrip(Int8.max) == Int8.max) + #expect(try jsGenericRoundTrip(UInt8(200)) == UInt8(200)) + #expect(try jsGenericRoundTrip(UInt8.max) == UInt8.max) + #expect(try jsGenericRoundTrip(Int16(-1000)) == Int16(-1000)) + #expect(try jsGenericRoundTrip(UInt16(60000)) == UInt16(60000)) + #expect(try jsGenericRoundTrip(Int32(-123456)) == Int32(-123456)) + #expect(try jsGenericRoundTrip(UInt32(3_000_000_000)) == UInt32(3_000_000_000)) + #expect(try jsGenericRoundTrip(UInt32.max) == UInt32.max) + #expect(try jsGenericRoundTrip(UInt(42)) == UInt(42)) + #expect(try jsGenericRoundTrip(UInt(4_000_000_000)) == UInt(4_000_000_000)) + #expect(try jsGenericRoundTrip(Int64(-9_000_000_000)) == Int64(-9_000_000_000)) + #expect(try jsGenericRoundTrip(Int64.min) == Int64.min) + #expect(try jsGenericRoundTrip(Int64.max) == Int64.max) + #expect(try jsGenericRoundTrip(UInt64(18_000_000_000_000_000_000)) == UInt64(18_000_000_000_000_000_000)) + #expect(try jsGenericRoundTrip(UInt64.max) == UInt64.max) + } + + @Test func genericRoundTripJSValue() throws { + let number = try jsGenericRoundTrip(JSValue.number(3.5)) + #expect(number.number == 3.5) + let string = try jsGenericRoundTrip(JSValue.string("hi")) + #expect(string.string == "hi") + let boolean = try jsGenericRoundTrip(JSValue.boolean(true)) + #expect(boolean.boolean == true) + #expect(try jsGenericRoundTrip(JSValue.null).isNull) + #expect(try jsGenericRoundTrip(JSValue.undefined).isUndefined) + let object = JSObject.global.Object.function!.new() + object.tag = 7 + let roundTripped = try jsGenericRoundTrip(JSValue.object(object)) + #expect(roundTripped.object?.tag.number == 7) + } + + @Test func genericWrappedRoundTrip() throws { + #expect(try jsGenericArrayRoundTrip([1, 2, 3]) == [1, 2, 3]) + #expect(try jsGenericArrayRoundTrip(["a", "b"]) == ["a", "b"]) + #expect(try jsGenericArrayRoundTrip([Int]()) == []) + #expect(try jsGenericOptionalRoundTrip(Optional.some(7)) == 7) + #expect(try jsGenericOptionalRoundTrip(Optional.none) == nil) + #expect(try jsGenericOptionalRoundTrip(Optional.some("hi")) == "hi") + let outcome = try jsGenericOptionalRoundTrip(Optional.some(.ok(code: 5))) + guard case .some(.ok(let code)) = outcome else { + Issue.record("expected .ok") + return + } + #expect(code == 5) + #expect(try jsGenericOptionalRoundTrip(Optional.none) == nil) + #expect(try jsGenericDictRoundTrip(["x": 1, "y": 2]) == ["x": 1, "y": 2]) + #expect(try jsGenericDictRoundTrip([String: String]()) == [:]) + } + + @Test func genericRoundTripEnums() throws { + #expect(try jsGenericRoundTrip(GenericRTColor.red) == .red) + #expect(try jsGenericRoundTrip(GenericRTColor.blue) == .blue) + #expect(try jsGenericRoundTrip(GenericRTMode.dark) == .dark) + #expect(try jsGenericRoundTrip(GenericRTMode.light).rawValue == "light") + #expect(try jsGenericRoundTrip(GenericRTLevel.high) == .high) + let outcome = try jsGenericRoundTrip(GenericRTOutcome.ok(code: 42)) + guard case .ok(let code) = outcome else { + Issue.record("expected .ok") + return + } + #expect(code == 42) + let failure = try jsGenericRoundTrip(GenericRTOutcome.fail(message: "boom")) + guard case .fail(let message) = failure else { + Issue.record("expected .fail") + return + } + #expect(message == "boom") + } + + @Test func genericRoundTripStruct() throws { + let point = try jsGenericRoundTrip(GenericRTPoint(x: 1, y: 2)) + #expect(point.x == 1) + #expect(point.y == 2) + } + + @Test func genericRoundTripNestedStruct() throws { + let metadata = try jsGenericRoundTrip(GenericRTNamespace.Metadata(label: "alpha", count: 7)) + #expect(metadata.label == "alpha") + #expect(metadata.count == 7) + } + + @Test func genericParse() throws { + let point: GenericRTPoint = try jsGenericParsePoint("{\"x\": 10, \"y\": 20}") + #expect(point.x == 10) + #expect(point.y == 20) + let n: Int = try jsGenericParsePoint("42") + #expect(n == 42) + let string: String = try jsGenericParsePoint("\"hi\"") + #expect(string == "hi") + } + + @Test func genericPickFirstMultiUse() throws { + #expect(try jsImportPickFirst(10, 20) as Int == 10) + #expect(try jsImportPickFirst("a", "b") as String == "a") + let firstPoint = try jsImportPickFirst(GenericRTPoint(x: 1, y: 2), GenericRTPoint(x: 3, y: 4)) + #expect(firstPoint.x == 1) + #expect(firstPoint.y == 2) + } + + @Test func genericMakeReturnOnly() throws { + let made: Int = try jsImportMakeInt() + #expect(made == 123) + } + + @Test func genericCombineSecondMultiParameter() throws { + #expect(try jsImportCombineSecond(7, "hello") as String == "hello") + #expect(try jsImportCombineSecond("x", 9) as Int == 9) + let point = try jsImportCombineSecond(42, GenericRTPoint(x: 5, y: 6)) + #expect(point.x == 5) + #expect(point.y == 6) + } + + @Test func genericRoundTripHeapObjectClass() throws { + let box = ImportGenericBox(value: 314) + #expect(box.get() == 314) + let sameBox = try jsGenericRoundTripClass(box) + #expect(sameBox.get() == 314) + sameBox.value = 271 + #expect(box.get() == 271) + } + + @Test func genericMixedConsecutiveCalls() throws { + #expect(try jsGenericRoundTrip(1) == 1) + #expect(try jsGenericRoundTrip("two") == "two") + #expect(try jsGenericRoundTrip(3.0) == 3.0) + let p = try jsGenericRoundTrip(GenericRTPoint(x: 4, y: 5)) + #expect(p.x == 4) + #expect(p.y == 5) + } + + @Test func importGenericInstanceMethod() throws { + let consumer = try ImportGenericConsumer() + #expect(try consumer.identity(42) == 42) + #expect(try consumer.identity(-7) == -7) + #expect(try consumer.identity("hi") == "hi") + #expect(try consumer.identity(true) == true) + #expect(try consumer.identity(false) == false) + let point = try consumer.identity(GenericRTPoint(x: 3, y: 4)) + #expect(point.x == 3) + #expect(point.y == 4) + } + + /// A generic parameter shares the stacks with any other stack-lowered + /// parameter, so both have to arrive in declaration order. + @Test func genericAlongsideOptionalArray() throws { + #expect(try jsGenericAfterOptionalArray([1, 2], 42) == "[1,2]|42") + #expect(try jsGenericAfterOptionalArray([1, 2], GenericRTPoint(x: 3, y: 4)) == #"[1,2]|{"x":3,"y":4}"#) + #expect(try jsGenericAfterOptionalArray(nil, "x") == #"null|"x""#) + } + + @Test func genericImportPropagatesJSException() throws { + #expect(try jsGenericThrowOrRoundTrip(false, 42) == 42) + #expect(try jsGenericThrowOrRoundTrip(false, GenericRTPoint(x: 1, y: 2)).x == 1) + do { + let _: Int = try jsGenericThrowOrRoundTrip(true, 0) + Issue.record("Expected exception") + } catch { + #expect(error.description.contains("TestError")) + } + // A throwing generic call must not strand its argument on the shared + // stack: the next call has to read its own value back. + #expect(try jsGenericThrowOrRoundTrip(false, GenericRTPoint(x: 7, y: 8)).y == 8) + } + + @Test func importGenericConstructor() throws { + let boxedInt = try ImportGenericBoxed(42) + #expect(try boxedInt.unwrap() == 42) + let boxedText = try ImportGenericBoxed("boxed") + #expect(try boxedText.unwrap() == "boxed") + let boxedPoint = try ImportGenericBoxed(GenericRTPoint(x: 1, y: 2)) + let point: GenericRTPoint = try boxedPoint.unwrap() + #expect(point.x == 1) + #expect(point.y == 2) + } + + @Test func importGenericStaticMethod() throws { + #expect(try ImportGenericConsumer.box(7) == 7) + #expect(try ImportGenericConsumer.box("s") == "s") + #expect(try ImportGenericConsumer.box(true) == true) + let color = try ImportGenericConsumer.box(GenericRTColor.green) + #expect(color == .green) + } +} diff --git a/Tests/BridgeJSRuntimeTests/JSNameAPIs.swift b/Tests/BridgeJSRuntimeTests/JSNameAPIs.swift new file mode 100644 index 000000000..48efcff59 --- /dev/null +++ b/Tests/BridgeJSRuntimeTests/JSNameAPIs.swift @@ -0,0 +1,34 @@ +import JavaScriptKit + +@JS("renamedEcho") func jsNameEcho(_ value: String) -> String { + return "echo: \(value)" +} + +@JS("greetName") func greet(_ name: String) -> String { + return "Hello, \(name)!" +} + +@JS("greetCount") func greet(_ count: Int) -> String { + return "Hello, \(count) people!" +} + +@JS class JSNameRenamedClass { + private var storage: Int + + @JS init(value: Int) { + self.storage = value + } + + @JS("current") var value: Int { + get { storage } + set { storage = newValue } + } + + @JS("doubled") func timesTwo() -> Int { + return storage * 2 + } + + @JS("makeWithValue") static func create(value: Int) -> JSNameRenamedClass { + return JSNameRenamedClass(value: value) + } +} diff --git a/Tests/BridgeJSRuntimeTests/StructAPIs.swift b/Tests/BridgeJSRuntimeTests/StructAPIs.swift index c2216c808..e11856d41 100644 --- a/Tests/BridgeJSRuntimeTests/StructAPIs.swift +++ b/Tests/BridgeJSRuntimeTests/StructAPIs.swift @@ -200,6 +200,10 @@ extension Vector2D { @JS func scaled(by factor: Double) -> Vector2D { return Vector2D(dx: dx * factor, dy: dy * factor) } + + @JS func describe() -> String { + return "Vector2D(\(dx), \(dy))" + } } @JS func roundTripDataPoint(_ data: DataPoint) -> DataPoint { diff --git a/Tests/prelude.mjs b/Tests/prelude.mjs index 42a0e3ea4..b7e21e821 100644 --- a/Tests/prelude.mjs +++ b/Tests/prelude.mjs @@ -161,6 +161,38 @@ export async function setupOptions(options, context) { jsJoinOptionalStructThenArray: joinStackParams, jsJoinEnumThenArray: joinStackParams, jsJoinStringThenStackParams: joinStackParams, + jsGenericRoundTrip: (v) => v, + jsGenericRoundTripClass: (v) => v, + jsGenericParsePoint: (json) => JSON.parse(json), + jsImportPickFirst: (a, b) => a, + jsImportMakeInt: () => 123, + jsImportCombineSecond: (a, b) => b, + jsGenericThrowOrRoundTrip: (shouldThrow, v) => { + if (shouldThrow) { + throw new Error("TestError"); + } + return v; + }, + jsGenericArrayRoundTrip: (v) => v, + jsGenericOptionalRoundTrip: (v) => v, + jsGenericDictRoundTrip: (v) => v, + jsGenericAfterOptionalArray: (a, b) => `${JSON.stringify(a)}|${JSON.stringify(b)}`, + ImportGenericConsumer: class { + identity(value) { + return value; + } + static box(value) { + return value; + } + }, + ImportGenericBoxed: class { + constructor(value) { + this.value = value; + } + unwrap() { + return this.value; + } + }, roundTripArrayMembers: (value) => { return value; }, @@ -281,6 +313,18 @@ function BridgeJSRuntimeTests_runJsWorks(instance, exports) { assert.equal(exports.roundTripUnsafeMutablePointer(p), p); } + assert.equal(exports.renamedEcho("hi"), "echo: hi"); + assert.equal(exports.jsNameEcho, undefined); + assert.equal(exports.greetName("John"), "Hello, John!"); + assert.equal(exports.greetCount(3), "Hello, 3 people!"); + const renamed = new exports.JSNameRenamedClass(21); + assert.equal(renamed.doubled(), 42); + assert.equal(renamed.current, 21); + renamed.current = 5; + assert.equal(renamed.doubled(), 10); + const madeRenamed = exports.JSNameRenamedClass.makeWithValue(7); + assert.equal(madeRenamed.current, 7); + const g = new exports.Greeter("John"); assert.equal(g.greet(), "Hello, John!"); @@ -871,6 +915,7 @@ function testStructSupport(exports) { const scaled = vec.scaled(2.0); assert.equal(scaled.dx, 6.0); assert.equal(scaled.dy, 8.0); + assert.equal(vec.describe(), "Vector2D(3.0, 4.0)"); const publicPoint = { x: 9, y: -3 }; assert.deepEqual(exports.roundTripPublicPoint(publicPoint), publicPoint);