return JS_EXCEPTION;
}
+static JSValue js_iterator_proto_includes(JSContext *ctx, JSValueConst this_val,
+ int argc, JSValueConst *argv)
+{
+ JSValue item, method;
+ int64_t to_skip, skipped;
+ double d;
+ int done;
+
+ if (!JS_IsObject(this_val))
+ return JS_ThrowTypeErrorNotAnObject(ctx);
+
+ // skippedElements is deliberately not coerced: anything that isn't an
+ // integral Number (or +/-Infinity) is a TypeError, and the underlying
+ // iterator is closed before the error propagates.
+ to_skip = 0;
+ if (argc > 1 && !JS_IsUndefined(argv[1])) {
+ if (!JS_IsNumber(argv[1])) {
+ JS_ThrowTypeError(ctx, "not a number");
+ goto fail;
+ }
+ JS_ToFloat64(ctx, &d, argv[1]); // cannot fail
+ if (isnan(d) || (isfinite(d) && trunc(d) != d)) {
+ JS_ThrowTypeError(ctx, "not an integral number");
+ goto fail;
+ }
+ if (d < 0 || (isfinite(d) && d > MAX_SAFE_INTEGER)) {
+ JS_ThrowRangeError(ctx, "must be positive");
+ goto fail;
+ }
+ // +Infinity means "skip everything"; use MAX_SAFE_INTEGER
+ to_skip = isfinite(d) ? (int64_t)d : MAX_SAFE_INTEGER;
+ }
+
+ // Note: a failure here propagates without closing the iterator.
+ method = JS_GetProperty(ctx, this_val, JS_ATOM_next);
+ if (JS_IsException(method))
+ return JS_EXCEPTION;
+
+ for (skipped = 0; /*empty*/; /*empty*/) {
+ item = JS_IteratorNext(ctx, this_val, method, &done);
+ if (JS_IsException(item)) {
+ // IteratorStepValue marks the iterator done, it does not close it.
+ JS_FreeValue(ctx, method);
+ return JS_EXCEPTION;
+ }
+ if (done) {
+ JS_FreeValue(ctx, method);
+ return JS_FALSE;
+ }
+ if (skipped < to_skip) {
+ skipped++;
+ } else if (js_same_value_zero(ctx, item, argv[0])) {
+ JS_FreeValue(ctx, item);
+ JS_FreeValue(ctx, method);
+ if (JS_IteratorClose(ctx, this_val, false) < 0)
+ return JS_EXCEPTION;
+ return JS_TRUE;
+ }
+ JS_FreeValue(ctx, item);
+ }
+fail:
+ JS_IteratorClose(ctx, this_val, true);
+ return JS_EXCEPTION;
+}
+
static JSValue js_iterator_proto_reduce(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
JS_CFUNC_MAGIC_DEF("find", 1, js_iterator_proto_func, JS_ITERATOR_HELPER_KIND_FIND),
JS_CFUNC_MAGIC_DEF("forEach", 1, js_iterator_proto_func, JS_ITERATOR_HELPER_KIND_FOR_EACH ),
JS_CFUNC_MAGIC_DEF("some", 1, js_iterator_proto_func, JS_ITERATOR_HELPER_KIND_SOME ),
+ JS_CFUNC_DEF("includes", 1, js_iterator_proto_includes ),
JS_CFUNC_DEF("join", 1, js_iterator_proto_join ),
JS_CFUNC_DEF("reduce", 1, js_iterator_proto_reduce ),
JS_CFUNC_DEF("toArray", 0, js_iterator_proto_toArray ),