[njs] Moving modules_hash to njs_vm_shared_t.

Dmitry Volyntsev xeioex at nginx.com
Fri Feb 7 14:35:02 UTC 2020


details:   https://hg.nginx.org/njs/rev/f15c819f79e9
branches:  
changeset: 1320:f15c819f79e9
user:      Dmitry Volyntsev <xeioex at nginx.com>
date:      Thu Feb 06 20:23:12 2020 +0300
description:
Moving modules_hash to njs_vm_shared_t.

As it is shared between VM instances.

diffstat:

 src/njs_builtin.c        |   4 +-
 src/njs_module.c         |  92 ++++++++++++++++++++++++++++-------------------
 src/njs_vm.c             |   6 ++-
 src/njs_vm.h             |   2 +
 src/test/njs_unit_test.c |  12 ++++++
 5 files changed, 74 insertions(+), 42 deletions(-)

diffs (247 lines):

diff -r 5cec0811cafb -r f15c819f79e9 src/njs_builtin.c
--- a/src/njs_builtin.c	Wed Feb 05 17:30:20 2020 +0300
+++ b/src/njs_builtin.c	Thu Feb 06 20:23:12 2020 +0300
@@ -208,7 +208,7 @@ njs_builtin_objects_create(njs_vm_t *vm)
         return NJS_ERROR;
     }
 
-    njs_lvlhsh_init(&vm->modules_hash);
+    njs_lvlhsh_init(&shared->modules_hash);
 
     lhq.replace = 0;
     lhq.pool = vm->mem_pool;
@@ -258,7 +258,7 @@ njs_builtin_objects_create(njs_vm_t *vm)
         lhq.proto = &njs_modules_hash_proto;
         lhq.value = module;
 
-        ret = njs_lvlhsh_insert(&vm->modules_hash, &lhq);
+        ret = njs_lvlhsh_insert(&shared->modules_hash, &lhq);
         if (njs_fast_path(ret != NJS_OK)) {
             return NJS_ERROR;
         }
diff -r 5cec0811cafb -r f15c819f79e9 src/njs_module.c
--- a/src/njs_module.c	Wed Feb 05 17:30:20 2020 +0300
+++ b/src/njs_module.c	Thu Feb 06 20:23:12 2020 +0300
@@ -24,7 +24,8 @@ static njs_int_t njs_module_absolute_pat
 static njs_bool_t njs_module_realpath_equal(const njs_str_t *path1,
     const njs_str_t *path2);
 static njs_int_t njs_module_read(njs_vm_t *vm, int fd, njs_str_t *body);
-static njs_module_t *njs_module_find(njs_vm_t *vm, njs_str_t *name);
+static njs_module_t *njs_module_find(njs_vm_t *vm, njs_str_t *name,
+    njs_bool_t local);
 static njs_module_t *njs_module_add(njs_vm_t *vm, njs_str_t *name);
 static njs_int_t njs_module_insert(njs_vm_t *vm, njs_module_t *module);
 
@@ -111,7 +112,7 @@ njs_parser_module(njs_vm_t *vm, njs_pars
 
     parser->node = NULL;
 
-    module = njs_module_find(vm, &name);
+    module = njs_module_find(vm, &name, 0);
     if (module != NULL) {
         goto found;
     }
@@ -413,8 +414,11 @@ const njs_lvlhsh_proto_t  njs_modules_ha
 
 
 static njs_module_t *
-njs_module_find(njs_vm_t *vm, njs_str_t *name)
+njs_module_find(njs_vm_t *vm, njs_str_t *name, njs_bool_t local)
 {
+    njs_int_t           ret;
+    njs_module_t        *module, *shared;
+    njs_object_t        *object;
     njs_lvlhsh_query_t  lhq;
 
     lhq.key = *name;
@@ -425,6 +429,38 @@ njs_module_find(njs_vm_t *vm, njs_str_t 
         return lhq.value;
     }
 
+    if (njs_lvlhsh_find(&vm->shared->modules_hash, &lhq) == NJS_OK) {
+        shared = lhq.value;
+
+        if (!local) {
+            return shared;
+        }
+
+        module = njs_mp_alloc(vm->mem_pool, sizeof(njs_module_t));
+        if (njs_slow_path(module == NULL)) {
+            njs_memory_error(vm);
+            return NULL;
+        }
+
+        memcpy(module, shared, sizeof(njs_module_t));
+        object = &module->object;
+
+        object->__proto__ = &vm->prototypes[NJS_OBJ_TYPE_OBJECT].object;
+        object->shared = 0;
+        object->extensible = 1;
+        object->error_data = 0;
+        object->fast_array = 0;
+
+        lhq.replace = 0;
+        lhq.value = module;
+        lhq.pool = vm->mem_pool;
+
+        ret = njs_lvlhsh_insert(&vm->modules_hash, &lhq);
+        if (njs_fast_path(ret == NJS_OK)) {
+            return module;
+        }
+    }
+
     return NULL;
 }
 
@@ -444,7 +480,6 @@ njs_module_add(njs_vm_t *vm, njs_str_t *
 
     ret = njs_name_copy(vm, &module->name, name);
     if (njs_slow_path(ret != NJS_OK)) {
-        njs_mp_free(vm->mem_pool, module);
         njs_memory_error(vm);
         return NULL;
     }
@@ -457,7 +492,6 @@ njs_module_add(njs_vm_t *vm, njs_str_t *
     lhq.proto = &njs_modules_hash_proto;
 
     ret = njs_lvlhsh_insert(&vm->modules_hash, &lhq);
-
     if (njs_fast_path(ret == NJS_OK)) {
         return module;
     }
@@ -507,49 +541,31 @@ njs_int_t
 njs_module_require(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused)
 {
-    njs_int_t           ret;
-    njs_object_t        *object;
-    njs_module_t        *module;
-    njs_lvlhsh_query_t  lhq;
+    njs_int_t     ret;
+    njs_str_t     name;
+    njs_value_t   *path;
+    njs_module_t  *module;
 
     if (nargs < 2) {
         njs_type_error(vm, "missing path");
         return NJS_ERROR;
     }
 
-    if (njs_slow_path(!njs_is_string(&args[1]))) {
-        ret = njs_value_to_string(vm, &args[1], &args[1]);
-        if (njs_slow_path(ret != NJS_OK)) {
-            return ret;
-        }
+    path = njs_argument(args, 1);
+    ret = njs_value_to_string(vm, path, path);
+    if (njs_slow_path(ret != NJS_OK)) {
+        return ret;
     }
 
-    njs_string_get(&args[1], &lhq.key);
-    lhq.key_hash = njs_djb_hash(lhq.key.start, lhq.key.length);
-    lhq.proto = &njs_modules_hash_proto;
-
-    if (njs_lvlhsh_find(&vm->modules_hash, &lhq) == NJS_OK) {
-        module = lhq.value;
+    njs_string_get(path, &name);
 
-        object = njs_mp_alloc(vm->mem_pool, sizeof(njs_object_t));
-        if (njs_slow_path(object == NULL)) {
-            njs_memory_error(vm);
-            return NJS_ERROR;
-        }
+    module = njs_module_find(vm, &name, 1);
+    if (njs_slow_path(module == NULL)) {
+        njs_error(vm, "Cannot find module \"%V\"", &name);
 
-        *object = module->object;
-        object->__proto__ = &vm->prototypes[NJS_OBJ_TYPE_OBJECT].object;
-        object->shared = 0;
-        object->extensible = 0;
-        object->error_data = 0;
-        object->fast_array = 0;
-
-        njs_set_object(&vm->retval, object);
-
-        return NJS_OK;
+        return NJS_ERROR;
     }
 
-    njs_error(vm, "Cannot find module \"%V\"", &lhq.key);
-
-    return NJS_ERROR;
+    njs_set_object(&vm->retval, &module->object);
+    return NJS_OK;
 }
diff -r 5cec0811cafb -r f15c819f79e9 src/njs_vm.c
--- a/src/njs_vm.c	Wed Feb 05 17:30:20 2020 +0300
+++ b/src/njs_vm.c	Thu Feb 06 20:23:12 2020 +0300
@@ -44,6 +44,8 @@ njs_vm_create(njs_vm_opt_t *options)
         return NULL;
     }
 
+    njs_lvlhsh_init(&vm->values_hash);
+
     vm->options = *options;
 
     if (options->shared != NULL) {
@@ -56,8 +58,6 @@ njs_vm_create(njs_vm_opt_t *options)
         }
     }
 
-    njs_lvlhsh_init(&vm->values_hash);
-
     vm->external = options->external;
 
     vm->external_objects = njs_arr_create(vm->mem_pool, 4, sizeof(void *));
@@ -302,6 +302,8 @@ njs_vm_init(njs_vm_t *vm)
         return NJS_ERROR;
     }
 
+    njs_lvlhsh_init(&vm->modules_hash);
+
     njs_lvlhsh_init(&vm->events_hash);
     njs_queue_init(&vm->posted_events);
     njs_queue_init(&vm->promise_events);
diff -r 5cec0811cafb -r f15c819f79e9 src/njs_vm.h
--- a/src/njs_vm.h	Wed Feb 05 17:30:20 2020 +0300
+++ b/src/njs_vm.h	Thu Feb 06 20:23:12 2020 +0300
@@ -276,6 +276,8 @@ struct njs_vm_shared_s {
     njs_lvlhsh_t             arguments_object_instance_hash;
     njs_lvlhsh_t             regexp_instance_hash;
 
+    njs_lvlhsh_t             modules_hash;
+
     njs_lvlhsh_t             env_hash;
 
     njs_object_t             string_object;
diff -r 5cec0811cafb -r f15c819f79e9 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c	Wed Feb 05 17:30:20 2020 +0300
+++ b/src/test/njs_unit_test.c	Thu Feb 06 20:23:12 2020 +0300
@@ -15825,6 +15825,15 @@ static njs_unit_test_t  njs_test[] =
     { njs_str("var fs = require('fs'); typeof fs"),
       njs_str("object") },
 
+    { njs_str("var fs = require('fs'); Object.isExtensible(fs)"),
+      njs_str("true") },
+
+    { njs_str("require('fs') === require('fs')"),
+      njs_str("true") },
+
+    { njs_str("require('fs').a = 1; require('fs').a"),
+      njs_str("1") },
+
     /* require('fs').readFile() */
 
     { njs_str("var fs = require('fs');"
@@ -16472,6 +16481,9 @@ static njs_unit_test_t  njs_shared_test[
     { njs_str("import cr from 'crypto'; cr.createHash('md5')"),
       njs_str("[object Hash]") },
 
+    { njs_str("var fs = require('fs'); fs.a = 1; fs.a"),
+      njs_str("1") },
+
     { njs_str("isFinite()"),
       njs_str("false") },
 


More information about the nginx-devel mailing list