diff --git a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift index 0680a3d3..b2bdbe84 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift @@ -134,6 +134,12 @@ struct BridgeJSLink { target.set(tmpRetBytes); tmpRetBytes = undefined; } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } \(importObjectBuilders.flatMap { $0.importedLines }.map { $0.indent(count: 12) }.joined(separator: "\n")) }, setInstance: (i) => { diff --git a/Plugins/BridgeJS/Sources/BridgeJSTool/ExportSwift.swift b/Plugins/BridgeJS/Sources/BridgeJSTool/ExportSwift.swift index 2e0180fa..25b1ed01 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSTool/ExportSwift.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSTool/ExportSwift.swift @@ -221,11 +221,9 @@ class ExportSwift { return nil } guard let typeDecl = typeDeclResolver.lookupType(for: identifier) else { - print("Failed to lookup type \(type.trimmedDescription): not found in typeDeclResolver") return nil } guard typeDecl.is(ClassDeclSyntax.self) || typeDecl.is(ActorDeclSyntax.self) else { - print("Failed to lookup type \(type.trimmedDescription): is not a class or actor") return nil } return .swiftHeapObject(typeDecl.name.text) @@ -237,10 +235,16 @@ class ExportSwift { // // To update this file, just rebuild your project or run // `swift package bridge-js`. + + @_spi(JSObject_id) import JavaScriptKit + @_extern(wasm, module: "bjs", name: "return_string") private func _return_string(_ ptr: UnsafePointer?, _ len: Int32) @_extern(wasm, module: "bjs", name: "init_memory") private func _init_memory(_ sourceId: Int32, _ ptr: UnsafeMutablePointer?) + + @_extern(wasm, module: "bjs", name: "swift_js_retain") + private func _swift_js_retain(_ ptr: Int32) -> Int32 """ func renderSwiftGlue() -> String? { @@ -317,11 +321,19 @@ class ExportSwift { ) abiParameterSignatures.append((bytesLabel, .i32)) abiParameterSignatures.append((lengthLabel, .i32)) - case .jsObject: + case .jsObject(nil): abiParameterForwardings.append( LabeledExprSyntax( label: param.label, - expression: ExprSyntax("\(raw: param.name)") + expression: ExprSyntax("JSObject(id: UInt32(bitPattern: \(raw: param.name)))") + ) + ) + abiParameterSignatures.append((param.name, .i32)) + case .jsObject(let name): + abiParameterForwardings.append( + LabeledExprSyntax( + label: param.label, + expression: ExprSyntax("\(raw: name)(takingThis: UInt32(bitPattern: \(raw: param.name)))") ) ) abiParameterSignatures.append((param.name, .i32)) @@ -404,10 +416,16 @@ class ExportSwift { } """ ) - case .jsObject: + case .jsObject(nil): + body.append( + """ + return _swift_js_retain(Int32(bitPattern: ret.id)) + """ + ) + case .jsObject(_?): body.append( """ - return ret.id + return _swift_js_retain(Int32(bitPattern: ret.this.id)) """ ) case .swiftHeapObject: @@ -566,6 +584,8 @@ extension BridgeType { self = .bool case "Void": self = .void + case "JSObject": + self = .jsObject(nil) default: return nil } diff --git a/Plugins/BridgeJS/Sources/BridgeJSTool/ImportTS.swift b/Plugins/BridgeJS/Sources/BridgeJSTool/ImportTS.swift index bf269a95..77198dab 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSTool/ImportTS.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSTool/ImportTS.swift @@ -333,9 +333,6 @@ struct ImportTS { @_extern(wasm, module: "bjs", name: "init_memory_with_result") private func _init_memory_with_result(_ ptr: UnsafePointer?, _ len: Int32) - - @_extern(wasm, module: "bjs", name: "free_jsobject") - private func _free_jsobject(_ ptr: Int32) -> Void """ func renderSwiftThunk( diff --git a/Plugins/BridgeJS/Sources/JavaScript/src/processor.js b/Plugins/BridgeJS/Sources/JavaScript/src/processor.js index d4c72d28..0f97ea14 100644 --- a/Plugins/BridgeJS/Sources/JavaScript/src/processor.js +++ b/Plugins/BridgeJS/Sources/JavaScript/src/processor.js @@ -238,7 +238,8 @@ export class TypeProcessor { for (const member of node.members) { if (ts.isPropertyDeclaration(member)) { - // TODO + const property = this.visitPropertyDecl(member); + if (property) properties.push(property); } else if (ts.isMethodDeclaration(member)) { const decl = this.visitFunctionLikeDecl(member); if (decl) methods.push(decl); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/TypeScriptClass.d.ts b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/TypeScriptClass.d.ts index d10c0138..074772f2 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/TypeScriptClass.d.ts +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/Inputs/TypeScriptClass.d.ts @@ -1,4 +1,6 @@ export class Greeter { + name: string; + readonly age: number; constructor(name: string); greet(): string; changeName(name: string): void; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayParameter.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayParameter.Import.js index caad458d..73ef604f 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayParameter.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayParameter.Import.js @@ -35,6 +35,12 @@ export async function createInstantiator(options, swift) { target.set(tmpRetBytes); tmpRetBytes = undefined; } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } const TestModule = importObject["TestModule"] = {}; TestModule["bjs_checkArray"] = function bjs_checkArray(a) { options.imports.checkArray(swift.memory.getObject(a)); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Interface.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Interface.Import.js index 4b381185..940c565f 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Interface.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Interface.Import.js @@ -35,6 +35,12 @@ export async function createInstantiator(options, swift) { target.set(tmpRetBytes); tmpRetBytes = undefined; } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } const TestModule = importObject["TestModule"] = {}; TestModule["bjs_returnAnimatable"] = function bjs_returnAnimatable() { let ret = options.imports.returnAnimatable(); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Export.js index 2d9ee4b1..a5b206c5 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Export.js @@ -35,6 +35,12 @@ export async function createInstantiator(options, swift) { target.set(tmpRetBytes); tmpRetBytes = undefined; } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } }, setInstance: (i) => { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Import.js index 0d871bbb..7217750a 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.Import.js @@ -35,6 +35,12 @@ export async function createInstantiator(options, swift) { target.set(tmpRetBytes); tmpRetBytes = undefined; } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } const TestModule = importObject["TestModule"] = {}; TestModule["bjs_check"] = function bjs_check(a, b) { options.imports.check(a, b); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Export.js index 8a66f041..3480cc97 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Export.js @@ -35,6 +35,12 @@ export async function createInstantiator(options, swift) { target.set(tmpRetBytes); tmpRetBytes = undefined; } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } }, setInstance: (i) => { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Import.js index a638f864..5aba76f1 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.Import.js @@ -35,6 +35,12 @@ export async function createInstantiator(options, swift) { target.set(tmpRetBytes); tmpRetBytes = undefined; } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } const TestModule = importObject["TestModule"] = {}; TestModule["bjs_checkNumber"] = function bjs_checkNumber() { let ret = options.imports.checkNumber(); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Export.js index c13cd358..c9397bbd 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Export.js @@ -35,6 +35,12 @@ export async function createInstantiator(options, swift) { target.set(tmpRetBytes); tmpRetBytes = undefined; } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } }, setInstance: (i) => { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Import.js index 6e5d4bdc..5b9808f6 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.Import.js @@ -35,6 +35,12 @@ export async function createInstantiator(options, swift) { target.set(tmpRetBytes); tmpRetBytes = undefined; } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } const TestModule = importObject["TestModule"] = {}; TestModule["bjs_checkString"] = function bjs_checkString(a) { const aObject = swift.memory.getObject(a); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Export.js index 0208d8ce..caa68521 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Export.js @@ -35,6 +35,12 @@ export async function createInstantiator(options, swift) { target.set(tmpRetBytes); tmpRetBytes = undefined; } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } }, setInstance: (i) => { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Import.js index 26e57959..dfc6f048 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.Import.js @@ -35,6 +35,12 @@ export async function createInstantiator(options, swift) { target.set(tmpRetBytes); tmpRetBytes = undefined; } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } const TestModule = importObject["TestModule"] = {}; TestModule["bjs_checkString"] = function bjs_checkString() { let ret = options.imports.checkString(); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.Export.js index 971b9d69..6b30cd68 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.Export.js @@ -35,6 +35,12 @@ export async function createInstantiator(options, swift) { target.set(tmpRetBytes); tmpRetBytes = undefined; } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } }, setInstance: (i) => { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeAlias.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeAlias.Import.js index e5909f6c..71133762 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeAlias.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeAlias.Import.js @@ -35,6 +35,12 @@ export async function createInstantiator(options, swift) { target.set(tmpRetBytes); tmpRetBytes = undefined; } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } const TestModule = importObject["TestModule"] = {}; TestModule["bjs_checkSimple"] = function bjs_checkSimple(a) { options.imports.checkSimple(a); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeScriptClass.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeScriptClass.Import.js index 2111af96..f86e6054 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeScriptClass.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/TypeScriptClass.Import.js @@ -35,6 +35,12 @@ export async function createInstantiator(options, swift) { target.set(tmpRetBytes); tmpRetBytes = undefined; } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } const TestModule = importObject["TestModule"] = {}; TestModule["bjs_Greeter_init"] = function bjs_Greeter_init(name) { const nameObject = swift.memory.getObject(name); @@ -42,6 +48,20 @@ export async function createInstantiator(options, swift) { let ret = new options.imports.Greeter(nameObject); return swift.memory.retain(ret); } + TestModule["bjs_Greeter_name_get"] = function bjs_Greeter_name_get(self) { + let ret = swift.memory.getObject(self).name; + tmpRetBytes = textEncoder.encode(ret); + return tmpRetBytes.length; + } + TestModule["bjs_Greeter_name_set"] = function bjs_Greeter_name_set(self, newValue) { + const newValueObject = swift.memory.getObject(newValue); + swift.memory.release(newValue); + swift.memory.getObject(self).name = newValueObject; + } + TestModule["bjs_Greeter_age_get"] = function bjs_Greeter_age_get(self) { + let ret = swift.memory.getObject(self).age; + return ret; + } TestModule["bjs_Greeter_greet"] = function bjs_Greeter_greet(self) { let ret = swift.memory.getObject(self).greet(); tmpRetBytes = textEncoder.encode(ret); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Export.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Export.js index a3dae190..166eeed0 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Export.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Export.js @@ -35,6 +35,12 @@ export async function createInstantiator(options, swift) { target.set(tmpRetBytes); tmpRetBytes = undefined; } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } }, setInstance: (i) => { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Import.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Import.js index db9312aa..91b344c3 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Import.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.Import.js @@ -35,6 +35,12 @@ export async function createInstantiator(options, swift) { target.set(tmpRetBytes); tmpRetBytes = undefined; } + bjs["swift_js_retain"] = function(id) { + return swift.memory.retainByRef(id); + } + bjs["swift_js_release"] = function(id) { + swift.memory.release(id); + } const TestModule = importObject["TestModule"] = {}; TestModule["bjs_check"] = function bjs_check() { options.imports.check(); diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveParameters.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveParameters.swift index 6df14156..5181eece 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveParameters.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveParameters.swift @@ -3,11 +3,17 @@ // // To update this file, just rebuild your project or run // `swift package bridge-js`. + +@_spi(JSObject_id) import JavaScriptKit + @_extern(wasm, module: "bjs", name: "return_string") private func _return_string(_ ptr: UnsafePointer?, _ len: Int32) @_extern(wasm, module: "bjs", name: "init_memory") private func _init_memory(_ sourceId: Int32, _ ptr: UnsafeMutablePointer?) +@_extern(wasm, module: "bjs", name: "swift_js_retain") +private func _swift_js_retain(_ ptr: Int32) -> Int32 + @_expose(wasm, "bjs_check") @_cdecl("bjs_check") public func _bjs_check(a: Int32, b: Float32, c: Float64, d: Int32) -> Void { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveReturn.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveReturn.swift index a24b2b31..fb624231 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveReturn.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/PrimitiveReturn.swift @@ -3,11 +3,17 @@ // // To update this file, just rebuild your project or run // `swift package bridge-js`. + +@_spi(JSObject_id) import JavaScriptKit + @_extern(wasm, module: "bjs", name: "return_string") private func _return_string(_ ptr: UnsafePointer?, _ len: Int32) @_extern(wasm, module: "bjs", name: "init_memory") private func _init_memory(_ sourceId: Int32, _ ptr: UnsafeMutablePointer?) +@_extern(wasm, module: "bjs", name: "swift_js_retain") +private func _swift_js_retain(_ ptr: Int32) -> Int32 + @_expose(wasm, "bjs_checkInt") @_cdecl("bjs_checkInt") public func _bjs_checkInt() -> Int32 { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StringParameter.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StringParameter.swift index 080f028e..d16cd81c 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StringParameter.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StringParameter.swift @@ -3,11 +3,17 @@ // // To update this file, just rebuild your project or run // `swift package bridge-js`. + +@_spi(JSObject_id) import JavaScriptKit + @_extern(wasm, module: "bjs", name: "return_string") private func _return_string(_ ptr: UnsafePointer?, _ len: Int32) @_extern(wasm, module: "bjs", name: "init_memory") private func _init_memory(_ sourceId: Int32, _ ptr: UnsafeMutablePointer?) +@_extern(wasm, module: "bjs", name: "swift_js_retain") +private func _swift_js_retain(_ ptr: Int32) -> Int32 + @_expose(wasm, "bjs_checkString") @_cdecl("bjs_checkString") public func _bjs_checkString(aBytes: Int32, aLen: Int32) -> Void { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StringReturn.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StringReturn.swift index bf0be042..4f3a9e89 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StringReturn.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/StringReturn.swift @@ -3,11 +3,17 @@ // // To update this file, just rebuild your project or run // `swift package bridge-js`. + +@_spi(JSObject_id) import JavaScriptKit + @_extern(wasm, module: "bjs", name: "return_string") private func _return_string(_ ptr: UnsafePointer?, _ len: Int32) @_extern(wasm, module: "bjs", name: "init_memory") private func _init_memory(_ sourceId: Int32, _ ptr: UnsafeMutablePointer?) +@_extern(wasm, module: "bjs", name: "swift_js_retain") +private func _swift_js_retain(_ ptr: Int32) -> Int32 + @_expose(wasm, "bjs_checkString") @_cdecl("bjs_checkString") public func _bjs_checkString() -> Void { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftClass.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftClass.swift index 20fd9c94..fa0190f7 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftClass.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/SwiftClass.swift @@ -3,11 +3,17 @@ // // To update this file, just rebuild your project or run // `swift package bridge-js`. + +@_spi(JSObject_id) import JavaScriptKit + @_extern(wasm, module: "bjs", name: "return_string") private func _return_string(_ ptr: UnsafePointer?, _ len: Int32) @_extern(wasm, module: "bjs", name: "init_memory") private func _init_memory(_ sourceId: Int32, _ ptr: UnsafeMutablePointer?) +@_extern(wasm, module: "bjs", name: "swift_js_retain") +private func _swift_js_retain(_ ptr: Int32) -> Int32 + @_expose(wasm, "bjs_takeGreeter") @_cdecl("bjs_takeGreeter") public func _bjs_takeGreeter(greeter: UnsafeMutableRawPointer) -> Void { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/VoidParameterVoidReturn.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/VoidParameterVoidReturn.swift index cf4b76fe..a500740c 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/VoidParameterVoidReturn.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ExportSwiftTests/VoidParameterVoidReturn.swift @@ -3,11 +3,17 @@ // // To update this file, just rebuild your project or run // `swift package bridge-js`. + +@_spi(JSObject_id) import JavaScriptKit + @_extern(wasm, module: "bjs", name: "return_string") private func _return_string(_ ptr: UnsafePointer?, _ len: Int32) @_extern(wasm, module: "bjs", name: "init_memory") private func _init_memory(_ sourceId: Int32, _ ptr: UnsafeMutablePointer?) +@_extern(wasm, module: "bjs", name: "swift_js_retain") +private func _swift_js_retain(_ ptr: Int32) -> Int32 + @_expose(wasm, "bjs_check") @_cdecl("bjs_check") public func _bjs_check() -> Void { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/ArrayParameter.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/ArrayParameter.swift index 1773223b..2d7ad9f2 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/ArrayParameter.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/ArrayParameter.swift @@ -12,9 +12,6 @@ private func _make_jsstring(_ ptr: UnsafePointer?, _ len: Int32) -> Int32 @_extern(wasm, module: "bjs", name: "init_memory_with_result") private func _init_memory_with_result(_ ptr: UnsafePointer?, _ len: Int32) -@_extern(wasm, module: "bjs", name: "free_jsobject") -private func _free_jsobject(_ ptr: Int32) -> Void - func checkArray(_ a: JSObject) -> Void { @_extern(wasm, module: "Check", name: "bjs_checkArray") func bjs_checkArray(_ a: Int32) -> Void diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/Interface.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/Interface.swift index c565a2f8..85f12665 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/Interface.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/Interface.swift @@ -12,9 +12,6 @@ private func _make_jsstring(_ ptr: UnsafePointer?, _ len: Int32) -> Int32 @_extern(wasm, module: "bjs", name: "init_memory_with_result") private func _init_memory_with_result(_ ptr: UnsafePointer?, _ len: Int32) -@_extern(wasm, module: "bjs", name: "free_jsobject") -private func _free_jsobject(_ ptr: Int32) -> Void - func returnAnimatable() -> Animatable { @_extern(wasm, module: "Check", name: "bjs_returnAnimatable") func bjs_returnAnimatable() -> Int32 diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/PrimitiveParameters.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/PrimitiveParameters.swift index 4ab7f754..401d78b8 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/PrimitiveParameters.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/PrimitiveParameters.swift @@ -12,9 +12,6 @@ private func _make_jsstring(_ ptr: UnsafePointer?, _ len: Int32) -> Int32 @_extern(wasm, module: "bjs", name: "init_memory_with_result") private func _init_memory_with_result(_ ptr: UnsafePointer?, _ len: Int32) -@_extern(wasm, module: "bjs", name: "free_jsobject") -private func _free_jsobject(_ ptr: Int32) -> Void - func check(_ a: Double, _ b: Bool) -> Void { @_extern(wasm, module: "Check", name: "bjs_check") func bjs_check(_ a: Float64, _ b: Int32) -> Void diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/PrimitiveReturn.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/PrimitiveReturn.swift index a60c9323..da9bfc3b 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/PrimitiveReturn.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/PrimitiveReturn.swift @@ -12,9 +12,6 @@ private func _make_jsstring(_ ptr: UnsafePointer?, _ len: Int32) -> Int32 @_extern(wasm, module: "bjs", name: "init_memory_with_result") private func _init_memory_with_result(_ ptr: UnsafePointer?, _ len: Int32) -@_extern(wasm, module: "bjs", name: "free_jsobject") -private func _free_jsobject(_ ptr: Int32) -> Void - func checkNumber() -> Double { @_extern(wasm, module: "Check", name: "bjs_checkNumber") func bjs_checkNumber() -> Float64 diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/StringParameter.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/StringParameter.swift index 491978bc..85852bd2 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/StringParameter.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/StringParameter.swift @@ -12,9 +12,6 @@ private func _make_jsstring(_ ptr: UnsafePointer?, _ len: Int32) -> Int32 @_extern(wasm, module: "bjs", name: "init_memory_with_result") private func _init_memory_with_result(_ ptr: UnsafePointer?, _ len: Int32) -@_extern(wasm, module: "bjs", name: "free_jsobject") -private func _free_jsobject(_ ptr: Int32) -> Void - func checkString(_ a: String) -> Void { @_extern(wasm, module: "Check", name: "bjs_checkString") func bjs_checkString(_ a: Int32) -> Void diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/StringReturn.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/StringReturn.swift index ce32a643..4702c5a9 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/StringReturn.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/StringReturn.swift @@ -12,9 +12,6 @@ private func _make_jsstring(_ ptr: UnsafePointer?, _ len: Int32) -> Int32 @_extern(wasm, module: "bjs", name: "init_memory_with_result") private func _init_memory_with_result(_ ptr: UnsafePointer?, _ len: Int32) -@_extern(wasm, module: "bjs", name: "free_jsobject") -private func _free_jsobject(_ ptr: Int32) -> Void - func checkString() -> String { @_extern(wasm, module: "Check", name: "bjs_checkString") func bjs_checkString() -> Int32 diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TypeAlias.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TypeAlias.swift index 79f29c92..2c7a8c7f 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TypeAlias.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TypeAlias.swift @@ -12,9 +12,6 @@ private func _make_jsstring(_ ptr: UnsafePointer?, _ len: Int32) -> Int32 @_extern(wasm, module: "bjs", name: "init_memory_with_result") private func _init_memory_with_result(_ ptr: UnsafePointer?, _ len: Int32) -@_extern(wasm, module: "bjs", name: "free_jsobject") -private func _free_jsobject(_ ptr: Int32) -> Void - func checkSimple(_ a: Double) -> Void { @_extern(wasm, module: "Check", name: "bjs_checkSimple") func bjs_checkSimple(_ a: Float64) -> Void diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TypeScriptClass.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TypeScriptClass.swift index 0f1f42d1..3dc779ae 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TypeScriptClass.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/TypeScriptClass.swift @@ -12,9 +12,6 @@ private func _make_jsstring(_ ptr: UnsafePointer?, _ len: Int32) -> Int32 @_extern(wasm, module: "bjs", name: "init_memory_with_result") private func _init_memory_with_result(_ ptr: UnsafePointer?, _ len: Int32) -@_extern(wasm, module: "bjs", name: "free_jsobject") -private func _free_jsobject(_ ptr: Int32) -> Void - struct Greeter { let this: JSObject @@ -37,6 +34,36 @@ struct Greeter { self.this = JSObject(id: UInt32(bitPattern: ret)) } + var name: String { + get { + @_extern(wasm, module: "Check", name: "bjs_Greeter_name_get") + func bjs_Greeter_name_get(_ self: Int32) -> Int32 + let ret = bjs_Greeter_name_get(Int32(bitPattern: self.this.id)) + return String(unsafeUninitializedCapacity: Int(ret)) { b in + _init_memory_with_result(b.baseAddress.unsafelyUnwrapped, Int32(ret)) + return Int(ret) + } + } + nonmutating set { + @_extern(wasm, module: "Check", name: "bjs_Greeter_name_set") + func bjs_Greeter_name_set(_ self: Int32, _ newValue: Int32) -> Void + var newValue = newValue + let newValueId = newValue.withUTF8 { b in + _make_jsstring(b.baseAddress.unsafelyUnwrapped, Int32(b.count)) + } + bjs_Greeter_name_set(Int32(bitPattern: self.this.id), newValueId) + } + } + + var age: Double { + get { + @_extern(wasm, module: "Check", name: "bjs_Greeter_age_get") + func bjs_Greeter_age_get(_ self: Int32) -> Float64 + let ret = bjs_Greeter_age_get(Int32(bitPattern: self.this.id)) + return Double(ret) + } + } + func greet() -> String { @_extern(wasm, module: "Check", name: "bjs_Greeter_greet") func bjs_Greeter_greet(_ self: Int32) -> Int32 diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/VoidParameterVoidReturn.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/VoidParameterVoidReturn.swift index 3f2ecc78..71cee5dc 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/VoidParameterVoidReturn.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/ImportTSTests/VoidParameterVoidReturn.swift @@ -12,9 +12,6 @@ private func _make_jsstring(_ ptr: UnsafePointer?, _ len: Int32) -> Int32 @_extern(wasm, module: "bjs", name: "init_memory_with_result") private func _init_memory_with_result(_ ptr: UnsafePointer?, _ len: Int32) -@_extern(wasm, module: "bjs", name: "free_jsobject") -private func _free_jsobject(_ ptr: Int32) -> Void - func check() -> Void { @_extern(wasm, module: "Check", name: "bjs_check") func bjs_check() -> Void diff --git a/Plugins/PackageToJS/Templates/runtime.d.ts b/Plugins/PackageToJS/Templates/runtime.d.ts index 9613004c..ed94f7e4 100644 --- a/Plugins/PackageToJS/Templates/runtime.d.ts +++ b/Plugins/PackageToJS/Templates/runtime.d.ts @@ -8,6 +8,7 @@ declare class Memory { retain: (value: any) => number; getObject: (ref: number) => any; release: (ref: number) => void; + retainByRef: (ref: number) => number; bytes: () => Uint8Array; dataView: () => DataView; writeBytes: (ptr: pointer, bytes: Uint8Array) => void; diff --git a/Plugins/PackageToJS/Templates/runtime.mjs b/Plugins/PackageToJS/Templates/runtime.mjs index 71f7f9a3..e3673835 100644 --- a/Plugins/PackageToJS/Templates/runtime.mjs +++ b/Plugins/PackageToJS/Templates/runtime.mjs @@ -158,6 +158,9 @@ class SwiftRuntimeHeap { this._heapEntryByValue.set(value, { id: id, rc: 1 }); return id; } + retainByRef(ref) { + return this.retain(this.referenceHeap(ref)); + } release(ref) { const value = this._heapValueById.get(ref); const entry = this._heapEntryByValue.get(value); @@ -182,6 +185,7 @@ class Memory { this.retain = (value) => this.heap.retain(value); this.getObject = (ref) => this.heap.referenceHeap(ref); this.release = (ref) => this.heap.release(ref); + this.retainByRef = (ref) => this.heap.retainByRef(ref); this.bytes = () => new Uint8Array(this.rawMemory.buffer); this.dataView = () => new DataView(this.rawMemory.buffer); this.writeBytes = (ptr, bytes) => this.bytes().set(bytes, ptr); diff --git a/Runtime/src/memory.ts b/Runtime/src/memory.ts index d8334516..5ba00c82 100644 --- a/Runtime/src/memory.ts +++ b/Runtime/src/memory.ts @@ -13,6 +13,7 @@ export class Memory { retain = (value: any) => this.heap.retain(value); getObject = (ref: number) => this.heap.referenceHeap(ref); release = (ref: number) => this.heap.release(ref); + retainByRef = (ref: number) => this.heap.retainByRef(ref); bytes = () => new Uint8Array(this.rawMemory.buffer); dataView = () => new DataView(this.rawMemory.buffer); diff --git a/Runtime/src/object-heap.ts b/Runtime/src/object-heap.ts index d59f5101..a239cf2b 100644 --- a/Runtime/src/object-heap.ts +++ b/Runtime/src/object-heap.ts @@ -33,6 +33,10 @@ export class SwiftRuntimeHeap { return id; } + retainByRef(ref: ref) { + return this.retain(this.referenceHeap(ref)); + } + release(ref: ref) { const value = this._heapValueById.get(ref); const entry = this._heapEntryByValue.get(value)!; diff --git a/Tests/BridgeJSRuntimeTests/ExportAPITests.swift b/Tests/BridgeJSRuntimeTests/ExportAPITests.swift index 8449b06d..e113a514 100644 --- a/Tests/BridgeJSRuntimeTests/ExportAPITests.swift +++ b/Tests/BridgeJSRuntimeTests/ExportAPITests.swift @@ -28,6 +28,10 @@ func runJsWorks() -> Void return v } +@JS func roundTripJSObject(v: JSObject) -> JSObject { + return v +} + @JS class Greeter { var name: String diff --git a/Tests/BridgeJSRuntimeTests/Generated/ExportSwift.swift b/Tests/BridgeJSRuntimeTests/Generated/ExportSwift.swift index 4a7c262c..28514c8e 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/ExportSwift.swift +++ b/Tests/BridgeJSRuntimeTests/Generated/ExportSwift.swift @@ -3,11 +3,17 @@ // // To update this file, just rebuild your project or run // `swift package bridge-js`. + +@_spi(JSObject_id) import JavaScriptKit + @_extern(wasm, module: "bjs", name: "return_string") private func _return_string(_ ptr: UnsafePointer?, _ len: Int32) @_extern(wasm, module: "bjs", name: "init_memory") private func _init_memory(_ sourceId: Int32, _ ptr: UnsafeMutablePointer?) +@_extern(wasm, module: "bjs", name: "swift_js_retain") +private func _swift_js_retain(_ ptr: Int32) -> Int32 + @_expose(wasm, "bjs_roundTripVoid") @_cdecl("bjs_roundTripVoid") public func _bjs_roundTripVoid() -> Void { @@ -62,6 +68,13 @@ public func _bjs_roundTripSwiftHeapObject(v: UnsafeMutableRawPointer) -> UnsafeM return Unmanaged.passRetained(ret).toOpaque() } +@_expose(wasm, "bjs_roundTripJSObject") +@_cdecl("bjs_roundTripJSObject") +public func _bjs_roundTripJSObject(v: Int32) -> Int32 { + let ret = roundTripJSObject(v: JSObject(id: UInt32(bitPattern: v))) + return _swift_js_retain(Int32(bitPattern: ret.id)) +} + @_expose(wasm, "bjs_takeGreeter") @_cdecl("bjs_takeGreeter") public func _bjs_takeGreeter(g: UnsafeMutableRawPointer, nameBytes: Int32, nameLen: Int32) -> Void { diff --git a/Tests/BridgeJSRuntimeTests/Generated/ImportTS.swift b/Tests/BridgeJSRuntimeTests/Generated/ImportTS.swift index f479a071..c01a0fce 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/ImportTS.swift +++ b/Tests/BridgeJSRuntimeTests/Generated/ImportTS.swift @@ -12,9 +12,6 @@ private func _make_jsstring(_ ptr: UnsafePointer?, _ len: Int32) -> Int32 @_extern(wasm, module: "bjs", name: "init_memory_with_result") private func _init_memory_with_result(_ ptr: UnsafePointer?, _ len: Int32) -@_extern(wasm, module: "bjs", name: "free_jsobject") -private func _free_jsobject(_ ptr: Int32) -> Void - func jsRoundTripVoid() -> Void { @_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsRoundTripVoid") func bjs_jsRoundTripVoid() -> Void @@ -60,17 +57,54 @@ struct JsGreeter { self.this = JSObject(id: UInt32(bitPattern: this)) } - init(_ name: String) { + init(_ name: String, _ prefix: String) { @_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_JsGreeter_init") - func bjs_JsGreeter_init(_ name: Int32) -> Int32 + func bjs_JsGreeter_init(_ name: Int32, _ prefix: Int32) -> Int32 var name = name let nameId = name.withUTF8 { b in _make_jsstring(b.baseAddress.unsafelyUnwrapped, Int32(b.count)) } - let ret = bjs_JsGreeter_init(nameId) + var prefix = prefix + let prefixId = prefix.withUTF8 { b in + _make_jsstring(b.baseAddress.unsafelyUnwrapped, Int32(b.count)) + } + let ret = bjs_JsGreeter_init(nameId, prefixId) self.this = JSObject(id: UInt32(bitPattern: ret)) } + var name: String { + get { + @_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_JsGreeter_name_get") + func bjs_JsGreeter_name_get(_ self: Int32) -> Int32 + let ret = bjs_JsGreeter_name_get(Int32(bitPattern: self.this.id)) + return String(unsafeUninitializedCapacity: Int(ret)) { b in + _init_memory_with_result(b.baseAddress.unsafelyUnwrapped, Int32(ret)) + return Int(ret) + } + } + nonmutating set { + @_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_JsGreeter_name_set") + func bjs_JsGreeter_name_set(_ self: Int32, _ newValue: Int32) -> Void + var newValue = newValue + let newValueId = newValue.withUTF8 { b in + _make_jsstring(b.baseAddress.unsafelyUnwrapped, Int32(b.count)) + } + bjs_JsGreeter_name_set(Int32(bitPattern: self.this.id), newValueId) + } + } + + var prefix: String { + get { + @_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_JsGreeter_prefix_get") + func bjs_JsGreeter_prefix_get(_ self: Int32) -> Int32 + let ret = bjs_JsGreeter_prefix_get(Int32(bitPattern: self.this.id)) + return String(unsafeUninitializedCapacity: Int(ret)) { b in + _init_memory_with_result(b.baseAddress.unsafelyUnwrapped, Int32(ret)) + return Int(ret) + } + } + } + func greet() -> String { @_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_JsGreeter_greet") func bjs_JsGreeter_greet(_ self: Int32) -> Int32 diff --git a/Tests/BridgeJSRuntimeTests/Generated/JavaScript/ExportSwift.json b/Tests/BridgeJSRuntimeTests/Generated/JavaScript/ExportSwift.json index b4ab9701..d72c17b9 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/JavaScript/ExportSwift.json +++ b/Tests/BridgeJSRuntimeTests/Generated/JavaScript/ExportSwift.json @@ -185,6 +185,26 @@ } } }, + { + "abiName" : "bjs_roundTripJSObject", + "name" : "roundTripJSObject", + "parameters" : [ + { + "label" : "v", + "name" : "v", + "type" : { + "jsObject" : { + + } + } + } + ], + "returnType" : { + "jsObject" : { + + } + } + }, { "abiName" : "bjs_takeGreeter", "name" : "takeGreeter", diff --git a/Tests/BridgeJSRuntimeTests/Generated/JavaScript/ImportTS.json b/Tests/BridgeJSRuntimeTests/Generated/JavaScript/ImportTS.json index 867957d9..ad8fcd87 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/JavaScript/ImportTS.json +++ b/Tests/BridgeJSRuntimeTests/Generated/JavaScript/ImportTS.json @@ -77,6 +77,14 @@ "type" : { "string" : { + } + } + }, + { + "name" : "prefix", + "type" : { + "string" : { + } } } @@ -115,7 +123,24 @@ ], "name" : "JsGreeter", "properties" : [ + { + "isReadonly" : false, + "name" : "name", + "type" : { + "string" : { + } + } + }, + { + "isReadonly" : true, + "name" : "prefix", + "type" : { + "string" : { + + } + } + } ] } ] diff --git a/Tests/BridgeJSRuntimeTests/ImportAPITests.swift b/Tests/BridgeJSRuntimeTests/ImportAPITests.swift index bc50f9f1..a8d586bf 100644 --- a/Tests/BridgeJSRuntimeTests/ImportAPITests.swift +++ b/Tests/BridgeJSRuntimeTests/ImportAPITests.swift @@ -36,9 +36,15 @@ class ImportAPITests: XCTestCase { } func testClass() { - let greeter = JsGreeter("Alice") + let greeter = JsGreeter("Alice", "Hello") XCTAssertEqual(greeter.greet(), "Hello, Alice!") greeter.changeName("Bob") XCTAssertEqual(greeter.greet(), "Hello, Bob!") + + greeter.name = "Charlie" + XCTAssertEqual(greeter.greet(), "Hello, Charlie!") + XCTAssertEqual(greeter.name, "Charlie") + + XCTAssertEqual(greeter.prefix, "Hello") } } diff --git a/Tests/BridgeJSRuntimeTests/bridge-js.d.ts b/Tests/BridgeJSRuntimeTests/bridge-js.d.ts index d2a54f05..664dd447 100644 --- a/Tests/BridgeJSRuntimeTests/bridge-js.d.ts +++ b/Tests/BridgeJSRuntimeTests/bridge-js.d.ts @@ -4,7 +4,9 @@ export function jsRoundTripBool(v: boolean): boolean export function jsRoundTripString(v: string): string export class JsGreeter { - constructor(name: string); + name: string; + readonly prefix: string; + constructor(name: string, prefix: string); greet(): string; changeName(name: string): void; } \ No newline at end of file diff --git a/Tests/prelude.mjs b/Tests/prelude.mjs index 24a194f9..c79feb2a 100644 --- a/Tests/prelude.mjs +++ b/Tests/prelude.mjs @@ -20,12 +20,16 @@ export async function setupOptions(options, context) { return v; }, JsGreeter: class { - /** @param {string} name */ - constructor(name) { + /** + * @param {string} name + * @param {string} prefix + */ + constructor(name, prefix) { this.name = name; + this.prefix = prefix; } greet() { - return `Hello, ${this.name}!`; + return `${this.prefix}, ${this.name}!`; } /** @param {string} name */ changeName(name) { @@ -98,6 +102,9 @@ function BridgeJSRuntimeTests_runJsWorks(instance, exports) { exports.takeGreeter(g, "Jay"); assert.equal(g.greet(), "Hello, Jay!"); g.release(); + + const anyObject = {}; + assert.equal(exports.roundTripJSObject(anyObject), anyObject); } function setupTestGlobals(global) {