Skip to content

Commit 3774db4

Browse files
Added runtime coverage for import-side arrays: new @JSFunction declarations (Tests/BridgeJSRuntimeTests/ImportArrayAPIs.swift) and tests in Tests/BridgeJSRuntimeTests/ImportAPITests.swift validating roundtrip and length for [Int]/[String], with JS implementations wired into Tests/prelude.mjs. Updated BridgeJSLink to allow stack-lifted parameters (array import) without assertions, and regenerated BridgeJS runtime glue.
Tests: `SWIFT_SDK_ID=DEVELOPMENT-SNAPSHOT-2025-11-03-a-wasm32-unknown-wasip1 make unittest` (all 20 suites / 96 tests pass).
1 parent 8c3e5f5 commit 3774db4

6 files changed

Lines changed: 167 additions & 5 deletions

File tree

Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2146,12 +2146,10 @@ extension BridgeJSLink {
21462146

21472147
func liftParameter(param: Parameter) throws {
21482148
let liftingFragment = try IntrinsicJSFragment.liftParameter(type: param.type, context: context)
2149-
assert(
2150-
liftingFragment.parameters.count >= 1,
2151-
"Lifting fragment should have at least one parameter to lift"
2152-
)
21532149
let valuesToLift: [String]
2154-
if liftingFragment.parameters.count == 1 {
2150+
if liftingFragment.parameters.isEmpty {
2151+
valuesToLift = []
2152+
} else if liftingFragment.parameters.count == 1 {
21552153
parameterNames.append(param.name)
21562154
valuesToLift = [scope.variable(param.name)]
21572155
} else {

Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8304,6 +8304,60 @@ func _$Animal_getIsCat(_ self: JSObject) throws(JSException) -> Bool {
83048304
return Bool.bridgeJSLiftReturn(ret)
83058305
}
83068306

8307+
#if arch(wasm32)
8308+
@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsRoundTripIntArray")
8309+
fileprivate func bjs_jsRoundTripIntArray() -> Void
8310+
#else
8311+
fileprivate func bjs_jsRoundTripIntArray() -> Void {
8312+
fatalError("Only available on WebAssembly")
8313+
}
8314+
#endif
8315+
8316+
func _$jsRoundTripIntArray(_ items: [Int]) throws(JSException) -> [Int] {
8317+
let _ = items.bridgeJSLowerParameter()
8318+
let ret = bjs_jsRoundTripIntArray()
8319+
if let error = _swift_js_take_exception() {
8320+
throw error
8321+
}
8322+
return [Int].bridgeJSLiftReturn()
8323+
}
8324+
8325+
#if arch(wasm32)
8326+
@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsRoundTripStringArray")
8327+
fileprivate func bjs_jsRoundTripStringArray() -> Void
8328+
#else
8329+
fileprivate func bjs_jsRoundTripStringArray() -> Void {
8330+
fatalError("Only available on WebAssembly")
8331+
}
8332+
#endif
8333+
8334+
func _$jsRoundTripStringArray(_ items: [String]) throws(JSException) -> [String] {
8335+
let _ = items.bridgeJSLowerParameter()
8336+
let ret = bjs_jsRoundTripStringArray()
8337+
if let error = _swift_js_take_exception() {
8338+
throw error
8339+
}
8340+
return [String].bridgeJSLiftReturn()
8341+
}
8342+
8343+
#if arch(wasm32)
8344+
@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsArrayLength")
8345+
fileprivate func bjs_jsArrayLength() -> Int32
8346+
#else
8347+
fileprivate func bjs_jsArrayLength() -> Int32 {
8348+
fatalError("Only available on WebAssembly")
8349+
}
8350+
#endif
8351+
8352+
func _$jsArrayLength(_ items: [Int]) throws(JSException) -> Int {
8353+
let _ = items.bridgeJSLowerParameter()
8354+
let ret = bjs_jsArrayLength()
8355+
if let error = _swift_js_take_exception() {
8356+
throw error
8357+
}
8358+
return Int.bridgeJSLiftReturn(ret)
8359+
}
8360+
83078361
#if arch(wasm32)
83088362
@_extern(wasm, module: "BridgeJSRuntimeTests", name: "bjs_jsApplyInt")
83098363
fileprivate func bjs_jsApplyInt(_ value: Int32, _ transform: UnsafeMutableRawPointer) -> Int32

Tests/BridgeJSRuntimeTests/Generated/JavaScript/BridgeJS.json

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12127,6 +12127,87 @@
1212712127

1212812128
]
1212912129
},
12130+
{
12131+
"functions" : [
12132+
{
12133+
"name" : "jsRoundTripIntArray",
12134+
"parameters" : [
12135+
{
12136+
"name" : "items",
12137+
"type" : {
12138+
"array" : {
12139+
"_0" : {
12140+
"int" : {
12141+
12142+
}
12143+
}
12144+
}
12145+
}
12146+
}
12147+
],
12148+
"returnType" : {
12149+
"array" : {
12150+
"_0" : {
12151+
"int" : {
12152+
12153+
}
12154+
}
12155+
}
12156+
}
12157+
},
12158+
{
12159+
"name" : "jsRoundTripStringArray",
12160+
"parameters" : [
12161+
{
12162+
"name" : "items",
12163+
"type" : {
12164+
"array" : {
12165+
"_0" : {
12166+
"string" : {
12167+
12168+
}
12169+
}
12170+
}
12171+
}
12172+
}
12173+
],
12174+
"returnType" : {
12175+
"array" : {
12176+
"_0" : {
12177+
"string" : {
12178+
12179+
}
12180+
}
12181+
}
12182+
}
12183+
},
12184+
{
12185+
"name" : "jsArrayLength",
12186+
"parameters" : [
12187+
{
12188+
"name" : "items",
12189+
"type" : {
12190+
"array" : {
12191+
"_0" : {
12192+
"int" : {
12193+
12194+
}
12195+
}
12196+
}
12197+
}
12198+
}
12199+
],
12200+
"returnType" : {
12201+
"int" : {
12202+
12203+
}
12204+
}
12205+
}
12206+
],
12207+
"types" : [
12208+
12209+
]
12210+
},
1213012211
{
1213112212
"functions" : [
1213212213
{

Tests/BridgeJSRuntimeTests/ImportAPITests.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,21 @@ class ImportAPITests: XCTestCase {
114114
XCTAssertEqual(prefixer("world!"), "Hello, world!")
115115
}
116116

117+
func testRoundTripIntArray() throws {
118+
let values = [1, 2, 3, 4, 5]
119+
let result = try jsRoundTripIntArray(values)
120+
XCTAssertEqual(result, values)
121+
XCTAssertEqual(try jsArrayLength(values), values.count)
122+
XCTAssertEqual(try jsRoundTripIntArray([]), [])
123+
}
124+
125+
func testRoundTripStringArray() throws {
126+
let values = ["", "Hello", "こんにちは", "emoji 👋"]
127+
let result = try jsRoundTripStringArray(values)
128+
XCTAssertEqual(result, values)
129+
XCTAssertEqual(try jsRoundTripStringArray([]), [])
130+
}
131+
117132
func testClosureParameterIntToVoid() throws {
118133
var total = 0
119134
let ret = try jsCallTwice(5) { total += $0 }
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
@_spi(Experimental) @_spi(BridgeJS) import JavaScriptKit
2+
3+
@JSFunction func jsRoundTripIntArray(_ items: [Int]) throws (JSException) -> [Int]
4+
@JSFunction func jsRoundTripStringArray(_ items: [String]) throws (JSException) -> [String]
5+
@JSFunction func jsArrayLength(_ items: [Int]) throws (JSException) -> Int

Tests/prelude.mjs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,15 @@ export async function setupOptions(options, context) {
2525
"jsRoundTripString": (v) => {
2626
return v;
2727
},
28+
"jsRoundTripIntArray": (items) => {
29+
return items;
30+
},
31+
"jsRoundTripStringArray": (items) => {
32+
return items;
33+
},
34+
"jsArrayLength": (items) => {
35+
return items.length;
36+
},
2837
"jsThrowOrVoid": (shouldThrow) => {
2938
if (shouldThrow) {
3039
throw new Error("TestError");

0 commit comments

Comments
 (0)