[njs] Introduced "name" instance property for a function object.
Dmitry Volyntsev
xeioex at nginx.com
Wed Sep 21 00:46:00 UTC 2022
details: https://hg.nginx.org/njs/rev/74d30c2d70f3
branches:
changeset: 1960:74d30c2d70f3
user: Dmitry Volyntsev <xeioex at nginx.com>
date: Tue Sep 20 17:44:25 2022 -0700
description:
Introduced "name" instance property for a function object.
This closes #360 issue on Github.
diffstat:
src/njs_async.c | 7 +++
src/njs_disassembler.c | 8 ++-
src/njs_error.c | 5 ++
src/njs_function.c | 99 +++++++++++++++++++++++++++++++++++------------
src/njs_function.h | 4 +
src/njs_generator.c | 92 ++++++++++++++++++++++++++++++++++++++++---
src/njs_object_prop.c | 5 ++
src/njs_parser.c | 10 ++--
src/njs_value.c | 1 +
src/njs_value.h | 1 +
src/njs_vm.c | 1 +
src/njs_vm.h | 1 +
src/njs_vmcode.c | 36 +++++++++++++---
src/njs_vmcode.h | 2 +
src/test/njs_unit_test.c | 71 +++++++++++++++++++++++++++++++++-
15 files changed, 293 insertions(+), 50 deletions(-)
diffs (670 lines):
diff -r 33fcc9fc6704 -r 74d30c2d70f3 src/njs_async.c
--- a/src/njs_async.c Mon Sep 19 17:36:02 2022 -0700
+++ b/src/njs_async.c Tue Sep 20 17:44:25 2022 -0700
@@ -228,6 +228,13 @@ const njs_object_prop_t njs_async_funct
.value = njs_prop_handler(njs_function_instance_length),
.configurable = 1,
},
+
+ {
+ .type = NJS_PROPERTY_HANDLER,
+ .name = njs_string("name"),
+ .value = njs_prop_handler(njs_function_instance_name),
+ .configurable = 1,
+ },
};
diff -r 33fcc9fc6704 -r 74d30c2d70f3 src/njs_disassembler.c
--- a/src/njs_disassembler.c Mon Sep 19 17:36:02 2022 -0700
+++ b/src/njs_disassembler.c Tue Sep 20 17:44:25 2022 -0700
@@ -74,8 +74,12 @@ static njs_code_name_t code_names[] = {
njs_str("VOID ") },
{ NJS_VMCODE_TYPEOF, sizeof(njs_vmcode_2addr_t),
njs_str("TYPEOF ") },
- { NJS_VMCODE_TO_PROPERTY_KEY, sizeof(njs_vmcode_3addr_t),
- njs_str("TO PROPERTY KEY ") },
+ { NJS_VMCODE_TO_PROPERTY_KEY, sizeof(njs_vmcode_2addr_t),
+ njs_str("TO PROP KEY ") },
+ { NJS_VMCODE_TO_PROPERTY_KEY_CHK, sizeof(njs_vmcode_3addr_t),
+ njs_str("TO PROP KEY CHK ") },
+ { NJS_VMCODE_SET_FUNCTION_NAME, sizeof(njs_vmcode_2addr_t),
+ njs_str("SET FUNC NAME ") },
{ NJS_VMCODE_UNARY_PLUS, sizeof(njs_vmcode_2addr_t),
njs_str("PLUS ") },
diff -r 33fcc9fc6704 -r 74d30c2d70f3 src/njs_error.c
--- a/src/njs_error.c Mon Sep 19 17:36:02 2022 -0700
+++ b/src/njs_error.c Tue Sep 20 17:44:25 2022 -0700
@@ -1319,6 +1319,11 @@ njs_add_backtrace_entry(njs_vm_t *vm, nj
if (code != NULL) {
be->name = code->name;
+
+ if (be->name.length == 0) {
+ be->name = njs_entry_anonymous;
+ }
+
be->line = njs_lookup_line(code->lines, native_frame->pc - code->start);
if (!vm->options.quiet) {
be->file = code->file;
diff -r 33fcc9fc6704 -r 74d30c2d70f3 src/njs_function.c
--- a/src/njs_function.c Mon Sep 19 17:36:02 2022 -0700
+++ b/src/njs_function.c Tue Sep 20 17:44:25 2022 -0700
@@ -145,29 +145,34 @@ njs_function_name_set(njs_vm_t *vm, njs_
}
if (prefix != NULL || symbol != 0) {
- value = prop->value;
- (void) njs_string_prop(&string, &value);
+ if (njs_is_defined(&prop->value)) {
+ value = prop->value;
+ (void) njs_string_prop(&string, &value);
- len = (prefix != NULL) ? njs_strlen(prefix) + 1: 0;
- p = njs_string_alloc(vm, &prop->value, string.size + len + symbol,
- string.length + len + symbol);
- if (njs_slow_path(p == NULL)) {
- return NJS_ERROR;
- }
+ len = (prefix != NULL) ? njs_strlen(prefix) + 1: 0;
+ p = njs_string_alloc(vm, &prop->value, string.size + len + symbol,
+ string.length + len + symbol);
+ if (njs_slow_path(p == NULL)) {
+ return NJS_ERROR;
+ }
- if (len != 0) {
- p = njs_cpymem(p, prefix, len - 1);
- *p++ = ' ';
- }
+ if (len != 0) {
+ p = njs_cpymem(p, prefix, len - 1);
+ *p++ = ' ';
+ }
+
+ if (symbol != 0) {
+ *p++ = '[';
+ }
- if (symbol != 0) {
- *p++ = '[';
- }
+ p = njs_cpymem(p, string.start, string.size);
- p = njs_cpymem(p, string.start, string.size);
+ if (symbol != 0) {
+ *p++ = ']';
+ }
- if (symbol != 0) {
- *p++ = ']';
+ } else {
+ njs_value_assign(&prop->value, &njs_string_empty);
}
}
@@ -1253,6 +1258,12 @@ njs_function_constructor(njs_vm_t *vm, n
function->global_this = 1;
function->args_count = lambda->nargs - lambda->rest_parameters;
+ ret = njs_function_name_set(vm, function,
+ njs_value_arg(&njs_string_anonymous), NULL);
+ if (njs_slow_path(ret == NJS_ERROR)) {
+ return ret;
+ }
+
njs_set_function(&vm->retval, function);
return NJS_OK;
@@ -1324,6 +1335,30 @@ njs_function_instance_length(njs_vm_t *v
}
+njs_int_t
+njs_function_instance_name(njs_vm_t *vm, njs_object_prop_t *prop,
+ njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
+{
+ njs_function_t *function;
+
+ function = njs_object_proto_lookup(njs_object(value), NJS_FUNCTION,
+ njs_function_t);
+ if (njs_slow_path(function == NULL)) {
+ njs_set_undefined(retval);
+ return NJS_DECLINED;
+ }
+
+ if (!function->native) {
+ njs_value_assign(retval, &function->u.lambda->name);
+ return NJS_OK;
+ }
+
+ njs_value_assign(retval, &njs_string_empty);
+
+ return NJS_OK;
+}
+
+
static njs_int_t
njs_function_prototype_call(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
njs_index_t unused)
@@ -1447,11 +1482,10 @@ static njs_int_t
njs_function_prototype_bind(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
njs_index_t unused)
{
- size_t size;
- njs_int_t ret;
- njs_value_t *values, name;
- njs_function_t *function;
- njs_lvlhsh_query_t lhq;
+ size_t size;
+ njs_int_t ret;
+ njs_value_t *values, name;
+ njs_function_t *function;
if (!njs_is_function(&args[0])) {
njs_type_error(vm, "\"this\" argument is not a function");
@@ -1476,9 +1510,8 @@ njs_function_prototype_bind(njs_vm_t *vm
function->u.bound_target = njs_function(&args[0]);
- njs_object_property_init(&lhq, &njs_string_name, NJS_NAME_HASH);
-
- ret = njs_object_property(vm, &args[0], &lhq, &name);
+ ret = njs_value_property(vm, &args[0], njs_value_arg(&njs_string_name),
+ &name);
if (njs_slow_path(ret == NJS_ERROR)) {
return ret;
}
@@ -1616,6 +1649,13 @@ const njs_object_prop_t njs_function_in
{
.type = NJS_PROPERTY_HANDLER,
+ .name = njs_string("name"),
+ .value = njs_prop_handler(njs_function_instance_name),
+ .configurable = 1,
+ },
+
+ {
+ .type = NJS_PROPERTY_HANDLER,
.name = njs_string("prototype"),
.value = njs_prop_handler(njs_function_prototype_create),
.writable = 1
@@ -1637,6 +1677,13 @@ const njs_object_prop_t njs_arrow_insta
.value = njs_prop_handler(njs_function_instance_length),
.configurable = 1,
},
+
+ {
+ .type = NJS_PROPERTY_HANDLER,
+ .name = njs_string("name"),
+ .value = njs_prop_handler(njs_function_instance_name),
+ .configurable = 1,
+ },
};
diff -r 33fcc9fc6704 -r 74d30c2d70f3 src/njs_function.h
--- a/src/njs_function.h Mon Sep 19 17:36:02 2022 -0700
+++ b/src/njs_function.h Tue Sep 20 17:44:25 2022 -0700
@@ -23,6 +23,8 @@ struct njs_function_lambda_s {
uint8_t ctor; /* 1 bit */
uint8_t rest_parameters; /* 1 bit */
+ njs_value_t name;
+
u_char *start;
};
@@ -99,6 +101,8 @@ njs_int_t njs_function_constructor(njs_v
njs_uint_t nargs, njs_index_t unused);
njs_int_t njs_function_instance_length(njs_vm_t *vm, njs_object_prop_t *prop,
njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
+njs_int_t njs_function_instance_name(njs_vm_t *vm, njs_object_prop_t *prop,
+ njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
njs_int_t njs_eval_function(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
njs_index_t unused);
njs_int_t njs_function_native_frame(njs_vm_t *vm, njs_function_t *function,
diff -r 33fcc9fc6704 -r 74d30c2d70f3 src/njs_generator.c
--- a/src/njs_generator.c Mon Sep 19 17:36:02 2022 -0700
+++ b/src/njs_generator.c Tue Sep 20 17:44:25 2022 -0700
@@ -1050,10 +1050,12 @@ static njs_int_t
njs_generate_var_statement_after(njs_vm_t *vm, njs_generator_t *generator,
njs_parser_node_t *node)
{
- njs_int_t ret;
- njs_variable_t *var;
- njs_parser_node_t *lvalue, *expr;
- njs_vmcode_move_t *move;
+ ssize_t length;
+ njs_int_t ret;
+ njs_variable_t *var;
+ njs_parser_node_t *lvalue, *expr;
+ njs_vmcode_move_t *move;
+ const njs_lexer_entry_t *lex_entry;
lvalue = node->left;
expr = node->right;
@@ -1080,6 +1082,29 @@ njs_generate_var_statement_after(njs_vm_
node->index = expr->index;
node->temporary = expr->temporary;
+ if ((expr->token_type == NJS_TOKEN_FUNCTION_EXPRESSION
+ || expr->token_type == NJS_TOKEN_ASYNC_FUNCTION_EXPRESSION)
+ && njs_values_same(&expr->u.value.data.u.lambda->name,
+ &njs_string_empty))
+ {
+ lex_entry = njs_lexer_entry(node->left->u.reference.unique_id);
+ if (njs_slow_path(lex_entry == NULL)) {
+ return NJS_ERROR;
+ }
+
+ length = njs_utf8_length(lex_entry->name.start, lex_entry->name.length);
+ if (njs_slow_path(length < 0)) {
+ return NJS_ERROR;
+ }
+
+ ret = njs_string_new(vm, &expr->u.value.data.u.lambda->name,
+ lex_entry->name.start, lex_entry->name.length,
+ length);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return NJS_ERROR;
+ }
+ }
+
return njs_generator_stack_pop(vm, generator, NULL);
}
@@ -2854,7 +2879,9 @@ njs_generate_assignment_end(njs_vm_t *vm
njs_parser_node_t *node)
{
njs_int_t ret;
+ njs_index_t prop_index;
njs_parser_node_t *lvalue, *expr, *object, *property;
+ njs_vmcode_2addr_t *set_function, *to_prop_key;
njs_vmcode_prop_set_t *prop_set;
lvalue = node->left;
@@ -2862,9 +2889,34 @@ njs_generate_assignment_end(njs_vm_t *vm
object = lvalue->left;
property = lvalue->right;
+ prop_index = property->index;
switch (lvalue->token_type) {
case NJS_TOKEN_PROPERTY_INIT:
+
+ if ((expr->token_type == NJS_TOKEN_FUNCTION
+ || expr->token_type == NJS_TOKEN_FUNCTION_EXPRESSION
+ || expr->token_type == NJS_TOKEN_ASYNC_FUNCTION_EXPRESSION))
+ {
+ if (property->token_type == NJS_TOKEN_STRING) {
+ njs_value_assign(&expr->u.value.data.u.lambda->name,
+ &property->u.value);
+
+ } else {
+ njs_generate_code(generator, njs_vmcode_2addr_t, to_prop_key,
+ NJS_VMCODE_TO_PROPERTY_KEY, 2, property);
+
+ to_prop_key->src = property->index;
+ to_prop_key->dst = prop_index;
+
+ njs_generate_code(generator, njs_vmcode_2addr_t, set_function,
+ NJS_VMCODE_SET_FUNCTION_NAME, 2, expr);
+
+ set_function->dst = expr->index;
+ set_function->src = prop_index;
+ }
+ }
+
njs_generate_code(generator, njs_vmcode_prop_set_t, prop_set,
NJS_VMCODE_PROPERTY_INIT, 3, expr);
break;
@@ -2882,7 +2934,7 @@ njs_generate_assignment_end(njs_vm_t *vm
prop_set->value = expr->index;
prop_set->object = object->index;
- prop_set->property = property->index;
+ prop_set->property = prop_index;
node->index = expr->index;
node->temporary = expr->temporary;
@@ -3063,7 +3115,7 @@ njs_generate_operation_assignment_prop(n
}
njs_generate_code(generator, njs_vmcode_3addr_t, to_property_key,
- NJS_VMCODE_TO_PROPERTY_KEY, 2, property);
+ NJS_VMCODE_TO_PROPERTY_KEY_CHK, 2, property);
to_property_key->src2 = object->index;
to_property_key->src1 = property->index;
@@ -3233,6 +3285,7 @@ static njs_int_t
njs_generate_function_expression(njs_vm_t *vm, njs_generator_t *generator,
njs_parser_node_t *node)
{
+ ssize_t length;
njs_int_t ret;
njs_variable_t *var;
njs_function_lambda_t *lambda;
@@ -3262,6 +3315,17 @@ njs_generate_function_expression(njs_vm_
return ret;
}
+ length = njs_utf8_length(lex_entry->name.start, lex_entry->name.length);
+ if (njs_slow_path(length < 0)) {
+ return NJS_ERROR;
+ }
+
+ ret = njs_string_new(vm, &lambda->name, lex_entry->name.start,
+ lex_entry->name.length, length);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return NJS_ERROR;
+ }
+
njs_generate_code(generator, njs_vmcode_function_t, function,
NJS_VMCODE_FUNCTION, 1, node);
function->lambda = lambda;
@@ -3289,7 +3353,7 @@ njs_generate_function(njs_vm_t *vm, njs_
lambda = node->u.value.data.u.lambda;
ret = njs_generate_function_scope(vm, generator, lambda, node,
- &njs_entry_anonymous);
+ &njs_entry_empty);
if (njs_slow_path(ret != NJS_OK)) {
return ret;
}
@@ -3731,7 +3795,7 @@ found:
}
njs_generate_code(generator, njs_vmcode_3addr_t, to_property_key,
- NJS_VMCODE_TO_PROPERTY_KEY, 2, node);
+ NJS_VMCODE_TO_PROPERTY_KEY_CHK, 2, node);
to_property_key->src2 = lvalue->left->index;
to_property_key->src1 = lvalue->right->index;
@@ -3787,6 +3851,7 @@ static njs_int_t
njs_generate_function_declaration(njs_vm_t *vm, njs_generator_t *generator,
njs_parser_node_t *node)
{
+ ssize_t length;
njs_int_t ret;
njs_bool_t async;
njs_variable_t *var;
@@ -3811,6 +3876,17 @@ njs_generate_function_declaration(njs_vm
return NJS_ERROR;
}
+ length = njs_utf8_length(lex_entry->name.start, lex_entry->name.length);
+ if (njs_slow_path(length < 0)) {
+ return NJS_ERROR;
+ }
+
+ ret = njs_string_new(vm, &lambda->name, lex_entry->name.start,
+ lex_entry->name.length, length);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return NJS_ERROR;
+ }
+
ret = njs_generate_function_scope(vm, generator, lambda, node,
&lex_entry->name);
if (njs_slow_path(ret != NJS_OK)) {
diff -r 33fcc9fc6704 -r 74d30c2d70f3 src/njs_object_prop.c
--- a/src/njs_object_prop.c Mon Sep 19 17:36:02 2022 -0700
+++ b/src/njs_object_prop.c Tue Sep 20 17:44:25 2022 -0700
@@ -452,6 +452,11 @@ done:
pq.lhq.value = NULL;
goto set_prop;
}
+
+ } else {
+
+ prev->type = prop->type;
+ njs_value_assign(&prev->value, &prop->value);
}
} else {
diff -r 33fcc9fc6704 -r 74d30c2d70f3 src/njs_parser.c
--- a/src/njs_parser.c Mon Sep 19 17:36:02 2022 -0700
+++ b/src/njs_parser.c Tue Sep 20 17:44:25 2022 -0700
@@ -6872,9 +6872,9 @@ njs_parser_function_parse(njs_parser_t *
}
-static const njs_lexer_entry_t njs_parser_anonymous_entry =
-{
- .name = njs_str("anonymous")
+static const njs_lexer_entry_t njs_parser_empty_entry =
+{
+ .name = njs_str("")
};
@@ -6909,7 +6909,7 @@ njs_parser_function_expression(njs_parse
}
} else {
- unique_id = (uintptr_t) &njs_parser_anonymous_entry;
+ unique_id = (uintptr_t) &njs_parser_empty_entry;
}
if (token->type != NJS_TOKEN_OPEN_PARENTHESIS) {
@@ -7155,7 +7155,7 @@ njs_parser_arrow_function(njs_parser_t *
node->left = name;
- unique_id = (uintptr_t) &njs_parser_anonymous_entry;
+ unique_id = (uintptr_t) &njs_parser_empty_entry;
var = njs_variable_scope_add(parser, parser->scope, parser->scope,
unique_id, NJS_VARIABLE_FUNCTION, 1);
diff -r 33fcc9fc6704 -r 74d30c2d70f3 src/njs_value.c
--- a/src/njs_value.c Mon Sep 19 17:36:02 2022 -0700
+++ b/src/njs_value.c Tue Sep 20 17:44:25 2022 -0700
@@ -54,6 +54,7 @@ const njs_value_t njs_string_external =
const njs_value_t njs_string_invalid = njs_string("invalid");
const njs_value_t njs_string_object = njs_string("object");
const njs_value_t njs_string_function = njs_string("function");
+const njs_value_t njs_string_anonymous = njs_string("anonymous");
const njs_value_t njs_string_memory_error = njs_string("MemoryError");
diff -r 33fcc9fc6704 -r 74d30c2d70f3 src/njs_value.h
--- a/src/njs_value.h Mon Sep 19 17:36:02 2022 -0700
+++ b/src/njs_value.h Tue Sep 20 17:44:25 2022 -0700
@@ -836,6 +836,7 @@ extern const njs_value_t njs_string_ext
extern const njs_value_t njs_string_invalid;
extern const njs_value_t njs_string_object;
extern const njs_value_t njs_string_function;
+extern const njs_value_t njs_string_anonymous;
extern const njs_value_t njs_string_memory_error;
diff -r 33fcc9fc6704 -r 74d30c2d70f3 src/njs_vm.c
--- a/src/njs_vm.c Mon Sep 19 17:36:02 2022 -0700
+++ b/src/njs_vm.c Tue Sep 20 17:44:25 2022 -0700
@@ -12,6 +12,7 @@ static njs_int_t njs_vm_init(njs_vm_t *v
static njs_int_t njs_vm_handle_events(njs_vm_t *vm);
+const njs_str_t njs_entry_empty = njs_str("");
const njs_str_t njs_entry_main = njs_str("main");
const njs_str_t njs_entry_module = njs_str("module");
const njs_str_t njs_entry_native = njs_str("native");
diff -r 33fcc9fc6704 -r 74d30c2d70f3 src/njs_vm.h
--- a/src/njs_vm.h Mon Sep 19 17:36:02 2022 -0700
+++ b/src/njs_vm.h Tue Sep 20 17:44:25 2022 -0700
@@ -267,6 +267,7 @@ void *njs_lvlhsh_alloc(void *data, size_
void njs_lvlhsh_free(void *data, void *p, size_t size);
+extern const njs_str_t njs_entry_empty;
extern const njs_str_t njs_entry_main;
extern const njs_str_t njs_entry_module;
extern const njs_str_t njs_entry_native;
diff -r 33fcc9fc6704 -r 74d30c2d70f3 src/njs_vmcode.c
--- a/src/njs_vmcode.c Mon Sep 19 17:36:02 2022 -0700
+++ b/src/njs_vmcode.c Tue Sep 20 17:44:25 2022 -0700
@@ -889,21 +889,41 @@ next:
break;
case NJS_VMCODE_TO_PROPERTY_KEY:
+ case NJS_VMCODE_TO_PROPERTY_KEY_CHK:
njs_vmcode_operand(vm, (njs_index_t) value2, retval);
- njs_vmcode_operand(vm, vmcode->operand3, value2);
-
- if (njs_slow_path(njs_is_null_or_undefined(value2))) {
- (void) njs_throw_cannot_property(vm, value2, value1,
- "get");
- goto error;
+
+ if (op == NJS_VMCODE_TO_PROPERTY_KEY_CHK) {
+ njs_vmcode_operand(vm, vmcode->operand3, value2);
+
+ if (njs_slow_path(njs_is_null_or_undefined(value2))) {
+ (void) njs_throw_cannot_property(vm, value2, value1,
+ "get");
+ goto error;
+ }
}
- ret = njs_value_to_string(vm, retval, value1);
+ ret = njs_value_to_key(vm, retval, value1);
if (njs_fast_path(ret == NJS_ERROR)) {
goto error;
}
- ret = sizeof(njs_vmcode_3addr_t);
+ ret = (op == NJS_VMCODE_TO_PROPERTY_KEY)
+ ? sizeof(njs_vmcode_2addr_t)
+ : sizeof(njs_vmcode_3addr_t);
+ break;
+
+ case NJS_VMCODE_SET_FUNCTION_NAME:
+ njs_vmcode_operand(vm, (njs_index_t) value2, value2);
+
+ njs_assert(njs_is_function(value2));
+
+ ret = njs_function_name_set(vm, njs_function(value2), value1,
+ NULL);
+ if (njs_slow_path(ret == NJS_ERROR)) {
+ return ret;
+ }
+
+ ret = sizeof(njs_vmcode_2addr_t);
break;
case NJS_VMCODE_PROTO_INIT:
diff -r 33fcc9fc6704 -r 74d30c2d70f3 src/njs_vmcode.h
--- a/src/njs_vmcode.h Mon Sep 19 17:36:02 2022 -0700
+++ b/src/njs_vmcode.h Tue Sep 20 17:44:25 2022 -0700
@@ -50,6 +50,8 @@ enum {
NJS_VMCODE_ARGUMENTS,
NJS_VMCODE_PROTO_INIT,
NJS_VMCODE_TO_PROPERTY_KEY,
+ NJS_VMCODE_TO_PROPERTY_KEY_CHK,
+ NJS_VMCODE_SET_FUNCTION_NAME,
NJS_VMCODE_IMPORT,
NJS_VMCODE_AWAIT,
diff -r 33fcc9fc6704 -r 74d30c2d70f3 src/test/njs_unit_test.c
--- a/src/test/njs_unit_test.c Mon Sep 19 17:36:02 2022 -0700
+++ b/src/test/njs_unit_test.c Tue Sep 20 17:44:25 2022 -0700
@@ -3846,6 +3846,24 @@ static njs_unit_test_t njs_test[] =
{ njs_str("({[{toString(){return {}}}]:1})"),
njs_str("TypeError: Cannot convert object to primitive value") },
+ { njs_str("({['a' + 'v'](){}}).av.name"),
+ njs_str("av") },
+
+ { njs_str("({[Symbol.toStringTag](){}})[Symbol.toStringTag].name"),
+ njs_str("[Symbol.toStringTag]") },
+
+ { njs_str("var anonSym = Symbol(); ({[anonSym]: () => {}})[anonSym].name"),
+ njs_str("") },
+
+ { njs_str("var named = Symbol('xxx'); ({[named]: () => {}})[named].name"),
+ njs_str("[xxx]") },
+
+ { njs_str("var called = false;"
+ "({"
+ " [{toString(){ if (called) throw 'OOps'; called = true; return 'a'}}](){}"
+ "}).a.name"),
+ njs_str("a") },
+
{ njs_str("var o = { [new Number(12345)]: 1000 }; o[12345]"),
njs_str("1000") },
@@ -7740,6 +7758,10 @@ static njs_unit_test_t njs_test[] =
"var o = { toString: f }; o"),
njs_str("0,1,2") },
+ { njs_str("var f = function F() {};"
+ "[f.name, f.bind().name, f.bind().bind().name]"),
+ njs_str("F,bound F,bound bound F") },
+
{ njs_str("var f = Object.defineProperty(function() {}, 'name', {value: 'F'});"
"[f.name, f.bind().name, f.bind().bind().name]"),
njs_str("F,bound F,bound bound F") },
@@ -9948,6 +9970,53 @@ static njs_unit_test_t njs_test[] =
"f.length"),
njs_str("42") },
+ { njs_str("function f(){}; f.name"),
+ njs_str("f") },
+
+ { njs_str("function f(){}; njs.dump(Object.getOwnPropertyDescriptor(f, 'name'))"),
+ njs_str("{value:'f',writable:false,enumerable:false,configurable:true}") },
+
+ { njs_str("function f(){}; Object.defineProperty(f, 'name', {value: 'F'}); f.name"),
+ njs_str("F") },
+
+ { njs_str("function f(){}; Object.defineProperty(f, 'name', {value: 'F'});"
+ "njs.dump(Object.getOwnPropertyDescriptor(f, 'name'))"),
+ njs_str("{value:'F',writable:false,enumerable:false,configurable:true}") },
+
+ { njs_str("function f() {}; f.name = 'a'"),
+ njs_str("TypeError: Cannot assign to read-only property \"name\" of function") },
+
+ { njs_str("(function f () { return f.name})()"),
+ njs_str("f") },
+
+ { njs_str("var a = function () {}; a.name"),
+ njs_str("a") },
+
+ { njs_str("(function () {}).name"),
+ njs_str("") },
+
+ { njs_str("var a = (null, function () {}); a.name"),
+ njs_str("") },
+
+ { njs_str("var a = async function () {}; a.name"),
+ njs_str("a") },
+
+ { njs_str("let a = () => {}; a.name"),
+ njs_str("a") },
+
+ { njs_str("let a = async () => {}; a.name"),
+ njs_str("a") },
+
+ { njs_str("Function().name"),
+ njs_str("anonymous") },
+
+ { njs_str("var o = {f: function (){}, g: () => {}, h: async function(){}};"
+ "[o.f.name, o.g.name, o.h.name]"),
+ njs_str("f,g,h") },
+
+ { njs_str("({t(){}}).t.name"),
+ njs_str("t") },
+
/* Function nesting depth. */
{ njs_str("() => () => () => () => () => () => () => () => () => () => () =>"
@@ -14789,7 +14858,7 @@ static njs_unit_test_t njs_test[] =
njs_str("0,1,2,length") },
{ njs_str("Object.getOwnPropertyNames(function() {})"),
- njs_str("length,prototype") },
+ njs_str("length,name,prototype") },
{ njs_str("Object.getOwnPropertyNames(Array)"),
njs_str("name,length,prototype,isArray,of") },
More information about the nginx-devel
mailing list