details: https://hg.nginx.org/njs/rev/74d30c2d70f3 branches: changeset: 1960:74d30c2d70f3 user: Dmitry Volyntsev <xei...@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") }, _______________________________________________ nginx-devel mailing list -- nginx-devel@nginx.org To unsubscribe send an email to nginx-devel-le...@nginx.org