Implement Iterator.prototype.filter

This commit is contained in:
Saúl Ibarra Corretgé 2024-11-12 22:01:45 +01:00 committed by GitHub
parent 000061f635
commit c68c416e2e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 56 additions and 70 deletions

View file

@ -40123,7 +40123,7 @@ static JSValue js_iterator_from(JSContext *ctx, JSValue this_val,
} }
static JSValue js_create_iterator_helper(JSContext *ctx, JSValue iterator, static JSValue js_create_iterator_helper(JSContext *ctx, JSValue iterator,
JSIteratorHelperKindEnum kind, JSValue func, int64_t limit); JSIteratorHelperKindEnum kind, JSValue func, int64_t count);
static JSValue js_iterator_proto_drop(JSContext *ctx, JSValue this_val, static JSValue js_iterator_proto_drop(JSContext *ctx, JSValue this_val,
int argc, JSValue *argv) int argc, JSValue *argv)
@ -40224,7 +40224,13 @@ exception:
static JSValue js_iterator_proto_filter(JSContext *ctx, JSValue this_val, static JSValue js_iterator_proto_filter(JSContext *ctx, JSValue this_val,
int argc, JSValue *argv) int argc, JSValue *argv)
{ {
return JS_ThrowInternalError(ctx, "TODO implement Iterator.prototype.filter"); JSValue func;
if (!JS_IsObject(this_val))
return JS_ThrowTypeError(ctx, "Iterator.prototype.filter called on non-object");
func = argv[0];
if (check_function(ctx, func))
return JS_EXCEPTION;
return js_create_iterator_helper(ctx, this_val, JS_ITERATOR_HELPER_KIND_FILTER, func, 0);
} }
static JSValue js_iterator_proto_find(JSContext *ctx, JSValue this_val, static JSValue js_iterator_proto_find(JSContext *ctx, JSValue this_val,
@ -40587,7 +40593,7 @@ typedef struct JSIteratorHelperData {
JSValue obj; JSValue obj;
JSValue next; JSValue next;
JSValue func; // predicate (filter) or mapper (flatMap, map) JSValue func; // predicate (filter) or mapper (flatMap, map)
int64_t limit; // (drop, take) int64_t count; // limit (drop, take) or counter (filter, map, flatMap)
BOOL executing; BOOL executing;
BOOL done; BOOL done;
} JSIteratorHelperData; } JSIteratorHelperData;
@ -40630,8 +40636,10 @@ static JSValue js_iterator_helper_next(JSContext *ctx, JSValue this_val,
goto fail; goto fail;
if (it->executing) if (it->executing)
return JS_ThrowTypeError(ctx, "cannot invoke a running iterator"); return JS_ThrowTypeError(ctx, "cannot invoke a running iterator");
if (it->done) if (it->done) {
*pdone = TRUE;
return JS_UNDEFINED; return JS_UNDEFINED;
}
it->executing = TRUE; it->executing = TRUE;
@ -40646,8 +40654,8 @@ static JSValue js_iterator_helper_next(JSContext *ctx, JSValue this_val,
if (JS_IsException(method)) if (JS_IsException(method))
goto fail; goto fail;
} }
while (it->limit > 0) { while (it->count > 0) {
it->limit--; it->count--;
item = JS_IteratorNext(ctx, it->obj, method, 0, NULL, pdone); item = JS_IteratorNext(ctx, it->obj, method, 0, NULL, pdone);
if (JS_IsException(item)) { if (JS_IsException(item)) {
JS_FreeValue(ctx, method); JS_FreeValue(ctx, method);
@ -40671,10 +40679,9 @@ static JSValue js_iterator_helper_next(JSContext *ctx, JSValue this_val,
goto done; goto done;
} }
break; break;
case JS_ITERATOR_HELPER_KIND_TAKE: case JS_ITERATOR_HELPER_KIND_FILTER:
{ {
JSValue item, method; JSValue item, method, selected, index_val, args[2];
if (it->limit > 0) {
if (magic == GEN_MAGIC_NEXT) { if (magic == GEN_MAGIC_NEXT) {
method = js_dup(it->next); method = js_dup(it->next);
} else { } else {
@ -40682,7 +40689,46 @@ static JSValue js_iterator_helper_next(JSContext *ctx, JSValue this_val,
if (JS_IsException(method)) if (JS_IsException(method))
goto fail; goto fail;
} }
it->limit--; filter_again:
item = JS_IteratorNext(ctx, it->obj, method, 0, NULL, pdone);
if (JS_IsException(item)) {
JS_FreeValue(ctx, method);
goto fail;
}
if (*pdone || magic == GEN_MAGIC_RETURN) {
JS_FreeValue(ctx, method);
ret = item;
goto done;
}
index_val = JS_NewInt64(ctx, it->count++);
args[0] = item;
args[1] = index_val;
selected = JS_Call(ctx, it->func, JS_UNDEFINED, countof(args), args);
JS_FreeValue(ctx, index_val);
if (JS_IsException(selected)) {
JS_FreeValue(ctx, method);
goto fail;
}
if (JS_ToBoolFree(ctx, selected)) {
JS_FreeValue(ctx, method);
ret = item;
goto done;
}
goto filter_again;
}
break;
case JS_ITERATOR_HELPER_KIND_TAKE:
{
JSValue item, method;
if (it->count > 0) {
if (magic == GEN_MAGIC_NEXT) {
method = js_dup(it->next);
} else {
method = JS_GetProperty(ctx, it->obj, JS_ATOM_return);
if (JS_IsException(method))
goto fail;
}
it->count--;
item = JS_IteratorNext(ctx, it->obj, method, 0, NULL, pdone); item = JS_IteratorNext(ctx, it->obj, method, 0, NULL, pdone);
JS_FreeValue(ctx, method); JS_FreeValue(ctx, method);
if (JS_IsException(item)) if (JS_IsException(item))
@ -40717,7 +40763,7 @@ fail:
} }
static JSValue js_create_iterator_helper(JSContext *ctx, JSValue iterator, static JSValue js_create_iterator_helper(JSContext *ctx, JSValue iterator,
JSIteratorHelperKindEnum kind, JSValue func, int64_t limit) JSIteratorHelperKindEnum kind, JSValue func, int64_t count)
{ {
JSValue obj, method; JSValue obj, method;
JSIteratorHelperData *it; JSIteratorHelperData *it;
@ -40740,7 +40786,7 @@ static JSValue js_create_iterator_helper(JSContext *ctx, JSValue iterator,
it->obj = js_dup(iterator); it->obj = js_dup(iterator);
it->func = js_dup(func); it->func = js_dup(func);
it->next = method; it->next = method;
it->limit = limit; it->count = count;
it->executing = FALSE; it->executing = FALSE;
it->done = FALSE; it->done = FALSE;
JS_SetOpaqueInternal(obj, it); JS_SetOpaqueInternal(obj, it);

View file

@ -24,66 +24,6 @@ test262/test/built-ins/Iterator/prototype/constructor/prop-desc.js:10: Test262Er
test262/test/built-ins/Iterator/prototype/constructor/prop-desc.js:10: strict mode: Test262Error: Expected SameValue(«undefined», «function») to be true test262/test/built-ins/Iterator/prototype/constructor/prop-desc.js:10: strict mode: Test262Error: Expected SameValue(«undefined», «function») to be true
test262/test/built-ins/Iterator/prototype/constructor/weird-setter.js:23: TypeError: cannot read property 'call' of undefined test262/test/built-ins/Iterator/prototype/constructor/weird-setter.js:23: TypeError: cannot read property 'call' of undefined
test262/test/built-ins/Iterator/prototype/constructor/weird-setter.js:23: strict mode: TypeError: cannot read property 'call' of undefined test262/test/built-ins/Iterator/prototype/constructor/weird-setter.js:23: strict mode: TypeError: cannot read property 'call' of undefined
test262/test/built-ins/Iterator/prototype/filter/argument-effect-order.js:16: Test262Error: Expected a TypeError but got a InternalError
test262/test/built-ins/Iterator/prototype/filter/argument-effect-order.js:16: strict mode: Test262Error: Expected a TypeError but got a InternalError
test262/test/built-ins/Iterator/prototype/filter/callable.js:10: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/callable.js:10: strict mode: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/exhaustion-does-not-call-return.js:34: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/exhaustion-does-not-call-return.js:34: strict mode: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/get-next-method-only-once.js:38: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/get-next-method-only-once.js:38: strict mode: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/get-next-method-throws.js:17: Test262Error: Expected a Test262Error but got a InternalError
test262/test/built-ins/Iterator/prototype/filter/get-next-method-throws.js:17: strict mode: Test262Error: Expected a Test262Error but got a InternalError
test262/test/built-ins/Iterator/prototype/filter/get-return-method-throws.js:25: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/get-return-method-throws.js:25: strict mode: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/iterator-already-exhausted.js:22: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/iterator-already-exhausted.js:22: strict mode: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/iterator-return-method-throws.js:25: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/iterator-return-method-throws.js:25: strict mode: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/next-method-returns-non-object.js:21: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/next-method-returns-non-object.js:21: strict mode: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/next-method-returns-throwing-done.js:29: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/next-method-returns-throwing-done.js:29: strict mode: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/next-method-returns-throwing-value-done.js:29: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/next-method-returns-throwing-value-done.js:29: strict mode: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/next-method-returns-throwing-value.js:29: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/next-method-returns-throwing-value.js:29: strict mode: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/next-method-throws.js:21: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/next-method-throws.js:21: strict mode: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/non-callable-predicate.js:18: Test262Error: Expected a TypeError but got a InternalError
test262/test/built-ins/Iterator/prototype/filter/non-callable-predicate.js:18: strict mode: Test262Error: Expected a TypeError but got a InternalError
test262/test/built-ins/Iterator/prototype/filter/predicate-args.js:22: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/predicate-args.js:22: strict mode: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/predicate-filters.js:26: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/predicate-filters.js:26: strict mode: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/predicate-returns-non-boolean.js:25: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/predicate-returns-non-boolean.js:25: strict mode: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/predicate-this.js:26: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/predicate-this.js:26: strict mode: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/predicate-throws-then-closing-iterator-also-throws.js:30: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/predicate-throws-then-closing-iterator-also-throws.js:30: strict mode: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/predicate-throws.js:31: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/predicate-throws.js:31: strict mode: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/result-is-iterator.js:12: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/result-is-iterator.js:12: strict mode: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/return-is-forwarded.js:28: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/return-is-forwarded.js:28: strict mode: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/return-is-not-forwarded-after-exhaustion.js:27: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/return-is-not-forwarded-after-exhaustion.js:27: strict mode: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/this-non-callable-next.js:15: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/this-non-callable-next.js:15: strict mode: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/this-non-object.js:21: Test262Error: Expected a TypeError but got a InternalError
test262/test/built-ins/Iterator/prototype/filter/this-non-object.js:21: strict mode: Test262Error: Expected a TypeError but got a InternalError
test262/test/built-ins/Iterator/prototype/filter/this-plain-iterator.js:26: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/this-plain-iterator.js:26: strict mode: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/throws-typeerror-when-generator-is-running.js:39: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/throws-typeerror-when-generator-is-running.js:39: strict mode: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/underlying-iterator-advanced-in-parallel.js:19: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/underlying-iterator-advanced-in-parallel.js:19: strict mode: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/underlying-iterator-closed-in-parallel.js:19: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/underlying-iterator-closed-in-parallel.js:19: strict mode: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/underlying-iterator-closed.js:21: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/filter/underlying-iterator-closed.js:21: strict mode: InternalError: TODO implement Iterator.prototype.filter
test262/test/built-ins/Iterator/prototype/flatMap/argument-effect-order.js:21: Test262Error: Expected a TypeError but got a InternalError test262/test/built-ins/Iterator/prototype/flatMap/argument-effect-order.js:21: Test262Error: Expected a TypeError but got a InternalError
test262/test/built-ins/Iterator/prototype/flatMap/argument-effect-order.js:21: strict mode: Test262Error: Expected a TypeError but got a InternalError test262/test/built-ins/Iterator/prototype/flatMap/argument-effect-order.js:21: strict mode: Test262Error: Expected a TypeError but got a InternalError
test262/test/built-ins/Iterator/prototype/flatMap/callable.js:10: InternalError: TODO implement Iterator.prototype.flatMap test262/test/built-ins/Iterator/prototype/flatMap/callable.js:10: InternalError: TODO implement Iterator.prototype.flatMap