diff --git a/quickjs.c b/quickjs.c index da725538..ac267078 100644 --- a/quickjs.c +++ b/quickjs.c @@ -40055,7 +40055,67 @@ static JSValue js_iterator_proto_map(JSContext *ctx, JSValue this_val, static JSValue js_iterator_proto_reduce(JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { - return JS_ThrowInternalError(ctx, "TODO implement Iterator.prototype.reduce"); + JSValue item, method, ret, func, index_val, acc; + JSValue args[3]; + int64_t idx; + BOOL done; + + if (!JS_IsObject(this_val)) + return JS_ThrowTypeError(ctx, "Iterator.prototype.reduce called on non-object"); + if (check_function(ctx, argv[0])) + return JS_EXCEPTION; + acc = JS_UNDEFINED; + func = js_dup(argv[0]); + method = JS_GetProperty(ctx, this_val, JS_ATOM_next); + if (JS_IsException(method)) + goto exception; + if (argc > 1) { + acc = js_dup(argv[1]); + idx = 0; + } else { + acc = JS_IteratorNext(ctx, this_val, method, 0, NULL, &done); + if (JS_IsException(acc)) + goto exception; + if (done) { + JS_ThrowTypeError(ctx, "empty iterator"); + goto exception; + } + idx = 1; + } + for (/* empty */; /*empty*/; idx++) { + item = JS_IteratorNext(ctx, this_val, method, 0, NULL, &done); + if (JS_IsException(item)) + goto exception; + if (done) + break; + index_val = JS_NewInt64(ctx, idx); + if (JS_IsException(index_val)) { + JS_FreeValue(ctx, item); + goto exception; + } + args[0] = acc; + args[1] = item; + args[2] = index_val; + ret = JS_Call(ctx, func, JS_UNDEFINED, countof(args), args); + JS_FreeValue(ctx, item); + JS_FreeValue(ctx, index_val); + if (JS_IsException(ret)) + goto exception; + JS_FreeValue(ctx, acc); + acc = ret; + index_val = JS_UNDEFINED; + ret = JS_UNDEFINED; + item = JS_UNDEFINED; + } + JS_FreeValue(ctx, func); + JS_FreeValue(ctx, method); + return acc; +exception: + JS_IteratorClose(ctx, this_val, TRUE); + JS_FreeValue(ctx, acc); + JS_FreeValue(ctx, func); + JS_FreeValue(ctx, method); + return JS_EXCEPTION; } static JSValue js_iterator_proto_some(JSContext *ctx, JSValue this_val, diff --git a/test262_errors.txt b/test262_errors.txt index d608e0b5..4dc21144 100644 --- a/test262_errors.txt +++ b/test262_errors.txt @@ -320,52 +320,6 @@ test262/test/built-ins/Iterator/prototype/map/underlying-iterator-closed-in-para test262/test/built-ins/Iterator/prototype/map/underlying-iterator-closed-in-parallel.js:19: strict mode: InternalError: TODO implement Iterator.prototype.map test262/test/built-ins/Iterator/prototype/map/underlying-iterator-closed.js:21: InternalError: TODO implement Iterator.prototype.map test262/test/built-ins/Iterator/prototype/map/underlying-iterator-closed.js:21: strict mode: InternalError: TODO implement Iterator.prototype.map -test262/test/built-ins/Iterator/prototype/reduce/argument-effect-order.js:16: Test262Error: Expected a TypeError but got a InternalError -test262/test/built-ins/Iterator/prototype/reduce/argument-effect-order.js:16: strict mode: Test262Error: Expected a TypeError but got a InternalError -test262/test/built-ins/Iterator/prototype/reduce/callable.js:10: InternalError: TODO implement Iterator.prototype.reduce -test262/test/built-ins/Iterator/prototype/reduce/callable.js:10: strict mode: InternalError: TODO implement Iterator.prototype.reduce -test262/test/built-ins/Iterator/prototype/reduce/get-next-method-only-once.js:33: InternalError: TODO implement Iterator.prototype.reduce -test262/test/built-ins/Iterator/prototype/reduce/get-next-method-only-once.js:33: strict mode: InternalError: TODO implement Iterator.prototype.reduce -test262/test/built-ins/Iterator/prototype/reduce/get-next-method-throws.js:15: Test262Error: Expected a Test262Error but got a InternalError -test262/test/built-ins/Iterator/prototype/reduce/get-next-method-throws.js:15: strict mode: Test262Error: Expected a Test262Error but got a InternalError -test262/test/built-ins/Iterator/prototype/reduce/iterator-already-exhausted-initial-value.js:20: InternalError: TODO implement Iterator.prototype.reduce -test262/test/built-ins/Iterator/prototype/reduce/iterator-already-exhausted-initial-value.js:20: strict mode: InternalError: TODO implement Iterator.prototype.reduce -test262/test/built-ins/Iterator/prototype/reduce/iterator-already-exhausted-no-initial-value.js:19: Test262Error: Expected a TypeError but got a InternalError -test262/test/built-ins/Iterator/prototype/reduce/iterator-already-exhausted-no-initial-value.js:19: strict mode: Test262Error: Expected a TypeError but got a InternalError -test262/test/built-ins/Iterator/prototype/reduce/iterator-yields-once-initial-value.js:32: InternalError: TODO implement Iterator.prototype.reduce -test262/test/built-ins/Iterator/prototype/reduce/iterator-yields-once-initial-value.js:32: strict mode: InternalError: TODO implement Iterator.prototype.reduce -test262/test/built-ins/Iterator/prototype/reduce/iterator-yields-once-no-initial-value.js:23: InternalError: TODO implement Iterator.prototype.reduce -test262/test/built-ins/Iterator/prototype/reduce/iterator-yields-once-no-initial-value.js:23: strict mode: InternalError: TODO implement Iterator.prototype.reduce -test262/test/built-ins/Iterator/prototype/reduce/next-method-returns-non-object.js:21: Test262Error: Expected a TypeError but got a InternalError -test262/test/built-ins/Iterator/prototype/reduce/next-method-returns-non-object.js:21: strict mode: Test262Error: Expected a TypeError but got a InternalError -test262/test/built-ins/Iterator/prototype/reduce/next-method-returns-throwing-done.js:17: Test262Error: Expected a Test262Error but got a InternalError -test262/test/built-ins/Iterator/prototype/reduce/next-method-returns-throwing-done.js:17: strict mode: Test262Error: Expected a Test262Error but got a InternalError -test262/test/built-ins/Iterator/prototype/reduce/next-method-returns-throwing-value-done.js:28: InternalError: TODO implement Iterator.prototype.reduce -test262/test/built-ins/Iterator/prototype/reduce/next-method-returns-throwing-value-done.js:28: strict mode: InternalError: TODO implement Iterator.prototype.reduce -test262/test/built-ins/Iterator/prototype/reduce/next-method-returns-throwing-value.js:18: Test262Error: Expected a Test262Error but got a InternalError -test262/test/built-ins/Iterator/prototype/reduce/next-method-returns-throwing-value.js:18: strict mode: Test262Error: Expected a Test262Error but got a InternalError -test262/test/built-ins/Iterator/prototype/reduce/next-method-throws.js:15: Test262Error: Expected a Test262Error but got a InternalError -test262/test/built-ins/Iterator/prototype/reduce/next-method-throws.js:15: strict mode: Test262Error: Expected a Test262Error but got a InternalError -test262/test/built-ins/Iterator/prototype/reduce/non-callable-reducer.js:18: Test262Error: Expected a TypeError but got a InternalError -test262/test/built-ins/Iterator/prototype/reduce/non-callable-reducer.js:18: strict mode: Test262Error: Expected a TypeError but got a InternalError -test262/test/built-ins/Iterator/prototype/reduce/reducer-args-initial-value.js:42: InternalError: TODO implement Iterator.prototype.reduce -test262/test/built-ins/Iterator/prototype/reduce/reducer-args-initial-value.js:42: strict mode: InternalError: TODO implement Iterator.prototype.reduce -test262/test/built-ins/Iterator/prototype/reduce/reducer-args-no-initial-value.js:38: InternalError: TODO implement Iterator.prototype.reduce -test262/test/built-ins/Iterator/prototype/reduce/reducer-args-no-initial-value.js:38: strict mode: InternalError: TODO implement Iterator.prototype.reduce -test262/test/built-ins/Iterator/prototype/reduce/reducer-memo-can-be-any-type.js:28: InternalError: TODO implement Iterator.prototype.reduce -test262/test/built-ins/Iterator/prototype/reduce/reducer-memo-can-be-any-type.js:28: strict mode: InternalError: TODO implement Iterator.prototype.reduce -test262/test/built-ins/Iterator/prototype/reduce/reducer-this.js:29: InternalError: TODO implement Iterator.prototype.reduce -test262/test/built-ins/Iterator/prototype/reduce/reducer-this.js:29: strict mode: InternalError: TODO implement Iterator.prototype.reduce -test262/test/built-ins/Iterator/prototype/reduce/reducer-throws-then-closing-iterator-also-throws.js:30: Test262Error: Expected a Test262Error but got a InternalError -test262/test/built-ins/Iterator/prototype/reduce/reducer-throws-then-closing-iterator-also-throws.js:30: strict mode: Test262Error: Expected a Test262Error but got a InternalError -test262/test/built-ins/Iterator/prototype/reduce/reducer-throws.js:32: Test262Error: Expected a Test262Error but got a InternalError -test262/test/built-ins/Iterator/prototype/reduce/reducer-throws.js:32: strict mode: Test262Error: Expected a Test262Error but got a InternalError -test262/test/built-ins/Iterator/prototype/reduce/this-non-callable-next.js:13: Test262Error: Expected a TypeError but got a InternalError -test262/test/built-ins/Iterator/prototype/reduce/this-non-callable-next.js:13: strict mode: Test262Error: Expected a TypeError but got a InternalError -test262/test/built-ins/Iterator/prototype/reduce/this-non-object.js:23: Test262Error: Expected a TypeError but got a InternalError -test262/test/built-ins/Iterator/prototype/reduce/this-non-object.js:23: strict mode: Test262Error: Expected a TypeError but got a InternalError -test262/test/built-ins/Iterator/prototype/reduce/this-plain-iterator.js:29: InternalError: TODO implement Iterator.prototype.reduce -test262/test/built-ins/Iterator/prototype/reduce/this-plain-iterator.js:29: strict mode: InternalError: TODO implement Iterator.prototype.reduce test262/test/built-ins/Iterator/prototype/some/argument-effect-order.js:16: Test262Error: Expected a TypeError but got a InternalError test262/test/built-ins/Iterator/prototype/some/argument-effect-order.js:16: strict mode: Test262Error: Expected a TypeError but got a InternalError test262/test/built-ins/Iterator/prototype/some/callable.js:10: InternalError: TODO implement Iterator.prototype.some