diff --git a/Benchmarks/Sources/Generated/BridgeJS.swift b/Benchmarks/Sources/Generated/BridgeJS.swift index 384ca35a2..8f61d6bd4 100644 --- a/Benchmarks/Sources/Generated/BridgeJS.swift +++ b/Benchmarks/Sources/Generated/BridgeJS.swift @@ -1829,9 +1829,9 @@ public func _bjs_ArrayRoundtrip_init() -> UnsafeMutableRawPointer { @_expose(wasm, "bjs_ArrayRoundtrip_takeIntArray") @_cdecl("bjs_ArrayRoundtrip_takeIntArray") -public func _bjs_ArrayRoundtrip_takeIntArray(_ _self: UnsafeMutableRawPointer) -> Void { +public func _bjs_ArrayRoundtrip_takeIntArray(_ _self: UnsafeMutableRawPointer, _ valuesSourceId: Int32, _ valuesCount: Int32) -> Void { #if arch(wasm32) - ArrayRoundtrip.bridgeJSLiftParameter(_self).takeIntArray(_: [Int].bridgeJSStackPop()) + ArrayRoundtrip.bridgeJSLiftParameter(_self).takeIntArray(_: [Int].bridgeJSTypedArrayLiftParameter(valuesSourceId, valuesCount)) #else fatalError("Only available on WebAssembly") #endif @@ -1842,7 +1842,7 @@ public func _bjs_ArrayRoundtrip_takeIntArray(_ _self: UnsafeMutableRawPointer) - public func _bjs_ArrayRoundtrip_makeIntArray(_ _self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) let ret = ArrayRoundtrip.bridgeJSLiftParameter(_self).makeIntArray() - ret.bridgeJSStackPush() + ret.bridgeJSTypedArrayPush() #else fatalError("Only available on WebAssembly") #endif @@ -1850,10 +1850,10 @@ public func _bjs_ArrayRoundtrip_makeIntArray(_ _self: UnsafeMutableRawPointer) - @_expose(wasm, "bjs_ArrayRoundtrip_roundtripIntArray") @_cdecl("bjs_ArrayRoundtrip_roundtripIntArray") -public func _bjs_ArrayRoundtrip_roundtripIntArray(_ _self: UnsafeMutableRawPointer) -> Void { +public func _bjs_ArrayRoundtrip_roundtripIntArray(_ _self: UnsafeMutableRawPointer, _ valuesSourceId: Int32, _ valuesCount: Int32) -> Void { #if arch(wasm32) - let ret = ArrayRoundtrip.bridgeJSLiftParameter(_self).roundtripIntArray(_: [Int].bridgeJSStackPop()) - ret.bridgeJSStackPush() + let ret = ArrayRoundtrip.bridgeJSLiftParameter(_self).roundtripIntArray(_: [Int].bridgeJSTypedArrayLiftParameter(valuesSourceId, valuesCount)) + ret.bridgeJSTypedArrayPush() #else fatalError("Only available on WebAssembly") #endif @@ -1864,7 +1864,7 @@ public func _bjs_ArrayRoundtrip_roundtripIntArray(_ _self: UnsafeMutableRawPoint public func _bjs_ArrayRoundtrip_makeIntArrayLarge(_ _self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) let ret = ArrayRoundtrip.bridgeJSLiftParameter(_self).makeIntArrayLarge() - ret.bridgeJSStackPush() + ret.bridgeJSTypedArrayPush() #else fatalError("Only available on WebAssembly") #endif @@ -1872,9 +1872,9 @@ public func _bjs_ArrayRoundtrip_makeIntArrayLarge(_ _self: UnsafeMutableRawPoint @_expose(wasm, "bjs_ArrayRoundtrip_takeDoubleArray") @_cdecl("bjs_ArrayRoundtrip_takeDoubleArray") -public func _bjs_ArrayRoundtrip_takeDoubleArray(_ _self: UnsafeMutableRawPointer) -> Void { +public func _bjs_ArrayRoundtrip_takeDoubleArray(_ _self: UnsafeMutableRawPointer, _ valuesSourceId: Int32, _ valuesCount: Int32) -> Void { #if arch(wasm32) - ArrayRoundtrip.bridgeJSLiftParameter(_self).takeDoubleArray(_: [Double].bridgeJSStackPop()) + ArrayRoundtrip.bridgeJSLiftParameter(_self).takeDoubleArray(_: [Double].bridgeJSTypedArrayLiftParameter(valuesSourceId, valuesCount)) #else fatalError("Only available on WebAssembly") #endif @@ -1885,7 +1885,7 @@ public func _bjs_ArrayRoundtrip_takeDoubleArray(_ _self: UnsafeMutableRawPointer public func _bjs_ArrayRoundtrip_makeDoubleArray(_ _self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) let ret = ArrayRoundtrip.bridgeJSLiftParameter(_self).makeDoubleArray() - ret.bridgeJSStackPush() + ret.bridgeJSTypedArrayPush() #else fatalError("Only available on WebAssembly") #endif @@ -1893,10 +1893,10 @@ public func _bjs_ArrayRoundtrip_makeDoubleArray(_ _self: UnsafeMutableRawPointer @_expose(wasm, "bjs_ArrayRoundtrip_roundtripDoubleArray") @_cdecl("bjs_ArrayRoundtrip_roundtripDoubleArray") -public func _bjs_ArrayRoundtrip_roundtripDoubleArray(_ _self: UnsafeMutableRawPointer) -> Void { +public func _bjs_ArrayRoundtrip_roundtripDoubleArray(_ _self: UnsafeMutableRawPointer, _ valuesSourceId: Int32, _ valuesCount: Int32) -> Void { #if arch(wasm32) - let ret = ArrayRoundtrip.bridgeJSLiftParameter(_self).roundtripDoubleArray(_: [Double].bridgeJSStackPop()) - ret.bridgeJSStackPush() + let ret = ArrayRoundtrip.bridgeJSLiftParameter(_self).roundtripDoubleArray(_: [Double].bridgeJSTypedArrayLiftParameter(valuesSourceId, valuesCount)) + ret.bridgeJSTypedArrayPush() #else fatalError("Only available on WebAssembly") #endif diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/ClosureCodegen.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/ClosureCodegen.swift index 45cfb73f1..d2cdcfff3 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/ClosureCodegen.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/ClosureCodegen.swift @@ -132,6 +132,19 @@ public struct ClosureCodegen { for (index, paramType) in signature.parameters.enumerated() { let paramName = "param\(index)" + + // Numeric arrays use bulk TypedArray transfer with (sourceId, count) WASM params + if case .array(let elementType) = paramType, elementType.isNumericScalar { + let sourceIdName = "\(paramName)SourceId" + let countName = "\(paramName)Count" + abiParams.append((sourceIdName, .i32)) + abiParams.append((countName, .i32)) + liftedParams.append( + "[\(elementType.swiftType)].bridgeJSTypedArrayLiftParameter(\(sourceIdName), \(countName))" + ) + continue + } + let liftInfo = try paramType.liftParameterInfo() for (argName, wasmType) in liftInfo.parameters { diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift index b649b244d..fdf5f41d5 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/ExportSwift.swift @@ -137,6 +137,18 @@ public class ExportSwift { case .swiftStruct(let structName): typeNameForIntrinsic = structName liftingExpr = ExprSyntax("\(raw: structName).bridgeJSLiftParameter()") + case .array(let elementType) where elementType.isNumericScalar: + // Numeric arrays use bulk TypedArray transfer with (sourceId, count) WASM params + let elementSwiftType = elementType.swiftType + typeNameForIntrinsic = param.type.swiftType + liftingExpr = ExprSyntax( + "[\(raw: elementSwiftType)].bridgeJSTypedArrayLiftParameter(\(raw: param.name)SourceId, \(raw: param.name)Count)" + ) + // Override the ABI signatures: two i32 params instead of stack-based + liftedParameterExprs.append(liftingExpr) + abiParameterSignatures.append(("\(param.name)SourceId", .i32)) + abiParameterSignatures.append(("\(param.name)Count", .i32)) + return case .array: typeNameForIntrinsic = param.type.swiftType liftingExpr = StackCodegen().liftExpression(for: param.type) @@ -301,6 +313,8 @@ public class ExportSwift { switch returnType { case .closure(_, useJSTypedClosure: false): append("return JSTypedClosure(ret).bridgeJSLowerReturn()") + case .array(let elementType) where elementType.isNumericScalar: + append("ret.bridgeJSTypedArrayPush()") case .array, .nullable(.array, _): let stackCodegen = StackCodegen() for stmt in stackCodegen.lowerStatements(for: returnType, accessor: "ret", varPrefix: "ret") { diff --git a/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift b/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift index d491c4058..1f3ecbe57 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSCore/ImportTS.swift @@ -152,6 +152,10 @@ public struct ImportTS { // The just created JSObject is not owned by the caller unlike those passed in parameters, // so we need to extend its lifetime during the call to ensure the JSObject.id is valid. valuesToExtendLifetimeDuringCall.append(param.name) + case .array(let elementType) where elementType.isNumericScalar: + // Numeric arrays use bulk TypedArray transfer instead of element-by-element + stackLoweringStmts.insert("\(param.name).bridgeJSTypedArrayPush()", at: 0) + return default: break } @@ -302,6 +306,12 @@ public struct ImportTS { switch returnType { case .closure(let signature, _): liftExpr = "_BJS_Closure_\(signature.mangleName).bridgeJSLift(ret)" + case .array(let elementType) where elementType.isNumericScalar: + // Numeric arrays: JS pushed (sourceId, count) onto i32 stack + let swiftElementType = elementType.swiftType + body.write("let _count = _swift_js_pop_i32()") + body.write("let _sourceId = _swift_js_pop_i32()") + liftExpr = "[\(swiftElementType)].bridgeJSTypedArrayLiftParameter(_sourceId, _count)" default: if liftingInfo.valueToLift != nil { liftExpr = "\(returnType.swiftType).bridgeJSLiftReturn(ret)" diff --git a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift index ceaaae8f1..a53f9750c 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSLink/BridgeJSLink.swift @@ -345,6 +345,8 @@ public struct BridgeJSLink { "let \(JSGlueVariableScope.reservedF32Stack) = [];", "let \(JSGlueVariableScope.reservedF64Stack) = [];", "let \(JSGlueVariableScope.reservedPointerStack) = [];", + "let \(JSGlueVariableScope.reservedTaStack) = [];", + "const \(JSGlueVariableScope.reservedTypedArrayConstructors) = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array];", "const \(JSGlueVariableScope.reservedEnumHelpers) = {};", "const \(JSGlueVariableScope.reservedStructHelpers) = {};", "", @@ -487,6 +489,66 @@ public struct BridgeJSLink { printer.write("return \(JSGlueVariableScope.reservedI64Stack).pop();") } printer.write("}") + printer.write("bjs[\"swift_js_push_typed_array\"] = function(ptr, count, kind) {") + printer.indent { + printer.write( + "const Constructor = \(JSGlueVariableScope.reservedTypedArrayConstructors)[kind];" + ) + printer.write( + "const elemSize = Constructor.BYTES_PER_ELEMENT;" + ) + printer.write( + "const totalBytes = count * elemSize;" + ) + printer.write( + "const copy = new Uint8Array(totalBytes);" + ) + printer.write( + "copy.set(new Uint8Array(\(JSGlueVariableScope.reservedMemory).buffer, ptr, totalBytes));" + ) + printer.write( + "\(JSGlueVariableScope.reservedTaStack).push(new Constructor(copy.buffer));" + ) + } + printer.write("}") + printer.write("bjs[\"swift_js_init_typed_array_memory\"] = function(sourceId, destPtr, count, kind) {") + printer.indent { + printer.write( + "const source = \(JSGlueVariableScope.reservedSwift).\(JSGlueVariableScope.reservedMemory).getObject(sourceId);" + ) + printer.write( + "\(JSGlueVariableScope.reservedSwift).\(JSGlueVariableScope.reservedMemory).release(sourceId);" + ) + printer.write( + "const Constructor = \(JSGlueVariableScope.reservedTypedArrayConstructors)[kind];" + ) + printer.write( + "const elemSize = Constructor.BYTES_PER_ELEMENT;" + ) + printer.write( + "if (destPtr % elemSize === 0) {" + ) + printer.indent { + printer.write( + "const dest = new Constructor(\(JSGlueVariableScope.reservedMemory).buffer, destPtr, count);" + ) + printer.write("dest.set(source);") + } + printer.write( + "} else {" + ) + printer.indent { + printer.write( + "const dest = new Uint8Array(\(JSGlueVariableScope.reservedMemory).buffer, destPtr, count * elemSize);" + ) + printer.write( + "const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength);" + ) + printer.write("dest.set(srcBytes);") + } + printer.write("}") + } + printer.write("}") if !allStructs.isEmpty { for structDef in allStructs { printer.write("bjs[\"swift_js_struct_lower_\(structDef.abiName)\"] = function(objectId) {") diff --git a/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift b/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift index 1ad397f71..c19ce4442 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSLink/JSGlueGen.swift @@ -34,6 +34,8 @@ final class JSGlueVariableScope { static let reservedStructHelpers = "structHelpers" static let reservedSwiftClosureRegistry = "swiftClosureRegistry" static let reservedMakeSwiftClosure = "makeClosure" + static let reservedTaStack = "taStack" + static let reservedTypedArrayConstructors = "typedArrayConstructors" private let intrinsicRegistry: JSIntrinsicRegistry @@ -63,6 +65,8 @@ final class JSGlueVariableScope { reservedStructHelpers, reservedSwiftClosureRegistry, reservedMakeSwiftClosure, + reservedTaStack, + reservedTypedArrayConstructors, ] init(intrinsicRegistry: JSIntrinsicRegistry) { @@ -1317,6 +1321,8 @@ struct IntrinsicJSFragment: Sendable { ) case .namespaceEnum(let string): throw BridgeJSLinkError(message: "Namespace enums are not supported to be passed as parameters: \(string)") + case .array(let elementType) where elementType.isNumericScalar: + return numericArrayLower(elementType: elementType) case .array(let elementType): return try arrayLower(elementType: elementType) case .dictionary(let valueType): @@ -1374,6 +1380,8 @@ struct IntrinsicJSFragment: Sendable { throw BridgeJSLinkError( message: "Namespace enums are not supported to be returned from functions: \(string)" ) + case .array(let elementType) where elementType.isNumericScalar: + return numericArrayLift(elementType: elementType) case .array(let elementType): return try arrayLift(elementType: elementType) case .dictionary(let valueType): @@ -1472,6 +1480,8 @@ struct IntrinsicJSFragment: Sendable { message: "Namespace enums are not supported to be passed as parameters to imported JS functions: \(string)" ) + case .array(let elementType) where elementType.isNumericScalar: + return numericArrayLift(elementType: elementType) case .array(let elementType): return try arrayLift(elementType: elementType) case .dictionary(let valueType): @@ -1534,6 +1544,8 @@ struct IntrinsicJSFragment: Sendable { throw BridgeJSLinkError( message: "Namespace enums are not supported to be returned from imported JS functions: \(string)" ) + case .array(let elementType) where elementType.isNumericScalar: + return numericArrayLowerReturn(elementType: elementType) case .array(let elementType): return try arrayLower(elementType: elementType) case .dictionary(let valueType): @@ -1828,6 +1840,72 @@ struct IntrinsicJSFragment: Sendable { // MARK: - Array Helpers + /// Lowers a numeric array from JS to Swift via bulk TypedArray transfer. + /// Converts the JS Array to a TypedArray, retains it, and passes (sourceId, count) as WASM params. + static func numericArrayLower(elementType: BridgeType) -> IntrinsicJSFragment { + let kind = elementType.typedArrayKind! + return IntrinsicJSFragment( + parameters: ["arr"], + printCode: { arguments, context in + let (scope, printer) = (context.scope, context.printer) + let arr = arguments[0] + let typedArrVar = scope.variable("typedArr") + let idVar = scope.variable("typedArrId") + printer.write( + "const \(typedArrVar) = new \(JSGlueVariableScope.reservedTypedArrayConstructors)[\(kind)](\(arr));" + ) + printer.write( + "const \(idVar) = \(JSGlueVariableScope.reservedSwift).memory.retain(\(typedArrVar));" + ) + return [idVar, "\(typedArrVar).length"] + } + ) + } + + /// Lowers a numeric array from JS to Swift for return values (stack-based). + /// Pushes (sourceId, count) onto the i32 stack. + static func numericArrayLowerReturn(elementType: BridgeType) -> IntrinsicJSFragment { + let kind = elementType.typedArrayKind! + return IntrinsicJSFragment( + parameters: ["arr"], + printCode: { arguments, context in + let (scope, printer) = (context.scope, context.printer) + let arr = arguments[0] + let typedArrVar = scope.variable("typedArr") + let idVar = scope.variable("typedArrId") + printer.write( + "const \(typedArrVar) = new \(JSGlueVariableScope.reservedTypedArrayConstructors)[\(kind)](\(arr));" + ) + printer.write( + "const \(idVar) = \(JSGlueVariableScope.reservedSwift).memory.retain(\(typedArrVar));" + ) + scope.emitPushI32Parameter(idVar, printer: printer) + scope.emitPushI32Parameter("\(typedArrVar).length", printer: printer) + return [] + } + ) + } + + /// Lifts a numeric array from Swift to JS via bulk TypedArray transfer. + /// Swift side pushed the typed array view onto taStack; JS pops and converts to plain Array. + static func numericArrayLift(elementType: BridgeType) -> IntrinsicJSFragment { + return IntrinsicJSFragment( + parameters: [], + printCode: { arguments, context in + let (scope, printer) = (context.scope, context.printer) + let srcVar = scope.variable("taSrc") + let resultVar = scope.variable("arrayResult") + let iVar = scope.variable("i") + printer.write("const \(srcVar) = \(JSGlueVariableScope.reservedTaStack).pop();") + printer.write("const \(resultVar) = new Array(\(srcVar).length);") + printer.write( + "for (let \(iVar) = 0; \(iVar) < \(srcVar).length; \(iVar)++) \(resultVar)[\(iVar)] = \(srcVar)[\(iVar)];" + ) + return [resultVar] + } + ) + } + /// Lowers an array from JS to Swift by iterating elements and pushing to stacks static func arrayLower(elementType: BridgeType) throws -> IntrinsicJSFragment { return IntrinsicJSFragment( diff --git a/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift b/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift index 346b7333b..ba141775a 100644 --- a/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift +++ b/Plugins/BridgeJS/Sources/BridgeJSSkeleton/BridgeJSSkeleton.swift @@ -275,6 +275,42 @@ public enum BridgeType: Codable, Equatable, Hashable, Sendable { indirect case closure(ClosureSignature, useJSTypedClosure: Bool) } +extension BridgeType { + /// Returns true if this type is a numeric scalar eligible for bulk TypedArray transfer. + /// Used by codegen to route `[NumericType]` through the optimized typed-array path + /// instead of element-by-element stack operations. + public var isNumericScalar: Bool { + switch self { + case .integer, .float, .double: return true + default: return false + } + } + + /// Returns the JavaScript TypedArray constructor kind index for numeric scalars. + /// The index matches the `typedArrayConstructors` table in JS glue code. + /// Returns nil for non-numeric types. + public var typedArrayKind: Int? { + switch self { + case .integer(let t): + switch (t.width, t.isSigned) { + case (.w8, true): return 0 // Int8Array + case (.w8, false): return 1 // Uint8Array + case (.w16, true): return 2 // Int16Array + case (.w16, false): return 3 // Uint16Array + case (.w32, true): return 4 // Int32Array + case (.w32, false): return 5 // Uint32Array + case (.w64, true): return 6 // BigInt64Array + case (.w64, false): return 7 // BigUint64Array + case (.word, true): return 4 // Int (i32 on wasm32) → Int32Array + case (.word, false): return 5 // UInt (u32 on wasm32) → Uint32Array + } + case .float: return 8 // Float32Array + case .double: return 9 // Float64Array + default: return nil + } + } +} + public enum WasmCoreType: String, Codable, Sendable { case i32, i64, f32, f64, pointer } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ArrayTypes.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ArrayTypes.swift index a058d13a7..a4c253fdf 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ArrayTypes.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ArrayTypes.swift @@ -94,10 +94,10 @@ fileprivate func _bjs_struct_lift_Point_extern() -> Int32 { @_expose(wasm, "bjs_processIntArray") @_cdecl("bjs_processIntArray") -public func _bjs_processIntArray() -> Void { +public func _bjs_processIntArray(_ valuesSourceId: Int32, _ valuesCount: Int32) -> Void { #if arch(wasm32) - let ret = processIntArray(_: [Int].bridgeJSStackPop()) - ret.bridgeJSStackPush() + let ret = processIntArray(_: [Int].bridgeJSTypedArrayLiftParameter(valuesSourceId, valuesCount)) + ret.bridgeJSTypedArrayPush() #else fatalError("Only available on WebAssembly") #endif @@ -116,10 +116,10 @@ public func _bjs_processStringArray() -> Void { @_expose(wasm, "bjs_processDoubleArray") @_cdecl("bjs_processDoubleArray") -public func _bjs_processDoubleArray() -> Void { +public func _bjs_processDoubleArray(_ valuesSourceId: Int32, _ valuesCount: Int32) -> Void { #if arch(wasm32) - let ret = processDoubleArray(_: [Double].bridgeJSStackPop()) - ret.bridgeJSStackPush() + let ret = processDoubleArray(_: [Double].bridgeJSTypedArrayLiftParameter(valuesSourceId, valuesCount)) + ret.bridgeJSTypedArrayPush() #else fatalError("Only available on WebAssembly") #endif @@ -171,9 +171,9 @@ public func _bjs_processStatusArray() -> Void { @_expose(wasm, "bjs_sumIntArray") @_cdecl("bjs_sumIntArray") -public func _bjs_sumIntArray() -> Int32 { +public func _bjs_sumIntArray(_ valuesSourceId: Int32, _ valuesCount: Int32) -> Int32 { #if arch(wasm32) - let ret = sumIntArray(_: [Int].bridgeJSStackPop()) + let ret = sumIntArray(_: [Int].bridgeJSTypedArrayLiftParameter(valuesSourceId, valuesCount)) return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -380,10 +380,10 @@ public func _bjs_processNestedJSObjectArray() -> Void { @_expose(wasm, "bjs_multiArrayParams") @_cdecl("bjs_multiArrayParams") -public func _bjs_multiArrayParams() -> Int32 { +public func _bjs_multiArrayParams(_ numsSourceId: Int32, _ numsCount: Int32) -> Int32 { #if arch(wasm32) let _tmp_strs = [String].bridgeJSStackPop() - let _tmp_nums = [Int].bridgeJSStackPop() + let _tmp_nums = [Int].bridgeJSTypedArrayLiftParameter(numsSourceId, numsCount) let ret = multiArrayParams(nums: _tmp_nums, strs: _tmp_strs) return ret.bridgeJSLowerReturn() #else @@ -437,10 +437,10 @@ fileprivate func _bjs_Item_wrap_extern(_ pointer: UnsafeMutableRawPointer) -> In @_expose(wasm, "bjs_MultiArrayContainer_init") @_cdecl("bjs_MultiArrayContainer_init") -public func _bjs_MultiArrayContainer_init() -> UnsafeMutableRawPointer { +public func _bjs_MultiArrayContainer_init(_ numsSourceId: Int32, _ numsCount: Int32) -> UnsafeMutableRawPointer { #if arch(wasm32) let _tmp_strs = [String].bridgeJSStackPop() - let _tmp_nums = [Int].bridgeJSStackPop() + let _tmp_nums = [Int].bridgeJSTypedArrayLiftParameter(numsSourceId, numsCount) let ret = MultiArrayContainer(nums: _tmp_nums, strs: _tmp_strs) return ret.bridgeJSLowerReturn() #else @@ -453,7 +453,7 @@ public func _bjs_MultiArrayContainer_init() -> UnsafeMutableRawPointer { public func _bjs_MultiArrayContainer_numbers_get(_ _self: UnsafeMutableRawPointer) -> Void { #if arch(wasm32) let ret = MultiArrayContainer.bridgeJSLiftParameter(_self).numbers - ret.bridgeJSStackPush() + ret.bridgeJSTypedArrayPush() #else fatalError("Only available on WebAssembly") #endif @@ -555,7 +555,7 @@ fileprivate func bjs_importProcessNumbers_extern() -> Void { } func _$importProcessNumbers(_ values: [Double]) throws(JSException) -> Void { - let _ = values.bridgeJSLowerParameter() + values.bridgeJSTypedArrayPush() bjs_importProcessNumbers() if let error = _swift_js_take_exception() { throw error @@ -579,7 +579,9 @@ func _$importGetNumbers() throws(JSException) -> [Double] { if let error = _swift_js_take_exception() { throw error } - return [Double].bridgeJSLiftReturn() + let _count = _swift_js_pop_i32() + let _sourceId = _swift_js_pop_i32() + return [Double].bridgeJSTypedArrayLiftParameter(_sourceId, _count) } #if arch(wasm32) @@ -595,12 +597,14 @@ fileprivate func bjs_importTransformNumbers_extern() -> Void { } func _$importTransformNumbers(_ values: [Double]) throws(JSException) -> [Double] { - let _ = values.bridgeJSLowerParameter() + values.bridgeJSTypedArrayPush() bjs_importTransformNumbers() if let error = _swift_js_take_exception() { throw error } - return [Double].bridgeJSLiftReturn() + let _count = _swift_js_pop_i32() + let _sourceId = _swift_js_pop_i32() + return [Double].bridgeJSTypedArrayLiftParameter(_sourceId, _count) } #if arch(wasm32) diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DefaultParameters.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DefaultParameters.swift index 507827646..4828f79ec 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DefaultParameters.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/DefaultParameters.swift @@ -322,10 +322,10 @@ public func _bjs_testOptionalStructWithValueDefault() -> Void { @_expose(wasm, "bjs_testIntArrayDefault") @_cdecl("bjs_testIntArrayDefault") -public func _bjs_testIntArrayDefault() -> Void { +public func _bjs_testIntArrayDefault(_ valuesSourceId: Int32, _ valuesCount: Int32) -> Void { #if arch(wasm32) - let ret = testIntArrayDefault(values: [Int].bridgeJSStackPop()) - ret.bridgeJSStackPush() + let ret = testIntArrayDefault(values: [Int].bridgeJSTypedArrayLiftParameter(valuesSourceId, valuesCount)) + ret.bridgeJSTypedArrayPush() #else fatalError("Only available on WebAssembly") #endif @@ -344,10 +344,10 @@ public func _bjs_testStringArrayDefault() -> Void { @_expose(wasm, "bjs_testDoubleArrayDefault") @_cdecl("bjs_testDoubleArrayDefault") -public func _bjs_testDoubleArrayDefault() -> Void { +public func _bjs_testDoubleArrayDefault(_ valuesSourceId: Int32, _ valuesCount: Int32) -> Void { #if arch(wasm32) - let ret = testDoubleArrayDefault(values: [Double].bridgeJSStackPop()) - ret.bridgeJSStackPush() + let ret = testDoubleArrayDefault(values: [Double].bridgeJSTypedArrayLiftParameter(valuesSourceId, valuesCount)) + ret.bridgeJSTypedArrayPush() #else fatalError("Only available on WebAssembly") #endif @@ -366,10 +366,10 @@ public func _bjs_testBoolArrayDefault() -> Void { @_expose(wasm, "bjs_testEmptyArrayDefault") @_cdecl("bjs_testEmptyArrayDefault") -public func _bjs_testEmptyArrayDefault() -> Void { +public func _bjs_testEmptyArrayDefault(_ itemsSourceId: Int32, _ itemsCount: Int32) -> Void { #if arch(wasm32) - let ret = testEmptyArrayDefault(items: [Int].bridgeJSStackPop()) - ret.bridgeJSStackPush() + let ret = testEmptyArrayDefault(items: [Int].bridgeJSTypedArrayLiftParameter(itemsSourceId, itemsCount)) + ret.bridgeJSTypedArrayPush() #else fatalError("Only available on WebAssembly") #endif @@ -377,9 +377,9 @@ public func _bjs_testEmptyArrayDefault() -> Void { @_expose(wasm, "bjs_testMixedWithArrayDefault") @_cdecl("bjs_testMixedWithArrayDefault") -public func _bjs_testMixedWithArrayDefault(_ nameBytes: Int32, _ nameLength: Int32, _ enabled: Int32) -> Void { +public func _bjs_testMixedWithArrayDefault(_ nameBytes: Int32, _ nameLength: Int32, _ valuesSourceId: Int32, _ valuesCount: Int32, _ enabled: Int32) -> Void { #if arch(wasm32) - let ret = testMixedWithArrayDefault(name: String.bridgeJSLiftParameter(nameBytes, nameLength), values: [Int].bridgeJSStackPop(), enabled: Bool.bridgeJSLiftParameter(enabled)) + let ret = testMixedWithArrayDefault(name: String.bridgeJSLiftParameter(nameBytes, nameLength), values: [Int].bridgeJSTypedArrayLiftParameter(valuesSourceId, valuesCount), enabled: Bool.bridgeJSLiftParameter(enabled)) return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ImportArray.swift b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ImportArray.swift index db1f136e7..731032729 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ImportArray.swift +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSCodegenTests/ImportArray.swift @@ -11,12 +11,14 @@ fileprivate func bjs_roundtrip_extern() -> Void { } func _$roundtrip(_ items: [Int]) throws(JSException) -> [Int] { - let _ = items.bridgeJSLowerParameter() + items.bridgeJSTypedArrayPush() bjs_roundtrip() if let error = _swift_js_take_exception() { throw error } - return [Int].bridgeJSLiftReturn() + let _count = _swift_js_pop_i32() + let _sourceId = _swift_js_pop_i32() + return [Int].bridgeJSTypedArrayLiftParameter(_sourceId, _count) } #if arch(wasm32) diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayTypes.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayTypes.js index 8359220c9..1c8b80045 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayTypes.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ArrayTypes.js @@ -38,6 +38,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -123,6 +125,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_struct_lower_Point"] = function(objectId) { structHelpers.Point.lower(swift.memory.getObject(objectId)); } @@ -249,13 +273,9 @@ export async function createInstantiator(options, swift) { } TestModule["bjs_importProcessNumbers"] = function bjs_importProcessNumbers() { try { - const arrayLen = i32Stack.pop(); - const arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const f64 = f64Stack.pop(); - arrayResult.push(f64); - } - arrayResult.reverse(); + const taSrc = taStack.pop(); + const arrayResult = new Array(taSrc.length); + for (let i = 0; i < taSrc.length; i++) arrayResult[i] = taSrc[i]; imports.importProcessNumbers(arrayResult); } catch (error) { setException(error); @@ -264,28 +284,24 @@ 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); + const typedArr = new typedArrayConstructors[9](ret); + const typedArrId = swift.memory.retain(typedArr); + i32Stack.push(typedArrId); + i32Stack.push(typedArr.length); } catch (error) { setException(error); } } TestModule["bjs_importTransformNumbers"] = function bjs_importTransformNumbers() { try { - const arrayLen = i32Stack.pop(); - const arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const f64 = f64Stack.pop(); - arrayResult.push(f64); - } - arrayResult.reverse(); + const taSrc = taStack.pop(); + const arrayResult = new Array(taSrc.length); + for (let i = 0; i < taSrc.length; i++) arrayResult[i] = taSrc[i]; let ret = imports.importTransformNumbers(arrayResult); - for (const elem of ret) { - f64Stack.push(elem); - } - i32Stack.push(ret.length); + const typedArr = new typedArrayConstructors[9](ret); + const typedArrId = swift.memory.retain(typedArr); + i32Stack.push(typedArrId); + i32Stack.push(typedArr.length); } catch (error) { setException(error); } @@ -406,29 +422,23 @@ 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 typedArr = new typedArrayConstructors[4](nums); + const typedArrId = swift.memory.retain(typedArr); + for (const elem of strs) { + const bytes = textEncoder.encode(elem); const id = swift.memory.retain(bytes); i32Stack.push(bytes.length); i32Stack.push(id); } i32Stack.push(strs.length); - const ret = instance.exports.bjs_MultiArrayContainer_init(); + const ret = instance.exports.bjs_MultiArrayContainer_init(typedArrId, typedArr.length); return MultiArrayContainer.__construct(ret); } get numbers() { instance.exports.bjs_MultiArrayContainer_numbers_get(this.pointer); - const arrayLen = i32Stack.pop(); - const arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const int = i32Stack.pop(); - arrayResult.push(int); - } - arrayResult.reverse(); + const taSrc = taStack.pop(); + const arrayResult = new Array(taSrc.length); + for (let i = 0; i < taSrc.length; i++) arrayResult[i] = taSrc[i]; return arrayResult; } get strings() { @@ -450,18 +460,12 @@ export async function createInstantiator(options, swift) { Item, MultiArrayContainer, processIntArray: function bjs_processIntArray(values) { - for (const elem of values) { - i32Stack.push((elem | 0)); - } - i32Stack.push(values.length); - instance.exports.bjs_processIntArray(); - const arrayLen = i32Stack.pop(); - const arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const int = i32Stack.pop(); - arrayResult.push(int); - } - arrayResult.reverse(); + const typedArr = new typedArrayConstructors[4](values); + const typedArrId = swift.memory.retain(typedArr); + instance.exports.bjs_processIntArray(typedArrId, typedArr.length); + const taSrc = taStack.pop(); + const arrayResult = new Array(taSrc.length); + for (let i = 0; i < taSrc.length; i++) arrayResult[i] = taSrc[i]; return arrayResult; }, processStringArray: function bjs_processStringArray(values) { @@ -483,18 +487,12 @@ export async function createInstantiator(options, swift) { return arrayResult; }, processDoubleArray: function bjs_processDoubleArray(values) { - for (const elem of values) { - f64Stack.push(elem); - } - i32Stack.push(values.length); - instance.exports.bjs_processDoubleArray(); - const arrayLen = i32Stack.pop(); - const arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const f64 = f64Stack.pop(); - arrayResult.push(f64); - } - arrayResult.reverse(); + const typedArr = new typedArrayConstructors[9](values); + const typedArrId = swift.memory.retain(typedArr); + instance.exports.bjs_processDoubleArray(typedArrId, typedArr.length); + const taSrc = taStack.pop(); + const arrayResult = new Array(taSrc.length); + for (let i = 0; i < taSrc.length; i++) arrayResult[i] = taSrc[i]; return arrayResult; }, processBoolArray: function bjs_processBoolArray(values) { @@ -558,11 +556,9 @@ export async function createInstantiator(options, swift) { return arrayResult; }, sumIntArray: function bjs_sumIntArray(values) { - for (const elem of values) { - i32Stack.push((elem | 0)); - } - i32Stack.push(values.length); - const ret = instance.exports.bjs_sumIntArray(); + const typedArr = new typedArrayConstructors[4](values); + const typedArrId = swift.memory.retain(typedArr); + const ret = instance.exports.bjs_sumIntArray(typedArrId, typedArr.length); return ret; }, findFirstPoint: function bjs_findFirstPoint(points, matching) { @@ -971,18 +967,16 @@ export async function createInstantiator(options, swift) { 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 typedArr = new typedArrayConstructors[4](nums); + const typedArrId = swift.memory.retain(typedArr); + for (const elem of strs) { + const bytes = textEncoder.encode(elem); const id = swift.memory.retain(bytes); i32Stack.push(bytes.length); i32Stack.push(id); } i32Stack.push(strs.length); - const ret = instance.exports.bjs_multiArrayParams(); + const ret = instance.exports.bjs_multiArrayParams(typedArrId, typedArr.length); return ret; }, multiOptionalArrayParams: function bjs_multiOptionalArrayParams(a, b) { diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.js index bf368738e..3a7336db6 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Async.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -98,6 +100,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncImport.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncImport.js index 89ab29827..4724f722b 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncImport.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncImport.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -213,6 +215,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncStaticImport.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncStaticImport.js index 7fd6a0d6b..0132b8c4e 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncStaticImport.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/AsyncStaticImport.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -212,6 +214,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DefaultParameters.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DefaultParameters.js index cafd250b0..bcf2d61db 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DefaultParameters.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DefaultParameters.js @@ -31,6 +31,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -140,6 +142,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_struct_lower_Config"] = function(objectId) { structHelpers.Config.lower(swift.memory.getObject(objectId)); } @@ -544,18 +568,12 @@ export async function createInstantiator(options, swift) { return optResult; }, testIntArrayDefault: function bjs_testIntArrayDefault(values = [1, 2, 3]) { - for (const elem of values) { - i32Stack.push((elem | 0)); - } - i32Stack.push(values.length); - instance.exports.bjs_testIntArrayDefault(); - const arrayLen = i32Stack.pop(); - const arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const int = i32Stack.pop(); - arrayResult.push(int); - } - arrayResult.reverse(); + const typedArr = new typedArrayConstructors[4](values); + const typedArrId = swift.memory.retain(typedArr); + instance.exports.bjs_testIntArrayDefault(typedArrId, typedArr.length); + const taSrc = taStack.pop(); + const arrayResult = new Array(taSrc.length); + for (let i = 0; i < taSrc.length; i++) arrayResult[i] = taSrc[i]; return arrayResult; }, testStringArrayDefault: function bjs_testStringArrayDefault(names = ["a", "b", "c"]) { @@ -577,18 +595,12 @@ export async function createInstantiator(options, swift) { 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); - instance.exports.bjs_testDoubleArrayDefault(); - const arrayLen = i32Stack.pop(); - const arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const f64 = f64Stack.pop(); - arrayResult.push(f64); - } - arrayResult.reverse(); + const typedArr = new typedArrayConstructors[9](values); + const typedArrId = swift.memory.retain(typedArr); + instance.exports.bjs_testDoubleArrayDefault(typedArrId, typedArr.length); + const taSrc = taStack.pop(); + const arrayResult = new Array(taSrc.length); + for (let i = 0; i < taSrc.length; i++) arrayResult[i] = taSrc[i]; return arrayResult; }, testBoolArrayDefault: function bjs_testBoolArrayDefault(flags = [true, false, true]) { @@ -607,28 +619,20 @@ export async function createInstantiator(options, swift) { return arrayResult; }, testEmptyArrayDefault: function bjs_testEmptyArrayDefault(items = []) { - for (const elem of items) { - i32Stack.push((elem | 0)); - } - i32Stack.push(items.length); - instance.exports.bjs_testEmptyArrayDefault(); - const arrayLen = i32Stack.pop(); - const arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const int = i32Stack.pop(); - arrayResult.push(int); - } - arrayResult.reverse(); + const typedArr = new typedArrayConstructors[4](items); + const typedArrId = swift.memory.retain(typedArr); + instance.exports.bjs_testEmptyArrayDefault(typedArrId, typedArr.length); + const taSrc = taStack.pop(); + const arrayResult = new Array(taSrc.length); + for (let i = 0; i < taSrc.length; i++) arrayResult[i] = taSrc[i]; 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); - instance.exports.bjs_testMixedWithArrayDefault(nameId, nameBytes.length, enabled); + const typedArr = new typedArrayConstructors[4](values); + const typedArrId = swift.memory.retain(typedArr); + instance.exports.bjs_testMixedWithArrayDefault(nameId, nameBytes.length, typedArrId, typedArr.length, enabled); const ret = tmpRetString; tmpRetString = undefined; return ret; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DictionaryTypes.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DictionaryTypes.js index 920017972..f5b5d5a35 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DictionaryTypes.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/DictionaryTypes.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -139,6 +141,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_struct_lower_Counters"] = function(objectId) { structHelpers.Counters.lower(swift.memory.getObject(objectId)); } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.js index 3d2230c6c..e90d1dc88 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumAssociatedValue.js @@ -106,6 +106,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -831,6 +833,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_struct_lower_Point"] = function(objectId) { structHelpers.Point.lower(swift.memory.getObject(objectId)); } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.js index fe94c046f..ec72973fe 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumCase.js @@ -49,6 +49,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -122,6 +124,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Global.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Global.js index 10fe31f64..e7230ac89 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Global.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.Global.js @@ -69,6 +69,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -142,6 +144,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.js index a6aeee4b0..771883d78 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumNamespace.js @@ -50,6 +50,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -123,6 +125,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.js index 7e5334811..cbb25e6fc 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/EnumRawType.js @@ -100,6 +100,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -174,6 +176,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/FixedWidthIntegers.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/FixedWidthIntegers.js index 53ddd7301..786434d4b 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/FixedWidthIntegers.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/FixedWidthIntegers.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -99,6 +101,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalGetter.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalGetter.js index 346b74eac..deae935cf 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalGetter.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalGetter.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -99,6 +101,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalThisImports.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalThisImports.js index f74095374..a1a740b64 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalThisImports.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/GlobalThisImports.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -98,6 +100,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.ConfigPointer.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.ConfigPointer.js index c2490c0ea..bab670c6a 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.ConfigPointer.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.ConfigPointer.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -98,6 +100,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.PerClass.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.PerClass.js index d970c5d77..ea142b2ea 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.PerClass.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.PerClass.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -98,6 +100,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.js index d970c5d77..ea142b2ea 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/IdentityModeClass.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -98,6 +100,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ImportArray.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ImportArray.js index 06cf6550e..fcf6abd14 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ImportArray.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ImportArray.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -99,6 +101,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; @@ -192,18 +216,14 @@ export async function createInstantiator(options, swift) { const TestModule = importObject["TestModule"] = importObject["TestModule"] || {}; TestModule["bjs_roundtrip"] = function bjs_roundtrip() { try { - const arrayLen = i32Stack.pop(); - const arrayResult = []; - for (let i = 0; i < arrayLen; i++) { - const int = i32Stack.pop(); - arrayResult.push(int); - } - arrayResult.reverse(); + const taSrc = taStack.pop(); + const arrayResult = new Array(taSrc.length); + for (let i = 0; i < taSrc.length; i++) arrayResult[i] = taSrc[i]; let ret = imports.roundtrip(arrayResult); - for (const elem of ret) { - i32Stack.push((elem | 0)); - } - i32Stack.push(ret.length); + const typedArr = new typedArrayConstructors[4](ret); + const typedArrId = swift.memory.retain(typedArr); + i32Stack.push(typedArrId); + i32Stack.push(typedArr.length); } 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 c469fcb58..6c9d5b81b 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ImportedTypeInExportedInterface.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ImportedTypeInExportedInterface.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -137,6 +139,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_struct_lower_FooContainer"] = function(objectId) { structHelpers.FooContainer.lower(swift.memory.getObject(objectId)); } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/InvalidPropertyNames.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/InvalidPropertyNames.js index 952197c2a..0ff9a9fa6 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/InvalidPropertyNames.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/InvalidPropertyNames.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -99,6 +101,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClass.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClass.js index 88a5adb38..5db796d21 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClass.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClass.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -99,6 +101,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClassStaticFunctions.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClassStaticFunctions.js index 10fafb7a0..5df29285b 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClassStaticFunctions.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSClassStaticFunctions.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -99,6 +101,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSValue.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSValue.js index 0258b63b6..c788d4957 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSValue.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/JSValue.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -188,6 +190,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedGlobal.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedGlobal.js index 195eef468..f9a0b29f4 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedGlobal.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedGlobal.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -98,6 +100,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedModules.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedModules.js index ca54493f6..942a84e84 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedModules.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedModules.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -98,6 +100,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedPrivate.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedPrivate.js index 3551caab2..06db9c652 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedPrivate.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/MixedPrivate.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -98,6 +100,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Global.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Global.js index a63df44be..5f69528a6 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Global.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.Global.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -98,6 +100,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.js index 32a325bda..073e4b8df 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Namespaces.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -98,6 +100,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/NestedType.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/NestedType.js index cf24e7e2d..00b65682c 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/NestedType.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/NestedType.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -109,6 +111,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_struct_lower_User_Stats"] = function(objectId) { structHelpers.Stats.lower(swift.memory.getObject(objectId)); } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Optionals.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Optionals.js index 1d585ce0b..ee405d182 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Optionals.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Optionals.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -99,6 +101,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.js index 490f2b4e2..e5bfe71c9 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveParameters.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -99,6 +101,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.js index bec07b959..737752a70 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PrimitiveReturn.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -99,6 +101,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PropertyTypes.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PropertyTypes.js index 7f840708e..1e8ed9a60 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PropertyTypes.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/PropertyTypes.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -98,6 +100,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Protocol.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Protocol.js index 9fb9b172b..6b7a5be52 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Protocol.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Protocol.js @@ -49,6 +49,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -155,6 +157,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ProtocolInClosure.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ProtocolInClosure.js index aefdb5679..d725915fc 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ProtocolInClosure.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/ProtocolInClosure.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -123,6 +125,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.Global.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.Global.js index ef685b8a4..218640ce7 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.Global.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.Global.js @@ -36,6 +36,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -142,6 +144,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.js index 1fd066076..80182818c 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticFunctions.js @@ -36,6 +36,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -142,6 +144,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.Global.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.Global.js index 5800fcb56..166bdfe76 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.Global.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.Global.js @@ -30,6 +30,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -103,6 +105,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.js index b81255810..10705b6fc 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StaticProperties.js @@ -30,6 +30,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -103,6 +105,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.js index 033f08cd2..95bb37830 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringParameter.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -99,6 +101,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.js index 8187b9e92..d7f087f9b 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/StringReturn.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -99,6 +101,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.js index 9ee57d692..2da578662 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClass.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -99,6 +101,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosure.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosure.js index 0b4ca3dcc..d86becd95 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosure.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosure.js @@ -55,6 +55,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -226,6 +228,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_struct_lower_Animal"] = function(objectId) { structHelpers.Animal.lower(swift.memory.getObject(objectId)); } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosureImports.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosureImports.js index d9df868ec..33f665df6 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosureImports.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftClosureImports.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -124,6 +126,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStruct.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStruct.js index abfb24d48..7c0de44ac 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStruct.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStruct.js @@ -30,6 +30,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -311,6 +313,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_struct_lower_DataPoint"] = function(objectId) { structHelpers.DataPoint.lower(swift.memory.getObject(objectId)); } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStructImports.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStructImports.js index d4f1160f3..7ee6d49b2 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStructImports.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftStructImports.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -110,6 +112,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_struct_lower_Point"] = function(objectId) { structHelpers.Point.lower(swift.memory.getObject(objectId)); } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftTypedClosureAccess.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftTypedClosureAccess.js index 4e0fd8341..680204392 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftTypedClosureAccess.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/SwiftTypedClosureAccess.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -123,6 +125,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Throws.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Throws.js index b2c381a03..1038735af 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Throws.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/Throws.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -98,6 +100,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/UnsafePointer.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/UnsafePointer.js index ef81ef69e..25b65ff15 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/UnsafePointer.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/UnsafePointer.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -115,6 +117,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_struct_lower_PointerFields"] = function(objectId) { structHelpers.PointerFields.lower(swift.memory.getObject(objectId)); } diff --git a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.js b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.js index 97948b286..f41a881eb 100644 --- a/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.js +++ b/Plugins/BridgeJS/Tests/BridgeJSToolTests/__Snapshots__/BridgeJSLinkTests/VoidParameterVoidReturn.js @@ -25,6 +25,8 @@ export async function createInstantiator(options, swift) { let f32Stack = []; let f64Stack = []; let ptrStack = []; + let taStack = []; + const typedArrayConstructors = [Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, BigUint64Array, Float32Array, Float64Array]; const enumHelpers = {}; const structHelpers = {}; @@ -99,6 +101,28 @@ export async function createInstantiator(options, swift) { bjs["swift_js_pop_i64"] = function() { return i64Stack.pop(); } + bjs["swift_js_push_typed_array"] = function(ptr, count, kind) { + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + const totalBytes = count * elemSize; + const copy = new Uint8Array(totalBytes); + copy.set(new Uint8Array(memory.buffer, ptr, totalBytes)); + taStack.push(new Constructor(copy.buffer)); + } + bjs["swift_js_init_typed_array_memory"] = function(sourceId, destPtr, count, kind) { + const source = swift.memory.getObject(sourceId); + swift.memory.release(sourceId); + const Constructor = typedArrayConstructors[kind]; + const elemSize = Constructor.BYTES_PER_ELEMENT; + if (destPtr % elemSize === 0) { + const dest = new Constructor(memory.buffer, destPtr, count); + dest.set(source); + } else { + const dest = new Uint8Array(memory.buffer, destPtr, count * elemSize); + const srcBytes = new Uint8Array(source.buffer, source.byteOffset, source.byteLength); + dest.set(srcBytes); + } + } bjs["swift_js_return_optional_bool"] = function(isSome, value) { if (isSome === 0) { tmpRetOptionalBool = null; diff --git a/Sources/JavaScriptKit/BridgeJSIntrinsics.swift b/Sources/JavaScriptKit/BridgeJSIntrinsics.swift index 86a1aaf3f..4628dfc7a 100644 --- a/Sources/JavaScriptKit/BridgeJSIntrinsics.swift +++ b/Sources/JavaScriptKit/BridgeJSIntrinsics.swift @@ -1964,6 +1964,139 @@ extension _BridgedAsOptional where Wrapped: _BridgedSwiftStruct { } } +// MARK: - Typed Array Bulk Transfer + +/// Protocol for numeric types eligible for bulk TypedArray transfer. +/// +/// Conforming types can use the optimized typed-array path for `[T]` bridging +/// instead of element-by-element stack operations. The codegen detects when an +/// array's element type conforms to this protocol and generates bulk transfer calls. +public protocol _BridgeJSTypedArrayElement { + /// The TypedArray constructor kind index (matches `typedArrayConstructors` in JS glue). + @_spi(BridgeJS) static var _bridgeJSTypedArrayKind: Int32 { get } +} + +extension Int8: _BridgeJSTypedArrayElement { + @_spi(BridgeJS) public static var _bridgeJSTypedArrayKind: Int32 { 0 } +} +extension UInt8: _BridgeJSTypedArrayElement { + @_spi(BridgeJS) public static var _bridgeJSTypedArrayKind: Int32 { 1 } +} +extension Int16: _BridgeJSTypedArrayElement { + @_spi(BridgeJS) public static var _bridgeJSTypedArrayKind: Int32 { 2 } +} +extension UInt16: _BridgeJSTypedArrayElement { + @_spi(BridgeJS) public static var _bridgeJSTypedArrayKind: Int32 { 3 } +} +extension Int32: _BridgeJSTypedArrayElement { + @_spi(BridgeJS) public static var _bridgeJSTypedArrayKind: Int32 { 4 } +} +extension UInt32: _BridgeJSTypedArrayElement { + @_spi(BridgeJS) public static var _bridgeJSTypedArrayKind: Int32 { 5 } +} +extension Int64: _BridgeJSTypedArrayElement { + @_spi(BridgeJS) public static var _bridgeJSTypedArrayKind: Int32 { 6 } +} +extension UInt64: _BridgeJSTypedArrayElement { + @_spi(BridgeJS) public static var _bridgeJSTypedArrayKind: Int32 { 7 } +} +extension Float: _BridgeJSTypedArrayElement { + @_spi(BridgeJS) public static var _bridgeJSTypedArrayKind: Int32 { 8 } +} +extension Double: _BridgeJSTypedArrayElement { + @_spi(BridgeJS) public static var _bridgeJSTypedArrayKind: Int32 { 9 } +} +extension Int: _BridgeJSTypedArrayElement { + @_spi(BridgeJS) public static var _bridgeJSTypedArrayKind: Int32 { 4 } // Int is i32 on wasm32 +} +extension UInt: _BridgeJSTypedArrayElement { + @_spi(BridgeJS) public static var _bridgeJSTypedArrayKind: Int32 { 5 } // UInt is u32 on wasm32 +} + +// MARK: Typed Array WASM Externs + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_push_typed_array") +private func _swift_js_push_typed_array_extern(_ ptr: UnsafeRawPointer, _ count: Int32, _ kind: Int32) +#else +private func _swift_js_push_typed_array_extern(_ ptr: UnsafeRawPointer, _ count: Int32, _ kind: Int32) { + _onlyAvailableOnWasm() +} +#endif + +/// Pushes a typed array view onto the typed-array stack. +/// JS side creates a view of WASM memory and converts to a plain Array immediately. +@_spi(BridgeJS) @inline(never) public func _swift_js_push_typed_array( + _ ptr: UnsafeRawPointer, + _ count: Int32, + _ kind: Int32 +) { + _swift_js_push_typed_array_extern(ptr, count, kind) +} + +#if arch(wasm32) +@_extern(wasm, module: "bjs", name: "swift_js_init_typed_array_memory") +private func _swift_js_init_typed_array_memory_extern( + _ sourceId: Int32, + _ destPtr: UnsafeMutableRawPointer, + _ count: Int32, + _ kind: Int32 +) +#else +private func _swift_js_init_typed_array_memory_extern( + _ sourceId: Int32, + _ destPtr: UnsafeMutableRawPointer, + _ count: Int32, + _ kind: Int32 +) { + _onlyAvailableOnWasm() +} +#endif + +/// Copies a JS TypedArray (retained by `sourceId`) into WASM memory at `destPtr`. +/// The JS side releases the source object after copying. +@_spi(BridgeJS) @inline(never) public func _swift_js_init_typed_array_memory( + _ sourceId: Int32, + _ destPtr: UnsafeMutableRawPointer, + _ count: Int32, + _ kind: Int32 +) { + _swift_js_init_typed_array_memory_extern(sourceId, destPtr, count, kind) +} + +// MARK: Typed Array Bulk Push/Lift + +extension Array where Element: _BridgeJSTypedArrayElement { + /// Bulk push for numeric arrays — uses TypedArray transfer instead of element-by-element. + @_spi(BridgeJS) public consuming func bridgeJSTypedArrayPush() { + self.withUnsafeBufferPointer { buffer in + guard let baseAddress = buffer.baseAddress else { + _swift_js_push_typed_array(UnsafeRawPointer(bitPattern: 1)!, 0, Element._bridgeJSTypedArrayKind) + return + } + _swift_js_push_typed_array( + UnsafeRawPointer(baseAddress), + Int32(buffer.count), + Element._bridgeJSTypedArrayKind + ) + } + } + + /// Bulk lift for numeric array parameters — uses retain-allocate-callback pattern. + @_spi(BridgeJS) public static func bridgeJSTypedArrayLiftParameter(_ sourceId: Int32, _ count: Int32) -> [Element] { + guard count > 0 else { return [] } + return Array(unsafeUninitializedCapacity: Int(count)) { buffer, initializedCount in + _swift_js_init_typed_array_memory( + sourceId, + UnsafeMutableRawPointer(buffer.baseAddress!), + count, + Element._bridgeJSTypedArrayKind + ) + initializedCount = Int(count) + } + } +} + // MARK: - Array Support extension Array: _BridgedSwiftTypeLoweredIntoVoidType diff --git a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift index 771838716..7ea1bfd4c 100644 --- a/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift +++ b/Tests/BridgeJSRuntimeTests/Generated/BridgeJS.swift @@ -2199,7 +2199,7 @@ private enum _BJS_Closure_20BridgeJSRuntimeTestssSaSd_y { return { [callback] param0 in #if arch(wasm32) let callbackValue = callback.bridgeJSLowerParameter() - let _ = param0.bridgeJSLowerParameter() + param0.bridgeJSTypedArrayPush() invoke_js_callback_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSaSd_y(callbackValue) #else fatalError("Only available on WebAssembly") @@ -2221,10 +2221,10 @@ extension JSTypedClosure where Signature == (sending [Double]) -> Void { @_expose(wasm, "invoke_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSaSd_y") @_cdecl("invoke_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSaSd_y") -public func _invoke_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSaSd_y(_ boxPtr: UnsafeMutableRawPointer) -> Void { +public func _invoke_swift_closure_BridgeJSRuntimeTests_20BridgeJSRuntimeTestssSaSd_y(_ boxPtr: UnsafeMutableRawPointer, _ param0SourceId: Int32, _ param0Count: Int32) -> Void { #if arch(wasm32) let closure = Unmanaged<_BridgeJSTypedClosureBox<(sending [Double]) -> Void>>.fromOpaque(boxPtr).takeUnretainedValue().closure - closure([Double].bridgeJSLiftParameter()) + closure([Double].bridgeJSTypedArrayLiftParameter(param0SourceId, param0Count)) #else fatalError("Only available on WebAssembly") #endif @@ -3334,10 +3334,10 @@ fileprivate func bjs_DataProcessor_optionalHelper_set_extern(_ jsObject: Int32, @_expose(wasm, "bjs_ArraySupportExports_static_roundTripIntArray") @_cdecl("bjs_ArraySupportExports_static_roundTripIntArray") -public func _bjs_ArraySupportExports_static_roundTripIntArray() -> Void { +public func _bjs_ArraySupportExports_static_roundTripIntArray(_ vSourceId: Int32, _ vCount: Int32) -> Void { #if arch(wasm32) - let ret = ArraySupportExports.roundTripIntArray(_: [Int].bridgeJSStackPop()) - ret.bridgeJSStackPush() + let ret = ArraySupportExports.roundTripIntArray(_: [Int].bridgeJSTypedArrayLiftParameter(vSourceId, vCount)) + ret.bridgeJSTypedArrayPush() #else fatalError("Only available on WebAssembly") #endif @@ -3356,10 +3356,10 @@ public func _bjs_ArraySupportExports_static_roundTripStringArray() -> Void { @_expose(wasm, "bjs_ArraySupportExports_static_roundTripDoubleArray") @_cdecl("bjs_ArraySupportExports_static_roundTripDoubleArray") -public func _bjs_ArraySupportExports_static_roundTripDoubleArray() -> Void { +public func _bjs_ArraySupportExports_static_roundTripDoubleArray(_ vSourceId: Int32, _ vCount: Int32) -> Void { #if arch(wasm32) - let ret = ArraySupportExports.roundTripDoubleArray(_: [Double].bridgeJSStackPop()) - ret.bridgeJSStackPush() + let ret = ArraySupportExports.roundTripDoubleArray(_: [Double].bridgeJSTypedArrayLiftParameter(vSourceId, vCount)) + ret.bridgeJSTypedArrayPush() #else fatalError("Only available on WebAssembly") #endif @@ -3766,12 +3766,12 @@ public func _bjs_ArraySupportExports_static_roundTripNestedSwiftClassArray() -> @_expose(wasm, "bjs_ArraySupportExports_static_multiArrayFirst") @_cdecl("bjs_ArraySupportExports_static_multiArrayFirst") -public func _bjs_ArraySupportExports_static_multiArrayFirst() -> Void { +public func _bjs_ArraySupportExports_static_multiArrayFirst(_ aSourceId: Int32, _ aCount: Int32) -> Void { #if arch(wasm32) let _tmp_b = [String].bridgeJSStackPop() - let _tmp_a = [Int].bridgeJSStackPop() + let _tmp_a = [Int].bridgeJSTypedArrayLiftParameter(aSourceId, aCount) let ret = ArraySupportExports.multiArrayFirst(_: _tmp_a, _: _tmp_b) - ret.bridgeJSStackPush() + ret.bridgeJSTypedArrayPush() #else fatalError("Only available on WebAssembly") #endif @@ -3779,10 +3779,10 @@ public func _bjs_ArraySupportExports_static_multiArrayFirst() -> Void { @_expose(wasm, "bjs_ArraySupportExports_static_multiArraySecond") @_cdecl("bjs_ArraySupportExports_static_multiArraySecond") -public func _bjs_ArraySupportExports_static_multiArraySecond() -> Void { +public func _bjs_ArraySupportExports_static_multiArraySecond(_ aSourceId: Int32, _ aCount: Int32) -> Void { #if arch(wasm32) let _tmp_b = [String].bridgeJSStackPop() - let _tmp_a = [Int].bridgeJSStackPop() + let _tmp_a = [Int].bridgeJSTypedArrayLiftParameter(aSourceId, aCount) let ret = ArraySupportExports.multiArraySecond(_: _tmp_a, _: _tmp_b) ret.bridgeJSStackPush() #else @@ -3950,9 +3950,9 @@ public func _bjs_DefaultArgumentExports_static_describeConstructorDefaults(_ val @_expose(wasm, "bjs_DefaultArgumentExports_static_arrayWithDefault") @_cdecl("bjs_DefaultArgumentExports_static_arrayWithDefault") -public func _bjs_DefaultArgumentExports_static_arrayWithDefault() -> Int32 { +public func _bjs_DefaultArgumentExports_static_arrayWithDefault(_ valuesSourceId: Int32, _ valuesCount: Int32) -> Int32 { #if arch(wasm32) - let ret = DefaultArgumentExports.arrayWithDefault(_: [Int].bridgeJSStackPop()) + let ret = DefaultArgumentExports.arrayWithDefault(_: [Int].bridgeJSTypedArrayLiftParameter(valuesSourceId, valuesCount)) return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -3972,9 +3972,9 @@ public func _bjs_DefaultArgumentExports_static_arrayWithOptionalDefault() -> Int @_expose(wasm, "bjs_DefaultArgumentExports_static_arrayMixedDefaults") @_cdecl("bjs_DefaultArgumentExports_static_arrayMixedDefaults") -public func _bjs_DefaultArgumentExports_static_arrayMixedDefaults(_ prefixBytes: Int32, _ prefixLength: Int32, _ suffixBytes: Int32, _ suffixLength: Int32) -> Void { +public func _bjs_DefaultArgumentExports_static_arrayMixedDefaults(_ prefixBytes: Int32, _ prefixLength: Int32, _ valuesSourceId: Int32, _ valuesCount: Int32, _ suffixBytes: Int32, _ suffixLength: Int32) -> Void { #if arch(wasm32) - let ret = DefaultArgumentExports.arrayMixedDefaults(prefix: String.bridgeJSLiftParameter(prefixBytes, prefixLength), values: [Int].bridgeJSStackPop(), suffix: String.bridgeJSLiftParameter(suffixBytes, suffixLength)) + let ret = DefaultArgumentExports.arrayMixedDefaults(prefix: String.bridgeJSLiftParameter(prefixBytes, prefixLength), values: [Int].bridgeJSTypedArrayLiftParameter(valuesSourceId, valuesCount), suffix: String.bridgeJSLiftParameter(suffixBytes, suffixLength)) return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -6547,9 +6547,9 @@ fileprivate func _bjs_struct_lift_ArrayMembers_extern() -> Int32 { @_expose(wasm, "bjs_ArrayMembers_sumValues") @_cdecl("bjs_ArrayMembers_sumValues") -public func _bjs_ArrayMembers_sumValues() -> Int32 { +public func _bjs_ArrayMembers_sumValues(_ valuesSourceId: Int32, _ valuesCount: Int32) -> Int32 { #if arch(wasm32) - let ret = ArrayMembers.bridgeJSLiftParameter().sumValues(_: [Int].bridgeJSStackPop()) + let ret = ArrayMembers.bridgeJSLiftParameter().sumValues(_: [Int].bridgeJSTypedArrayLiftParameter(valuesSourceId, valuesCount)) return ret.bridgeJSLowerReturn() #else fatalError("Only available on WebAssembly") @@ -7974,9 +7974,9 @@ public func _bjs_roundTripArrayMembers() -> Void { @_expose(wasm, "bjs_arrayMembersSum") @_cdecl("bjs_arrayMembersSum") -public func _bjs_arrayMembersSum() -> Int32 { +public func _bjs_arrayMembersSum(_ valuesSourceId: Int32, _ valuesCount: Int32) -> Int32 { #if arch(wasm32) - let _tmp_values = [Int].bridgeJSStackPop() + let _tmp_values = [Int].bridgeJSTypedArrayLiftParameter(valuesSourceId, valuesCount) let _tmp_value = ArrayMembers.bridgeJSLiftParameter() let ret = arrayMembersSum(_: _tmp_value, _: _tmp_values) return ret.bridgeJSLowerReturn() @@ -11188,7 +11188,7 @@ fileprivate func bjs_ArraySupportImports_runJsArraySupportTests_static_extern() } func _$ArraySupportImports_jsIntArrayLength(_ items: [Int]) throws(JSException) -> Int { - let _ = items.bridgeJSLowerParameter() + items.bridgeJSTypedArrayPush() let ret = bjs_ArraySupportImports_jsIntArrayLength_static() if let error = _swift_js_take_exception() { throw error @@ -11197,21 +11197,25 @@ func _$ArraySupportImports_jsIntArrayLength(_ items: [Int]) throws(JSException) } func _$ArraySupportImports_jsRoundTripIntArray(_ items: [Int]) throws(JSException) -> [Int] { - let _ = items.bridgeJSLowerParameter() + items.bridgeJSTypedArrayPush() bjs_ArraySupportImports_jsRoundTripIntArray_static() if let error = _swift_js_take_exception() { throw error } - return [Int].bridgeJSLiftReturn() + let _count = _swift_js_pop_i32() + let _sourceId = _swift_js_pop_i32() + return [Int].bridgeJSTypedArrayLiftParameter(_sourceId, _count) } func _$ArraySupportImports_jsRoundTripNumberArray(_ values: [Double]) throws(JSException) -> [Double] { - let _ = values.bridgeJSLowerParameter() + values.bridgeJSTypedArrayPush() bjs_ArraySupportImports_jsRoundTripNumberArray_static() if let error = _swift_js_take_exception() { throw error } - return [Double].bridgeJSLiftReturn() + let _count = _swift_js_pop_i32() + let _sourceId = _swift_js_pop_i32() + return [Double].bridgeJSTypedArrayLiftParameter(_sourceId, _count) } func _$ArraySupportImports_jsRoundTripStringArray(_ values: [String]) throws(JSException) -> [String] { @@ -11314,7 +11318,7 @@ func _$ArraySupportImports_jsRoundTripOptionalJSClassArray(_ values: [Optional Double { - let _ = values.bridgeJSLowerParameter() + values.bridgeJSTypedArrayPush() let ret = bjs_ArraySupportImports_jsSumNumberArray_static() if let error = _swift_js_take_exception() { throw error @@ -11327,7 +11331,9 @@ func _$ArraySupportImports_jsCreateNumberArray() throws(JSException) -> [Double] if let error = _swift_js_take_exception() { throw error } - return [Double].bridgeJSLiftReturn() + let _count = _swift_js_pop_i32() + let _sourceId = _swift_js_pop_i32() + return [Double].bridgeJSTypedArrayLiftParameter(_sourceId, _count) } func _$ArraySupportImports_runJsArraySupportTests() throws(JSException) -> Void { @@ -11547,7 +11553,7 @@ func _$AsyncImportImports_jsAsyncRoundTripIntArray(_ values: [Double]) async thr }, makeRejectClosure: { JSTypedClosure<(sending JSValue) -> Void>($0) }) { resolveRef, rejectRef in - let _ = values.bridgeJSLowerParameter() + values.bridgeJSTypedArrayPush() bjs_AsyncImportImports_jsAsyncRoundTripIntArray_static(resolveRef, rejectRef) } return resolved @@ -13444,7 +13450,7 @@ fileprivate func bjs_JSClassWithArrayMembers_firstLabel_extern(_ self: Int32) -> func _$JSClassWithArrayMembers_init(_ numbers: [Int], _ labels: [String]) throws(JSException) -> JSObject { let _ = labels.bridgeJSLowerParameter() - let _ = numbers.bridgeJSLowerParameter() + numbers.bridgeJSTypedArrayPush() let ret = bjs_JSClassWithArrayMembers_init() if let error = _swift_js_take_exception() { throw error @@ -13458,7 +13464,9 @@ func _$JSClassWithArrayMembers_numbers_get(_ self: JSObject) throws(JSException) if let error = _swift_js_take_exception() { throw error } - return [Int].bridgeJSLiftReturn() + let _count = _swift_js_pop_i32() + let _sourceId = _swift_js_pop_i32() + return [Int].bridgeJSTypedArrayLiftParameter(_sourceId, _count) } func _$JSClassWithArrayMembers_labels_get(_ self: JSObject) throws(JSException) -> [String] { @@ -13472,7 +13480,7 @@ func _$JSClassWithArrayMembers_labels_get(_ self: JSObject) throws(JSException) func _$JSClassWithArrayMembers_numbers_set(_ self: JSObject, _ newValue: [Int]) throws(JSException) -> Void { let selfValue = self.bridgeJSLowerParameter() - let _ = newValue.bridgeJSLowerParameter() + newValue.bridgeJSTypedArrayPush() bjs_JSClassWithArrayMembers_numbers_set(selfValue) if let error = _swift_js_take_exception() { throw error @@ -13490,12 +13498,14 @@ func _$JSClassWithArrayMembers_labels_set(_ self: JSObject, _ newValue: [String] func _$JSClassWithArrayMembers_concatNumbers(_ self: JSObject, _ values: [Int]) throws(JSException) -> [Int] { let selfValue = self.bridgeJSLowerParameter() - let _ = values.bridgeJSLowerParameter() + values.bridgeJSTypedArrayPush() bjs_JSClassWithArrayMembers_concatNumbers(selfValue) if let error = _swift_js_take_exception() { throw error } - return [Int].bridgeJSLiftReturn() + let _count = _swift_js_pop_i32() + let _sourceId = _swift_js_pop_i32() + return [Int].bridgeJSTypedArrayLiftParameter(_sourceId, _count) } func _$JSClassWithArrayMembers_concatLabels(_ self: JSObject, _ values: [String]) throws(JSException) -> [String] { @@ -13532,7 +13542,7 @@ fileprivate func bjs_JSClassSupportImports_makeJSClassWithArrayMembers_static_ex func _$JSClassSupportImports_makeJSClassWithArrayMembers(_ numbers: [Int], _ labels: [String]) throws(JSException) -> JSClassWithArrayMembers { let _ = labels.bridgeJSLowerParameter() - let _ = numbers.bridgeJSLowerParameter() + numbers.bridgeJSTypedArrayPush() let ret = bjs_JSClassSupportImports_makeJSClassWithArrayMembers_static() if let error = _swift_js_take_exception() { throw error