Skip to content

Commit

Permalink
ArrayBuffer and DataView
Browse files Browse the repository at this point in the history
  • Loading branch information
lahma committed Jul 15, 2021
1 parent 99d05af commit 0e9e586
Show file tree
Hide file tree
Showing 25 changed files with 1,320 additions and 102 deletions.
15 changes: 15 additions & 0 deletions Jint.Tests.Test262/BuiltIns/ArrayBufferTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Xunit;

namespace Jint.Tests.Test262.BuiltIns
{
public class ArrayBufferTests : Test262Test
{
[Theory(DisplayName = "built-ins\\ArrayBuffer")]
[MemberData(nameof(SourceFiles), "built-ins\\ArrayBuffer", false)]
[MemberData(nameof(SourceFiles), "built-ins\\ArrayBuffer", true, Skip = "Skipped")]
protected void RunTest(SourceFile sourceFile)
{
RunTestInternal(sourceFile);
}
}
}
15 changes: 15 additions & 0 deletions Jint.Tests.Test262/BuiltIns/DataViewTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Xunit;

namespace Jint.Tests.Test262.BuiltIns
{
public class DataViewTests : Test262Test
{
[Theory(DisplayName = "built-ins\\DataView")]
[MemberData(nameof(SourceFiles), "built-ins\\DataView", false)]
[MemberData(nameof(SourceFiles), "built-ins\\DataView", true, Skip = "Skipped")]
protected void RunTest(SourceFile sourceFile)
{
RunTestInternal(sourceFile);
}
}
}
15 changes: 0 additions & 15 deletions Jint.Tests.Test262/BuiltIns/StringIteratorPrototypeTests.cs

This file was deleted.

8 changes: 8 additions & 0 deletions Jint.Tests.Test262/BuiltIns/StringTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,13 @@ protected void String(SourceFile sourceFile)
{
RunTestInternal(sourceFile);
}

[Theory(DisplayName = "built-ins\\StringIteratorPrototype")]
[MemberData(nameof(SourceFiles), "built-ins\\StringIteratorPrototype", false)]
[MemberData(nameof(SourceFiles), "built-ins\\StringIteratorPrototype", true, Skip = "Skipped")]
protected void StringIteratorPrototype(SourceFile sourceFile)
{
RunTestInternal(sourceFile);
}
}
}
51 changes: 32 additions & 19 deletions Jint.Tests.Test262/Test262Test.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
using System.Text.RegularExpressions;
using Esprima;
using Esprima.Ast;
using Jint.Native;
using Jint.Native.ArrayBuffer;
using Jint.Runtime;
using Jint.Runtime.Descriptors;
using Jint.Runtime.Interop;
Expand Down Expand Up @@ -67,7 +69,8 @@ static Test262Test()
"wellKnownIntrinsicObjects.js",
"fnGlobalObject.js",
"testTypedArray.js",
"detachArrayBuffer.js"
"detachArrayBuffer.js",
"byteConversionValues.js"
};

Sources = new Dictionary<string, Script>(files.Length);
Expand Down Expand Up @@ -126,6 +129,14 @@ protected void RunTestCode(string fileName, string code, bool strict)
return realm.GlobalObject;
}), true, true, true));

o.FastSetProperty("detachArrayBuffer", new PropertyDescriptor(new ClrFunctionInstance(engine, "detachArrayBuffer",
(thisObj, args) =>
{
var buffer = (ArrayBufferInstance) args.At(0);
buffer.DetachArrayBuffer();
return JsValue.Undefined;
}), true, true, true));

engine.SetValue("$262", o);

var includes = Regex.Match(code, @"includes: \[(.+?)\]");
Expand Down Expand Up @@ -282,6 +293,26 @@ public static IEnumerable<object[]> SourceFiles(string pathPrefix, bool skipped)
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";
break;
case "resizable-arraybuffer":
skip = true;
reason = "resizable-arraybuffer not implemented";
break;
case "TypedArray.prototype.at":
skip = true;
reason = "TypedArray.prototype.at not implemented";
break;
}
}
}
Expand Down Expand Up @@ -310,30 +341,12 @@ 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/Promise"))
{
skip = true;
reason = "Promise not implemented";
}

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

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

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

if (name.StartsWith("language/statements/class/subclass/builtins.js"))
{
skip = true;
Expand Down
4 changes: 0 additions & 4 deletions Jint.Tests.Test262/test/skipped.json
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,6 @@
"source": "built-ins/Proxy/enumerate/removed-does-not-trigger.js",
"reason": "for-of not implemented"
},
{
"source": "built-ins/Array/from/items-is-arraybuffer.js",
"reason": "ArrayBuffer not implemented"
},
{
"source": "built-ins/Array/prototype/concat/Array.prototype.concat_large-typed-array.js",
"reason": "Uint8Array not implemented"
Expand Down
4 changes: 3 additions & 1 deletion Jint/Native/Array/ArrayInstance.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ public ArrayInstance(Engine engine, Dictionary<uint, PropertyDescriptor> items)

public override bool IsArrayLike => true;

public override bool IsArray() => true;

internal override bool HasOriginalIterator
=> ReferenceEquals(Get(GlobalSymbolRegistry.Iterator), _engine.Realm.Intrinsics.Array.PrototypeObject._originalIteratorFunction);

Expand Down Expand Up @@ -419,7 +421,7 @@ public override void RemoveOwnProperty(JsValue p)
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool IsArrayIndex(JsValue p, out uint index)
internal static bool IsArrayIndex(JsValue p, out uint index)
{
if (p is JsNumber number)
{
Expand Down
2 changes: 1 addition & 1 deletion Jint/Native/Array/ArrayPrototype.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1263,7 +1263,7 @@ private JsValue Concat(JsValue thisObj, JsValue[] arguments)
return a;
}

private JsValue ToString(JsValue thisObj, JsValue[] arguments)
internal JsValue ToString(JsValue thisObj, JsValue[] arguments)
{
var array = TypeConverter.ToObject(_realm, thisObj);

Expand Down
95 changes: 95 additions & 0 deletions Jint/Native/ArrayBuffer/ArrayBufferConstructor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
using Jint.Collections;
using Jint.Native.DataView;
using Jint.Native.Function;
using Jint.Native.Object;
using Jint.Native.Symbol;
using Jint.Runtime;
using Jint.Runtime.Descriptors;
using Jint.Runtime.Interop;

namespace Jint.Native.ArrayBuffer
{
/// <summary>
/// https://tc39.es/ecma262/#sec-properties-of-the-arraybuffer-constructor
/// </summary>
public sealed class ArrayBufferConstructor : FunctionInstance, IConstructor
{
private static readonly JsString _functionName = new("ArrayBuffer");

internal ArrayBufferConstructor(
Engine engine,
Realm realm,
FunctionPrototype functionPrototype,
ObjectPrototype objectPrototype)
: base(engine, realm, _functionName)
{
_prototype = functionPrototype;
PrototypeObject = new ArrayBufferPrototype(engine, realm, this, objectPrototype);
_length = new PropertyDescriptor(1, PropertyFlag.Configurable);
_prototypeDescriptor = new PropertyDescriptor(PrototypeObject, PropertyFlag.AllForbidden);
}

public ArrayBufferPrototype PrototypeObject { get; }

protected override void Initialize()
{
const PropertyFlag lengthFlags = PropertyFlag.Configurable;
var properties = new PropertyDictionary(1, checkExistingKeys: false)
{
["isView"] = new PropertyDescriptor(new PropertyDescriptor(new ClrFunctionInstance(Engine, "isView", IsView, 1, lengthFlags), PropertyFlag.Configurable | PropertyFlag.Writable)),
};
SetProperties(properties);

var symbols = new SymbolDictionary(1)
{
[GlobalSymbolRegistry.Species] = new GetSetPropertyDescriptor(get: new ClrFunctionInstance(Engine, "get [Symbol.species]", Species, 0, lengthFlags), set: Undefined,PropertyFlag.Configurable),
};
SetSymbols(symbols);
}

/// <summary>
/// https://tc39.es/ecma262/#sec-arraybuffer.isview
/// </summary>
private static JsValue IsView(JsValue thisObject, JsValue[] arguments)
{
var arg = arguments.At(0);
return arg is DataViewInstance;
}

/// <summary>
/// https://tc39.es/ecma262/#sec-get-arraybuffer-@@species
/// </summary>
private static JsValue Species(JsValue thisObject, JsValue[] arguments)
{
return thisObject;
}

public override JsValue Call(JsValue thisObject, JsValue[] arguments)
{
ExceptionHelper.ThrowTypeError(_realm, "Constructor ArrayBuffer requires 'new'");
return Undefined;
}

public ObjectInstance Construct(JsValue[] arguments, JsValue newTarget)
{
if (newTarget.IsUndefined())
{
ExceptionHelper.ThrowTypeError(_realm);
}

var byteLength = TypeConverter.ToIndex(_realm, arguments.At(0));
return AllocateArrayBuffer(newTarget, byteLength);
}

internal ArrayBufferInstance AllocateArrayBuffer(JsValue constructor, uint byteLength)
{
var obj = OrdinaryCreateFromConstructor(
constructor,
static intrinsics => intrinsics.ArrayBuffer.PrototypeObject,
static (engine, realm, state) => new ArrayBufferInstance(engine, (uint) ((JsNumber) state)._value),
JsNumber.Create(byteLength));

return obj;
}
}
}

0 comments on commit 0e9e586

Please sign in to comment.