SIMD.js specification

Table of Contents

  1. Introduction
  2. 1 ECMAScript Data Types and Values (6)
    1. 1.1 ECMAScript language types (6.1)
      1. 1.1.1 Well-Known Intrinsic Objects (6.1.7.4)
    2. 1.2 SIMD types
      1. 1.2.1 Float32x4
      2. 1.2.2 Float64x2
      3. 1.2.3 Int32x4
      4. 1.2.4 Int16x8
      5. 1.2.5 Int8x16
  3. 2 Abstract Operations (7)
    1. 2.1 Type Conversion (7.1)
      1. 2.1.1 ToPrimitive ( input [, PreferredType] ) (7.1.1)
      2. 2.1.2 ToBoolean ( argument ) (7.1.2)
      3. 2.1.3 ToNumber ( argument ) (7.1.3)
      4. 2.1.4 ToString ( argument ) (7.1.12)
      5. 2.1.5 ToObject ( argument ) (7.1.13)
    2. 2.2 RequireObjectCoercible ( argument ) (7.2.1)
    3. 2.3 SameValue(x, y) (7.2.9)
    4. 2.4 SameValueZero(x, y) (7.2.10)
    5. 2.5 Abstract relational comparison (7.2.11)
    6. 2.6 Abstract Equality Comparison (7.2.12)
    7. 2.7 Strict Equality Comparison (7.2.13)
  4. 3 The typeof Operator (12.5.6)
    1. 3.1 Runtime Semantics: Evaluation (12.5.6.1)
  5. 4 DataView objects (24.2)
    1. 4.1 Properties of the DataView Prototype Object (24.2.4)
      1. 4.1.1 DataView.prototype.get_SIMD_ ( byteOffset [ , littleEndian ] )
      2. 4.1.2 DataView.prototype.set_SIMD_ ( byteOffset, value [ , littleEndian ] )
  6. 5 SIMD objects
    1. 5.1 Internal algorithms on SIMD types
      1. 5.1.1 SIMDCreate( descriptor, fields...)
      2. 5.1.2 SIMDExtractLane( value, field )
      3. 5.1.3 SIMDReplaceLane( value, field, replacement )
      4. 5.1.4 SIMDBinaryOp( a, b, op )
      5. 5.1.5 SIMDUnaryOp( a, op )
      6. 5.1.6 SIMDLoad( dataBlock, descriptor, byteOffset [, length] )
      7. 5.1.7 SIMDStore( dataBlock, descriptor, byteOffset, n [, length] )
      8. 5.1.8 SIMDReinterpretCast( value, newDescriptor )
    2. 5.2 _SIMD_Constructor
      1. 5.2.1 _SIMD_Constructor( value )
      2. 5.2.2 _SIMD_Constructor( fields... )
      3. 5.2.3 _SIMD_Constructor.check(a)
      4. 5.2.4 _SIMD_Constructor.splat(n)
      5. 5.2.5 _SIMD_Constructor.add(a, b)
      6. 5.2.6 _SIMD_Constructor.sub(a, b)
      7. 5.2.7 _SIMD_Constructor.mul(a, b)
      8. 5.2.8 _SIMD_Constructor.div(a, b)
      9. 5.2.9 _SIMD_Constructor.max(a, b)
      10. 5.2.10 _SIMD_Constructor.min(a, b)
      11. 5.2.11 MaxNum(n, m)
      12. 5.2.12 _SIMD_Constructor.maxNum(a, b)
      13. 5.2.13 MinNum(n, m)
      14. 5.2.14 _SIMD_Constructor.minNum(a, b)
      15. 5.2.15 _SIMD_Constructor.neg(a, b)
      16. 5.2.16 _SIMD_Constructor.sqrt(a)
      17. 5.2.17 ReciprocalApproximation(n)
      18. 5.2.18 _SIMD_Constructor.reciprocalApproximation(a, b)
      19. 5.2.19 ReciprocalApproximation(n)
      20. 5.2.20 _SIMD_Constructor.reciprocalSqrtApproximation(a)
      21. 5.2.21 _SIMD_Constructor.abs(a)
      22. 5.2.22 _SIMD_Constructor.extractLane(simd, field)
      23. 5.2.23 _SIMD_Constructor.replaceLane(simd, field)
      24. 5.2.24 _SIMD_Constructor.store(tarray, index, simd)
      25. 5.2.25 _SIMD_Constructor.store1(tarray, index, simd)
      26. 5.2.26 _SIMD_Constructor.store2(tarray, index, simd)
      27. 5.2.27 _SIMD_Constructor.store3(tarray, index)
      28. 5.2.28 _SIMD_Constructor.load(tarray, index)
      29. 5.2.29 _SIMD_Constructor.load1(tarray, index)
      30. 5.2.30 _SIMD_Constructor.load2(tarray, index)
      31. 5.2.31 _SIMD_Constructor.load3(tarray, index)
      32. 5.2.32 SIMDConstructor.fromTIMDBits( value )
      33. 5.2.33 _SIMD_.swizzle( a, lanes... )
      34. 5.2.34 _SIMD_.shuffle( a, b, lanes... )
    3. 5.3 The _SIMD_Constructor.prototype
      1. 5.3.1 _SIMD_Constructor.prototype.constructor
      2. 5.3.2 _SIMD_Constructor.prototype.valueOf()
      3. 5.3.3 _SIMD_Constructor.prototype.toString()
    4. 5.4 SIMD type descriptors
      1. 5.4.1 Float32x4Descriptor type descriptor
        1. 5.4.1.1 SerializeFloat32( block, offset, n, isLittleEndian )
        2. 5.4.1.2 DeserializeFloat32( block, offset, isLittleEndian )
      2. 5.4.2 Float64x2Descriptor type descriptor
        1. 5.4.2.1 SerializeFloat64( block, offset, n, isLittleEndian )
        2. 5.4.2.2 DeserializeFloat64( block, offset, isLittleEndian )
      3. 5.4.3 Int32x4Descriptor type descriptor
        1. 5.4.3.1 SerializeInt32( block, offset, n, isLittleEndian )
        2. 5.4.3.2 DeserializeInt32( block, offset, isLittleEndian )
      4. 5.4.4 Int16x8Descriptor type descriptor
        1. 5.4.4.1 SerializeInt16( block, offset, n, isLittleEndian )
        2. 5.4.4.2 DeserializeInt16( block, offset, isLittleEndian )
      5. 5.4.5 Int8x16Descriptor type descriptor
        1. 5.4.5.1 SerializeInt8( block, offset, n, isLittleEndian )
        2. 5.4.5.2 DeserializeInt8( block, offset, isLittleEndian )

Introduction

This proposal adds SIMD types and operations to Javascript, focusing on the value semantics. The proposal adds new primitive types Float32x4, etc, together with wrappers and a definition of their behavior in the language. The current proposal does not include all SIMD functions, but it defines almost all types and some core operations on them. More definitions for more functions that operate on them can be found at the SIMD.js reference documentation.

One problem that this spec aims to solve is to define equality for SIMD values. Existing implementations use object identity-based equality. However, maintaining object identity puts a big burden on compilers to maintain this identity through operations, where they would rather be able to duplicate and de-duplicate SIMD values arbitrarily based on algebraic identities. By making SIMD values into primitive types with structural equality, compilers are given more freedom.

Ideally, SIMD values will fit into a larger value types proposal. Such a proposal would be a bit more involved, but good work has already been done in that direction. This document describes SIMD without a larger value type system, but it aims to be consistent with how value types might work, and once someone steps forward to describe value types in more detail, it will be great to simplify this text by just explaining SIMD in terms of value types. On the other hand, this proposal gives a vehicle to work out some of the issues in value types and can be used as a guide for future value type designs.

This document is organized in terms of where changes would be made to the ES6 spec. Although ecmarkup generates numbering at the beginning of headers, these won't correspond to the numbering within the existing ECMA spec, so I've included a matching numbering in parentheses afterwards, referring to the ES6 spec.

In this text, SIMD is used to refer to the various SIMD types: Float32x4, Float64x2, Int32x4, Int16x8, and Int8x16. Similarly to Number, SIMD is used to refer to both the type and the wrapper constructor object. This looks a bit confusing, but it provides the most regularity, as an aim of this specification is to make SIMD types primitives that operate analogously to the existing primitives, rather than a new, exotic sort of thing. To reduce ambiguity, the wrapper constructor is usually referred to as SIMDConstructor, and the type is referred to as SIMDType. SIMD types are associated with a descriptor spec object, called SIMDDescriptor.

Please file any issues here!

Because this document is in spec order, rather than written for direct readability, the logical starting point is actually halfway down.

Related links:

Changelog:

TODO:

1ECMAScript Data Types and Values (6)

1.1ECMAScript language types (6.1)

1.1.1Well-Known Intrinsic Objects (6.1.7.4)

Intrinsic name: %SIMD%
Global name: SIMD
ECMAScript Language Association: The SIMD object (27)

Intrinsic name: %SIMDConstructor%
Global name: SIMD.SIMD (e.g., SIMD.Float32x4)
ECMAScript Language Association: The SIMDConstructor constructor

Intrinsic name: %SIMDPrototype%
Global name: SIMD.SIMD.prototype (e.g., SIMD.Float32x4.prototype)
ECMAScript Language Association: The initial value of the prototype data property of %SIMDConstructor% (27.1.2)

1.2SIMD types

1.2.1Float32x4

Float32x4 is a SIMD type representing four 32-bit floating point values. Float32x4 values can be created using the [[Call]] operation on the SIMD.Float32x4 object. Its behavior as a SIMD type is defined by the Float32x4 SIMD type descriptor.

1.2.2Float64x2

Float64x2 is a SIMD type representing two 64-bit floating point values. Float64x2 values can be created using the [[Call]] operation on the SIMD.Float64x2 object. Its behavior as a SIMD type is defined by the Float64x2 SIMD type descriptor

1.2.3Int32x4

Int32x4 is a SIMD type representing four 32-bit integer values. Int32x4 values can be created using the [[Call]] operation on the SIMD.Int32x4 object. Its behavior as a SIMD type is defined by the Int32x4 SIMD type descriptor

1.2.4Int16x8

Int16x8 is a SIMD type representing eight 16-bit integer values. Int16x8 values can be created using the [[Call]] operation on the SIMD.Int16x8 object. Its behavior as a SIMD type is defined by the Int16x8 SIMD type descriptor

1.2.5Int8x16

Int8x16 is a SIMD type representing sixteen 8-bit integer values. Int8x16 values can be created using the [[Call]] operation on the SIMD.Int8x16 object. Its behavior as a SIMD type is defined by the Int8x16 SIMD type descriptor

2Abstract Operations (7)

2.1Type Conversion (7.1)

2.1.1ToPrimitive ( input [, PreferredType] ) (7.1.1)

Argument type: SIMDType
Result: return input Note An additional option considered is to define this as calling ToObject on it, and then ToPrimitive on the resulting wrapper object. This would have the advantage of allowing toString and valueOf be defined on the wrapper prototype, which seems more realistic to me as a path for value types.

2.1.2ToBoolean ( argument ) (7.1.2)

Argument type: SIMDType
Result: return true Note Even if it would be consistent to return false if it is all zero, there probably isn't much gain from adding more falsy values.

2.1.3ToNumber ( argument ) (7.1.3)

Argument type: SIMDType
Result: throw a TypeError exception

2.1.4ToString ( argument ) (7.1.12)

Argument type: SIMDType
Result: Return typeof argument + "(" + Array.prototype.join.call(an Array containing the contents of argument.[[SIMDElements]]) + ")", for the initial value of Array.prototype.join and Function.prototype.call NoteThe definition is extended similarly for other SIMD types. An alternative would be to call ToObject and let the wrapper handle ToString the way it works for objects. NoteThe behavior here is consistent with existing implementations, producing values like "float32x4(1, 2, 3, 4)". An alternative would be to return homoiconic syntax like "SIMD.Float32x4(1, 2, 3, 4)".

2.1.5ToObject ( argument ) (7.1.13)

Argument type: SIMDType
Result: Return a new %SIMDConstructor% wrapper object whose [[SIMDWrapperData]] internal slot is set to argument.

2.2RequireObjectCoercible ( argument ) (7.2.1)

Argument type: SIMDType
Result: return argument

2.3SameValue(x, y) (7.2.9)

Add an extra step at the bottom of the definition of SameValue for the new case involving the new type:
  1. For each SIMD type SIMDType:
    1. If Type(x) is SIMDType:
      1. Assert Type(y) is SIMDType.
      2. For i from 0 to SIMDDescriptor.[[SIMDLength]] - 1:
        1. If SameValue(SIMDExtractLane(x, i), SIMDExtractLane(y, i)) is false, return false.
      3. return true

2.4SameValueZero(x, y) (7.2.10)

Add an extra step at the bottom of the definition of SameValueZero for the new case involving the new type:
  1. For each SIMD type SIMDType:
    1. If Type(x) is SIMDType:
      1. Assert Type(y) is SIMDType.
      2. For i from 0 to SIMDDescriptor.[[SIMDLength]] - 1:
        1. If SameValueZero(SIMDExtractLane(x, i), SIMDExtractLane(y, i)) is false, return false.
      3. return true

2.5Abstract relational comparison (7.2.11)

NoteNo changes needed for SIMD; it will just compare them as strings with the current defintion.

2.6Abstract Equality Comparison (7.2.12)

Replace step 10 with the following:
  1. If Type(x) is either String, Number, Symbol, or any SIMDType, and Type(y) is Object, then return the result of the comparison x == ToPrimitive(y).

2.7Strict Equality Comparison (7.2.13)

Add a new step 9, before the existing step 9:
  1. For each SIMD type SIMDType:
    1. If Type(x) is SIMDType:
      1. Assert Type(y) is SIMDType.
      2. For i from 0 to SIMDType.[[SIMDLength]] - 1:
        1. If SIMDExtractLane(x, i) === SIMDExtractLane(y, i) is false, return false.
      3. return true

3The typeof Operator (12.5.6)

3.1Runtime Semantics: Evaluation (12.5.6.1)

Type of val: Float32x4
Result: "float32x4"
Type of val: Float64x2
Result: "float64x2"
Type of val: Int32x4
Result: "int32x4"
Type of val: Int16x8
Result: "int16x8"
Type of val: Int8x16
Result: "int8x16" NoteThis follows the pattern for Number ("number"), Boolean ("boolean"), etc.

4DataView objects (24.2)

4.1Properties of the DataView Prototype Object (24.2.4)

For each SIMD type descriptor SIMDDescriptor, called by names like Float32x4Descriptor, define the following properties on DataView.prototype:

4.1.1DataView.prototype.getSIMD ( byteOffset [ , littleEndian ] )

  1. Let v be the this value.
  2. If littleEndian is not present, let littleEndian be false.
  3. Let list be a new List of length SIMDDescriptor.[[SIMDLength]].
  4. Let typeName be the string "_SIMD_" up until the "x" character, e.g., "Float32" for Float32x4.
  5. For i from 0 to SIMDDescriptor.[[SIMDLength]] - 1,
    1. Set list[i] to GetViewValue(v, byteOffset + i * SIMDDescriptor.[[SIMDElementSize]], littleEndian, typeName)
  6. Return SIMDCreate(SIMDDescriptor, ...list).
NoteGetViewValue does the range checking for us. NoteThis algorithm uses the GetValueFromBuffer machinery rather than the [[SIMDDeserialize]] machinery; these have matching definitions, and ideally the spec would be refactored in terms of one of the two.

4.1.2DataView.prototype.setSIMD ( byteOffset, value [ , littleEndian ] )

  1. If Type(value) is not SIMDType, throw a TypeError.
  2. Let v be the this value.
  3. If littleEndian is not present, let littleEndian be false.
  4. Let typeName be the string "_SIMD_" up until the "x" character, e.g., "Float32" for Float32x4.
  5. For i from 0 to SIMDDescriptor.[[SIMDLength]] - 1,
    1. SetViewValue(v, byteOffset + i * SIMDDescriptor.[[SIMDElementSize]], littleEndian, typeName, value.[[SIMDElements]][i])

5SIMD objects

The SIMD global object has several constructor properties, one for each SIMD type.

Each SIMD value is specified as a record with the following internal attributes:

SIMD type descriptors have the following internal slots: NoteRather than constructors having internal slots, this could be specified by a table analogous to Table 49 in the ES6 description for TypedArrays. However, the author finds it easier to express this purely in terms of records. TypedArrays could be specified like this too, and share some infrastructure with SIMD, but in their current form, it seems difficult to generalize them to SIMD directly. NoteSIMDCastNumber converts elements to Numbers; however, for most SIMD types, it will convert them to a restricted range of Number. In a real implementation, the numbers would likely be represented in a more compact form. However, the internal representation is not observable.

5.1Internal algorithms on SIMD types

5.1.1SIMDCreate( descriptor, fields...)

This internal algorithm creates a new value of the type corresponding to the specified wrapper with the following procedure: NoteThe following algorithm uses splat arguments in the spec and indexes them as an array, but there isn't proper machinery in the spec to describe this behavior
  1. If Length(fields) == descriptor.[[SIMDLength]], then throw a TypeError.
  2. Let list be a new List of length descriptor.[[SIMDLength]].
  3. For i from 0 to descriptor.[[SIMDLength]],
    1. Let n be descriptor.[[SIMDCastNumber]](fields[i]).
    2. ReturnIfAbrupt(n).
    3. Set list[i] to n.
  4. Return the record { [[SIMDTypeDescriptor]]: descriptor, [[SIMDElements]]: list }.

5.1.2SIMDExtractLane( value, field )

  1. Assert: Type(value) is a SIMDType.
  2. Return value.[[SIMDElements]][field]
NoteWhile this single definition doesn't explicitly refer to the SIMD type in indexing the list, an implementation may use different representations for the Number elements on different types and generate different code for the accesses.

5.1.3SIMDReplaceLane( value, field, replacement )

  1. Assert: Type(value) is a SIMDType.
  2. Let descriptor be a.[[SIMDTypeDescriptor]].
  3. If Type(field) is not Number, throw a TypeError
  4. If field != ToInt32(field) or field < 0 or field >= descriptor.[[SIMDLength]], throw a RangeError.
  5. Let list be a copy of value.[[SIMDElements]].
  6. Set list[field] to replacement.
  7. Return SIMDCreate(descriptor, ...list).
NoteWhile this single definition doesn't explicitly refer to the SIMD type in indexing the list, an implementation may use different representations for the Number elements on different types and generate different code for the accesses.

5.1.4SIMDBinaryOp( a, b, op )

  1. Assert: a.[[SIMDTypeDescriptor]] is b.[[SIMDTypeDescriptor]]
  2. Let descriptor be a.[[SIMDTypeDescriptor]].
  3. Let list be a new List of length descriptor.[[SIMDLength]].
  4. For i from 0 to descriptor.[[SIMDLength]],
    1. Let ax = SIMDExtractLane(a, i).
    2. Let bx = SIMDExtractLane(b, i).
    3. Let res = op(ax, bx).
    4. ReturnIfAbrupt(res).
    5. Set list[i] to res.
  5. Return SIMDCreate(descriptor, ...list).

5.1.5SIMDUnaryOp( a, op )

  1. Let descriptor be a.[[SIMDTypeDescriptor]].
  2. Let list be a new List of length descriptor.[[SIMDLength]].
  3. ReturnIfAbrupt(block).
  4. For i from 0 to descriptor.[[SIMDLength]],
    1. Let ax = SIMDExtractLane(a, i).
    2. Let res = op(ax).
    3. ReturnIfAbrupt(res).
    4. Set list[i] to res.
  5. Return SIMDCreate(descriptor, ...list).

5.1.6SIMDLoad( dataBlock, descriptor, byteOffset [, length] )

  1. Assert: dataBlock is a Data Block, descriptor is a SIMD type descriptor
  2. If length is not provided, let length be descriptor.[[SIMDLength]]. Otherwise, assert length <= descriptor.[[SIMDLength]].
  3. Assert: byteOffset is an integer greater than or equal to zero, and less than or equal to the size of dataBlock - descriptor.[[SIMDElementSize]] * length.
  4. Let list be a List of length descriptor.[[SIMDLength]], initialized to all 0.
  5. For i from 0 to length - 1,
    1. Set list[i] to descriptor.[[SIMDDeserializeElement]](dataBlock, byteOffset).
  6. Return the record { [[SIMDTypeDescriptor]]: descriptor, [[SIMDElements]]: list }.

5.1.7SIMDStore( dataBlock, descriptor, byteOffset, n [, length] )

  1. Assert: dataBlock is a Data Block, descriptor is a SIMD type descriptor
  2. If length is not provided, let length be descriptor.[[SIMDLength]]. Otherwise, assert length <= descriptor.[[SIMDLength]].
  3. Assert: byteOffset is an integer greater than or equal to zero, and less than or equal to the size of dataBlock - descriptor.[[SIMDElementSize]] * length.
  4. For i from 0 to length - 1,
    1. descriptor.[[SIMDSerializeElement]](dataBlock, byteOffset + i * descriptor.[[SIMDElementSize]], n.[[SIMDElements]][i]).

5.1.8SIMDReinterpretCast( value, newDescriptor )

NoteThis is used to define operations like SIMD.Float32x4.fromInt8x16Bits.
  1. Assert: value.[[SIMDTypeDescriptor]].[[SIMDLength]] * value.[[SIMDTypeDescriptor]].[[SIMDElementSize]] == newDescriptor.[[SIMDLength]] * newDescriptor.[[SIMDElementSize]].
  2. Let bytes be newDescriptor.[[SIMDLength]] * newDescriptor.[[SIMDElementSize]].
  3. Let block be the result of CreateByteDataBlock(bytes).
  4. ReturnIfAbrupt(block).
  5. SIMDStore(block, value, 0).
  6. Return SIMDLoad(block, newDescriptor, 0).

5.2SIMDConstructor

Each SIMDConstructor, namely Float32x4, Float64x2, Int32x4, Int16x8, and Int8x16, is associated with a SIMDType and SIMDDescriptor. This section describes the constructors and properties on them. Most properties are identical, existing separately defined on each constructor, with most differences being in the SIMDDescriptor. Certain functions are defined only on a subset of SIMDConstructors, however, and this is noted above their algorithm definition.

The definitions of the constructor and properties of the constructor to follow constitute different identities of functions and objects for each of the copies; in a real implementation, they may call out to completely different pieces of code, even if their implementation in the spec is the same.

Note As with Boolean, String, etc, SIMDConstructor is a constructor for the wrapper when invoked with new, and returns a primitive when called as a function.

5.2.1SIMDConstructor( value )

This description applies if the constructor is called with exactly one argument.
  1. If NewTarget is undefined, throw a ReferenceError (NB: TypeError?).
  2. If value is not of the type SIMDType, throw a TypeError.
  3. Let O be OrdinaryCreateFromConstructor(NewTarget, "%_SIMD_Prototype%", «[[SIMDWrapperData]]» ).
  4. ReturnIfAbrupt(O).
  5. Set the value of O’s [[SIMDWrapperData]] internal slot to value.
  6. Return O.

5.2.2SIMDConstructor( fields... )

This description applies if the constructor is called with more than one argument.
  1. If SIMDDescriptor.[[SIMDElementsLength]] does not equal Length(fields), throw a TypeError.
  2. Return SIMDCreate(SIMDDescriptor, fields...).

5.2.3SIMDConstructor.check(a)

  1. If a.[[SIMDTypeDescriptor]] is not SIMDDescriptor or b.[[SIMDTypeDescriptor]] is not SIMDDescriptor, throw a TypeError.
  2. Return a.

5.2.4SIMDConstructor.splat(n)

  1. Let list be a new List of length SIMDDescriptor.[[SIMDLength]], with all entries filled with n.
  2. Return SIMDCreate(SIMDDescriptor, ...list).

5.2.5SIMDConstructor.add(a, b)

NoteThis definition uses the normal definition of + on Javascript numbers. Is this appropriate for all SIMD types?
  1. If a.[[SIMDTypeDescriptor]] is not SIMDDescriptor or b.[[SIMDTypeDescriptor]] is not SIMDDescriptor, throw a TypeError.
  2. Return SIMDBinaryOp(a, b, +).

5.2.6SIMDConstructor.sub(a, b)

NoteThis definition uses the normal definition of - on Javascript numbers. Is this appropriate for all SIMD types?
  1. If a.[[SIMDTypeDescriptor]] is not SIMDDescriptor or b.[[SIMDTypeDescriptor]] is not SIMDDescriptor, throw a TypeError.
  2. Return SIMDBinaryOp(a, b, -).

5.2.7SIMDConstructor.mul(a, b)

NoteThis definition uses the normal definition of * on Javascript numbers. Is this appropriate for all SIMD types?
  1. If a.[[SIMDTypeDescriptor]] is not SIMDDescriptor or b.[[SIMDTypeDescriptor]] is not SIMDDescriptor, throw a TypeError.
  2. Return SIMDBinaryOp(a, b, *).

5.2.8SIMDConstructor.div(a, b)

NoteThis definition uses the normal definition of / on Javascript numbers. Is this appropriate for all SIMD types?
  1. If a.[[SIMDTypeDescriptor]] is not SIMDDescriptor or b.[[SIMDTypeDescriptor]] is not SIMDDescriptor, throw a TypeError.
  2. Return SIMDBinaryOp(a, b, /).
This property is defined only on SIMD types with floating point values. NoteIn this specification, that includes only Float32x4 and Float64x2

5.2.9SIMDConstructor.max(a, b)

  1. If a.[[SIMDTypeDescriptor]] is not SIMDDescriptor or b.[[SIMDTypeDescriptor]] is not SIMDDescriptor, throw a TypeError.
  2. Return SIMDBinaryOp(a, b, Math.max), for the initial value of Math.max.
This property is defined only on SIMD types with floating point values. NoteIn this specification, that includes only Float32x4 and Float64x2

5.2.10SIMDConstructor.min(a, b)

  1. If a.[[SIMDTypeDescriptor]] is not SIMDDescriptor or b.[[SIMDTypeDescriptor]] is not SIMDDescriptor, throw a TypeError.
  2. Return SIMDBinaryOp(a, b, Math.min), for the initial value of Math.min.

5.2.11MaxNum(n, m)

  1. Assert Type(n) is Number and Type(m) is Number.
  2. If n is NaN, return m.
  3. If m is NaN, return n.
  4. Return Math.max(n, m) for the initial value of Math.max.

5.2.12SIMDConstructor.maxNum(a, b)

This property is defined only on SIMD types with floating point values. NoteIn this specification, that includes only Float32x4 and Float64x2
  1. If a.[[SIMDTypeDescriptor]] is not SIMDDescriptor or b.[[SIMDTypeDescriptor]] is not SIMDDescriptor, throw a TypeError.
  2. Return SIMDBinaryOp(a, b, MaxNum).

5.2.13MinNum(n, m)

  1. Assert Type(n) is Number and Type(m) is Number.
  2. If n is NaN, return m.
  3. If m is NaN, return n.
  4. Return Math.min(n, m) for the initial value of Math.min.

5.2.14SIMDConstructor.minNum(a, b)

This property is defined only on SIMD types with floating point values. NoteIn this specification, that includes only Float32x4 and Float64x2
  1. If a.[[SIMDTypeDescriptor]] is not SIMDDescriptor or b.[[SIMDTypeDescriptor]] is not SIMDDescriptor, throw a TypeError.
  2. Return SIMDBinaryOp(a, b, MinNum).

5.2.15SIMDConstructor.neg(a, b)

  1. If a.[[SIMDTypeDescriptor]] is not SIMDDescriptor, throw a TypeError.
  2. Return SIMDUnaryOp(a, b, -).

5.2.16SIMDConstructor.sqrt(a)

This property is defined only on SIMD types with floating point values. NoteIn this specification, that includes only Float32x4 and Float64x2
  1. If a.[[SIMDTypeDescriptor]] is not SIMDDescriptor, throw a TypeError.
  2. Return SIMDUnaryOp(a, Math.sqrt), for the initial value of Math.sqrt.

5.2.17ReciprocalApproximation(n)

NoteThe definition here calculates the actual reciprocal. The definition should be reformulated in terms of the boundary case requirements used for function properties of the math object in 20.2.2
  1. Assert: Type(n) is Number.
  2. Return ToNumber(1 / n).

5.2.18SIMDConstructor.reciprocalApproximation(a, b)

This property is defined only on SIMD types with floating point values. NoteIn this specification, that includes only Float32x4 and Float64x2
  1. If a.[[SIMDTypeDescriptor]] is not SIMDDescriptor, throw a TypeError.
  2. Return SIMDUnaryOp(a, b, ReciprocalApproximation).

5.2.19ReciprocalApproximation(n)

NoteThe definition here calculates the actual reciprocal. The definition should be reformulated in terms of the boundary case requirements used for function properties of the math object in 20.2.2
  1. Assert: Type(n) is Number.
  2. Return ToNumber(1 / Math.sqrt(n)), for the initial value of Math.sqrt.

5.2.20SIMDConstructor.reciprocalSqrtApproximation(a)

This property is defined only on SIMD types with floating point values. NoteIn this specification, that includes only Float32x4 and Float64x2
  1. If a.[[SIMDTypeDescriptor]] is not SIMDDescriptor, throw a TypeError.
  2. Return SIMDUnaryOp(a, ReciprocalSqrtApproximation).sqrt`.

5.2.21SIMDConstructor.abs(a)

  1. If a.[[SIMDTypeDescriptor]] is not SIMDDescriptor, throw a TypeError.
  2. Return SIMDUnaryOp(a, Math.abs), for the initial value of Math.abs.

5.2.22SIMDConstructor.extractLane(simd, field)

  1. If a.[[SIMDTypeDescriptor]] is not SIMDDescriptor, throw a TypeError.
  2. Return SIMDExtractLane(simd, field).

5.2.23SIMDConstructor.replaceLane(simd, field)

  1. If a.[[SIMDTypeDescriptor]] is not SIMDDescriptor, throw a TypeError.
  2. Return SIMDReplaceLane(simd, field).

5.2.24SIMDConstructor.store(tarray, index, simd)

NoteThe first seven steps of the following store/load functions are very similar. A refactoring could reduce the spec size.
  1. If simd.[[SIMDTypeDescriptor]] is not SIMDDescriptor, throw a TypeError.
  2. If tarray does not have a [[ViewedArrayBuffer]] internal slot, throw a TypeError.
  3. Let block be tarray.[[ViewedArrayBuffer]].[[ArrayBufferData]]
  4. If index != ToInt32(index), throw a TypeError.
  5. Let elementLength be tarray.[[ByteLength]] / _tarray.[[ArrayLength]].
  6. Let byteIndex be index * elementLength.
  7. If byteIndex + SIMDDescriptor.[[SIMDElementSize]] * SIMDDescriptor.[[SIMDLength]] > tarray.[[ByteLength]] or byteIndex < 0, throw a RangeError.
  8. SIMDStore(block, SIMDDescriptor, byteIndex, simd).

5.2.25SIMDConstructor.store1(tarray, index, simd)

This function is defined only on SIMD types where SIMDDescriptor.[[SIMDLength]] <= 4. NoteIn this specification, that set consists of Float32x4, Int32x4, and Float64x2.
  1. If simd.[[SIMDTypeDescriptor]] is not SIMDDescriptor, throw a TypeError.
  2. If tarray does not have a [[ViewedArrayBuffer]] internal slot, throw a TypeError.
  3. Let block be tarray.[[ViewedArrayBuffer]].[[ArrayBufferData]]
  4. If index != ToInt32(index), throw a TypeError.
  5. Let elementLength be tarray.[[ByteLength]] / _tarray.[[ArrayLength]].
  6. Let byteIndex be index * elementLength.
  7. If byteIndex + SIMDDescriptor.[[SIMDElementSize]] > tarray.[[ByteLength]] or byteIndex < 0, throw a RangeError.
  8. SIMDStore(block, SIMDDescriptor, byteIndex, simd, 1).

5.2.26SIMDConstructor.store2(tarray, index, simd)

This function is defined only on SIMD types where SIMDDescriptor.[[SIMDLength]] == 4. NoteIn this specification, that set consists of Float32x4 and Int32x4.
  1. If simd.[[SIMDTypeDescriptor]] is not SIMDDescriptor, throw a TypeError.
  2. If tarray does not have a [[ViewedArrayBuffer]] internal slot, throw a TypeError.
  3. Let block be tarray.[[ViewedArrayBuffer]].[[ArrayBufferData]]
  4. If index != ToInt32(index), throw a TypeError.
  5. Let elementLength be tarray.[[ByteLength]] / _tarray.[[ArrayLength]].
  6. Let byteIndex be index * elementLength.
  7. If byteIndex + SIMDDescriptor.[[SIMDElementSize]] * 2 > tarray.[[ByteLength]] or byteIndex < 0, throw a RangeError.
  8. SIMDStore(block, SIMDDescriptor, byteIndex, simd, 2).

5.2.27SIMDConstructor.store3(tarray, index)

This function is defined only on SIMD types where SIMDDescriptor.[[SIMDLength]] == 4. NoteIn this specification, that set consists of Float32x4 and Int32x4.
  1. If simd.[[SIMDTypeDescriptor]] is not SIMDDescriptor, throw a TypeError.
  2. If tarray does not have a [[ViewedArrayBuffer]] internal slot, throw a TypeError.
  3. Let block be tarray.[[ViewedArrayBuffer]].[[ArrayBufferData]]
  4. If index != ToInt32(index), throw a TypeError.
  5. Let elementLength be tarray.[[ByteLength]] / _tarray.[[ArrayLength]].
  6. Let byteIndex be index * elementLength.
  7. If byteIndex + SIMDDescriptor.[[SIMDElementSize]] * 3 > tarray.[[ByteLength]] or byteIndex < 0, throw a RangeError.
  8. Return SIMDStore(block, SIMDDescriptor, byteIndex, 3).

5.2.28SIMDConstructor.load(tarray, index)

  1. If tarray does not have a [[ViewedArrayBuffer]] internal slot, throw a TypeError.
  2. Let block be tarray.[[ViewedArrayBuffer]].[[ArrayBufferData]]
  3. If index != ToInt32(index), throw a TypeError.
  4. Let elementLength be tarray.[[ByteLength]] / _tarray.[[ArrayLength]].
  5. Let byteIndex be index * elementLength.
  6. If byteIndex + SIMDDescriptor.[[SIMDElementSize]] * SIMDDescriptor.[[SIMDLength]] > tarray.[[ByteLength]] or byteIndex < 0, throw a RangeError.
  7. Return SIMDLoad(block, SIMDDescriptor, byteIndex).

5.2.29SIMDConstructor.load1(tarray, index)

This function is defined only on SIMD types where SIMDDescriptor.[[SIMDLength]] <= 4. NoteIn this specification, that set consists of Float32x4, Int32x4, and Float64x2.
  1. If tarray does not have a [[ViewedArrayBuffer]] internal slot, throw a TypeError.
  2. Let block be tarray.[[ViewedArrayBuffer]].[[ArrayBufferData]]
  3. If index != ToInt32(index), throw a TypeError.
  4. Let elementLength be tarray.[[ByteLength]] / _tarray.[[ArrayLength]].
  5. Let byteIndex be index * elementLength.
  6. If byteIndex + SIMDDescriptor.[[SIMDElementSize]] > tarray.[[ByteLength]] or byteIndex < 0, throw a RangeError.
  7. Return SIMDLoad(block, SIMDDescriptor, byteIndex, 1).

5.2.30SIMDConstructor.load2(tarray, index)

This function is defined only on SIMD types where SIMDDescriptor.[[SIMDLength]] == 4. NoteIn this specification, that set consists of Float32x4 and Int32x4.
  1. If tarray does not have a [[ViewedArrayBuffer]] internal slot, throw a TypeError.
  2. Let block be tarray.[[ViewedArrayBuffer]].[[ArrayBufferData]]
  3. If index != ToInt32(index), throw a TypeError.
  4. Let elementLength be tarray.[[ByteLength]] / _tarray.[[ArrayLength]].
  5. Let byteIndex be index * elementLength.
  6. If byteIndex + SIMDDescriptor.[[SIMDElementSize]] * 2 > tarray.[[ByteLength]] or byteIndex < 0, throw a RangeError.
  7. Return SIMDLoad(block, SIMDDescriptor, byteIndex, 2).

5.2.31SIMDConstructor.load3(tarray, index)

This function is defined only on SIMD types where SIMDDescriptor.[[SIMDLength]] == 4. NoteIn this specification, that set consists of Float32x4 and Int32x4.
  1. If tarray does not have a [[ViewedArrayBuffer]] internal slot, throw a TypeError.
  2. Let block be tarray.[[ViewedArrayBuffer]].[[ArrayBufferData]]
  3. If index != ToInt32(index), throw a TypeError.
  4. Let elementLength be tarray.[[ByteLength]] / _tarray.[[ArrayLength]].
  5. Let byteIndex be index * elementLength.
  6. If byteIndex + SIMDDescriptor.[[SIMDElementSize]] * 3 > tarray.[[ByteLength]] or byteIndex < 0, throw a RangeError.
  7. Return SIMDLoad(block, SIMDDescriptor, byteIndex, 3).

5.2.32SIMDConstructor.fromTIMDBits( value )

In this definition, TIMD ranges over all SIMD types for which SIMDDescriptor.[[SIMDElementSize]] * SIMDDescriptor.[[SIMDLength]] == TIMDDescriptor.[[SIMDElementSize]] * TIMDDescriptor.[[SIMDLength]]. NoteAll of the SIMD types described in this spec are 16 bytes, so all pairs are included.
  1. If value.[[SIMDTypeDescriptor]] is not TIMDDescriptor, throw a TypeError.
  2. Return SIMDReinterpretCast(value, SIMDDescriptor).

5.2.33SIMD.swizzle( a, lanes... )

  1. If a.[[SIMDTypeDescriptor]] is not SIMDDescriptor, throw a TypeError.
  2. If the length of lanes does not equal SIMDDescriptor.[[SIMDLength]], throw a TypeError.
  3. For each lane in lanes:
    1. If lane is not a Number, or lane != ToInt32(lane), throw a TypeError.
    2. If lane < 0 or lane >= SIMDDescriptor.[[SIMDLength]], throw a RangeError.
  4. Let list be a new List of length SIMDDescriptor.[[SIMDLength]].
  5. For i in from 0 to SIMDDescriptor.[[SIMDLength]] - 1,
    1. Set list[i] to SIMDExtractLane(a, lanes[i])
  6. Return SIMDCreate(SIMDDescriptor, ...list).

5.2.34SIMD.shuffle( a, b, lanes... )

  1. If a.[[SIMDTypeDescriptor]] is not SIMDDescriptor, or if b.[[SIMDTypeDescriptor]] is not SIMDDescriptor, throw a TypeError.
  2. If the length of lanes does not equal SIMDDescriptor.[[SIMDLength]] * 2, throw a TypeError.
  3. For each lane in lanes:
    1. If lane is not a Number, or lane != ToInt32(lane), throw a TypeError.
    2. If lane < 0 or lane >= SIMDDescriptor.[[SIMDLength]] * 2, throw a RangeError.
  4. Let list be a new List of length SIMDDescriptor.[[SIMDLength]].
  5. For i in from 0 to SIMDDescriptor.[[SIMDLength]] - 1,
    1. Let idx be lanes[i].
    2. If idx >= SIMDDescriptor.[[SIMDLength]],
      1. Set list[i] to SIMDExtractLane(b, lanes[i] - SIMDDescriptor.[[SIMDLength]])
    3. Otherwise,
      1. Set list[i] to SIMDExtractLane(a, lanes[i])
  6. Return SIMDCreate(SIMDDescriptor, ...list).

5.3The SIMDConstructor.prototype

Note Previously, if accessors like x were included, these would be spec'd as getters (with null setter) on the SIMDConstructor.prototype . However, they have been removed in favor of SIMDConstructor.extractLane. Are there any non-trivial properties? Users could add methods like .add() here if they want to use SIMD in an object-oriented way. It would also be easy to define properties on the prototype that would make SIMD values and wrapper objects array-like.

5.3.1SIMDConstructor.prototype.constructor

The initial value of SIMDConstructor.prototype.constructor is the intrinsic object %SIMDConstructor%

5.3.2SIMDConstructor.prototype.valueOf()

  1. If this does not have a [[SIMDWrapperData]] internal slot, throw a TypeError.
  2. Return this.[[SIMDWrapperData]].

5.3.3SIMDConstructor.prototype.toString()

  1. If this does not have a [[SIMDWrapperData]] internal slot, throw a TypeError.
  2. Return ToString(this.[[SIMDWrapperData]]).
NoteThis definition depends on the primitive SIMDType's behavior under ToString. Alternatively, SIMDType could have ToString defined by calling ToObject and then reaching this method (or whatever the user overrides it with), in which case the current definition in ToString would be brought down here.

5.4SIMD type descriptors

In the internal algorithms in this section, preceding the first step, if isLittleEndian is not present, set isLittleEndian to either true or false. The choice is implementation dependent and should be the alternative that is most efficient for the implementation. An implementation must use the same value each time one of the following algorithms is executed, and it must be consistent across all algorithms. NoteA refactoring might be able to reduce the size of this section somewhat.

5.4.1Float32x4Descriptor type descriptor

The Float32x4Descriptor SIMD type descriptor has the following internal slots:

  • [[SIMDLength]]: 4
  • [[SIMDElementSize]]: 4
  • [[SIMDCastNumber]]: the initial value of Math.fround
  • [[SIMDSerializeElement]]: SerializeFloat32
  • [[SIMDDeserializeElement]]: DeserializeFloat32

5.4.1.1SerializeFloat32( block, offset, n, isLittleEndian )

NoteDerived from part of SetValueInBuffer. Note that this specification does not require a particular bit pattern for NaN, and that it does not need to be the same across calls, but it cannot be signalling because the serialized value should be safe for other code to read, if a number is placed in an external ArrayBuffer which is read by external code.
  1. Assert: block is a Data Block.
  2. Assert: offset is a number.
  3. Assert: n is a number.
  4. Assert: offset + 4 is less than or equal to the size of block.
  5. Set rawBytes to a List containing the 4 bytes that are the result of converting value to IEEE 754-2008 binary32 format using “Round to nearest, ties to even” rounding mode. If isLittleEndian is false, the bytes are arranged in big endian order. Otherwise, the bytes are arranged in little endian order. If value is NaN, rawValue may be set to any implementation chosen non-signaling NaN encoding. An implementation must always choose the same non-signaling NaN encoding for a distinct Not-a-Number value.
  6. Store the individual bytes of rawBytes into block, in order, starting at block[offset].

5.4.1.2DeserializeFloat32( block, offset, isLittleEndian )

NoteDerived from part of GetValueFromBuffer. Note that while this says to return "the NaN value", the binary representation is not observable and canonicalization is not required.
  1. Assert: block is a Data Block.
  2. Assert: offset is a number.
  3. Assert: offset + 4 is less than or equal to the size of block.
  4. Let rawValue be a List of 4 containing, in order, the sequence of 4 bytes starting with block[offset].
  5. If isLittleEndian is false, reverse the order of the elements of rawValue.
  6. Let value be the byte elements of rawValue concatenated and interpreted as a little-endian bit string encoding of an IEEE 754-2008 binary32 value.
  7. If value is an IEEE 754-2008 binary32 NaN value, return the NaN Number value.
  8. Return the Number value that corresponds to value.

5.4.2Float64x2Descriptor type descriptor

The Float64x2Descriptor SIMD type descriptor has the following internal slots:

  • [[SIMDLength]]: 2
  • [[SIMDElementSize]]: 8
  • [[SIMDCastNumber]]: ToNumber
  • [[SIMDSerializeElement]]: SerializeFloat64
  • [[SIMDDeserializeElement]]: DeserializeFloat64

5.4.2.1SerializeFloat64( block, offset, n, isLittleEndian )

NoteDerived from part of SetValueInBuffer. Note that this specification does not require a particular bit pattern for NaN, and that it does not need to be the same across calls, but it cannot be signalling because the serialized value should be safe for other code to read, if a number is placed in an external ArrayBuffer which is read by external code.
  1. Assert: block is a Data Block.
  2. Assert: offset is a number.
  3. Assert: n is a number.
  4. Assert: offset + 8 is less than or equal to the size of block.
  5. Set rawBytes to a List containing the 8 bytes that are the result of converting value to IEEE 754-2008 binary64 format using “Round to nearest, ties to even” rounding mode. If isLittleEndian is false, the bytes are arranged in big endian order. Otherwise, the bytes are arranged in little endian order. If value is NaN, rawValue may be set to any implementation chosen non-signaling NaN encoding. An implementation must always choose the same non-signaling NaN encoding for a distinct Not-a-Number value.
  6. Store the individual bytes of rawBytes into block, in order, starting at block[offset].

5.4.2.2DeserializeFloat64( block, offset, isLittleEndian )

NoteDerived from part of GetValueFromBuffer. Note that while this says to return "the NaN value", the binary representation is not observable and canonicalization is not required.
  1. Assert: block is a Data Block.
  2. Assert: offset is a number.
  3. Assert: offset + 8 is less than or equal to the size of block.
  4. Let rawValue be a List of 8 containing, in order, the sequence of 8 bytes starting with block[offset].
  5. If isLittleEndian is false, reverse the order of the elements of rawValue.
  6. Let value be the byte elements of rawValue concatenated and interpreted as a little-endian bit string encoding of an IEEE 754-2008 binary64 value.
  7. If value is an IEEE 754-2008 binary64 NaN value, return the NaN Number value.
  8. Return the Number value that corresponds to value.

5.4.3Int32x4Descriptor type descriptor

The Int32x4Descriptor SIMD type descriptor has the following internal slots:

  • [[SIMDLength]]: 4
  • [[SIMDElementSize]]: 4
  • [[SIMDCastNumber]]: ToInt32
  • [[SIMDSerializeElement]]: SerializeInt32
  • [[SIMDDeserializeElement]]: DeserializeInt32

5.4.3.1SerializeInt32( block, offset, n, isLittleEndian )

NoteDerived from part of SetValueInBuffer.
  1. Assert: block is a Data Block.
  2. Assert: offset is a number.
  3. Assert: n is a number.
  4. Assert: n == ToInt32(n).
  5. Assert: offset + 4 is less than or equal to the size of block.
  6. Let rawBytes be a List containing the 4-byte binary 2’s complement encoding of n. If isLittleEndian is false, the bytes are ordered in big endian order. Otherwise, the bytes are ordered in little endian order.
  7. Store the individual bytes of rawBytes into block, in order, starting at block[offset].

5.4.3.2DeserializeInt32( block, offset, isLittleEndian )

NoteDerived from part of GetValueFromBuffer.
  1. Assert: block is a Data Block.
  2. Assert: offset is a number.
  3. Assert: offset + 4 is less than or equal to the size of block.
  4. Let rawValue be a List of 4 containing, in order, the sequence of 4 bytes starting with block[offset].
  5. If isLittleEndian is false, reverse the order of the elements of rawValue.
  6. Let intValue be the byte elements of rawValue concatenated and interpreted as a bit string encoding of a binary little-endian 2’s complement number of bit length 32.
  7. Return the Number value that corresponds to intValue.

5.4.4Int16x8Descriptor type descriptor

The Int16x8Descriptor SIMD type descriptor has the following internal slots:

  • [[SIMDLength]]: 8
  • [[SIMDElementSize]]: 2
  • [[SIMDCastNumber]]: ToInt16
  • [[SIMDSerializeElement]]: SerializeInt16
  • [[SIMDDeserializeElement]]: DeserializeInt16

5.4.4.1SerializeInt16( block, offset, n, isLittleEndian )

NoteDerived from part of SetValueInBuffer.
  1. Assert: block is a Data Block.
  2. Assert: offset is a number.
  3. Assert: n is a number.
  4. Assert: n == ToInt16(n).
  5. Assert: offset + 2 is less than or equal to the size of block.
  6. Let rawBytes be a List containing the 2-byte binary 2’s complement encoding of n. If isLittleEndian is false, the bytes are ordered in big endian order. Otherwise, the bytes are ordered in little endian order.
  7. Store the individual bytes of rawBytes into block, in order, starting at block[offset].

5.4.4.2DeserializeInt16( block, offset, isLittleEndian )

NoteDerived from part of GetValueFromBuffer.
  1. Assert: block is a Data Block.
  2. Assert: offset is a number.
  3. Assert: offset + 4 is less than or equal to the size of block.
  4. Let rawValue be a List of 4 containing, in order, the sequence of 2 bytes starting with block[offset].
  5. If isLittleEndian is false, reverse the order of the elements of rawValue.
  6. Let intValue be the byte elements of rawValue concatenated and interpreted as a bit string encoding of a binary little-endian 2’s complement number of bit length 16.
  7. Return the Number value that corresponds to intValue.

5.4.5Int8x16Descriptor type descriptor

The Int8x16Descriptor SIMD type descriptor has the following internal slots:

  • [[SIMDLength]]: 16
  • [[SIMDElementSize]]: 1
  • [[SIMDCastNumber]]: ToInt8
  • [[SIMDSerializeElement]]: SerializeInt8
  • [[SIMDDeserializeElement]]: DeserializeInt8

5.4.5.1SerializeInt8( block, offset, n, isLittleEndian )

NoteDerived from part of SetValueInBuffer.
  1. Assert: block is a Data Block.
  2. Assert: offset is a number.
  3. Assert: n is a number.
  4. Assert: n == ToInt8(n).
  5. Assert: offset + 1 is less than or equal to the size of block.
  6. Let rawBytes be a List containing the 1-byte binary 2’s complement encoding of n.
  7. Store the individual bytes of rawBytes into block, in order, starting at block[offset].

5.4.5.2DeserializeInt8( block, offset, isLittleEndian )

NoteDerived from part of GetValueFromBuffer.
  1. Assert: block is a Data Block.
  2. Assert: offset is a number.
  3. Assert: offset + 4 is less than or equal to the size of block.
  4. Let rawValue be a List of one element containing, the singleton byte at block[offset].
  5. Let intValue be the byte elements of rawValue concatenated and interpreted as a bit string encoding of a binary little-endian 2’s complement number of bit length 8.
  6. Return the Number value that corresponds to intValue.