From 71aa136e21feee6ca33127c7083412d9e3527884 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Ibarra=20Corretg=C3=A9?= Date: Mon, 18 Nov 2024 09:26:46 +0100 Subject: [PATCH 1/3] Simplify iterator helpers code, remove duplication --- quickjs.c | 582 ++++++++++++++++++++++-------------------------------- 1 file changed, 239 insertions(+), 343 deletions(-) diff --git a/quickjs.c b/quickjs.c index 675abb0b..af45ca10 100644 --- a/quickjs.c +++ b/quickjs.c @@ -712,9 +712,13 @@ typedef enum JSIteratorKindEnum { typedef enum JSIteratorHelperKindEnum { JS_ITERATOR_HELPER_KIND_DROP, + JS_ITERATOR_HELPER_KIND_EVERY, JS_ITERATOR_HELPER_KIND_FILTER, + JS_ITERATOR_HELPER_KIND_FIND, JS_ITERATOR_HELPER_KIND_FLAT_MAP, + JS_ITERATOR_HELPER_KIND_FOR_EACH, JS_ITERATOR_HELPER_KIND_MAP, + JS_ITERATOR_HELPER_KIND_SOME, JS_ITERATOR_HELPER_KIND_TAKE, } JSIteratorHelperKindEnum; @@ -40185,237 +40189,265 @@ static JSValue js_iterator_from(JSContext *ctx, JSValue this_val, return JS_EXCEPTION; } -static JSValue js_create_iterator_helper(JSContext *ctx, JSValue iterator, - JSIteratorHelperKindEnum kind, JSValue func, int64_t count); - -static JSValue js_iterator_proto_drop(JSContext *ctx, JSValue this_val, - int argc, JSValue *argv) +static int check_iterator(JSContext *ctx, JSValue obj) { - JSValue v; - double dlimit; - int64_t limit; - if (!JS_IsObject(this_val)) - return JS_ThrowTypeError(ctx, "Iterator.prototype.drop called on non-object"); - v = JS_ToNumber(ctx, argv[0]); - if (JS_IsException(v)) - return JS_EXCEPTION; - // Check for Infinity. - if (JS_ToFloat64(ctx, &dlimit, v)) { - JS_FreeValue(ctx, v); - return JS_EXCEPTION; - } - if (isnan(dlimit)) { - JS_FreeValue(ctx, v); - goto fail; - } - if (!isfinite(dlimit)) { - JS_FreeValue(ctx, v); - if (dlimit < 0) - goto fail; - else - limit = MAX_SAFE_INTEGER; - } else { - v = JS_ToIntegerFree(ctx, v); - if (JS_IsException(v)) - return JS_EXCEPTION; - if (JS_ToInt64Free(ctx, &limit, v)) - return JS_EXCEPTION; - } - if (limit < 0) { - fail: - return JS_ThrowRangeError(ctx, "must be positive"); + if (!JS_IsObject(obj)) { + JS_ThrowTypeErrorNotAnObject(ctx); + return -1; } - return js_create_iterator_helper(ctx, this_val, JS_ITERATOR_HELPER_KIND_DROP, JS_UNDEFINED, limit); + return 0; } -static JSValue js_iterator_proto_every(JSContext *ctx, JSValue this_val, - int argc, JSValue *argv) -{ - JSValue item, method, ret, func, index_val, r; - JSValue args[2]; - int64_t idx; +typedef struct JSIteratorHelperData { + JSIteratorHelperKindEnum kind; + JSValue obj; + JSValue next; + JSValue func; // predicate (filter) or mapper (flatMap, map) + JSValue inner; // innerValue (flatMap) + int64_t count; // limit (drop, take) or counter (filter, map, flatMap) + BOOL executing; BOOL done; +} JSIteratorHelperData; - if (!JS_IsObject(this_val)) - return JS_ThrowTypeError(ctx, "Iterator.prototype.every called on non-object"); - if (check_function(ctx, argv[0])) +static JSValue js_create_iterator_helper(JSContext *ctx, JSValue this_val, + int argc, JSValue *argv, int magic) +{ + JSValue func, obj, method; + int64_t count; + JSIteratorHelperData *it; + + if (check_iterator(ctx, this_val) < 0) return JS_EXCEPTION; - func = js_dup(argv[0]); - method = JS_GetProperty(ctx, this_val, JS_ATOM_next); - if (JS_IsException(method)) - goto exception; - r = JS_TRUE; - for (idx = 0; /*empty*/; idx++) { - item = JS_IteratorNext(ctx, this_val, method, 0, NULL, &done); - if (JS_IsException(item)) - goto exception; - if (done) + func = JS_UNDEFINED; + count = 0; + + switch(magic) { + case JS_ITERATOR_HELPER_KIND_DROP: + case JS_ITERATOR_HELPER_KIND_TAKE: + { + JSValue v; + double dlimit; + v = JS_ToNumber(ctx, argv[0]); + if (JS_IsException(v)) + return JS_EXCEPTION; + // Check for Infinity. + if (JS_ToFloat64(ctx, &dlimit, v)) { + JS_FreeValue(ctx, v); + return JS_EXCEPTION; + } + if (isnan(dlimit)) { + JS_FreeValue(ctx, v); + goto fail; + } + if (!isfinite(dlimit)) { + JS_FreeValue(ctx, v); + if (dlimit < 0) + goto fail; + else + count = MAX_SAFE_INTEGER; + } else { + v = JS_ToIntegerFree(ctx, v); + if (JS_IsException(v)) + return JS_EXCEPTION; + if (JS_ToInt64Free(ctx, &count, v)) + return JS_EXCEPTION; + } + if (count < 0) { + fail: + return JS_ThrowRangeError(ctx, "must be positive"); + } + } break; - index_val = js_int64(idx); - args[0] = item; - args[1] = 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; - if (!JS_ToBoolFree(ctx, ret)) { - if (JS_IteratorClose(ctx, this_val, FALSE) < 0) - r = JS_EXCEPTION; - else - r = JS_FALSE; + case JS_ITERATOR_HELPER_KIND_FILTER: + case JS_ITERATOR_HELPER_KIND_FLAT_MAP: + case JS_ITERATOR_HELPER_KIND_MAP: + { + func = argv[0]; + if (check_function(ctx, func)) + return JS_EXCEPTION; + } + break; + default: + abort(); break; - } - index_val = JS_UNDEFINED; - ret = JS_UNDEFINED; - item = JS_UNDEFINED; } - JS_FreeValue(ctx, func); - JS_FreeValue(ctx, method); - return r; -exception: - JS_IteratorClose(ctx, this_val, TRUE); - JS_FreeValue(ctx, func); - JS_FreeValue(ctx, method); - return JS_EXCEPTION; -} -static JSValue js_iterator_proto_filter(JSContext *ctx, JSValue this_val, - int argc, JSValue *argv) -{ - 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)) + method = JS_GetProperty(ctx, this_val, JS_ATOM_next); + if (JS_IsException(method)) + return JS_EXCEPTION; + obj = JS_NewObjectClass(ctx, JS_CLASS_ITERATOR_HELPER); + if (JS_IsException(obj)) { + JS_FreeValue(ctx, method); + return JS_EXCEPTION; + } + it = js_malloc(ctx, sizeof(*it)); + if (!it) { + JS_FreeValue(ctx, obj); + JS_FreeValue(ctx, method); return JS_EXCEPTION; - return js_create_iterator_helper(ctx, this_val, JS_ITERATOR_HELPER_KIND_FILTER, func, 0); + } + it->kind = magic; + it->obj = js_dup(this_val); + it->func = js_dup(func); + it->next = method; + it->inner = JS_UNDEFINED; + it->count = count; + it->executing = FALSE; + it->done = FALSE; + JS_SetOpaqueInternal(obj, it); + return obj; } -static JSValue js_iterator_proto_find(JSContext *ctx, JSValue this_val, - int argc, JSValue *argv) +static JSValue js_iterator_proto_func(JSContext *ctx, JSValue this_val, + int argc, JSValue *argv, int magic) { JSValue item, method, ret, func, index_val, r; JSValue args[2]; int64_t idx; BOOL done; - if (!JS_IsObject(this_val)) - return JS_ThrowTypeError(ctx, "Iterator.prototype.filter called on non-object"); + if (check_iterator(ctx, this_val) < 0) + return JS_EXCEPTION; if (check_function(ctx, argv[0])) return JS_EXCEPTION; func = js_dup(argv[0]); method = JS_GetProperty(ctx, this_val, JS_ATOM_next); if (JS_IsException(method)) - goto exception; + goto fail; + r = JS_UNDEFINED; - for (idx = 0; /*empty*/; idx++) { - item = JS_IteratorNext(ctx, this_val, method, 0, NULL, &done); - if (JS_IsException(item)) - goto exception; - if (done) + + switch(magic) { + case JS_ITERATOR_HELPER_KIND_EVERY: + { + r = JS_TRUE; + for (idx = 0; /*empty*/; idx++) { + item = JS_IteratorNext(ctx, this_val, method, 0, NULL, &done); + if (JS_IsException(item)) + goto fail; + if (done) + break; + index_val = js_int64(idx); + args[0] = item; + args[1] = 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 fail; + if (!JS_ToBoolFree(ctx, ret)) { + if (JS_IteratorClose(ctx, this_val, FALSE) < 0) + r = JS_EXCEPTION; + else + r = JS_FALSE; + break; + } + index_val = JS_UNDEFINED; + ret = JS_UNDEFINED; + item = JS_UNDEFINED; + } + } break; - index_val = js_int64(idx); - args[0] = item; - args[1] = index_val; - ret = JS_Call(ctx, func, JS_UNDEFINED, countof(args), args); - JS_FreeValue(ctx, index_val); - if (JS_IsException(ret)) { - JS_FreeValue(ctx, item); - goto exception; - } - if (JS_ToBoolFree(ctx, ret)) { - if (JS_IteratorClose(ctx, this_val, FALSE) < 0) { - JS_FreeValue(ctx, item); - r = JS_EXCEPTION; - } else { - r = item; + case JS_ITERATOR_HELPER_KIND_FIND: + { + for (idx = 0; /*empty*/; idx++) { + item = JS_IteratorNext(ctx, this_val, method, 0, NULL, &done); + if (JS_IsException(item)) + goto fail; + if (done) + break; + index_val = js_int64(idx); + args[0] = item; + args[1] = index_val; + ret = JS_Call(ctx, func, JS_UNDEFINED, countof(args), args); + JS_FreeValue(ctx, index_val); + if (JS_IsException(ret)) { + JS_FreeValue(ctx, item); + goto fail; + } + if (JS_ToBoolFree(ctx, ret)) { + if (JS_IteratorClose(ctx, this_val, FALSE) < 0) { + JS_FreeValue(ctx, item); + r = JS_EXCEPTION; + } else { + r = item; + } + break; + } + index_val = JS_UNDEFINED; + ret = JS_UNDEFINED; + item = JS_UNDEFINED; + } } break; - } - index_val = JS_UNDEFINED; - ret = JS_UNDEFINED; - item = JS_UNDEFINED; - } - JS_FreeValue(ctx, func); - JS_FreeValue(ctx, method); - return r; -exception: - JS_IteratorClose(ctx, this_val, TRUE); - JS_FreeValue(ctx, func); - JS_FreeValue(ctx, method); - return JS_EXCEPTION; -} - -static JSValue js_iterator_proto_flatMap(JSContext *ctx, JSValue this_val, - int argc, JSValue *argv) -{ - JSValue func; - if (!JS_IsObject(this_val)) - return JS_ThrowTypeError(ctx, "Iterator.prototype.flatMap 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_FLAT_MAP, func, 0); -} - -static JSValue js_iterator_proto_forEach(JSContext *ctx, JSValue this_val, - int argc, JSValue *argv) -{ - JSValue item, method, ret, func, index_val; - JSValue args[2]; - int64_t idx; - BOOL done; - - if (!JS_IsObject(this_val)) - return JS_ThrowTypeError(ctx, "Iterator.prototype.forEach called on non-object"); - if (check_function(ctx, argv[0])) - return JS_EXCEPTION; - func = js_dup(argv[0]); - method = JS_GetProperty(ctx, this_val, JS_ATOM_next); - if (JS_IsException(method)) - goto exception; - for (idx = 0; /*empty*/; idx++) { - item = JS_IteratorNext(ctx, this_val, method, 0, NULL, &done); - if (JS_IsException(item)) - goto exception; - if (done) + case JS_ITERATOR_HELPER_KIND_FOR_EACH: + { + for (idx = 0; /*empty*/; idx++) { + item = JS_IteratorNext(ctx, this_val, method, 0, NULL, &done); + if (JS_IsException(item)) + goto fail; + if (done) + break; + index_val = js_int64(idx); + args[0] = item; + args[1] = 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 fail; + JS_FreeValue(ctx, ret); + index_val = JS_UNDEFINED; + ret = JS_UNDEFINED; + item = JS_UNDEFINED; + } + } + break; + case JS_ITERATOR_HELPER_KIND_SOME: + { + r = JS_FALSE; + for (idx = 0; /*empty*/; idx++) { + item = JS_IteratorNext(ctx, this_val, method, 0, NULL, &done); + if (JS_IsException(item)) + goto fail; + if (done) + break; + index_val = js_int64(idx); + args[0] = item; + args[1] = 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 fail; + if (JS_ToBoolFree(ctx, ret)) { + if (JS_IteratorClose(ctx, this_val, FALSE) < 0) + r = JS_EXCEPTION; + else + r = JS_TRUE; + break; + } + index_val = JS_UNDEFINED; + ret = JS_UNDEFINED; + item = JS_UNDEFINED; + } + } + break; + default: + abort(); break; - index_val = js_int64(idx); - args[0] = item; - args[1] = 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, ret); - index_val = JS_UNDEFINED; - ret = JS_UNDEFINED; - item = JS_UNDEFINED; } + JS_FreeValue(ctx, func); JS_FreeValue(ctx, method); - return JS_UNDEFINED; -exception: + return r; +fail: JS_IteratorClose(ctx, this_val, TRUE); JS_FreeValue(ctx, func); JS_FreeValue(ctx, method); return JS_EXCEPTION; } -static JSValue js_iterator_proto_map(JSContext *ctx, JSValue this_val, - int argc, JSValue *argv) -{ - JSValue func; - if (!JS_IsObject(this_val)) - return JS_ThrowTypeError(ctx, "Iterator.prototype.map 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_MAP, func, 0); -} - static JSValue js_iterator_proto_reduce(JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { @@ -40424,8 +40456,8 @@ static JSValue js_iterator_proto_reduce(JSContext *ctx, JSValue this_val, int64_t idx; BOOL done; - if (!JS_IsObject(this_val)) - return JS_ThrowTypeError(ctx, "Iterator.prototype.reduce called on non-object"); + if (check_iterator(ctx, this_val) < 0) + return JS_EXCEPTION; if (check_function(ctx, argv[0])) return JS_EXCEPTION; acc = JS_UNDEFINED; @@ -40478,98 +40510,6 @@ static JSValue js_iterator_proto_reduce(JSContext *ctx, JSValue this_val, return JS_EXCEPTION; } -static JSValue js_iterator_proto_some(JSContext *ctx, JSValue this_val, - int argc, JSValue *argv) -{ - JSValue item, method, ret, func, index_val, r; - JSValue args[2]; - int64_t idx; - BOOL done; - - if (!JS_IsObject(this_val)) - return JS_ThrowTypeError(ctx, "Iterator.prototype.some called on non-object"); - if (check_function(ctx, argv[0])) - return JS_EXCEPTION; - func = js_dup(argv[0]); - method = JS_GetProperty(ctx, this_val, JS_ATOM_next); - if (JS_IsException(method)) - goto exception; - r = JS_FALSE; - for (idx = 0; /*empty*/; idx++) { - item = JS_IteratorNext(ctx, this_val, method, 0, NULL, &done); - if (JS_IsException(item)) - goto exception; - if (done) - break; - index_val = js_int64(idx); - args[0] = item; - args[1] = 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; - if (JS_ToBoolFree(ctx, ret)) { - if (JS_IteratorClose(ctx, this_val, FALSE) < 0) - r = JS_EXCEPTION; - else - r = JS_TRUE; - break; - } - index_val = JS_UNDEFINED; - ret = JS_UNDEFINED; - item = JS_UNDEFINED; - } - JS_FreeValue(ctx, func); - JS_FreeValue(ctx, method); - return r; -exception: - JS_IteratorClose(ctx, this_val, TRUE); - JS_FreeValue(ctx, func); - JS_FreeValue(ctx, method); - return JS_EXCEPTION; -} - -static JSValue js_iterator_proto_take(JSContext *ctx, JSValue this_val, - int argc, JSValue *argv) -{ - JSValue v; - double dlimit; - int64_t limit; - if (!JS_IsObject(this_val)) - return JS_ThrowTypeError(ctx, "Iterator.prototype.take called on non-object"); - v = JS_ToNumber(ctx, argv[0]); - if (JS_IsException(v)) - return JS_EXCEPTION; - // Check for Infinity. - if (JS_ToFloat64(ctx, &dlimit, v)) { - JS_FreeValue(ctx, v); - return JS_EXCEPTION; - } - if (isnan(dlimit)) { - JS_FreeValue(ctx, v); - goto fail; - } - if (!isfinite(dlimit)) { - JS_FreeValue(ctx, v); - if (dlimit < 0) - goto fail; - else - limit = MAX_SAFE_INTEGER; - } else { - v = JS_ToIntegerFree(ctx, v); - if (JS_IsException(v)) - return JS_EXCEPTION; - if (JS_ToInt64Free(ctx, &limit, v)) - return JS_EXCEPTION; - } - if (limit < 0) { - fail: - return JS_ThrowRangeError(ctx, "must be positive"); - } - return js_create_iterator_helper(ctx, this_val, JS_ITERATOR_HELPER_KIND_TAKE, JS_UNDEFINED, limit); -} - static JSValue js_iterator_proto_toArray(JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { @@ -40578,8 +40518,8 @@ static JSValue js_iterator_proto_toArray(JSContext *ctx, JSValue this_val, BOOL done; result = JS_UNDEFINED; - if (!JS_IsObject(this_val)) - return JS_ThrowTypeError(ctx, "Iterator.prototype.toArray called on non-object"); + if (check_iterator(ctx, this_val) < 0) + return JS_EXCEPTION; method = JS_GetProperty(ctx, this_val, JS_ATOM_next); if (JS_IsException(method)) return JS_EXCEPTION; @@ -40621,9 +40561,8 @@ static JSValue js_iterator_proto_set_toStringTag(JSContext *ctx, JSValue this_va { int res; - if (JS_VALUE_GET_TAG(this_val) != JS_TAG_OBJECT) - return JS_ThrowTypeError(ctx, - "set Iterator.prototype[Symbol.toStringTag] called on non-object"); + if (check_iterator(ctx, this_val) < 0) + return JS_EXCEPTION; if (js_same_value(ctx, this_val, ctx->class_proto[JS_CLASS_ITERATOR])) return JS_ThrowTypeError(ctx, "Cannot assign to read only property"); res = JS_GetOwnProperty(ctx, NULL, this_val, JS_ATOM_Symbol_toStringTag); @@ -40639,17 +40578,6 @@ static JSValue js_iterator_proto_set_toStringTag(JSContext *ctx, JSValue this_va return JS_UNDEFINED; } -typedef struct JSIteratorHelperData { - JSIteratorHelperKindEnum kind; - JSValue obj; - JSValue next; - JSValue func; // predicate (filter) or mapper (flatMap, map) - JSValue inner; // innerValue (flatMap) - int64_t count; // limit (drop, take) or counter (filter, map, flatMap) - BOOL executing; - BOOL done; -} JSIteratorHelperData; - static void js_iterator_helper_finalizer(JSRuntime *rt, JSValue val) { JSObject *p = JS_VALUE_GET_OBJ(val); @@ -40927,53 +40855,21 @@ static JSValue js_iterator_helper_next(JSContext *ctx, JSValue this_val, goto done; } -static JSValue js_create_iterator_helper(JSContext *ctx, JSValue iterator, - JSIteratorHelperKindEnum kind, JSValue func, int64_t count) -{ - JSValue obj, method; - JSIteratorHelperData *it; - - method = JS_GetProperty(ctx, iterator, JS_ATOM_next); - if (JS_IsException(method)) - return JS_EXCEPTION; - obj = JS_NewObjectClass(ctx, JS_CLASS_ITERATOR_HELPER); - if (JS_IsException(obj)) { - JS_FreeValue(ctx, method); - return JS_EXCEPTION; - } - it = js_malloc(ctx, sizeof(*it)); - if (!it) { - JS_FreeValue(ctx, obj); - JS_FreeValue(ctx, method); - return JS_EXCEPTION; - } - it->kind = kind; - it->obj = js_dup(iterator); - it->func = js_dup(func); - it->next = method; - it->inner = JS_UNDEFINED; - it->count = count; - it->executing = FALSE; - it->done = FALSE; - JS_SetOpaqueInternal(obj, it); - return obj; -} - static const JSCFunctionListEntry js_iterator_funcs[] = { JS_CFUNC_DEF("from", 1, js_iterator_from ), }; static const JSCFunctionListEntry js_iterator_proto_funcs[] = { - JS_CFUNC_DEF("drop", 1, js_iterator_proto_drop ), - JS_CFUNC_DEF("every", 1, js_iterator_proto_every ), - JS_CFUNC_DEF("filter", 1, js_iterator_proto_filter ), - JS_CFUNC_DEF("find", 1, js_iterator_proto_find ), - JS_CFUNC_DEF("flatMap", 1, js_iterator_proto_flatMap ), - JS_CFUNC_DEF("forEach", 1, js_iterator_proto_forEach ), - JS_CFUNC_DEF("map", 1, js_iterator_proto_map ), + JS_CFUNC_MAGIC_DEF("drop", 1, js_create_iterator_helper, JS_ITERATOR_HELPER_KIND_DROP ), + JS_CFUNC_MAGIC_DEF("filter", 1, js_create_iterator_helper, JS_ITERATOR_HELPER_KIND_FILTER ), + JS_CFUNC_MAGIC_DEF("flatMap", 1, js_create_iterator_helper, JS_ITERATOR_HELPER_KIND_FLAT_MAP ), + JS_CFUNC_MAGIC_DEF("map", 1, js_create_iterator_helper, JS_ITERATOR_HELPER_KIND_MAP ), + JS_CFUNC_MAGIC_DEF("take", 1, js_create_iterator_helper, JS_ITERATOR_HELPER_KIND_TAKE ), + JS_CFUNC_MAGIC_DEF("every", 1, js_iterator_proto_func, JS_ITERATOR_HELPER_KIND_EVERY ), + 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("reduce", 1, js_iterator_proto_reduce ), - JS_CFUNC_DEF("some", 1, js_iterator_proto_some ), - JS_CFUNC_DEF("take", 1, js_iterator_proto_take ), JS_CFUNC_DEF("toArray", 0, js_iterator_proto_toArray ), JS_CFUNC_DEF("[Symbol.iterator]", 0, js_iterator_proto_iterator ), JS_CGETSET_DEF("[Symbol.toStringTag]", js_iterator_proto_get_toStringTag, js_iterator_proto_set_toStringTag), From b01d2e2e2e1170d50e053e59399115b50c075c94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Ibarra=20Corretg=C3=A9?= Date: Mon, 18 Nov 2024 10:31:50 +0100 Subject: [PATCH 2/3] fixup! --- quickjs.c | 320 +++++++++++++++++++++++++++--------------------------- 1 file changed, 160 insertions(+), 160 deletions(-) diff --git a/quickjs.c b/quickjs.c index af45ca10..50f601ac 100644 --- a/quickjs.c +++ b/quickjs.c @@ -40199,14 +40199,14 @@ static int check_iterator(JSContext *ctx, JSValue obj) } typedef struct JSIteratorHelperData { - JSIteratorHelperKindEnum kind; JSValue obj; JSValue next; JSValue func; // predicate (filter) or mapper (flatMap, map) JSValue inner; // innerValue (flatMap) int64_t count; // limit (drop, take) or counter (filter, map, flatMap) - BOOL executing; - BOOL done; + JSIteratorHelperKindEnum kind; + uint8_t executing : 1; + uint8_t done : 1; } JSIteratorHelperData; static JSValue js_create_iterator_helper(JSContext *ctx, JSValue this_val, @@ -40222,54 +40222,54 @@ static JSValue js_create_iterator_helper(JSContext *ctx, JSValue this_val, count = 0; switch(magic) { - case JS_ITERATOR_HELPER_KIND_DROP: - case JS_ITERATOR_HELPER_KIND_TAKE: - { - JSValue v; - double dlimit; - v = JS_ToNumber(ctx, argv[0]); + case JS_ITERATOR_HELPER_KIND_DROP: + case JS_ITERATOR_HELPER_KIND_TAKE: + { + JSValue v; + double dlimit; + v = JS_ToNumber(ctx, argv[0]); + if (JS_IsException(v)) + return JS_EXCEPTION; + // Check for Infinity. + if (JS_ToFloat64(ctx, &dlimit, v)) { + JS_FreeValue(ctx, v); + return JS_EXCEPTION; + } + if (isnan(dlimit)) { + JS_FreeValue(ctx, v); + goto fail; + } + if (!isfinite(dlimit)) { + JS_FreeValue(ctx, v); + if (dlimit < 0) + goto fail; + else + count = MAX_SAFE_INTEGER; + } else { + v = JS_ToIntegerFree(ctx, v); if (JS_IsException(v)) return JS_EXCEPTION; - // Check for Infinity. - if (JS_ToFloat64(ctx, &dlimit, v)) { - JS_FreeValue(ctx, v); + if (JS_ToInt64Free(ctx, &count, v)) return JS_EXCEPTION; - } - if (isnan(dlimit)) { - JS_FreeValue(ctx, v); - goto fail; - } - if (!isfinite(dlimit)) { - JS_FreeValue(ctx, v); - if (dlimit < 0) - goto fail; - else - count = MAX_SAFE_INTEGER; - } else { - v = JS_ToIntegerFree(ctx, v); - if (JS_IsException(v)) - return JS_EXCEPTION; - if (JS_ToInt64Free(ctx, &count, v)) - return JS_EXCEPTION; - } - if (count < 0) { - fail: - return JS_ThrowRangeError(ctx, "must be positive"); - } } - break; - case JS_ITERATOR_HELPER_KIND_FILTER: - case JS_ITERATOR_HELPER_KIND_FLAT_MAP: - case JS_ITERATOR_HELPER_KIND_MAP: - { - func = argv[0]; - if (check_function(ctx, func)) - return JS_EXCEPTION; + if (count < 0) { + fail: + return JS_ThrowRangeError(ctx, "must be positive"); } - break; - default: - abort(); - break; + } + break; + case JS_ITERATOR_HELPER_KIND_FILTER: + case JS_ITERATOR_HELPER_KIND_FLAT_MAP: + case JS_ITERATOR_HELPER_KIND_MAP: + { + func = argv[0]; + if (check_function(ctx, func)) + return JS_EXCEPTION; + } + break; + default: + abort(); + break; } method = JS_GetProperty(ctx, this_val, JS_ATOM_next); @@ -40292,8 +40292,8 @@ static JSValue js_create_iterator_helper(JSContext *ctx, JSValue this_val, it->next = method; it->inner = JS_UNDEFINED; it->count = count; - it->executing = FALSE; - it->done = FALSE; + it->executing = 0; + it->done = 0; JS_SetOpaqueInternal(obj, it); return obj; } @@ -40318,124 +40318,124 @@ static JSValue js_iterator_proto_func(JSContext *ctx, JSValue this_val, r = JS_UNDEFINED; switch(magic) { - case JS_ITERATOR_HELPER_KIND_EVERY: - { - r = JS_TRUE; - for (idx = 0; /*empty*/; idx++) { - item = JS_IteratorNext(ctx, this_val, method, 0, NULL, &done); - if (JS_IsException(item)) - goto fail; - if (done) - break; - index_val = js_int64(idx); - args[0] = item; - args[1] = 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 fail; - if (!JS_ToBoolFree(ctx, ret)) { - if (JS_IteratorClose(ctx, this_val, FALSE) < 0) - r = JS_EXCEPTION; - else - r = JS_FALSE; - break; - } - index_val = JS_UNDEFINED; - ret = JS_UNDEFINED; - item = JS_UNDEFINED; + case JS_ITERATOR_HELPER_KIND_EVERY: + { + r = JS_TRUE; + for (idx = 0; /*empty*/; idx++) { + item = JS_IteratorNext(ctx, this_val, method, 0, NULL, &done); + if (JS_IsException(item)) + goto fail; + if (done) + break; + index_val = js_int64(idx); + args[0] = item; + args[1] = 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 fail; + if (!JS_ToBoolFree(ctx, ret)) { + if (JS_IteratorClose(ctx, this_val, FALSE) < 0) + r = JS_EXCEPTION; + else + r = JS_FALSE; + break; } + index_val = JS_UNDEFINED; + ret = JS_UNDEFINED; + item = JS_UNDEFINED; } - break; - case JS_ITERATOR_HELPER_KIND_FIND: - { - for (idx = 0; /*empty*/; idx++) { - item = JS_IteratorNext(ctx, this_val, method, 0, NULL, &done); - if (JS_IsException(item)) - goto fail; - if (done) - break; - index_val = js_int64(idx); - args[0] = item; - args[1] = index_val; - ret = JS_Call(ctx, func, JS_UNDEFINED, countof(args), args); - JS_FreeValue(ctx, index_val); - if (JS_IsException(ret)) { + } + break; + case JS_ITERATOR_HELPER_KIND_FIND: + { + for (idx = 0; /*empty*/; idx++) { + item = JS_IteratorNext(ctx, this_val, method, 0, NULL, &done); + if (JS_IsException(item)) + goto fail; + if (done) + break; + index_val = js_int64(idx); + args[0] = item; + args[1] = index_val; + ret = JS_Call(ctx, func, JS_UNDEFINED, countof(args), args); + JS_FreeValue(ctx, index_val); + if (JS_IsException(ret)) { + JS_FreeValue(ctx, item); + goto fail; + } + if (JS_ToBoolFree(ctx, ret)) { + if (JS_IteratorClose(ctx, this_val, FALSE) < 0) { JS_FreeValue(ctx, item); - goto fail; - } - if (JS_ToBoolFree(ctx, ret)) { - if (JS_IteratorClose(ctx, this_val, FALSE) < 0) { - JS_FreeValue(ctx, item); - r = JS_EXCEPTION; - } else { - r = item; - } - break; + r = JS_EXCEPTION; + } else { + r = item; } - index_val = JS_UNDEFINED; - ret = JS_UNDEFINED; - item = JS_UNDEFINED; + break; } + index_val = JS_UNDEFINED; + ret = JS_UNDEFINED; + item = JS_UNDEFINED; } - break; - case JS_ITERATOR_HELPER_KIND_FOR_EACH: - { - for (idx = 0; /*empty*/; idx++) { - item = JS_IteratorNext(ctx, this_val, method, 0, NULL, &done); - if (JS_IsException(item)) - goto fail; - if (done) - break; - index_val = js_int64(idx); - args[0] = item; - args[1] = 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 fail; - JS_FreeValue(ctx, ret); - index_val = JS_UNDEFINED; - ret = JS_UNDEFINED; - item = JS_UNDEFINED; - } + } + break; + case JS_ITERATOR_HELPER_KIND_FOR_EACH: + { + for (idx = 0; /*empty*/; idx++) { + item = JS_IteratorNext(ctx, this_val, method, 0, NULL, &done); + if (JS_IsException(item)) + goto fail; + if (done) + break; + index_val = js_int64(idx); + args[0] = item; + args[1] = 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 fail; + JS_FreeValue(ctx, ret); + index_val = JS_UNDEFINED; + ret = JS_UNDEFINED; + item = JS_UNDEFINED; } - break; - case JS_ITERATOR_HELPER_KIND_SOME: - { - r = JS_FALSE; - for (idx = 0; /*empty*/; idx++) { - item = JS_IteratorNext(ctx, this_val, method, 0, NULL, &done); - if (JS_IsException(item)) - goto fail; - if (done) - break; - index_val = js_int64(idx); - args[0] = item; - args[1] = 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 fail; - if (JS_ToBoolFree(ctx, ret)) { - if (JS_IteratorClose(ctx, this_val, FALSE) < 0) - r = JS_EXCEPTION; - else - r = JS_TRUE; - break; - } - index_val = JS_UNDEFINED; - ret = JS_UNDEFINED; - item = JS_UNDEFINED; + } + break; + case JS_ITERATOR_HELPER_KIND_SOME: + { + r = JS_FALSE; + for (idx = 0; /*empty*/; idx++) { + item = JS_IteratorNext(ctx, this_val, method, 0, NULL, &done); + if (JS_IsException(item)) + goto fail; + if (done) + break; + index_val = js_int64(idx); + args[0] = item; + args[1] = 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 fail; + if (JS_ToBoolFree(ctx, ret)) { + if (JS_IteratorClose(ctx, this_val, FALSE) < 0) + r = JS_EXCEPTION; + else + r = JS_TRUE; + break; } + index_val = JS_UNDEFINED; + ret = JS_UNDEFINED; + item = JS_UNDEFINED; } - break; - default: - abort(); - break; + } + break; + default: + abort(); + break; } JS_FreeValue(ctx, func); @@ -40623,7 +40623,7 @@ static JSValue js_iterator_helper_next(JSContext *ctx, JSValue this_val, return JS_UNDEFINED; } - it->executing = TRUE; + it->executing = 1; switch (it->kind) { case JS_ITERATOR_HELPER_KIND_DROP: @@ -40843,8 +40843,8 @@ static JSValue js_iterator_helper_next(JSContext *ctx, JSValue this_val, } done: - it->done = magic == GEN_MAGIC_NEXT ? *pdone : TRUE; - it->executing = FALSE; + it->done = magic == GEN_MAGIC_NEXT ? *pdone : 1; + it->executing = 0; return ret; fail: if (it) { From 08dc5e6621eed12895ee7a79772afb48bd9a718a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Ibarra=20Corretg=C3=A9?= Date: Mon, 18 Nov 2024 22:27:26 +0100 Subject: [PATCH 3/3] fixup! --- quickjs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quickjs.c b/quickjs.c index 50f601ac..2eaa127b 100644 --- a/quickjs.c +++ b/quickjs.c @@ -40204,7 +40204,7 @@ typedef struct JSIteratorHelperData { JSValue func; // predicate (filter) or mapper (flatMap, map) JSValue inner; // innerValue (flatMap) int64_t count; // limit (drop, take) or counter (filter, map, flatMap) - JSIteratorHelperKindEnum kind; + JSIteratorHelperKindEnum kind : 8; uint8_t executing : 1; uint8_t done : 1; } JSIteratorHelperData;