[njs] Refactored completions and backtrace matches.
Dmitry Volyntsev
xeioex at nginx.com
Thu Oct 31 15:18:03 UTC 2019
details: https://hg.nginx.org/njs/rev/2868545c461b
branches:
changeset: 1212:2868545c461b
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Thu Oct 31 18:17:31 2019 +0300
description:
Refactored completions and backtrace matches.
diffstat:
src/njs_builtin.c | 460 ++++++++++++++++++++++------------------------
src/njs_crypto.c | 56 +++++-
src/njs_object.c | 81 ++++++++
src/njs_object.h | 20 ++
src/njs_value.c | 1 +
src/njs_value.h | 1 +
test/njs_expect_test.exp | 4 +-
7 files changed, 381 insertions(+), 242 deletions(-)
diffs (808 lines):
diff -r c75a8fc6d534 -r 2868545c461b src/njs_builtin.c
--- a/src/njs_builtin.c Thu Oct 31 18:17:31 2019 +0300
+++ b/src/njs_builtin.c Thu Oct 31 18:17:31 2019 +0300
@@ -14,6 +14,19 @@ typedef struct {
} njs_function_init_t;
+typedef struct {
+ enum {
+ NJS_BUILTIN_TRAVERSE_KEYS,
+ NJS_BUILTIN_TRAVERSE_MATCH,
+ } type;
+
+ njs_function_native_t native;
+
+ njs_lvlhsh_t keys;
+ njs_str_t match;
+} njs_builtin_traverse_t;
+
+
static njs_int_t njs_prototype_function(njs_vm_t *vm, njs_value_t *args,
njs_uint_t nargs, njs_index_t unused);
static njs_arr_t *njs_vm_expression_completions(njs_vm_t *vm,
@@ -503,17 +516,130 @@ njs_builtin_objects_clone(njs_vm_t *vm,
}
-static size_t
-njs_builtin_completions_size(njs_vm_t *vm)
+static njs_int_t
+njs_builtin_traverse(njs_vm_t *vm, njs_traverse_t *traverse, void *data)
{
- njs_uint_t n;
+ size_t len;
+ u_char *p, *start, *end;
+ njs_int_t ret, n;
+ njs_str_t name;
+ njs_object_prop_t *prop;
+ njs_lvlhsh_query_t lhq;
+ njs_builtin_traverse_t *ctx;
+ njs_traverse_t *path[NJS_TRAVERSE_MAX_DEPTH];
+ u_char buf[256];
+
+ ctx = data;
+
+ if (ctx->type == NJS_BUILTIN_TRAVERSE_MATCH) {
+ prop = traverse->prop;
+
+ if (!(njs_is_function(&prop->value)
+ && njs_function(&prop->value)->native
+ && njs_function(&prop->value)->u.native == ctx->native))
+ {
+ return NJS_OK;
+ }
+ }
+
+ n = 0;
+
+ while (traverse != NULL) {
+ path[n++] = traverse;
+ traverse = traverse->parent;
+ }
+
+ n--;
+
+ p = buf;
+ end = buf + sizeof(buf);
+
+ do {
+ njs_string_get(&path[n]->prop->name, &name);
+
+ if (njs_slow_path((p + name.length + 1) > end)) {
+ njs_type_error(vm, "njs_builtin_traverse() key is too long");
+ return NJS_ERROR;
+ }
+
+ p = njs_cpymem(p, name.start, name.length);
+
+ if (n != 0) {
+ *p++ = '.';
+ }
+
+ } while (n-- > 0);
+
+ if (ctx->type == NJS_BUILTIN_TRAVERSE_MATCH) {
+ len = ctx->match.length;
+ start = njs_mp_alloc(vm->mem_pool, len + (p - buf) + (len != 0));
+ if (njs_slow_path(start == NULL)) {
+ njs_memory_error(vm);
+ return NJS_ERROR;
+ }
+
+ if (len != 0) {
+ memcpy(start, ctx->match.start, len);
+ start[len++] = '.';
+ }
+
+ memcpy(start + len, buf, p - buf);
+ ctx->match.length = len + p - buf;
+ ctx->match.start = start;
+
+ return NJS_DONE;
+ }
+
+ /* NJS_BUILTIN_TRAVERSE_KEYS. */
+
+ prop = njs_object_prop_alloc(vm, &njs_value_undefined, &njs_value_null, 0);
+ if (njs_slow_path(prop == NULL)) {
+ return NJS_ERROR;
+ }
+
+ ret = njs_string_new(vm, &prop->name, buf, p - buf, 0);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return ret;
+ }
+
+ lhq.value = prop;
+ njs_string_get(&prop->name, &lhq.key);
+ lhq.key_hash = njs_djb_hash(lhq.key.start, lhq.key.length);
+ lhq.replace = 1;
+ lhq.pool = vm->mem_pool;
+ lhq.proto = &njs_object_hash_proto;
+
+ ret = njs_lvlhsh_insert(&ctx->keys, &lhq);
+ if (njs_slow_path(ret != NJS_OK)) {
+ njs_internal_error(vm, "lvlhsh insert/replace failed");
+ return NJS_ERROR;
+ }
+
+ return NJS_OK;
+}
+
+
+static njs_arr_t *
+njs_builtin_completions(njs_vm_t *vm)
+{
+ u_char *compl;
+ size_t len;
+ njs_arr_t *array;
+ njs_str_t *completion;
+ njs_int_t ret;
njs_keyword_t *keyword;
njs_lvlhsh_each_t lhe, lhe_prop;
njs_extern_value_t *ev;
const njs_extern_t *ext_proto, *ext_prop;
- const njs_object_init_t **p;
+ njs_builtin_traverse_t ctx;
+ const njs_object_prop_t *prop;
- n = 0;
+ array = njs_arr_create(vm->mem_pool, 64, sizeof(njs_str_t));
+ if (njs_slow_path(array == NULL)) {
+ return NULL;
+ }
+
+ /* Keywords completions. */
njs_lvlhsh_each_init(&lhe, &njs_keyword_hash_proto);
@@ -524,149 +650,43 @@ njs_builtin_completions_size(njs_vm_t *v
break;
}
- n++;
- }
-
- for (p = njs_object_init; *p != NULL; p++) {
- n += (*p)->items;
- }
-
- for (p = njs_prototype_init; *p != NULL; p++) {
- n += (*p)->items;
- }
-
- for (p = njs_constructor_init; *p != NULL; p++) {
- n += (*p)->items;
- }
-
- njs_lvlhsh_each_init(&lhe, &njs_extern_value_hash_proto);
-
- for ( ;; ) {
- ev = njs_lvlhsh_each(&vm->externals_hash, &lhe);
-
- if (ev == NULL) {
- break;
+ completion = njs_arr_add(array);
+ if (njs_slow_path(completion == NULL)) {
+ return NULL;
}
- ext_proto = ev->value.external.proto;
-
- njs_lvlhsh_each_init(&lhe_prop, &njs_extern_hash_proto);
-
- n++;
-
- for ( ;; ) {
- ext_prop = njs_lvlhsh_each(&ext_proto->hash, &lhe_prop);
-
- if (ext_prop == NULL) {
- break;
- }
-
- n++;
- }
+ *completion = keyword->name;
}
- return n;
-}
+ /* Global object completions. */
+ ctx.type = NJS_BUILTIN_TRAVERSE_KEYS;
+ njs_lvlhsh_init(&ctx.keys);
-static njs_arr_t *
-njs_builtin_completions(njs_vm_t *vm, njs_arr_t *array)
-{
- u_char *compl;
- size_t n, len;
- njs_str_t string, *completions;
- njs_uint_t i, k;
- njs_keyword_t *keyword;
- njs_lvlhsh_each_t lhe, lhe_prop;
- njs_extern_value_t *ev;
- const njs_extern_t *ext_proto, *ext_prop;
- const njs_object_prop_t *prop;
- const njs_object_init_t *obj, **p;
+ ret = njs_object_traverse(vm, &vm->global_object, &ctx,
+ njs_builtin_traverse);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return NULL;
+ }
- n = 0;
- completions = array->start;
-
- njs_lvlhsh_each_init(&lhe, &njs_keyword_hash_proto);
+ njs_lvlhsh_each_init(&lhe, &njs_object_hash_proto);
for ( ;; ) {
- keyword = njs_lvlhsh_each(&vm->shared->keywords_hash, &lhe);
+ prop = njs_lvlhsh_each(&ctx.keys, &lhe);
- if (keyword == NULL) {
+ if (prop == NULL) {
break;
}
- completions[n++] = keyword->name;
- }
-
- for (p = njs_object_init; *p != NULL; p++) {
- obj = *p;
-
- for (i = 0; i < obj->items; i++) {
- prop = &obj->properties[i];
- njs_string_get(&prop->name, &string);
- len = obj->name.length + string.length + 2;
+ completion = njs_arr_add(array);
+ if (njs_slow_path(completion == NULL)) {
+ return NULL;
+ }
- compl = njs_mp_zalloc(vm->mem_pool, len);
- if (compl == NULL) {
- return NULL;
- }
-
- njs_sprintf(compl, compl + len, "%s.%s%Z", obj->name.start,
- string.start);
-
- completions[n].length = len;
- completions[n++].start = (u_char *) compl;
- }
+ njs_string_get(&prop->name, completion);
}
- for (p = njs_prototype_init; *p != NULL; p++) {
- obj = *p;
-
- for (i = 0; i < obj->items; i++) {
- prop = &obj->properties[i];
- njs_string_get(&prop->name, &string);
- len = string.length + 2;
-
- compl = njs_mp_zalloc(vm->mem_pool, len);
- if (compl == NULL) {
- return NULL;
- }
-
- njs_sprintf(compl, compl + len, ".%s%Z", string.start);
-
- for (k = 0; k < n; k++) {
- if (njs_strncmp(completions[k].start, compl, len) == 0) {
- break;
- }
- }
-
- if (k == n) {
- completions[n].length = len;
- completions[n++].start = (u_char *) compl;
- }
- }
- }
-
- for (p = njs_constructor_init; *p != NULL; p++) {
- obj = *p;
-
- for (i = 0; i < obj->items; i++) {
- prop = &obj->properties[i];
- njs_string_get(&prop->name, &string);
- len = obj->name.length + string.length + 2;
-
- compl = njs_mp_zalloc(vm->mem_pool, len);
- if (compl == NULL) {
- return NULL;
- }
-
- njs_sprintf(compl, compl + len, "%s.%s%Z", obj->name.start,
- string.start);
-
- completions[n].length = len;
- completions[n++].start = (u_char *) compl;
- }
- }
+ /* Externals completions. */
njs_lvlhsh_each_init(&lhe, &njs_extern_value_hash_proto);
@@ -689,8 +709,13 @@ njs_builtin_completions(njs_vm_t *vm, nj
njs_sprintf(compl, compl + len, "%V%Z", &ev->name);
- completions[n].length = len;
- completions[n++].start = (u_char *) compl;
+ completion = njs_arr_add(array);
+ if (njs_slow_path(completion == NULL)) {
+ return NULL;
+ }
+
+ completion->length = len;
+ completion->start = (u_char *) compl;
for ( ;; ) {
ext_prop = njs_lvlhsh_each(&ext_proto->hash, &lhe_prop);
@@ -708,13 +733,16 @@ njs_builtin_completions(njs_vm_t *vm, nj
njs_sprintf(compl, compl + len, "%V.%V%Z", &ev->name,
&ext_prop->name);
- completions[n].length = len;
- completions[n++].start = (u_char *) compl;
+ completion = njs_arr_add(array);
+ if (njs_slow_path(completion == NULL)) {
+ return NULL;
+ }
+
+ completion->length = len;
+ completion->start = (u_char *) compl;
}
}
- array->items = n;
-
return array;
}
@@ -722,18 +750,8 @@ njs_builtin_completions(njs_vm_t *vm, nj
njs_arr_t *
njs_vm_completions(njs_vm_t *vm, njs_str_t *expression)
{
- size_t size;
- njs_arr_t *completions;
-
if (expression == NULL) {
- size = njs_builtin_completions_size(vm);
-
- completions = njs_arr_create(vm->mem_pool, size, sizeof(njs_str_t));
- if (njs_slow_path(completions == NULL)) {
- return NULL;
- }
-
- return njs_builtin_completions(vm, completions);
+ return njs_builtin_completions(vm);
}
return njs_vm_expression_completions(vm, expression);
@@ -913,34 +931,71 @@ njs_object_completions(njs_vm_t *vm, njs
}
-static njs_int_t
-njs_builtin_match(const njs_object_init_t **objects, njs_function_t *function,
- const njs_object_prop_t **prop, const njs_object_init_t **object)
+njs_int_t
+njs_builtin_match_native_function(njs_vm_t *vm, njs_function_t *function,
+ njs_str_t *name)
{
- njs_uint_t i;
- njs_function_t *fun;
- const njs_object_init_t *o, **p;
- const njs_object_prop_t *pr;
+ njs_int_t ret;
+ njs_uint_t i;
+ njs_value_t value;
+ njs_module_t *module;
+ njs_lvlhsh_each_t lhe;
+ njs_builtin_traverse_t ctx;
+
+ ctx.type = NJS_BUILTIN_TRAVERSE_MATCH;
+ ctx.native = function->u.native;
+
+ /* Global object. */
- for (p = objects; *p != NULL; p++) {
- o = *p;
+ ctx.match = njs_str_value("");
+
+ ret = njs_object_traverse(vm, &vm->global_object, &ctx,
+ njs_builtin_traverse);
+
+ if (ret == NJS_DONE) {
+ *name = ctx.match;
+ return NJS_OK;
+ }
+
+ /* Constructor from built-in modules (not-mapped to global object). */
+
+ for (i = NJS_OBJ_TYPE_CRYPTO_HASH; i < NJS_OBJ_TYPE_ERROR; i++) {
+ njs_set_object(&value, &vm->constructors[i].object);
- for (i = 0; i < o->items; i++) {
- pr = &o->properties[i];
+ ret = njs_value_property(vm, &value, njs_value_arg(&njs_string_name),
+ &value);
+
+ if (ret == NJS_OK && njs_is_string(&value)) {
+ njs_string_get(&value, &ctx.match);
+ }
- if (pr->type != NJS_PROPERTY || !njs_is_function(&pr->value)) {
- continue;
- }
+ ret = njs_object_traverse(vm, &vm->constructors[i].object, &ctx,
+ njs_builtin_traverse);
+
+ if (ret == NJS_DONE) {
+ *name = ctx.match;
+ return NJS_OK;
+ }
+ }
- fun = njs_function(&pr->value);
+ /* Modules. */
+
+ njs_lvlhsh_each_init(&lhe, &njs_modules_hash_proto);
+
+ for ( ;; ) {
+ module = njs_lvlhsh_each(&vm->modules_hash, &lhe);
- if (function->u.native != fun->u.native) {
- continue;
- }
+ if (module == NULL) {
+ break;
+ }
+
+ ctx.match = module->name;
- *prop = pr;
- *object = o;
+ ret = njs_object_traverse(vm, &module->object, &ctx,
+ njs_builtin_traverse);
+ if (ret == NJS_DONE) {
+ *name = ctx.match;
return NJS_OK;
}
}
@@ -949,68 +1004,6 @@ njs_builtin_match(const njs_object_init_
}
-njs_int_t
-njs_builtin_match_native_function(njs_vm_t *vm, njs_function_t *function,
- njs_str_t *name)
-{
- size_t len;
- njs_str_t string, middle;
- njs_int_t ret;
- const njs_object_init_t *obj;
- const njs_object_prop_t *prop;
-
- middle = njs_str_value(".");
-
- ret = njs_builtin_match(njs_object_init, function, &prop, &obj);
-
- if (ret == NJS_OK) {
- if (!obj->name.length) {
- middle = njs_str_value("");
- }
-
- goto found;
- }
-
- ret = njs_builtin_match(njs_prototype_init, function, &prop, &obj);
-
- if (ret == NJS_OK) {
- middle = njs_str_value(".prototype.");
- goto found;
- }
-
- ret = njs_builtin_match(njs_constructor_init, function, &prop, &obj);
-
- if (ret == NJS_OK) {
- goto found;
- }
-
- ret = njs_builtin_match(njs_module_init, function, &prop, &obj);
-
- if (ret == NJS_OK) {
- goto found;
- }
-
- return NJS_DECLINED;
-
-found:
-
- njs_string_get(&prop->name, &string);
-
- len = obj->name.length + middle.length + string.length;
-
- name->length = len;
- name->start = njs_mp_zalloc(vm->mem_pool, len);
- if (name->start == NULL) {
- return NJS_ERROR;
- }
-
- njs_sprintf(name->start, name->start + len,
- "%V%V%V", &obj->name, &middle, &string);
-
- return NJS_OK;
-}
-
-
static njs_int_t
njs_dump_value(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
njs_index_t unused)
@@ -1515,11 +1508,6 @@ njs_process_object_argv(njs_vm_t *vm, nj
static const njs_value_t argv_string = njs_string("argv");
- if (njs_slow_path(vm->options.argv == NULL)) {
- njs_internal_error(vm, "argv was not provided by host environment");
- return NJS_ERROR;
- }
-
argv = njs_array_alloc(vm, vm->options.argc, 0);
if (njs_slow_path(argv == NULL)) {
return NJS_ERROR;
diff -r c75a8fc6d534 -r 2868545c461b src/njs_crypto.c
--- a/src/njs_crypto.c Thu Oct 31 18:17:31 2019 +0300
+++ b/src/njs_crypto.c Thu Oct 31 18:17:31 2019 +0300
@@ -361,10 +361,34 @@ njs_hash_constructor(njs_vm_t *vm, njs_v
}
+static const njs_object_prop_t njs_hash_constructor_properties[] =
+{
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("name"),
+ .value = njs_string("Hash"),
+ .configurable = 1,
+ },
+
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("length"),
+ .value = njs_value(NJS_NUMBER, 1, 2.0),
+ .configurable = 1,
+ },
+
+ {
+ .type = NJS_PROPERTY_HANDLER,
+ .name = njs_string("prototype"),
+ .value = njs_prop_handler(njs_object_prototype_create),
+ },
+};
+
+
const njs_object_init_t njs_hash_constructor_init = {
njs_str("Hash"),
- NULL,
- 0,
+ njs_hash_constructor_properties,
+ njs_nitems(njs_hash_constructor_properties),
};
@@ -621,10 +645,34 @@ njs_hmac_constructor(njs_vm_t *vm, njs_v
}
+static const njs_object_prop_t njs_hmac_constructor_properties[] =
+{
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("name"),
+ .value = njs_string("Hmac"),
+ .configurable = 1,
+ },
+
+ {
+ .type = NJS_PROPERTY,
+ .name = njs_string("length"),
+ .value = njs_value(NJS_NUMBER, 1, 3.0),
+ .configurable = 1,
+ },
+
+ {
+ .type = NJS_PROPERTY_HANDLER,
+ .name = njs_string("prototype"),
+ .value = njs_prop_handler(njs_object_prototype_create),
+ },
+};
+
+
const njs_object_init_t njs_hmac_constructor_init = {
njs_str("Hmac"),
- NULL,
- 0,
+ njs_hmac_constructor_properties,
+ njs_nitems(njs_hmac_constructor_properties),
};
diff -r c75a8fc6d534 -r 2868545c461b src/njs_object.c
--- a/src/njs_object.c Thu Oct 31 18:17:31 2019 +0300
+++ b/src/njs_object.c Thu Oct 31 18:17:31 2019 +0300
@@ -1084,6 +1084,87 @@ njs_object_own_enumerate_object(njs_vm_t
}
+njs_int_t
+njs_object_traverse(njs_vm_t *vm, njs_object_t *object, void *ctx,
+ njs_object_traverse_cb_t cb)
+{
+ njs_int_t depth, ret;
+ njs_str_t name;
+ njs_value_t value, obj;
+ njs_object_prop_t *prop;
+ njs_traverse_t state[NJS_TRAVERSE_MAX_DEPTH];
+
+ static const njs_str_t constructor_key = njs_str("constructor");
+
+ depth = 0;
+
+ state[depth].prop = NULL;
+ state[depth].parent = NULL;
+ state[depth].object = object;
+ state[depth].hash = &object->shared_hash;
+ njs_lvlhsh_each_init(&state[depth].lhe, &njs_object_hash_proto);
+
+ for ( ;; ) {
+ prop = njs_lvlhsh_each(state[depth].hash, &state[depth].lhe);
+
+ if (prop == NULL) {
+ if (state[depth].hash == &state[depth].object->shared_hash) {
+ state[depth].hash = &state[depth].object->hash;
+ njs_lvlhsh_each_init(&state[depth].lhe, &njs_object_hash_proto);
+ continue;
+ }
+
+ if (depth == 0) {
+ return NJS_OK;
+ }
+
+ depth--;
+ continue;
+ }
+
+ state[depth].prop = prop;
+
+ ret = cb(vm, &state[depth], ctx);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return ret;
+ }
+
+ value = prop->value;
+
+ if (prop->type == NJS_PROPERTY_HANDLER) {
+ njs_set_object(&obj, state[depth].object);
+ ret = prop->value.data.u.prop_handler(vm, prop, &obj, NULL, &value);
+ if (njs_slow_path(ret == NJS_ERROR)) {
+ return ret;
+
+ }
+ }
+
+ njs_string_get(&prop->name, &name);
+
+ /*
+ * "constructor" properties make loops in object hierarchies.
+ * Object.prototype.constructor -> Object.
+ */
+
+ if (njs_is_object(&value) && !njs_strstr_eq(&name, &constructor_key)) {
+ if (++depth > (NJS_TRAVERSE_MAX_DEPTH - 1)) {
+ njs_type_error(vm, "njs_object_traverse() recursion limit:%d",
+ depth);
+ return NJS_ERROR;
+ }
+
+ state[depth].prop = NULL;
+ state[depth].parent = &state[depth - 1];
+ state[depth].object = njs_object(&value);
+ state[depth].hash = &njs_object(&value)->shared_hash;
+ njs_lvlhsh_each_init(&state[depth].lhe, &njs_object_hash_proto);
+ }
+
+ }
+}
+
+
static njs_int_t
njs_object_define_property(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
njs_index_t unused)
diff -r c75a8fc6d534 -r 2868545c461b src/njs_object.h
--- a/src/njs_object.h Thu Oct 31 18:17:31 2019 +0300
+++ b/src/njs_object.h Thu Oct 31 18:17:31 2019 +0300
@@ -43,6 +43,24 @@ struct njs_object_init_s {
};
+typedef struct njs_traverse_s njs_traverse_t;
+
+struct njs_traverse_s {
+ struct njs_traverse_s *parent;
+ njs_object_prop_t *prop;
+
+ njs_object_t *object;
+ njs_lvlhsh_t *hash;
+ njs_lvlhsh_each_t lhe;
+
+#define NJS_TRAVERSE_MAX_DEPTH 32
+};
+
+
+typedef njs_int_t (*njs_object_traverse_cb_t)(njs_vm_t *vm,
+ njs_traverse_t *traverse, void *ctx);
+
+
njs_object_t *njs_object_alloc(njs_vm_t *vm);
njs_object_t *njs_object_value_copy(njs_vm_t *vm, njs_value_t *value);
njs_object_t *njs_object_value_alloc(njs_vm_t *vm, const njs_value_t *value,
@@ -51,6 +69,8 @@ njs_array_t *njs_object_enumerate(njs_vm
njs_object_enum_t kind, njs_bool_t all);
njs_array_t *njs_object_own_enumerate(njs_vm_t *vm, const njs_object_t *object,
njs_object_enum_t kind, njs_bool_t all);
+njs_int_t njs_object_traverse(njs_vm_t *vm, njs_object_t *object, void *ctx,
+ njs_object_traverse_cb_t cb);
njs_int_t njs_object_hash_create(njs_vm_t *vm, njs_lvlhsh_t *hash,
const njs_object_prop_t *prop, njs_uint_t n);
njs_int_t njs_object_constructor(njs_vm_t *vm, njs_value_t *args,
diff -r c75a8fc6d534 -r 2868545c461b src/njs_value.c
--- a/src/njs_value.c Thu Oct 31 18:17:31 2019 +0300
+++ b/src/njs_value.c Thu Oct 31 18:17:31 2019 +0300
@@ -48,6 +48,7 @@ const njs_value_t njs_string_plus_infin
njs_string("Infinity");
const njs_value_t njs_string_nan = njs_string("NaN");
const njs_value_t njs_string_string = njs_string("string");
+const njs_value_t njs_string_name = njs_string("name");
const njs_value_t njs_string_data = njs_string("data");
const njs_value_t njs_string_external = njs_string("external");
const njs_value_t njs_string_invalid = njs_string("invalid");
diff -r c75a8fc6d534 -r 2868545c461b src/njs_value.h
--- a/src/njs_value.h Thu Oct 31 18:17:31 2019 +0300
+++ b/src/njs_value.h Thu Oct 31 18:17:31 2019 +0300
@@ -665,6 +665,7 @@ extern const njs_value_t njs_string_plu
extern const njs_value_t njs_string_nan;
extern const njs_value_t njs_string_string;
extern const njs_value_t njs_string_data;
+extern const njs_value_t njs_string_name;
extern const njs_value_t njs_string_external;
extern const njs_value_t njs_string_invalid;
extern const njs_value_t njs_string_object;
diff -r c75a8fc6d534 -r 2868545c461b test/njs_expect_test.exp
--- a/test/njs_expect_test.exp Thu Oct 31 18:17:31 2019 +0300
+++ b/test/njs_expect_test.exp Thu Oct 31 18:17:31 2019 +0300
@@ -101,7 +101,7 @@ njs_test {
njs_test {
{"O\t"
- "O\a*bject."}
+ "O\a*bject"}
{"\t\t"
"Object.create*Object.isSealed"}
}
@@ -120,7 +120,7 @@ njs_test {
njs_test {
{"Ma\t"
- "Ma\a*th."}
+ "Ma\a*th"}
{"\t\t"
"Math.abs*Math.atan2"}
}
More information about the nginx-devel
mailing list