@@ -44200,6 +44200,7 @@ typedef struct JSIteratorHelperData {
4420044200 JSValue next;
4420144201 JSValue func; // predicate (filter) or mapper (flatMap, map)
4420244202 JSValue inner; // innerValue (flatMap)
44203+ JSValue inner_next; // innerValue next method (flatMap)
4420344204 int64_t count; // limit (drop, take) or counter (filter, map, flatMap)
4420444205 JSIteratorHelperKindEnum kind : 8;
4420544206 uint8_t executing : 1;
@@ -44271,6 +44272,7 @@ static JSValue js_create_iterator_helper(JSContext *ctx, JSValueConst this_val,
4427144272 it->func = JS_DupValue(ctx, func);
4427244273 it->next = method;
4427344274 it->inner = JS_UNDEFINED;
44275+ it->inner_next = JS_UNDEFINED;
4427444276 it->count = count;
4427544277 it->executing = 0;
4427644278 it->done = 0;
@@ -44582,6 +44584,7 @@ static void js_iterator_helper_finalizer(JSRuntime *rt, JSValue val)
4458244584 JS_FreeValueRT(rt, it->func);
4458344585 JS_FreeValueRT(rt, it->next);
4458444586 JS_FreeValueRT(rt, it->inner);
44587+ JS_FreeValueRT(rt, it->inner_next);
4458544588 js_free_rt(rt, it);
4458644589 }
4458744590}
@@ -44596,6 +44599,7 @@ static void js_iterator_helper_mark(JSRuntime *rt, JSValueConst val,
4459644599 JS_MarkValue(rt, it->func, mark_func);
4459744600 JS_MarkValue(rt, it->next, mark_func);
4459844601 JS_MarkValue(rt, it->inner, mark_func);
44602+ JS_MarkValue(rt, it->inner_next, mark_func);
4459944603 }
4460044604}
4460144605
@@ -44620,183 +44624,154 @@ static JSValue js_iterator_helper_next(JSContext *ctx, JSValueConst this_val,
4462044624
4462144625 it->executing = 1;
4462244626
44627+ if (magic == GEN_MAGIC_RETURN) {
44628+ *pdone = TRUE;
44629+ ret = JS_UNDEFINED;
44630+
44631+ if (!JS_IsUndefined(it->inner)) {
44632+ if (JS_IteratorClose(ctx, it->inner, FALSE))
44633+ ret = JS_EXCEPTION;
44634+ JS_FreeValue(ctx, it->inner);
44635+ JS_FreeValue(ctx, it->inner_next);
44636+ it->inner = JS_UNDEFINED;
44637+ it->inner_next = JS_UNDEFINED;
44638+ }
44639+ if (JS_IteratorClose(ctx, it->obj, JS_IsException(ret)))
44640+ ret = JS_EXCEPTION;
44641+ goto done;
44642+ }
44643+
4462344644 switch (it->kind) {
4462444645 case JS_ITERATOR_HELPER_KIND_DROP:
4462544646 {
44626- JSValue item, method;
44627- if (magic == GEN_MAGIC_NEXT) {
44628- method = JS_DupValue(ctx, it->next);
44629- } else {
44630- method = JS_GetProperty(ctx, it->obj, JS_ATOM_return);
44631- if (JS_IsException(method))
44632- goto fail;
44633- }
44647+ JSValue item;
4463444648 while (it->count > 0) {
4463544649 it->count--;
44636- item = JS_IteratorNext(ctx, it->obj, method, 0, NULL, pdone);
44637- if (JS_IsException(item)) {
44638- JS_FreeValue(ctx, method);
44650+ item = JS_IteratorNext(ctx, it->obj, it->next, 0, NULL, pdone);
44651+ if (JS_IsException(item))
4463944652 goto fail_no_close;
44640- }
4464144653 JS_FreeValue(ctx, item);
44642- if (magic == GEN_MAGIC_RETURN)
44643- *pdone = TRUE;
4464444654 if (*pdone) {
44645- JS_FreeValue(ctx, method);
4464644655 ret = JS_UNDEFINED;
4464744656 goto done;
4464844657 }
4464944658 }
4465044659
44651- item = JS_IteratorNext(ctx, it->obj, method, 0, NULL, pdone);
44652- JS_FreeValue(ctx, method);
44660+ item = JS_IteratorNext(ctx, it->obj, it->next, 0, NULL, pdone);
4465344661 if (JS_IsException(item))
4465444662 goto fail_no_close;
4465544663 ret = item;
44656- goto done;
4465744664 }
4465844665 break;
4465944666 case JS_ITERATOR_HELPER_KIND_FILTER:
4466044667 {
44661- JSValue item, method, selected, index_val;
44668+ JSValue item, selected, index_val;
4466244669 JSValueConst args[2];
44663- if (magic == GEN_MAGIC_NEXT) {
44664- method = JS_DupValue(ctx, it->next);
44665- } else {
44666- method = JS_GetProperty(ctx, it->obj, JS_ATOM_return);
44667- if (JS_IsException(method))
44668- goto fail;
44669- }
44670- filter_again:
44671- item = JS_IteratorNext(ctx, it->obj, method, 0, NULL, pdone);
44672- if (JS_IsException(item)) {
44673- JS_FreeValue(ctx, method);
44674- goto fail_no_close;
44675- }
44676- if (*pdone || magic == GEN_MAGIC_RETURN) {
44677- JS_FreeValue(ctx, method);
44678- ret = item;
44679- goto done;
44680- }
44681- index_val = JS_NewInt64(ctx, it->count++);
44682- args[0] = item;
44683- args[1] = index_val;
44684- selected = JS_Call(ctx, it->func, JS_UNDEFINED, countof(args), args);
44685- JS_FreeValue(ctx, index_val);
44686- if (JS_IsException(selected)) {
44687- JS_FreeValue(ctx, item);
44688- JS_FreeValue(ctx, method);
44689- goto fail;
44690- }
44691- if (JS_ToBoolFree(ctx, selected)) {
44692- JS_FreeValue(ctx, method);
44693- ret = item;
44694- goto done;
44695- }
44696- JS_FreeValue(ctx, item);
44697- goto filter_again;
44698- }
44699- break;
44700- case JS_ITERATOR_HELPER_KIND_FLAT_MAP:
44701- {
44702- JSValue item, method, index_val, iter;
44703- JSValueConst args[2];
44704- flat_map_again:
44705- if (JS_IsUndefined(it->inner)) {
44706- if (magic == GEN_MAGIC_NEXT) {
44707- method = JS_DupValue(ctx, it->next);
44708- } else {
44709- method = JS_GetProperty(ctx, it->obj, JS_ATOM_return);
44710- if (JS_IsException(method))
44711- goto fail;
44712- }
44713- item = JS_IteratorNext(ctx, it->obj, method, 0, NULL, pdone);
44714- JS_FreeValue(ctx, method);
44670+ for(;;) {
44671+ item = JS_IteratorNext(ctx, it->obj, it->next, 0, NULL, pdone);
4471544672 if (JS_IsException(item))
4471644673 goto fail_no_close;
44717- if (*pdone || magic == GEN_MAGIC_RETURN ) {
44674+ if (*pdone) {
4471844675 ret = item;
44719- goto done ;
44676+ break ;
4472044677 }
4472144678 index_val = JS_NewInt64(ctx, it->count++);
4472244679 args[0] = item;
4472344680 args[1] = index_val;
44724- ret = JS_Call(ctx, it->func, JS_UNDEFINED, countof(args), args);
44725- JS_FreeValue(ctx, item);
44681+ selected = JS_Call(ctx, it->func, JS_UNDEFINED, countof(args), args);
4472644682 JS_FreeValue(ctx, index_val);
44727- if (JS_IsException(ret))
44728- goto fail;
44729- if (!JS_IsObject(ret)) {
44730- JS_FreeValue(ctx, ret);
44731- JS_ThrowTypeError(ctx, "not an object");
44683+ if (JS_IsException(selected)) {
44684+ JS_FreeValue(ctx, item);
4473244685 goto fail;
4473344686 }
44734- method = JS_GetProperty(ctx, ret, JS_ATOM_Symbol_iterator);
44735- if (JS_IsException(method)) {
44736- JS_FreeValue(ctx, ret);
44737- goto fail;
44687+ if (JS_ToBoolFree(ctx, selected)) {
44688+ ret = item;
44689+ break;
4473844690 }
44739- if (JS_IsNull(method) || JS_IsUndefined(method)) {
44740- JS_FreeValue(ctx, method);
44741- iter = ret;
44742- } else {
44743- iter = JS_GetIterator2(ctx, ret, method);
44744- JS_FreeValue(ctx, method);
44745- JS_FreeValue(ctx, ret);
44746- if (JS_IsException(iter))
44691+ JS_FreeValue(ctx, item);
44692+ }
44693+ }
44694+ break;
44695+ case JS_ITERATOR_HELPER_KIND_FLAT_MAP:
44696+ {
44697+ JSValue item, method, index_val, iter;
44698+ JSValueConst args[2];
44699+ for(;;) {
44700+ if (JS_IsUndefined(it->inner)) {
44701+ item = JS_IteratorNext(ctx, it->obj, it->next, 0, NULL, pdone);
44702+ if (JS_IsException(item))
44703+ goto fail_no_close;
44704+ if (*pdone) {
44705+ ret = item;
44706+ break;
44707+ }
44708+ index_val = JS_NewInt64(ctx, it->count++);
44709+ args[0] = item;
44710+ args[1] = index_val;
44711+ ret = JS_Call(ctx, it->func, JS_UNDEFINED, countof(args), args);
44712+ JS_FreeValue(ctx, item);
44713+ JS_FreeValue(ctx, index_val);
44714+ if (JS_IsException(ret))
4474744715 goto fail;
44748- }
44716+ if (!JS_IsObject(ret)) {
44717+ JS_FreeValue(ctx, ret);
44718+ JS_ThrowTypeError(ctx, "not an object");
44719+ goto fail;
44720+ }
44721+ method = JS_GetProperty(ctx, ret, JS_ATOM_Symbol_iterator);
44722+ if (JS_IsException(method)) {
44723+ JS_FreeValue(ctx, ret);
44724+ goto fail;
44725+ }
44726+ if (JS_IsNull(method) || JS_IsUndefined(method)) {
44727+ JS_FreeValue(ctx, method);
44728+ iter = ret;
44729+ } else {
44730+ iter = JS_GetIterator2(ctx, ret, method);
44731+ JS_FreeValue(ctx, method);
44732+ JS_FreeValue(ctx, ret);
44733+ if (JS_IsException(iter))
44734+ goto fail;
44735+ }
4474944736
44750- it->inner = iter;
44751- }
44737+ it->inner = iter;
44738+ method = JS_GetProperty(ctx, it->inner, JS_ATOM_next);
44739+ if (JS_IsException(method))
44740+ goto inner_fail;
44741+ it->inner_next = method;
44742+ }
4475244743
44753- if (magic == GEN_MAGIC_NEXT)
44754- method = JS_GetProperty(ctx, it->inner, JS_ATOM_next);
44755- else
44756- method = JS_GetProperty(ctx, it->inner, JS_ATOM_return);
44757- if (JS_IsException(method)) {
44758- inner_fail:
44759- JS_IteratorClose(ctx, it->inner, FALSE);
44760- JS_FreeValue(ctx, it->inner);
44761- it->inner = JS_UNDEFINED;
44762- goto fail;
44763- }
44764- if (magic == GEN_MAGIC_RETURN && (JS_IsUndefined(method) || JS_IsNull(method))) {
44765- goto inner_end;
44766- } else {
44767- item = JS_IteratorNext(ctx, it->inner, method, 0, NULL, pdone);
44768- JS_FreeValue(ctx, method);
44769- if (JS_IsException(item))
44770- goto inner_fail;
44771- }
44772- if (*pdone) {
44773- inner_end:
44744+ item = JS_IteratorNext(ctx, it->inner, it->inner_next, 0, NULL, pdone);
44745+ if (JS_IsException(item)) {
44746+ inner_fail:
44747+ JS_IteratorClose(ctx, it->inner, FALSE);
44748+ JS_FreeValue(ctx, it->inner);
44749+ JS_FreeValue(ctx, it->inner_next);
44750+ it->inner = JS_UNDEFINED;
44751+ it->inner_next = JS_UNDEFINED;
44752+ goto fail;
44753+ }
44754+ if (!*pdone) {
44755+ ret = item;
44756+ break;
44757+ }
4477444758 *pdone = FALSE; // The outer iterator must continue.
4477544759 JS_IteratorClose(ctx, it->inner, FALSE);
4477644760 JS_FreeValue(ctx, it->inner);
44761+ JS_FreeValue(ctx, it->inner_next);
4477744762 it->inner = JS_UNDEFINED;
44778- goto flat_map_again ;
44763+ it->inner_next = JS_UNDEFINED ;
4477944764 }
44780- ret = item;
44781- goto done;
4478244765 }
4478344766 break;
4478444767 case JS_ITERATOR_HELPER_KIND_MAP:
4478544768 {
44786- JSValue item, method, index_val;
44769+ JSValue item, index_val;
4478744770 JSValueConst args[2];
44788- if (magic == GEN_MAGIC_NEXT) {
44789- method = JS_DupValue(ctx, it->next);
44790- } else {
44791- method = JS_GetProperty(ctx, it->obj, JS_ATOM_return);
44792- if (JS_IsException(method))
44793- goto fail;
44794- }
44795- item = JS_IteratorNext(ctx, it->obj, method, 0, NULL, pdone);
44796- JS_FreeValue(ctx, method);
44771+ item = JS_IteratorNext(ctx, it->obj, it->next, 0, NULL, pdone);
4479744772 if (JS_IsException(item))
4479844773 goto fail_no_close;
44799- if (*pdone || magic == GEN_MAGIC_RETURN ) {
44774+ if (*pdone) {
4480044775 ret = item;
4480144776 goto done;
4480244777 }
@@ -44808,43 +44783,32 @@ static JSValue js_iterator_helper_next(JSContext *ctx, JSValueConst this_val,
4480844783 JS_FreeValue(ctx, item);
4480944784 if (JS_IsException(ret))
4481044785 goto fail;
44811- goto done;
4481244786 }
4481344787 break;
4481444788 case JS_ITERATOR_HELPER_KIND_TAKE:
4481544789 {
44816- JSValue item, method ;
44790+ JSValue item;
4481744791 if (it->count > 0) {
44818- if (magic == GEN_MAGIC_NEXT) {
44819- method = JS_DupValue(ctx, it->next);
44820- } else {
44821- method = JS_GetProperty(ctx, it->obj, JS_ATOM_return);
44822- if (JS_IsException(method))
44823- goto fail;
44824- }
4482544792 it->count--;
44826- item = JS_IteratorNext(ctx, it->obj, method, 0, NULL, pdone);
44827- JS_FreeValue(ctx, method);
44793+ item = JS_IteratorNext(ctx, it->obj, it->next, 0, NULL, pdone);
4482844794 if (JS_IsException(item))
4482944795 goto fail_no_close;
4483044796 ret = item;
44831- goto done;
44797+ } else {
44798+ *pdone = TRUE;
44799+ if (JS_IteratorClose(ctx, it->obj, FALSE))
44800+ ret = JS_EXCEPTION;
44801+ else
44802+ ret = JS_UNDEFINED;
4483244803 }
44833-
44834- *pdone = TRUE;
44835- if (JS_IteratorClose(ctx, it->obj, FALSE))
44836- ret = JS_EXCEPTION;
44837- else
44838- ret = JS_UNDEFINED;
44839- goto done;
4484044804 }
4484144805 break;
4484244806 default:
4484344807 abort();
4484444808 }
4484544809
4484644810 done:
44847- it->done = magic == GEN_MAGIC_NEXT ? *pdone : 1 ;
44811+ it->done = *pdone;
4484844812 it->executing = 0;
4484944813 return ret;
4485044814 fail:
0 commit comments