ref: f66986d3d866e321e379dc2e7c176373b9411ef0
parent: 8cb771cd7c5d2a21084a42236f8f62efd450eee3
author: Tor Andersson <tor@ccxvii.net>
date: Sat Jan 25 12:40:37 EST 2014
Implement a smarter deletion of properties when resizing an array.
--- a/jsproperty.c
+++ b/jsproperty.c
@@ -237,3 +237,20 @@
}
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;
+}
--- a/jsrun.c
+++ b/jsrun.c
@@ -299,14 +299,9 @@
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 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)
--- a/jsvalue.h
+++ b/jsvalue.h
@@ -120,6 +120,8 @@
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);