Skip to content

Commit c68c416

Browse files
authored
Implement Iterator.prototype.filter
1 parent 000061f commit c68c416

File tree

2 files changed

+56
-70
lines changed

2 files changed

+56
-70
lines changed

quickjs.c

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40123,7 +40123,7 @@ static JSValue js_iterator_from(JSContext *ctx, JSValue this_val,
4012340123
}
4012440124

4012540125
static JSValue js_create_iterator_helper(JSContext *ctx, JSValue iterator,
40126-
JSIteratorHelperKindEnum kind, JSValue func, int64_t limit);
40126+
JSIteratorHelperKindEnum kind, JSValue func, int64_t count);
4012740127

4012840128
static JSValue js_iterator_proto_drop(JSContext *ctx, JSValue this_val,
4012940129
int argc, JSValue *argv)
@@ -40224,7 +40224,13 @@ static JSValue js_iterator_proto_every(JSContext *ctx, JSValue this_val,
4022440224
static JSValue js_iterator_proto_filter(JSContext *ctx, JSValue this_val,
4022540225
int argc, JSValue *argv)
4022640226
{
40227-
return JS_ThrowInternalError(ctx, "TODO implement Iterator.prototype.filter");
40227+
JSValue func;
40228+
if (!JS_IsObject(this_val))
40229+
return JS_ThrowTypeError(ctx, "Iterator.prototype.filter called on non-object");
40230+
func = argv[0];
40231+
if (check_function(ctx, func))
40232+
return JS_EXCEPTION;
40233+
return js_create_iterator_helper(ctx, this_val, JS_ITERATOR_HELPER_KIND_FILTER, func, 0);
4022840234
}
4022940235

4023040236
static JSValue js_iterator_proto_find(JSContext *ctx, JSValue this_val,
@@ -40587,7 +40593,7 @@ typedef struct JSIteratorHelperData {
4058740593
JSValue obj;
4058840594
JSValue next;
4058940595
JSValue func; // predicate (filter) or mapper (flatMap, map)
40590-
int64_t limit; // (drop, take)
40596+
int64_t count; // limit (drop, take) or counter (filter, map, flatMap)
4059140597
BOOL executing;
4059240598
BOOL done;
4059340599
} JSIteratorHelperData;
@@ -40630,8 +40636,10 @@ static JSValue js_iterator_helper_next(JSContext *ctx, JSValue this_val,
4063040636
goto fail;
4063140637
if (it->executing)
4063240638
return JS_ThrowTypeError(ctx, "cannot invoke a running iterator");
40633-
if (it->done)
40639+
if (it->done) {
40640+
*pdone = TRUE;
4063440641
return JS_UNDEFINED;
40642+
}
4063540643

4063640644
it->executing = TRUE;
4063740645

@@ -40646,8 +40654,8 @@ static JSValue js_iterator_helper_next(JSContext *ctx, JSValue this_val,
4064640654
if (JS_IsException(method))
4064740655
goto fail;
4064840656
}
40649-
while (it->limit > 0) {
40650-
it->limit--;
40657+
while (it->count > 0) {
40658+
it->count--;
4065140659
item = JS_IteratorNext(ctx, it->obj, method, 0, NULL, pdone);
4065240660
if (JS_IsException(item)) {
4065340661
JS_FreeValue(ctx, method);
@@ -40671,18 +40679,56 @@ static JSValue js_iterator_helper_next(JSContext *ctx, JSValue this_val,
4067140679
goto done;
4067240680
}
4067340681
break;
40682+
case JS_ITERATOR_HELPER_KIND_FILTER:
40683+
{
40684+
JSValue item, method, selected, index_val, args[2];
40685+
if (magic == GEN_MAGIC_NEXT) {
40686+
method = js_dup(it->next);
40687+
} else {
40688+
method = JS_GetProperty(ctx, it->obj, JS_ATOM_return);
40689+
if (JS_IsException(method))
40690+
goto fail;
40691+
}
40692+
filter_again:
40693+
item = JS_IteratorNext(ctx, it->obj, method, 0, NULL, pdone);
40694+
if (JS_IsException(item)) {
40695+
JS_FreeValue(ctx, method);
40696+
goto fail;
40697+
}
40698+
if (*pdone || magic == GEN_MAGIC_RETURN) {
40699+
JS_FreeValue(ctx, method);
40700+
ret = item;
40701+
goto done;
40702+
}
40703+
index_val = JS_NewInt64(ctx, it->count++);
40704+
args[0] = item;
40705+
args[1] = index_val;
40706+
selected = JS_Call(ctx, it->func, JS_UNDEFINED, countof(args), args);
40707+
JS_FreeValue(ctx, index_val);
40708+
if (JS_IsException(selected)) {
40709+
JS_FreeValue(ctx, method);
40710+
goto fail;
40711+
}
40712+
if (JS_ToBoolFree(ctx, selected)) {
40713+
JS_FreeValue(ctx, method);
40714+
ret = item;
40715+
goto done;
40716+
}
40717+
goto filter_again;
40718+
}
40719+
break;
4067440720
case JS_ITERATOR_HELPER_KIND_TAKE:
4067540721
{
4067640722
JSValue item, method;
40677-
if (it->limit > 0) {
40723+
if (it->count > 0) {
4067840724
if (magic == GEN_MAGIC_NEXT) {
4067940725
method = js_dup(it->next);
4068040726
} else {
4068140727
method = JS_GetProperty(ctx, it->obj, JS_ATOM_return);
4068240728
if (JS_IsException(method))
4068340729
goto fail;
4068440730
}
40685-
it->limit--;
40731+
it->count--;
4068640732
item = JS_IteratorNext(ctx, it->obj, method, 0, NULL, pdone);
4068740733
JS_FreeValue(ctx, method);
4068840734
if (JS_IsException(item))
@@ -40717,7 +40763,7 @@ static JSValue js_iterator_helper_next(JSContext *ctx, JSValue this_val,
4071740763
}
4071840764

4071940765
static JSValue js_create_iterator_helper(JSContext *ctx, JSValue iterator,
40720-
JSIteratorHelperKindEnum kind, JSValue func, int64_t limit)
40766+
JSIteratorHelperKindEnum kind, JSValue func, int64_t count)
4072140767
{
4072240768
JSValue obj, method;
4072340769
JSIteratorHelperData *it;
@@ -40740,7 +40786,7 @@ static JSValue js_create_iterator_helper(JSContext *ctx, JSValue iterator,
4074040786
it->obj = js_dup(iterator);
4074140787
it->func = js_dup(func);
4074240788
it->next = method;
40743-
it->limit = limit;
40789+
it->count = count;
4074440790
it->executing = FALSE;
4074540791
it->done = FALSE;
4074640792
JS_SetOpaqueInternal(obj, it);

test262_errors.txt

Lines changed: 0 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -24,66 +24,6 @@ test262/test/built-ins/Iterator/prototype/constructor/prop-desc.js:10: Test262Er
2424
test262/test/built-ins/Iterator/prototype/constructor/prop-desc.js:10: strict mode: Test262Error: Expected SameValue(«undefined», «function») to be true
2525
test262/test/built-ins/Iterator/prototype/constructor/weird-setter.js:23: TypeError: cannot read property 'call' of undefined
2626
test262/test/built-ins/Iterator/prototype/constructor/weird-setter.js:23: strict mode: TypeError: cannot read property 'call' of undefined
27-
test262/test/built-ins/Iterator/prototype/filter/argument-effect-order.js:16: Test262Error: Expected a TypeError but got a InternalError
28-
test262/test/built-ins/Iterator/prototype/filter/argument-effect-order.js:16: strict mode: Test262Error: Expected a TypeError but got a InternalError
29-
test262/test/built-ins/Iterator/prototype/filter/callable.js:10: InternalError: TODO implement Iterator.prototype.filter
30-
test262/test/built-ins/Iterator/prototype/filter/callable.js:10: strict mode: InternalError: TODO implement Iterator.prototype.filter
31-
test262/test/built-ins/Iterator/prototype/filter/exhaustion-does-not-call-return.js:34: InternalError: TODO implement Iterator.prototype.filter
32-
test262/test/built-ins/Iterator/prototype/filter/exhaustion-does-not-call-return.js:34: strict mode: InternalError: TODO implement Iterator.prototype.filter
33-
test262/test/built-ins/Iterator/prototype/filter/get-next-method-only-once.js:38: InternalError: TODO implement Iterator.prototype.filter
34-
test262/test/built-ins/Iterator/prototype/filter/get-next-method-only-once.js:38: strict mode: InternalError: TODO implement Iterator.prototype.filter
35-
test262/test/built-ins/Iterator/prototype/filter/get-next-method-throws.js:17: Test262Error: Expected a Test262Error but got a InternalError
36-
test262/test/built-ins/Iterator/prototype/filter/get-next-method-throws.js:17: strict mode: Test262Error: Expected a Test262Error but got a InternalError
37-
test262/test/built-ins/Iterator/prototype/filter/get-return-method-throws.js:25: InternalError: TODO implement Iterator.prototype.filter
38-
test262/test/built-ins/Iterator/prototype/filter/get-return-method-throws.js:25: strict mode: InternalError: TODO implement Iterator.prototype.filter
39-
test262/test/built-ins/Iterator/prototype/filter/iterator-already-exhausted.js:22: InternalError: TODO implement Iterator.prototype.filter
40-
test262/test/built-ins/Iterator/prototype/filter/iterator-already-exhausted.js:22: strict mode: InternalError: TODO implement Iterator.prototype.filter
41-
test262/test/built-ins/Iterator/prototype/filter/iterator-return-method-throws.js:25: InternalError: TODO implement Iterator.prototype.filter
42-
test262/test/built-ins/Iterator/prototype/filter/iterator-return-method-throws.js:25: strict mode: InternalError: TODO implement Iterator.prototype.filter
43-
test262/test/built-ins/Iterator/prototype/filter/next-method-returns-non-object.js:21: InternalError: TODO implement Iterator.prototype.filter
44-
test262/test/built-ins/Iterator/prototype/filter/next-method-returns-non-object.js:21: strict mode: InternalError: TODO implement Iterator.prototype.filter
45-
test262/test/built-ins/Iterator/prototype/filter/next-method-returns-throwing-done.js:29: InternalError: TODO implement Iterator.prototype.filter
46-
test262/test/built-ins/Iterator/prototype/filter/next-method-returns-throwing-done.js:29: strict mode: InternalError: TODO implement Iterator.prototype.filter
47-
test262/test/built-ins/Iterator/prototype/filter/next-method-returns-throwing-value-done.js:29: InternalError: TODO implement Iterator.prototype.filter
48-
test262/test/built-ins/Iterator/prototype/filter/next-method-returns-throwing-value-done.js:29: strict mode: InternalError: TODO implement Iterator.prototype.filter
49-
test262/test/built-ins/Iterator/prototype/filter/next-method-returns-throwing-value.js:29: InternalError: TODO implement Iterator.prototype.filter
50-
test262/test/built-ins/Iterator/prototype/filter/next-method-returns-throwing-value.js:29: strict mode: InternalError: TODO implement Iterator.prototype.filter
51-
test262/test/built-ins/Iterator/prototype/filter/next-method-throws.js:21: InternalError: TODO implement Iterator.prototype.filter
52-
test262/test/built-ins/Iterator/prototype/filter/next-method-throws.js:21: strict mode: InternalError: TODO implement Iterator.prototype.filter
53-
test262/test/built-ins/Iterator/prototype/filter/non-callable-predicate.js:18: Test262Error: Expected a TypeError but got a InternalError
54-
test262/test/built-ins/Iterator/prototype/filter/non-callable-predicate.js:18: strict mode: Test262Error: Expected a TypeError but got a InternalError
55-
test262/test/built-ins/Iterator/prototype/filter/predicate-args.js:22: InternalError: TODO implement Iterator.prototype.filter
56-
test262/test/built-ins/Iterator/prototype/filter/predicate-args.js:22: strict mode: InternalError: TODO implement Iterator.prototype.filter
57-
test262/test/built-ins/Iterator/prototype/filter/predicate-filters.js:26: InternalError: TODO implement Iterator.prototype.filter
58-
test262/test/built-ins/Iterator/prototype/filter/predicate-filters.js:26: strict mode: InternalError: TODO implement Iterator.prototype.filter
59-
test262/test/built-ins/Iterator/prototype/filter/predicate-returns-non-boolean.js:25: InternalError: TODO implement Iterator.prototype.filter
60-
test262/test/built-ins/Iterator/prototype/filter/predicate-returns-non-boolean.js:25: strict mode: InternalError: TODO implement Iterator.prototype.filter
61-
test262/test/built-ins/Iterator/prototype/filter/predicate-this.js:26: InternalError: TODO implement Iterator.prototype.filter
62-
test262/test/built-ins/Iterator/prototype/filter/predicate-this.js:26: strict mode: InternalError: TODO implement Iterator.prototype.filter
63-
test262/test/built-ins/Iterator/prototype/filter/predicate-throws-then-closing-iterator-also-throws.js:30: InternalError: TODO implement Iterator.prototype.filter
64-
test262/test/built-ins/Iterator/prototype/filter/predicate-throws-then-closing-iterator-also-throws.js:30: strict mode: InternalError: TODO implement Iterator.prototype.filter
65-
test262/test/built-ins/Iterator/prototype/filter/predicate-throws.js:31: InternalError: TODO implement Iterator.prototype.filter
66-
test262/test/built-ins/Iterator/prototype/filter/predicate-throws.js:31: strict mode: InternalError: TODO implement Iterator.prototype.filter
67-
test262/test/built-ins/Iterator/prototype/filter/result-is-iterator.js:12: InternalError: TODO implement Iterator.prototype.filter
68-
test262/test/built-ins/Iterator/prototype/filter/result-is-iterator.js:12: strict mode: InternalError: TODO implement Iterator.prototype.filter
69-
test262/test/built-ins/Iterator/prototype/filter/return-is-forwarded.js:28: InternalError: TODO implement Iterator.prototype.filter
70-
test262/test/built-ins/Iterator/prototype/filter/return-is-forwarded.js:28: strict mode: InternalError: TODO implement Iterator.prototype.filter
71-
test262/test/built-ins/Iterator/prototype/filter/return-is-not-forwarded-after-exhaustion.js:27: InternalError: TODO implement Iterator.prototype.filter
72-
test262/test/built-ins/Iterator/prototype/filter/return-is-not-forwarded-after-exhaustion.js:27: strict mode: InternalError: TODO implement Iterator.prototype.filter
73-
test262/test/built-ins/Iterator/prototype/filter/this-non-callable-next.js:15: InternalError: TODO implement Iterator.prototype.filter
74-
test262/test/built-ins/Iterator/prototype/filter/this-non-callable-next.js:15: strict mode: InternalError: TODO implement Iterator.prototype.filter
75-
test262/test/built-ins/Iterator/prototype/filter/this-non-object.js:21: Test262Error: Expected a TypeError but got a InternalError
76-
test262/test/built-ins/Iterator/prototype/filter/this-non-object.js:21: strict mode: Test262Error: Expected a TypeError but got a InternalError
77-
test262/test/built-ins/Iterator/prototype/filter/this-plain-iterator.js:26: InternalError: TODO implement Iterator.prototype.filter
78-
test262/test/built-ins/Iterator/prototype/filter/this-plain-iterator.js:26: strict mode: InternalError: TODO implement Iterator.prototype.filter
79-
test262/test/built-ins/Iterator/prototype/filter/throws-typeerror-when-generator-is-running.js:39: InternalError: TODO implement Iterator.prototype.filter
80-
test262/test/built-ins/Iterator/prototype/filter/throws-typeerror-when-generator-is-running.js:39: strict mode: InternalError: TODO implement Iterator.prototype.filter
81-
test262/test/built-ins/Iterator/prototype/filter/underlying-iterator-advanced-in-parallel.js:19: InternalError: TODO implement Iterator.prototype.filter
82-
test262/test/built-ins/Iterator/prototype/filter/underlying-iterator-advanced-in-parallel.js:19: strict mode: InternalError: TODO implement Iterator.prototype.filter
83-
test262/test/built-ins/Iterator/prototype/filter/underlying-iterator-closed-in-parallel.js:19: InternalError: TODO implement Iterator.prototype.filter
84-
test262/test/built-ins/Iterator/prototype/filter/underlying-iterator-closed-in-parallel.js:19: strict mode: InternalError: TODO implement Iterator.prototype.filter
85-
test262/test/built-ins/Iterator/prototype/filter/underlying-iterator-closed.js:21: InternalError: TODO implement Iterator.prototype.filter
86-
test262/test/built-ins/Iterator/prototype/filter/underlying-iterator-closed.js:21: strict mode: InternalError: TODO implement Iterator.prototype.filter
8727
test262/test/built-ins/Iterator/prototype/flatMap/argument-effect-order.js:21: Test262Error: Expected a TypeError but got a InternalError
8828
test262/test/built-ins/Iterator/prototype/flatMap/argument-effect-order.js:21: strict mode: Test262Error: Expected a TypeError but got a InternalError
8929
test262/test/built-ins/Iterator/prototype/flatMap/callable.js:10: InternalError: TODO implement Iterator.prototype.flatMap

0 commit comments

Comments
 (0)