shithub: libmujs

Download patch

ref: f66986d3d866e321e379dc2e7c176373b9411ef0
parent: 8cb771cd7c5d2a21084a42236f8f62efd450eee3
author: Tor Andersson <[email protected]>
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);