浏览代码

Add support for Float16Array (#1840)

Marko Lahma 1 年之前
父节点
当前提交
2754f1c391

+ 0 - 1
Jint.Tests.Test262/Test262Harness.settings.json

@@ -9,7 +9,6 @@
     "async-iteration",
     "async-iteration",
     "Atomics",
     "Atomics",
     "decorators",
     "decorators",
-    "Float16Array",
     "import-assertions",
     "import-assertions",
     "iterator-helpers",
     "iterator-helpers",
     "regexp-lookbehind",
     "regexp-lookbehind",

+ 18 - 2
Jint.Tests/Runtime/TypedArrayInteropTests.cs

@@ -120,15 +120,31 @@ namespace Jint.Tests.Runtime
             Assert.Equal(source, fromEngine.AsBigUint64Array());
             Assert.Equal(source, fromEngine.AsBigUint64Array());
         }
         }
 
 
+#if NET6_0_OR_GREATER
+        [Fact]
+        public void CanInteropWithFloat16()
+        {
+            var engine = new Engine();
+            var source = new[] { (Half) 42, (Half) 12 };
+            
+            engine.SetValue("testSubject", engine.Realm.Intrinsics.Float16Array.Construct(source));
+            ValidateCreatedTypeArray(engine, "Float16Array");
+            
+            var fromEngine = engine.GetValue("testSubject");
+            Assert.True(fromEngine.IsFloat16Array());
+            Assert.Equal(source, fromEngine.AsFloat16Array());
+        }
+#endif
+
         [Fact]
         [Fact]
         public void CanInteropWithFloat32()
         public void CanInteropWithFloat32()
         {
         {
             var engine = new Engine();
             var engine = new Engine();
             var source = new float[] { 42f, 12f };
             var source = new float[] { 42f, 12f };
-            
+
             engine.SetValue("testSubject", engine.Realm.Intrinsics.Float32Array.Construct(source));
             engine.SetValue("testSubject", engine.Realm.Intrinsics.Float32Array.Construct(source));
             ValidateCreatedTypeArray(engine, "Float32Array");
             ValidateCreatedTypeArray(engine, "Float32Array");
-            
+
             var fromEngine = engine.GetValue("testSubject");
             var fromEngine = engine.GetValue("testSubject");
             Assert.True(fromEngine.IsFloat32Array());
             Assert.True(fromEngine.IsFloat32Array());
             Assert.Equal(source, fromEngine.AsFloat32Array());
             Assert.Equal(source, fromEngine.AsFloat32Array());

+ 4 - 0
Jint/Jint.csproj

@@ -30,6 +30,10 @@
     <DefineConstants>$(DefineConstants);SUPPORTS_SPAN_PARSE;SUPPORTS_WEAK_TABLE_ADD_OR_UPDATE;SUPPORTS_WEAK_TABLE_CLEAR</DefineConstants>
     <DefineConstants>$(DefineConstants);SUPPORTS_SPAN_PARSE;SUPPORTS_WEAK_TABLE_ADD_OR_UPDATE;SUPPORTS_WEAK_TABLE_CLEAR</DefineConstants>
   </PropertyGroup>
   </PropertyGroup>
 
 
+  <PropertyGroup Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net6.0'))">
+    <DefineConstants>$(DefineConstants);SUPPORTS_HALF</DefineConstants>
+  </PropertyGroup>
+
   <ItemGroup>
   <ItemGroup>
     <None Include="../README.md" Pack="true" PackagePath="\"/>
     <None Include="../README.md" Pack="true" PackagePath="\"/>
   </ItemGroup>
   </ItemGroup>

+ 19 - 0
Jint/JsValueExtensions.cs

@@ -444,6 +444,25 @@ public static class JsValueExtensions
         return ((JsTypedArray) value).ToNativeArray<ulong>();
         return ((JsTypedArray) value).ToNativeArray<ulong>();
     }
     }
 
 
+    [MethodImpl(MethodImplOptions.AggressiveInlining)]
+    public static bool IsFloat16Array(this JsValue value)
+    {
+        return value is JsTypedArray { _arrayElementType: TypedArrayElementType.Float16 };
+    }
+
+#if SUPPORTS_HALF
+    [MethodImpl(MethodImplOptions.AggressiveInlining)]
+    public static Half[] AsFloat16Array(this JsValue value)
+    {
+        if (!value.IsFloat16Array())
+        {
+            ThrowWrongTypeException(value, "Float16Array");
+        }
+
+        return ((JsTypedArray) value).ToNativeArray<Half>();
+    }
+#endif
+
     [MethodImpl(MethodImplOptions.AggressiveInlining)]
     [MethodImpl(MethodImplOptions.AggressiveInlining)]
     public static bool IsFloat32Array(this JsValue value)
     public static bool IsFloat32Array(this JsValue value)
     {
     {

+ 16 - 7
Jint/Native/DataView/DataViewPrototype.cs

@@ -31,7 +31,7 @@ namespace Jint.Native.DataView
         {
         {
             const PropertyFlag lengthFlags = PropertyFlag.Configurable;
             const PropertyFlag lengthFlags = PropertyFlag.Configurable;
             const PropertyFlag propertyFlags = PropertyFlag.Configurable | PropertyFlag.Writable;
             const PropertyFlag propertyFlags = PropertyFlag.Configurable | PropertyFlag.Writable;
-            var properties = new PropertyDictionary(24, checkExistingKeys: false)
+            var properties = new PropertyDictionary(26, checkExistingKeys: false)
             {
             {
                 ["buffer"] = new GetSetPropertyDescriptor(new ClrFunction(_engine, "get buffer", Buffer, 0, lengthFlags), Undefined, PropertyFlag.Configurable),
                 ["buffer"] = new GetSetPropertyDescriptor(new ClrFunction(_engine, "get buffer", Buffer, 0, lengthFlags), Undefined, PropertyFlag.Configurable),
                 ["byteLength"] = new GetSetPropertyDescriptor(new ClrFunction(_engine, "get byteLength", ByteLength, 0, lengthFlags), Undefined, PropertyFlag.Configurable),
                 ["byteLength"] = new GetSetPropertyDescriptor(new ClrFunction(_engine, "get byteLength", ByteLength, 0, lengthFlags), Undefined, PropertyFlag.Configurable),
@@ -39,6 +39,7 @@ namespace Jint.Native.DataView
                 ["constructor"] = new PropertyDescriptor(_constructor, PropertyFlag.NonEnumerable),
                 ["constructor"] = new PropertyDescriptor(_constructor, PropertyFlag.NonEnumerable),
                 ["getBigInt64"] = new PropertyDescriptor(new ClrFunction(Engine, "getBigInt64", GetBigInt64, length: 1, lengthFlags), propertyFlags),
                 ["getBigInt64"] = new PropertyDescriptor(new ClrFunction(Engine, "getBigInt64", GetBigInt64, length: 1, lengthFlags), propertyFlags),
                 ["getBigUint64"] = new PropertyDescriptor(new ClrFunction(Engine, "getBigUint64", GetBigUint64, length: 1, lengthFlags), propertyFlags),
                 ["getBigUint64"] = new PropertyDescriptor(new ClrFunction(Engine, "getBigUint64", GetBigUint64, length: 1, lengthFlags), propertyFlags),
+                ["getFloat16"] = new PropertyDescriptor(new ClrFunction(Engine, "getFloat16", GetFloat16, length: 1, lengthFlags), propertyFlags),
                 ["getFloat32"] = new PropertyDescriptor(new ClrFunction(Engine, "getFloat32", GetFloat32, length: 1, lengthFlags), propertyFlags),
                 ["getFloat32"] = new PropertyDescriptor(new ClrFunction(Engine, "getFloat32", GetFloat32, length: 1, lengthFlags), propertyFlags),
                 ["getFloat64"] = new PropertyDescriptor(new ClrFunction(Engine, "getFloat64", GetFloat64, length: 1, lengthFlags), propertyFlags),
                 ["getFloat64"] = new PropertyDescriptor(new ClrFunction(Engine, "getFloat64", GetFloat64, length: 1, lengthFlags), propertyFlags),
                 ["getInt8"] = new PropertyDescriptor(new ClrFunction(Engine, "getInt8", GetInt8, length: 1, lengthFlags), propertyFlags),
                 ["getInt8"] = new PropertyDescriptor(new ClrFunction(Engine, "getInt8", GetInt8, length: 1, lengthFlags), propertyFlags),
@@ -49,6 +50,7 @@ namespace Jint.Native.DataView
                 ["getUint32"] = new PropertyDescriptor(new ClrFunction(Engine, "getUint32", GetUint32, length: 1, lengthFlags), propertyFlags),
                 ["getUint32"] = new PropertyDescriptor(new ClrFunction(Engine, "getUint32", GetUint32, length: 1, lengthFlags), propertyFlags),
                 ["setBigInt64"] = new PropertyDescriptor(new ClrFunction(Engine, "setBigInt64", SetBigInt64, length: 2, lengthFlags), propertyFlags),
                 ["setBigInt64"] = new PropertyDescriptor(new ClrFunction(Engine, "setBigInt64", SetBigInt64, length: 2, lengthFlags), propertyFlags),
                 ["setBigUint64"] = new PropertyDescriptor(new ClrFunction(Engine, "setBigUint64", SetBigUint64, length: 2, lengthFlags), propertyFlags),
                 ["setBigUint64"] = new PropertyDescriptor(new ClrFunction(Engine, "setBigUint64", SetBigUint64, length: 2, lengthFlags), propertyFlags),
+                ["setFloat16"] = new PropertyDescriptor(new ClrFunction(Engine, "setFloat16", SetFloat16, length: 2, lengthFlags), propertyFlags),
                 ["setFloat32"] = new PropertyDescriptor(new ClrFunction(Engine, "setFloat32", SetFloat32, length: 2, lengthFlags), propertyFlags),
                 ["setFloat32"] = new PropertyDescriptor(new ClrFunction(Engine, "setFloat32", SetFloat32, length: 2, lengthFlags), propertyFlags),
                 ["setFloat64"] = new PropertyDescriptor(new ClrFunction(Engine, "setFloat64", SetFloat64, length: 2, lengthFlags), propertyFlags),
                 ["setFloat64"] = new PropertyDescriptor(new ClrFunction(Engine, "setFloat64", SetFloat64, length: 2, lengthFlags), propertyFlags),
                 ["setInt8"] = new PropertyDescriptor(new ClrFunction(Engine, "setInt8", SetInt8, length: 2, lengthFlags), propertyFlags),
                 ["setInt8"] = new PropertyDescriptor(new ClrFunction(Engine, "setInt8", SetInt8, length: 2, lengthFlags), propertyFlags),
@@ -60,10 +62,7 @@ namespace Jint.Native.DataView
             };
             };
             SetProperties(properties);
             SetProperties(properties);
 
 
-            var symbols = new SymbolDictionary(1)
-            {
-                [GlobalSymbolRegistry.ToStringTag] = new PropertyDescriptor("DataView", PropertyFlag.Configurable)
-            };
+            var symbols = new SymbolDictionary(1) { [GlobalSymbolRegistry.ToStringTag] = new PropertyDescriptor("DataView", PropertyFlag.Configurable) };
             SetSymbols(symbols);
             SetSymbols(symbols);
         }
         }
 
 
@@ -137,6 +136,11 @@ namespace Jint.Native.DataView
             return GetViewValue(thisObject, arguments.At(0), arguments.At(1), TypedArrayElementType.BigUint64);
             return GetViewValue(thisObject, arguments.At(0), arguments.At(1), TypedArrayElementType.BigUint64);
         }
         }
 
 
+        private JsValue GetFloat16(JsValue thisObject, JsValue[] arguments)
+        {
+            return GetViewValue(thisObject, arguments.At(0), arguments.At(1, JsBoolean.False), TypedArrayElementType.Float16);
+        }
+
         private JsValue GetFloat32(JsValue thisObject, JsValue[] arguments)
         private JsValue GetFloat32(JsValue thisObject, JsValue[] arguments)
         {
         {
             return GetViewValue(thisObject, arguments.At(0), arguments.At(1, JsBoolean.False), TypedArrayElementType.Float32);
             return GetViewValue(thisObject, arguments.At(0), arguments.At(1, JsBoolean.False), TypedArrayElementType.Float32);
@@ -187,7 +191,12 @@ namespace Jint.Native.DataView
             return SetViewValue(thisObject, arguments.At(0), arguments.At(2), TypedArrayElementType.BigUint64, arguments.At(1));
             return SetViewValue(thisObject, arguments.At(0), arguments.At(2), TypedArrayElementType.BigUint64, arguments.At(1));
         }
         }
 
 
-        private JsValue SetFloat32 (JsValue thisObject, JsValue[] arguments)
+        private JsValue SetFloat16(JsValue thisObject, JsValue[] arguments)
+        {
+            return SetViewValue(thisObject, arguments.At(0), arguments.At(2, JsBoolean.False), TypedArrayElementType.Float16, arguments.At(1));
+        }
+
+        private JsValue SetFloat32(JsValue thisObject, JsValue[] arguments)
         {
         {
             return SetViewValue(thisObject, arguments.At(0), arguments.At(2, JsBoolean.False), TypedArrayElementType.Float32, arguments.At(1));
             return SetViewValue(thisObject, arguments.At(0), arguments.At(2, JsBoolean.False), TypedArrayElementType.Float32, arguments.At(1));
         }
         }
@@ -197,7 +206,7 @@ namespace Jint.Native.DataView
             return SetViewValue(thisObject, arguments.At(0), arguments.At(2, JsBoolean.False), TypedArrayElementType.Float64, arguments.At(1));
             return SetViewValue(thisObject, arguments.At(0), arguments.At(2, JsBoolean.False), TypedArrayElementType.Float64, arguments.At(1));
         }
         }
 
 
-        private JsValue SetInt8 (JsValue thisObject, JsValue[] arguments)
+        private JsValue SetInt8(JsValue thisObject, JsValue[] arguments)
         {
         {
             return SetViewValue(thisObject, arguments.At(0), JsBoolean.True, TypedArrayElementType.Int8, arguments.At(1));
             return SetViewValue(thisObject, arguments.At(0), JsBoolean.True, TypedArrayElementType.Int8, arguments.At(1));
         }
         }

+ 3 - 1
Jint/Native/Global/GlobalObject.Properties.cs

@@ -20,6 +20,7 @@ public partial class GlobalObject
     private static readonly Key propertyError = "Error";
     private static readonly Key propertyError = "Error";
     private static readonly Key propertyEvalError = "EvalError";
     private static readonly Key propertyEvalError = "EvalError";
     private static readonly Key propertyFinalizationRegistry = "FinalizationRegistry";
     private static readonly Key propertyFinalizationRegistry = "FinalizationRegistry";
+    private static readonly Key propertyFloat16Array = "Float16Array";
     private static readonly Key propertyFloat32Array = "Float32Array";
     private static readonly Key propertyFloat32Array = "Float32Array";
     private static readonly Key propertyFloat64Array = "Float64Array";
     private static readonly Key propertyFloat64Array = "Float64Array";
     private static readonly Key propertyFunction = "Function";
     private static readonly Key propertyFunction = "Function";
@@ -81,7 +82,7 @@ public partial class GlobalObject
         const PropertyFlag LengthFlags = PropertyFlag.Configurable;
         const PropertyFlag LengthFlags = PropertyFlag.Configurable;
         const PropertyFlag PropertyFlags = PropertyFlag.Configurable | PropertyFlag.Writable;
         const PropertyFlag PropertyFlags = PropertyFlag.Configurable | PropertyFlag.Writable;
 
 
-        var properties = new StringDictionarySlim<PropertyDescriptor>(64);
+        var properties = new StringDictionarySlim<PropertyDescriptor>(65);
         properties.AddDangerous(propertyAggregateError, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.AggregateError, PropertyFlags));
         properties.AddDangerous(propertyAggregateError, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.AggregateError, PropertyFlags));
         properties.AddDangerous(propertyArray, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Array, PropertyFlags));
         properties.AddDangerous(propertyArray, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Array, PropertyFlags));
         properties.AddDangerous(propertyArrayBuffer, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.ArrayBuffer, PropertyFlags));
         properties.AddDangerous(propertyArrayBuffer, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.ArrayBuffer, PropertyFlags));
@@ -95,6 +96,7 @@ public partial class GlobalObject
         properties.AddDangerous(propertyError, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Error, PropertyFlags));
         properties.AddDangerous(propertyError, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Error, PropertyFlags));
         properties.AddDangerous(propertyEvalError, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.EvalError, PropertyFlags));
         properties.AddDangerous(propertyEvalError, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.EvalError, PropertyFlags));
         properties.AddDangerous(propertyFinalizationRegistry, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.FinalizationRegistry, PropertyFlags));
         properties.AddDangerous(propertyFinalizationRegistry, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.FinalizationRegistry, PropertyFlags));
+        properties.AddDangerous(propertyFloat16Array, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Float16Array, PropertyFlags));
         properties.AddDangerous(propertyFloat32Array, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Float32Array, PropertyFlags));
         properties.AddDangerous(propertyFloat32Array, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Float32Array, PropertyFlags));
         properties.AddDangerous(propertyFloat64Array, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Float64Array, PropertyFlags));
         properties.AddDangerous(propertyFloat64Array, new LazyPropertyDescriptor(this, static state => ((GlobalObject) state!)._realm.Intrinsics.Float64Array, PropertyFlags));
         properties.AddDangerous(propertyFunction, new PropertyDescriptor(_realm.Intrinsics.Function, PropertyFlags));
         properties.AddDangerous(propertyFunction, new PropertyDescriptor(_realm.Intrinsics.Function, PropertyFlags));

+ 46 - 21
Jint/Native/JsArrayBuffer.cs

@@ -110,7 +110,7 @@ public class JsArrayBuffer : ObjectInstance
         // 8 byte values require a little more at the moment
         // 8 byte values require a little more at the moment
         var needsReverse = !isLittleEndian
         var needsReverse = !isLittleEndian
                            && elementSize > 1
                            && elementSize > 1
-                           && type is TypedArrayElementType.Float32 or TypedArrayElementType.Float64 or TypedArrayElementType.BigInt64 or TypedArrayElementType.BigUint64;
+                           && type is TypedArrayElementType.Float16 or TypedArrayElementType.Float32 or TypedArrayElementType.Float64 or TypedArrayElementType.BigInt64 or TypedArrayElementType.BigUint64;
 
 
         if (needsReverse)
         if (needsReverse)
         {
         {
@@ -120,6 +120,26 @@ public class JsArrayBuffer : ObjectInstance
             rawBytes = _workBuffer;
             rawBytes = _workBuffer;
         }
         }
 
 
+        if (type == TypedArrayElementType.Float16)
+        {
+#if SUPPORTS_HALF
+            // rawBytes concatenated and interpreted as a little-endian bit string encoding of an IEEE 754-2019 binary32 value.
+            var value = BitConverter.ToHalf(rawBytes, byteIndex);
+
+            // If value is an IEEE 754-2019 binary32 NaN value, return the NaN Number value.
+            if (Half.IsNaN(value))
+            {
+                return double.NaN;
+            }
+
+            return value;
+#else
+            ExceptionHelper.ThrowNotImplementedException("Float16/Half type is not supported in this build");
+            return default;
+#endif
+
+        }
+
         if (type == TypedArrayElementType.Float32)
         if (type == TypedArrayElementType.Float32)
         {
         {
             // rawBytes concatenated and interpreted as a little-endian bit string encoding of an IEEE 754-2019 binary32 value.
             // rawBytes concatenated and interpreted as a little-endian bit string encoding of an IEEE 754-2019 binary32 value.
@@ -155,25 +175,21 @@ public class JsArrayBuffer : ObjectInstance
 
 
         TypedArrayValue? arrayValue = type switch
         TypedArrayValue? arrayValue = type switch
         {
         {
-            TypedArrayElementType.Int8 => ((sbyte) rawBytes[byteIndex]),
-            TypedArrayElementType.Uint8 => (rawBytes[byteIndex]),
-            TypedArrayElementType.Uint8C =>(rawBytes[byteIndex]),
-            TypedArrayElementType.Int16 => (isLittleEndian
-                    ? (short) (rawBytes[byteIndex] | (rawBytes[byteIndex + 1] << 8))
-                    : (short) (rawBytes[byteIndex + 1] | (rawBytes[byteIndex] << 8))
-                ),
-            TypedArrayElementType.Uint16 => (isLittleEndian
-                    ? (ushort) (rawBytes[byteIndex] | (rawBytes[byteIndex + 1] << 8))
-                    : (ushort) (rawBytes[byteIndex + 1] | (rawBytes[byteIndex] << 8))
-                ),
-            TypedArrayElementType.Int32 => (isLittleEndian
-                    ? rawBytes[byteIndex] | (rawBytes[byteIndex + 1] << 8) | (rawBytes[byteIndex + 2] << 16) | (rawBytes[byteIndex + 3] << 24)
-                    : rawBytes[byteIndex + 3] | (rawBytes[byteIndex + 2] << 8) | (rawBytes[byteIndex + 1] << 16) | (rawBytes[byteIndex + 0] << 24)
-                ),
-            TypedArrayElementType.Uint32 => (isLittleEndian
-                    ? (uint) (rawBytes[byteIndex] | (rawBytes[byteIndex + 1] << 8) | (rawBytes[byteIndex + 2] << 16) | (rawBytes[byteIndex + 3] << 24))
-                    : (uint) (rawBytes[byteIndex + 3] | (rawBytes[byteIndex + 2] << 8) | (rawBytes[byteIndex + 1] << 16) | (rawBytes[byteIndex] << 24))
-                ),
+            TypedArrayElementType.Int8 => (sbyte) rawBytes[byteIndex],
+            TypedArrayElementType.Uint8 => rawBytes[byteIndex],
+            TypedArrayElementType.Uint8C =>rawBytes[byteIndex],
+            TypedArrayElementType.Int16 => isLittleEndian
+                ? (short) (rawBytes[byteIndex] | (rawBytes[byteIndex + 1] << 8))
+                : (short) (rawBytes[byteIndex + 1] | (rawBytes[byteIndex] << 8)),
+            TypedArrayElementType.Uint16 => isLittleEndian
+                ? (ushort) (rawBytes[byteIndex] | (rawBytes[byteIndex + 1] << 8))
+                : (ushort) (rawBytes[byteIndex + 1] | (rawBytes[byteIndex] << 8)),
+            TypedArrayElementType.Int32 => isLittleEndian
+                ? rawBytes[byteIndex] | (rawBytes[byteIndex + 1] << 8) | (rawBytes[byteIndex + 2] << 16) | (rawBytes[byteIndex + 3] << 24)
+                : rawBytes[byteIndex + 3] | (rawBytes[byteIndex + 2] << 8) | (rawBytes[byteIndex + 1] << 16) | (rawBytes[byteIndex + 0] << 24),
+            TypedArrayElementType.Uint32 => isLittleEndian
+                ? (uint) (rawBytes[byteIndex] | (rawBytes[byteIndex + 1] << 8) | (rawBytes[byteIndex + 2] << 16) | (rawBytes[byteIndex + 3] << 24))
+                : (uint) (rawBytes[byteIndex + 3] | (rawBytes[byteIndex + 2] << 8) | (rawBytes[byteIndex + 1] << 16) | (rawBytes[byteIndex] << 24)),
             _ => null
             _ => null
         };
         };
 
 
@@ -205,7 +221,16 @@ public class JsArrayBuffer : ObjectInstance
     private byte[] NumericToRawBytes(TypedArrayElementType type, TypedArrayValue value, bool isLittleEndian)
     private byte[] NumericToRawBytes(TypedArrayElementType type, TypedArrayValue value, bool isLittleEndian)
     {
     {
         byte[] rawBytes;
         byte[] rawBytes;
-        if (type == TypedArrayElementType.Float32)
+        if (type == TypedArrayElementType.Float16)
+        {
+#if SUPPORTS_HALF
+            rawBytes = BitConverter.GetBytes((Half) value.DoubleValue);
+#else
+            ExceptionHelper.ThrowNotImplementedException("Float16/Half type is not supported in this build");
+            return default!;
+#endif
+        }
+        else if (type == TypedArrayElementType.Float32)
         {
         {
             // Let rawBytes be a List whose elements are the 4 bytes that are the result of converting value to IEEE 754-2019 binary32 format using roundTiesToEven 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, rawBytes may be set to any implementation chosen IEEE 754-2019 binary32 format Not-a-Number encoding. An implementation must always choose the same encoding for each implementation distinguishable NaN value.
             // Let rawBytes be a List whose elements are the 4 bytes that are the result of converting value to IEEE 754-2019 binary32 format using roundTiesToEven 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, rawBytes may be set to any implementation chosen IEEE 754-2019 binary32 format Not-a-Number encoding. An implementation must always choose the same encoding for each implementation distinguishable NaN value.
             rawBytes = BitConverter.GetBytes((float) value.DoubleValue);
             rawBytes = BitConverter.GetBytes((float) value.DoubleValue);

+ 73 - 45
Jint/Native/Math/MathInstance.cs

@@ -21,49 +21,50 @@ namespace Jint.Native.Math
         {
         {
             var properties = new PropertyDictionary(45, checkExistingKeys: false)
             var properties = new PropertyDictionary(45, checkExistingKeys: false)
             {
             {
-                ["abs"] = new PropertyDescriptor(new ClrFunction(Engine, "abs", Abs, 1, PropertyFlag.Configurable), true, false, true),
-                ["acos"] = new PropertyDescriptor(new ClrFunction(Engine, "acos", Acos, 1, PropertyFlag.Configurable), true, false, true),
-                ["acosh"] = new PropertyDescriptor(new ClrFunction(Engine, "acosh", Acosh, 1, PropertyFlag.Configurable), true, false, true),
-                ["asin"] = new PropertyDescriptor(new ClrFunction(Engine, "asin", Asin, 1, PropertyFlag.Configurable), true, false, true),
-                ["asinh"] = new PropertyDescriptor(new ClrFunction(Engine, "asinh", Asinh, 1, PropertyFlag.Configurable), true, false, true),
-                ["atan"] = new PropertyDescriptor(new ClrFunction(Engine, "atan", Atan, 1, PropertyFlag.Configurable), true, false, true),
-                ["atanh"] = new PropertyDescriptor(new ClrFunction(Engine, "atanh", Atanh, 1, PropertyFlag.Configurable), true, false, true),
-                ["atan2"] = new PropertyDescriptor(new ClrFunction(Engine, "atan2", Atan2, 2, PropertyFlag.Configurable), true, false, true),
-                ["ceil"] = new PropertyDescriptor(new ClrFunction(Engine, "ceil", Ceil, 1, PropertyFlag.Configurable), true, false, true),
-                ["cos"] = new PropertyDescriptor(new ClrFunction(Engine, "cos", Cos, 1, PropertyFlag.Configurable), true, false, true),
-                ["cosh"] = new PropertyDescriptor(new ClrFunction(Engine, "cosh", Cosh, 1, PropertyFlag.Configurable), true, false, true),
-                ["exp"] = new PropertyDescriptor(new ClrFunction(Engine, "exp", Exp, 1, PropertyFlag.Configurable), true, false, true),
-                ["expm1"] = new PropertyDescriptor(new ClrFunction(Engine, "expm1", Expm1, 1, PropertyFlag.Configurable), true, false, true),
-                ["floor"] = new PropertyDescriptor(new ClrFunction(Engine, "floor", Floor, 1, PropertyFlag.Configurable), true, false, true),
-                ["log"] = new PropertyDescriptor(new ClrFunction(Engine, "log", Log, 1, PropertyFlag.Configurable), true, false, true),
-                ["log1p"] = new PropertyDescriptor(new ClrFunction(Engine, "log1p", Log1p, 1, PropertyFlag.Configurable), true, false, true),
-                ["log2"] = new PropertyDescriptor(new ClrFunction(Engine, "log2", Log2, 1, PropertyFlag.Configurable), true, false, true),
-                ["log10"] = new PropertyDescriptor(new ClrFunction(Engine, "log10", Log10, 1, PropertyFlag.Configurable), true, false, true),
-                ["max"] = new PropertyDescriptor(new ClrFunction(Engine, "max", Max, 2, PropertyFlag.Configurable), true, false, true),
-                ["min"] = new PropertyDescriptor(new ClrFunction(Engine, "min", Min, 2, PropertyFlag.Configurable), true, false, true),
-                ["pow"] = new PropertyDescriptor(new ClrFunction(Engine, "pow", Pow, 2, PropertyFlag.Configurable), true, false, true),
-                ["random"] = new PropertyDescriptor(new ClrFunction(Engine, "random", Random, 0, PropertyFlag.Configurable), true, false, true),
-                ["round"] = new PropertyDescriptor(new ClrFunction(Engine, "round", Round, 1, PropertyFlag.Configurable), true, false, true),
-                ["fround"] = new PropertyDescriptor(new ClrFunction(Engine, "fround", Fround, 1, PropertyFlag.Configurable), true, false, true),
-                ["sin"] = new PropertyDescriptor(new ClrFunction(Engine, "sin", Sin, 1, PropertyFlag.Configurable), true, false, true),
-                ["sinh"] = new PropertyDescriptor(new ClrFunction(Engine, "sinh", Sinh, 1, PropertyFlag.Configurable), true, false, true),
-                ["sqrt"] = new PropertyDescriptor(new ClrFunction(Engine, "sqrt", Sqrt, 1, PropertyFlag.Configurable), true, false, true),
-                ["tan"] = new PropertyDescriptor(new ClrFunction(Engine, "tan", Tan, 1, PropertyFlag.Configurable), true, false, true),
-                ["tanh"] = new PropertyDescriptor(new ClrFunction(Engine, "tanh", Tanh, 1, PropertyFlag.Configurable), true, false, true),
-                ["trunc"] = new PropertyDescriptor(new ClrFunction(Engine, "trunc", Truncate, 1, PropertyFlag.Configurable), true, false, true),
-                ["sign"] = new PropertyDescriptor(new ClrFunction(Engine, "sign", Sign, 1, PropertyFlag.Configurable), true, false, true),
-                ["cbrt"] = new PropertyDescriptor(new ClrFunction(Engine, "cbrt", Cbrt, 1, PropertyFlag.Configurable), true, false, true),
-                ["hypot"] = new PropertyDescriptor(new ClrFunction(Engine, "hypot", Hypot, 2, PropertyFlag.Configurable), true, false, true),
-                ["imul"] = new PropertyDescriptor(new ClrFunction(Engine, "imul", Imul, 2, PropertyFlag.Configurable), true, false, true),
-                ["clz32"] = new PropertyDescriptor(new ClrFunction(Engine, "clz32", Clz32, 1, PropertyFlag.Configurable), true, false, true),
-                ["E"] = new PropertyDescriptor(System.Math.E, false, false, false),
-                ["LN10"] = new PropertyDescriptor(System.Math.Log(10), false, false, false),
-                ["LN2"] = new PropertyDescriptor(System.Math.Log(2), false, false, false),
-                ["LOG2E"] = new PropertyDescriptor(System.Math.Log(System.Math.E, 2), false, false, false),
-                ["LOG10E"] = new PropertyDescriptor(System.Math.Log(System.Math.E, 10), false, false, false),
-                ["PI"] = new PropertyDescriptor(System.Math.PI, false, false, false),
-                ["SQRT1_2"] = new PropertyDescriptor(System.Math.Sqrt(0.5), false, false, false),
-                ["SQRT2"] = new PropertyDescriptor(System.Math.Sqrt(2), false, false, false)
+                ["abs"] = new PropertyDescriptor(new ClrFunction(Engine, "abs", Abs, 1, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["acos"] = new PropertyDescriptor(new ClrFunction(Engine, "acos", Acos, 1, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["acosh"] = new PropertyDescriptor(new ClrFunction(Engine, "acosh", Acosh, 1, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["asin"] = new PropertyDescriptor(new ClrFunction(Engine, "asin", Asin, 1, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["asinh"] = new PropertyDescriptor(new ClrFunction(Engine, "asinh", Asinh, 1, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["atan"] = new PropertyDescriptor(new ClrFunction(Engine, "atan", Atan, 1, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["atanh"] = new PropertyDescriptor(new ClrFunction(Engine, "atanh", Atanh, 1, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["atan2"] = new PropertyDescriptor(new ClrFunction(Engine, "atan2", Atan2, 2, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["ceil"] = new PropertyDescriptor(new ClrFunction(Engine, "ceil", Ceil, 1, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["cos"] = new PropertyDescriptor(new ClrFunction(Engine, "cos", Cos, 1, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["cosh"] = new PropertyDescriptor(new ClrFunction(Engine, "cosh", Cosh, 1, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["exp"] = new PropertyDescriptor(new ClrFunction(Engine, "exp", Exp, 1, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["expm1"] = new PropertyDescriptor(new ClrFunction(Engine, "expm1", Expm1, 1, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["floor"] = new PropertyDescriptor(new ClrFunction(Engine, "floor", Floor, 1, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["f16round"] = new PropertyDescriptor(new ClrFunction(Engine, "f16round", F16Round, 1, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["log"] = new PropertyDescriptor(new ClrFunction(Engine, "log", Log, 1, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["log1p"] = new PropertyDescriptor(new ClrFunction(Engine, "log1p", Log1p, 1, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["log2"] = new PropertyDescriptor(new ClrFunction(Engine, "log2", Log2, 1, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["log10"] = new PropertyDescriptor(new ClrFunction(Engine, "log10", Log10, 1, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["max"] = new PropertyDescriptor(new ClrFunction(Engine, "max", Max, 2, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["min"] = new PropertyDescriptor(new ClrFunction(Engine, "min", Min, 2, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["pow"] = new PropertyDescriptor(new ClrFunction(Engine, "pow", Pow, 2, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["random"] = new PropertyDescriptor(new ClrFunction(Engine, "random", Random, 0, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["round"] = new PropertyDescriptor(new ClrFunction(Engine, "round", Round, 1, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["fround"] = new PropertyDescriptor(new ClrFunction(Engine, "fround", Fround, 1, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["sin"] = new PropertyDescriptor(new ClrFunction(Engine, "sin", Sin, 1, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["sinh"] = new PropertyDescriptor(new ClrFunction(Engine, "sinh", Sinh, 1, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["sqrt"] = new PropertyDescriptor(new ClrFunction(Engine, "sqrt", Sqrt, 1, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["tan"] = new PropertyDescriptor(new ClrFunction(Engine, "tan", Tan, 1, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["tanh"] = new PropertyDescriptor(new ClrFunction(Engine, "tanh", Tanh, 1, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["trunc"] = new PropertyDescriptor(new ClrFunction(Engine, "trunc", Truncate, 1, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["sign"] = new PropertyDescriptor(new ClrFunction(Engine, "sign", Sign, 1, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["cbrt"] = new PropertyDescriptor(new ClrFunction(Engine, "cbrt", Cbrt, 1, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["hypot"] = new PropertyDescriptor(new ClrFunction(Engine, "hypot", Hypot, 2, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["imul"] = new PropertyDescriptor(new ClrFunction(Engine, "imul", Imul, 2, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["clz32"] = new PropertyDescriptor(new ClrFunction(Engine, "clz32", Clz32, 1, PropertyFlag.Configurable), PropertyFlag.NonEnumerable),
+                ["E"] = new PropertyDescriptor(System.Math.E, PropertyFlag.AllForbidden),
+                ["LN10"] = new PropertyDescriptor(System.Math.Log(10), PropertyFlag.AllForbidden),
+                ["LN2"] = new PropertyDescriptor(System.Math.Log(2), PropertyFlag.AllForbidden),
+                ["LOG2E"] = new PropertyDescriptor(System.Math.Log(System.Math.E, 2), PropertyFlag.AllForbidden),
+                ["LOG10E"] = new PropertyDescriptor(System.Math.Log(System.Math.E, 10), PropertyFlag.AllForbidden),
+                ["PI"] = new PropertyDescriptor(System.Math.PI, PropertyFlag.AllForbidden),
+                ["SQRT1_2"] = new PropertyDescriptor(System.Math.Sqrt(0.5), PropertyFlag.AllForbidden),
+                ["SQRT2"] = new PropertyDescriptor(System.Math.Sqrt(2), PropertyFlag.AllForbidden),
             };
             };
             SetProperties(properties);
             SetProperties(properties);
 
 
@@ -841,8 +842,35 @@ namespace Jint.Native.Math
 
 
         private static JsValue Fround(JsValue thisObject, JsValue[] arguments)
         private static JsValue Fround(JsValue thisObject, JsValue[] arguments)
         {
         {
-            var x = TypeConverter.ToNumber(arguments.At(0));
-            return (double) (float) x;
+            var x = arguments.At(0);
+            var n = TypeConverter.ToNumber(x);
+            return (double) (float) n;
+        }
+
+        /// <summary>
+        /// https://tc39.es/proposal-float16array/#sec-math.f16round
+        /// </summary>
+        private static JsValue F16Round(JsValue thisObject, JsValue[] arguments)
+        {
+#if SUPPORTS_HALF
+            var x = arguments.At(0);
+            var n = TypeConverter.ToNumber(x);
+
+            if (double.IsNaN(n))
+            {
+                return JsNumber.DoubleNaN;
+            }
+
+            if (double.IsInfinity(n) || NumberInstance.IsPositiveZero(n) || NumberInstance.IsNegativeZero(n))
+            {
+                return x;
+            }
+
+            return (double) (Half) n;
+#else
+            ExceptionHelper.ThrowNotImplementedException("Float16/Half type is not supported in this build");
+            return default;
+#endif
         }
         }
 
 
         private static JsValue Sin(JsValue thisObject, JsValue[] arguments)
         private static JsValue Sin(JsValue thisObject, JsValue[] arguments)

+ 34 - 11
Jint/Native/TypedArray/TypedArrayConstructor.Types.cs

@@ -14,7 +14,7 @@ namespace Jint.Native.TypedArray
 
 
         public JsTypedArray Construct(sbyte[] values)
         public JsTypedArray Construct(sbyte[] values)
         {
         {
-            var array = (JsTypedArray) base.Construct(new JsValue[] { values.Length }, this);
+            var array = (JsTypedArray) base.Construct([values.Length], this);
             FillTypedArrayInstance(array, values);
             FillTypedArrayInstance(array, values);
             return array;
             return array;
         }
         }
@@ -32,7 +32,7 @@ namespace Jint.Native.TypedArray
 
 
         public JsTypedArray Construct(byte[] values)
         public JsTypedArray Construct(byte[] values)
         {
         {
-            var array = (JsTypedArray) base.Construct(new JsValue[] { values.Length }, this);
+            var array = (JsTypedArray) base.Construct([values.Length], this);
             FillTypedArrayInstance(array, values);
             FillTypedArrayInstance(array, values);
             return array;
             return array;
         }
         }
@@ -50,7 +50,7 @@ namespace Jint.Native.TypedArray
 
 
         public JsTypedArray Construct(byte[] values)
         public JsTypedArray Construct(byte[] values)
         {
         {
-            var array = (JsTypedArray) base.Construct(new JsValue[] { values.Length }, this);
+            var array = (JsTypedArray) base.Construct([values.Length], this);
             FillTypedArrayInstance(array, values);
             FillTypedArrayInstance(array, values);
             return array;
             return array;
         }
         }
@@ -68,7 +68,7 @@ namespace Jint.Native.TypedArray
 
 
         public JsTypedArray Construct(short[] values)
         public JsTypedArray Construct(short[] values)
         {
         {
-            var array = (JsTypedArray) base.Construct(new JsValue[] { values.Length }, this);
+            var array = (JsTypedArray) base.Construct([values.Length], this);
             FillTypedArrayInstance(array, values);
             FillTypedArrayInstance(array, values);
             return array;
             return array;
         }
         }
@@ -86,7 +86,7 @@ namespace Jint.Native.TypedArray
 
 
         public JsTypedArray Construct(ushort[] values)
         public JsTypedArray Construct(ushort[] values)
         {
         {
-            var array = (JsTypedArray) base.Construct(new JsValue[] { values.Length }, this);
+            var array = (JsTypedArray) base.Construct([values.Length], this);
             FillTypedArrayInstance(array, values);
             FillTypedArrayInstance(array, values);
             return array;
             return array;
         }
         }
@@ -104,7 +104,7 @@ namespace Jint.Native.TypedArray
 
 
         public JsTypedArray Construct(int[] values)
         public JsTypedArray Construct(int[] values)
         {
         {
-            var array = (JsTypedArray) base.Construct(new JsValue[] { values.Length }, this);
+            var array = (JsTypedArray) base.Construct([values.Length], this);
             FillTypedArrayInstance(array, values);
             FillTypedArrayInstance(array, values);
             return array;
             return array;
         }
         }
@@ -122,12 +122,35 @@ namespace Jint.Native.TypedArray
 
 
         public JsTypedArray Construct(uint[] values)
         public JsTypedArray Construct(uint[] values)
         {
         {
-            var array = (JsTypedArray) base.Construct(new JsValue[] { values.Length }, this);
+            var array = (JsTypedArray) base.Construct([values.Length], this);
             FillTypedArrayInstance(array, values);
             FillTypedArrayInstance(array, values);
             return array;
             return array;
         }
         }
     }
     }
 
 
+    public sealed class Float16ArrayConstructor : TypedArrayConstructor
+    {
+        internal Float16ArrayConstructor(
+            Engine engine,
+            Realm realm,
+            IntrinsicTypedArrayConstructor functionPrototype,
+            IntrinsicTypedArrayPrototype objectPrototype) : base(engine, realm, functionPrototype, objectPrototype, TypedArrayElementType.Float16)
+        {
+        }
+
+#if SUPPORTS_HALF
+        public JsTypedArray Construct(Half[] values)
+        {
+            var array = (JsTypedArray) base.Construct([values.Length], this);
+            for (var i = 0; i < values.Length; ++i)
+            {
+                array.DoIntegerIndexedElementSet(i, values[i]);
+            }
+            return array;
+        }
+#endif
+    }
+
     public sealed class Float32ArrayConstructor : TypedArrayConstructor
     public sealed class Float32ArrayConstructor : TypedArrayConstructor
     {
     {
         internal Float32ArrayConstructor(
         internal Float32ArrayConstructor(
@@ -140,7 +163,7 @@ namespace Jint.Native.TypedArray
 
 
         public JsTypedArray Construct(float[] values)
         public JsTypedArray Construct(float[] values)
         {
         {
-            var array = (JsTypedArray) base.Construct(new JsValue[] { values.Length }, this);
+            var array = (JsTypedArray) base.Construct([values.Length], this);
             FillTypedArrayInstance(array, values);
             FillTypedArrayInstance(array, values);
             return array;
             return array;
         }
         }
@@ -158,7 +181,7 @@ namespace Jint.Native.TypedArray
 
 
         public JsTypedArray Construct(double[] values)
         public JsTypedArray Construct(double[] values)
         {
         {
-            var array = (JsTypedArray) base.Construct(new JsValue[] { values.Length }, this);
+            var array = (JsTypedArray) base.Construct([values.Length], this);
             FillTypedArrayInstance(array, values);
             FillTypedArrayInstance(array, values);
             return array;
             return array;
         }
         }
@@ -176,7 +199,7 @@ namespace Jint.Native.TypedArray
 
 
         public JsTypedArray Construct(long[] values)
         public JsTypedArray Construct(long[] values)
         {
         {
-            var array = (JsTypedArray) base.Construct(new JsValue[] { values.Length }, this);
+            var array = (JsTypedArray) base.Construct([values.Length], this);
             FillTypedArrayInstance(array, values);
             FillTypedArrayInstance(array, values);
             return array;
             return array;
         }
         }
@@ -194,7 +217,7 @@ namespace Jint.Native.TypedArray
 
 
         public JsTypedArray Construct(ulong[] values)
         public JsTypedArray Construct(ulong[] values)
         {
         {
-            var array = (JsTypedArray) base.Construct(new JsValue[] { values.Length }, this);
+            var array = (JsTypedArray) base.Construct([values.Length], this);
             FillTypedArrayInstance(array, values);
             FillTypedArrayInstance(array, values);
             return array;
             return array;
         }
         }

+ 2 - 1
Jint/Native/TypedArray/TypedArrayConstructor.cs

@@ -51,12 +51,13 @@ namespace Jint.Native.TypedArray
 
 
             Func<Intrinsics, ObjectInstance> proto = _arrayElementType switch
             Func<Intrinsics, ObjectInstance> proto = _arrayElementType switch
             {
             {
+                TypedArrayElementType.Float16 => static intrinsics => intrinsics.Float16Array.PrototypeObject,
                 TypedArrayElementType.Float32 => static intrinsics => intrinsics.Float32Array.PrototypeObject,
                 TypedArrayElementType.Float32 => static intrinsics => intrinsics.Float32Array.PrototypeObject,
+                TypedArrayElementType.Float64 => static intrinsics => intrinsics.Float64Array.PrototypeObject,
                 TypedArrayElementType.Int8 => static intrinsics => intrinsics.Int8Array.PrototypeObject,
                 TypedArrayElementType.Int8 => static intrinsics => intrinsics.Int8Array.PrototypeObject,
                 TypedArrayElementType.Int16 => static intrinsics => intrinsics.Int16Array.PrototypeObject,
                 TypedArrayElementType.Int16 => static intrinsics => intrinsics.Int16Array.PrototypeObject,
                 TypedArrayElementType.Int32 => static intrinsics => intrinsics.Int32Array.PrototypeObject,
                 TypedArrayElementType.Int32 => static intrinsics => intrinsics.Int32Array.PrototypeObject,
                 TypedArrayElementType.BigInt64 => static intrinsics => intrinsics.BigInt64Array.PrototypeObject,
                 TypedArrayElementType.BigInt64 => static intrinsics => intrinsics.BigInt64Array.PrototypeObject,
-                TypedArrayElementType.Float64 => static intrinsics => intrinsics.Float64Array.PrototypeObject,
                 TypedArrayElementType.Uint8 => static intrinsics => intrinsics.Uint8Array.PrototypeObject,
                 TypedArrayElementType.Uint8 => static intrinsics => intrinsics.Uint8Array.PrototypeObject,
                 TypedArrayElementType.Uint8C => static intrinsics => intrinsics.Uint8ClampedArray.PrototypeObject,
                 TypedArrayElementType.Uint8C => static intrinsics => intrinsics.Uint8ClampedArray.PrototypeObject,
                 TypedArrayElementType.Uint16 => static intrinsics => intrinsics.Uint16Array.PrototypeObject,
                 TypedArrayElementType.Uint16 => static intrinsics => intrinsics.Uint16Array.PrototypeObject,

+ 6 - 0
Jint/Native/TypedArray/TypedArrayElementType.cs

@@ -8,7 +8,10 @@ namespace Jint.Native.TypedArray
         Int8,
         Int8,
         Int16,
         Int16,
         Int32,
         Int32,
+
         BigInt64,
         BigInt64,
+
+        Float16,
         Float32,
         Float32,
         Float64,
         Float64,
 
 
@@ -34,6 +37,7 @@ namespace Jint.Native.TypedArray
                 TypedArrayElementType.Uint32 => 4,
                 TypedArrayElementType.Uint32 => 4,
                 TypedArrayElementType.BigInt64 => 8,
                 TypedArrayElementType.BigInt64 => 8,
                 TypedArrayElementType.BigUint64 => 8,
                 TypedArrayElementType.BigUint64 => 8,
+                TypedArrayElementType.Float16 => 2,
                 TypedArrayElementType.Float32 => 4,
                 TypedArrayElementType.Float32 => 4,
                 TypedArrayElementType.Float64 => 8,
                 TypedArrayElementType.Float64 => 8,
                 _ => 0
                 _ => 0
@@ -53,6 +57,7 @@ namespace Jint.Native.TypedArray
                 TypedArrayElementType.Uint32 => "Uint32Array",
                 TypedArrayElementType.Uint32 => "Uint32Array",
                 TypedArrayElementType.BigInt64 => "BigInt64Array",
                 TypedArrayElementType.BigInt64 => "BigInt64Array",
                 TypedArrayElementType.BigUint64 => "BigUint64Array",
                 TypedArrayElementType.BigUint64 => "BigUint64Array",
+                TypedArrayElementType.Float16 => "Float16Array",
                 TypedArrayElementType.Float32 => "Float32Array",
                 TypedArrayElementType.Float32 => "Float32Array",
                 TypedArrayElementType.Float64 => "Float64Array",
                 TypedArrayElementType.Float64 => "Float64Array",
                 _ => ""
                 _ => ""
@@ -72,6 +77,7 @@ namespace Jint.Native.TypedArray
                 TypedArrayElementType.Uint32 => intrinsics.Uint32Array,
                 TypedArrayElementType.Uint32 => intrinsics.Uint32Array,
                 TypedArrayElementType.BigInt64 => intrinsics.BigInt64Array,
                 TypedArrayElementType.BigInt64 => intrinsics.BigInt64Array,
                 TypedArrayElementType.BigUint64 => intrinsics.BigUint64Array,
                 TypedArrayElementType.BigUint64 => intrinsics.BigUint64Array,
+                TypedArrayElementType.Float16 => intrinsics.Float16Array,
                 TypedArrayElementType.Float32 => intrinsics.Float32Array,
                 TypedArrayElementType.Float32 => intrinsics.Float32Array,
                 TypedArrayElementType.Float64 => intrinsics.Float64Array,
                 TypedArrayElementType.Float64 => intrinsics.Float64Array,
                 _ => null!
                 _ => null!

+ 14 - 0
Jint/Native/TypedArray/TypedArrayValue.cs

@@ -10,6 +10,13 @@ namespace Jint.Native.TypedArray;
 [StructLayout(LayoutKind.Auto)]
 [StructLayout(LayoutKind.Auto)]
 internal readonly record struct TypedArrayValue(Types Type, double DoubleValue, BigInteger BigInteger) : IConvertible
 internal readonly record struct TypedArrayValue(Types Type, double DoubleValue, BigInteger BigInteger) : IConvertible
 {
 {
+#if SUPPORTS_HALF
+    public static implicit operator TypedArrayValue(Half value)
+    {
+        return new TypedArrayValue(Types.Number, (double) value, default);
+    }
+#endif
+
     public static implicit operator TypedArrayValue(double value)
     public static implicit operator TypedArrayValue(double value)
     {
     {
         return new TypedArrayValue(Types.Number, value, default);
         return new TypedArrayValue(Types.Number, value, default);
@@ -154,6 +161,13 @@ internal readonly record struct TypedArrayValue(Types Type, double DoubleValue,
             return BigInteger;
             return BigInteger;
         }
         }
 
 
+#if SUPPORTS_HALF
+        if (conversionType == typeof(Half) && Type == Types.Number)
+        {
+            return (Half) DoubleValue;
+        }
+#endif
+
         ExceptionHelper.ThrowNotImplementedException();
         ExceptionHelper.ThrowNotImplementedException();
         return default;
         return default;
     }
     }

+ 4 - 0
Jint/Runtime/Intrinsics.cs

@@ -98,6 +98,7 @@ namespace Jint.Runtime
         private Uint32ArrayConstructor? _uint32Array;
         private Uint32ArrayConstructor? _uint32Array;
         private BigInt64ArrayConstructor? _bigInt64Array;
         private BigInt64ArrayConstructor? _bigInt64Array;
         private BigUint64ArrayConstructor? _bigUint64Array;
         private BigUint64ArrayConstructor? _bigUint64Array;
+        private Float16ArrayConstructor? _float16Array;
         private Float32ArrayConstructor? _float32Array;
         private Float32ArrayConstructor? _float32Array;
         private Float64ArrayConstructor? _float64Array;
         private Float64ArrayConstructor? _float64Array;
 
 
@@ -176,6 +177,9 @@ namespace Jint.Runtime
         public BigUint64ArrayConstructor BigUint64Array =>
         public BigUint64ArrayConstructor BigUint64Array =>
             _bigUint64Array ??= new BigUint64ArrayConstructor(_engine, _realm, TypedArray, TypedArray.PrototypeObject);
             _bigUint64Array ??= new BigUint64ArrayConstructor(_engine, _realm, TypedArray, TypedArray.PrototypeObject);
 
 
+        public Float16ArrayConstructor Float16Array =>
+            _float16Array ??= new Float16ArrayConstructor(_engine, _realm, TypedArray, TypedArray.PrototypeObject);
+
         public Float32ArrayConstructor Float32Array =>
         public Float32ArrayConstructor Float32Array =>
             _float32Array ??= new Float32ArrayConstructor(_engine, _realm, TypedArray, TypedArray.PrototypeObject);
             _float32Array ??= new Float32ArrayConstructor(_engine, _realm, TypedArray, TypedArray.PrototypeObject);
 
 

+ 1 - 0
README.md

@@ -122,6 +122,7 @@ and many more.
 
 
 - ✔ `ArrayBuffer.prototype.transfer`
 - ✔ `ArrayBuffer.prototype.transfer`
 - ✔ Array Grouping - `Object.groupBy` and `Map.groupBy`
 - ✔ Array Grouping - `Object.groupBy` and `Map.groupBy`
+- ✔ Float16Array (Jint v4, requires NET 6 target or higher)
 - ✔ Import attributes
 - ✔ Import attributes
 - ✔ JSON modules
 - ✔ JSON modules
 - ✔ `Promise.withResolvers`
 - ✔ `Promise.withResolvers`