Implement a smarter deletion of properties when resizing an array.

This commit is contained in:
Tor Andersson
2014-01-25 17:40:37 +01:00
parent 8cb771cd7c
commit f66986d3d8
3 changed files with 20 additions and 7 deletions
+17
View File
@@ -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;
}
+1 -7
View File
@@ -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)
+2
View File
@@ -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);