From bd9920c5714bcfe51f3514d5df7b7b963d846058 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Mon, 7 Jan 2019 13:21:36 +0100 Subject: [PATCH] Handle null/undefined in OP_NEXTITER rather than creating empty iterator. Only create an iterator for coercible types in OP_ITERATOR, and then detect the lack of a real iterator in OP_NEXTITER. Thus we don't need to allocate and push an empty iterator object for these cases. --- jsproperty.c | 8 -------- jsrun.c | 24 ++++++++++++++---------- jsvalue.h | 1 - 3 files changed, 14 insertions(+), 19 deletions(-) diff --git a/jsproperty.c b/jsproperty.c index 4aa3a49..a66c433 100644 --- a/jsproperty.c +++ b/jsproperty.c @@ -252,14 +252,6 @@ static js_Iterator *itflatten(js_State *J, js_Object *obj) return iter; } -js_Object *jsV_emptyiterator(js_State *J) -{ - js_Object *io = jsV_newobject(J, JS_CITERATOR, NULL); - io->u.iter.target = NULL; - io->u.iter.head = NULL; - return io; -} - js_Object *jsV_newiterator(js_State *J, js_Object *obj, int own) { char buf[32]; diff --git a/jsrun.c b/jsrun.c index 68c963e..ac1a1c4 100644 --- a/jsrun.c +++ b/jsrun.c @@ -1469,20 +1469,24 @@ static void jsR_run(js_State *J, js_Function *F) break; case OP_ITERATOR: - if (js_isundefined(J, -1) || js_isnull(J, -1)) - obj = jsV_emptyiterator(J); - else + if (js_iscoercible(J, -1)) { obj = jsV_newiterator(J, js_toobject(J, -1), 0); - js_pop(J, 1); - js_pushobject(J, obj); + js_pop(J, 1); + js_pushobject(J, obj); + } break; case OP_NEXTITER: - obj = js_toobject(J, -1); - str = jsV_nextiterator(J, obj); - if (str) { - js_pushliteral(J, str); - js_pushboolean(J, 1); + if (js_isobject(J, -1)) { + obj = js_toobject(J, -1); + str = jsV_nextiterator(J, obj); + if (str) { + js_pushliteral(J, str); + js_pushboolean(J, 1); + } else { + js_pop(J, 1); + js_pushboolean(J, 0); + } } else { js_pop(J, 1); js_pushboolean(J, 0); diff --git a/jsvalue.h b/jsvalue.h index 05750c9..09427da 100644 --- a/jsvalue.h +++ b/jsvalue.h @@ -173,7 +173,6 @@ js_Property *jsV_setproperty(js_State *J, js_Object *obj, const char *name); js_Property *jsV_nextproperty(js_State *J, js_Object *obj, const char *name); void jsV_delproperty(js_State *J, js_Object *obj, const char *name); -js_Object *jsV_emptyiterator(js_State *J); js_Object *jsV_newiterator(js_State *J, js_Object *obj, int own); const char *jsV_nextiterator(js_State *J, js_Object *iter);