ref: 2fd435e986ecdcfcfe51d39160dd8adead12ba81
parent: 34b9fda6f8778c7dbfae55c2480f09ffb6f0d952
author: Tor Andersson <tor@ccxvii.net>
date: Fri Jan 24 20:14:02 EST 2014
Push result of delete operator.
--- a/jsrun.c
+++ b/jsrun.c
@@ -336,11 +336,16 @@
}
}
-static void jsR_delproperty(js_State *J, js_Object *obj, const char *name)
+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 && !(ref->atts & JS_DONTDELETE))
+ if (ref) {
+ if (ref->atts & JS_DONTDELETE)
+ return 0;
jsV_delproperty(J, obj, name);
+ }
+ return 1;
}
/* Registry, global and object property accessors */
@@ -480,6 +485,23 @@
jsR_setproperty(J, J->G, name, -1);
}
+static int js_delvar(js_State *J, const char *name)
+{
+ js_Environment *E = J->E;
+ do {
+ // TODO: does delete follow prototype chain?
+ js_Property *ref = jsV_getownproperty(J, E->variables, name);
+ if (ref) {
+ if (ref->atts & JS_DONTDELETE)
+ return 0;
+ jsV_delproperty(J, E->variables, name);
+ return 1;
+ }
+ E = E->outer;
+ } while (E);
+ return jsR_delproperty(J, J->G, name);
+}
+
/* Function calls */
static void jsR_callfunction(js_State *J, int n, js_Function *F, js_Environment *scope)
@@ -723,7 +745,10 @@
js_setvar(J, ST[*pc++]);
break;
- // OP_DELVAR
+ case OP_DELVAR:
+ b = js_delvar(J, ST[*pc++]);
+ js_pushboolean(J, b);
+ break;
case OP_IN:
str = js_tostring(J, -2);
@@ -786,15 +811,17 @@
case OP_DELPROP:
str = js_tostring(J, -1);
obj = js_toobject(J, -2);
- jsR_delproperty(J, obj, str);
+ b = jsR_delproperty(J, obj, str);
js_pop(J, 2);
+ js_pushboolean(J, b);
break;
case OP_DELPROP_S:
str = ST[*pc++];
obj = js_toobject(J, -1);
- jsR_delproperty(J, obj, str);
+ b = jsR_delproperty(J, obj, str);
js_pop(J, 1);
+ js_pushboolean(J, b);
break;
case OP_ITERATOR: