Skip to content

Commit f744a71

Browse files
committed
Implement Iterator Helpers
1 parent a3c7444 commit f744a71

File tree

7 files changed

+142
-20
lines changed

7 files changed

+142
-20
lines changed

Jint.Tests.Test262/Test262Harness.settings.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
"decorators",
1212
"explicit-resource-management",
1313
"import-defer",
14-
"iterator-helpers",
1514
"iterator-sequencing",
1615
"json-parse-with-source",
1716
"regexp-lookbehind",

Jint/Native/Global/GlobalObject.Properties.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public partial class GlobalObject
2828
private static readonly Key propertyInt16Array = "Int16Array";
2929
private static readonly Key propertyInt32Array = "Int32Array";
3030
private static readonly Key propertyInt8Array = "Int8Array";
31+
private static readonly Key propertyIterator = "Iterator";
3132
//private static readonly Key propertyIntl = "Intl";
3233
private static readonly Key propertyJSON = "JSON";
3334
private static readonly Key propertyMap = "Map";
@@ -105,6 +106,7 @@ protected override void Initialize()
105106
properties.AddDangerous(propertyInt32Array, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Int32Array, PropertyFlags));
106107
properties.AddDangerous(propertyInt8Array, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Int8Array, PropertyFlags));
107108
// TODO properties.AddDapropertygerous(propertyIntl, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Intl, propertyFlags));
109+
properties.AddDangerous(propertyIterator, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Iterator, PropertyFlags));
108110
properties.AddDangerous(propertyJSON, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Json, PropertyFlags));
109111
properties.AddDangerous(propertyMap, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Map, PropertyFlags));
110112
properties.AddDangerous(propertyMath, new LazyPropertyDescriptor<GlobalObject>(this, static global => global._realm.Intrinsics.Math, PropertyFlags));

Jint/Native/Iterator/IteratorPrototype.cs

Lines changed: 119 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Jint.Collections;
2+
using Jint.Native.Object;
23
using Jint.Native.Symbol;
34
using Jint.Runtime;
45
using Jint.Runtime.Descriptors;
@@ -14,20 +15,135 @@ internal class IteratorPrototype : Prototype
1415
internal IteratorPrototype(
1516
Engine engine,
1617
Realm realm,
17-
Prototype objectPrototype) : base(engine, realm)
18+
ObjectInstance objectPrototype) : base(engine, realm)
1819
{
1920
_prototype = objectPrototype;
2021
}
2122

2223
protected override void Initialize()
2324
{
24-
var symbols = new SymbolDictionary(1)
25+
var properties = new PropertyDictionary(12, checkExistingKeys: false)
2526
{
26-
[GlobalSymbolRegistry.Iterator] = new(new ClrFunction(Engine, "[Symbol.iterator]", ToIterator, 0, PropertyFlag.Configurable), true, false, true),
27+
[KnownKeys.Constructor] = new GetSetPropertyDescriptor(
28+
new ClrFunction(_engine, "Iterator.prototype.constructor", (_, _) => _engine.Intrinsics.Iterator),
29+
new ClrFunction(_engine, "Iterator.prototype.constructor", (_, _) =>
30+
{
31+
ExceptionHelper.ThrowTypeError(_realm);
32+
return Undefined;
33+
}),
34+
PropertyFlag.Configurable),
35+
["map"] = new(new ClrFunction(_engine, "map", Map, 1, PropertyFlag.Configurable), PropertyFlag.Writable | PropertyFlag.Configurable),
36+
["filter"] = new(new ClrFunction(_engine, "filter", Filter, 1, PropertyFlag.Configurable), PropertyFlag.Writable | PropertyFlag.Configurable),
37+
["take"] = new(new ClrFunction(_engine, "take", Take, 1, PropertyFlag.Configurable), PropertyFlag.Writable | PropertyFlag.Configurable),
38+
["drop"] = new(new ClrFunction(_engine, "drop", Drop, 1, PropertyFlag.Configurable), PropertyFlag.Writable | PropertyFlag.Configurable),
39+
["flatMap"] = new(new ClrFunction(_engine, "flatMap", FlatMap, 1, PropertyFlag.Configurable), PropertyFlag.Writable | PropertyFlag.Configurable),
40+
["reduce"] = new(new ClrFunction(_engine, "reduce", Reduce, 1, PropertyFlag.Configurable), PropertyFlag.Writable | PropertyFlag.Configurable),
41+
["toArray"] = new(new ClrFunction(_engine, "toArray", ToArray, 1, PropertyFlag.Configurable), PropertyFlag.Writable | PropertyFlag.Configurable),
42+
["forEach"] = new(new ClrFunction(_engine, "forEach", ForEach, 1, PropertyFlag.Configurable), PropertyFlag.Writable | PropertyFlag.Configurable),
43+
["some"] = new(new ClrFunction(_engine, "some", Some, 1, PropertyFlag.Configurable), PropertyFlag.Writable | PropertyFlag.Configurable),
44+
["evey"] = new(new ClrFunction(_engine, "every", Every, 1, PropertyFlag.Configurable), PropertyFlag.Writable | PropertyFlag.Configurable),
45+
["find"] = new(new ClrFunction(_engine, "find", Find, 1, PropertyFlag.Configurable), PropertyFlag.Writable | PropertyFlag.Configurable),
2746
};
47+
48+
SetProperties(properties);
49+
50+
var symbols = new SymbolDictionary(1) { [GlobalSymbolRegistry.Iterator] = new(new ClrFunction(Engine, "[Symbol.iterator]", ToIterator, 0, PropertyFlag.Configurable), true, false, true), };
2851
SetSymbols(symbols);
2952
}
3053

54+
private JsValue Map(JsValue thisObject, JsValue[] arguments)
55+
{
56+
if (thisObject is not ObjectInstance o)
57+
{
58+
ExceptionHelper.ThrowTypeError(_realm, "object must be an Object");
59+
return Undefined;
60+
}
61+
62+
var callable = GetCallable(arguments.At(0));
63+
var iterated = GetIteratorDirect(o);
64+
//var iterator = new iterao
65+
66+
var closure = () =>
67+
{
68+
//a. Let counter be 0.
69+
// b. Repeat,
70+
//i. Let value be ? IteratorStepValue(iterated).
71+
// ii. If value is done, return undefined.
72+
// iii. Let mapped be Completion(Call(mapper, undefined, « value, 𝔽(counter) »)).
73+
//iv. IfAbruptCloseIterator(mapped, iterated).
74+
// v. Let completion be Completion(Yield(mapped)).
75+
// vi. IfAbruptCloseIterator(completion, iterated).
76+
// vii. Set counter to counter + 1.
77+
};
78+
79+
var result = new SuperFoo(_engine, closure, iterated);
80+
return result;
81+
}
82+
83+
private static IteratorInstance.ObjectIterator GetIteratorDirect(ObjectInstance objectInstance) => new(objectInstance);
84+
85+
private sealed class SuperFoo : IteratorInstance
86+
{
87+
public SuperFoo(Engine engine, Action closure, IteratorInstance iterated) : base(engine)
88+
{
89+
}
90+
91+
public override bool TryIteratorStep(out ObjectInstance nextItem)
92+
{
93+
throw new NotImplementedException();
94+
}
95+
}
96+
97+
private JsValue Filter(JsValue thisObject, JsValue[] arguments)
98+
{
99+
return Undefined;
100+
}
101+
102+
private JsValue Take(JsValue thisObject, JsValue[] arguments)
103+
{
104+
return Undefined;
105+
}
106+
107+
private JsValue Drop(JsValue thisObject, JsValue[] arguments)
108+
{
109+
return Undefined;
110+
}
111+
112+
private JsValue FlatMap(JsValue thisObject, JsValue[] arguments)
113+
{
114+
return Undefined;
115+
}
116+
117+
private JsValue Reduce(JsValue thisObject, JsValue[] arguments)
118+
{
119+
return Undefined;
120+
}
121+
122+
private JsValue ToArray(JsValue thisObject, JsValue[] arguments)
123+
{
124+
return Undefined;
125+
}
126+
127+
private JsValue ForEach(JsValue thisObject, JsValue[] arguments)
128+
{
129+
return Undefined;
130+
}
131+
132+
private JsValue Some(JsValue thisObject, JsValue[] arguments)
133+
{
134+
return Undefined;
135+
}
136+
137+
private JsValue Every(JsValue thisObject, JsValue[] arguments)
138+
{
139+
return Undefined;
140+
}
141+
142+
private JsValue Find(JsValue thisObject, JsValue[] arguments)
143+
{
144+
return Undefined;
145+
}
146+
31147
private static JsValue ToIterator(JsValue thisObject, JsValue[] arguments)
32148
{
33149
return thisObject;

Jint/Native/JsValue.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,22 @@ internal bool InstanceofOperator(JsValue target)
302302
return target.OrdinaryHasInstance(this);
303303
}
304304

305+
internal static ICallable? GetMethod(Realm realm, JsValue v, JsValue p)
306+
{
307+
var jsValue = v.Get(p);
308+
if (jsValue.IsNullOrUndefined())
309+
{
310+
return null;
311+
}
312+
313+
var callable = jsValue as ICallable;
314+
if (callable is null)
315+
{
316+
ExceptionHelper.ThrowTypeError(realm, $"Value returned for property '{p}' of object is not a function");
317+
}
318+
return callable;
319+
}
320+
305321
public override string ToString()
306322
{
307323
return "None";

Jint/Native/Object/ObjectInstance.cs

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1359,22 +1359,6 @@ internal static JsObject OrdinaryObjectCreate(Engine engine, ObjectInstance? pro
13591359
return GetMethod(_engine.Realm, this, property);
13601360
}
13611361

1362-
internal static ICallable? GetMethod(Realm realm, JsValue v, JsValue p)
1363-
{
1364-
var jsValue = v.Get(p);
1365-
if (jsValue.IsNullOrUndefined())
1366-
{
1367-
return null;
1368-
}
1369-
1370-
var callable = jsValue as ICallable;
1371-
if (callable is null)
1372-
{
1373-
ExceptionHelper.ThrowTypeError(realm, "Value returned for property '" + p + "' of object is not a function");
1374-
}
1375-
return callable;
1376-
}
1377-
13781362
internal void CopyDataProperties(
13791363
ObjectInstance target,
13801364
HashSet<JsValue>? excludedItems)

Jint/Runtime/Intrinsics.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ public sealed partial class Intrinsics
6565
private ReflectInstance? _reflect;
6666
private EvalFunction? _eval;
6767
private DateConstructor? _date;
68+
private IteratorConstructor? _iteratorConstructor;
6869
private IteratorPrototype? _iteratorPrototype;
6970
private MathInstance? _math;
7071
private JsonInstance? _json;
@@ -216,6 +217,9 @@ internal Intrinsics(Engine engine, Realm realm)
216217
internal PromiseConstructor Promise =>
217218
_promise ??= new PromiseConstructor(_engine, _realm, Function.PrototypeObject, Object.PrototypeObject);
218219

220+
internal IteratorConstructor Iterator =>
221+
_iteratorConstructor ??= new IteratorConstructor(_engine, _realm, Function.PrototypeObject, Object.PrototypeObject);
222+
219223
internal IteratorPrototype IteratorPrototype =>
220224
_iteratorPrototype ??= new IteratorPrototype(_engine, _realm, Object.PrototypeObject);
221225

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ and many more.
133133
-`Error.isError`
134134
-`Float16Array` (Requires NET 6 or higher)
135135
- ✔ Import attributes
136+
- ✔ Iterator Helpers
136137
- ✔ JSON modules
137138
-`Math.sumPrecise`
138139
-`Promise.try`

0 commit comments

Comments
 (0)