added the Iterator object

This commit is contained in:
Fabrice Bellard 2025-09-20 16:05:36 +02:00
parent 0377dab4f2
commit 982b7aa14f
2 changed files with 36 additions and 11 deletions

View File

@ -230,6 +230,7 @@ DEF(Map, "Map")
DEF(Set, "Set") /* Map + 1 */ DEF(Set, "Set") /* Map + 1 */
DEF(WeakMap, "WeakMap") /* Map + 2 */ DEF(WeakMap, "WeakMap") /* Map + 2 */
DEF(WeakSet, "WeakSet") /* Map + 3 */ DEF(WeakSet, "WeakSet") /* Map + 3 */
DEF(Iterator, "Iterator")
DEF(Map_Iterator, "Map Iterator") DEF(Map_Iterator, "Map Iterator")
DEF(Set_Iterator, "Set Iterator") DEF(Set_Iterator, "Set Iterator")
DEF(Array_Iterator, "Array Iterator") DEF(Array_Iterator, "Array Iterator")

View File

@ -157,6 +157,7 @@ enum {
JS_CLASS_SET, /* u.map_state */ JS_CLASS_SET, /* u.map_state */
JS_CLASS_WEAKMAP, /* u.map_state */ JS_CLASS_WEAKMAP, /* u.map_state */
JS_CLASS_WEAKSET, /* u.map_state */ JS_CLASS_WEAKSET, /* u.map_state */
JS_CLASS_ITERATOR, /* u.map_iterator_data */
JS_CLASS_MAP_ITERATOR, /* u.map_iterator_data */ JS_CLASS_MAP_ITERATOR, /* u.map_iterator_data */
JS_CLASS_SET_ITERATOR, /* u.map_iterator_data */ JS_CLASS_SET_ITERATOR, /* u.map_iterator_data */
JS_CLASS_ARRAY_ITERATOR, /* u.array_iterator_data */ JS_CLASS_ARRAY_ITERATOR, /* u.array_iterator_data */
@ -453,7 +454,7 @@ struct JSContext {
JSValue regexp_ctor; JSValue regexp_ctor;
JSValue promise_ctor; JSValue promise_ctor;
JSValue native_error_proto[JS_NATIVE_ERROR_COUNT]; JSValue native_error_proto[JS_NATIVE_ERROR_COUNT];
JSValue iterator_proto; JSValue iterator_ctor;
JSValue async_iterator_proto; JSValue async_iterator_proto;
JSValue array_proto_values; JSValue array_proto_values;
JSValue throw_type_error; JSValue throw_type_error;
@ -1540,6 +1541,7 @@ static JSClassShortDef const js_std_class_def[] = {
{ JS_ATOM_Set, js_map_finalizer, js_map_mark }, /* JS_CLASS_SET */ { JS_ATOM_Set, js_map_finalizer, js_map_mark }, /* JS_CLASS_SET */
{ JS_ATOM_WeakMap, js_map_finalizer, js_map_mark }, /* JS_CLASS_WEAKMAP */ { JS_ATOM_WeakMap, js_map_finalizer, js_map_mark }, /* JS_CLASS_WEAKMAP */
{ JS_ATOM_WeakSet, js_map_finalizer, js_map_mark }, /* JS_CLASS_WEAKSET */ { JS_ATOM_WeakSet, js_map_finalizer, js_map_mark }, /* JS_CLASS_WEAKSET */
{ JS_ATOM_Iterator, NULL, NULL }, /* JS_CLASS_ITERATOR */
{ JS_ATOM_Map_Iterator, js_map_iterator_finalizer, js_map_iterator_mark }, /* JS_CLASS_MAP_ITERATOR */ { JS_ATOM_Map_Iterator, js_map_iterator_finalizer, js_map_iterator_mark }, /* JS_CLASS_MAP_ITERATOR */
{ JS_ATOM_Set_Iterator, js_map_iterator_finalizer, js_map_iterator_mark }, /* JS_CLASS_SET_ITERATOR */ { JS_ATOM_Set_Iterator, js_map_iterator_finalizer, js_map_iterator_mark }, /* JS_CLASS_SET_ITERATOR */
{ JS_ATOM_Array_Iterator, js_array_iterator_finalizer, js_array_iterator_mark }, /* JS_CLASS_ARRAY_ITERATOR */ { JS_ATOM_Array_Iterator, js_array_iterator_finalizer, js_array_iterator_mark }, /* JS_CLASS_ARRAY_ITERATOR */
@ -2132,6 +2134,7 @@ JSContext *JS_NewContextRaw(JSRuntime *rt)
for(i = 0; i < rt->class_count; i++) for(i = 0; i < rt->class_count; i++)
ctx->class_proto[i] = JS_NULL; ctx->class_proto[i] = JS_NULL;
ctx->array_ctor = JS_NULL; ctx->array_ctor = JS_NULL;
ctx->iterator_ctor = JS_NULL;
ctx->regexp_ctor = JS_NULL; ctx->regexp_ctor = JS_NULL;
ctx->promise_ctor = JS_NULL; ctx->promise_ctor = JS_NULL;
init_list_head(&ctx->loaded_modules); init_list_head(&ctx->loaded_modules);
@ -2251,7 +2254,7 @@ static void JS_MarkContext(JSRuntime *rt, JSContext *ctx,
for(i = 0; i < rt->class_count; i++) { for(i = 0; i < rt->class_count; i++) {
JS_MarkValue(rt, ctx->class_proto[i], mark_func); JS_MarkValue(rt, ctx->class_proto[i], mark_func);
} }
JS_MarkValue(rt, ctx->iterator_proto, mark_func); JS_MarkValue(rt, ctx->iterator_ctor, mark_func);
JS_MarkValue(rt, ctx->async_iterator_proto, mark_func); JS_MarkValue(rt, ctx->async_iterator_proto, mark_func);
JS_MarkValue(rt, ctx->promise_ctor, mark_func); JS_MarkValue(rt, ctx->promise_ctor, mark_func);
JS_MarkValue(rt, ctx->array_ctor, mark_func); JS_MarkValue(rt, ctx->array_ctor, mark_func);
@ -2315,7 +2318,7 @@ void JS_FreeContext(JSContext *ctx)
JS_FreeValue(ctx, ctx->class_proto[i]); JS_FreeValue(ctx, ctx->class_proto[i]);
} }
js_free_rt(rt, ctx->class_proto); js_free_rt(rt, ctx->class_proto);
JS_FreeValue(ctx, ctx->iterator_proto); JS_FreeValue(ctx, ctx->iterator_ctor);
JS_FreeValue(ctx, ctx->async_iterator_proto); JS_FreeValue(ctx, ctx->async_iterator_proto);
JS_FreeValue(ctx, ctx->promise_ctor); JS_FreeValue(ctx, ctx->promise_ctor);
JS_FreeValue(ctx, ctx->array_ctor); JS_FreeValue(ctx, ctx->array_ctor);
@ -42161,12 +42164,24 @@ static JSValue js_array_iterator_next(JSContext *ctx, JSValueConst this_val,
} }
} }
static JSValue js_iterator_constructor(JSContext *ctx, JSValueConst new_target,
int argc, JSValueConst *argv)
{
if (JS_IsUndefined(new_target))
return JS_ThrowTypeError(ctx, "constructor requires 'new'");
/* XXX: cannot be invoked directly */
return js_create_from_ctor(ctx, new_target, JS_CLASS_ITERATOR);
}
static JSValue js_iterator_proto_iterator(JSContext *ctx, JSValueConst this_val, static JSValue js_iterator_proto_iterator(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv) int argc, JSValueConst *argv)
{ {
return JS_DupValue(ctx, this_val); return JS_DupValue(ctx, this_val);
} }
static const JSCFunctionListEntry js_iterator_funcs[] = {
};
static const JSCFunctionListEntry js_iterator_proto_funcs[] = { static const JSCFunctionListEntry js_iterator_proto_funcs[] = {
JS_CFUNC_DEF("[Symbol.iterator]", 0, js_iterator_proto_iterator ), JS_CFUNC_DEF("[Symbol.iterator]", 0, js_iterator_proto_iterator ),
}; };
@ -46343,7 +46358,7 @@ void JS_AddIntrinsicRegExp(JSContext *ctx)
JS_SetPropertyFunctionList(ctx, obj, js_regexp_funcs, countof(js_regexp_funcs)); JS_SetPropertyFunctionList(ctx, obj, js_regexp_funcs, countof(js_regexp_funcs));
ctx->class_proto[JS_CLASS_REGEXP_STRING_ITERATOR] = ctx->class_proto[JS_CLASS_REGEXP_STRING_ITERATOR] =
JS_NewObjectProto(ctx, ctx->iterator_proto); JS_NewObjectProto(ctx, ctx->class_proto[JS_CLASS_ITERATOR]);
JS_SetPropertyFunctionList(ctx, ctx->class_proto[JS_CLASS_REGEXP_STRING_ITERATOR], JS_SetPropertyFunctionList(ctx, ctx->class_proto[JS_CLASS_REGEXP_STRING_ITERATOR],
js_regexp_string_iterator_proto_funcs, js_regexp_string_iterator_proto_funcs,
countof(js_regexp_string_iterator_proto_funcs)); countof(js_regexp_string_iterator_proto_funcs));
@ -49935,7 +49950,7 @@ void JS_AddIntrinsicMapSet(JSContext *ctx)
for(i = 0; i < 2; i++) { for(i = 0; i < 2; i++) {
ctx->class_proto[JS_CLASS_MAP_ITERATOR + i] = ctx->class_proto[JS_CLASS_MAP_ITERATOR + i] =
JS_NewObjectProto(ctx, ctx->iterator_proto); JS_NewObjectProto(ctx, ctx->class_proto[JS_CLASS_ITERATOR]);
JS_SetPropertyFunctionList(ctx, ctx->class_proto[JS_CLASS_MAP_ITERATOR + i], JS_SetPropertyFunctionList(ctx, ctx->class_proto[JS_CLASS_MAP_ITERATOR + i],
js_map_proto_funcs_ptr[i + 4], js_map_proto_funcs_ptr[i + 4],
js_map_proto_funcs_count[i + 4]); js_map_proto_funcs_count[i + 4]);
@ -53093,11 +53108,17 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx)
ctx->native_error_proto[i]); ctx->native_error_proto[i]);
} }
/* Iterator prototype */ /* Iterator */
ctx->iterator_proto = JS_NewObject(ctx); ctx->class_proto[JS_CLASS_ITERATOR] = JS_NewObject(ctx);
JS_SetPropertyFunctionList(ctx, ctx->iterator_proto, JS_SetPropertyFunctionList(ctx, ctx->class_proto[JS_CLASS_ITERATOR],
js_iterator_proto_funcs, js_iterator_proto_funcs,
countof(js_iterator_proto_funcs)); countof(js_iterator_proto_funcs));
obj = JS_NewGlobalCConstructor(ctx, "Iterator", js_iterator_constructor, 0,
ctx->class_proto[JS_CLASS_ITERATOR]);
ctx->iterator_ctor = JS_DupValue(ctx, obj);
JS_SetPropertyFunctionList(ctx, obj,
js_iterator_funcs,
countof(js_iterator_funcs));
/* Array */ /* Array */
JS_SetPropertyFunctionList(ctx, ctx->class_proto[JS_CLASS_ARRAY], JS_SetPropertyFunctionList(ctx, ctx->class_proto[JS_CLASS_ARRAY],
@ -53144,7 +53165,8 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx)
ctx->array_proto_values = ctx->array_proto_values =
JS_GetProperty(ctx, ctx->class_proto[JS_CLASS_ARRAY], JS_ATOM_values); JS_GetProperty(ctx, ctx->class_proto[JS_CLASS_ARRAY], JS_ATOM_values);
ctx->class_proto[JS_CLASS_ARRAY_ITERATOR] = JS_NewObjectProto(ctx, ctx->iterator_proto); ctx->class_proto[JS_CLASS_ARRAY_ITERATOR] =
JS_NewObjectProto(ctx, ctx->class_proto[JS_CLASS_ITERATOR]);
JS_SetPropertyFunctionList(ctx, ctx->class_proto[JS_CLASS_ARRAY_ITERATOR], JS_SetPropertyFunctionList(ctx, ctx->class_proto[JS_CLASS_ARRAY_ITERATOR],
js_array_iterator_proto_funcs, js_array_iterator_proto_funcs,
countof(js_array_iterator_proto_funcs)); countof(js_array_iterator_proto_funcs));
@ -53186,7 +53208,8 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx)
JS_SetPropertyFunctionList(ctx, ctx->class_proto[JS_CLASS_STRING], js_string_proto_funcs, JS_SetPropertyFunctionList(ctx, ctx->class_proto[JS_CLASS_STRING], js_string_proto_funcs,
countof(js_string_proto_funcs)); countof(js_string_proto_funcs));
ctx->class_proto[JS_CLASS_STRING_ITERATOR] = JS_NewObjectProto(ctx, ctx->iterator_proto); ctx->class_proto[JS_CLASS_STRING_ITERATOR] =
JS_NewObjectProto(ctx, ctx->class_proto[JS_CLASS_ITERATOR]);
JS_SetPropertyFunctionList(ctx, ctx->class_proto[JS_CLASS_STRING_ITERATOR], JS_SetPropertyFunctionList(ctx, ctx->class_proto[JS_CLASS_STRING_ITERATOR],
js_string_iterator_proto_funcs, js_string_iterator_proto_funcs,
countof(js_string_iterator_proto_funcs)); countof(js_string_iterator_proto_funcs));
@ -53218,7 +53241,8 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx)
} }
/* ES6 Generator */ /* ES6 Generator */
ctx->class_proto[JS_CLASS_GENERATOR] = JS_NewObjectProto(ctx, ctx->iterator_proto); ctx->class_proto[JS_CLASS_GENERATOR] =
JS_NewObjectProto(ctx, ctx->class_proto[JS_CLASS_ITERATOR]);
JS_SetPropertyFunctionList(ctx, ctx->class_proto[JS_CLASS_GENERATOR], JS_SetPropertyFunctionList(ctx, ctx->class_proto[JS_CLASS_GENERATOR],
js_generator_proto_funcs, js_generator_proto_funcs,
countof(js_generator_proto_funcs)); countof(js_generator_proto_funcs));