Add Iterator.from (#555)

This commit is contained in:
Ben Noordhuis 2024-09-27 00:16:50 +02:00 committed by GitHub
parent 06175d1e0c
commit 348d60985d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 48 additions and 20 deletions

View file

@ -153,7 +153,7 @@ enum {
JS_CLASS_SET, /* u.map_state */
JS_CLASS_WEAKMAP, /* u.map_state */
JS_CLASS_WEAKSET, /* u.map_state */
JS_CLASS_ITERATOR, /* u.map_iterator_data */
JS_CLASS_ITERATOR,
JS_CLASS_MAP_ITERATOR, /* u.map_iterator_data */
JS_CLASS_SET_ITERATOR, /* u.map_iterator_data */
JS_CLASS_ARRAY_ITERATOR, /* u.array_iterator_data */
@ -39770,7 +39770,53 @@ static JSValue js_iterator_constructor(JSContext *ctx, JSValue new_target,
static JSValue js_iterator_from(JSContext *ctx, JSValue this_val,
int argc, JSValue *argv)
{
return JS_ThrowInternalError(ctx, "TODO implement Iterator.from");
JSValue obj, method, iter, temp;
int ret;
obj = argv[0];
if (JS_IsString(obj)) {
method = JS_GetProperty(ctx, obj, JS_ATOM_Symbol_iterator);
if (JS_IsException(method))
return JS_EXCEPTION;
return JS_CallFree(ctx, method, obj, 0, NULL);
}
if (!JS_IsObject(obj))
return JS_ThrowTypeError(ctx, "Iterator.from called on non-object");
ret = JS_OrdinaryIsInstanceOf(ctx, obj, ctx->iterator_ctor);
if (ret < 0)
return JS_EXCEPTION;
if (ret)
return js_dup(obj);
method = JS_GetProperty(ctx, obj, JS_ATOM_Symbol_iterator);
if (JS_IsException(method))
return JS_EXCEPTION;
if (JS_IsNull(method) || JS_IsUndefined(method)) {
method = JS_GetProperty(ctx, obj, JS_ATOM_next);
if (JS_IsException(method))
return JS_EXCEPTION;
// honestly kind of ghetto but avoids having to
// define a separate JS_CLASS_NON_GHETTO_ITERATOR
temp = method;
method = js_function_bind(ctx, method, 1, &obj);
JS_FreeValue(ctx, temp);
if (JS_IsException(method))
return JS_EXCEPTION;
iter = JS_NewObjectProtoClass(ctx, ctx->iterator_proto, JS_CLASS_ITERATOR);
if (JS_IsException(iter)) {
JS_FreeValue(ctx, method);
return JS_EXCEPTION;
}
if (JS_SetProperty(ctx, iter, JS_ATOM_next, method) < 0) {
JS_FreeValue(ctx, iter);
return JS_EXCEPTION;
}
} else {
iter = JS_GetIterator2(ctx, obj, method);
JS_FreeValue(ctx, method);
if (JS_IsException(iter))
return JS_EXCEPTION;
}
return iter;
}
static JSValue js_iterator_proto_drop(JSContext *ctx, JSValue this_val,

View file

@ -18,24 +18,6 @@ test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-undefined-retu
test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-undefined-return-not-object.js:72: strict mode: TypeError: $DONE() not called
test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-undefined-return-object.js:66: TypeError: $DONE() not called
test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-undefined-return-object.js:66: strict mode: TypeError: $DONE() not called
test262/test/built-ins/Iterator/from/callable.js:11: InternalError: TODO implement Iterator.from
test262/test/built-ins/Iterator/from/callable.js:11: strict mode: InternalError: TODO implement Iterator.from
test262/test/built-ins/Iterator/from/get-next-method-only-once.js:38: InternalError: TODO implement Iterator.from
test262/test/built-ins/Iterator/from/get-next-method-only-once.js:38: strict mode: InternalError: TODO implement Iterator.from
test262/test/built-ins/Iterator/from/get-next-method-throws.js:17: Test262Error: Expected a Test262Error but got a InternalError
test262/test/built-ins/Iterator/from/get-next-method-throws.js:17: strict mode: Test262Error: Expected a Test262Error but got a InternalError
test262/test/built-ins/Iterator/from/iterable-primitives.js:33: Test262Error: Expected a TypeError but got a InternalError
test262/test/built-ins/Iterator/from/iterable-primitives.js:33: strict mode: Test262Error: Expected a TypeError but got a InternalError
test262/test/built-ins/Iterator/from/iterable-to-iterator-fallback.js:29: Test262Error: Expected a TypeError but got a InternalError
test262/test/built-ins/Iterator/from/iterable-to-iterator-fallback.js:29: strict mode: Test262Error: Expected a TypeError but got a InternalError
test262/test/built-ins/Iterator/from/primitives.js:14: Test262Error: Expected a TypeError but got a InternalError
test262/test/built-ins/Iterator/from/primitives.js:14: strict mode: Test262Error: Expected a TypeError but got a InternalError
test262/test/built-ins/Iterator/from/result-proto.js:19: InternalError: TODO implement Iterator.from
test262/test/built-ins/Iterator/from/result-proto.js:19: strict mode: InternalError: TODO implement Iterator.from
test262/test/built-ins/Iterator/from/supports-iterable.js:14: InternalError: TODO implement Iterator.from
test262/test/built-ins/Iterator/from/supports-iterable.js:14: strict mode: InternalError: TODO implement Iterator.from
test262/test/built-ins/Iterator/from/supports-iterator.js:29: InternalError: TODO implement Iterator.from
test262/test/built-ins/Iterator/from/supports-iterator.js:29: strict mode: InternalError: TODO implement Iterator.from
test262/test/built-ins/Iterator/prototype/Symbol.iterator/prop-desc.js:15: Test262Error: obj should have an own property Symbol(Symbol.iterator)
test262/test/built-ins/Iterator/prototype/Symbol.iterator/prop-desc.js:15: strict mode: Test262Error: obj should have an own property Symbol(Symbol.iterator)
test262/test/built-ins/Iterator/prototype/Symbol.toStringTag/prop-desc.js:11: TypeError: cannot read property 'get' of undefined