[njs] Fixed own properties quering.

Valentin Bartenev vbart at nginx.com
Mon May 6 15:37:28 UTC 2019


details:   https://hg.nginx.org/njs/rev/d94c836632c7
branches:  
changeset: 949:d94c836632c7
user:      Valentin Bartenev <vbart at nginx.com>
date:      Mon May 06 11:33:23 2019 +0300
description:
Fixed own properties quering.

njs_property_query() and njs_object_property_query() were simplified.

diffstat:

 njs/njs_object.c         |  124 +++++++++++++++++-----------------------------
 njs/test/njs_unit_test.c |   17 ++++++
 2 files changed, 63 insertions(+), 78 deletions(-)

diffs (186 lines):

diff -r 6ee0e7a44e79 -r d94c836632c7 njs/njs_object.c
--- a/njs/njs_object.c	Mon May 06 17:47:26 2019 +0300
+++ b/njs/njs_object.c	Mon May 06 11:33:23 2019 +0300
@@ -322,39 +322,11 @@ njs_property_query(njs_vm_t *vm, njs_pro
         obj = &vm->string_object;
         break;
 
-    case NJS_OBJECT_STRING:
-        if (nxt_fast_path(!njs_is_null_or_undefined_or_boolean(property))) {
-            index = njs_value_to_index(property);
-
-            if (nxt_fast_path(index < NJS_STRING_MAX_LENGTH)) {
-                ret = njs_string_property_query(vm, pq,
-                                            &object->data.u.object_value->value,
-                                            index);
-
-                if (nxt_fast_path(ret != NXT_DECLINED)) {
-                    return ret;
-                }
-            }
-        }
-
-        obj = object->data.u.object;
-        break;
-
+    case NJS_OBJECT:
     case NJS_ARRAY:
-        if (nxt_fast_path(!njs_is_null_or_undefined_or_boolean(property))) {
-            index = njs_value_to_index(property);
-
-            if (nxt_fast_path(index < NJS_ARRAY_MAX_INDEX)) {
-                return njs_array_property_query(vm, pq, object->data.u.array,
-                                                index);
-            }
-        }
-
-        /* Fall through. */
-
-    case NJS_OBJECT:
     case NJS_OBJECT_BOOLEAN:
     case NJS_OBJECT_NUMBER:
+    case NJS_OBJECT_STRING:
     case NJS_REGEXP:
     case NJS_DATE:
     case NJS_OBJECT_ERROR:
@@ -442,62 +414,58 @@ njs_object_property_query(njs_vm_t *vm, 
     do {
         pq->prototype = proto;
 
-        if (nxt_fast_path(!pq->own || proto == object)) {
-            ret = nxt_lvlhsh_find(&proto->hash, &pq->lhq);
+        if (!njs_is_null_or_undefined_or_boolean(property)) {
+            switch (proto->type) {
+            case NJS_ARRAY:
+                index = njs_value_to_index(property);
+                if (nxt_fast_path(index < NJS_ARRAY_MAX_INDEX)) {
+                    array = (njs_array_t *) proto;
+                    return njs_array_property_query(vm, pq, array, index);
+                }
+
+                break;
+
+            case NJS_OBJECT_STRING:
+                index = njs_value_to_index(property);
+                if (nxt_fast_path(index < NJS_STRING_MAX_LENGTH)) {
+                    ov = (njs_object_value_t *) proto;
+                    ret = njs_string_property_query(vm, pq, &ov->value, index);
+
+                    if (nxt_fast_path(ret != NXT_DECLINED)) {
+                        return ret;
+                    }
+                }
+
+            default:
+                break;
+            }
+        }
+
+        ret = nxt_lvlhsh_find(&proto->hash, &pq->lhq);
+
+        if (ret == NXT_OK) {
+            prop = pq->lhq.value;
+
+            if (prop->type != NJS_WHITEOUT) {
+                pq->shared = 0;
+
+                return ret;
+            }
+
+        } else {
+            ret = nxt_lvlhsh_find(&proto->shared_hash, &pq->lhq);
 
             if (ret == NXT_OK) {
-                prop = pq->lhq.value;
-
-                if (prop->type != NJS_WHITEOUT) {
-                    pq->shared = 0;
-
-                    return ret;
-                }
-
-                goto next;
-            }
-
-            if (proto != object
-                && !njs_is_null_or_undefined_or_boolean(property))
-            {
-                switch (proto->type) {
-                case NJS_ARRAY:
-                    index = njs_value_to_index(property);
-                    if (nxt_fast_path(index < NJS_ARRAY_MAX_INDEX)) {
-                        array = (njs_array_t *) proto;
-                        return njs_array_property_query(vm, pq, array, index);
-                    }
-
-                    break;
-
-                case NJS_OBJECT_STRING:
-                    index = njs_value_to_index(property);
-                    if (nxt_fast_path(index < NJS_STRING_MAX_LENGTH)) {
-                        ov = (njs_object_value_t *) proto;
-                        return njs_string_property_query(vm, pq, &ov->value,
-                                                         index);
-                    }
-
-                default:
-                    break;
-                }
+                pq->shared = 1;
+
+                return ret;
             }
         }
 
-        ret = nxt_lvlhsh_find(&proto->shared_hash, &pq->lhq);
-
-        if (ret == NXT_OK) {
-            pq->shared = 1;
-
-            return ret;
-        }
-
-        if (pq->query > NJS_PROPERTY_QUERY_GET) {
+        if (pq->own || pq->query > NJS_PROPERTY_QUERY_GET) {
             return NXT_DECLINED;
         }
 
-next:
-
         proto = proto->__proto__;
 
     } while (proto != NULL);
diff -r 6ee0e7a44e79 -r d94c836632c7 njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c	Mon May 06 17:47:26 2019 +0300
+++ b/njs/test/njs_unit_test.c	Mon May 06 11:33:23 2019 +0300
@@ -9102,6 +9102,12 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("'s'.hasOwnProperty('1')"),
       nxt_string("false") },
 
+    { nxt_string("Object.hasOwnProperty('hasOwnProperty')"),
+      nxt_string("false") },
+
+    { nxt_string("Object.prototype.hasOwnProperty('hasOwnProperty')"),
+      nxt_string("true") },
+
     { nxt_string("var p = { a:5 }; var o = Object.create(p);"
                  "Object.getPrototypeOf(o) === p"),
       nxt_string("true") },
@@ -9160,6 +9166,17 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("Object.create(function(a,b,c){}).length"),
       nxt_string("3") },
 
+    { nxt_string("Object.create(Math).hasOwnProperty('abs')"),
+      nxt_string("false") },
+
+    { nxt_string("var m = Object.create(Math); m.abs = 3;"
+                 "[m.hasOwnProperty('abs'), m.abs]"),
+      nxt_string("true,3") },
+
+    { nxt_string("var m = Object.create(Math); m.abs = Math.floor;"
+                 "[m.hasOwnProperty('abs'), delete m.abs, m.abs(-1)]"),
+      nxt_string("true,true,1") },
+
     { nxt_string("Object.getOwnPropertyDescriptor({a:1}, 'a').value"),
       nxt_string("1") },
 


More information about the nginx-devel mailing list