diff --git a/json.c b/json.c index 335bcd1..6610a65 100644 --- a/json.c +++ b/json.c @@ -137,7 +137,7 @@ static void jsonrevive(js_State *J, const char *name) } } else { js_pushiterator(J, -1, 1); - while ((key = js_nextiterator(J, -1))) { + while ((key = js_nextiterator(J, -1, buf))) { js_rot2(J); jsonrevive(J, key); if (js_isundefined(J, -1)) { @@ -254,6 +254,7 @@ static int filterprop(js_State *J, const char *key) static void fmtobject(js_State *J, js_Buffer **sb, js_Object *obj, const char *gap, int level) { + char buf[32]; const char *key; int save; int i, n; @@ -267,7 +268,7 @@ static void fmtobject(js_State *J, js_Buffer **sb, js_Object *obj, const char *g n = 0; js_putc(J, sb, '{'); js_pushiterator(J, -1, 1); - while ((key = js_nextiterator(J, -1))) { + while ((key = js_nextiterator(J, -1, buf))) { if (filterprop(J, key)) { save = (*sb)->n; if (n) js_putc(J, sb, ','); diff --git a/jsproperty.c b/jsproperty.c index 6e6304a..b39740c 100644 --- a/jsproperty.c +++ b/jsproperty.c @@ -229,20 +229,12 @@ void jsV_delproperty(js_State *J, js_Object *obj, const char *name) /* Flatten hierarchy of enumerable properties into an iterator object */ static js_Iterator *itnewnode(js_State *J, const char *name, js_Iterator *next) { - js_Iterator *node = js_malloc(J, offsetof(js_Iterator, buf)); + js_Iterator *node = js_malloc(J, sizeof(js_Iterator)); node->name = name; node->next = next; return node; } -static js_Iterator *itnewnodeix(js_State *J, int ix) { - js_Iterator *node = js_malloc(J, sizeof(js_Iterator)); - js_itoa(node->buf, ix); - node->name = node->buf; - node->next = NULL; - return node; -} - static js_Iterator *itwalk(js_State *J, js_Iterator *iter, js_Property *prop, js_Object *seen) { if (prop->right != &sentinel) @@ -269,10 +261,10 @@ static js_Iterator *itflatten(js_State *J, js_Object *obj) js_Object *jsV_newiterator(js_State *J, js_Object *obj, int own) { - char buf[32]; - int k; js_Object *io = jsV_newobject(J, JS_CITERATOR, NULL); io->u.iter.target = obj; + io->u.iter.i = 0; + io->u.iter.n = 0; if (own) { io->u.iter.head = NULL; if (obj->properties != &sentinel) @@ -281,49 +273,25 @@ js_Object *jsV_newiterator(js_State *J, js_Object *obj, int own) io->u.iter.head = itflatten(J, obj); } - if (obj->type == JS_CSTRING) { - js_Iterator *tail = io->u.iter.head; - if (tail) - while (tail->next) - tail = tail->next; - for (k = 0; k < obj->u.s.length; ++k) { - js_itoa(buf, k); - if (!jsV_getenumproperty(J, obj, buf)) { - js_Iterator *node = itnewnodeix(J, k); - if (!tail) - io->u.iter.head = tail = node; - else { - tail->next = node; - tail = node; - } - } - } - } + if (obj->type == JS_CSTRING) + io->u.iter.n = obj->u.s.length; - if (obj->type == JS_CARRAY && obj->u.a.simple) { - js_Iterator *tail = io->u.iter.head; - if (tail) - while (tail->next) - tail = tail->next; - for (k = 0; k < obj->u.a.length; ++k) { - js_Iterator *node = itnewnodeix(J, k); - if (!tail) - io->u.iter.head = tail = node; - else { - tail->next = node; - tail = node; - } - } - } + if (obj->type == JS_CARRAY && obj->u.a.simple) + io->u.iter.n = obj->u.a.length; return io; } -const char *jsV_nextiterator(js_State *J, js_Object *io) +const char *jsV_nextiterator(js_State *J, js_Object *io, char buf[12]) { int k; if (io->type != JS_CITERATOR) js_typeerror(J, "not an iterator"); + if (io->u.iter.i < io->u.iter.n) { + js_itoa(buf, io->u.iter.i); + io->u.iter.i++; + return buf; + } while (io->u.iter.head) { js_Iterator *next = io->u.iter.head->next; const char *name = io->u.iter.head->name; @@ -352,7 +320,7 @@ void jsV_resizearray(js_State *J, js_Object *obj, int newlen) if (newlen < obj->u.a.length) { if (obj->u.a.length > obj->count * 2) { js_Object *it = jsV_newiterator(J, obj, 1); - while ((s = jsV_nextiterator(J, it))) { + while ((s = jsV_nextiterator(J, it, buf))) { k = jsV_numbertointeger(jsV_stringtonumber(J, s)); if (k >= newlen && !strcmp(s, jsV_numbertostring(J, buf, k))) jsV_delproperty(J, obj, s); diff --git a/jsrepr.c b/jsrepr.c index b9a12fe..ba2f684 100644 --- a/jsrepr.c +++ b/jsrepr.c @@ -82,6 +82,7 @@ static void reprident(js_State *J, js_Buffer **sb, const char *name) static void reprobject(js_State *J, js_Buffer **sb) { + char buf[32]; const char *key; int i, n; @@ -98,7 +99,7 @@ static void reprobject(js_State *J, js_Buffer **sb) n = 0; js_putc(J, sb, '{'); js_pushiterator(J, -1, 1); - while ((key = js_nextiterator(J, -1))) { + while ((key = js_nextiterator(J, -1, buf))) { if (n++ > 0) js_puts(J, sb, ", "); reprident(J, sb, key); diff --git a/jsrun.c b/jsrun.c index cc76d69..e560f09 100644 --- a/jsrun.c +++ b/jsrun.c @@ -1021,9 +1021,9 @@ void js_pushiterator(js_State *J, int idx, int own) js_pushobject(J, jsV_newiterator(J, js_toobject(J, idx), own)); } -const char *js_nextiterator(js_State *J, int idx) +const char *js_nextiterator(js_State *J, int idx, char buf[12]) { - return jsV_nextiterator(J, js_toobject(J, idx)); + return jsV_nextiterator(J, js_toobject(J, idx), buf); } /* Environment records */ @@ -1733,8 +1733,9 @@ static void jsR_run(js_State *J, js_Function *F) case OP_NEXTITER: if (js_isobject(J, -1)) { + char buf[12]; obj = js_toobject(J, -1); - str = jsV_nextiterator(J, obj); + str = jsV_nextiterator(J, obj, buf); if (str) { js_pushliteral(J, str); js_pushboolean(J, 1); diff --git a/jsvalue.h b/jsvalue.h index 3152dc2..0392d0e 100644 --- a/jsvalue.h +++ b/jsvalue.h @@ -93,7 +93,7 @@ struct js_Object } s; struct { int length; - int simple; // true if array has only non-sparse array properties + int simple; /* true if array has only non-sparse array properties */ int capacity; js_Value *array; } a; @@ -112,7 +112,8 @@ struct js_Object js_Regexp r; struct { js_Object *target; - js_Iterator *head; + int i, n; /* for array part */ + js_Iterator *head; /* for object part */ } iter; struct { const char *tag; @@ -143,7 +144,6 @@ struct js_Iterator { const char *name; js_Iterator *next; - char buf[12]; /* for integer iterators */ }; /* jsrun.c */ @@ -183,7 +183,7 @@ 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_newiterator(js_State *J, js_Object *obj, int own); -const char *jsV_nextiterator(js_State *J, js_Object *iter); +const char *jsV_nextiterator(js_State *J, js_Object *iter, char buf[12]); void jsV_resizearray(js_State *J, js_Object *obj, int newlen); diff --git a/mujs.h b/mujs.h index 1c1d52d..3d11e91 100644 --- a/mujs.h +++ b/mujs.h @@ -180,7 +180,7 @@ void js_newuserdatax(js_State *J, const char *tag, void *data, js_HasProperty ha void js_newregexp(js_State *J, const char *pattern, int flags); void js_pushiterator(js_State *J, int idx, int own); -const char *js_nextiterator(js_State *J, int idx); +const char *js_nextiterator(js_State *J, int idx, char buf[12]); int js_isdefined(js_State *J, int idx); int js_isundefined(js_State *J, int idx);