[njs] delete operator refactored.

Dmitry Volyntsev xeioex at nginx.com
Fri Oct 19 18:30:53 UTC 2018


details:   http://hg.nginx.org/njs/rev/da92ae8bcae3
branches:  
changeset: 624:da92ae8bcae3
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Fri Oct 19 20:54:59 2018 +0300
description:
delete operator refactored.

diffstat:

 njs/njs_json.c           |   9 ++++++++-
 njs/njs_object.c         |   4 ++--
 njs/njs_vm.c             |  23 +++++++++++++++++------
 njs/test/njs_unit_test.c |  22 ++++++++++++++++++++++
 4 files changed, 49 insertions(+), 9 deletions(-)

diffs (154 lines):

diff -r 9d7b9cc03569 -r da92ae8bcae3 njs/njs_json.c
--- a/njs/njs_json.c	Fri Oct 19 20:52:57 2018 +0300
+++ b/njs/njs_json.c	Fri Oct 19 20:54:59 2018 +0300
@@ -934,6 +934,12 @@ njs_json_parse_continuation(njs_vm_t *vm
                 }
 
                 prop = lhq.value;
+
+                if (prop->type == NJS_WHITEOUT) {
+                    state->index++;
+                    break;
+                }
+
                 state->prop_value = &prop->value;
 
                 if (njs_json_is_non_empty(&prop->value)) {
@@ -1233,6 +1239,7 @@ njs_json_stringify_continuation(njs_vm_t
 
             if (!prop->enumerable
                 || njs_is_void(&prop->value)
+                || !njs_is_valid(&prop->value)
                 || njs_is_function(&prop->value))
             {
                 break;
@@ -2382,7 +2389,7 @@ njs_vm_value_dump(njs_vm_t *vm, nxt_str_
                 prop = lhq.value;
                 val = &prop->value;
 
-                if (!prop->enumerable) {
+                if (prop->type == NJS_WHITEOUT || !prop->enumerable) {
                     break;
                 }
             }
diff -r 9d7b9cc03569 -r da92ae8bcae3 njs/njs_object.c
--- a/njs/njs_object.c	Fri Oct 19 20:52:57 2018 +0300
+++ b/njs/njs_object.c	Fri Oct 19 20:54:59 2018 +0300
@@ -922,7 +922,7 @@ njs_object_keys_array(njs_vm_t *vm, cons
             break;
         }
 
-        if (prop->enumerable) {
+        if (prop->type != NJS_WHITEOUT && prop->enumerable) {
             keys_length++;
         }
     }
@@ -954,7 +954,7 @@ njs_object_keys_array(njs_vm_t *vm, cons
             break;
         }
 
-        if (prop->enumerable) {
+        if (prop->type != NJS_WHITEOUT && prop->enumerable) {
             njs_string_copy(&keys->start[n++], &prop->name);
         }
     }
diff -r 9d7b9cc03569 -r da92ae8bcae3 njs/njs_vm.c
--- a/njs/njs_vm.c	Fri Oct 19 20:52:57 2018 +0300
+++ b/njs/njs_vm.c	Fri Oct 19 20:54:59 2018 +0300
@@ -552,6 +552,19 @@ njs_vmcode_property_set(njs_vm_t *vm, nj
             return NXT_ERROR;
         }
 
+        if (nxt_slow_path(pq.lhq.value != NULL)) {
+            prop = pq.lhq.value;
+
+            if (nxt_slow_path(prop->type == NJS_WHITEOUT)) {
+                /* Previously deleted property.  */
+                prop->type = NJS_PROPERTY;
+                prop->enumerable = 1;
+                prop->configurable = 1;
+                prop->writable = 1;
+                break;
+            }
+        }
+
         prop = njs_object_prop_alloc(vm, &pq.value, &njs_value_void, 1);
         if (nxt_slow_path(prop == NULL)) {
             return NXT_ERROR;
@@ -695,11 +708,9 @@ njs_vmcode_property_delete(njs_vm_t *vm,
             return NXT_ERROR;
         }
 
-        pq.lhq.pool = vm->mem_cache_pool;
-
-        (void) nxt_lvlhsh_delete(&object->data.u.object->hash, &pq.lhq);
-
-        njs_release(vm, property);
+        /* GC: release value. */
+        prop->type = NJS_WHITEOUT;
+        njs_set_invalid(&prop->value);
 
         retval = &njs_value_true;
 
@@ -811,7 +822,7 @@ njs_vmcode_property_next(njs_vm_t *vm, n
                 break;
             }
 
-            if (prop->enumerable) {
+            if (prop->type != NJS_WHITEOUT && prop->enumerable) {
                 *retval = prop->name;
 
                 return code->offset;
diff -r 9d7b9cc03569 -r da92ae8bcae3 njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c	Fri Oct 19 20:52:57 2018 +0300
+++ b/njs/test/njs_unit_test.c	Fri Oct 19 20:54:59 2018 +0300
@@ -2112,6 +2112,14 @@ static njs_unit_test_t  njs_test[] =
                  "for (var p in o) {s += p}; s"),
       nxt_string("y") },
 
+    { nxt_string("var o = {a:1, b:2}; var arr = []; "
+                 "for (var a in o) {arr.push(a)}; arr"),
+      nxt_string("a,b") },
+
+    { nxt_string("var o = {a:1, b:2}; var arr = []; delete o.a; "
+                 "for (var a in o) {arr.push(a)}; arr"),
+      nxt_string("b") },
+
     /* switch. */
 
     { nxt_string("switch"),
@@ -2636,6 +2644,9 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("delete --[][1]"),
       nxt_string("true") },
 
+    { nxt_string("var a = [1,2]; delete a.length"),
+      nxt_string("false") },
+
     { nxt_string("var a = [1,2,3]; a.x = 10;  delete a[1]"),
       nxt_string("true") },
 
@@ -2654,6 +2665,14 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("Math.E = 1"),
       nxt_string("TypeError: Cannot assign to read-only property 'E' of object") },
 
+    { nxt_string("var o = { 'a': 1, 'b': 2 }; var i; "
+                 "for (i in o) { delete o.a; delete o.b; }; njs.dump(o)"),
+      nxt_string("{}") },
+
+    { nxt_string("var o  = {}; Object.defineProperty(o, 'a', {value:1, configurable:1}); "
+                 "delete o.a; o.a=2; o.a"),
+      nxt_string("2") },
+
     { nxt_string("var a = {}; 1 in a"),
       nxt_string("false") },
 
@@ -6894,6 +6913,9 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("var a = [,6,,3]; a.one = 7; Object.keys(a)"),
       nxt_string("1,3,one") },
 
+    { nxt_string("var o = {a:1,b:2}; delete o.a; Object.keys(o)"),
+      nxt_string("b") },
+
     { nxt_string("Object.keys()"),
       nxt_string("TypeError: cannot convert void argument to object") },
 


More information about the nginx-devel mailing list