@@ -65,7 +65,49 @@ public JSTypedArray(int length)
6565 /// </summary>
6666 public unsafe JSTypedArray ( Memory < T > data )
6767 {
68- // Check if this Memory is already owned by a JS TypedArray value.
68+ JSValue ? value = GetJSValueForMemory ( data ) ;
69+ if ( value is not null )
70+ {
71+ _value = value . Value ;
72+ }
73+ else
74+ {
75+ // The Memory was NOT created from a JS TypedArray. Most likely it was allocated
76+ // directly or via a .NET array or string.
77+
78+ JSValue arrayBuffer = data . Length > 0 ?
79+ JSValue . CreateExternalArrayBuffer ( data ) : JSValue . CreateArrayBuffer ( 0 ) ;
80+ _value = JSValue . CreateTypedArray ( ArrayType , data . Length , arrayBuffer , 0 ) ;
81+ }
82+ }
83+
84+ /// <summary>
85+ /// Creates a typed-array over read-memory, without copying. Only valid for memory
86+ /// which was previously marshalled from a JS typed-array to .NET.
87+ /// </summary>
88+ /// <exception cref="NotSupportedException">The memory is external to JS.</exception>
89+ public unsafe JSTypedArray ( ReadOnlyMemory < T > data )
90+ {
91+ JSValue ? value = GetJSValueForMemory ( data ) ;
92+ if ( value is not null )
93+ {
94+ _value = value . Value ;
95+ }
96+ else
97+ {
98+ // Consider copying the memory?
99+ throw new NotSupportedException (
100+ "Read-only memory cannot be transferred from .NET to JS." ) ;
101+ }
102+ }
103+
104+ /// <summary>
105+ /// Checks if this Memory is already owned by a JS TypedArray value, and if so
106+ /// returns that JS value.
107+ /// </summary>
108+ /// <returns>The JS value, or null if the memory is external to JS.</returns>
109+ private static unsafe JSValue ? GetJSValueForMemory ( ReadOnlyMemory < T > data )
110+ {
69111 // This assumes the owner object of a Memory struct is stored as a reference in the
70112 // first (private) field of the struct. If the Memory internal structure ever changes
71113 // (in a future major version of the .NET Runtime), this unsafe code could crash.
@@ -83,24 +125,19 @@ public unsafe JSTypedArray(Memory<T> data)
83125 void * memoryLengthPointer = ( byte * ) memoryIndexPointer + Unsafe . SizeOf < int > ( ) ;
84126 int length = Unsafe . Read < int > ( memoryLengthPointer ) ;
85127
86- _value = manager . JSValue ;
87- int valueLength = _value . GetTypedArrayLength ( out _ ) ;
128+ JSValue value = manager . JSValue ;
129+ int valueLength = value . GetTypedArrayLength ( out _ ) ;
88130
89131 if ( index != 0 || length != valueLength )
90132 {
91133 // The Memory was sliced, so get an equivalent slice of the JS TypedArray.
92- _value = _value . CallMethod ( "slice" , index , index + length ) ;
134+ value = value . CallMethod ( "slice" , index , index + length ) ;
93135 }
94- }
95- else
96- {
97- // The Memory was NOT created from a JS TypedArray. Most likely it was allocated
98- // directly or via a .NET array or string.
99136
100- JSValue arrayBuffer = data . Length > 0 ?
101- JSValue . CreateExternalArrayBuffer ( data ) : JSValue . CreateArrayBuffer ( 0 ) ;
102- _value = JSValue . CreateTypedArray ( ArrayType , data . Length , arrayBuffer , 0 ) ;
137+ return value ;
103138 }
139+
140+ return null ;
104141 }
105142
106143 /// <summary>
0 commit comments