]> git.kaiwu.me - njs.git/commitdiff
Added "name" property for built-in methods.
authorValentin Bartenev <vbart@nginx.com>
Thu, 23 May 2019 13:21:55 +0000 (16:21 +0300)
committerValentin Bartenev <vbart@nginx.com>
Thu, 23 May 2019 13:21:55 +0000 (16:21 +0300)
njs/njs_object.c
njs/test/njs_unit_test.c

index 0d2ef7c8755e8199accb62ce0e2aeaa35c209810..cb3d1d4a8a97443e3300e1c6ff4380efdcc28dc0 100644 (file)
@@ -710,8 +710,12 @@ njs_external_property_delete(njs_vm_t *vm, njs_value_t *value,
 njs_ret_t
 njs_method_private_copy(njs_vm_t *vm, njs_property_query_t *pq)
 {
-    njs_function_t     *function;
-    njs_object_prop_t  *prop, *shared;
+    nxt_int_t           ret;
+    njs_function_t      *function;
+    njs_object_prop_t   *prop, *shared, *name;
+    nxt_lvlhsh_query_t  lhq;
+
+    static const njs_value_t  name_string = njs_string("name");
 
     prop = nxt_mp_align(vm->mem_pool, sizeof(njs_value_t),
                         sizeof(njs_object_prop_t));
@@ -735,6 +739,26 @@ njs_method_private_copy(njs_vm_t *vm, njs_property_query_t *pq)
         function->object.shared_hash = vm->shared->arrow_instance_hash;
     }
 
+    name = njs_object_prop_alloc(vm, &name_string, &prop->name, 0);
+    if (nxt_slow_path(name == NULL)) {
+        return NXT_ERROR;
+    }
+
+    name->configurable = 1;
+
+    lhq.key_hash = NJS_NAME_HASH;
+    lhq.key = nxt_string_value("name");
+    lhq.replace = 0;
+    lhq.value = name;
+    lhq.proto = &njs_object_hash_proto;
+    lhq.pool = vm->mem_pool;
+
+    ret = nxt_lvlhsh_insert(&function->object.hash, &lhq);
+    if (nxt_slow_path(ret != NXT_OK)) {
+        njs_internal_error(vm, "lvlhsh insert failed");
+        return NXT_ERROR;
+    }
+
     pq->lhq.replace = 0;
     pq->lhq.value = prop;
     pq->lhq.pool = vm->mem_pool;
index a6593a568ae77101bfc37fff0642e45039b2d127..1a98ae6fceedd107eead8ed8e351ac2138893e8b 100644 (file)
@@ -9625,7 +9625,7 @@ static njs_unit_test_t  njs_test[] =
       nxt_string("name,length,prototype,isArray,of") },
 
     { nxt_string("Object.getOwnPropertyNames(Array.isArray)"),
-      nxt_string("length") },
+      nxt_string("name,length") },
 
     { nxt_string("Object.defineProperty(Object.freeze({}), 'b', {})"),
       nxt_string("TypeError: object is not extensible") },
@@ -12173,6 +12173,37 @@ static njs_unit_test_t  njs_test[] =
     { nxt_string("njs.dump($r.header)"),
       nxt_string("{type:\"object\",props:[\"getter\",\"foreach\",\"next\"]}") },
 
+    /* Built-in methods name. */
+
+    { nxt_string(
+        "var fail;"
+        "function isMethodsHaveName(o) {"
+        "    var except = ["
+        "        'prototype',"
+        "        'constructor',"
+        "    ];"
+        "    return Object.getOwnPropertyNames(o)"
+        "                 .filter(v => !except.includes(v)"
+        "                              && typeof o[v] == 'function')"
+        "                 .every(v => o[v].name == v"
+        "                             || !(fail = `${o.name}.${v}: ${o[v].name}`));"
+        "}"
+        "["
+        "    Boolean, Boolean.prototype,"
+        "    Number, Number.prototype,"
+        "    String, String.prototype,"
+        "    Object, Object.prototype,"
+        "    Array, Array.prototype,"
+        "    Function, Function.prototype,"
+        "    RegExp, RegExp.prototype,"
+        "    Date, Date.prototype,"
+        "    Error, Error.prototype,"
+        "    Math,"
+        "    JSON,"
+        "].every(obj => isMethodsHaveName(obj)) || fail"),
+
+      nxt_string("true") },
+
     /* require(). */
 
     { nxt_string("require('unknown_module')"),