diff --git a/quickjs-atom.h b/quickjs-atom.h index 50a9099..6b78579 100644 --- a/quickjs-atom.h +++ b/quickjs-atom.h @@ -230,6 +230,7 @@ DEF(Map, "Map") DEF(Set, "Set") /* Map + 1 */ DEF(WeakMap, "WeakMap") /* Map + 2 */ DEF(WeakSet, "WeakSet") /* Map + 3 */ +DEF(Iterator, "Iterator") DEF(Map_Iterator, "Map Iterator") DEF(Set_Iterator, "Set Iterator") DEF(Array_Iterator, "Array Iterator") diff --git a/quickjs.c b/quickjs.c index 9a17c08..16de7ee 100644 --- a/quickjs.c +++ b/quickjs.c @@ -157,6 +157,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_MAP_ITERATOR, /* u.map_iterator_data */ JS_CLASS_SET_ITERATOR, /* u.map_iterator_data */ JS_CLASS_ARRAY_ITERATOR, /* u.array_iterator_data */ @@ -453,7 +454,7 @@ struct JSContext { JSValue regexp_ctor; JSValue promise_ctor; JSValue native_error_proto[JS_NATIVE_ERROR_COUNT]; - JSValue iterator_proto; + JSValue iterator_ctor; JSValue async_iterator_proto; JSValue array_proto_values; 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_WeakMap, js_map_finalizer, js_map_mark }, /* JS_CLASS_WEAKMAP */ { 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_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 */ @@ -2132,6 +2134,7 @@ JSContext *JS_NewContextRaw(JSRuntime *rt) for(i = 0; i < rt->class_count; i++) ctx->class_proto[i] = JS_NULL; ctx->array_ctor = JS_NULL; + ctx->iterator_ctor = JS_NULL; ctx->regexp_ctor = JS_NULL; ctx->promise_ctor = JS_NULL; 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++) { 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->promise_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_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->promise_ctor); JS_FreeValue(ctx, ctx->array_ctor); @@ -42161,11 +42164,23 @@ 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, int argc, JSValueConst *argv) { return JS_DupValue(ctx, this_val); } + +static const JSCFunctionListEntry js_iterator_funcs[] = { +}; static const JSCFunctionListEntry js_iterator_proto_funcs[] = { 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)); 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_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++) { 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_map_proto_funcs_ptr[i + 4], js_map_proto_funcs_count[i + 4]); @@ -53093,11 +53108,17 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx) ctx->native_error_proto[i]); } - /* Iterator prototype */ - ctx->iterator_proto = JS_NewObject(ctx); - JS_SetPropertyFunctionList(ctx, ctx->iterator_proto, + /* Iterator */ + ctx->class_proto[JS_CLASS_ITERATOR] = JS_NewObject(ctx); + JS_SetPropertyFunctionList(ctx, ctx->class_proto[JS_CLASS_ITERATOR], 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 */ JS_SetPropertyFunctionList(ctx, ctx->class_proto[JS_CLASS_ARRAY], @@ -53144,7 +53165,8 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx) ctx->array_proto_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_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, 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_string_iterator_proto_funcs, countof(js_string_iterator_proto_funcs)); @@ -53218,7 +53241,8 @@ void JS_AddIntrinsicBaseObjects(JSContext *ctx) } /* 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_generator_proto_funcs, countof(js_generator_proto_funcs));