Skip to content

Commit

Permalink
Harmonize iterator prototype intrinsics to follow spec
Browse files Browse the repository at this point in the history
  • Loading branch information
lahma committed Jul 20, 2021
1 parent e752354 commit bf2c8b8
Show file tree
Hide file tree
Showing 16 changed files with 364 additions and 310 deletions.
110 changes: 110 additions & 0 deletions Jint/Native/Array/ArrayIteratorPrototype.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
using System;
using Jint.Native.Iterator;
using Jint.Native.Object;
using Jint.Native.TypedArray;
using Jint.Runtime;

namespace Jint.Native.Array
{
internal class ArrayIteratorPrototype : IteratorPrototype
{
internal ArrayIteratorPrototype(
Engine engine,
Realm realm,
ObjectPrototype objectPrototype) : base(engine, realm, "Array Iterator", objectPrototype)
{
}

internal IteratorInstance Construct(ObjectInstance array, Func<Intrinsics, Prototype> prototypeSelector)
{
var instance = new ArrayLikeIterator(Engine, array, ArrayIteratorType.KeyAndValue)
{
_prototype = prototypeSelector(_realm.Intrinsics)
};

return instance;
}

internal IteratorInstance Construct(ObjectInstance array, ArrayIteratorType kind)
{
var instance = new ArrayLikeIterator(Engine, array, kind)
{
_prototype = this
};

return instance;
}

private sealed class ArrayLikeIterator : IteratorInstance
{
private readonly ArrayIteratorType _kind;
private readonly TypedArrayInstance _typedArray;
private readonly ArrayOperations _operations;
private uint _position;
private bool _closed;

public ArrayLikeIterator(Engine engine, ObjectInstance objectInstance, ArrayIteratorType kind) : base(engine)
{
_kind = kind;
_typedArray = objectInstance as TypedArrayInstance;
if (_typedArray is null)
{
_operations = ArrayOperations.For(objectInstance);
}

_position = 0;
}

public override bool TryIteratorStep(out ObjectInstance nextItem)
{
uint len;
if (_typedArray is not null)
{
_typedArray._viewedArrayBuffer.AssertNotDetached();
len = _typedArray.Length;
}
else
{
len = _operations.GetLength();
}

if (!_closed && _position < len)
{
JsValue value;
if (_typedArray is not null)
{
nextItem = _kind switch
{
ArrayIteratorType.Key => new ValueIteratorPosition(_engine, _position),
ArrayIteratorType.Value => new ValueIteratorPosition(_engine, _typedArray[(int) _position]),
_ => new KeyValueIteratorPosition(_engine, _position, _typedArray[(int) _position])
};
}
else
{
_operations.TryGetValue(_position, out value);
if (_kind == ArrayIteratorType.Key)
{
nextItem = new ValueIteratorPosition(_engine, _position);
}
else if (_kind == ArrayIteratorType.Value)
{
nextItem = new ValueIteratorPosition(_engine, value);
}
else
{
nextItem = new KeyValueIteratorPosition(_engine, _position, value);
}
}

_position++;
return true;
}

_closed = true;
nextItem = KeyValueIteratorPosition.Done;
return false;
}
}
}
}
6 changes: 3 additions & 3 deletions Jint/Native/Array/ArrayPrototype.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ private ObjectInstance Keys(JsValue thisObj, JsValue[] arguments)
{
if (thisObj is ObjectInstance oi && oi.IsArrayLike)
{
return _realm.Intrinsics.Iterator.CreateArrayLikeIterator(oi, ArrayIteratorType.Key);
return _realm.Intrinsics.ArrayIteratorPrototype.Construct(oi, ArrayIteratorType.Key);
}

ExceptionHelper.ThrowTypeError(_realm, "cannot construct iterator");
Expand All @@ -117,7 +117,7 @@ internal ObjectInstance Values(JsValue thisObj, JsValue[] arguments)
{
if (thisObj is ObjectInstance oi && oi.IsArrayLike)
{
return _realm.Intrinsics.Iterator.CreateArrayLikeIterator(oi, ArrayIteratorType.Value);
return _realm.Intrinsics.ArrayIteratorPrototype.Construct(oi, ArrayIteratorType.Value);
}

ExceptionHelper.ThrowTypeError(_realm, "cannot construct iterator");
Expand All @@ -128,7 +128,7 @@ private ObjectInstance Entries(JsValue thisObj, JsValue[] arguments)
{
if (thisObj is ObjectInstance oi && oi.IsArrayLike)
{
return _realm.Intrinsics.Iterator.CreateArrayLikeIterator(oi, ArrayIteratorType.KeyAndValue);
return _realm.Intrinsics.ArrayIteratorPrototype.Construct(oi, ArrayIteratorType.KeyAndValue);
}

ExceptionHelper.ThrowTypeError(_realm, "cannot construct iterator");
Expand Down
157 changes: 0 additions & 157 deletions Jint/Native/Iterator/IteratorConstructor.cs

This file was deleted.

0 comments on commit bf2c8b8

Please sign in to comment.