ES6+ Features: Typed Arrays
Relevant source files
The following files were used as context for generating this wiki page:
The Jurassic engine provides a comprehensive implementation of the ECMAScript 6 Typed Arrays specification, which is a framework for accessing and manipulating raw binary data. This feature is crucial for performance-sensitive applications, web standards that rely on binary data (like WebGL, Web Audio API), and interoperability with native .NET libraries. The implementation is nearly complete, passing 45 out of 46 compatibility tests.
The architecture is composed of three main components:
ArrayBuffer: An object representing a chunk of raw binary data.- Typed Array Views: Objects that provide a typed context for interpreting the data in an
ArrayBuffer. Examples includeInt8ArrayandFloat32Array. DataView: An object that provides a low-level, untyped interface for reading and writing data of various types at any byte offset within anArrayBuffer, with explicit control over endianness.
Sources: README.md, Jurassic/Library/TypedArray/ArrayBufferInstance.cs, Jurassic/Library/TypedArray/TypedArrayInstance.cs, Jurassic/Library/TypedArray/DataViewInstance.cs
Architecture and Class Hierarchy
At the core of the implementation is the separation of the raw data buffer (ArrayBufferInstance) from the views that interpret that data (TypedArrayInstance and DataViewInstance). All these components inherit from ObjectInstance, the base class for all JavaScript objects in the Jurassic engine.
The following diagram illustrates the inheritance and composition relationships between the key classes involved in the Typed Arrays feature.
Diagram showing the class relationships for Typed Arrays.
Sources: Jurassic/Library/TypedArray/ArrayBufferInstance.cs, Jurassic/Library/TypedArray/TypedArrayInstance.cs, Jurassic/Library/TypedArray/DataViewInstance.cs
ArrayBuffer
The ArrayBufferInstance class represents a fixed-length raw binary data buffer. It is a container for a sequence of bytes and cannot be read from or written to directly from JavaScript. Instead, one of the view objects must be used.
Constructor
new ArrayBuffer(length): Creates a newArrayBufferof the given length in bytes. The contents are initialized to zero.
Properties and Methods
| Member | Description | Source File |
|---|---|---|
ByteLength (property) | Returns the size, in bytes, of the array. This is established when the array is constructed and cannot be changed. | ArrayBufferInstance.cs:33-36 |
Slice(begin, end) (method) | Returns a new ArrayBuffer whose contents are a copy of this ArrayBuffer's bytes from begin (inclusive) to end (exclusive). | ArrayBufferInstance.cs:60-84 |
The internal data is stored in a byte[] array within the ArrayBufferInstance.
Sources: Jurassic/Library/TypedArray/ArrayBufferInstance.cs
Typed Array Views
Typed Array views provide an array-like interface for accessing the data in an ArrayBuffer. Each view has a specific element type, size, and endianness (native to the platform).
Supported Typed Array Types
The TypedArrayType enum defines the various types of arrays that can be created.
| Type | TypedArrayType Enum | Element Size (Bytes) | .NET Type | Description |
|---|---|---|---|---|
Int8Array | Int8 | 1 | sbyte | 8-bit two's complement signed integer. |
Uint8Array | Uint8 | 1 | byte | 8-bit unsigned integer. |
Uint8ClampedArray | Uint8Clamped | 1 | byte | 8-bit unsigned integer (clamped). |
Int16Array | Int16 | 2 | short | 16-bit two's complement signed integer. |
Uint16Array | Uint16 | 2 | ushort | 16-bit unsigned integer. |
Int32Array | Int32 | 4 | int | 32-bit two's complement signed integer. |
Uint32Array | Uint32 | 4 | uint | 32-bit unsigned integer. |
Float32Array | Float32 | 4 | float | 32-bit IEEE floating point number. |
Float64Array | Float64 | 8 | double | 64-bit IEEE floating point number. |
Sources: Jurassic/Library/TypedArray/TypedArrayInstance.cs:23-35, Test Suite Runner/Kangax/compat-table.json
Constructors
A TypedArray can be constructed in several ways, determined by the arguments passed to the constructor. The logic is handled by TypedArrayConstructor.cs.
This flowchart shows the different construction paths for a new Typed Array instance.
Sources: Jurassic/Library/TypedArray/TypedArrayConstructor.cs:33-159
Key Properties
All TypedArray instances share a common set of properties defined in the base class TypedArrayInstance.
| Property | Description | Source File |
|---|---|---|
Buffer | The ArrayBuffer referenced by the typed array. | TypedArrayInstance.cs:113-116 |
ByteOffset | The offset (in bytes) from the start of the referenced ArrayBuffer. | TypedArrayInstance.cs:122-125 |
ByteLength | The length (in bytes) of the typed array. | TypedArrayInstance.cs:131-134 |
Length | The number of elements in the typed array. | TypedArrayInstance.cs:140-143 |
Key Methods
| Method | Description | Source File |
|---|---|---|
Set(source, [offset]) | Copies values from a source array or TypedArray into the current array, starting at the given offset. | TypedArrayInstance.cs:202-282 |
SubArray(begin, [end]) | Returns a new TypedArray of the same type that shares the same ArrayBuffer but represents a subset of the elements. | TypedArrayInstance.cs:290-323 |
Slice(begin, [end]) | Returns a new TypedArray containing a copy of the elements from begin to end. | TypedArrayInstance.cs:331-356 |
Other standard array methods like map, filter, reduce, forEach, find, sort, etc., are also implemented.
Sources: Jurassic/Library/TypedArray/TypedArrayInstance.cs, Test Suite Runner/Kangax/compat-table.json
DataView
The DataViewInstance provides a low-level interface for reading and writing multiple number types in an ArrayBuffer without being constrained to a single element type. It allows for explicit control over the byte order (endianness).
Constructor
new DataView(buffer, [byteOffset], [byteLength]): Creates a newDataViewobject that represents a view over the givenArrayBuffer.
Sources: Jurassic/Library/TypedArray/DataViewInstance.cs:40-70
Accessor Methods
DataView provides a suite of get and set methods for different numeric types. Each method takes a byteOffset as the first argument. set methods take the value to write as the second argument. Multi-byte methods also accept an optional littleEndian boolean argument (defaults to false, i.e., big-endian).
| Getter | Setter | Element Type |
|---|---|---|
getInt8() | setInt8() | 8-bit signed integer |
getUint8() | setUint8() | 8-bit unsigned integer |
getInt16() | setInt16() | 16-bit signed integer |
getUint16() | setUint16() | 16-bit unsigned integer |
getInt32() | setInt32() | 32-bit signed integer |
getUint32() | setUint32() | 32-bit unsigned integer |
getFloat32() | setFloat32() | 32-bit float |
getFloat64() | setFloat64() | 64-bit float |
Sources: Jurassic/Library/TypedArray/DataViewInstance.cs:113-281
Testing
The correctness of the Typed Arrays implementation is verified through a combination of C# unit tests and a large suite of JavaScript-based compatibility tests.
Unit Tests
The TypedArrayTests.cs file contains NUnit tests that directly validate the behavior of the .NET classes. These tests cover constructor logic, property access, and method functionality.
// Example from Unit Tests/Library/TypedArrayTests.cs
[Test]
public void Constructor()
{
// new Int8Array(length)
Assert.AreEqual(5, Evaluate("new Int8Array(5).length"));
Assert.AreEqual(0, Evaluate("new Int8Array(5)[0]"));
Assert.AreEqual(0, Evaluate("new Int8Array(5)[4]"));
// new Int8Array(typedArray)
Assert.AreEqual("[5,6,7,8]", Evaluate("new Int8Array(new Int8Array([5, 6, 7, 8])).toString()"));
Assert.AreEqual("[-128,127]", Evaluate("new Int8Array(new Int8Array([-128, 127])).toString()"));
// ... more tests
}
This snippet shows how constructors are tested for Int8Array.
Sources: Unit Tests/Library/TypedArrayTests.cs:23-57
Compatibility Tests
The compat-table.json file contains a comprehensive set of tests from the Kangax compatibility table. These are executed by the test runner to ensure adherence to the ECMAScript specification.
{
"name": "typed arrays",
"group": "Built-ins",
"detail": "Int8Array",
"script": "\nvar buffer = new ArrayBuffer(64);\nvar view = new Int8Array(buffer); view[0] = 0x80;\nreturn view[0] === -0x80;\n "
},
{
"name": "typed arrays",
"group": "Built-ins",
"detail": "DataView (Int16)",
"script": "\nvar buffer = new ArrayBuffer(64);\nvar view = new DataView(buffer);\nview.setInt16(0, 0x8000);\nreturn view.getInt16(0) === -0x8000;\n "
}
This JSON snippet shows two of the many JavaScript tests used to verify Typed Array and DataView behavior.
Sources: Test Suite Runner/Kangax/compat-table.json
Summary
The Jurassic engine's implementation of ES6 Typed Arrays is robust and standards-compliant. It provides the necessary tools (ArrayBuffer, TypedArray views, and DataView) for high-performance manipulation of binary data within the .NET environment. The clear separation between data buffers and views, along with a comprehensive set of accessor methods and properties, makes it a powerful feature for developers building applications that require low-level data access.