diff --git a/jsproperty.c b/jsproperty.c index 70351eb..7127277 100644 --- a/jsproperty.c +++ b/jsproperty.c @@ -237,3 +237,20 @@ const char *jsV_nextiterator(js_State *J, js_Object *iobj) } return NULL; } + +/* Walk all the properties and delete them one by one for arrays */ + +void jsV_resizearray(js_State *J, js_Object *obj, unsigned int newlen) +{ + const char *s; + unsigned int k; + if (newlen < obj->u.a.length) { + js_Object *it = jsV_newiterator(J, obj); + while ((s = jsV_nextiterator(J, it))) { + k = jsV_numbertouint32(jsV_stringtonumber(J, s)); + if (k >= newlen && !strcmp(s, jsV_numbertostring(J, k))) + jsV_delproperty(J, obj, s); + } + } + obj->u.a.length = newlen; +} diff --git a/jsrun.c b/jsrun.c index 5367c2f..0fda60f 100644 --- a/jsrun.c +++ b/jsrun.c @@ -299,14 +299,9 @@ static void jsR_setproperty(js_State *J, js_Object *obj, const char *name, int i if (!strcmp(name, "length")) { double rawlen = js_tonumber(J, idx); unsigned int newlen = jsV_numbertouint32(rawlen); - unsigned int oldlen = obj->u.a.length; if (newlen != rawlen) js_rangeerror(J, "array length"); - for (k = newlen; k < oldlen; ++k) { - sprintf(buf, "%u", k); - jsV_delproperty(J, obj, buf); - } - obj->u.a.length = newlen; + jsV_resizearray(J, obj, newlen); return; } @@ -340,7 +335,6 @@ static void jsR_defproperty(js_State *J, js_Object *obj, const char *name, int i static int jsR_delproperty(js_State *J, js_Object *obj, const char *name) { - // TODO: does delete follow prototype chain? js_Property *ref = jsV_getownproperty(J, obj, name); if (ref) { if (ref->atts & JS_DONTDELETE) diff --git a/jsvalue.h b/jsvalue.h index 5460357..1f2be4e 100644 --- a/jsvalue.h +++ b/jsvalue.h @@ -120,6 +120,8 @@ void jsV_delproperty(js_State *J, js_Object *obj, const char *name); js_Object *jsV_newiterator(js_State *J, js_Object *obj); const char *jsV_nextiterator(js_State *J, js_Object *iobj); +void jsV_resizearray(js_State *J, js_Object *obj, unsigned int newlen); + /* jsdump.c */ void js_dumpobject(js_State *J, js_Object *obj); void js_dumpvalue(js_State *J, js_Value v);