Skip to content

Commit

Permalink
Issue #166: Use special iterator for string and array numeric part.
Browse files Browse the repository at this point in the history
  • Loading branch information
ccxvii committed Oct 20, 2022
1 parent d592c78 commit c907989
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 57 deletions.
5 changes: 3 additions & 2 deletions json.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down Expand Up @@ -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;
Expand All @@ -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, ',');
Expand Down
60 changes: 14 additions & 46 deletions jsproperty.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion jsrepr.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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);
Expand Down
7 changes: 4 additions & 3 deletions jsrun.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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);
Expand Down
8 changes: 4 additions & 4 deletions jsvalue.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -143,7 +144,6 @@ struct js_Iterator
{
const char *name;
js_Iterator *next;
char buf[12]; /* for integer iterators */
};

/* jsrun.c */
Expand Down Expand Up @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion mujs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit c907989

Please sign in to comment.