@@ -34,6 +34,8 @@ final class JSGlueVariableScope {
3434 static let reservedStructHelpers = " structHelpers "
3535 static let reservedSwiftClosureRegistry = " swiftClosureRegistry "
3636 static let reservedMakeSwiftClosure = " makeClosure "
37+ static let reservedTaStack = " taStack "
38+ static let reservedTypedArrayConstructors = " typedArrayConstructors "
3739
3840 private let intrinsicRegistry : JSIntrinsicRegistry
3941
@@ -63,6 +65,8 @@ final class JSGlueVariableScope {
6365 reservedStructHelpers ,
6466 reservedSwiftClosureRegistry ,
6567 reservedMakeSwiftClosure ,
68+ reservedTaStack ,
69+ reservedTypedArrayConstructors ,
6670 ]
6771
6872 init ( intrinsicRegistry : JSIntrinsicRegistry ) {
@@ -1317,6 +1321,8 @@ struct IntrinsicJSFragment: Sendable {
13171321 )
13181322 case . namespaceEnum ( let string ) :
13191323 throw BridgeJSLinkError ( message : " Namespace enums are not supported to be passed as parameters: \( string ) " )
1324+ case . array ( let elementType ) where elementType . isNumericScalar :
1325+ return numericArrayLower ( elementType : elementType )
13201326 case . array ( let elementType ) :
13211327 return try arrayLower ( elementType : elementType )
13221328 case . dictionary ( let valueType ) :
@@ -1374,6 +1380,8 @@ struct IntrinsicJSFragment: Sendable {
13741380 throw BridgeJSLinkError (
13751381 message : " Namespace enums are not supported to be returned from functions: \( string ) "
13761382 )
1383+ case . array ( let elementType ) where elementType . isNumericScalar :
1384+ return numericArrayLift ( elementType : elementType )
13771385 case . array ( let elementType ) :
13781386 return try arrayLift ( elementType : elementType )
13791387 case . dictionary ( let valueType ) :
@@ -1472,6 +1480,8 @@ struct IntrinsicJSFragment: Sendable {
14721480 message :
14731481 " Namespace enums are not supported to be passed as parameters to imported JS functions: \( string ) "
14741482 )
1483+ case . array ( let elementType ) where elementType . isNumericScalar :
1484+ return numericArrayLift ( elementType : elementType )
14751485 case . array ( let elementType ) :
14761486 return try arrayLift ( elementType : elementType )
14771487 case . dictionary ( let valueType ) :
@@ -1534,6 +1544,8 @@ struct IntrinsicJSFragment: Sendable {
15341544 throw BridgeJSLinkError (
15351545 message : " Namespace enums are not supported to be returned from imported JS functions: \( string ) "
15361546 )
1547+ case . array ( let elementType ) where elementType . isNumericScalar :
1548+ return numericArrayLowerReturn ( elementType : elementType )
15371549 case . array ( let elementType ) :
15381550 return try arrayLower ( elementType : elementType )
15391551 case . dictionary ( let valueType ) :
@@ -1828,6 +1840,72 @@ struct IntrinsicJSFragment: Sendable {
18281840
18291841 // MARK: - Array Helpers
18301842
1843+ /// Lowers a numeric array from JS to Swift via bulk TypedArray transfer.
1844+ /// Converts the JS Array to a TypedArray, retains it, and passes (sourceId, count) as WASM params.
1845+ static func numericArrayLower ( elementType : BridgeType ) -> IntrinsicJSFragment {
1846+ let kind = elementType . typedArrayKind !
1847+ return IntrinsicJSFragment (
1848+ parameters : [ " arr " ] ,
1849+ printCode : { arguments , context in
1850+ let ( scope , printer ) = ( context . scope , context . printer )
1851+ let arr = arguments [ 0 ]
1852+ let typedArrVar = scope . variable ( " typedArr " )
1853+ let idVar = scope . variable ( " typedArrId " )
1854+ printer . write (
1855+ " const \( typedArrVar ) = new \( JSGlueVariableScope . reservedTypedArrayConstructors ) [ \( kind ) ]( \( arr ) ); "
1856+ )
1857+ printer . write (
1858+ " const \( idVar ) = \( JSGlueVariableScope . reservedSwift ) .memory.retain( \( typedArrVar ) ); "
1859+ )
1860+ return [ idVar , " \( typedArrVar ) .length " ]
1861+ }
1862+ )
1863+ }
1864+
1865+ /// Lowers a numeric array from JS to Swift for return values (stack-based).
1866+ /// Pushes (sourceId, count) onto the i32 stack.
1867+ static func numericArrayLowerReturn ( elementType : BridgeType ) -> IntrinsicJSFragment {
1868+ let kind = elementType . typedArrayKind !
1869+ return IntrinsicJSFragment (
1870+ parameters : [ " arr " ] ,
1871+ printCode : { arguments , context in
1872+ let ( scope , printer ) = ( context . scope , context . printer )
1873+ let arr = arguments [ 0 ]
1874+ let typedArrVar = scope . variable ( " typedArr " )
1875+ let idVar = scope . variable ( " typedArrId " )
1876+ printer . write (
1877+ " const \( typedArrVar ) = new \( JSGlueVariableScope . reservedTypedArrayConstructors ) [ \( kind ) ]( \( arr ) ); "
1878+ )
1879+ printer . write (
1880+ " const \( idVar ) = \( JSGlueVariableScope . reservedSwift ) .memory.retain( \( typedArrVar ) ); "
1881+ )
1882+ scope . emitPushI32Parameter ( idVar , printer : printer )
1883+ scope . emitPushI32Parameter ( " \( typedArrVar ) .length " , printer : printer )
1884+ return [ ]
1885+ }
1886+ )
1887+ }
1888+
1889+ /// Lifts a numeric array from Swift to JS via bulk TypedArray transfer.
1890+ /// Swift side pushed the typed array view onto taStack; JS pops and converts to plain Array.
1891+ static func numericArrayLift ( elementType : BridgeType ) -> IntrinsicJSFragment {
1892+ return IntrinsicJSFragment (
1893+ parameters : [ ] ,
1894+ printCode : { arguments , context in
1895+ let ( scope , printer ) = ( context . scope , context . printer )
1896+ let srcVar = scope . variable ( " taSrc " )
1897+ let resultVar = scope . variable ( " arrayResult " )
1898+ let iVar = scope . variable ( " i " )
1899+ printer . write ( " const \( srcVar ) = \( JSGlueVariableScope . reservedTaStack ) .pop(); " )
1900+ printer . write ( " const \( resultVar ) = new Array( \( srcVar ) .length); " )
1901+ printer . write (
1902+ " for (let \( iVar ) = 0; \( iVar ) < \( srcVar ) .length; \( iVar ) ++) \( resultVar ) [ \( iVar ) ] = \( srcVar ) [ \( iVar ) ]; "
1903+ )
1904+ return [ resultVar ]
1905+ }
1906+ )
1907+ }
1908+
18311909 /// Lowers an array from JS to Swift by iterating elements and pushing to stacks
18321910 static func arrayLower ( elementType : BridgeType ) throws -> IntrinsicJSFragment {
18331911 return IntrinsicJSFragment (
0 commit comments