Skip to content

Commit

Permalink
Typed arrays (#925)
Browse files Browse the repository at this point in the history
  • Loading branch information
lahma authored Jul 17, 2021
1 parent 7080fdf commit 1a9cd0e
Show file tree
Hide file tree
Showing 47 changed files with 3,118 additions and 326 deletions.
2 changes: 1 addition & 1 deletion Jint.Benchmark/Jint.Benchmark.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
<ProjectReference Include="..\Jint\Jint.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.12.1" />
<PackageReference Include="BenchmarkDotNet" Version="0.13.0" />
<PackageReference Include="Jurassic" Version="3.1.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="NiL.JS.NetCore" Version="2.5.1419" />
Expand Down
98 changes: 98 additions & 0 deletions Jint.Benchmark/TypedArrayBenchmark.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
using BenchmarkDotNet.Attributes;

namespace Jint.Benchmark
{
[MemoryDiagnoser]
public class TypedArrayBenchmark
{
private const string script = @"
var testArray = new Int32Array([29, 27, 28, 838, 22, 2882, 2, 93, 84, 74, 7, 933, 3754, 3874, 22838, 38464, 3837, 82424, 2927, 2625, 63, 27, 28, 838, 22, 2882, 2, 93, 84, 74, 7, 933, 3754, 3874, 22838, 38464, 3837, 82424, 2927, 2625, 63, 27, 28, 838, 22, 2882, 2, 93, 84, 74, 7, 933, 3754, 3874, 22838, 38464, 3837, 82424, 2927, 2625, 63, 27, 28, 838, 22, 2882, 2, 93, 84, 74, 7, 933, 3754, 3874, 22838, 38464, 3837, 82424, 2927, 2625, 63]);
";

private Engine engine;


[GlobalSetup]
public void Setup()
{
engine = new Engine();
engine.Execute(script);
}

[Params(100)]
public int N { get; set; }

[Benchmark]
public void Slice()
{
for (var i = 0; i < N; ++i)
{
engine.Execute("testArray.slice();");
}
}

[Benchmark]
public void Concat()
{
// tests conversion performance as TypedArray does not have concat
for (var i = 0; i < N; ++i)
{
engine.Execute("[].concat(testArray);");
}
}

[Benchmark]
public void Index()
{
for (var i = 0; i < N; ++i)
{
engine.Execute(@"
var obj2 = new Int32Array(testArray.length);
for (var i = 0, l = testArray.length; i < l; i++) {
obj2[i] = testArray[i];
}
");
}
}

[Benchmark]
public void Map()
{
for (var i = 0; i < N; ++i)
{
engine.Execute(@"
var obj2 = testArray.map(function(i) {
return i;
});
");
}
}

[Benchmark]
public void Apply()
{
for (var i = 0; i < N; ++i)
{
engine.Execute("Array.apply(undefined, testArray);");
}
}

[Benchmark]
public void JsonStringifyParse()
{
for (var i = 0; i < N; ++i)
{
engine.Execute("JSON.parse(JSON.stringify(testArray));");
}
}

[Benchmark]
public void FilterWithNumber()
{
for (var i = 0; i < N; ++i)
{
engine.Execute("testArray.filter(function(i) { return i > 55; });");
}
}
}
}
2 changes: 1 addition & 1 deletion Jint.Tests.CommonScripts/Jint.Tests.CommonScripts.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<ProjectReference Include="..\Jint\Jint.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.analyzers" Version="0.10.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
Expand Down
2 changes: 1 addition & 1 deletion Jint.Tests.Ecma/Jint.Tests.Ecma.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<ProjectReference Include="..\Jint\Jint.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.analyzers" Version="0.10.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3" />
Expand Down
23 changes: 23 additions & 0 deletions Jint.Tests.Test262/BuiltIns/TypedArrayTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using Xunit;

namespace Jint.Tests.Test262.BuiltIns
{
public class TypedArrayTests : Test262Test
{
[Theory(DisplayName = "built-ins\\TypedArray")]
[MemberData(nameof(SourceFiles), "built-ins\\TypedArray", false)]
[MemberData(nameof(SourceFiles), "built-ins\\TypedArray", true, Skip = "Skipped")]
protected void TypedArray(SourceFile sourceFile)
{
RunTestInternal(sourceFile);
}

[Theory(DisplayName = "built-ins\\TypedArrayConstructors")]
[MemberData(nameof(SourceFiles), "built-ins\\TypedArrayConstructors", false)]
[MemberData(nameof(SourceFiles), "built-ins\\TypedArrayConstructors", true, Skip = "Skipped")]
protected void TypedArrayConstructors(SourceFile sourceFile)
{
RunTestInternal(sourceFile);
}
}
}
2 changes: 1 addition & 1 deletion Jint.Tests.Test262/Jint.Tests.Test262.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<ProjectReference Include="..\Jint\Jint.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.analyzers" Version="0.10.0" />
Expand Down
32 changes: 0 additions & 32 deletions Jint.Tests.Test262/Test262Test.cs
Original file line number Diff line number Diff line change
Expand Up @@ -261,10 +261,6 @@ public static IEnumerable<object[]> SourceFiles(string pathPrefix, bool skipped)
skip = true;
reason = "private/public class fields not implemented in esprima";
break;
case "super":
skip = true;
reason = "super not implemented";
break;
case "String.prototype.replaceAll":
skip = true;
reason = "not in spec yet";
Expand All @@ -285,22 +281,6 @@ public static IEnumerable<object[]> SourceFiles(string pathPrefix, bool skipped)
skip = true;
reason = "regexp-lookbehind not implemented";
break;
case "TypedArray":
skip = true;
reason = "TypedArray not implemented";
break;
case "Int32Array":
skip = true;
reason = "Int32Array not implemented";
break;
case "Int8Array":
skip = true;
reason = "Int8Array not implemented";
break;
case "Uint8Array":
skip = true;
reason = "Uint8Array not implemented";
break;
case "SharedArrayBuffer":
skip = true;
reason = "SharedArrayBuffer not implemented";
Expand Down Expand Up @@ -341,18 +321,6 @@ public static IEnumerable<object[]> SourceFiles(string pathPrefix, bool skipped)
reason = "Unicode support and its special cases need more work";
}

if (name.StartsWith("language/statements/class/subclass/builtin-objects/TypedArray"))
{
skip = true;
reason = "TypedArray not implemented";
}

if (name.StartsWith("language/statements/class/subclass/builtins.js"))
{
skip = true;
reason = "Uint8Array not implemented";
}

if (name.StartsWith("built-ins/RegExp/CharacterClassEscapes/"))
{
skip = true;
Expand Down
16 changes: 8 additions & 8 deletions Jint.Tests.Test262/test/skipped.json
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,6 @@
"source": "built-ins/Proxy/enumerate/removed-does-not-trigger.js",
"reason": "for-of not implemented"
},
{
"source": "built-ins/Array/prototype/concat/Array.prototype.concat_large-typed-array.js",
"reason": "Uint8Array not implemented"
},
{
"source": "built-ins/Array/prototype/concat/Array.prototype.concat_small-typed-array.js",
"reason": "Uint8Array not implemented"
},
{
"source": "built-ins/Map/prototype/forEach/iterates-values-deleted-then-readded.js",
"reason": "delete/add detection not implemented for map iterator during iteration"
Expand Down Expand Up @@ -190,6 +182,10 @@
"source": "language/expressions/object/accessor-name-computed.js",
"reason": "yield not implemented"
},
{
"source": "built-ins/TypedArrayConstructors/ctors/object-arg/as-generator-iterable-returns.js",
"reason": "yield not implemented"
},
{
"source": "language/expressions/object/prop-dup-set-get-set.js",
"reason": "accessor not implemented"
Expand Down Expand Up @@ -274,6 +270,10 @@

// Esprima problems

{
"source": "language/expressions/object/method-definition/name-super-prop-param.js",
"reason": "Esprima problem"
},
{
"source": "language/expressions/optional-chaining/member-expression.js",
"reason": "Esprima problem"
Expand Down
2 changes: 1 addition & 1 deletion Jint.Tests/Jint.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Flurl.Http.Signed" Version="3.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.10.0" />
<PackageReference Include="MongoDB.Bson.signed" Version="2.11.2" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="xunit" Version="2.4.1" />
Expand Down
86 changes: 86 additions & 0 deletions Jint.Tests/Runtime/TypedArrayInteropTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
using Xunit;

namespace Jint.Tests.Runtime
{
public class TypedArrayInteropTests
{
[Fact]
public void CanInteropWithInt8()
{
var engine = new Engine();
engine.SetValue("testSubject", engine.Realm.Intrinsics.Int8Array.Construct(new sbyte[] { 42 }));
ValidateCreatedTypeArray(engine, "Int8Array");
}

[Fact]
public void CanInteropWithUint8()
{
var engine = new Engine();
engine.SetValue("testSubject", engine.Realm.Intrinsics.Uint8Array.Construct(new byte[] { 42 }));
ValidateCreatedTypeArray(engine, "Uint8Array");
}

[Fact]
public void CanInteropWithUint8Clamped()
{
var engine = new Engine();
engine.SetValue("testSubject", engine.Realm.Intrinsics.Uint8ClampedArray.Construct(new byte[] { 42 }));
ValidateCreatedTypeArray(engine, "Uint8ClampedArray");
}

[Fact]
public void CanInteropWithInt16()
{
var engine = new Engine();
engine.SetValue("testSubject", engine.Realm.Intrinsics.Int16Array.Construct(new short[] { 42 }));
ValidateCreatedTypeArray(engine, "Int16Array");
}

[Fact]
public void CanInteropWithUint16()
{
var engine = new Engine();
engine.SetValue("testSubject", engine.Realm.Intrinsics.Uint16Array.Construct(new ushort[] { 42 }));
ValidateCreatedTypeArray(engine, "Uint16Array");
}

[Fact]
public void CanInteropWithInt32()
{
var engine = new Engine();
engine.SetValue("testSubject", engine.Realm.Intrinsics.Int32Array.Construct(new int[] { 42 }));
ValidateCreatedTypeArray(engine, "Int32Array");
}

[Fact]
public void CanInteropWithUint32()
{
var engine = new Engine();
engine.SetValue("testSubject", engine.Realm.Intrinsics.Uint32Array.Construct(new uint[] { 42 }));
ValidateCreatedTypeArray(engine, "Uint32Array");
}

[Fact(Skip = "BigInt not implemented")]
public void CanInteropWithBigInt64()
{
var engine = new Engine();
engine.SetValue("testSubject", engine.Realm.Intrinsics.BigInt64Array.Construct(new long[] { 42 }));
ValidateCreatedTypeArray(engine, "BigInt64Array");
}

[Fact(Skip = "BigInt not implemented")]
public void CanInteropWithBigUint64()
{
var engine = new Engine();
engine.SetValue("testSubject", engine.Realm.Intrinsics.BigUint64Array.Construct(new ulong[] { 42 }));
ValidateCreatedTypeArray(engine, "BigUint64Array");
}

private static void ValidateCreatedTypeArray(Engine engine, string arrayName)
{
Assert.Equal(arrayName, engine.Evaluate("testSubject.constructor.name").AsString());
Assert.Equal(1, engine.Evaluate("testSubject.length").AsNumber());
Assert.Equal(42, engine.Evaluate("testSubject[0]").AsNumber());
}
}
}
2 changes: 1 addition & 1 deletion Jint/Engine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ internal JsValue GetValue(Reference reference, bool returnReferenceToPool)
{
var baseValue = reference.GetBase();

if (baseValue._type == InternalTypes.Undefined)
if (baseValue.IsUndefined())
{
if (_referenceResolver.TryUnresolvableReference(this, reference, out JsValue val))
{
Expand Down
5 changes: 1 addition & 4 deletions Jint/Jint.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Esprima" Version="2.0.0" />
<PackageReference Include="IsExternalInit" Version="1.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="IsExternalInit" Version="1.0.1" PrivateAssets="all" />
<PackageReference Include="Nullable" Version="1.3.0" PrivateAssets="all" />
</ItemGroup>
</Project>
Loading

0 comments on commit 1a9cd0e

Please sign in to comment.