mirror of
https://github.com/ccxvii/mujs.git
synced 2026-09-21 22:53:41 +08:00
Implement a smarter deletion of properties when resizing an array.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user