From: Vadim Zhestikov Date: Thu, 29 Aug 2024 05:03:14 +0000 (-0700) Subject: Refactored working with built-in strings, symbols and small integers. X-Git-Tag: 0.9.0~11 X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=b28e50b1;p=njs.git Refactored working with built-in strings, symbols and small integers. - Implemented atom IDs for strings, symbols and small numbers, enabling equality checks via ID comparison - Optimized string operations for faster property lookups and comparisons - Removed short string inlining from njs_value_t structure Performance improvements (arewefastyet/benchmarks/v8-v7 benchmark): - Richards: +57% (631 → 989) - Crypto: +7% (1445 → 1551) - RayTrace: +37% (562 → 772) - NavierStokes: +20% (2062 → 2465) - Overall score: +29% (1014 → 1307) In collaboration with Dmitry Volyntsev. --- diff --git a/auto/sources b/auto/sources index 9b33eead..0e8db2cd 100644 --- a/auto/sources +++ b/auto/sources @@ -19,10 +19,10 @@ NJS_LIB_SRCS=" \ src/njs_utils.c \ src/njs_chb.c \ src/njs_value.c \ + src/njs_atom.c \ src/njs_vm.c \ src/njs_vmcode.c \ src/njs_lexer.c \ - src/njs_lexer_keyword.c \ src/njs_parser.c \ src/njs_variable.c \ src/njs_scope.c \ diff --git a/external/njs_crypto_module.c b/external/njs_crypto_module.c index 2781a485..cdbb4b30 100644 --- a/external/njs_crypto_module.c +++ b/external/njs_crypto_module.c @@ -362,7 +362,7 @@ njs_hash_prototype_update(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return NJS_ERROR; } - njs_value_string_get(njs_value_arg(&result), &data); + njs_value_string_get(vm, njs_value_arg(&result), &data); } else if (njs_value_is_buffer(value)) { ret = njs_value_buffer_get(vm, value, &data); @@ -526,7 +526,7 @@ njs_crypto_create_hmac(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return NJS_ERROR; } - njs_value_string_get(njs_value_arg(&result), &key); + njs_value_string_get(vm, njs_value_arg(&result), &key); } else if (njs_value_is_buffer(value)) { ret = njs_value_buffer_get(vm, value, &key); @@ -589,7 +589,7 @@ njs_crypto_algorithm(njs_vm_t *vm, njs_value_t *value) return NULL; } - njs_value_string_get(value, &name); + njs_value_string_get(vm, value, &name); for (e = &njs_hash_algorithms[0]; e->name.length != 0; e++) { if (njs_strstr_eq(&name, &e->name)) { @@ -618,7 +618,7 @@ njs_crypto_encoding(njs_vm_t *vm, njs_value_t *value) return &njs_encodings[0]; } - njs_value_string_get(value, &name); + njs_value_string_get(vm, value, &name); for (e = &njs_encodings[1]; e->name.length != 0; e++) { if (njs_strstr_eq(&name, &e->name)) { diff --git a/external/njs_fs_module.c b/external/njs_fs_module.c index 5f8924ae..c56a685a 100644 --- a/external/njs_fs_module.c +++ b/external/njs_fs_module.c @@ -180,7 +180,8 @@ static njs_int_t njs_fs_write_file(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t calltype, njs_value_t *retval); static njs_int_t njs_fs_constant(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval); + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval); static njs_int_t njs_fs_dirent_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval); @@ -190,7 +191,8 @@ static njs_int_t njs_fs_dirent_test(njs_vm_t *vm, njs_value_t *args, static njs_int_t njs_fs_stats_test(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t testtype, njs_value_t *retval); static njs_int_t njs_fs_stats_prop(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval); + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval); static njs_int_t njs_fs_stats_create(njs_vm_t *vm, struct stat *st, njs_value_t *retval); @@ -1966,7 +1968,7 @@ njs_fs_readdir(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, if (njs_value_is_string(njs_value_arg(&encode))) { - njs_value_string_get(njs_value_arg(&encode), &s); + njs_value_string_get(vm, njs_value_arg(&encode), &s); } else { s.length = 0; @@ -2111,7 +2113,7 @@ njs_fs_readlink(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, encoding = NULL; if (njs_value_is_string(njs_value_arg(&encode))) { - njs_value_string_get(njs_value_arg(&encode), &s); + njs_value_string_get(vm, njs_value_arg(&encode), &s); } else { s.length = 0; @@ -2203,7 +2205,7 @@ njs_fs_realpath(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, encoding = NULL; if (njs_value_is_string(njs_value_arg(&encode))) { - njs_value_string_get(njs_value_arg(&encode), &s); + njs_value_string_get(vm, njs_value_arg(&encode), &s); } else { s.length = 0; @@ -2610,7 +2612,7 @@ njs_fs_write(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return NJS_ERROR; } - njs_value_string_get(njs_value_arg(&result), &data); + njs_value_string_get(vm, njs_value_arg(&result), &data); goto process; } @@ -2790,7 +2792,7 @@ njs_fs_write_file(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return NJS_ERROR; } - njs_value_string_get(njs_value_arg(&result), &content); + njs_value_string_get(vm, njs_value_arg(&result), &content); } flags = njs_fs_flags(vm, njs_value_arg(&flag), O_CREAT | O_WRONLY); @@ -3213,7 +3215,7 @@ njs_fs_path(njs_vm_t *vm, char storage[NJS_MAX_PATH + 1], njs_value_t *src, njs_int_t ret; if (njs_value_is_string(src)) { - njs_value_string_get(src, &str); + njs_value_string_get(vm, src, &str); } else if (njs_value_is_buffer(src)) { ret = njs_value_buffer_get(vm, src, &str); @@ -3261,7 +3263,7 @@ njs_fs_flags(njs_vm_t *vm, njs_value_t *value, int default_flags) return -1; } - njs_value_string_get(value, &flags); + njs_value_string_get(vm, value, &flags); for (fl = &njs_flags_table[0]; fl->name.length != 0; fl++) { if (njs_strstr_eq(&flags, &fl->name)) { @@ -3651,8 +3653,8 @@ njs_fs_stats_test(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, static njs_int_t -njs_fs_stats_prop(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, - njs_value_t *setval, njs_value_t *retval) +njs_fs_stats_prop(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, + njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { double v; njs_int_t ret; @@ -3870,8 +3872,8 @@ njs_fs_bytes_written_create(njs_vm_t *vm, int bytes, njs_value_t *buffer, njs_int_t -njs_fs_constant(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, - njs_value_t *setval, njs_value_t *retval) +njs_fs_constant(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, + njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { njs_value_number_set(retval, njs_vm_prop_magic32(prop)); diff --git a/external/njs_query_string_module.c b/external/njs_query_string_module.c index e2f849d2..c5b4d58a 100644 --- a/external/njs_query_string_module.c +++ b/external/njs_query_string_module.c @@ -294,8 +294,8 @@ njs_query_string_append(njs_vm_t *vm, njs_value_t *object, const u_char *key, } } - ret = njs_value_property(vm, object, njs_value_arg(&name), - njs_value_arg(&retval)); + ret = njs_value_property_val(vm, object, njs_value_arg(&name), + njs_value_arg(&retval)); if (ret == NJS_OK) { if (njs_value_is_array(njs_value_arg(&retval))) { @@ -331,8 +331,8 @@ njs_query_string_append(njs_vm_t *vm, njs_value_t *object, const u_char *key, njs_value_assign(&value, &array); } - return njs_value_property_set(vm, object, njs_value_arg(&name), - njs_value_arg(&value)); + return njs_value_property_val_set(vm, object, njs_value_arg(&name), + njs_value_arg(&value)); } @@ -383,7 +383,7 @@ njs_query_string_parse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, string = njs_arg(args, nargs, 1); if (njs_value_is_string(string)) { - njs_value_string_get(string, &str); + njs_value_string_get(vm, string, &str); } else { str = njs_str_value(""); @@ -399,8 +399,8 @@ njs_query_string_parse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return ret; } - if (njs_string_length(njs_value_arg(&val_sep)) != 0) { - njs_value_string_get(njs_value_arg(&val_sep), &sep); + if (njs_value_string_length(vm, njs_value_arg(&val_sep)) != 0) { + njs_value_string_get(vm, njs_value_arg(&val_sep), &sep); } } @@ -411,8 +411,8 @@ njs_query_string_parse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return ret; } - if (njs_string_length(njs_value_arg(&val_eq)) != 0) { - njs_value_string_get(njs_value_arg(&val_eq), &eq); + if (njs_value_string_length(vm, njs_value_arg(&val_eq)) != 0) { + njs_value_string_get(vm, njs_value_arg(&val_eq), &eq); } } @@ -614,7 +614,7 @@ njs_query_string_encoder_call(njs_vm_t *vm, njs_chb_t *chain, } if (njs_fast_path(njs_query_string_is_native_encoder(encoder))) { - njs_value_string_get(string, &str); + njs_value_string_get(vm, string, &str); return njs_query_string_encode(chain, &str); } @@ -631,7 +631,7 @@ njs_query_string_encoder_call(njs_vm_t *vm, njs_chb_t *chain, } } - njs_value_string_get(njs_value_arg(&retval), &str); + njs_value_string_get(vm, njs_value_arg(&retval), &str); njs_chb_append_str(chain, &str); @@ -705,8 +705,8 @@ njs_query_string_stringify(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return ret; } - if (njs_string_length(arg) > 0) { - njs_value_string_get(arg, &sep); + if (njs_value_string_length(vm, arg) > 0) { + njs_value_string_get(vm, arg, &sep); } } @@ -717,8 +717,8 @@ njs_query_string_stringify(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return ret; } - if (njs_string_length(arg) > 0) { - njs_value_string_get(arg, &eq); + if (njs_value_string_length(vm, arg) > 0) { + njs_value_string_get(vm, arg, &eq); } } @@ -764,8 +764,8 @@ njs_query_string_stringify(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } for (n = 0; n < keys_length; n++, string++) { - ret = njs_value_property(vm, object, njs_value_arg(string), - njs_value_arg(&value)); + ret = njs_value_property_val(vm, object, njs_value_arg(string), + njs_value_arg(&value)); if (njs_slow_path(ret == NJS_ERROR)) { goto failed; } @@ -775,9 +775,9 @@ njs_query_string_stringify(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, for (i = 0; i < len; i++) { njs_value_number_set(njs_value_arg(&key), i); - ret = njs_value_property(vm, njs_value_arg(&value), - njs_value_arg(&key), - njs_value_arg(&result)); + ret = njs_value_property_val(vm, njs_value_arg(&value), + njs_value_arg(&key), + njs_value_arg(&result)); if (njs_slow_path(ret == NJS_ERROR)) { goto failed; } @@ -839,7 +839,7 @@ njs_query_string_escape(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, string = njs_value_arg(&value); } - njs_value_string_get(string, &str); + njs_value_string_get(vm, string, &str); NJS_CHB_MP_INIT(&chain, njs_vm_memory_pool(vm)); @@ -876,7 +876,7 @@ njs_query_string_unescape(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, string = njs_value_arg(&value); } - njs_value_string_get(string, &str); + njs_value_string_get(vm, string, &str); return njs_query_string_decode(vm, retval, str.start, str.length); } diff --git a/external/njs_shell.c b/external/njs_shell.c index aeab226c..75316339 100644 --- a/external/njs_shell.c +++ b/external/njs_shell.c @@ -1585,8 +1585,9 @@ njs_engine_njs_complete(njs_engine_t *engine, njs_str_t *expression) return NULL; } - ret = njs_value_property(vm, njs_value_arg(&value), njs_value_arg(&key), - njs_value_arg(&retval)); + ret = njs_value_property_val(vm, njs_value_arg(&value), + njs_value_arg(&key), + njs_value_arg(&retval)); if (njs_slow_path(ret != NJS_OK)) { if (ret == NJS_DECLINED && !global) { goto done; @@ -3664,11 +3665,11 @@ njs_ext_console_time(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return ret; } - njs_value_string_get(value, &name); + njs_value_string_get(vm, value, &name); } } else { - njs_value_string_get(value, &name); + njs_value_string_get(vm, value, &name); } if (njs_console_time(console, &name) != NJS_OK) { @@ -3713,11 +3714,11 @@ njs_ext_console_time_end(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return ret; } - njs_value_string_get(value, &name); + njs_value_string_get(vm, value, &name); } } else { - njs_value_string_get(value, &name); + njs_value_string_get(vm, value, &name); } njs_console_time_end(console, &name, ns); diff --git a/external/njs_webcrypto_module.c b/external/njs_webcrypto_module.c index 59d02c1d..d2918891 100644 --- a/external/njs_webcrypto_module.c +++ b/external/njs_webcrypto_module.c @@ -129,13 +129,17 @@ static njs_int_t njs_ext_unwrap_key(njs_vm_t *vm, njs_value_t *args, static njs_int_t njs_ext_wrap_key(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval); static njs_int_t njs_key_ext_algorithm(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval); + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval); static njs_int_t njs_key_ext_extractable(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval); + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval); static njs_int_t njs_key_ext_type(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval); + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval); static njs_int_t njs_key_ext_usages(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval); + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval); static njs_int_t njs_ext_get_random_values(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval); @@ -2767,7 +2771,7 @@ fail0: return NULL; } - njs_value_string_get(val, &alg); + njs_value_string_get(vm, val, &alg); for (w = &njs_webcrypto_alg_hash[0]; w->name.length != 0; w++) { if (njs_strstr_eq(&alg, &w->name)) { @@ -3068,7 +3072,7 @@ fail0: val = njs_vm_object_prop(vm, jwk, &string_crv, &value); if (val != NULL && !njs_value_is_undefined(val)) { - njs_value_string_get(val, &name); + njs_value_string_get(vm, val, &name); for (e = &njs_webcrypto_curve[0]; e->name.length != 0; e++) { if (njs_strstr_eq(&name, &e->name)) { @@ -3194,7 +3198,7 @@ njs_import_jwk_oct(njs_vm_t *vm, njs_value_t *jwk, njs_webcrypto_key_t *key) return NJS_ERROR; } - njs_value_string_get(val, &b64); + njs_value_string_get(vm, val, &b64); (void) njs_decode_base64url_length(&b64, &key->u.s.raw.length); @@ -3213,7 +3217,7 @@ njs_import_jwk_oct(njs_vm_t *vm, njs_value_t *jwk, njs_webcrypto_key_t *key) return NJS_ERROR; } - njs_value_string_get(val, &alg); + njs_value_string_get(vm, val, &alg); size = 16; @@ -4133,8 +4137,8 @@ njs_ext_wrap_key(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, static njs_int_t -njs_key_ext_algorithm(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, - njs_value_t *setval, njs_value_t *retval) +njs_key_ext_algorithm(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, + njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { u_char *start; njs_int_t ret; @@ -4292,7 +4296,7 @@ njs_key_ext_algorithm(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, static njs_int_t -njs_key_ext_extractable(njs_vm_t *vm, njs_object_prop_t *prop, +njs_key_ext_extractable(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { njs_webcrypto_key_t *key; @@ -4310,8 +4314,8 @@ njs_key_ext_extractable(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t -njs_key_ext_type(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, - njs_value_t *setval, njs_value_t *retval) +njs_key_ext_type(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, + njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { const char *type; njs_webcrypto_key_t *key; @@ -4336,8 +4340,8 @@ njs_key_ext_type(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, static njs_int_t -njs_key_ext_usages(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, - njs_value_t *setval, njs_value_t *retval) +njs_key_ext_usages(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, + njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { njs_webcrypto_key_t *key; @@ -4436,7 +4440,7 @@ njs_key_format(njs_vm_t *vm, njs_value_t *value) return NJS_KEY_FORMAT_UNKNOWN; } - njs_value_string_get(njs_value_arg(&string), &format); + njs_value_string_get(vm, njs_value_arg(&string), &format); for (e = &njs_webcrypto_format[0]; e->name.length != 0; e++) { if (njs_strstr_eq(&format, &e->name)) { @@ -4482,7 +4486,7 @@ njs_key_usage_array_handler(njs_vm_t *vm, njs_iterator_args_t *args, return NJS_ERROR; } - njs_value_string_get(njs_value_arg(&usage), &u); + njs_value_string_get(vm, njs_value_arg(&usage), &u); for (e = &njs_webcrypto_usage[0]; e->name.length != 0; e++) { if (njs_strstr_eq(&u, &e->name)) { @@ -4585,7 +4589,7 @@ njs_key_algorithm(njs_vm_t *vm, njs_value_t *options) return NULL; } - njs_value_string_get(njs_value_arg(&name), &a); + njs_value_string_get(vm, njs_value_arg(&name), &a); for (e = &njs_webcrypto_alg[0]; e->name.length != 0; e++) { if (njs_strstr_case_eq(&a, &e->name)) { @@ -4647,7 +4651,7 @@ njs_algorithm_hash(njs_vm_t *vm, njs_value_t *options, return NJS_ERROR; } - njs_value_string_get(njs_value_arg(&value), &name); + njs_value_string_get(vm, njs_value_arg(&value), &name); for (e = &njs_webcrypto_hash[0]; e->name.length != 0; e++) { if (njs_strstr_eq(&name, &e->name)) { @@ -4722,7 +4726,7 @@ njs_algorithm_curve(njs_vm_t *vm, njs_value_t *options, int *curve) return NJS_ERROR; } - njs_value_string_get(njs_value_arg(&value), &name); + njs_value_string_get(vm, njs_value_arg(&value), &name); for (e = &njs_webcrypto_curve[0]; e->name.length != 0; e++) { if (njs_strstr_eq(&name, &e->name)) { diff --git a/external/njs_xml_module.c b/external/njs_xml_module.c index e524ba5c..95e5024a 100644 --- a/external/njs_xml_module.c +++ b/external/njs_xml_module.c @@ -43,27 +43,32 @@ static njs_int_t njs_xml_ext_canonicalization(njs_vm_t *vm, njs_value_t *args, static njs_int_t njs_xml_doc_ext_prop_keys(njs_vm_t *vm, njs_value_t *value, njs_value_t *keys); static njs_int_t njs_xml_doc_ext_root(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *unused, njs_value_t *retval); + uint32_t atom_id, njs_value_t *value, njs_value_t *unused, + njs_value_t *retval); static njs_int_t njs_xml_node_ext_prop_keys(njs_vm_t *vm, njs_value_t *value, njs_value_t *keys); static njs_int_t njs_xml_node_ext_prop_handler(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *unused, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t atom_id, njs_value_t *value, + njs_value_t *unused, njs_value_t *retval); static njs_int_t njs_xml_attr_ext_prop_keys(njs_vm_t *vm, njs_value_t *value, njs_value_t *keys); static njs_int_t njs_xml_attr_ext_prop_handler(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *unused, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t atom_id, njs_value_t *value, + njs_value_t *unused, njs_value_t *retval); static njs_int_t njs_xml_node_ext_add_child(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval); static njs_int_t njs_xml_node_ext_attrs(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval); + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval); static njs_int_t njs_xml_node_ext_name(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval); + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval); static njs_int_t njs_xml_node_ext_ns(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval); + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval); static njs_int_t njs_xml_node_ext_parent(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval); + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval); static njs_int_t njs_xml_node_ext_remove_all_attributes(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval); @@ -83,9 +88,11 @@ static njs_int_t njs_xml_node_ext_set_text(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval); static njs_int_t njs_xml_node_ext_tags(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval); + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval); static njs_int_t njs_xml_node_ext_text(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval); + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval); static njs_int_t njs_xml_node_attr_handler(njs_vm_t *vm, xmlNode *current, njs_str_t *name, njs_value_t *setval, njs_value_t *retval); @@ -505,8 +512,8 @@ njs_xml_doc_ext_prop_keys(njs_vm_t *vm, njs_value_t *value, njs_value_t *keys) static njs_int_t -njs_xml_doc_ext_root(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, - njs_value_t *unused, njs_value_t *retval) +njs_xml_doc_ext_root(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t atom_id, + njs_value_t *value, njs_value_t *unused, njs_value_t *retval) { xmlNode *node; njs_int_t ret; @@ -523,7 +530,7 @@ njs_xml_doc_ext_root(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, any = njs_vm_prop_magic32(prop); if (!any) { - ret = njs_vm_prop_name(vm, prop, &name); + ret = njs_vm_prop_name(vm, atom_id, &name); if (njs_slow_path(ret != NJS_OK)) { njs_value_undefined_set(retval); return NJS_DECLINED; @@ -656,7 +663,8 @@ njs_xml_node_ext_prop_keys(njs_vm_t *vm, njs_value_t *value, njs_value_t *keys) static njs_int_t njs_xml_node_ext_prop_handler(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t atom_id, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { xmlNode *current; njs_int_t ret; @@ -675,7 +683,7 @@ njs_xml_node_ext_prop_handler(njs_vm_t *vm, njs_object_prop_t *prop, return NJS_DECLINED; } - ret = njs_vm_prop_name(vm, prop, &name); + ret = njs_vm_prop_name(vm, atom_id, &name); if (njs_slow_path(ret != NJS_OK)) { njs_value_undefined_set(retval); return NJS_DECLINED; @@ -773,7 +781,7 @@ error: static njs_int_t -njs_xml_node_ext_attrs(njs_vm_t *vm, njs_object_prop_t *prop, +njs_xml_node_ext_attrs(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { xmlNode *current; @@ -790,8 +798,8 @@ njs_xml_node_ext_attrs(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t -njs_xml_node_ext_name(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, - njs_value_t *setval, njs_value_t *retval) +njs_xml_node_ext_name(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, + njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { xmlNode *current; @@ -807,7 +815,7 @@ njs_xml_node_ext_name(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, static njs_int_t -njs_xml_node_ext_ns(njs_vm_t *vm, njs_object_prop_t *prop, +njs_xml_node_ext_ns(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { xmlNode *current; @@ -824,7 +832,7 @@ njs_xml_node_ext_ns(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t -njs_xml_node_ext_parent(njs_vm_t *vm, njs_object_prop_t *prop, +njs_xml_node_ext_parent(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { xmlNode *current; @@ -853,7 +861,8 @@ njs_xml_node_ext_remove_attribute(njs_vm_t *vm, njs_value_t *args, static njs_int_t njs_xml_node_ext_remove_all_attributes(njs_vm_t *vm, - njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval) + njs_value_t *args, njs_uint_t nargs, njs_index_t unused, + njs_value_t *retval) { xmlNode *current; @@ -898,7 +907,7 @@ njs_xml_node_ext_remove_children(njs_vm_t *vm, njs_value_t *args, return NJS_ERROR; } - njs_value_string_get(selector, &name); + njs_value_string_get(vm, selector, &name); return njs_xml_node_tag_remove(vm, current, &name); } @@ -924,7 +933,7 @@ static njs_int_t njs_xml_node_ext_remove_text(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval) { - return njs_xml_node_ext_text(vm, NULL, njs_argument(args, 0), NULL, NULL); + return njs_xml_node_ext_text(vm, NULL, 0, njs_argument(args, 0), NULL, NULL); } @@ -949,7 +958,7 @@ njs_xml_node_ext_set_attribute(njs_vm_t *vm, njs_value_t *args, return NJS_ERROR; } - njs_value_string_get(name, &str); + njs_value_string_get(vm, name, &str); return njs_xml_node_attr_handler(vm, current, &str, njs_arg(args, nargs, 2), !remove ? retval : NULL); @@ -960,14 +969,14 @@ static njs_int_t njs_xml_node_ext_set_text(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval) { - return njs_xml_node_ext_text(vm, NULL, njs_argument(args, 0), + return njs_xml_node_ext_text(vm, NULL, 0, njs_argument(args, 0), njs_arg(args, nargs, 1), retval); } static njs_int_t -njs_xml_node_ext_tags(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, - njs_value_t *setval, njs_value_t *retval) +njs_xml_node_ext_tags(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, + njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { xmlNode *current; njs_str_t name; @@ -986,7 +995,7 @@ njs_xml_node_ext_tags(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, static njs_int_t -njs_xml_node_ext_text(njs_vm_t *vm, njs_object_prop_t *unused, +njs_xml_node_ext_text(njs_vm_t *vm, njs_object_prop_t *unused, uint32_t unused1, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { u_char *text; @@ -1022,7 +1031,7 @@ njs_xml_node_ext_text(njs_vm_t *vm, njs_object_prop_t *unused, return NJS_ERROR; } - njs_value_string_get(setval, &content); + njs_value_string_get(vm, setval, &content); ret = njs_xml_encode_special_chars(vm, &content, &enc); if (njs_slow_path(ret != NJS_OK)) { @@ -1875,7 +1884,8 @@ njs_xml_attr_ext_prop_keys(njs_vm_t *vm, njs_value_t *value, njs_value_t *keys) static njs_int_t njs_xml_attr_ext_prop_handler(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *unused, njs_value_t *retval) + uint32_t atom_id, njs_value_t *value, njs_value_t *unused, + njs_value_t *retval) { size_t size; xmlAttr *node, *current; @@ -1888,7 +1898,7 @@ njs_xml_attr_ext_prop_handler(njs_vm_t *vm, njs_object_prop_t *prop, return NJS_DECLINED; } - ret = njs_vm_prop_name(vm, prop, &name); + ret = njs_vm_prop_name(vm, atom_id, &name); if (njs_slow_path(ret != NJS_OK)) { njs_value_undefined_set(retval); return NJS_DECLINED; diff --git a/external/njs_zlib_module.c b/external/njs_zlib_module.c index d3a667d8..46202fb9 100644 --- a/external/njs_zlib_module.c +++ b/external/njs_zlib_module.c @@ -15,7 +15,8 @@ static njs_int_t njs_zlib_ext_deflate(njs_vm_t *vm, njs_value_t *args, static njs_int_t njs_zlib_ext_inflate(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval); njs_int_t njs_zlib_constant(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval); + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval); static njs_int_t njs_zlib_init(njs_vm_t *vm); static void *njs_zlib_alloc(void *opaque, u_int items, u_int size); static void njs_zlib_free(void *opaque, void *address); @@ -520,7 +521,7 @@ fail: njs_int_t -njs_zlib_constant(njs_vm_t *vm, njs_object_prop_t *prop, +njs_zlib_constant(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { njs_value_number_set(retval, njs_vm_prop_magic32(prop)); diff --git a/nginx/ngx_http_js_module.c b/nginx/ngx_http_js_module.c index ce4ce365..3ac95478 100644 --- a/nginx/ngx_http_js_module.c +++ b/nginx/ngx_http_js_module.c @@ -129,11 +129,11 @@ static ngx_table_elt_t *ngx_http_js_get_header(ngx_list_part_t *part, u_char *data, size_t len); #endif static njs_int_t ngx_http_js_ext_raw_header(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static njs_int_t ngx_http_js_ext_header_out(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t atom_id, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); #if defined(nginx_version) && (nginx_version < 1023000) static njs_int_t ngx_http_js_header_single(njs_vm_t *vm, ngx_http_request_t *r, ngx_list_t *headers, njs_str_t *name, @@ -172,7 +172,8 @@ static njs_int_t ngx_http_js_server122(njs_vm_t *vm, ngx_http_request_t *r, static njs_int_t ngx_http_js_ext_keys_header_out(njs_vm_t *vm, njs_value_t *value, njs_value_t *keys); static njs_int_t ngx_http_js_ext_status(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval); + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval); static njs_int_t ngx_http_js_ext_send_header(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval); static njs_int_t ngx_http_js_ext_send(njs_vm_t *vm, njs_value_t *args, @@ -193,23 +194,23 @@ static njs_int_t ngx_http_js_ext_internal_redirect(njs_vm_t *vm, njs_value_t *retval); static njs_int_t ngx_http_js_ext_get_http_version(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static njs_int_t ngx_http_js_ext_internal(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static njs_int_t ngx_http_js_ext_get_remote_address(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static njs_int_t ngx_http_js_ext_get_args(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static njs_int_t ngx_http_js_ext_get_request_body(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static njs_int_t ngx_http_js_ext_header_in(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t atom_id, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); #if defined(nginx_version) && (nginx_version < 1023000) static njs_int_t ngx_http_js_header_cookie(njs_vm_t *vm, ngx_http_request_t *r, ngx_list_t *headers, njs_str_t *name, @@ -225,21 +226,21 @@ static njs_int_t ngx_http_js_header_in_array(njs_vm_t *vm, static njs_int_t ngx_http_js_ext_keys_header_in(njs_vm_t *vm, njs_value_t *value, njs_value_t *keys); static njs_int_t ngx_http_js_ext_variables(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t atom_id, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static njs_int_t ngx_http_js_periodic_session_variables(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t atom_id, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static njs_int_t ngx_http_js_ext_subrequest(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval); static ngx_int_t ngx_http_js_subrequest_done(ngx_http_request_t *r, void *data, ngx_int_t rc); static njs_int_t ngx_http_js_ext_get_parent(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static njs_int_t ngx_http_js_ext_get_response_body(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); #if defined(nginx_version) && (nginx_version >= 1023000) static njs_int_t ngx_http_js_header_in(njs_vm_t *vm, ngx_http_request_t *r, @@ -1705,7 +1706,7 @@ ngx_http_js_ext_keys_header(njs_vm_t *vm, njs_value_t *value, njs_value_t *keys, start = njs_vm_array_start(vm, keys); for (i = 0; i < length; i++) { - njs_value_string_get(njs_argument(start, i), &hdr); + njs_value_string_get(vm, njs_argument(start, i), &hdr); if (h->key.len == hdr.length && ngx_strncasecmp(h->key.data, hdr.start, hdr.length) == 0) @@ -1772,7 +1773,8 @@ ngx_http_js_get_header(ngx_list_part_t *part, u_char *data, size_t len) static njs_int_t ngx_http_js_ext_raw_header(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { njs_int_t rc; ngx_uint_t i; @@ -1854,7 +1856,8 @@ ngx_http_js_ext_raw_header(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t ngx_http_js_ext_header_out(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t atom_id, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { njs_int_t rc; njs_str_t name; @@ -1910,7 +1913,7 @@ ngx_http_js_ext_header_out(njs_vm_t *vm, njs_object_prop_t *prop, return NJS_DECLINED; } - rc = njs_vm_prop_name(vm, prop, &name); + rc = njs_vm_prop_name(vm, atom_id, &name); if (rc != NJS_OK) { if (retval != NULL) { njs_value_undefined_set(retval); @@ -2395,7 +2398,7 @@ ngx_http_js_ext_keys_header_out(njs_vm_t *vm, njs_value_t *value, static njs_int_t -ngx_http_js_ext_status(njs_vm_t *vm, njs_object_prop_t *prop, +ngx_http_js_ext_status(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { ngx_int_t n; @@ -2792,7 +2795,8 @@ ngx_http_js_ext_internal_redirect(njs_vm_t *vm, njs_value_t *args, static njs_int_t ngx_http_js_ext_get_http_version(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { ngx_str_t v; ngx_http_request_t *r; @@ -2837,7 +2841,7 @@ ngx_http_js_ext_get_http_version(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t -ngx_http_js_ext_internal(njs_vm_t *vm, njs_object_prop_t *prop, +ngx_http_js_ext_internal(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { ngx_http_request_t *r; @@ -2856,7 +2860,8 @@ ngx_http_js_ext_internal(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t ngx_http_js_ext_get_remote_address(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { ngx_connection_t *c; ngx_http_request_t *r; @@ -2875,7 +2880,7 @@ ngx_http_js_ext_get_remote_address(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t -ngx_http_js_ext_get_args(njs_vm_t *vm, njs_object_prop_t *prop, +ngx_http_js_ext_get_args(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { u_char *data; @@ -2911,7 +2916,8 @@ ngx_http_js_ext_get_args(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t ngx_http_js_ext_get_request_body(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { u_char *p, *body; size_t len; @@ -3021,7 +3027,7 @@ done: #if defined(nginx_version) && (nginx_version < 1023000) static njs_int_t -ngx_http_js_ext_header_in(njs_vm_t *vm, njs_object_prop_t *prop, +ngx_http_js_ext_header_in(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t atom_id, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { njs_int_t rc; @@ -3055,7 +3061,7 @@ ngx_http_js_ext_header_in(njs_vm_t *vm, njs_object_prop_t *prop, return NJS_DECLINED; } - rc = njs_vm_prop_name(vm, prop, &name); + rc = njs_vm_prop_name(vm, atom_id, &name); if (rc != NJS_OK) { if (retval != NULL) { njs_value_undefined_set(retval); @@ -3136,7 +3142,7 @@ ngx_http_js_header_in_array(njs_vm_t *vm, ngx_http_request_t *r, } #else static njs_int_t -ngx_http_js_ext_header_in(njs_vm_t *vm, njs_object_prop_t *prop, +ngx_http_js_ext_header_in(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t atom_id, njs_value_t *value, njs_value_t *unused, njs_value_t *retval) { unsigned flags; @@ -3164,7 +3170,7 @@ ngx_http_js_ext_header_in(njs_vm_t *vm, njs_object_prop_t *prop, return NJS_DECLINED; } - rc = njs_vm_prop_name(vm, prop, &name); + rc = njs_vm_prop_name(vm, atom_id, &name); if (rc != NJS_OK) { if (retval != NULL) { njs_value_undefined_set(retval); @@ -3212,7 +3218,8 @@ ngx_http_js_ext_keys_header_in(njs_vm_t *vm, njs_value_t *value, static njs_int_t ngx_http_js_request_variables(njs_vm_t *vm, njs_object_prop_t *prop, - ngx_http_request_t *r, njs_value_t *setval, njs_value_t *retval) + uint32_t atom_id, ngx_http_request_t *r, njs_value_t *setval, + njs_value_t *retval) { njs_int_t rc, is_capture, start, length; njs_str_t val, s; @@ -3223,7 +3230,7 @@ ngx_http_js_request_variables(njs_vm_t *vm, njs_object_prop_t *prop, ngx_http_variable_value_t *vv; u_char storage[64]; - rc = njs_vm_prop_name(vm, prop, &val); + rc = njs_vm_prop_name(vm, atom_id, &val); if (rc != NJS_OK) { njs_value_undefined_set(retval); return NJS_DECLINED; @@ -3350,7 +3357,8 @@ ngx_http_js_request_variables(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t ngx_http_js_ext_variables(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t atom_id, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { ngx_http_request_t *r; @@ -3360,13 +3368,14 @@ ngx_http_js_ext_variables(njs_vm_t *vm, njs_object_prop_t *prop, return NJS_DECLINED; } - return ngx_http_js_request_variables(vm, prop, r, setval, retval); + return ngx_http_js_request_variables(vm, prop, atom_id, r, setval, retval); } static njs_int_t ngx_http_js_periodic_session_variables(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t atom_id, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { ngx_http_request_t *r; @@ -3376,7 +3385,7 @@ ngx_http_js_periodic_session_variables(njs_vm_t *vm, njs_object_prop_t *prop, return NJS_DECLINED; } - return ngx_http_js_request_variables(vm, prop, r, setval, retval); + return ngx_http_js_request_variables(vm, prop, atom_id, r, setval, retval); } @@ -3708,7 +3717,8 @@ ngx_http_js_subrequest_done(ngx_http_request_t *r, void *data, ngx_int_t rc) static njs_int_t ngx_http_js_ext_get_parent(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { ngx_http_js_ctx_t *ctx; ngx_http_request_t *r; @@ -3735,7 +3745,8 @@ ngx_http_js_ext_get_parent(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t ngx_http_js_ext_get_response_body(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { size_t len; u_char *p; diff --git a/nginx/ngx_js.c b/nginx/ngx_js.c index 316a2076..f91fcd99 100644 --- a/nginx/ngx_js.c +++ b/nginx/ngx_js.c @@ -108,21 +108,26 @@ static JSModuleDef *ngx_qjs_core_init(JSContext *cx, const char *name); #endif static njs_int_t ngx_js_ext_build(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval); -static njs_int_t ngx_js_ext_conf_file_path(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, + uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval); +static njs_int_t ngx_js_ext_conf_file_path(njs_vm_t *vm, + njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static njs_int_t ngx_js_ext_conf_prefix(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval); -static njs_int_t ngx_js_ext_error_log_path(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, + uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval); +static njs_int_t ngx_js_ext_error_log_path(njs_vm_t *vm, + njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static njs_int_t ngx_js_ext_prefix(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval); + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval); static njs_int_t ngx_js_ext_version(njs_vm_t *vm, njs_object_prop_t *prop, + uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval); static njs_int_t ngx_js_ext_worker_id(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval); + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval); static njs_int_t ngx_js_ext_console_time(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval); static njs_int_t ngx_js_ext_console_time_end(njs_vm_t *vm, njs_value_t *args, @@ -2403,8 +2408,8 @@ ngx_js_core_init(njs_vm_t *vm) njs_int_t -ngx_js_ext_string(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, - njs_value_t *setval, njs_value_t *retval) +ngx_js_ext_string(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, + njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { char *p; ngx_str_t *field; @@ -2422,8 +2427,8 @@ ngx_js_ext_string(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, njs_int_t -ngx_js_ext_uint(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, - njs_value_t *setval, njs_value_t *retval) +ngx_js_ext_uint(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, + njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { char *p; ngx_uint_t field; @@ -2443,7 +2448,7 @@ ngx_js_ext_uint(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, njs_int_t -ngx_js_ext_constant(njs_vm_t *vm, njs_object_prop_t *prop, +ngx_js_ext_constant(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { uint32_t magic32; @@ -2466,7 +2471,7 @@ ngx_js_ext_constant(njs_vm_t *vm, njs_object_prop_t *prop, njs_int_t -ngx_js_ext_flags(njs_vm_t *vm, njs_object_prop_t *prop, +ngx_js_ext_flags(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { uintptr_t data; @@ -2491,8 +2496,8 @@ ngx_js_ext_flags(njs_vm_t *vm, njs_object_prop_t *prop, njs_int_t -ngx_js_ext_build(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, - njs_value_t *setval, njs_value_t *retval) +ngx_js_ext_build(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, + njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { return njs_vm_value_string_create(vm, retval, #ifdef NGX_BUILD @@ -2508,7 +2513,8 @@ ngx_js_ext_build(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, njs_int_t ngx_js_ext_conf_file_path(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { return njs_vm_value_string_create(vm, retval, ngx_cycle->conf_file.data, ngx_cycle->conf_file.len); @@ -2516,7 +2522,7 @@ ngx_js_ext_conf_file_path(njs_vm_t *vm, njs_object_prop_t *prop, njs_int_t -ngx_js_ext_conf_prefix(njs_vm_t *vm, njs_object_prop_t *prop, +ngx_js_ext_conf_prefix(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { return njs_vm_value_string_create(vm, retval, ngx_cycle->conf_prefix.data, @@ -2525,7 +2531,7 @@ ngx_js_ext_conf_prefix(njs_vm_t *vm, njs_object_prop_t *prop, njs_int_t -ngx_js_ext_error_log_path(njs_vm_t *vm, njs_object_prop_t *prop, +ngx_js_ext_error_log_path(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { return njs_vm_value_string_create(vm, retval, ngx_cycle->error_log.data, @@ -2534,7 +2540,7 @@ ngx_js_ext_error_log_path(njs_vm_t *vm, njs_object_prop_t *prop, njs_int_t -ngx_js_ext_prefix(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, +ngx_js_ext_prefix(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { return njs_vm_value_string_create(vm, retval, ngx_cycle->prefix.data, @@ -2543,8 +2549,8 @@ ngx_js_ext_prefix(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, njs_int_t -ngx_js_ext_version(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, - njs_value_t *setval, njs_value_t *retval) +ngx_js_ext_version(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, + njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { return njs_vm_value_string_create(vm, retval, (u_char *) NGINX_VERSION, njs_strlen(NGINX_VERSION)); @@ -2552,8 +2558,8 @@ ngx_js_ext_version(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, njs_int_t -ngx_js_ext_worker_id(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, - njs_value_t *setval, njs_value_t *retval) +ngx_js_ext_worker_id(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, + njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { njs_value_number_set(retval, ngx_worker); return NJS_OK; @@ -2640,11 +2646,11 @@ ngx_js_ext_console_time(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return ret; } - njs_value_string_get(value, &name); + njs_value_string_get(vm, value, &name); } } else { - njs_value_string_get(value, &name); + njs_value_string_get(vm, value, &name); } console = njs_value_external(this); @@ -2733,11 +2739,11 @@ ngx_js_ext_console_time_end(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return ret; } - njs_value_string_get(value, &name); + njs_value_string_get(vm, value, &name); } } else { - njs_value_string_get(value, &name); + njs_value_string_get(vm, value, &name); } console = njs_value_external(this); diff --git a/nginx/ngx_js.h b/nginx/ngx_js.h index 0a99a696..0e811f44 100644 --- a/nginx/ngx_js.h +++ b/nginx/ngx_js.h @@ -405,13 +405,13 @@ char * ngx_js_merge_conf(ngx_conf_t *cf, void *parent, void *child, char *ngx_js_shared_dict_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf, void *tag); -njs_int_t ngx_js_ext_string(njs_vm_t *vm, njs_object_prop_t *prop, +njs_int_t ngx_js_ext_string(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval); -njs_int_t ngx_js_ext_uint(njs_vm_t *vm, njs_object_prop_t *prop, +njs_int_t ngx_js_ext_uint(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval); -njs_int_t ngx_js_ext_constant(njs_vm_t *vm, njs_object_prop_t *prop, +njs_int_t ngx_js_ext_constant(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval); -njs_int_t ngx_js_ext_flags(njs_vm_t *vm, njs_object_prop_t *prop, +njs_int_t ngx_js_ext_flags(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval); ngx_int_t ngx_js_string(njs_vm_t *vm, njs_value_t *value, njs_str_t *str); diff --git a/nginx/ngx_js_fetch.c b/nginx/ngx_js_fetch.c index 63e7a298..4902fe4f 100644 --- a/nginx/ngx_js_fetch.c +++ b/nginx/ngx_js_fetch.c @@ -210,8 +210,8 @@ static njs_int_t ngx_headers_js_ext_get(njs_vm_t *vm, njs_value_t *args, static njs_int_t ngx_headers_js_ext_has(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval); static njs_int_t ngx_headers_js_ext_prop(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t atom_id, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static njs_int_t ngx_headers_js_ext_keys(njs_vm_t *vm, njs_value_t *value, njs_value_t *keys); static njs_int_t ngx_headers_js_ext_set(njs_vm_t *vm, njs_value_t *args, @@ -219,37 +219,38 @@ static njs_int_t ngx_headers_js_ext_set(njs_vm_t *vm, njs_value_t *args, static njs_int_t ngx_request_js_ext_body(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval); static njs_int_t ngx_request_js_ext_body_used(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static njs_int_t ngx_request_js_ext_cache(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static njs_int_t ngx_request_js_ext_credentials(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static njs_int_t ngx_request_js_ext_headers(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static njs_int_t ngx_request_js_ext_mode(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval); -static njs_int_t ngx_response_js_ext_status(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, + uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval); +static njs_int_t ngx_response_js_ext_status(njs_vm_t *vm, + njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static njs_int_t ngx_response_js_ext_status_text(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static njs_int_t ngx_response_js_ext_ok(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static njs_int_t ngx_response_js_ext_body_used(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static njs_int_t ngx_response_js_ext_headers(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static njs_int_t ngx_response_js_ext_type(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static njs_int_t ngx_response_js_ext_body(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval); @@ -3523,13 +3524,13 @@ ngx_headers_js_ext_has(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, static njs_int_t -ngx_headers_js_ext_prop(njs_vm_t *vm, njs_object_prop_t *prop, +ngx_headers_js_ext_prop(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t atom_id, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { njs_int_t ret; njs_str_t name; - ret = njs_vm_prop_name(vm, prop, &name); + ret = njs_vm_prop_name(vm, atom_id, &name); if (ret != NJS_OK) { return NJS_ERROR; } @@ -3539,9 +3540,40 @@ ngx_headers_js_ext_prop(njs_vm_t *vm, njs_object_prop_t *prop, static ngx_int_t -ngx_string_compare(const void *s1, const void *s2) +ngx_string_compare(const void *s1, const void *s2, void *ctx) { - return njs_vm_string_compare(s1, s2); + return njs_vm_string_compare(ctx, s1, s2); +} + + +static void +ngx_js_sort(void *base, size_t n, size_t size, + ngx_int_t (*cmp)(const void *, const void *, void *), void *ctx) +{ + u_char *p1, *p2, *p; + + p = ngx_alloc(size, ngx_cycle->log); + if (p == NULL) { + return; + } + + for (p1 = (u_char *) base + size; + p1 < (u_char *) base + n * size; + p1 += size) + { + ngx_memcpy(p, p1, size); + + for (p2 = p1; + p2 > (u_char *) base && cmp(p2 - size, p, ctx) > 0; + p2 -= size) + { + ngx_memcpy(p2, p2 - size, size); + } + + ngx_memcpy(p2, p, size); + } + + ngx_free(p); } @@ -3591,7 +3623,7 @@ ngx_headers_js_ext_keys(njs_vm_t *vm, njs_value_t *value, njs_value_t *keys) start = njs_vm_array_start(vm, keys); for (k = 0; k < length; k++) { - njs_value_string_get(njs_argument(start, k), &hdr); + njs_value_string_get(vm, njs_argument(start, k), &hdr); if (h[i].key.len == hdr.length && njs_strncasecmp(h[i].key.data, hdr.start, hdr.length) == 0) @@ -3618,8 +3650,8 @@ ngx_headers_js_ext_keys(njs_vm_t *vm, njs_value_t *value, njs_value_t *keys) start = njs_vm_array_start(vm, keys); - ngx_sort(start, (size_t) length, sizeof(njs_opaque_value_t), - ngx_string_compare); + ngx_js_sort(start, (size_t) length, sizeof(njs_opaque_value_t), + ngx_string_compare, vm); return NJS_OK; } @@ -3762,7 +3794,8 @@ ngx_request_js_ext_body(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, static njs_int_t ngx_request_js_ext_body_used(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { ngx_js_request_t *request; @@ -3779,7 +3812,7 @@ ngx_request_js_ext_body_used(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t -ngx_request_js_ext_cache(njs_vm_t *vm, njs_object_prop_t *prop, +ngx_request_js_ext_cache(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { ngx_js_request_t *request; @@ -3797,7 +3830,8 @@ ngx_request_js_ext_cache(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t ngx_request_js_ext_credentials(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { ngx_js_request_t *request; @@ -3814,7 +3848,8 @@ ngx_request_js_ext_credentials(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t ngx_request_js_ext_headers(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { njs_int_t ret; ngx_js_request_t *request; @@ -3842,7 +3877,7 @@ ngx_request_js_ext_headers(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t -ngx_request_js_ext_mode(njs_vm_t *vm, njs_object_prop_t *prop, +ngx_request_js_ext_mode(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { ngx_js_request_t *request; @@ -3921,7 +3956,8 @@ ngx_response_js_ext_body(njs_vm_t *vm, njs_value_t *args, static njs_int_t ngx_response_js_ext_body_used(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { ngx_js_response_t *response; @@ -3939,7 +3975,8 @@ ngx_response_js_ext_body_used(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t ngx_response_js_ext_headers(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { njs_int_t ret; ngx_js_response_t *response; @@ -3967,7 +4004,7 @@ ngx_response_js_ext_headers(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t -ngx_response_js_ext_ok(njs_vm_t *vm, njs_object_prop_t *prop, +ngx_response_js_ext_ok(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { ngx_uint_t code; @@ -3989,7 +4026,8 @@ ngx_response_js_ext_ok(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t ngx_response_js_ext_status(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { ngx_js_response_t *response; @@ -4007,7 +4045,8 @@ ngx_response_js_ext_status(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t ngx_response_js_ext_status_text(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { ngx_js_response_t *response; @@ -4025,7 +4064,7 @@ ngx_response_js_ext_status_text(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t -ngx_response_js_ext_type(njs_vm_t *vm, njs_object_prop_t *prop, +ngx_response_js_ext_type(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { ngx_js_response_t *response; diff --git a/nginx/ngx_js_shared_dict.c b/nginx/ngx_js_shared_dict.c index c0928088..ccca530d 100644 --- a/nginx/ngx_js_shared_dict.c +++ b/nginx/ngx_js_shared_dict.c @@ -47,8 +47,8 @@ struct ngx_js_dict_s { static njs_int_t njs_js_ext_shared_dict_capacity(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static njs_int_t njs_js_ext_shared_dict_clear(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t flags, njs_value_t *retval); static njs_int_t njs_js_ext_shared_dict_delete(njs_vm_t *vm, njs_value_t *args, @@ -67,8 +67,8 @@ static njs_int_t njs_js_ext_shared_dict_incr(njs_vm_t *vm, njs_value_t *args, static njs_int_t njs_js_ext_shared_dict_items(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval); static njs_int_t njs_js_ext_shared_dict_name(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static njs_int_t njs_js_ext_shared_dict_pop(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval); static njs_int_t njs_js_ext_shared_dict_set(njs_vm_t *vm, njs_value_t *args, @@ -76,8 +76,8 @@ static njs_int_t njs_js_ext_shared_dict_set(njs_vm_t *vm, njs_value_t *args, static njs_int_t njs_js_ext_shared_dict_size(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval); static njs_int_t njs_js_ext_shared_dict_type(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static ngx_js_dict_node_t *ngx_js_dict_lookup(ngx_js_dict_t *dict, njs_str_t *key); @@ -86,15 +86,16 @@ static ngx_js_dict_node_t *ngx_js_dict_lookup(ngx_js_dict_t *dict, static ngx_int_t ngx_js_dict_set(njs_vm_t *vm, ngx_js_dict_t *dict, njs_str_t *key, njs_value_t *value, ngx_msec_t timeout, unsigned flags); -static ngx_int_t ngx_js_dict_add(ngx_js_dict_t *dict, njs_str_t *key, - njs_value_t *value, ngx_msec_t timeout, ngx_msec_t now); -static ngx_int_t ngx_js_dict_update(ngx_js_dict_t *dict, +static ngx_int_t ngx_js_dict_add(njs_vm_t *vm, ngx_js_dict_t *dict, + njs_str_t *key, njs_value_t *value, ngx_msec_t timeout, ngx_msec_t now); +static ngx_int_t ngx_js_dict_update(njs_vm_t *vm, ngx_js_dict_t *dict, ngx_js_dict_node_t *node, njs_value_t *value, ngx_msec_t timeout, ngx_msec_t now); static ngx_int_t ngx_js_dict_get(njs_vm_t *vm, ngx_js_dict_t *dict, njs_str_t *key, njs_value_t *retval); -static ngx_int_t ngx_js_dict_incr(ngx_js_dict_t *dict, njs_str_t *key, - njs_value_t *delta, njs_value_t *init, double *value, ngx_msec_t timeout); +static ngx_int_t ngx_js_dict_incr(njs_vm_t *vm, ngx_js_dict_t *dict, + njs_str_t *key, njs_value_t *delta, njs_value_t *init, double *value, + ngx_msec_t timeout); static ngx_int_t ngx_js_dict_delete(njs_vm_t *vm, ngx_js_dict_t *dict, njs_str_t *key, njs_value_t *retval); static ngx_int_t ngx_js_dict_copy_value_locked(njs_vm_t *vm, @@ -104,8 +105,8 @@ static void ngx_js_dict_expire(ngx_js_dict_t *dict, ngx_msec_t now); static void ngx_js_dict_evict(ngx_js_dict_t *dict, ngx_int_t count); static njs_int_t ngx_js_dict_shared_error_name(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static ngx_int_t ngx_js_dict_init_zone(ngx_shm_zone_t *shm_zone, void *data); static njs_int_t ngx_js_shared_dict_preinit(njs_vm_t *vm); @@ -480,7 +481,8 @@ qjs_module_t ngx_qjs_ngx_shared_dict_module = { njs_int_t njs_js_ext_global_shared_prop(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t atom_id, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { njs_int_t ret; njs_str_t name; @@ -488,7 +490,7 @@ njs_js_ext_global_shared_prop(njs_vm_t *vm, njs_object_prop_t *prop, ngx_shm_zone_t *shm_zone; ngx_js_main_conf_t *conf; - ret = njs_vm_prop_name(vm, prop, &name); + ret = njs_vm_prop_name(vm, atom_id, &name); if (ret != NJS_OK) { return NJS_ERROR; } @@ -559,7 +561,8 @@ njs_js_ext_global_shared_keys(njs_vm_t *vm, njs_value_t *unused, static njs_int_t njs_js_ext_shared_dict_capacity(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { ngx_shm_zone_t *shm_zone; @@ -912,7 +915,8 @@ njs_js_ext_shared_dict_incr(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, timeout = dict->timeout; } - rc = ngx_js_dict_incr(shm_zone->data, &key, delta, init, &value, timeout); + rc = ngx_js_dict_incr(vm, shm_zone->data, &key, delta, init, &value, + timeout); if (rc == NGX_ERROR) { njs_vm_error(vm, "failed to increment value in shared dict"); return NJS_ERROR; @@ -1033,7 +1037,8 @@ fail: static njs_int_t njs_js_ext_shared_dict_name(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { ngx_shm_zone_t *shm_zone; @@ -1210,7 +1215,8 @@ njs_js_ext_shared_dict_size(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, static njs_int_t njs_js_ext_shared_dict_type(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { njs_str_t type; ngx_js_dict_t *dict; @@ -1308,7 +1314,7 @@ ngx_js_dict_set(njs_vm_t *vm, ngx_js_dict_t *dict, njs_str_t *key, return NGX_DECLINED; } - if (ngx_js_dict_add(dict, key, value, timeout, now) != NGX_OK) { + if (ngx_js_dict_add(vm, dict, key, value, timeout, now) != NGX_OK) { goto memory_error; } @@ -1320,7 +1326,7 @@ ngx_js_dict_set(njs_vm_t *vm, ngx_js_dict_t *dict, njs_str_t *key, } } - if (ngx_js_dict_update(dict, node, value, timeout, now) != NGX_OK) { + if (ngx_js_dict_update(vm, dict, node, value, timeout, now) != NGX_OK) { goto memory_error; } } @@ -1340,8 +1346,8 @@ memory_error: static ngx_int_t -ngx_js_dict_add(ngx_js_dict_t *dict, njs_str_t *key, njs_value_t *value, - ngx_msec_t timeout, ngx_msec_t now) +ngx_js_dict_add(njs_vm_t *vm, ngx_js_dict_t *dict, njs_str_t *key, + njs_value_t *value, ngx_msec_t timeout, ngx_msec_t now) { size_t n; uint32_t hash; @@ -1363,7 +1369,7 @@ ngx_js_dict_add(ngx_js_dict_t *dict, njs_str_t *key, njs_value_t *value, node->sn.str.data = (u_char *) node + sizeof(ngx_js_dict_node_t); if (dict->type == NGX_JS_DICT_TYPE_STRING) { - njs_value_string_get(value, &string); + njs_value_string_get(vm, value, &string); node->u.value.data = ngx_js_dict_alloc(dict, string.length); if (node->u.value.data == NULL) { ngx_slab_free_locked(dict->shpool, node); @@ -1394,14 +1400,14 @@ ngx_js_dict_add(ngx_js_dict_t *dict, njs_str_t *key, njs_value_t *value, static ngx_int_t -ngx_js_dict_update(ngx_js_dict_t *dict, ngx_js_dict_node_t *node, +ngx_js_dict_update(njs_vm_t *vm, ngx_js_dict_t *dict, ngx_js_dict_node_t *node, njs_value_t *value, ngx_msec_t timeout, ngx_msec_t now) { u_char *p; njs_str_t string; if (dict->type == NGX_JS_DICT_TYPE_STRING) { - njs_value_string_get(value, &string); + njs_value_string_get(vm, value, &string); p = ngx_js_dict_alloc(dict, string.length); if (p == NULL) { @@ -1476,8 +1482,8 @@ ngx_js_dict_delete(njs_vm_t *vm, ngx_js_dict_t *dict, njs_str_t *key, static ngx_int_t -ngx_js_dict_incr(ngx_js_dict_t *dict, njs_str_t *key, njs_value_t *delta, - njs_value_t *init, double *value, ngx_msec_t timeout) +ngx_js_dict_incr(njs_vm_t *vm, ngx_js_dict_t *dict, njs_str_t *key, + njs_value_t *delta, njs_value_t *init, double *value, ngx_msec_t timeout) { ngx_msec_t now; ngx_time_t *tp; @@ -1493,7 +1499,7 @@ ngx_js_dict_incr(ngx_js_dict_t *dict, njs_str_t *key, njs_value_t *delta, if (node == NULL) { njs_value_number_set(init, njs_value_number(init) + njs_value_number(delta)); - if (ngx_js_dict_add(dict, key, init, timeout, now) != NGX_OK) { + if (ngx_js_dict_add(vm, dict, key, init, timeout, now) != NGX_OK) { ngx_rwlock_unlock(&dict->sh->rwlock); return NGX_ERROR; } @@ -1653,7 +1659,8 @@ ngx_js_dict_evict(ngx_js_dict_t *dict, ngx_int_t count) static njs_int_t ngx_js_dict_shared_error_name(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { return njs_vm_value_string_create(vm, retval, (u_char *) "SharedMemoryError", 17); diff --git a/nginx/ngx_js_shared_dict.h b/nginx/ngx_js_shared_dict.h index ed1f4de7..b9c7f967 100644 --- a/nginx/ngx_js_shared_dict.h +++ b/nginx/ngx_js_shared_dict.h @@ -9,7 +9,8 @@ #define _NGX_JS_SHARED_DICT_H_INCLUDED_ njs_int_t njs_js_ext_global_shared_prop(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval); + uint32_t atom_id, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval); njs_int_t njs_js_ext_global_shared_keys(njs_vm_t *vm, njs_value_t *value, njs_value_t *keys); diff --git a/nginx/ngx_stream_js_module.c b/nginx/ngx_stream_js_module.c index 7620f2e0..5c837494 100644 --- a/nginx/ngx_stream_js_module.c +++ b/nginx/ngx_stream_js_module.c @@ -120,8 +120,8 @@ static ngx_stream_js_ev_t *ngx_stream_js_event(ngx_stream_session_t *s, njs_str_t *event); static njs_int_t ngx_stream_js_ext_get_remote_address(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static njs_int_t ngx_stream_js_ext_done(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval); @@ -137,11 +137,11 @@ static njs_int_t ngx_stream_js_ext_set_return_value(njs_vm_t *vm, njs_value_t *retval); static njs_int_t ngx_stream_js_ext_variables(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t atom_id, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static njs_int_t ngx_stream_js_periodic_variables(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t atom_id, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); #if (NJS_HAVE_QUICKJS) @@ -1405,8 +1405,8 @@ ngx_stream_js_event(ngx_stream_session_t *s, njs_str_t *event) static njs_int_t ngx_stream_js_ext_get_remote_address(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval) + njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval) { ngx_connection_t *c; ngx_stream_session_t *s; @@ -1708,7 +1708,8 @@ ngx_stream_js_ext_set_return_value(njs_vm_t *vm, njs_value_t *args, static njs_int_t ngx_stream_js_session_variables(njs_vm_t *vm, njs_object_prop_t *prop, - ngx_stream_session_t *s, njs_value_t *setval, njs_value_t *retval) + uint32_t atom_id, ngx_stream_session_t *s, njs_value_t *setval, + njs_value_t *retval) { njs_int_t rc; njs_str_t val; @@ -1719,7 +1720,7 @@ ngx_stream_js_session_variables(njs_vm_t *vm, njs_object_prop_t *prop, ngx_stream_variable_value_t *vv; u_char storage[64]; - rc = njs_vm_prop_name(vm, prop, &val); + rc = njs_vm_prop_name(vm, atom_id, &val); if (rc != NJS_OK) { njs_value_undefined_set(retval); return NJS_DECLINED; @@ -1818,7 +1819,8 @@ ngx_stream_js_session_variables(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t ngx_stream_js_ext_variables(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t atom_id, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { ngx_stream_session_t *s; @@ -1828,13 +1830,14 @@ ngx_stream_js_ext_variables(njs_vm_t *vm, njs_object_prop_t *prop, return NJS_DECLINED; } - return ngx_stream_js_session_variables(vm, prop, s, setval, retval); + return ngx_stream_js_session_variables(vm, prop, atom_id, s, setval, retval); } static njs_int_t ngx_stream_js_periodic_variables(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t atom_id, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { ngx_stream_session_t *s; @@ -1844,7 +1847,7 @@ ngx_stream_js_periodic_variables(njs_vm_t *vm, njs_object_prop_t *prop, return NJS_DECLINED; } - return ngx_stream_js_session_variables(vm, prop, s, setval, retval); + return ngx_stream_js_session_variables(vm, prop, atom_id, s, setval, retval); } diff --git a/src/njs.h b/src/njs.h index 0e2855d1..0a196321 100644 --- a/src/njs.h +++ b/src/njs.h @@ -34,6 +34,7 @@ typedef struct njs_function_s njs_function_t; typedef struct njs_vm_shared_s njs_vm_shared_t; typedef struct njs_object_init_s njs_object_init_t; typedef struct njs_object_prop_s njs_object_prop_t; +typedef struct njs_object_prop_init_s njs_object_prop_init_t; typedef struct njs_object_type_init_s njs_object_type_init_t; typedef struct njs_external_s njs_external_t; @@ -43,7 +44,7 @@ typedef struct njs_external_s njs_external_t; */ typedef struct { - uint64_t filler[2]; + uint32_t filler[4]; } njs_opaque_value_t; /* sizeof(njs_value_t) is 16 bytes. */ @@ -61,6 +62,11 @@ extern const njs_value_t njs_value_undefined; memcpy(dst, src, sizeof(njs_opaque_value_t)) #define njs_value_arg(val) ((njs_value_t *) val) +#define njs_value_atom(val) (((njs_opaque_value_t *) (val))->filler[0]) + +#define njs_atom_is_number(atom_id) ((atom_id) & 0x80000000) +#define njs_atom_number(atom_id) ((atom_id) & 0x7FFFFFFF) +#define njs_number_atom(n) ((n) | 0x80000000) #define njs_lvalue_arg(lvalue, args, nargs, n) \ ((n < nargs) ? njs_argument(args, n) \ @@ -104,7 +110,8 @@ extern const njs_value_t njs_value_undefined; * the exception value. */ typedef njs_int_t (*njs_prop_handler_t) (njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval); + uint32_t atom_id, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval); typedef njs_int_t (*njs_exotic_keys_t)(njs_vm_t *vm, njs_value_t *value, njs_value_t *retval); typedef njs_int_t (*njs_function_native_t) (njs_vm_t *vm, njs_value_t *args, @@ -354,23 +361,24 @@ NJS_EXPORT njs_int_t njs_vm_external_create(njs_vm_t *vm, njs_value_t *value, NJS_EXPORT njs_external_ptr_t njs_vm_external(njs_vm_t *vm, njs_int_t proto_id, const njs_value_t *value); NJS_EXPORT njs_int_t njs_external_property(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); +NJS_EXPORT njs_int_t njs_atom_atomize_key(njs_vm_t *vm, njs_value_t *value); NJS_EXPORT njs_int_t njs_value_property(njs_vm_t *vm, njs_value_t *value, - njs_value_t *key, njs_value_t *retval); + uint32_t atom_id, njs_value_t *retval); NJS_EXPORT njs_int_t njs_value_property_set(njs_vm_t *vm, njs_value_t *value, - njs_value_t *key, njs_value_t *setval); + uint32_t atom_id, njs_value_t *setval); NJS_EXPORT uintptr_t njs_vm_meta(njs_vm_t *vm, njs_uint_t index); NJS_EXPORT njs_vm_opt_t *njs_vm_options(njs_vm_t *vm); NJS_EXPORT njs_int_t njs_error_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t type, njs_value_t *retval); NJS_EXPORT njs_int_t njs_object_prototype_create_constructor(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); NJS_EXPORT njs_int_t njs_object_prototype_create(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); NJS_EXPORT njs_function_t *njs_vm_function_alloc(njs_vm_t *vm, njs_function_native_t native, njs_bool_t shared, njs_bool_t ctor); @@ -403,12 +411,13 @@ NJS_EXPORT njs_int_t njs_value_to_integer(njs_vm_t *vm, njs_value_t *value, int64_t *dst); /* Gets string value, no copy. */ -NJS_EXPORT void njs_value_string_get(njs_value_t *value, njs_str_t *dst); +NJS_EXPORT void njs_value_string_get(njs_vm_t *vm, njs_value_t *value, + njs_str_t *dst); NJS_EXPORT njs_int_t njs_vm_value_string_create(njs_vm_t *vm, njs_value_t *value, const u_char *start, uint32_t size); NJS_EXPORT njs_int_t njs_vm_value_string_create_chb(njs_vm_t *vm, njs_value_t *value, njs_chb_t *chain); -NJS_EXPORT njs_int_t njs_vm_string_compare(const njs_value_t *v1, +NJS_EXPORT njs_int_t njs_vm_string_compare(njs_vm_t *vm, const njs_value_t *v1, const njs_value_t *v2); NJS_EXPORT njs_int_t njs_vm_value_array_buffer_set(njs_vm_t *vm, @@ -477,7 +486,7 @@ NJS_EXPORT njs_int_t njs_value_external_tag(const njs_value_t *value); NJS_EXPORT uint16_t njs_vm_prop_magic16(njs_object_prop_t *prop); NJS_EXPORT uint32_t njs_vm_prop_magic32(njs_object_prop_t *prop); -NJS_EXPORT njs_int_t njs_vm_prop_name(njs_vm_t *vm, njs_object_prop_t *prop, +NJS_EXPORT njs_int_t njs_vm_prop_name(njs_vm_t *vm, uint32_t atom_id, njs_str_t *dst); NJS_EXPORT njs_int_t njs_value_is_null(const njs_value_t *value); @@ -536,4 +545,49 @@ NJS_EXPORT njs_int_t njs_vm_promise_create(njs_vm_t *vm, njs_value_t *retval, njs_value_t *callbacks); +njs_inline njs_int_t +njs_value_property_val(njs_vm_t *vm, njs_value_t *value, njs_value_t *key, + njs_value_t *retval) +{ + njs_int_t ret; + + if (njs_value_atom(key) == 0 /* NJS_ATOM_STRING_unknown */) { + ret = njs_atom_atomize_key(vm, key); + if (ret != NJS_OK) { + return ret; + } + } + + return njs_value_property(vm, value, njs_value_atom(key), retval); +} + + +njs_inline njs_int_t +njs_value_property_val_set(njs_vm_t *vm, njs_value_t *value, njs_value_t *key, + njs_value_t *setval) +{ + njs_int_t ret; + + if (njs_value_atom(key) == 0 /* NJS_ATOM_STRING_unknown */) { + ret = njs_atom_atomize_key(vm, key); + if (ret != NJS_OK) { + return ret; + } + } + + return njs_value_property_set(vm, value, njs_value_atom(key), setval); +} + + +njs_inline size_t +njs_value_string_length(njs_vm_t *vm, njs_value_t *value) +{ + njs_str_t str; + + njs_value_string_get(vm, value, &str); + + return str.length; +} + + #endif /* _NJS_H_INCLUDED_ */ diff --git a/src/njs_array.c b/src/njs_array.c index 913bc8cf..e6f8ed83 100644 --- a/src/njs_array.c +++ b/src/njs_array.c @@ -139,7 +139,7 @@ njs_int_t njs_array_convert_to_slow_array(njs_vm_t *vm, njs_array_t *array) { uint32_t i, length; - njs_value_t index, value; + njs_value_t value; njs_object_prop_t *prop; if (njs_slow_path(!array->object.fast_array)) { @@ -153,8 +153,7 @@ njs_array_convert_to_slow_array(njs_vm_t *vm, njs_array_t *array) for (i = 0; i < length; i++) { if (njs_is_valid(&array->start[i])) { - njs_uint32_to_string(&index, i); - prop = njs_object_property_add(vm, &value, &index, 0); + prop = njs_object_property_add(vm, &value, njs_number_atom(i), 0); if (njs_slow_path(prop == NULL)) { return NJS_ERROR; } @@ -176,15 +175,13 @@ njs_array_length_redefine(njs_vm_t *vm, njs_value_t *value, uint32_t length, { njs_object_prop_t *prop; - static const njs_value_t string_length = njs_string("length"); - if (njs_slow_path(!njs_is_array(value))) { njs_internal_error(vm, "njs_array_length_redefine() " "applied to non-array"); return NJS_ERROR; } - prop = njs_object_property_add(vm, value, njs_value_arg(&string_length), 1); + prop = njs_object_property_add(vm, value, NJS_ATOM_STRING_length, 1); if (njs_slow_path(prop == NULL)) { njs_internal_error(vm, "njs_array_length_redefine() " "cannot redefine \"length\""); @@ -241,7 +238,8 @@ njs_array_length_set(njs_vm_t *vm, njs_value_t *value, do { idx = njs_string_to_index(&keys->start[i]); if (idx >= length) { - ret = njs_value_property_delete(vm, value, &keys->start[i], + ret = njs_value_property_delete(vm, value, + keys->start[i].atom_id, NULL, 1); if (njs_slow_path(ret == NJS_ERROR)) { goto done; @@ -603,19 +601,20 @@ njs_array_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } -static const njs_object_prop_t njs_array_constructor_properties[] = +static const njs_object_prop_init_t njs_array_constructor_properties[] = { NJS_DECLARE_PROP_LENGTH(1), NJS_DECLARE_PROP_NAME("Array"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), - NJS_DECLARE_PROP_NATIVE("from", njs_array_from, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_from, njs_array_from, 1, 0), - NJS_DECLARE_PROP_NATIVE("isArray", njs_array_is_array, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_isArray, njs_array_is_array, 1, 0), - NJS_DECLARE_PROP_NATIVE("of", njs_array_of, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_of, njs_array_of, 0, 0), }; @@ -626,8 +625,8 @@ const njs_object_init_t njs_array_constructor_init = { static njs_int_t -njs_array_length(njs_vm_t *vm,njs_object_prop_t *prop, njs_value_t *value, - njs_value_t *setval, njs_value_t *retval) +njs_array_length(njs_vm_t *vm,njs_object_prop_t *prop, uint32_t unused, + njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { double num; int64_t size; @@ -787,8 +786,8 @@ static njs_int_t njs_array_prototype_slice_copy(njs_vm_t *vm, njs_value_t *this, int64_t start, int64_t length, njs_value_t *retval) { + u_char *c, buf[4]; size_t size; - u_char *dst; uint32_t n; njs_int_t ret; njs_array_t *array, *keys; @@ -819,7 +818,7 @@ njs_array_prototype_slice_copy(njs_vm_t *vm, njs_value_t *this, string_slice.start = start; string_slice.length = length; - string_slice.string_length = njs_string_prop(&string, this); + string_slice.string_length = njs_string_prop(vm, &string, this); njs_string_slice_string_prop(&string, &string, &string_slice); @@ -828,10 +827,14 @@ njs_array_prototype_slice_copy(njs_vm_t *vm, njs_value_t *this, do { value = &array->start[n++]; - dst = njs_string_short_start(value); - dst = njs_utf8_copy(dst, &src, end); - size = dst - njs_string_short_start(value); - njs_string_short_set(value, size, 1); + c = buf; + c = njs_utf8_copy(c, &src, end); + size = c - buf; + + ret = njs_string_new(vm, value, buf, size, 1); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_ERROR; + } length--; } while (length != 0); @@ -896,12 +899,12 @@ njs_array_prototype_slice_copy(njs_vm_t *vm, njs_value_t *this, } for (n = 0; n < keys->length; n++) { - ret = njs_value_property(vm, this, &keys->start[n], &val); + ret = njs_value_property(vm, this, keys->start[n].atom_id, &val); if (njs_slow_path(ret == NJS_ERROR)) { goto done; } - ret = njs_value_property_set(vm, &self, &keys->start[n], &val); + ret = njs_value_property_set(vm, &self, keys->start[n].atom_id, &val); if (njs_slow_path(ret == NJS_ERROR)) { goto done; } @@ -1108,7 +1111,8 @@ njs_array_prototype_unshift(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, from = keys->length; while (from > 0) { - ret = njs_value_property_delete(vm, this, &keys->start[--from], + ret = njs_value_property_delete(vm, this, + keys->start[--from].atom_id, &entry, 1); if (njs_slow_path(ret == NJS_ERROR)) { njs_array_destroy(vm, keys); @@ -1607,14 +1611,13 @@ njs_int_t njs_array_prototype_to_string(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval) { - njs_int_t ret; - njs_value_t value; - njs_lvlhsh_query_t lhq; - - static const njs_value_t join_string = njs_string("join"); + njs_int_t ret; + njs_value_t value; + njs_flathsh_query_t lhq; if (njs_is_object(njs_argument(args, 0))) { - njs_object_property_init(&lhq, &join_string, NJS_JOIN_HASH); + lhq.proto = &njs_object_hash_proto; + lhq.key_hash = NJS_ATOM_STRING_join; ret = njs_object_property(vm, njs_object(njs_argument(args, 0)), &lhq, &value); @@ -1655,7 +1658,7 @@ njs_array_prototype_join(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, if (njs_slow_path(!njs_is_string(value))) { if (njs_is_undefined(value)) { - value = njs_value_arg(&njs_string_comma); + value = NULL; } else { ret = njs_value_to_string(vm, value, value); @@ -1665,10 +1668,17 @@ njs_array_prototype_join(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } } - (void) njs_string_prop(&separator, value); + if (value != NULL) { + (void) njs_string_prop(vm, &separator, value); + + } else { + separator.start = (u_char *) ","; + separator.length = 1; + separator.size = 1; + } if (njs_slow_path(!njs_is_object(this))) { - njs_value_assign(retval, &njs_string_empty); + njs_set_empty_string(vm, retval); return NJS_OK; } @@ -1680,7 +1690,7 @@ njs_array_prototype_join(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } if (njs_slow_path(len == 0)) { - njs_value_assign(retval, &njs_string_empty); + njs_set_empty_string(vm, retval); return NJS_OK; } @@ -1704,7 +1714,7 @@ njs_array_prototype_join(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, length += ret; } else { - (void) njs_string_prop(&string, value); + (void) njs_string_prop(vm, &string, value); length += string.length; njs_chb_append(&chain, string.start, string.size); } @@ -1773,8 +1783,9 @@ njs_array_indices_handler(const void *first, const void *second, void *ctx) return diff != 0; } - njs_string_get(val1, &str1); - njs_string_get(val2, &str2); + /* properties from njs_value_own_enumerate() are always intialized. */ + njs_string_get_unsafe(val1, &str1); + njs_string_get_unsafe(val2, &str2); cmp_res = strncmp((const char *) str1.start, (const char *) str2.start, njs_min(str1.length, str2.length)); @@ -1886,14 +1897,12 @@ njs_is_concat_spreadable(njs_vm_t *vm, njs_value_t *value) njs_int_t ret; njs_value_t retval; - static const njs_value_t key = - njs_wellknown_symbol(NJS_SYMBOL_IS_CONCAT_SPREADABLE); - if (njs_slow_path(!njs_is_object(value))) { return NJS_DECLINED; } - ret = njs_value_property(vm, value, njs_value_arg(&key), &retval); + ret = njs_value_property(vm, value, NJS_ATOM_SYMBOL_isConcatSpreadable, + &retval); if (njs_slow_path(ret == NJS_ERROR)) { return NJS_ERROR; } @@ -1980,7 +1989,7 @@ njs_array_prototype_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } for (k = 0; k < keys->length; k++) { - ret = njs_value_property(vm, e, &keys->start[k], &value); + ret = njs_value_property_val(vm, e, &keys->start[k], &value); if (njs_slow_path(ret == NJS_ERROR)) { return ret; } @@ -2162,7 +2171,7 @@ njs_array_handler_includes(njs_vm_t *vm, njs_iterator_args_t *args, entry = njs_value_arg(&njs_value_undefined); } - if (njs_values_same_zero(njs_value_arg(&args->argument), entry)) { + if (njs_values_same_zero(vm, njs_value_arg(&args->argument), entry)) { njs_set_true(retval); return NJS_DONE; @@ -2176,7 +2185,7 @@ static njs_int_t njs_array_handler_index_of(njs_vm_t *vm, njs_iterator_args_t *args, njs_value_t *entry, int64_t n, njs_value_t *retval) { - if (njs_values_strict_equal(njs_value_arg(&args->argument), entry)) { + if (njs_values_strict_equal(vm, njs_value_arg(&args->argument), entry)) { njs_set_number(retval, n); return NJS_DONE; @@ -2714,7 +2723,7 @@ njs_array_compare(const void *a, const void *b, void *c) } } - ret = njs_string_cmp(aslot->str, bslot->str); + ret = njs_string_cmp(ctx->vm, aslot->str, bslot->str); if (ret != 0) { return ret; @@ -2776,8 +2785,12 @@ njs_sort_indexed_properties(njs_vm_t *vm, njs_value_t *obj, int64_t length, njs_value_assign(&p->value, &start[i]); } else { - njs_uint32_to_string(&key, i); - ret = njs_value_property(vm, obj, &key, &p->value); + ret = njs_uint32_to_string(vm, &key, i); + if (njs_slow_path(ret != NJS_OK)) { + goto exception; + } + + ret = njs_value_property_val(vm, obj, &key, &p->value); if (njs_slow_path(ret == NJS_ERROR)) { goto exception; } @@ -2820,7 +2833,7 @@ njs_sort_indexed_properties(njs_vm_t *vm, njs_value_t *obj, int64_t length, ilength = njs_min(keys->length, length); for (i = 0; i < ilength; i++) { - ret = njs_value_property(vm, obj, &keys->start[i], &p->value); + ret = njs_value_property_val(vm, obj, &keys->start[i], &p->value); if (njs_slow_path(ret == NJS_ERROR)) { goto exception; } @@ -3179,103 +3192,105 @@ njs_array_prototype_iterator_obj(njs_vm_t *vm, njs_value_t *args, } -static const njs_object_prop_t njs_array_prototype_properties[] = +static const njs_object_prop_init_t njs_array_prototype_properties[] = { - NJS_DECLARE_PROP_HANDLER("length", njs_array_length, 0, 0, + NJS_DECLARE_PROP_HANDLER(STRING_length, njs_array_length, 0, NJS_OBJECT_PROP_VALUE_W), - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_NATIVE("concat", njs_array_prototype_concat, 1, 0), - - NJS_DECLARE_PROP_NATIVE("copyWithin", njs_array_prototype_copy_within, 2, + NJS_DECLARE_PROP_NATIVE(STRING_concat, njs_array_prototype_concat, 1, 0), - NJS_DECLARE_PROP_NATIVE("entries", njs_array_prototype_iterator_obj, 0, - NJS_ENUM_BOTH), + NJS_DECLARE_PROP_NATIVE(STRING_copyWithin, + njs_array_prototype_copy_within, 2, 0), + + NJS_DECLARE_PROP_NATIVE(STRING_entries, + njs_array_prototype_iterator_obj, 0, NJS_ENUM_BOTH), - NJS_DECLARE_PROP_NATIVE("every", njs_array_prototype_iterator, 1, + NJS_DECLARE_PROP_NATIVE(STRING_every, njs_array_prototype_iterator, 1, njs_array_func(NJS_ARRAY_EVERY)), - NJS_DECLARE_PROP_NATIVE("fill", njs_array_prototype_fill, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_fill, njs_array_prototype_fill, 1, 0), - NJS_DECLARE_PROP_NATIVE("filter", njs_array_prototype_iterator, 1, + NJS_DECLARE_PROP_NATIVE(STRING_filter, njs_array_prototype_iterator, 1, njs_array_func(NJS_ARRAY_FILTER)), - NJS_DECLARE_PROP_NATIVE("find", njs_array_prototype_iterator, 1, + NJS_DECLARE_PROP_NATIVE(STRING_find, njs_array_prototype_iterator, 1, njs_array_func(NJS_ARRAY_FIND)), - NJS_DECLARE_PROP_NATIVE("findIndex", njs_array_prototype_iterator, 1, - njs_array_func(NJS_ARRAY_FIND_INDEX)), + NJS_DECLARE_PROP_NATIVE(STRING_findIndex, njs_array_prototype_iterator, + 1, njs_array_func(NJS_ARRAY_FIND_INDEX)), - NJS_DECLARE_PROP_NATIVE("forEach", njs_array_prototype_iterator, 1, - njs_array_func(NJS_ARRAY_FOR_EACH)), + NJS_DECLARE_PROP_NATIVE(STRING_forEach, njs_array_prototype_iterator, + 1, njs_array_func(NJS_ARRAY_FOR_EACH)), - NJS_DECLARE_PROP_NATIVE("includes", njs_array_prototype_iterator, 1, - njs_array_arg(NJS_ARRAY_INCLUDES)), + NJS_DECLARE_PROP_NATIVE(STRING_includes, njs_array_prototype_iterator, + 1, njs_array_arg(NJS_ARRAY_INCLUDES)), - NJS_DECLARE_PROP_NATIVE("indexOf", njs_array_prototype_iterator, 1, + NJS_DECLARE_PROP_NATIVE(STRING_indexOf, njs_array_prototype_iterator, 1, njs_array_arg(NJS_ARRAY_INDEX_OF)), - NJS_DECLARE_PROP_NATIVE("join", njs_array_prototype_join, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_join, njs_array_prototype_join, 1, 0), - NJS_DECLARE_PROP_NATIVE("keys", njs_array_prototype_iterator_obj, 0, - NJS_ENUM_KEYS), + NJS_DECLARE_PROP_NATIVE(STRING_keys, njs_array_prototype_iterator_obj, + 0, NJS_ENUM_KEYS), - NJS_DECLARE_PROP_NATIVE("lastIndexOf", + NJS_DECLARE_PROP_NATIVE(STRING_lastIndexOf, njs_array_prototype_reverse_iterator, 1, NJS_ARRAY_LAST_INDEX_OF), - NJS_DECLARE_PROP_NATIVE("map", njs_array_prototype_iterator, 1, + NJS_DECLARE_PROP_NATIVE(STRING_map, njs_array_prototype_iterator, 1, njs_array_func(NJS_ARRAY_MAP)), - NJS_DECLARE_PROP_NATIVE("pop", njs_array_prototype_pop, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_pop, njs_array_prototype_pop, 0, 0), - NJS_DECLARE_PROP_NATIVE("push", njs_array_prototype_push, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_push, njs_array_prototype_push, 1, 0), - NJS_DECLARE_PROP_NATIVE("reduce", njs_array_prototype_iterator, 1, + NJS_DECLARE_PROP_NATIVE(STRING_reduce, njs_array_prototype_iterator, 1, njs_array_func(NJS_ARRAY_REDUCE)), - NJS_DECLARE_PROP_NATIVE("reduceRight", + NJS_DECLARE_PROP_NATIVE(STRING_reduceRight, njs_array_prototype_reverse_iterator, 1, njs_array_func(NJS_ARRAY_REDUCE_RIGHT)), - NJS_DECLARE_PROP_NATIVE("reverse", njs_array_prototype_reverse, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_reverse, njs_array_prototype_reverse, 0, 0), - NJS_DECLARE_PROP_NATIVE("shift", njs_array_prototype_shift, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_shift, njs_array_prototype_shift, 0, 0), - NJS_DECLARE_PROP_NATIVE("slice", njs_array_prototype_slice, 2, 0), + NJS_DECLARE_PROP_NATIVE(STRING_slice, njs_array_prototype_slice, 2, 0), - NJS_DECLARE_PROP_NATIVE("some", njs_array_prototype_iterator, 1, + NJS_DECLARE_PROP_NATIVE(STRING_some, njs_array_prototype_iterator, 1, njs_array_func(NJS_ARRAY_SOME)), - NJS_DECLARE_PROP_NATIVE("sort", njs_array_prototype_sort, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_sort, njs_array_prototype_sort, 1, 0), - NJS_DECLARE_PROP_NATIVE("splice", njs_array_prototype_splice, 2, 0), + NJS_DECLARE_PROP_NATIVE(STRING_splice, njs_array_prototype_splice, 2, + 0), - NJS_DECLARE_PROP_NATIVE("toReversed", njs_array_prototype_to_reversed, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_toReversed, + njs_array_prototype_to_reversed, 0, 0), - NJS_DECLARE_PROP_NATIVE("toSorted", njs_array_prototype_to_sorted, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_toSorted, njs_array_prototype_to_sorted, + 1, 0), - NJS_DECLARE_PROP_NATIVE("toSpliced", njs_array_prototype_to_spliced, 2, 0), + NJS_DECLARE_PROP_NATIVE(STRING_toSpliced, + njs_array_prototype_to_spliced, 2, 0), - NJS_DECLARE_PROP_NATIVE("toString", njs_array_prototype_to_string, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_toString, njs_array_prototype_to_string, + 0, 0), - NJS_DECLARE_PROP_NATIVE("unshift", njs_array_prototype_unshift, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_unshift, njs_array_prototype_unshift, 1, + 0), - NJS_DECLARE_PROP_NATIVE("values", njs_array_prototype_iterator_obj, 0, - NJS_ENUM_VALUES), + NJS_DECLARE_PROP_NATIVE(STRING_values, njs_array_prototype_iterator_obj, + 0, NJS_ENUM_VALUES), - { - .type = NJS_PROPERTY, - .name = njs_wellknown_symbol(NJS_SYMBOL_ITERATOR), - .u.value = njs_native_function2(njs_array_prototype_iterator_obj, 0, - NJS_ENUM_VALUES), - .writable = 1, - .configurable = 1, - }, + NJS_DECLARE_PROP_NATIVE(SYMBOL_iterator, + njs_array_prototype_iterator_obj, 0, + NJS_ENUM_VALUES), }; @@ -3285,9 +3300,9 @@ const njs_object_init_t njs_array_prototype_init = { }; -const njs_object_prop_t njs_array_instance_properties[] = +const njs_object_prop_init_t njs_array_instance_properties[] = { - NJS_DECLARE_PROP_HANDLER("length", njs_array_length, 0, 0, + NJS_DECLARE_PROP_HANDLER(STRING_length, njs_array_length, 0, NJS_OBJECT_PROP_VALUE_W), }; diff --git a/src/njs_array_buffer.c b/src/njs_array_buffer.c index dece7329..c0e51c9f 100644 --- a/src/njs_array_buffer.c +++ b/src/njs_array_buffer.c @@ -139,23 +139,20 @@ njs_array_buffer_writable(njs_vm_t *vm, njs_array_buffer_t *buffer) } -static const njs_object_prop_t njs_array_buffer_constructor_properties[] = +static const njs_object_prop_init_t njs_array_buffer_constructor_properties[] = { NJS_DECLARE_PROP_LENGTH(1), NJS_DECLARE_PROP_NAME("ArrayBuffer"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), - { - .type = NJS_ACCESSOR, - .name = njs_wellknown_symbol(NJS_SYMBOL_SPECIES), - .u.accessor = njs_getter(njs_array_buffer_get_this, 0), - .writable = NJS_ATTRIBUTE_UNSET, - .configurable = 1, - }, + NJS_DECLARE_PROP_GETTER(SYMBOL_species, + njs_array_buffer_get_this, + 0), - NJS_DECLARE_PROP_NATIVE("isView", njs_array_buffer_is_view, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_isView, njs_array_buffer_is_view, 1, 0), }; @@ -265,23 +262,20 @@ njs_array_buffer_detach(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, -static const njs_object_prop_t njs_array_buffer_prototype_properties[] = +static const njs_object_prop_init_t njs_array_buffer_prototype_properties[] = { - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_GETTER("byteLength", + NJS_DECLARE_PROP_GETTER(STRING_byteLength, njs_array_buffer_prototype_byte_length, 0), - NJS_DECLARE_PROP_NATIVE("slice", njs_array_buffer_prototype_slice, 2, 0), + NJS_DECLARE_PROP_NATIVE(STRING_slice, njs_array_buffer_prototype_slice, + 2, 0), - { - .type = NJS_PROPERTY, - .name = njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG), - .u.value = njs_string("ArrayBuffer"), - .configurable = 1, - }, + NJS_DECLARE_PROP_VALUE(SYMBOL_toStringTag, njs_ascii_strval("ArrayBuffer"), + NJS_OBJECT_PROP_VALUE_C), }; diff --git a/src/njs_async.c b/src/njs_async.c index 77b4605f..c352e86e 100644 --- a/src/njs_async.c +++ b/src/njs_async.c @@ -161,13 +161,14 @@ njs_async_context_free(njs_vm_t *vm, njs_async_ctx_t *ctx) } -static const njs_object_prop_t njs_async_constructor_properties[] = +static const njs_object_prop_init_t njs_async_constructor_properties[] = { NJS_DECLARE_PROP_LENGTH(1), NJS_DECLARE_PROP_NAME("AsyncFunction"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), }; @@ -177,18 +178,15 @@ const njs_object_init_t njs_async_constructor_init = { }; -static const njs_object_prop_t njs_async_prototype_properties[] = +static const njs_object_prop_init_t njs_async_prototype_properties[] = { - { - .type = NJS_PROPERTY, - .name = njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG), - .u.value = njs_string("AsyncFunction"), - .configurable = 1, - }, - - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_VALUE(SYMBOL_toStringTag, + njs_ascii_strval("AsyncFunction"), + NJS_OBJECT_PROP_VALUE_C), + + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), }; @@ -206,12 +204,12 @@ const njs_object_type_init_t njs_async_function_type_init = { }; -const njs_object_prop_t njs_async_function_instance_properties[] = +const njs_object_prop_init_t njs_async_function_instance_properties[] = { - NJS_DECLARE_PROP_HANDLER("length", njs_function_instance_length, 0, 0, + NJS_DECLARE_PROP_HANDLER(STRING_length, njs_function_instance_length, 0, NJS_OBJECT_PROP_VALUE_C), - NJS_DECLARE_PROP_HANDLER("name", njs_function_instance_name, 0, 0, + NJS_DECLARE_PROP_HANDLER(STRING_name, njs_function_instance_name, 0, NJS_OBJECT_PROP_VALUE_C), }; diff --git a/src/njs_atom.c b/src/njs_atom.c new file mode 100644 index 00000000..24e6dc17 --- /dev/null +++ b/src/njs_atom.c @@ -0,0 +1,333 @@ + +/* + * Copyright (C) Vadim Zhestkov + * Copyright (C) F5, Inc. + */ + + +#include + + +static njs_int_t njs_lexer_hash_test(njs_lvlhsh_query_t *lhq, void *data); +static njs_int_t njs_atom_hash_test(njs_flathsh_query_t *lhq, void *data); + + +const njs_value_t njs_atom[] = { +#define NJS_DEF_SYMBOL(_id, _s) njs_symval(_id, _s), +#define NJS_DEF_STRING(_id, _s, _typ, _tok) (njs_value_t) { \ + .string = { \ + .type = NJS_STRING, \ + .truth = njs_length(_s) ? 1 : 0, \ + .atom_id = NJS_ATOM_STRING_ ## _id, \ + .token_type = _typ, \ + .token_id = _tok, \ + .data = & (njs_string_t) { \ + .start = (u_char *) _s, \ + .length = njs_length(_s), \ + .size = njs_length(_s), \ + }, \ + } \ +}, + + #include +}; + + +const njs_lvlhsh_proto_t njs_lexer_hash_proto + njs_aligned(64) = +{ + NJS_LVLHSH_DEFAULT, + njs_lexer_hash_test, + njs_lvlhsh_alloc, + njs_lvlhsh_free, +}; + + +const njs_flathsh_proto_t njs_atom_hash_proto + njs_aligned(64) = +{ + 0, + njs_atom_hash_test, + njs_lvlhsh_alloc, + njs_lvlhsh_free, +}; + + +static njs_int_t +njs_lexer_hash_test(njs_lvlhsh_query_t *lhq, void *data) +{ + u_char *start; + njs_value_t *name; + + name = data; + + njs_assert(name->type == NJS_STRING); + + if (lhq->key.length != name->string.data->size) { + return NJS_DECLINED; + } + + start = name->string.data->start; + + if (memcmp(start, lhq->key.start, lhq->key.length) == 0) { + return NJS_OK; + } + + return NJS_DECLINED; +} + + +njs_value_t * +njs_atom_find_or_add(njs_vm_t *vm, u_char *key, size_t size, size_t length, + uint32_t hash) +{ + njs_int_t ret; + njs_value_t *entry; + njs_lvlhsh_query_t lhq; + + lhq.key.start = key; + lhq.key.length = size; + lhq.key_hash = hash; + lhq.proto = &njs_lexer_hash_proto; + + ret = njs_lvlhsh_find(vm->atom_hash_current, &lhq); + if (ret == NJS_OK) { + return lhq.value; + } + + ret = njs_lvlhsh_find(&vm->atom_hash_shared, &lhq); + if (ret == NJS_OK) { + return lhq.value; + } + + entry = njs_mp_alloc(vm->mem_pool, sizeof(njs_value_t)); + if (njs_slow_path(entry == NULL)) { + return NULL; + } + + ret = njs_string_create(vm, entry, key, size); + if (njs_slow_path(ret != NJS_OK)) { + return NULL; + } + + entry->string.atom_id = vm->atom_id_generator++; + if (njs_atom_is_number(entry->string.atom_id)) { + njs_internal_error(vm, "too many atoms"); + return NULL; + } + + entry->string.token_type = NJS_KEYWORD_TYPE_UNDEF; + + lhq.value = entry; + lhq.pool = vm->mem_pool; + + ret = njs_lvlhsh_insert(vm->atom_hash_current, &lhq); + if (njs_slow_path(ret != NJS_OK)) { + return NULL; + } + + return entry; +} + + +static njs_int_t +njs_atom_hash_test(njs_flathsh_query_t *lhq, void *data) +{ + size_t size; + u_char *start; + njs_value_t *name; + + name = data; + + if (name->type == NJS_STRING + && ((njs_value_t *) lhq->value)->type == NJS_STRING) + { + size = name->string.data->length; + + if (lhq->key.length != size) { + return NJS_DECLINED; + } + + start = (u_char *) name->string.data->start; + + if (memcmp(start, lhq->key.start, lhq->key.length) == 0) { + return NJS_OK; + } + } + + if (name->type == NJS_SYMBOL + && ((njs_value_t *) lhq->value)->type == NJS_SYMBOL) + { + if (lhq->key_hash == name->atom_id) { + return NJS_OK; + } + } + + return NJS_DECLINED; +} + + +uint32_t +njs_atom_hash_init(njs_vm_t *vm) +{ + u_char *start; + size_t len; + njs_int_t ret; + njs_uint_t n; + const njs_value_t *value, *values; + njs_flathsh_query_t lhq; + + values = &njs_atom[0]; + + njs_lvlhsh_init(&vm->atom_hash_shared); + + lhq.replace = 0; + lhq.proto = &njs_atom_hash_proto; + lhq.pool = vm->mem_pool; + + for (n = 0; n < NJS_ATOM_SIZE; n++) { + value = &values[n]; + + if (value->type == NJS_SYMBOL) { + lhq.key_hash = value->string.atom_id; + lhq.value = (void *) value; + + ret = njs_flathsh_insert(&vm->atom_hash_shared, &lhq); + if (njs_slow_path(ret != NJS_OK)) { + njs_internal_error(vm, "flathsh insert/replace failed"); + return 0xffffffff; + } + } + + if (value->type == NJS_STRING) { + start = value->string.data->start; + len = value->string.data->length; + + lhq.key_hash = njs_djb_hash(start, len); + lhq.key.length = len; + lhq.key.start = start; + lhq.value = (void *) value; + + ret = njs_flathsh_insert(&vm->atom_hash_shared, &lhq); + if (njs_slow_path(ret != NJS_OK)) { + njs_internal_error(vm, "flathsh insert/replace failed"); + return 0xffffffff; + } + } + } + + vm->atom_hash_current = &vm->atom_hash_shared; + + return NJS_ATOM_SIZE; +} + + +njs_int_t +njs_atom_atomize_key(njs_vm_t *vm, njs_value_t *value) +{ + double num; + uint32_t hash_id, u32; + njs_int_t ret; + njs_value_t val_str; + const njs_value_t *entry; + + njs_assert(value->atom_id == NJS_ATOM_STRING_unknown); + + switch (value->type) { + case NJS_STRING: + num = njs_key_to_index(value); + u32 = (uint32_t) num; + + if (njs_fast_path(u32 == num && (u32 < 0x80000000) + && !(num == 0 && signbit(num)))) + { + value->atom_id = njs_number_atom(u32); + + } else { + hash_id = njs_djb_hash(value->string.data->start, + value->string.data->size); + + entry = njs_atom_find_or_add(vm, value->string.data->start, + value->string.data->size, + value->string.data->length, + hash_id); + if (njs_slow_path(entry == NULL)) { + return NJS_ERROR; + } + + *value = *entry; + } + + break; + + case NJS_NUMBER: + num = njs_number(value); + u32 = (uint32_t) num; + + if (njs_fast_path(u32 == num && (u32 < 0x80000000))) { + value->atom_id = njs_number_atom(u32); + + } else { + ret = njs_number_to_string(vm, &val_str, value); + if (ret != NJS_OK) { + return ret; + } + + if (val_str.atom_id == NJS_ATOM_STRING_unknown) { + hash_id = njs_djb_hash(val_str.string.data->start, + val_str.string.data->size); + + entry = njs_atom_find_or_add(vm, val_str.string.data->start, + val_str.string.data->size, + val_str.string.data->length, + hash_id); + if (njs_slow_path(entry == NULL)) { + return NJS_ERROR; + } + + value->atom_id = entry->atom_id; + + } else { + value->atom_id = val_str.atom_id; + } + } + + break; + + case NJS_SYMBOL: + default: + /* do nothing. */ + break; + } + + return NJS_OK; +} + + +njs_int_t +njs_atom_symbol_add(njs_vm_t *vm, njs_value_t *value) +{ + njs_int_t ret; + njs_flathsh_query_t lhq; + + njs_assert(value->atom_id == NJS_ATOM_STRING_unknown); + + lhq.replace = 0; + lhq.proto = &njs_lexer_hash_proto; + lhq.pool = vm->mem_pool; + + value->atom_id = vm->atom_id_generator++; + + if (value->type == NJS_SYMBOL) { + lhq.key_hash = value->atom_id; + lhq.value = (void *) value; + + ret = njs_flathsh_insert(vm->atom_hash_current, &lhq); + if (njs_slow_path(ret != NJS_OK)) { + njs_internal_error(vm, "flathsh insert/replace failed"); + return NJS_ERROR; + } + } + + return NJS_OK; +} diff --git a/src/njs_atom.h b/src/njs_atom.h new file mode 100644 index 00000000..12bb0e54 --- /dev/null +++ b/src/njs_atom.h @@ -0,0 +1,70 @@ + +/* + * Copyright (C) Vadim Zhestkov + * Copyright (C) F5, Inc. + */ + + +#ifndef _NJS_ATOM_H_INCLUDED_ +#define _NJS_ATOM_H_INCLUDED_ + + +enum { +#define NJS_DEF_STRING(name, _1, _2, _3) NJS_ATOM_STRING_ ## name, +#define NJS_DEF_SYMBOL(name, str) NJS_ATOM_SYMBOL_ ## name, +#include + NJS_ATOM_SIZE, +#undef NJS_DEF_SYMBOL +#undef NJS_DEF_STRING +}; + + +uint32_t njs_atom_hash_init(njs_vm_t *vm); +njs_int_t njs_atom_symbol_add(njs_vm_t *vm, njs_value_t *value); +njs_value_t *njs_atom_find_or_add(njs_vm_t *vm, u_char *key, size_t size, + size_t length, uint32_t hash); + + +njs_inline njs_int_t +njs_atom_to_value(njs_vm_t *vm, njs_value_t *dst, uint32_t atom_id) +{ + size_t size; + double num; + njs_flathsh_descr_t *h; + u_char buf[128]; + + njs_assert(atom_id != NJS_ATOM_STRING_unknown); + + if (njs_atom_is_number(atom_id)) { + num = njs_atom_number(atom_id); + size = njs_dtoa(num, (char *) buf); + + if (njs_string_new(vm, dst, buf, size, size) != NJS_OK) { + return NJS_ERROR; + } + + dst->atom_id = atom_id; + + return NJS_OK; + } + + if (atom_id < vm->shared_atom_count) { + h = vm->atom_hash_shared.slot; + + njs_assert(atom_id < h->elts_count); + + *dst = *((njs_value_t *) njs_hash_elts(h)[atom_id].value); + + } else { + h = vm->atom_hash_current->slot; + atom_id -= vm->shared_atom_count; + + njs_assert(atom_id < h->elts_count); + + *dst = *((njs_value_t *) njs_hash_elts(h)[atom_id].value); + } + + return NJS_OK; +} + +#endif /* _NJS_ATOM_H_INCLUDED_ */ diff --git a/src/njs_atom_defs.h b/src/njs_atom_defs.h new file mode 100644 index 00000000..f940648a --- /dev/null +++ b/src/njs_atom_defs.h @@ -0,0 +1,502 @@ + +/* + * Copyright (C) Vadim Zhestkov + * Copyright (C) F5, Inc. + */ + + +NJS_DEF_STRING(unknown, "unknown", 0, NJS_TOKEN_ILLEGAL) + +NJS_DEF_SYMBOL(asyncIterator, "Symbol.asyncIterator") +NJS_DEF_SYMBOL(hasInstance, "Symbol.hasInstance") +NJS_DEF_SYMBOL(isConcatSpreadable, "Symbol.isConcatSpreadable") +NJS_DEF_SYMBOL(iterator, "Symbol.iterator") +NJS_DEF_SYMBOL(match, "Symbol.match") +NJS_DEF_SYMBOL(matchAll, "Symbol.matchAll") +NJS_DEF_SYMBOL(replace, "Symbol.replace") +NJS_DEF_SYMBOL(search, "Symbol.search") +NJS_DEF_SYMBOL(species, "Symbol.species") +NJS_DEF_SYMBOL(split, "Symbol.split") +NJS_DEF_SYMBOL(toPrimitive, "Symbol.toPrimitive") +NJS_DEF_SYMBOL(toStringTag, "Symbol.toStringTag") +NJS_DEF_SYMBOL(unscopables, "Symbol.unscopables") + +/* Keywords. */ + +#define NJS_KWD (NJS_KEYWORD_TYPE_KEYWORD) +#define NJS_KWD_RESERVED (NJS_KEYWORD_TYPE_RESERVED | NJS_KEYWORD_TYPE_KEYWORD) + +NJS_DEF_STRING(arguments, "arguments", NJS_KWD, NJS_TOKEN_ARGUMENTS) +NJS_DEF_STRING(async, "async", NJS_KWD, NJS_TOKEN_ASYNC) +NJS_DEF_STRING(await, "await", NJS_KWD_RESERVED, NJS_TOKEN_AWAIT) +NJS_DEF_STRING(break, "break", NJS_KWD_RESERVED, NJS_TOKEN_BREAK) +NJS_DEF_STRING(case, "case", NJS_KWD_RESERVED, NJS_TOKEN_CASE) +NJS_DEF_STRING(catch, "catch", NJS_KWD_RESERVED, NJS_TOKEN_CATCH) +NJS_DEF_STRING(class, "class", NJS_KWD_RESERVED, NJS_TOKEN_CLASS) +NJS_DEF_STRING(const, "const", NJS_KWD_RESERVED, NJS_TOKEN_CONST) +NJS_DEF_STRING(continue, "continue", NJS_KWD_RESERVED, NJS_TOKEN_CONTINUE) +NJS_DEF_STRING(debugger, "debugger", NJS_KWD_RESERVED, NJS_TOKEN_DEBUGGER) +NJS_DEF_STRING(default, "default", NJS_KWD_RESERVED, NJS_TOKEN_DEFAULT) +NJS_DEF_STRING(delete, "delete", NJS_KWD_RESERVED, NJS_TOKEN_DELETE) +NJS_DEF_STRING(do, "do", NJS_KWD_RESERVED, NJS_TOKEN_DO) +NJS_DEF_STRING(else, "else", NJS_KWD_RESERVED, NJS_TOKEN_ELSE) +NJS_DEF_STRING(enum, "enum", NJS_KWD_RESERVED, NJS_TOKEN_ENUM) +NJS_DEF_STRING(eval, "eval", NJS_KWD, NJS_TOKEN_EVAL) +NJS_DEF_STRING(export, "export", NJS_KWD_RESERVED, NJS_TOKEN_EXPORT) +NJS_DEF_STRING(extends, "extends", NJS_KWD_RESERVED, NJS_TOKEN_EXTENDS) +NJS_DEF_STRING(false, "false", NJS_KWD_RESERVED, NJS_TOKEN_FALSE) +NJS_DEF_STRING(finally, "finally", NJS_KWD_RESERVED, NJS_TOKEN_FINALLY) +NJS_DEF_STRING(for, "for", NJS_KWD_RESERVED, NJS_TOKEN_FOR) +NJS_DEF_STRING(from, "from", NJS_KWD, NJS_TOKEN_FROM) +NJS_DEF_STRING(function, "function", NJS_KWD_RESERVED, NJS_TOKEN_FUNCTION) +NJS_DEF_STRING(if, "if", NJS_KWD_RESERVED, NJS_TOKEN_IF) +NJS_DEF_STRING(implements, "implements", NJS_KWD_RESERVED, NJS_TOKEN_IMPLEMENTS) +NJS_DEF_STRING(import, "import", NJS_KWD_RESERVED, NJS_TOKEN_IMPORT) +NJS_DEF_STRING(in, "in", NJS_KWD_RESERVED, NJS_TOKEN_IN) +NJS_DEF_STRING(instanceof, "instanceof", NJS_KWD_RESERVED, NJS_TOKEN_INSTANCEOF) +NJS_DEF_STRING(interface, "interface", NJS_KWD_RESERVED, NJS_TOKEN_INTERFACE) +NJS_DEF_STRING(let, "let", NJS_KWD_RESERVED, NJS_TOKEN_LET) +NJS_DEF_STRING(meta, "meta", NJS_KWD, NJS_TOKEN_META) +NJS_DEF_STRING(new, "new", NJS_KWD_RESERVED, NJS_TOKEN_NEW) +NJS_DEF_STRING(null, "null", NJS_KWD_RESERVED, NJS_TOKEN_NULL) +NJS_DEF_STRING(of, "of", NJS_KWD, NJS_TOKEN_OF) +NJS_DEF_STRING(package, "package", NJS_KWD_RESERVED, NJS_TOKEN_PACKAGE) +NJS_DEF_STRING(private, "private", NJS_KWD_RESERVED, NJS_TOKEN_PRIVATE) +NJS_DEF_STRING(protected, "protected", NJS_KWD_RESERVED, NJS_TOKEN_PROTECTED) +NJS_DEF_STRING(public, "public", NJS_KWD_RESERVED, NJS_TOKEN_PUBLIC) +NJS_DEF_STRING(return, "return", NJS_KWD_RESERVED, NJS_TOKEN_RETURN) +NJS_DEF_STRING(static, "static", NJS_KWD_RESERVED, NJS_TOKEN_STATIC) +NJS_DEF_STRING(super, "super", NJS_KWD_RESERVED, NJS_TOKEN_SUPER) +NJS_DEF_STRING(switch, "switch", NJS_KWD_RESERVED, NJS_TOKEN_SWITCH) +NJS_DEF_STRING(target, "target", NJS_KWD, NJS_TOKEN_TARGET) +NJS_DEF_STRING(this, "this", NJS_KWD_RESERVED, NJS_TOKEN_THIS) +NJS_DEF_STRING(throw, "throw", NJS_KWD_RESERVED, NJS_TOKEN_THROW) +NJS_DEF_STRING(true, "true", NJS_KWD_RESERVED, NJS_TOKEN_TRUE) +NJS_DEF_STRING(try, "try", NJS_KWD_RESERVED, NJS_TOKEN_TRY) +NJS_DEF_STRING(typeof, "typeof", NJS_KWD_RESERVED, NJS_TOKEN_TYPEOF) +NJS_DEF_STRING(undefined, "undefined", NJS_KWD, NJS_TOKEN_UNDEFINED) +NJS_DEF_STRING(var, "var", NJS_KWD_RESERVED, NJS_TOKEN_VAR) +NJS_DEF_STRING(void, "void", NJS_KWD_RESERVED, NJS_TOKEN_VOID) +NJS_DEF_STRING(while, "while", NJS_KWD_RESERVED, NJS_TOKEN_WHILE) +NJS_DEF_STRING(with, "with", NJS_KWD_RESERVED, NJS_TOKEN_WITH) +NJS_DEF_STRING(yield, "yield", NJS_KWD_RESERVED, NJS_TOKEN_YIELD) + +/* Other predefined strings. */ + +NJS_DEF_STRING(spec_EMPTY_REGEXP, "(?:)", 0, 0) + +NJS_DEF_STRING(empty, "", 0, 0) +NJS_DEF_STRING(_262, "$262", 0, 0) +NJS_DEF_STRING(_Infinity, "-Infinity", 0, 0) +NJS_DEF_STRING(AggregateError, "AggregateError", 0, 0) +NJS_DEF_STRING(All_promises_were_rejected, "All promises were rejected", 0, 0) +NJS_DEF_STRING(Array, "Array", 0, 0) +NJS_DEF_STRING(Array_Iterator, "Array Iterator", 0, 0) +NJS_DEF_STRING(ArrayBuffer, "ArrayBuffer", 0, 0) +NJS_DEF_STRING(AsyncFunction, "AsyncFunction", 0, 0) +NJS_DEF_STRING(Boolean, "Boolean", 0, 0) +NJS_DEF_STRING(Buffer, "Buffer", 0, 0) +NJS_DEF_STRING(BYTES_PER_ELEMENT, "BYTES_PER_ELEMENT", 0, 0) +NJS_DEF_STRING(DataView, "DataView", 0, 0) +NJS_DEF_STRING(Date, "Date", 0, 0) +NJS_DEF_STRING(E, "E", 0, 0) +NJS_DEF_STRING(EPSILON, "EPSILON", 0, 0) +NJS_DEF_STRING(Error, "Error", 0, 0) +NJS_DEF_STRING(EvalError, "EvalError", 0, 0) +NJS_DEF_STRING(Float32Array, "Float32Array", 0, 0) +NJS_DEF_STRING(Float64Array, "Float64Array", 0, 0) +NJS_DEF_STRING(Function, "Function", 0, 0) +NJS_DEF_STRING(Infinity, "Infinity", 0, 0) +NJS_DEF_STRING(Int16Array, "Int16Array", 0, 0) +NJS_DEF_STRING(Int32Array, "Int32Array", 0, 0) +NJS_DEF_STRING(Int8Array, "Int8Array", 0, 0) +NJS_DEF_STRING(InternalError, "InternalError", 0, 0) +NJS_DEF_STRING(Invalid_Date, "Invalid Date", 0, 0) +NJS_DEF_STRING(JSON, "JSON", 0, 0) +NJS_DEF_STRING(LN10, "LN10", 0, 0) +NJS_DEF_STRING(LN2, "LN2", 0, 0) +NJS_DEF_STRING(LOG10E, "LOG10E", 0, 0) +NJS_DEF_STRING(LOG2E, "LOG2E", 0, 0) +NJS_DEF_STRING(MAX_LENGTH, "MAX_LENGTH", 0, 0) +NJS_DEF_STRING(MAX_SAFE_INTEGER, "MAX_SAFE_INTEGER", 0, 0) +NJS_DEF_STRING(MAX_STRING_LENGTH, "MAX_STRING_LENGTH", 0, 0) +NJS_DEF_STRING(MAX_VALUE, "MAX_VALUE", 0, 0) +NJS_DEF_STRING(MIN_SAFE_INTEGER, "MIN_SAFE_INTEGER", 0, 0) +NJS_DEF_STRING(MIN_VALUE, "MIN_VALUE", 0, 0) +NJS_DEF_STRING(Math, "Math", 0, 0) +NJS_DEF_STRING(MemoryError, "MemoryError", 0, 0) +NJS_DEF_STRING(NEGATIVE_INFINITY, "NEGATIVE_INFINITY", 0, 0) +NJS_DEF_STRING(NaN, "NaN", 0, 0) +NJS_DEF_STRING(Number, "Number", 0, 0) +NJS_DEF_STRING(Object, "Object", 0, 0) +NJS_DEF_STRING(PI, "PI", 0, 0) +NJS_DEF_STRING(POSITIVE_INFINITY, "POSITIVE_INFINITY", 0, 0) +NJS_DEF_STRING(Promise, "Promise", 0, 0) +NJS_DEF_STRING(RangeError, "RangeError", 0, 0) +NJS_DEF_STRING(ReferenceError, "ReferenceError", 0, 0) +NJS_DEF_STRING(RegExp, "RegExp", 0, 0) +NJS_DEF_STRING(SQRT1_2, "SQRT1_2", 0, 0) +NJS_DEF_STRING(SQRT2, "SQRT2", 0, 0) +NJS_DEF_STRING(String, "String", 0, 0) +NJS_DEF_STRING(Symbol, "Symbol", 0, 0) +NJS_DEF_STRING(SyntaxError, "SyntaxError", 0, 0) +NJS_DEF_STRING(TextDecoder, "TextDecoder", 0, 0) +NJS_DEF_STRING(TextEncoder, "TextEncoder", 0, 0) +NJS_DEF_STRING(TypeError, "TypeError", 0, 0) +NJS_DEF_STRING(TypedArray, "TypedArray", 0, 0) +NJS_DEF_STRING(URIError, "URIError", 0, 0) +NJS_DEF_STRING(UTC, "UTC", 0, 0) +NJS_DEF_STRING(Uint16Array, "Uint16Array", 0, 0) +NJS_DEF_STRING(Uint32Array, "Uint32Array", 0, 0) +NJS_DEF_STRING(Uint8Array, "Uint8Array", 0, 0) +NJS_DEF_STRING(Uint8ClampedArray, "Uint8ClampedArray", 0, 0) +NJS_DEF_STRING(_Getter_, "[Getter]", 0, 0) +NJS_DEF_STRING(_Setter_, "[Setter]", 0, 0) +NJS_DEF_STRING(_Getter_Setter_, "[Getter/Setter]", 0, 0) +NJS_DEF_STRING(_object_Array_, "[object Array]", 0, 0) +NJS_DEF_STRING(_object_Arguments_, "[object Arguments]", 0, 0) +NJS_DEF_STRING(_object_Boolean_, "[object Boolean]", 0, 0) +NJS_DEF_STRING(_object_Date_, "[object Date]", 0, 0) +NJS_DEF_STRING(_object_Error_, "[object Error]", 0, 0) +NJS_DEF_STRING(_object_Function_, "[object Function]", 0, 0) +NJS_DEF_STRING(_object_Null_, "[object Null]", 0, 0) +NJS_DEF_STRING(_object_Number_, "[object Number]", 0, 0) +NJS_DEF_STRING(_object_Object_, "[object Object]", 0, 0) +NJS_DEF_STRING(_object_RegExp_, "[object RegExp]", 0, 0) +NJS_DEF_STRING(_object_String_, "[object String]", 0, 0) +NJS_DEF_STRING(_object_Undefined_, "[object Undefined]", 0, 0) +NJS_DEF_STRING(__proto__, "__proto__", 0, 0) +NJS_DEF_STRING(abs, "abs", 0, 0) +NJS_DEF_STRING(acos, "acos", 0, 0) +NJS_DEF_STRING(acosh, "acosh", 0, 0) +NJS_DEF_STRING(all, "all", 0, 0) +NJS_DEF_STRING(alloc, "alloc", 0, 0) +NJS_DEF_STRING(allocUnsafe, "allocUnsafe", 0, 0) +NJS_DEF_STRING(allocUnsafeSlow, "allocUnsafeSlow", 0, 0) +NJS_DEF_STRING(allSettled, "allSettled", 0, 0) +NJS_DEF_STRING(anonymous, "anonymous", 0, 0) +NJS_DEF_STRING(any, "any", 0, 0) +NJS_DEF_STRING(apply, "apply", 0, 0) +NJS_DEF_STRING(argv, "argv", 0, 0) +NJS_DEF_STRING(asin, "asin", 0, 0) +NJS_DEF_STRING(asinh, "asinh", 0, 0) +NJS_DEF_STRING(assign, "assign", 0, 0) +NJS_DEF_STRING(asyncIterator, "asyncIterator", 0, 0) +NJS_DEF_STRING(atan, "atan", 0, 0) +NJS_DEF_STRING(atan2, "atan2", 0, 0) +NJS_DEF_STRING(atanh, "atanh", 0, 0) +NJS_DEF_STRING(atob, "atob", 0, 0) +NJS_DEF_STRING(bind, "bind", 0, 0) +NJS_DEF_STRING(boolean, "boolean", 0, 0) +NJS_DEF_STRING(btoa, "btoa", 0, 0) +NJS_DEF_STRING(buffer, "buffer", 0, 0) +NJS_DEF_STRING(byteLength, "byteLength", 0, 0) +NJS_DEF_STRING(byteOffset, "byteOffset", 0, 0) +NJS_DEF_STRING(call, "call", 0, 0) +NJS_DEF_STRING(callee, "callee", 0, 0) +NJS_DEF_STRING(caller, "caller", 0, 0) +NJS_DEF_STRING(cbrt, "cbrt", 0, 0) +NJS_DEF_STRING(ceil, "ceil", 0, 0) +NJS_DEF_STRING(charAt, "charAt", 0, 0) +NJS_DEF_STRING(charCodeAt, "charCodeAt", 0, 0) +NJS_DEF_STRING(cluster_size, "cluster_size", 0, 0) +NJS_DEF_STRING(clz32, "clz32", 0, 0) +NJS_DEF_STRING(codePointAt, "codePointAt", 0, 0) +NJS_DEF_STRING(compare, "compare", 0, 0) +NJS_DEF_STRING(concat, "concat", 0, 0) +NJS_DEF_STRING(configurable, "configurable", 0, 0) +NJS_DEF_STRING(constructor, "constructor", 0, 0) +NJS_DEF_STRING(copy, "copy", 0, 0) +NJS_DEF_STRING(copyWithin, "copyWithin", 0, 0) +NJS_DEF_STRING(cos, "cos", 0, 0) +NJS_DEF_STRING(cosh, "cosh", 0, 0) +NJS_DEF_STRING(create, "create", 0, 0) +NJS_DEF_STRING(data, "data", 0, 0) +NJS_DEF_STRING(decode, "decode", 0, 0) +NJS_DEF_STRING(decodeURI, "decodeURI", 0, 0) +NJS_DEF_STRING(decodeURIComponent, "decodeURIComponent", 0, 0) +NJS_DEF_STRING(defineProperty, "defineProperty", 0, 0) +NJS_DEF_STRING(defineProperties, "defineProperties", 0, 0) +NJS_DEF_STRING(description, "description", 0, 0) +NJS_DEF_STRING(done, "done", 0, 0) +NJS_DEF_STRING(dump, "dump", 0, 0) +NJS_DEF_STRING(encode, "encode", 0, 0) +NJS_DEF_STRING(encodeInto, "encodeInto", 0, 0) +NJS_DEF_STRING(encodeURI, "encodeURI", 0, 0) +NJS_DEF_STRING(encodeURIComponent, "encodeURIComponent", 0, 0) +NJS_DEF_STRING(encoding, "encoding", 0, 0) +NJS_DEF_STRING(endsWith, "endsWith", 0, 0) +NJS_DEF_STRING(engine, "engine", 0, 0) +NJS_DEF_STRING(enumerable, "enumerable", 0, 0) +NJS_DEF_STRING(entries, "entries", 0, 0) +NJS_DEF_STRING(env, "env", 0, 0) +NJS_DEF_STRING(equals, "equals", 0, 0) +NJS_DEF_STRING(errors, "errors", 0, 0) +NJS_DEF_STRING(every, "every", 0, 0) +NJS_DEF_STRING(exec, "exec", 0, 0) +NJS_DEF_STRING(exp, "exp", 0, 0) +NJS_DEF_STRING(expm1, "expm1", 0, 0) +NJS_DEF_STRING(external, "external", 0, 0) +NJS_DEF_STRING(fatal, "fatal", 0, 0) +NJS_DEF_STRING(fileName, "fileName", 0, 0) +NJS_DEF_STRING(fill, "fill", 0, 0) +NJS_DEF_STRING(filter, "filter", 0, 0) +NJS_DEF_STRING(find, "find", 0, 0) +NJS_DEF_STRING(findIndex, "findIndex", 0, 0) +NJS_DEF_STRING(flags, "flags", 0, 0) +NJS_DEF_STRING(floor, "floor", 0, 0) +NJS_DEF_STRING(forEach, "forEach", 0, 0) +NJS_DEF_STRING(freeze, "freeze", 0, 0) +NJS_DEF_STRING(fromCharCode, "fromCharCode", 0, 0) +NJS_DEF_STRING(fromCodePoint, "fromCodePoint", 0, 0) +NJS_DEF_STRING(fround, "fround", 0, 0) +NJS_DEF_STRING(fulfilled, "fulfilled", 0, 0) +NJS_DEF_STRING(get, "get", 0, 0) +NJS_DEF_STRING(getDate, "getDate", 0, 0) +NJS_DEF_STRING(getDay, "getDay", 0, 0) +NJS_DEF_STRING(getFloat32, "getFloat32", 0, 0) +NJS_DEF_STRING(getFloat64, "getFloat64", 0, 0) +NJS_DEF_STRING(getFullYear, "getFullYear", 0, 0) +NJS_DEF_STRING(getHours, "getHours", 0, 0) +NJS_DEF_STRING(getInt16, "getInt16", 0, 0) +NJS_DEF_STRING(getInt32, "getInt32", 0, 0) +NJS_DEF_STRING(getInt8, "getInt8", 0, 0) +NJS_DEF_STRING(getMilliseconds, "getMilliseconds", 0, 0) +NJS_DEF_STRING(getMinutes, "getMinutes", 0, 0) +NJS_DEF_STRING(getOwnPropertyDescriptor, "getOwnPropertyDescriptor", 0, 0) +NJS_DEF_STRING(getOwnPropertyDescriptors, "getOwnPropertyDescriptors", 0, 0) +NJS_DEF_STRING(getOwnPropertyNames, "getOwnPropertyNames", 0, 0) +NJS_DEF_STRING(getOwnPropertySymbols, "getOwnPropertySymbols", 0, 0) +NJS_DEF_STRING(getPrototypeOf, "getPrototypeOf", 0, 0) +NJS_DEF_STRING(getSeconds, "getSeconds", 0, 0) +NJS_DEF_STRING(getTime, "getTime", 0, 0) +NJS_DEF_STRING(getTimezoneOffset, "getTimezoneOffset", 0, 0) +NJS_DEF_STRING(getUTCDate, "getUTCDate", 0, 0) +NJS_DEF_STRING(getUTCDay, "getUTCDay", 0, 0) +NJS_DEF_STRING(getUTCFullYear, "getUTCFullYear", 0, 0) +NJS_DEF_STRING(getUTCHours, "getUTCHours", 0, 0) +NJS_DEF_STRING(getUTCMilliseconds, "getUTCMilliseconds", 0, 0) +NJS_DEF_STRING(getUTCMinutes, "getUTCMinutes", 0, 0) +NJS_DEF_STRING(getUTCMonth, "getUTCMonth", 0, 0) +NJS_DEF_STRING(getUTCSeconds, "getUTCSeconds", 0, 0) +NJS_DEF_STRING(getUint16, "getUint16", 0, 0) +NJS_DEF_STRING(getUint32, "getUint32", 0, 0) +NJS_DEF_STRING(getUint8, "getUint8", 0, 0) +NJS_DEF_STRING(getMonth, "getMonth", 0, 0) +NJS_DEF_STRING(global, "global", 0, 0) +NJS_DEF_STRING(globalThis, "globalThis", 0, 0) +NJS_DEF_STRING(groups, "groups", 0, 0) +NJS_DEF_STRING(hasOwnProperty, "hasOwnProperty", 0, 0) +NJS_DEF_STRING(hasInstance, "hasInstance", 0, 0) +NJS_DEF_STRING(hypot, "hypot", 0, 0) +NJS_DEF_STRING(ignoreBOM, "ignoreBOM", 0, 0) +NJS_DEF_STRING(ignoreCase, "ignoreCase", 0, 0) +NJS_DEF_STRING(imul, "imul", 0, 0) +NJS_DEF_STRING(includes, "includes", 0, 0) +NJS_DEF_STRING(index, "index", 0, 0) +NJS_DEF_STRING(indexOf, "indexOf", 0, 0) +NJS_DEF_STRING(input, "input", 0, 0) +NJS_DEF_STRING(is, "is", 0, 0) +NJS_DEF_STRING(isArray, "isArray", 0, 0) +NJS_DEF_STRING(isBuffer, "isBuffer", 0, 0) +NJS_DEF_STRING(isConcatSpreadable, "isConcatSpreadable", 0, 0) +NJS_DEF_STRING(isEncoding, "isEncoding", 0, 0) +NJS_DEF_STRING(isExtensible, "isExtensible", 0, 0) +NJS_DEF_STRING(isFinite, "isFinite", 0, 0) +NJS_DEF_STRING(isFrozen, "isFrozen", 0, 0) +NJS_DEF_STRING(isInteger, "isInteger", 0, 0) +NJS_DEF_STRING(isNaN, "isNaN", 0, 0) +NJS_DEF_STRING(isPrototypeOf, "isPrototypeOf", 0, 0) +NJS_DEF_STRING(isSafeInteger, "isSafeInteger", 0, 0) +NJS_DEF_STRING(isSealed, "isSealed", 0, 0) +NJS_DEF_STRING(isView, "isView", 0, 0) +NJS_DEF_STRING(iterator, "iterator", 0, 0) +NJS_DEF_STRING(join, "join", 0, 0) +NJS_DEF_STRING(keyFor, "keyFor", 0, 0) +NJS_DEF_STRING(keys, "keys", 0, 0) +NJS_DEF_STRING(kill, "kill", 0, 0) +NJS_DEF_STRING(lastIndex, "lastIndex", 0, 0) +NJS_DEF_STRING(lastIndexOf, "lastIndexOf", 0, 0) +NJS_DEF_STRING(length, "length", 0, 0) +NJS_DEF_STRING(lineNumber, "lineNumber", 0, 0) +NJS_DEF_STRING(log, "log", 0, 0) +NJS_DEF_STRING(log10, "log10", 0, 0) +NJS_DEF_STRING(log1p, "log1p", 0, 0) +NJS_DEF_STRING(log2, "log2", 0, 0) +NJS_DEF_STRING(map, "map", 0, 0) +NJS_DEF_STRING(matchAll, "matchAll", 0, 0) +NJS_DEF_STRING(match, "match", 0, 0) +NJS_DEF_STRING(max, "max", 0, 0) +NJS_DEF_STRING(min, "min", 0, 0) +NJS_DEF_STRING(memoryStats, "memoryStats", 0, 0) +NJS_DEF_STRING(message, "message", 0, 0) +NJS_DEF_STRING(multiline, "multiline", 0, 0) +NJS_DEF_STRING(name, "name", 0, 0) +NJS_DEF_STRING(nblocks, "nblocks", 0, 0) +NJS_DEF_STRING(next, "next", 0, 0) +NJS_DEF_STRING(njs, "njs", 0, 0) +NJS_DEF_STRING(now, "now", 0, 0) +NJS_DEF_STRING(number, "number", 0, 0) +NJS_DEF_STRING(object, "object", 0, 0) +NJS_DEF_STRING(on, "on", 0, 0) +NJS_DEF_STRING(padEnd, "padEnd", 0, 0) +NJS_DEF_STRING(padStart, "padStart", 0, 0) +NJS_DEF_STRING(page_size, "page_size", 0, 0) +NJS_DEF_STRING(parse, "parse", 0, 0) +NJS_DEF_STRING(parseFloat, "parseFloat", 0, 0) +NJS_DEF_STRING(parseInt, "parseInt", 0, 0) +NJS_DEF_STRING(pid, "pid", 0, 0) +NJS_DEF_STRING(pop, "pop", 0, 0) +NJS_DEF_STRING(pow, "pow", 0, 0) +NJS_DEF_STRING(ppid, "ppid", 0, 0) +NJS_DEF_STRING(preventExtensions, "preventExtensions", 0, 0) +NJS_DEF_STRING(process, "process", 0, 0) +NJS_DEF_STRING(propertyIsEnumerable, "propertyIsEnumerable", 0, 0) +NJS_DEF_STRING(prototype, "prototype", 0, 0) +NJS_DEF_STRING(push, "push", 0, 0) +NJS_DEF_STRING(race, "race", 0, 0) +NJS_DEF_STRING(random, "random", 0, 0) +NJS_DEF_STRING(read, "read", 0, 0) +NJS_DEF_STRING(readDoubleBE, "readDoubleBE", 0, 0) +NJS_DEF_STRING(readDoubleLE, "readDoubleLE", 0, 0) +NJS_DEF_STRING(readFloatBE, "readFloatBE", 0, 0) +NJS_DEF_STRING(readFloatLE, "readFloatLE", 0, 0) +NJS_DEF_STRING(readInt16BE, "readInt16BE", 0, 0) +NJS_DEF_STRING(readInt16LE, "readInt16LE", 0, 0) +NJS_DEF_STRING(readInt32BE, "readInt32BE", 0, 0) +NJS_DEF_STRING(readInt32LE, "readInt32LE", 0, 0) +NJS_DEF_STRING(readInt8, "readInt8", 0, 0) +NJS_DEF_STRING(readIntBE, "readIntBE", 0, 0) +NJS_DEF_STRING(readIntLE, "readIntLE", 0, 0) +NJS_DEF_STRING(readUInt16BE, "readUInt16BE", 0, 0) +NJS_DEF_STRING(readUInt16LE, "readUInt16LE", 0, 0) +NJS_DEF_STRING(readUInt32BE, "readUInt32BE", 0, 0) +NJS_DEF_STRING(readUInt32LE, "readUInt32LE", 0, 0) +NJS_DEF_STRING(readUInt8, "readUInt8", 0, 0) +NJS_DEF_STRING(readUIntBE, "readUIntBE", 0, 0) +NJS_DEF_STRING(readUIntLE, "readUIntLE", 0, 0) +NJS_DEF_STRING(reason, "reason", 0, 0) +NJS_DEF_STRING(reduce, "reduce", 0, 0) +NJS_DEF_STRING(reduceRight, "reduceRight", 0, 0) +NJS_DEF_STRING(reject, "reject", 0, 0) +NJS_DEF_STRING(rejected, "rejected", 0, 0) +NJS_DEF_STRING(repeat, "repeat", 0, 0) +NJS_DEF_STRING(replace, "replace", 0, 0) +NJS_DEF_STRING(replaceAll, "replaceAll", 0, 0) +NJS_DEF_STRING(require, "require", 0, 0) +NJS_DEF_STRING(resolve, "resolve", 0, 0) +NJS_DEF_STRING(reverse, "reverse", 0, 0) +NJS_DEF_STRING(round, "round", 0, 0) +NJS_DEF_STRING(seal, "seal", 0, 0) +NJS_DEF_STRING(search, "search", 0, 0) +NJS_DEF_STRING(set, "set", 0, 0) +NJS_DEF_STRING(setDate, "setDate", 0, 0) +NJS_DEF_STRING(setFloat32, "setFloat32", 0, 0) +NJS_DEF_STRING(setFloat64, "setFloat64", 0, 0) +NJS_DEF_STRING(setFullYear, "setFullYear", 0, 0) +NJS_DEF_STRING(setHours, "setHours", 0, 0) +NJS_DEF_STRING(setInt16, "setInt16", 0, 0) +NJS_DEF_STRING(setInt32, "setInt32", 0, 0) +NJS_DEF_STRING(setInt8, "setInt8", 0, 0) +NJS_DEF_STRING(setMilliseconds, "setMilliseconds", 0, 0) +NJS_DEF_STRING(setMinutes, "setMinutes", 0, 0) +NJS_DEF_STRING(setMonth, "setMonth", 0, 0) +NJS_DEF_STRING(setPrototypeOf, "setPrototypeOf", 0, 0) +NJS_DEF_STRING(setSeconds, "setSeconds", 0, 0) +NJS_DEF_STRING(setTime, "setTime", 0, 0) +NJS_DEF_STRING(setUint16, "setUint16", 0, 0) +NJS_DEF_STRING(setUint32, "setUint32", 0, 0) +NJS_DEF_STRING(setUint8, "setUint8", 0, 0) +NJS_DEF_STRING(setUTCDate, "setUTCDate", 0, 0) +NJS_DEF_STRING(setUTCFullYear, "setUTCFullYear", 0, 0) +NJS_DEF_STRING(setUTCHours, "setUTCHours", 0, 0) +NJS_DEF_STRING(setUTCMilliseconds, "setUTCMilliseconds", 0, 0) +NJS_DEF_STRING(setUTCMinutes, "setUTCMinutes", 0, 0) +NJS_DEF_STRING(setUTCMonth, "setUTCMonth", 0, 0) +NJS_DEF_STRING(setUTCSeconds, "setUTCSeconds", 0, 0) +NJS_DEF_STRING(shift, "shift", 0, 0) +NJS_DEF_STRING(sign, "sign", 0, 0) +NJS_DEF_STRING(sin, "sin", 0, 0) +NJS_DEF_STRING(sinh, "sinh", 0, 0) +NJS_DEF_STRING(size, "size", 0, 0) +NJS_DEF_STRING(slice, "slice", 0, 0) +NJS_DEF_STRING(some, "some", 0, 0) +NJS_DEF_STRING(sort, "sort", 0, 0) +NJS_DEF_STRING(source, "source", 0, 0) +NJS_DEF_STRING(species, "species", 0, 0) +NJS_DEF_STRING(splice, "splice", 0, 0) +NJS_DEF_STRING(split, "split", 0, 0) +NJS_DEF_STRING(sqrt, "sqrt", 0, 0) +NJS_DEF_STRING(stack, "stack", 0, 0) +NJS_DEF_STRING(startsWith, "startsWith", 0, 0) +NJS_DEF_STRING(status, "status", 0, 0) +NJS_DEF_STRING(sticky, "sticky", 0, 0) +NJS_DEF_STRING(stream, "stream", 0, 0) +NJS_DEF_STRING(string, "string", 0, 0) +NJS_DEF_STRING(stringify, "stringify", 0, 0) +NJS_DEF_STRING(subarray, "subarray", 0, 0) +NJS_DEF_STRING(substr, "substr", 0, 0) +NJS_DEF_STRING(substring, "substring", 0, 0) +NJS_DEF_STRING(symbol, "symbol", 0, 0) +NJS_DEF_STRING(swap16, "swap16", 0, 0) +NJS_DEF_STRING(swap32, "swap32", 0, 0) +NJS_DEF_STRING(swap64, "swap64", 0, 0) +NJS_DEF_STRING(tan, "tan", 0, 0) +NJS_DEF_STRING(tanh, "tanh", 0, 0) +NJS_DEF_STRING(test, "test", 0, 0) +NJS_DEF_STRING(then, "then", 0, 0) +NJS_DEF_STRING(times, "times", 0, 0) +NJS_DEF_STRING(toDateString, "toDateString", 0, 0) +NJS_DEF_STRING(toExponential, "toExponential", 0, 0) +NJS_DEF_STRING(toFixed, "toFixed", 0, 0) +NJS_DEF_STRING(toISOString, "toISOString", 0, 0) +NJS_DEF_STRING(toJSON, "toJSON", 0, 0) +NJS_DEF_STRING(toLocaleDateString, "toLocaleDateString", 0, 0) +NJS_DEF_STRING(toLocaleString, "toLocaleString", 0, 0) +NJS_DEF_STRING(toLocaleTimeString, "toLocaleTimeString", 0, 0) +NJS_DEF_STRING(toLowerCase, "toLowerCase", 0, 0) +NJS_DEF_STRING(toPrimitive, "toPrimitive", 0, 0) +NJS_DEF_STRING(toPrecision, "toPrecision", 0, 0) +NJS_DEF_STRING(toReversed, "toReversed", 0, 0) +NJS_DEF_STRING(toSorted, "toSorted", 0, 0) +NJS_DEF_STRING(toSpliced, "toSpliced", 0, 0) +NJS_DEF_STRING(toStringTag, "toStringTag", 0, 0) +NJS_DEF_STRING(toString, "toString", 0, 0) +NJS_DEF_STRING(toTimeString, "toTimeString", 0, 0) +NJS_DEF_STRING(toUpperCase, "toUpperCase", 0, 0) +NJS_DEF_STRING(toUTCString, "toUTCString", 0, 0) +NJS_DEF_STRING(trimEnd, "trimEnd", 0, 0) +NJS_DEF_STRING(trimStart, "trimStart", 0, 0) +NJS_DEF_STRING(trim, "trim", 0, 0) +NJS_DEF_STRING(trunc, "trunc", 0, 0) +NJS_DEF_STRING(type, "type", 0, 0) +NJS_DEF_STRING(usec, "usec", 0, 0) +NJS_DEF_STRING(unscopables, "unscopables", 0, 0) +NJS_DEF_STRING(unshift, "unshift", 0, 0) +NJS_DEF_STRING(utf_8, "utf-8", 0, 0) +NJS_DEF_STRING(value, "value", 0, 0) +NJS_DEF_STRING(valueOf, "valueOf", 0, 0) +NJS_DEF_STRING(values, "values", 0, 0) +NJS_DEF_STRING(version, "version", 0, 0) +NJS_DEF_STRING(version_number, "version_number", 0, 0) +NJS_DEF_STRING(write, "write", 0, 0) +NJS_DEF_STRING(writable, "writable", 0, 0) +NJS_DEF_STRING(writeDoubleBE, "writeDoubleBE", 0, 0) +NJS_DEF_STRING(writeDoubleLE, "writeDoubleLE", 0, 0) +NJS_DEF_STRING(writeFloatBE, "writeFloatBE", 0, 0) +NJS_DEF_STRING(writeFloatLE, "writeFloatLE", 0, 0) +NJS_DEF_STRING(writeIntBE, "writeIntBE", 0, 0) +NJS_DEF_STRING(writeIntLE, "writeIntLE", 0, 0) +NJS_DEF_STRING(writeInt16BE, "writeInt16BE", 0, 0) +NJS_DEF_STRING(writeInt16LE, "writeInt16LE", 0, 0) +NJS_DEF_STRING(writeInt32BE, "writeInt32BE", 0, 0) +NJS_DEF_STRING(writeInt32LE, "writeInt32LE", 0, 0) +NJS_DEF_STRING(writeInt8, "writeInt8", 0, 0) +NJS_DEF_STRING(writeUIntBE, "writeUIntBE", 0, 0) +NJS_DEF_STRING(writeUIntLE, "writeUIntLE", 0, 0) +NJS_DEF_STRING(writeUInt16BE, "writeUInt16BE", 0, 0) +NJS_DEF_STRING(writeUInt16LE, "writeUInt16LE", 0, 0) +NJS_DEF_STRING(writeUInt32BE, "writeUInt32BE", 0, 0) +NJS_DEF_STRING(writeUInt32LE, "writeUInt32LE", 0, 0) +NJS_DEF_STRING(writeUInt8, "writeUInt8", 0, 0) +NJS_DEF_STRING(written, "written", 0, 0) diff --git a/src/njs_boolean.c b/src/njs_boolean.c index ba26f751..39119060 100644 --- a/src/njs_boolean.c +++ b/src/njs_boolean.c @@ -38,23 +38,16 @@ njs_boolean_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } -static const njs_object_prop_t njs_boolean_constructor_properties[] = +static const njs_object_prop_init_t njs_boolean_constructor_properties[] = { - { - .type = NJS_PROPERTY, - .name = njs_string("name"), - .u.value = njs_string("Boolean"), - .configurable = 1, - }, - - { - .type = NJS_PROPERTY, - .name = njs_string("length"), - .u.value = njs_value(NJS_NUMBER, 1, 1.0), - .configurable = 1, - }, - - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval("Boolean"), + NJS_OBJECT_PROP_VALUE_C), + + NJS_DECLARE_PROP_VALUE(STRING_length, njs_value(NJS_NUMBER, 1, 1.0), + NJS_OBJECT_PROP_VALUE_C), + + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), }; @@ -110,29 +103,36 @@ njs_boolean_prototype_to_string(njs_vm_t *vm, njs_value_t *args, } } - njs_value_assign(retval, njs_is_true(value) ? &njs_string_true - : &njs_string_false); + if (njs_is_true(value)) { + njs_atom_to_value(vm, retval, NJS_ATOM_STRING_true); + + } else { + njs_atom_to_value(vm, retval, NJS_ATOM_STRING_false); + } return NJS_OK; } -static const njs_object_prop_t njs_boolean_prototype_properties[] = +static const njs_object_prop_init_t njs_boolean_prototype_properties[] = { - NJS_DECLARE_PROP_HANDLER("__proto__", njs_primitive_prototype_get_proto, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING___proto__, + njs_primitive_prototype_get_proto, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_NATIVE("valueOf", njs_boolean_prototype_value_of, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_valueOf, njs_boolean_prototype_value_of, + 0, 0), - NJS_DECLARE_PROP_NATIVE("toString", njs_boolean_prototype_to_string, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_toString, + njs_boolean_prototype_to_string, 0, 0), }; -const njs_object_init_t njs_boolean_prototype_init = { +static const njs_object_init_t njs_boolean_prototype_init = { njs_boolean_prototype_properties, njs_nitems(njs_boolean_prototype_properties), }; diff --git a/src/njs_buffer.c b/src/njs_buffer.c index 3ce1b90a..3f0469e7 100644 --- a/src/njs_buffer.c +++ b/src/njs_buffer.c @@ -76,7 +76,7 @@ static njs_int_t njs_buffer_write_string(njs_vm_t *vm, njs_value_t *value, njs_typed_array_t *array, const njs_buffer_encoding_t *encoding, uint64_t offset, uint64_t length, njs_value_t *retval); static njs_int_t njs_buffer_fill(njs_vm_t *vm, njs_typed_array_t *array, - const njs_value_t *fill, const njs_value_t *encoding, uint64_t offset, + const njs_value_t *fill, njs_value_t *encoding, uint64_t offset, uint64_t end); static njs_int_t njs_buffer_fill_string(njs_vm_t *vm, const njs_value_t *value, njs_typed_array_t *array, const njs_buffer_encoding_t *encoding, @@ -86,14 +86,14 @@ static njs_int_t njs_buffer_fill_typed_array(njs_vm_t *vm, uint8_t *end); static njs_int_t njs_buffer(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t atom_id, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static njs_int_t njs_buffer_constants(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t atom_id, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static njs_int_t njs_buffer_constant(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t atom_id, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static njs_int_t njs_buffer_init(njs_vm_t *vm); @@ -349,20 +349,17 @@ njs_buffer_from_object(njs_vm_t *vm, njs_value_t *value, njs_value_t *retval) njs_value_t val, data, length; njs_typed_array_t *buffer; - static const njs_value_t string_length = njs_string("length"); static const njs_str_t str_buffer = njs_str("Buffer"); next: - ret = njs_value_property(vm, value, njs_value_arg(&string_length), - &length); + ret = njs_value_property(vm, value, NJS_ATOM_STRING_length, &length); if (njs_slow_path(ret == NJS_ERROR)) { return ret; } if (ret == NJS_DECLINED) { - ret = njs_value_property(vm, value, njs_value_arg(&njs_string_type), - &val); + ret = njs_value_property(vm, value, NJS_ATOM_STRING_type, &val); if (njs_slow_path(ret != NJS_OK)) { return ret; } @@ -372,14 +369,13 @@ next: return ret; } - njs_string_get(&val, &str); + njs_string_get(vm, &val, &str); if (!njs_strstr_eq(&str, &str_buffer)) { return NJS_DECLINED; } - ret = njs_value_property(vm, value, njs_value_arg(&njs_string_data), - &val); + ret = njs_value_property(vm, value, NJS_ATOM_STRING_data, &val); if (njs_slow_path(ret != NJS_OK)) { return ret; } @@ -527,7 +523,7 @@ njs_buffer_from_string(njs_vm_t *vm, njs_value_t *value, return NJS_ERROR; } - njs_string_get(&dst, &str); + njs_string_get(vm, &dst, &str); buffer = njs_buffer_alloc(vm, str.length, 0); if (njs_slow_path(buffer == NULL)) { @@ -543,14 +539,14 @@ njs_buffer_from_string(njs_vm_t *vm, njs_value_t *value, static size_t -njs_buffer_decode_string_length(njs_value_t *value, +njs_buffer_decode_string_length(njs_vm_t *vm, njs_value_t *value, const njs_buffer_encoding_t *encoding) { size_t size; njs_str_t str; njs_string_prop_t string; - (void) njs_string_prop(&string, value); + (void) njs_string_prop(vm, &string, value); str.start = string.start; str.length = string.size; @@ -595,7 +591,7 @@ njs_buffer_byte_length(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return NJS_ERROR; } - size = njs_buffer_decode_string_length(value, encoding); + size = njs_buffer_decode_string_length(vm, value, encoding); njs_set_number(retval, size); @@ -965,7 +961,7 @@ static njs_int_t njs_buffer_is_encoding(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval) { - const njs_value_t *value; + njs_value_t *value; value = njs_arg(args, nargs, 1); njs_set_boolean(retval, njs_is_defined(value) @@ -977,7 +973,8 @@ njs_buffer_is_encoding(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, static njs_int_t njs_buffer_prototype_length(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { njs_typed_array_t *array; @@ -1703,7 +1700,7 @@ njs_buffer_write_string(njs_vm_t *vm, njs_value_t *value, return NJS_ERROR; } - njs_string_get(&dst, &str); + njs_string_get(vm, &dst, &str); start = &buffer->u.u8[array->offset + offset]; @@ -1812,7 +1809,7 @@ done: static njs_int_t njs_buffer_fill(njs_vm_t *vm, njs_typed_array_t *array, const njs_value_t *fill, - const njs_value_t *encode, uint64_t offset, uint64_t end) + njs_value_t *encode, uint64_t offset, uint64_t end) { double num; uint8_t *start, *stop; @@ -1887,7 +1884,7 @@ njs_buffer_fill_string(njs_vm_t *vm, const njs_value_t *value, return NJS_ERROR; } - njs_string_get(&dst, &str); + njs_string_get(vm, &dst, &str); if (str.length == 0) { memset(start, 0, end - start); @@ -1992,7 +1989,7 @@ njs_buffer_prototype_to_string(njs_vm_t *vm, njs_value_t *args, str.length = end - start; if (njs_slow_path(str.length == 0)) { - njs_value_assign(retval, &njs_string_empty); + njs_set_empty_string(vm, retval); return NJS_OK; } @@ -2173,7 +2170,7 @@ encoding: return ret; } - njs_string_get(&dst, &str); + njs_string_get(vm, &dst, &str); } else { src = njs_typed_array(value); @@ -2347,15 +2344,13 @@ njs_buffer_prototype_to_json(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, { u_char *p, *end; njs_int_t ret; - njs_value_t *value; + njs_value_t *value, setval; njs_value_t object, array; njs_array_t *arr; njs_object_t *obj; njs_typed_array_t *ta; njs_array_buffer_t *buffer; - static const njs_value_t string_buffer = njs_string("Buffer"); - ta = njs_buffer_slot(vm, njs_argument(args, 0), "this"); if (njs_slow_path(ta == NULL)) { return NJS_ERROR; @@ -2367,9 +2362,9 @@ njs_buffer_prototype_to_json(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } njs_set_object(&object, obj); + njs_atom_to_value(vm, &setval, NJS_ATOM_STRING_Buffer); - ret = njs_value_property_set(vm, &object, njs_value_arg(&njs_string_type), - njs_value_arg(&string_buffer)); + ret = njs_value_property_set(vm, &object, NJS_ATOM_STRING_type, &setval); if (njs_slow_path(ret != NJS_OK)) { return NJS_ERROR; } @@ -2395,8 +2390,7 @@ njs_buffer_prototype_to_json(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_set_array(&array, arr); - ret = njs_value_property_set(vm, &object, njs_value_arg(&njs_string_data), - &array); + ret = njs_value_property_set(vm, &object, NJS_ATOM_STRING_data, &array); if (njs_slow_path(ret != NJS_OK)) { return NJS_ERROR; } @@ -2408,10 +2402,10 @@ njs_buffer_prototype_to_json(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, const njs_buffer_encoding_t * -njs_buffer_encoding(njs_vm_t *vm, const njs_value_t *value, njs_bool_t throw) +njs_buffer_encoding(njs_vm_t *vm, njs_value_t *value, njs_bool_t throw) { - njs_str_t name; - njs_buffer_encoding_t *encoding; + njs_str_t name; + const njs_buffer_encoding_t *encoding; if (njs_slow_path(!njs_is_string(value))) { if (njs_is_defined(value)) { @@ -2422,7 +2416,7 @@ njs_buffer_encoding(njs_vm_t *vm, const njs_value_t *value, njs_bool_t throw) return &njs_buffer_encodings[0]; } - njs_string_get(value, &name); + njs_string_get(vm, value, &name); for (encoding = &njs_buffer_encodings[0]; encoding->name.length != 0; @@ -2449,7 +2443,7 @@ njs_buffer_decode_string(njs_vm_t *vm, const njs_value_t *value, njs_str_t str; njs_string_prop_t string; - (void) njs_string_prop(&string, value); + (void) njs_string_prop(vm, &string, value); str.start = string.start; str.length = string.size; @@ -2469,159 +2463,197 @@ njs_buffer_decode_string(njs_vm_t *vm, const njs_value_t *value, } -static const njs_object_prop_t njs_buffer_prototype_properties[] = +static const njs_object_prop_init_t njs_buffer_prototype_properties[] = { - { - .type = NJS_PROPERTY, - .name = njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG), - .u.value = njs_string("Buffer"), - .configurable = 1, - }, + NJS_DECLARE_PROP_VALUE(SYMBOL_toStringTag, njs_ascii_strval("Buffer"), + NJS_OBJECT_PROP_VALUE_C), - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("length", njs_buffer_prototype_length, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_length, njs_buffer_prototype_length, 0, + 0), - NJS_DECLARE_PROP_NATIVE("readInt8", njs_buffer_prototype_read_int, 1, - njs_buffer_magic(1, 1, 1)), + NJS_DECLARE_PROP_NATIVE(STRING_readInt8, njs_buffer_prototype_read_int, + 1, njs_buffer_magic(1, 1, 1)), - NJS_DECLARE_PROP_NATIVE("readUInt8", njs_buffer_prototype_read_int, 1, - njs_buffer_magic(1, 0, 1)), + NJS_DECLARE_PROP_NATIVE(STRING_readUInt8, njs_buffer_prototype_read_int, + 1, njs_buffer_magic(1, 0, 1)), - NJS_DECLARE_PROP_NATIVE("readInt16LE", njs_buffer_prototype_read_int, 1, + NJS_DECLARE_PROP_NATIVE(STRING_readInt16LE, + njs_buffer_prototype_read_int, 1, njs_buffer_magic(2, 1, 1)), - NJS_DECLARE_PROP_NATIVE("readUInt16LE", njs_buffer_prototype_read_int, 1, + NJS_DECLARE_PROP_NATIVE(STRING_readUInt16LE, + njs_buffer_prototype_read_int, 1, njs_buffer_magic(2, 0, 1)), - NJS_DECLARE_PROP_NATIVE("readInt16BE", njs_buffer_prototype_read_int, 1, + NJS_DECLARE_PROP_NATIVE(STRING_readInt16BE, + njs_buffer_prototype_read_int, 1, njs_buffer_magic(2, 1, 0)), - NJS_DECLARE_PROP_NATIVE("readUInt16BE", njs_buffer_prototype_read_int, 1, + NJS_DECLARE_PROP_NATIVE(STRING_readUInt16BE, + njs_buffer_prototype_read_int, 1, njs_buffer_magic(2, 0, 0)), - NJS_DECLARE_PROP_NATIVE("readInt32LE", njs_buffer_prototype_read_int, 1, + NJS_DECLARE_PROP_NATIVE(STRING_readInt32LE, + njs_buffer_prototype_read_int, 1, njs_buffer_magic(4, 1, 1)), - NJS_DECLARE_PROP_NATIVE("readUInt32LE", njs_buffer_prototype_read_int, 1, + NJS_DECLARE_PROP_NATIVE(STRING_readUInt32LE, + njs_buffer_prototype_read_int, 1, njs_buffer_magic(4, 0, 1)), - NJS_DECLARE_PROP_NATIVE("readInt32BE", njs_buffer_prototype_read_int, 1, + NJS_DECLARE_PROP_NATIVE(STRING_readInt32BE, + njs_buffer_prototype_read_int, 1, njs_buffer_magic(4, 1, 0)), - NJS_DECLARE_PROP_NATIVE("readUInt32BE", njs_buffer_prototype_read_int, 1, + NJS_DECLARE_PROP_NATIVE(STRING_readUInt32BE, + njs_buffer_prototype_read_int, 1, njs_buffer_magic(4, 0, 0)), - NJS_DECLARE_PROP_NATIVE("readIntLE", njs_buffer_prototype_read_int, 2, + NJS_DECLARE_PROP_NATIVE(STRING_readIntLE, + njs_buffer_prototype_read_int, 2, njs_buffer_magic(0, 1, 1)), - NJS_DECLARE_PROP_NATIVE("readUIntLE", njs_buffer_prototype_read_int, 2, + NJS_DECLARE_PROP_NATIVE(STRING_readUIntLE, + njs_buffer_prototype_read_int, 2, njs_buffer_magic(0, 0, 1)), - NJS_DECLARE_PROP_NATIVE("readIntBE", njs_buffer_prototype_read_int, 2, + NJS_DECLARE_PROP_NATIVE(STRING_readIntBE, + njs_buffer_prototype_read_int, 2, njs_buffer_magic(0, 1, 0)), - NJS_DECLARE_PROP_NATIVE("readUIntBE", njs_buffer_prototype_read_int, 2, + NJS_DECLARE_PROP_NATIVE(STRING_readUIntBE, + njs_buffer_prototype_read_int, 2, njs_buffer_magic(0, 0, 0)), - NJS_DECLARE_PROP_NATIVE("readFloatLE", njs_buffer_prototype_read_float, 1, + NJS_DECLARE_PROP_NATIVE(STRING_readFloatLE, + njs_buffer_prototype_read_float, 1, njs_buffer_magic(4, 0, 1)), - NJS_DECLARE_PROP_NATIVE("readFloatBE", njs_buffer_prototype_read_float, 1, + NJS_DECLARE_PROP_NATIVE(STRING_readFloatBE, + njs_buffer_prototype_read_float, 1, njs_buffer_magic(4, 0, 0)), - NJS_DECLARE_PROP_NATIVE("readDoubleLE", njs_buffer_prototype_read_float, 1, + NJS_DECLARE_PROP_NATIVE(STRING_readDoubleLE, + njs_buffer_prototype_read_float, 1, njs_buffer_magic(8, 0, 1)), - NJS_DECLARE_PROP_NATIVE("readDoubleBE", njs_buffer_prototype_read_float, 1, + NJS_DECLARE_PROP_NATIVE(STRING_readDoubleBE, + njs_buffer_prototype_read_float, 1, njs_buffer_magic(8, 0, 0)), - NJS_DECLARE_PROP_NATIVE("writeInt8", njs_buffer_prototype_write_int, 1, + NJS_DECLARE_PROP_NATIVE(STRING_writeInt8, + njs_buffer_prototype_write_int, 1, njs_buffer_magic(1, 1, 0)), - NJS_DECLARE_PROP_NATIVE("writeUInt8", njs_buffer_prototype_write_int, 1, + NJS_DECLARE_PROP_NATIVE(STRING_writeUInt8, + njs_buffer_prototype_write_int, 1, njs_buffer_magic(1, 0, 0)), - NJS_DECLARE_PROP_NATIVE("writeInt16LE", njs_buffer_prototype_write_int, 1, + NJS_DECLARE_PROP_NATIVE(STRING_writeInt16LE, + njs_buffer_prototype_write_int, 1, njs_buffer_magic(2, 1, 1)), - NJS_DECLARE_PROP_NATIVE("writeUInt16LE", njs_buffer_prototype_write_int, 1, + NJS_DECLARE_PROP_NATIVE(STRING_writeUInt16LE, + njs_buffer_prototype_write_int, 1, njs_buffer_magic(2, 0, 1)), - NJS_DECLARE_PROP_NATIVE("writeInt16BE", njs_buffer_prototype_write_int, 1, + NJS_DECLARE_PROP_NATIVE(STRING_writeInt16BE, + njs_buffer_prototype_write_int, 1, njs_buffer_magic(2, 1, 0)), - NJS_DECLARE_PROP_NATIVE("writeUInt16BE", njs_buffer_prototype_write_int, 1, + NJS_DECLARE_PROP_NATIVE(STRING_writeUInt16BE, + njs_buffer_prototype_write_int, 1, njs_buffer_magic(2, 0, 0)), - NJS_DECLARE_PROP_NATIVE("writeInt32LE", njs_buffer_prototype_write_int, 1, + NJS_DECLARE_PROP_NATIVE(STRING_writeInt32LE, + njs_buffer_prototype_write_int, 1, njs_buffer_magic(4, 1, 1)), - NJS_DECLARE_PROP_NATIVE("writeUInt32LE", njs_buffer_prototype_write_int, 1, + NJS_DECLARE_PROP_NATIVE(STRING_writeUInt32LE, + njs_buffer_prototype_write_int, 1, njs_buffer_magic(4, 0, 1)), - NJS_DECLARE_PROP_NATIVE("writeInt32BE", njs_buffer_prototype_write_int, 1, + NJS_DECLARE_PROP_NATIVE(STRING_writeInt32BE, + njs_buffer_prototype_write_int, 1, njs_buffer_magic(4, 1, 0)), - NJS_DECLARE_PROP_NATIVE("writeUInt32BE", njs_buffer_prototype_write_int, 1, + NJS_DECLARE_PROP_NATIVE(STRING_writeUInt32BE, + njs_buffer_prototype_write_int, 1, njs_buffer_magic(4, 0, 0)), - NJS_DECLARE_PROP_NATIVE("writeIntLE", njs_buffer_prototype_write_int, 1, + NJS_DECLARE_PROP_NATIVE(STRING_writeIntLE, + njs_buffer_prototype_write_int, 1, njs_buffer_magic(0, 1, 1)), - NJS_DECLARE_PROP_NATIVE("writeUIntLE", njs_buffer_prototype_write_int, 1, + NJS_DECLARE_PROP_NATIVE(STRING_writeUIntLE, + njs_buffer_prototype_write_int, 1, njs_buffer_magic(0, 0, 1)), - NJS_DECLARE_PROP_NATIVE("writeIntBE", njs_buffer_prototype_write_int, 1, + NJS_DECLARE_PROP_NATIVE(STRING_writeIntBE, + njs_buffer_prototype_write_int, 1, njs_buffer_magic(0, 1, 0)), - NJS_DECLARE_PROP_NATIVE("writeUIntBE", njs_buffer_prototype_write_int, 1, + NJS_DECLARE_PROP_NATIVE(STRING_writeUIntBE, + njs_buffer_prototype_write_int, 1, njs_buffer_magic(0, 0, 0)), - NJS_DECLARE_PROP_NATIVE("writeFloatLE", njs_buffer_prototype_write_float, + NJS_DECLARE_PROP_NATIVE(STRING_writeFloatLE, + njs_buffer_prototype_write_float, 1, njs_buffer_magic(4, 0, 1)), - NJS_DECLARE_PROP_NATIVE("writeFloatBE", njs_buffer_prototype_write_float, + NJS_DECLARE_PROP_NATIVE(STRING_writeFloatBE, + njs_buffer_prototype_write_float, 1, njs_buffer_magic(4, 0, 0)), - NJS_DECLARE_PROP_NATIVE("writeDoubleLE", njs_buffer_prototype_write_float, + NJS_DECLARE_PROP_NATIVE(STRING_writeDoubleLE, + njs_buffer_prototype_write_float, 1, njs_buffer_magic(8, 0, 1)), - NJS_DECLARE_PROP_NATIVE("writeDoubleBE", njs_buffer_prototype_write_float, + NJS_DECLARE_PROP_NATIVE(STRING_writeDoubleBE, + njs_buffer_prototype_write_float, 1, njs_buffer_magic(8, 0, 0)), - NJS_DECLARE_PROP_NATIVE("write", njs_buffer_prototype_write, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_write, njs_buffer_prototype_write, 1, 0), - NJS_DECLARE_PROP_NATIVE("fill", njs_buffer_prototype_fill, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_fill, njs_buffer_prototype_fill, 1, 0), - NJS_DECLARE_PROP_NATIVE("toString", njs_buffer_prototype_to_string, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_toString, njs_buffer_prototype_to_string, + 0, 0), - NJS_DECLARE_PROP_NATIVE("compare", njs_buffer_prototype_compare, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_compare, njs_buffer_prototype_compare, 1, + 0), - NJS_DECLARE_PROP_NATIVE("copy", njs_buffer_prototype_copy, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_copy, njs_buffer_prototype_copy, 1, 0), - NJS_DECLARE_PROP_NATIVE("equals", njs_buffer_prototype_equals, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_equals, njs_buffer_prototype_equals, 1, + 0), - NJS_DECLARE_PROP_NATIVE("indexOf", njs_buffer_prototype_index_of, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_indexOf, njs_buffer_prototype_index_of, + 1, 0), - NJS_DECLARE_PROP_NATIVE("lastIndexOf", njs_buffer_prototype_index_of, 1, - 1), + NJS_DECLARE_PROP_NATIVE(STRING_lastIndexOf, + njs_buffer_prototype_index_of, 1, 1), - NJS_DECLARE_PROP_NATIVE("includes", njs_buffer_prototype_includes, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_includes, njs_buffer_prototype_includes, 1, + 0), - NJS_DECLARE_PROP_NATIVE("subarray", njs_buffer_prototype_slice, 2, 0), + NJS_DECLARE_PROP_NATIVE(STRING_subarray, njs_buffer_prototype_slice, 2, + 0), - NJS_DECLARE_PROP_NATIVE("slice", njs_buffer_prototype_slice, 2, 0), + NJS_DECLARE_PROP_NATIVE(STRING_slice, njs_buffer_prototype_slice, 2, 0), - NJS_DECLARE_PROP_NATIVE("swap16", njs_buffer_prototype_swap, 0, 2), + NJS_DECLARE_PROP_NATIVE(STRING_swap16, njs_buffer_prototype_swap, 0, 2), - NJS_DECLARE_PROP_NATIVE("swap32", njs_buffer_prototype_swap, 0, 4), + NJS_DECLARE_PROP_NATIVE(STRING_swap32, njs_buffer_prototype_swap, 0, 4), - NJS_DECLARE_PROP_NATIVE("swap64", njs_buffer_prototype_swap, 0, 8), + NJS_DECLARE_PROP_NATIVE(STRING_swap64, njs_buffer_prototype_swap, 0, 8), - NJS_DECLARE_PROP_NATIVE("toJSON", njs_buffer_prototype_to_json, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_toJSON, njs_buffer_prototype_to_json, 0, + 0), }; @@ -2631,31 +2663,36 @@ const njs_object_init_t njs_buffer_prototype_init = { }; -static const njs_object_prop_t njs_buffer_constructor_properties[] = +static const njs_object_prop_init_t njs_buffer_constructor_properties[] = { NJS_DECLARE_PROP_LENGTH(0), NJS_DECLARE_PROP_NAME("Buffer"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), - NJS_DECLARE_PROP_NATIVE("alloc", njs_buffer_alloc_safe, 0, 1), + NJS_DECLARE_PROP_NATIVE(STRING_alloc, njs_buffer_alloc_safe, 0, 1), - NJS_DECLARE_PROP_NATIVE("allocUnsafe", njs_buffer_alloc_safe, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_allocUnsafe, njs_buffer_alloc_safe, 0, + 0), - NJS_DECLARE_PROP_LNATIVE("allocUnsafeSlow", njs_buffer_alloc_safe, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_allocUnsafeSlow, njs_buffer_alloc_safe, + 1, 0), - NJS_DECLARE_PROP_NATIVE("byteLength", njs_buffer_byte_length, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_byteLength, njs_buffer_byte_length, 1, + 0), - NJS_DECLARE_PROP_NATIVE("compare", njs_buffer_compare, 2, 0), + NJS_DECLARE_PROP_NATIVE(STRING_compare, njs_buffer_compare, 2, 0), - NJS_DECLARE_PROP_NATIVE("concat", njs_buffer_concat, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_concat, njs_buffer_concat, 1, 0), - NJS_DECLARE_PROP_NATIVE("from", njs_buffer_from, 3, 0), + NJS_DECLARE_PROP_NATIVE(STRING_from, njs_buffer_from, 3, 0), - NJS_DECLARE_PROP_NATIVE("isBuffer", njs_buffer_is_buffer, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_isBuffer, njs_buffer_is_buffer, 1, 0), - NJS_DECLARE_PROP_NATIVE("isEncoding", njs_buffer_is_encoding, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_isEncoding, njs_buffer_is_encoding, 1, + 0), }; @@ -2673,14 +2710,15 @@ const njs_object_type_init_t njs_buffer_type_init = { }; -static const njs_object_prop_t njs_buffer_constants_properties[] = +static const njs_object_prop_init_t njs_buffer_constants_properties[] = { - NJS_DECLARE_PROP_VALUE("MAX_LENGTH", njs_value(NJS_NUMBER, 1, INT32_MAX), + NJS_DECLARE_PROP_VALUE(STRING_MAX_LENGTH, + njs_value(NJS_NUMBER, 1, INT32_MAX), NJS_OBJECT_PROP_VALUE_E), - NJS_DECLARE_PROP_LVALUE("MAX_STRING_LENGTH", - njs_value(NJS_NUMBER, 1, NJS_STRING_MAX_LENGTH), - NJS_OBJECT_PROP_VALUE_E), + NJS_DECLARE_PROP_VALUE(STRING_MAX_STRING_LENGTH, + njs_value(NJS_NUMBER, 1, NJS_STRING_MAX_LENGTH), + NJS_OBJECT_PROP_VALUE_E), }; @@ -2691,26 +2729,26 @@ static const njs_object_init_t njs_buffer_constants_init = { static njs_int_t -njs_buffer(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, - njs_value_t *unused, njs_value_t *retval) +njs_buffer(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t atom_id, + njs_value_t *value, njs_value_t *unused, njs_value_t *retval) { - return njs_object_prop_init(vm, &njs_buffer_constructor_init, prop, value, - retval); + return njs_object_prop_init(vm, &njs_buffer_constructor_init, prop, atom_id, + value, retval); } static njs_int_t -njs_buffer_constants(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, - njs_value_t *unused, njs_value_t *retval) +njs_buffer_constants(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t atom_id, + njs_value_t *value, njs_value_t *unused, njs_value_t *retval) { - return njs_object_prop_init(vm, &njs_buffer_constants_init, prop, value, - retval); + return njs_object_prop_init(vm, &njs_buffer_constants_init, prop, atom_id, + value, retval); } static njs_int_t -njs_buffer_constant(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, - njs_value_t *unused, njs_value_t *retval) +njs_buffer_constant(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t not_used, + njs_value_t *value, njs_value_t *unused, njs_value_t *retval) { njs_value_number_set(retval, njs_vm_prop_magic32(prop)); diff --git a/src/njs_buffer.h b/src/njs_buffer.h index 696653c2..0ac4db79 100644 --- a/src/njs_buffer.h +++ b/src/njs_buffer.h @@ -27,7 +27,7 @@ njs_int_t njs_buffer_new(njs_vm_t *vm, njs_value_t *value, const u_char *start, uint32_t size); const njs_buffer_encoding_t *njs_buffer_encoding(njs_vm_t *vm, - const njs_value_t *value, njs_bool_t thrw); + njs_value_t *value, njs_bool_t thrw); njs_int_t njs_buffer_decode_string(njs_vm_t *vm, const njs_value_t *value, njs_value_t *dst, const njs_buffer_encoding_t *encoding); diff --git a/src/njs_builtin.c b/src/njs_builtin.c index 279c2158..230b4c1c 100644 --- a/src/njs_builtin.c +++ b/src/njs_builtin.c @@ -18,7 +18,7 @@ typedef struct { njs_function_t *func; - njs_lvlhsh_t keys; + njs_flathsh_t keys; njs_str_t match; } njs_builtin_traverse_t; @@ -30,10 +30,10 @@ typedef struct { static njs_int_t njs_global_this_prop_handler(njs_vm_t *vm, - njs_object_prop_t *self, njs_value_t *global, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *self, uint32_t atom_id, njs_value_t *global, + njs_value_t *setval, njs_value_t *retval); -static njs_int_t njs_env_hash_init(njs_vm_t *vm, njs_lvlhsh_t *hash, +static njs_int_t njs_env_hash_init(njs_vm_t *vm, njs_flathsh_t *hash, char **environment); @@ -132,7 +132,7 @@ static njs_signal_entry_t njs_signals_table[] = { njs_inline njs_int_t -njs_object_hash_init(njs_vm_t *vm, njs_lvlhsh_t *hash, +njs_object_hash_init(njs_vm_t *vm, njs_flathsh_t *hash, const njs_object_init_t *init) { return njs_object_hash_create(vm, hash, init->properties, init->items); @@ -158,9 +158,13 @@ njs_builtin_objects_create(njs_vm_t *vm) vm->shared = shared; - njs_lvlhsh_init(&shared->keywords_hash); njs_lvlhsh_init(&shared->values_hash); + vm->atom_id_generator = njs_atom_hash_init(vm); + if (njs_slow_path(vm->atom_id_generator == 0xffffffff)) { + return NJS_ERROR; + } + pattern = njs_regexp_pattern_create(vm, (u_char *) "(?:)", njs_length("(?:)"), 0); if (njs_slow_path(pattern == NULL)) { @@ -245,6 +249,16 @@ njs_builtin_objects_create(njs_vm_t *vm) prototype = njs_shared_prototype(shared, i); *prototype = njs_object_type_init[i]->prototype_value; + if (njs_object_type_init[i] == &njs_boolean_type_init) { + prototype->object_value.value = njs_value(NJS_BOOLEAN, 0, 0.0); + + } else if (njs_object_type_init[i] == &njs_number_type_init) { + prototype->object_value.value = njs_value(NJS_NUMBER, 0, 0.0); + + } else if (njs_object_type_init[i] == &njs_string_type_init) { + njs_set_empty_string(vm, &prototype->object_value.value); + } + ret = njs_object_hash_init(vm, &prototype->object.shared_hash, njs_object_type_init[i]->prototype_props); if (njs_slow_path(ret != NJS_OK)) { @@ -306,10 +320,10 @@ njs_builtin_traverse(njs_vm_t *vm, njs_traverse_t *traverse, void *data) njs_int_t ret, n; njs_str_t name; njs_bool_t symbol; - njs_value_t key, *value; + njs_value_t key, *value, prop_name; njs_function_t *func, *target; njs_object_prop_t *prop; - njs_lvlhsh_query_t lhq; + njs_flathsh_query_t lhq; njs_builtin_traverse_t *ctx; njs_traverse_t *path[NJS_TRAVERSE_MAX_DEPTH]; u_char buf[256]; @@ -356,13 +370,17 @@ njs_builtin_traverse(njs_vm_t *vm, njs_traverse_t *traverse, void *data) do { symbol = 0; - key = path[n]->prop->name; + + ret = njs_atom_to_value(vm, &key, path[n]->atom_id); + if (ret != NJS_OK) { + return NJS_ERROR; + } if (njs_slow_path(njs_is_symbol(&key))) { symbol = 1; key = *njs_symbol_description(&key); if (njs_is_undefined(&key)) { - key = njs_string_empty; + njs_set_empty_string(vm, &key); } } @@ -371,7 +389,7 @@ njs_builtin_traverse(njs_vm_t *vm, njs_traverse_t *traverse, void *data) return NJS_OK; } - njs_string_get(&key, &name); + njs_string_get(vm, &key, &name); if (njs_slow_path((p + name.length + 3) > end)) { njs_type_error(vm, "njs_builtin_traverse() key is too long"); @@ -415,24 +433,23 @@ njs_builtin_traverse(njs_vm_t *vm, njs_traverse_t *traverse, void *data) /* NJS_BUILTIN_TRAVERSE_KEYS. */ - prop = njs_object_prop_alloc(vm, &njs_value_undefined, &njs_value_null, 0); + prop = njs_object_prop_alloc(vm, &njs_value_null, 0); if (njs_slow_path(prop == NULL)) { return NJS_ERROR; } - ret = njs_string_create(vm, &prop->name, buf, p - buf); + ret = njs_atom_string_create(vm, &prop_name, buf, p - buf); 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.key_hash = prop_name.atom_id; lhq.replace = 1; lhq.pool = vm->mem_pool; lhq.proto = &njs_object_hash_proto; - ret = njs_lvlhsh_insert(&ctx->keys, &lhq); + ret = njs_flathsh_unique_insert(&ctx->keys, &lhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "lvlhsh insert/replace failed"); return NJS_ERROR; @@ -503,11 +520,9 @@ njs_builtin_match_native_function(njs_vm_t *vm, njs_function_t *function, for (i = NJS_OBJ_TYPE_HIDDEN_MIN; i < NJS_OBJ_TYPE_HIDDEN_MAX; i++) { njs_set_object(&value, &njs_vm_ctor(vm, i).object); - ret = njs_value_property(vm, &value, njs_value_arg(&njs_string_name), - &tag); - + ret = njs_value_property(vm, &value, NJS_ATOM_STRING_name, &tag); if (ret == NJS_OK && njs_is_string(&tag)) { - njs_string_get(&tag, &ctx.match); + njs_string_get(vm, &tag, &ctx.match); } ret = njs_object_traverse(vm, njs_object(&value), &ctx, @@ -560,7 +575,7 @@ njs_builtin_match_native_function(njs_vm_t *vm, njs_function_t *function, ret = njs_object_string_tag(vm, &value, &tag); if (ret == NJS_OK && njs_is_string(&tag)) { - njs_string_get(&tag, &ctx.match); + njs_string_get(vm, &tag, &ctx.match); } ret = njs_object_traverse(vm, njs_object(&value), &ctx, @@ -651,7 +666,7 @@ njs_ext_on(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return NJS_ERROR; } - njs_string_get(value, &type); + njs_string_get(vm, value, &type); i = 0; n = sizeof(hooks) / sizeof(hooks[0]); @@ -683,19 +698,14 @@ njs_ext_on(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, static njs_int_t -njs_ext_memory_stats(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *unused, njs_value_t *unused2, njs_value_t *retval) +njs_ext_memory_stats(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, + njs_value_t *unused2, njs_value_t *unused3, njs_value_t *retval) { njs_int_t ret; njs_value_t object, value; njs_object_t *stat; njs_mp_stat_t mp_stat; - static const njs_value_t size_string = njs_string("size"); - static const njs_value_t nblocks_string = njs_string("nblocks"); - static const njs_value_t page_string = njs_string("page_size"); - static const njs_value_t cluster_string = njs_string("cluster_size"); - stat = njs_object_alloc(vm); if (njs_slow_path(stat == NULL)) { return NJS_ERROR; @@ -707,23 +717,21 @@ njs_ext_memory_stats(njs_vm_t *vm, njs_object_prop_t *prop, njs_set_number(&value, mp_stat.size); - ret = njs_value_property_set(vm, &object, njs_value_arg(&size_string), - &value); + ret = njs_value_property_set(vm, &object, NJS_ATOM_STRING_size, &value); if (njs_slow_path(ret != NJS_OK)) { return NJS_ERROR; } njs_set_number(&value, mp_stat.nblocks); - ret = njs_value_property_set(vm, &object, njs_value_arg(&nblocks_string), - &value); + ret = njs_value_property_set(vm, &object, NJS_ATOM_STRING_nblocks, &value); if (njs_slow_path(ret != NJS_OK)) { return NJS_ERROR; } njs_set_number(&value, mp_stat.cluster_size); - ret = njs_value_property_set(vm, &object, njs_value_arg(&cluster_string), + ret = njs_value_property_set(vm, &object, NJS_ATOM_STRING_cluster_size, &value); if (njs_slow_path(ret != NJS_OK)) { return NJS_ERROR; @@ -731,8 +739,7 @@ njs_ext_memory_stats(njs_vm_t *vm, njs_object_prop_t *prop, njs_set_number(&value, mp_stat.page_size); - ret = njs_value_property_set(vm, &object, njs_value_arg(&page_string), - &value); + ret = njs_value_property_set(vm, &object, NJS_ATOM_STRING_page_size, &value); if (njs_slow_path(ret != NJS_OK)) { return NJS_ERROR; } @@ -747,32 +754,25 @@ njs_ext_memory_stats(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t njs_global_this_prop_handler(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *global, njs_value_t *setval, njs_value_t *retval) + uint32_t atom_id, njs_value_t *global, njs_value_t *setval, + njs_value_t *retval) { - njs_int_t ret; njs_value_t *value; njs_variable_t *var; njs_function_t *function; njs_rbtree_node_t *rb_node; - njs_lvlhsh_query_t lhq; njs_variable_node_t *node, var_node; if (retval == NULL) { return NJS_DECLINED; } - njs_string_get(&prop->name, &lhq.key); - lhq.key_hash = njs_djb_hash(lhq.key.start, lhq.key.length); - lhq.proto = &njs_lexer_hash_proto; + var_node.key = atom_id; - ret = njs_lvlhsh_find(&vm->shared->keywords_hash, &lhq); - - if (njs_slow_path(ret != NJS_OK || lhq.value == NULL)) { + if (njs_slow_path(vm->global_scope == NULL)) { return NJS_DECLINED; } - var_node.key = (uintptr_t) lhq.value; - rb_node = njs_rbtree_find(&vm->global_scope->variables, &var_node.node); if (rb_node == NULL) { return NJS_DECLINED; @@ -808,12 +808,12 @@ njs_global_this_prop_handler(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t -njs_global_this_object(njs_vm_t *vm, njs_object_prop_t *self, +njs_global_this_object(njs_vm_t *vm, njs_object_prop_t *self, uint32_t atom_id, njs_value_t *global, njs_value_t *setval, njs_value_t *retval) { - njs_int_t ret; - njs_object_prop_t *prop; - njs_lvlhsh_query_t lhq; + njs_int_t ret; + njs_object_prop_t *prop; + njs_flathsh_query_t lhq; if (retval == NULL) { return NJS_DECLINED; @@ -825,7 +825,7 @@ njs_global_this_object(njs_vm_t *vm, njs_object_prop_t *self, njs_value_assign(retval, setval); } - prop = njs_object_prop_alloc(vm, &self->name, retval, 1); + prop = njs_object_prop_alloc(vm, retval, 1); if (njs_slow_path(prop == NULL)) { return NJS_ERROR; } @@ -834,13 +834,12 @@ njs_global_this_object(njs_vm_t *vm, njs_object_prop_t *self, prop->enumerable = self->enumerable; lhq.value = prop; - njs_string_get(&self->name, &lhq.key); - lhq.key_hash = njs_prop_magic32(self); + lhq.key_hash = atom_id; lhq.replace = 1; lhq.pool = vm->mem_pool; lhq.proto = &njs_object_hash_proto; - ret = njs_lvlhsh_insert(njs_object_hash(global), &lhq); + ret = njs_flathsh_unique_insert(njs_object_hash(global), &lhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "lvlhsh insert/replace failed"); return NJS_ERROR; @@ -851,13 +850,13 @@ njs_global_this_object(njs_vm_t *vm, njs_object_prop_t *self, static njs_int_t -njs_top_level_object(njs_vm_t *vm, njs_object_prop_t *self, +njs_top_level_object(njs_vm_t *vm, njs_object_prop_t *self, uint32_t atom_id, njs_value_t *global, njs_value_t *setval, njs_value_t *retval) { - njs_int_t ret; - njs_object_t *object; - njs_object_prop_t *prop; - njs_lvlhsh_query_t lhq; + njs_int_t ret; + njs_object_t *object; + njs_object_prop_t *prop; + njs_flathsh_query_t lhq; if (njs_slow_path(setval != NULL)) { njs_value_assign(retval, setval); @@ -877,7 +876,7 @@ njs_top_level_object(njs_vm_t *vm, njs_object_prop_t *self, object->__proto__ = njs_vm_proto(vm, NJS_OBJ_TYPE_OBJECT); } - prop = njs_object_prop_alloc(vm, &self->name, retval, 1); + prop = njs_object_prop_alloc(vm, retval, 1); if (njs_slow_path(prop == NULL)) { return NJS_ERROR; } @@ -886,13 +885,12 @@ njs_top_level_object(njs_vm_t *vm, njs_object_prop_t *self, prop->enumerable = self->enumerable; lhq.value = prop; - njs_string_get(&self->name, &lhq.key); - lhq.key_hash = njs_prop_magic32(self); + lhq.key_hash = atom_id; lhq.replace = 1; lhq.pool = vm->mem_pool; lhq.proto = &njs_object_hash_proto; - ret = njs_lvlhsh_insert(njs_object_hash(global), &lhq); + ret = njs_flathsh_unique_insert(njs_object_hash(global), &lhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "lvlhsh insert/replace failed"); return NJS_ERROR; @@ -904,12 +902,13 @@ njs_top_level_object(njs_vm_t *vm, njs_object_prop_t *self, static njs_int_t njs_top_level_constructor(njs_vm_t *vm, njs_object_prop_t *self, - njs_value_t *global, njs_value_t *setval, njs_value_t *retval) + uint32_t atom_id, njs_value_t *global, njs_value_t *setval, + njs_value_t *retval) { - njs_int_t ret; - njs_function_t *ctor; - njs_object_prop_t *prop; - njs_lvlhsh_query_t lhq; + njs_int_t ret; + njs_function_t *ctor; + njs_object_prop_t *prop; + njs_flathsh_query_t lhq; if (njs_slow_path(setval != NULL)) { njs_value_assign(retval, setval); @@ -926,7 +925,7 @@ njs_top_level_constructor(njs_vm_t *vm, njs_object_prop_t *self, return NJS_OK; } - prop = njs_object_prop_alloc(vm, &self->name, retval, 1); + prop = njs_object_prop_alloc(vm, retval, 1); if (njs_slow_path(prop == NULL)) { return NJS_ERROR; } @@ -935,13 +934,12 @@ njs_top_level_constructor(njs_vm_t *vm, njs_object_prop_t *self, prop->enumerable = 0; lhq.value = prop; - njs_string_get(&self->name, &lhq.key); - lhq.key_hash = njs_prop_magic32(self); + lhq.key_hash = atom_id; lhq.replace = 1; lhq.pool = vm->mem_pool; lhq.proto = &njs_object_hash_proto; - ret = njs_lvlhsh_insert(njs_object_hash(global), &lhq); + ret = njs_flathsh_unique_insert(njs_object_hash(global), &lhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "lvlhsh insert/replace failed"); return NJS_ERROR; @@ -951,227 +949,205 @@ njs_top_level_constructor(njs_vm_t *vm, njs_object_prop_t *self, } -static const njs_object_prop_t njs_global_this_object_properties[] = +static const njs_object_prop_init_t njs_global_this_object_properties[] = { - { - .type = NJS_PROPERTY, - .name = njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG), - .u.value = njs_string("global"), - .configurable = 1, - }, + NJS_DECLARE_PROP_VALUE(SYMBOL_toStringTag, njs_ascii_strval("global"), + NJS_OBJECT_PROP_VALUE_C), /* Global aliases. */ - NJS_DECLARE_PROP_HANDLER("global", njs_global_this_object, 0, - NJS_GLOBAL_HASH, NJS_OBJECT_PROP_VALUE_ECW), + NJS_DECLARE_PROP_HANDLER(STRING_global, njs_global_this_object, 0, + NJS_OBJECT_PROP_VALUE_ECW), - NJS_DECLARE_PROP_HANDLER("globalThis", njs_global_this_object, 0, - NJS_GLOBAL_THIS_HASH, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_globalThis, njs_global_this_object, 0, + NJS_OBJECT_PROP_VALUE_CW), /* Global constants. */ - NJS_DECLARE_PROP_VALUE("NaN", njs_value(NJS_NUMBER, 0, NAN), 0), + NJS_DECLARE_PROP_VALUE(STRING_NaN, njs_value(NJS_NUMBER, 0, NAN), 0), - NJS_DECLARE_PROP_VALUE("Infinity", njs_value(NJS_NUMBER, 1, INFINITY), 0), + NJS_DECLARE_PROP_VALUE(STRING_Infinity, + njs_value(NJS_NUMBER, 1, INFINITY), 0), - NJS_DECLARE_PROP_VALUE("undefined", njs_value(NJS_UNDEFINED, 0, NAN), 0), + NJS_DECLARE_PROP_VALUE(STRING_undefined, + njs_value(NJS_UNDEFINED, 0, NAN), 0), /* Global functions. */ - NJS_DECLARE_PROP_NATIVE("isFinite", njs_number_global_is_finite, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_isFinite, njs_number_global_is_finite, 1, + 0), - NJS_DECLARE_PROP_NATIVE("isNaN", njs_number_global_is_nan, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_isNaN, njs_number_global_is_nan, 1, 0), - NJS_DECLARE_PROP_NATIVE("parseFloat", njs_number_parse_float, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_parseFloat, njs_number_parse_float, 1, + 0), - NJS_DECLARE_PROP_NATIVE("parseInt", njs_number_parse_int, 2, 0), + NJS_DECLARE_PROP_NATIVE(STRING_parseInt, njs_number_parse_int, 2, 0), - NJS_DECLARE_PROP_NATIVE("toString", njs_object_prototype_to_string, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_toString, njs_object_prototype_to_string, + 0, 0), - NJS_DECLARE_PROP_NATIVE("encodeURI", njs_string_encode_uri, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_encodeURI, njs_string_encode_uri, 1, 0), - NJS_DECLARE_PROP_LNATIVE("encodeURIComponent", njs_string_encode_uri, 1, 1), + NJS_DECLARE_PROP_NATIVE(STRING_encodeURIComponent, + njs_string_encode_uri, 1, 1), - NJS_DECLARE_PROP_NATIVE("decodeURI", njs_string_decode_uri, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_decodeURI, njs_string_decode_uri, 1, 0), - NJS_DECLARE_PROP_LNATIVE("decodeURIComponent", njs_string_decode_uri, 1, 1), + NJS_DECLARE_PROP_NATIVE(STRING_decodeURIComponent, + njs_string_decode_uri, 1, 1), - NJS_DECLARE_PROP_NATIVE("atob", njs_string_atob, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_atob, njs_string_atob, 1, 0), - NJS_DECLARE_PROP_NATIVE("btoa", njs_string_btoa, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_btoa, njs_string_btoa, 1, 0), - NJS_DECLARE_PROP_NATIVE("eval", njs_eval_function, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_eval, njs_eval_function, 1, 0), - NJS_DECLARE_PROP_NATIVE("require", njs_module_require, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_require, njs_module_require, 1, 0), /* Global objects. */ - NJS_DECLARE_PROP_HANDLER("njs", njs_top_level_object, NJS_OBJECT_NJS, - NJS_NJS_HASH, NJS_OBJECT_PROP_VALUE_ECW), + NJS_DECLARE_PROP_HANDLER(STRING_njs, njs_top_level_object, + NJS_OBJECT_NJS, NJS_OBJECT_PROP_VALUE_ECW), - NJS_DECLARE_PROP_HANDLER("process", njs_top_level_object, - NJS_OBJECT_PROCESS, NJS_PROCESS_HASH, - NJS_OBJECT_PROP_VALUE_ECW), + NJS_DECLARE_PROP_HANDLER(STRING_process, njs_top_level_object, + NJS_OBJECT_PROCESS, NJS_OBJECT_PROP_VALUE_ECW), - NJS_DECLARE_PROP_HANDLER("Math", njs_top_level_object, - NJS_OBJECT_MATH, NJS_MATH_HASH, - NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_Math, njs_top_level_object, + NJS_OBJECT_MATH, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("JSON", njs_top_level_object, - NJS_OBJECT_JSON, NJS_JSON_HASH, - NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_JSON, njs_top_level_object, + NJS_OBJECT_JSON, NJS_OBJECT_PROP_VALUE_CW), #ifdef NJS_TEST262 - NJS_DECLARE_PROP_HANDLER("$262", njs_top_level_object, - NJS_OBJECT_262, NJS_262_HASH, - NJS_OBJECT_PROP_VALUE_ECW), + NJS_DECLARE_PROP_HANDLER(STRING__262, njs_top_level_object, + NJS_OBJECT_262, NJS_OBJECT_PROP_VALUE_ECW), #endif /* Global constructors. */ - NJS_DECLARE_PROP_HANDLER("Object", njs_top_level_constructor, - NJS_OBJ_TYPE_OBJECT, NJS_OBJECT_HASH, - NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_Object, njs_top_level_constructor, + NJS_OBJ_TYPE_OBJECT, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("Array", njs_top_level_constructor, - NJS_OBJ_TYPE_ARRAY, NJS_ARRAY_HASH, - NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_Array, njs_top_level_constructor, + NJS_OBJ_TYPE_ARRAY, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("ArrayBuffer", njs_top_level_constructor, - NJS_OBJ_TYPE_ARRAY_BUFFER, NJS_ARRAY_BUFFER_HASH, + NJS_DECLARE_PROP_HANDLER(STRING_ArrayBuffer, njs_top_level_constructor, + NJS_OBJ_TYPE_ARRAY_BUFFER, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("DataView", njs_top_level_constructor, - NJS_OBJ_TYPE_DATA_VIEW, NJS_DATA_VIEW_HASH, + NJS_DECLARE_PROP_HANDLER(STRING_DataView, njs_top_level_constructor, + NJS_OBJ_TYPE_DATA_VIEW, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("TextDecoder", njs_top_level_constructor, - NJS_OBJ_TYPE_TEXT_DECODER, NJS_TEXT_DECODER_HASH, + NJS_DECLARE_PROP_HANDLER(STRING_TextDecoder, njs_top_level_constructor, + NJS_OBJ_TYPE_TEXT_DECODER, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("TextEncoder", njs_top_level_constructor, - NJS_OBJ_TYPE_TEXT_ENCODER, NJS_TEXT_ENCODER_HASH, + NJS_DECLARE_PROP_HANDLER(STRING_TextEncoder, njs_top_level_constructor, + NJS_OBJ_TYPE_TEXT_ENCODER, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("Buffer", njs_top_level_constructor, - NJS_OBJ_TYPE_BUFFER, NJS_BUFFER_HASH, - NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_Buffer, njs_top_level_constructor, + NJS_OBJ_TYPE_BUFFER, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("Uint8Array", njs_top_level_constructor, - NJS_OBJ_TYPE_UINT8_ARRAY, NJS_UINT8ARRAY_HASH, + NJS_DECLARE_PROP_HANDLER(STRING_Uint8Array, njs_top_level_constructor, + NJS_OBJ_TYPE_UINT8_ARRAY, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("Uint16Array", njs_top_level_constructor, - NJS_OBJ_TYPE_UINT16_ARRAY, NJS_UINT16ARRAY_HASH, + NJS_DECLARE_PROP_HANDLER(STRING_Uint16Array, njs_top_level_constructor, + NJS_OBJ_TYPE_UINT16_ARRAY, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("Uint32Array", njs_top_level_constructor, - NJS_OBJ_TYPE_UINT32_ARRAY, NJS_UINT32ARRAY_HASH, + NJS_DECLARE_PROP_HANDLER(STRING_Uint32Array, njs_top_level_constructor, + NJS_OBJ_TYPE_UINT32_ARRAY, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("Int8Array", njs_top_level_constructor, - NJS_OBJ_TYPE_INT8_ARRAY, NJS_INT8ARRAY_HASH, + NJS_DECLARE_PROP_HANDLER(STRING_Int8Array, njs_top_level_constructor, + NJS_OBJ_TYPE_INT8_ARRAY, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("Int16Array", njs_top_level_constructor, - NJS_OBJ_TYPE_INT16_ARRAY, NJS_INT16ARRAY_HASH, + NJS_DECLARE_PROP_HANDLER(STRING_Int16Array, njs_top_level_constructor, + NJS_OBJ_TYPE_INT16_ARRAY, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("Int32Array", njs_top_level_constructor, - NJS_OBJ_TYPE_INT32_ARRAY, NJS_INT32ARRAY_HASH, + NJS_DECLARE_PROP_HANDLER(STRING_Int32Array, njs_top_level_constructor, + NJS_OBJ_TYPE_INT32_ARRAY, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("Float32Array", njs_top_level_constructor, - NJS_OBJ_TYPE_FLOAT32_ARRAY, NJS_FLOAT32ARRAY_HASH, + NJS_DECLARE_PROP_HANDLER(STRING_Float32Array, njs_top_level_constructor, + NJS_OBJ_TYPE_FLOAT32_ARRAY, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("Float64Array", njs_top_level_constructor, - NJS_OBJ_TYPE_FLOAT64_ARRAY, NJS_FLOAT64ARRAY_HASH, + NJS_DECLARE_PROP_HANDLER(STRING_Float64Array, njs_top_level_constructor, + NJS_OBJ_TYPE_FLOAT64_ARRAY, NJS_OBJECT_PROP_VALUE_CW), - { - .type = NJS_PROPERTY_HANDLER, - .name = njs_long_string("Uint8ClampedArray"), - .u.value = njs_prop_handler2(njs_top_level_constructor, - NJS_OBJ_TYPE_UINT8_CLAMPED_ARRAY, - NJS_UINT8CLAMPEDARRAY_HASH), - .writable = 1, - .configurable = 1, - }, - - NJS_DECLARE_PROP_HANDLER("Boolean", njs_top_level_constructor, - NJS_OBJ_TYPE_BOOLEAN, NJS_BOOLEAN_HASH, + NJS_DECLARE_PROP_HANDLER(STRING_Uint8ClampedArray, + njs_top_level_constructor, + NJS_OBJ_TYPE_UINT8_CLAMPED_ARRAY, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("Number", njs_top_level_constructor, - NJS_OBJ_TYPE_NUMBER, NJS_NUMBER_HASH, - NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_Boolean, njs_top_level_constructor, + NJS_OBJ_TYPE_BOOLEAN, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("Symbol", njs_top_level_constructor, - NJS_OBJ_TYPE_SYMBOL, NJS_SYMBOL_HASH, - NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_Number, njs_top_level_constructor, + NJS_OBJ_TYPE_NUMBER, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("String", njs_top_level_constructor, - NJS_OBJ_TYPE_STRING, NJS_STRING_HASH, - NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_Symbol, njs_top_level_constructor, + NJS_OBJ_TYPE_SYMBOL, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("Function", njs_top_level_constructor, - NJS_OBJ_TYPE_FUNCTION, NJS_FUNCTION_HASH, - NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_String, njs_top_level_constructor, + NJS_OBJ_TYPE_STRING, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("RegExp", njs_top_level_constructor, - NJS_OBJ_TYPE_REGEXP, NJS_REGEXP_HASH, - NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_Function, njs_top_level_constructor, + NJS_OBJ_TYPE_FUNCTION, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("Date", njs_top_level_constructor, - NJS_OBJ_TYPE_DATE, NJS_DATE_HASH, - NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_RegExp, njs_top_level_constructor, + NJS_OBJ_TYPE_REGEXP, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("Promise", njs_top_level_constructor, - NJS_OBJ_TYPE_PROMISE, NJS_PROMISE_HASH, - NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_Date, njs_top_level_constructor, + NJS_OBJ_TYPE_DATE, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("Error", njs_top_level_constructor, - NJS_OBJ_TYPE_ERROR, NJS_ERROR_HASH, - NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_Promise, njs_top_level_constructor, + NJS_OBJ_TYPE_PROMISE, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("EvalError", njs_top_level_constructor, - NJS_OBJ_TYPE_EVAL_ERROR, NJS_EVAL_ERROR_HASH, - NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_Error, njs_top_level_constructor, + NJS_OBJ_TYPE_ERROR, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("InternalError", njs_top_level_constructor, + NJS_DECLARE_PROP_HANDLER(STRING_EvalError, njs_top_level_constructor, + NJS_OBJ_TYPE_EVAL_ERROR, NJS_OBJECT_PROP_VALUE_CW), + + NJS_DECLARE_PROP_HANDLER(STRING_InternalError, + njs_top_level_constructor, NJS_OBJ_TYPE_INTERNAL_ERROR, - NJS_INTERNAL_ERROR_HASH, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("RangeError", njs_top_level_constructor, - NJS_OBJ_TYPE_RANGE_ERROR, NJS_RANGE_ERROR_HASH, + NJS_DECLARE_PROP_HANDLER(STRING_RangeError, njs_top_level_constructor, + NJS_OBJ_TYPE_RANGE_ERROR, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("ReferenceError", njs_top_level_constructor, - NJS_OBJ_TYPE_REF_ERROR, NJS_REF_ERROR_HASH, - NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_ReferenceError, + njs_top_level_constructor, + NJS_OBJ_TYPE_REF_ERROR, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("SyntaxError", njs_top_level_constructor, - NJS_OBJ_TYPE_SYNTAX_ERROR, NJS_SYNTAX_ERROR_HASH, + NJS_DECLARE_PROP_HANDLER(STRING_SyntaxError, njs_top_level_constructor, + NJS_OBJ_TYPE_SYNTAX_ERROR, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("TypeError", njs_top_level_constructor, - NJS_OBJ_TYPE_TYPE_ERROR, NJS_TYPE_ERROR_HASH, - NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_TypeError, njs_top_level_constructor, + NJS_OBJ_TYPE_TYPE_ERROR, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("URIError", njs_top_level_constructor, - NJS_OBJ_TYPE_URI_ERROR, NJS_URI_ERROR_HASH, - NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_URIError, njs_top_level_constructor, + NJS_OBJ_TYPE_URI_ERROR, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("MemoryError", njs_top_level_constructor, - NJS_OBJ_TYPE_MEMORY_ERROR, NJS_MEMORY_ERROR_HASH, + NJS_DECLARE_PROP_HANDLER(STRING_MemoryError, njs_top_level_constructor, + NJS_OBJ_TYPE_MEMORY_ERROR, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("AggregateError", njs_top_level_constructor, + NJS_DECLARE_PROP_HANDLER(STRING_AggregateError, njs_top_level_constructor, NJS_OBJ_TYPE_AGGREGATE_ERROR, - NJS_AGGREGATE_ERROR_HASH, NJS_OBJECT_PROP_VALUE_CW), }; @@ -1182,30 +1158,26 @@ static const njs_object_init_t njs_global_this_init = { }; -static const njs_object_prop_t njs_njs_object_properties[] = +static const njs_object_prop_init_t njs_njs_object_properties[] = { - { - .type = NJS_PROPERTY, - .name = njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG), - .u.value = njs_string("njs"), - .configurable = 1, - }, - - NJS_DECLARE_PROP_VALUE("engine", njs_string("njs"), + NJS_DECLARE_PROP_VALUE(SYMBOL_toStringTag, njs_ascii_strval("njs"), + NJS_OBJECT_PROP_VALUE_C), + + NJS_DECLARE_PROP_VALUE(STRING_engine, njs_ascii_strval("njs"), NJS_OBJECT_PROP_VALUE_EC), - NJS_DECLARE_PROP_VALUE("version", njs_string(NJS_VERSION), + NJS_DECLARE_PROP_VALUE(STRING_version, njs_ascii_strval(NJS_VERSION), NJS_OBJECT_PROP_VALUE_EC), - NJS_DECLARE_PROP_VALUE("version_number", + NJS_DECLARE_PROP_VALUE(STRING_version_number, njs_value(NJS_NUMBER, 1, NJS_VERSION_NUMBER), NJS_OBJECT_PROP_VALUE_EC), - NJS_DECLARE_PROP_NATIVE("dump", njs_ext_dump, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_dump, njs_ext_dump, 0, 0), - NJS_DECLARE_PROP_NATIVE("on", njs_ext_on, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_on, njs_ext_on, 0, 0), - NJS_DECLARE_PROP_HANDLER("memoryStats", njs_ext_memory_stats, 0, 0, + NJS_DECLARE_PROP_HANDLER(STRING_memoryStats, njs_ext_memory_stats, 0, NJS_OBJECT_PROP_VALUE_EC), }; @@ -1218,17 +1190,15 @@ static const njs_object_init_t njs_njs_object_init = { static njs_int_t -njs_process_object_argv(njs_vm_t *vm, njs_object_prop_t *pr, - njs_value_t *process, njs_value_t *unused, njs_value_t *retval) +njs_process_object_argv(njs_vm_t *vm, njs_object_prop_t *pr, uint32_t unused, + njs_value_t *process, njs_value_t *unused2, njs_value_t *retval) { - char **arg; - njs_int_t ret; - njs_uint_t i; - njs_array_t *argv; - njs_object_prop_t *prop; - njs_lvlhsh_query_t lhq; - - static const njs_value_t argv_string = njs_string("argv"); + char **arg; + njs_int_t ret; + njs_uint_t i; + njs_array_t *argv; + njs_object_prop_t *prop; + njs_flathsh_query_t lhq; argv = njs_array_alloc(vm, 1, vm->options.argc, 0); if (njs_slow_path(argv == NULL)) { @@ -1238,11 +1208,14 @@ njs_process_object_argv(njs_vm_t *vm, njs_object_prop_t *pr, i = 0; for (arg = vm->options.argv; i < vm->options.argc; arg++) { - njs_string_create(vm, &argv->start[i++], (u_char *) *arg, - njs_strlen(*arg)); + ret = njs_string_create(vm, &argv->start[i++], (u_char *) *arg, + njs_strlen(*arg)); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_ERROR; + } } - prop = njs_object_prop_alloc(vm, &argv_string, &njs_value_undefined, 1); + prop = njs_object_prop_alloc(vm, &njs_value_undefined, 1); if (njs_slow_path(prop == NULL)) { return NJS_ERROR; } @@ -1250,14 +1223,12 @@ njs_process_object_argv(njs_vm_t *vm, njs_object_prop_t *pr, njs_set_array(njs_prop_value(prop), argv); lhq.value = prop; - lhq.key_hash = NJS_ARGV_HASH; - lhq.key = njs_str_value("argv"); + lhq.key_hash = NJS_ATOM_STRING_argv; lhq.replace = 1; lhq.pool = vm->mem_pool; lhq.proto = &njs_object_hash_proto; - ret = njs_lvlhsh_insert(njs_object_hash(process), &lhq); - + ret = njs_flathsh_unique_insert(njs_object_hash(process), &lhq); if (njs_fast_path(ret == NJS_OK)) { njs_value_assign(retval, njs_prop_value(prop)); return NJS_OK; @@ -1270,17 +1241,18 @@ njs_process_object_argv(njs_vm_t *vm, njs_object_prop_t *pr, static njs_int_t -njs_env_hash_init(njs_vm_t *vm, njs_lvlhsh_t *hash, char **environment) +njs_env_hash_init(njs_vm_t *vm, njs_flathsh_t *hash, char **environment) { - char **ep; - u_char *dst; - ssize_t length; - uint32_t cp; - njs_int_t ret; - const u_char *val, *entry, *s, *end; - njs_object_prop_t *prop; - njs_string_prop_t string; - njs_lvlhsh_query_t lhq; + char **ep; + u_char *dst; + ssize_t length; + uint32_t cp; + njs_int_t ret; + njs_value_t prop_name; + const u_char *val, *entry, *s, *end; + njs_object_prop_t *prop; + njs_string_prop_t string; + njs_flathsh_query_t lhq; lhq.replace = 0; lhq.pool = vm->mem_pool; @@ -1289,8 +1261,7 @@ njs_env_hash_init(njs_vm_t *vm, njs_lvlhsh_t *hash, char **environment) ep = environment; while (*ep != NULL) { - prop = njs_object_prop_alloc(vm, &njs_value_undefined, - &njs_value_undefined, 1); + prop = njs_object_prop_alloc(vm, &njs_value_undefined, 1); if (njs_slow_path(prop == NULL)) { return NJS_ERROR; } @@ -1302,12 +1273,12 @@ njs_env_hash_init(njs_vm_t *vm, njs_lvlhsh_t *hash, char **environment) continue; } - ret = njs_string_create(vm, &prop->name, entry, val - entry); + ret = njs_string_create(vm, &prop_name, entry, val - entry); if (njs_slow_path(ret != NJS_OK)) { return NJS_ERROR; } - (void) njs_string_prop(&string, &prop->name); + (void) njs_string_prop(vm, &string, &prop_name); length = string.length; s = string.start; @@ -1327,11 +1298,15 @@ njs_env_hash_init(njs_vm_t *vm, njs_lvlhsh_t *hash, char **environment) return NJS_ERROR; } + ret = njs_atom_atomize_key(vm, &prop_name); + if (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.key_hash = prop_name.atom_id; - ret = njs_lvlhsh_insert(hash, &lhq); + ret = njs_flathsh_unique_insert(hash, &lhq); if (njs_slow_path(ret != NJS_OK)) { if (ret == NJS_ERROR) { njs_internal_error(vm, "lvlhsh insert failed"); @@ -1352,15 +1327,13 @@ njs_env_hash_init(njs_vm_t *vm, njs_lvlhsh_t *hash, char **environment) static njs_int_t -njs_process_object_env(njs_vm_t *vm, njs_object_prop_t *pr, - njs_value_t *process, njs_value_t *unused, njs_value_t *retval) +njs_process_object_env(njs_vm_t *vm, njs_object_prop_t *pr, uint32_t unused, + njs_value_t *process, njs_value_t *unused2, njs_value_t *retval) { - njs_int_t ret; - njs_object_t *env; - njs_object_prop_t *prop; - njs_lvlhsh_query_t lhq; - - static const njs_value_t env_string = njs_string("env"); + njs_int_t ret; + njs_object_t *env; + njs_object_prop_t *prop; + njs_flathsh_query_t lhq; env = njs_object_alloc(vm); if (njs_slow_path(env == NULL)) { @@ -1369,7 +1342,7 @@ njs_process_object_env(njs_vm_t *vm, njs_object_prop_t *pr, env->shared_hash = vm->shared->env_hash; - prop = njs_object_prop_alloc(vm, &env_string, &njs_value_undefined, 1); + prop = njs_object_prop_alloc(vm, &njs_value_undefined, 1); if (njs_slow_path(prop == NULL)) { return NJS_ERROR; } @@ -1380,11 +1353,9 @@ njs_process_object_env(njs_vm_t *vm, njs_object_prop_t *pr, lhq.pool = vm->mem_pool; lhq.proto = &njs_object_hash_proto; lhq.value = prop; - lhq.key = njs_str_value("env"); - lhq.key_hash = NJS_ENV_HASH; - - ret = njs_lvlhsh_insert(njs_object_hash(process), &lhq); + lhq.key_hash = NJS_ATOM_STRING_env; + ret = njs_flathsh_unique_insert(njs_object_hash(process), &lhq); if (njs_fast_path(ret == NJS_OK)) { njs_value_assign(retval, njs_prop_value(prop)); return NJS_OK; @@ -1397,8 +1368,8 @@ njs_process_object_env(njs_vm_t *vm, njs_object_prop_t *pr, static njs_int_t -njs_process_object_pid(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *unused, njs_value_t *unused2, njs_value_t *retval) +njs_process_object_pid(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, + njs_value_t *unused2, njs_value_t *unused3, njs_value_t *retval) { njs_set_number(retval, getpid()); @@ -1407,8 +1378,8 @@ njs_process_object_pid(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t -njs_process_object_ppid(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *unused, njs_value_t *unused2, njs_value_t *retval) +njs_process_object_ppid(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, + njs_value_t *unused2, njs_value_t *unused3, njs_value_t *retval) { njs_set_number(retval, getppid()); @@ -1420,11 +1391,11 @@ static njs_int_t njs_ext_process_kill(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t magic, njs_value_t *retval) { - int signal; - njs_str_t str; - njs_uint_t pid; - njs_value_t *arg; - njs_signal_entry_t *s; + int signal; + njs_str_t str; + njs_uint_t pid; + njs_value_t *arg; + const njs_signal_entry_t *s; arg = njs_arg(args, nargs, 1); if (!njs_value_is_number(arg)) { @@ -1440,7 +1411,7 @@ njs_ext_process_kill(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, signal = njs_value_number(arg); } else if (njs_value_is_string(arg)) { - njs_value_string_get(arg, &str); + njs_string_get(vm, arg, &str); if (str.length < 3 || memcmp(str.start, "SIG", 3) != 0) { njs_vm_type_error(vm, "\"signal\" unknown value: \"%V\"", &str); @@ -1477,24 +1448,20 @@ njs_ext_process_kill(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } -static const njs_object_prop_t njs_process_object_properties[] = +static const njs_object_prop_init_t njs_process_object_properties[] = { - { - .type = NJS_PROPERTY, - .name = njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG), - .u.value = njs_string("process"), - .configurable = 1, - }, + NJS_DECLARE_PROP_VALUE(SYMBOL_toStringTag, njs_ascii_strval("process"), + NJS_OBJECT_PROP_VALUE_C), - NJS_DECLARE_PROP_HANDLER("argv", njs_process_object_argv, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_argv, njs_process_object_argv, 0, 0), - NJS_DECLARE_PROP_HANDLER("env", njs_process_object_env, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_env, njs_process_object_env, 0, 0), - NJS_DECLARE_PROP_HANDLER("pid", njs_process_object_pid, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_pid, njs_process_object_pid, 0, 0), - NJS_DECLARE_PROP_HANDLER("ppid", njs_process_object_ppid, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_ppid, njs_process_object_ppid, 0, 0), - NJS_DECLARE_PROP_NATIVE("kill", njs_ext_process_kill, 2, 0), + NJS_DECLARE_PROP_NATIVE(STRING_kill, njs_ext_process_kill, 2, 0), }; diff --git a/src/njs_date.c b/src/njs_date.c index cd10abd5..2832abbd 100644 --- a/src/njs_date.c +++ b/src/njs_date.c @@ -52,7 +52,7 @@ typedef enum { } njs_date_fmt_t; -static double njs_date_string_parse(njs_value_t *date); +static double njs_date_string_parse(njs_vm_t *vm, njs_value_t *date); static double njs_date_rfc2822_string_parse(int64_t tm[], const u_char *p, const u_char *end); static double njs_date_js_string_parse(int64_t tm[], const u_char *p, @@ -69,9 +69,6 @@ static njs_int_t njs_date_string(njs_vm_t *vm, njs_value_t *retval, njs_date_fmt_t fmt, double time); -static const njs_value_t njs_string_invalid_date = njs_string("Invalid Date"); - - njs_inline int64_t njs_mod(int64_t a, int64_t b) { @@ -425,7 +422,7 @@ njs_date_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, time = njs_date(&args[1])->time; } else if (njs_is_string(&args[1])) { - time = njs_date_string_parse(&args[1]); + time = njs_date_string_parse(vm, &args[1]); } else { time = njs_timeclip(njs_number(&args[1])); @@ -502,7 +499,7 @@ njs_date_parse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } } - time = njs_date_string_parse(&args[1]); + time = njs_date_string_parse(vm, &args[1]); } else { time = NAN; @@ -548,7 +545,7 @@ njs_date_utc_offset_parse(const u_char *start, const u_char *end) } static double -njs_date_string_parse(njs_value_t *date) +njs_date_string_parse(njs_vm_t *vm, njs_value_t *date) { size_t ms_length; int64_t ext, utc_off; @@ -557,7 +554,7 @@ njs_date_string_parse(njs_value_t *date) const u_char *p, *next, *end; int64_t tm[NJS_DATE_MAX_FIELDS]; - njs_string_get(date, &string); + njs_string_get(vm, date, &string); p = string.start; end = p + string.length; @@ -1127,19 +1124,20 @@ njs_date_number_parse(int64_t *value, const u_char *p, const u_char *end, } -static const njs_object_prop_t njs_date_constructor_properties[] = +static const njs_object_prop_init_t njs_date_constructor_properties[] = { NJS_DECLARE_PROP_LENGTH(7), NJS_DECLARE_PROP_NAME("Date"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), - NJS_DECLARE_PROP_NATIVE("UTC", njs_date_utc, 7, 0), + NJS_DECLARE_PROP_NATIVE(STRING_UTC, njs_date_utc, 7, 0), - NJS_DECLARE_PROP_NATIVE("now", njs_date_now, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_now, njs_date_now, 0, 0), - NJS_DECLARE_PROP_NATIVE("parse", njs_date_parse, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_parse, njs_date_parse, 1, 0), }; @@ -1206,7 +1204,7 @@ njs_date_string(njs_vm_t *vm, njs_value_t *retval, njs_date_fmt_t fmt, "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; if (njs_slow_path(isnan(time))) { - *retval = njs_string_invalid_date; + njs_atom_to_value(vm, retval, NJS_ATOM_STRING_Invalid_Date); return NJS_OK; } @@ -1443,14 +1441,13 @@ static njs_int_t njs_date_prototype_to_json(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval) { - njs_int_t ret; - njs_value_t value; - njs_lvlhsh_query_t lhq; - - static const njs_value_t to_iso_string = njs_string("toISOString"); + njs_int_t ret; + njs_value_t value; + njs_flathsh_query_t lhq; if (njs_is_object(njs_argument(args, 0))) { - njs_object_property_init(&lhq, &to_iso_string, NJS_TO_ISO_STRING_HASH); + lhq.proto = &njs_object_hash_proto; + lhq.key_hash = NJS_ATOM_STRING_toISOString; ret = njs_object_property(vm, njs_object(njs_argument(args, 0)), &lhq, &value); @@ -1471,171 +1468,179 @@ njs_date_prototype_to_json(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } -static const njs_object_prop_t njs_date_prototype_properties[] = +static const njs_object_prop_init_t njs_date_prototype_properties[] = { - NJS_DECLARE_PROP_HANDLER("__proto__", njs_primitive_prototype_get_proto, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING___proto__, + njs_primitive_prototype_get_proto, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_NATIVE("valueOf", njs_date_prototype_value_of, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_valueOf, njs_date_prototype_value_of, 0, + 0), - NJS_DECLARE_PROP_NATIVE("toString", njs_date_prototype_to_string, 0, - NJS_DATE_FMT_TO_STRING), + NJS_DECLARE_PROP_NATIVE(STRING_toString, njs_date_prototype_to_string, + 0, NJS_DATE_FMT_TO_STRING), - NJS_DECLARE_PROP_NATIVE("toDateString", njs_date_prototype_to_string, 0, + NJS_DECLARE_PROP_NATIVE(STRING_toDateString, + njs_date_prototype_to_string, 0, NJS_DATE_FMT_TO_DATE_STRING), - NJS_DECLARE_PROP_NATIVE("toTimeString", njs_date_prototype_to_string, 0, + NJS_DECLARE_PROP_NATIVE(STRING_toTimeString, + njs_date_prototype_to_string, 0, NJS_DATE_FMT_TO_TIME_STRING), - NJS_DECLARE_PROP_NATIVE("toLocaleString", njs_date_prototype_to_string, 0, + NJS_DECLARE_PROP_NATIVE(STRING_toLocaleString, + njs_date_prototype_to_string, 0, NJS_DATE_FMT_TO_STRING), - NJS_DECLARE_PROP_LNATIVE("toLocaleDateString", - njs_date_prototype_to_string, 0, - NJS_DATE_FMT_TO_DATE_STRING), + NJS_DECLARE_PROP_NATIVE(STRING_toLocaleDateString, + njs_date_prototype_to_string, 0, + NJS_DATE_FMT_TO_DATE_STRING), - NJS_DECLARE_PROP_LNATIVE("toLocaleTimeString", - njs_date_prototype_to_string, 0, - NJS_DATE_FMT_TO_TIME_STRING), + NJS_DECLARE_PROP_NATIVE(STRING_toLocaleTimeString, + njs_date_prototype_to_string, 0, + NJS_DATE_FMT_TO_TIME_STRING), - NJS_DECLARE_PROP_NATIVE("toUTCString", + NJS_DECLARE_PROP_NATIVE(STRING_toUTCString, njs_date_prototype_to_string, 0, NJS_DATE_FMT_TO_UTC_STRING), - NJS_DECLARE_PROP_NATIVE("toISOString", + NJS_DECLARE_PROP_NATIVE(STRING_toISOString, njs_date_prototype_to_string, 0, NJS_DATE_FMT_TO_ISO_STRING), - NJS_DECLARE_PROP_NATIVE("toJSON", njs_date_prototype_to_json, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_toJSON, njs_date_prototype_to_json, 1, + 0), - NJS_DECLARE_PROP_NATIVE("getTime", njs_date_prototype_value_of, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_getTime, njs_date_prototype_value_of, 0, + 0), - NJS_DECLARE_PROP_NATIVE("getFullYear", + NJS_DECLARE_PROP_NATIVE(STRING_getFullYear, njs_date_prototype_get_field, 0, njs_date_magic(NJS_DATE_YR, 1)), - NJS_DECLARE_PROP_NATIVE("getUTCFullYear", + NJS_DECLARE_PROP_NATIVE(STRING_getUTCFullYear, njs_date_prototype_get_field, 0, njs_date_magic(NJS_DATE_YR, 0)), - NJS_DECLARE_PROP_NATIVE("getMonth", + NJS_DECLARE_PROP_NATIVE(STRING_getMonth, njs_date_prototype_get_field, 0, njs_date_magic(NJS_DATE_MON, 1)), - NJS_DECLARE_PROP_NATIVE("getUTCMonth", + NJS_DECLARE_PROP_NATIVE(STRING_getUTCMonth, njs_date_prototype_get_field, 0, njs_date_magic(NJS_DATE_MON, 0)), - NJS_DECLARE_PROP_NATIVE("getDate", + NJS_DECLARE_PROP_NATIVE(STRING_getDate, njs_date_prototype_get_field, 0, njs_date_magic(NJS_DATE_DAY, 1)), - NJS_DECLARE_PROP_NATIVE("getUTCDate", + NJS_DECLARE_PROP_NATIVE(STRING_getUTCDate, njs_date_prototype_get_field, 0, njs_date_magic(NJS_DATE_DAY, 0)), - NJS_DECLARE_PROP_NATIVE("getDay", + NJS_DECLARE_PROP_NATIVE(STRING_getDay, njs_date_prototype_get_field, 0, njs_date_magic(NJS_DATE_WDAY, 1)), - NJS_DECLARE_PROP_NATIVE("getUTCDay", + NJS_DECLARE_PROP_NATIVE(STRING_getUTCDay, njs_date_prototype_get_field, 0, njs_date_magic(NJS_DATE_WDAY, 0)), - NJS_DECLARE_PROP_NATIVE("getHours", + NJS_DECLARE_PROP_NATIVE(STRING_getHours, njs_date_prototype_get_field, 0, njs_date_magic(NJS_DATE_HR, 1)), - NJS_DECLARE_PROP_NATIVE("getUTCHours", + NJS_DECLARE_PROP_NATIVE(STRING_getUTCHours, njs_date_prototype_get_field, 0, njs_date_magic(NJS_DATE_HR, 0)), - NJS_DECLARE_PROP_NATIVE("getMinutes", + NJS_DECLARE_PROP_NATIVE(STRING_getMinutes, njs_date_prototype_get_field, 0, njs_date_magic(NJS_DATE_MIN, 1)), - NJS_DECLARE_PROP_NATIVE("getUTCMinutes", + NJS_DECLARE_PROP_NATIVE(STRING_getUTCMinutes, njs_date_prototype_get_field, 0, njs_date_magic(NJS_DATE_MIN, 0)), - NJS_DECLARE_PROP_NATIVE("getSeconds", + NJS_DECLARE_PROP_NATIVE(STRING_getSeconds, njs_date_prototype_get_field, 0, njs_date_magic(NJS_DATE_SEC, 1)), - NJS_DECLARE_PROP_NATIVE("getUTCSeconds", + NJS_DECLARE_PROP_NATIVE(STRING_getUTCSeconds, njs_date_prototype_get_field, 0, njs_date_magic(NJS_DATE_SEC, 0)), - NJS_DECLARE_PROP_LNATIVE("getMilliseconds", - njs_date_prototype_get_field, 0, - njs_date_magic(NJS_DATE_MSEC, 1)), + NJS_DECLARE_PROP_NATIVE(STRING_getMilliseconds, + njs_date_prototype_get_field, 0, + njs_date_magic(NJS_DATE_MSEC, 1)), - NJS_DECLARE_PROP_LNATIVE("getUTCMilliseconds", - njs_date_prototype_get_field, 0, - njs_date_magic(NJS_DATE_MSEC, 0)), + NJS_DECLARE_PROP_NATIVE(STRING_getUTCMilliseconds, + njs_date_prototype_get_field, 0, + njs_date_magic(NJS_DATE_MSEC, 0)), - NJS_DECLARE_PROP_LNATIVE("getTimezoneOffset", - njs_date_prototype_get_timezone_offset, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_getTimezoneOffset, + njs_date_prototype_get_timezone_offset, 0, 0), - NJS_DECLARE_PROP_NATIVE("setTime", njs_date_prototype_set_time, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_setTime, njs_date_prototype_set_time, 1, + 0), - NJS_DECLARE_PROP_LNATIVE("setMilliseconds", - njs_date_prototype_set_fields, 1, - njs_date_magic2(NJS_DATE_MSEC, 1, 1)), + NJS_DECLARE_PROP_NATIVE(STRING_setMilliseconds, + njs_date_prototype_set_fields, 1, + njs_date_magic2(NJS_DATE_MSEC, 1, 1)), - NJS_DECLARE_PROP_LNATIVE("setUTCMilliseconds", - njs_date_prototype_set_fields, 1, - njs_date_magic2(NJS_DATE_MSEC, 1, 0)), + NJS_DECLARE_PROP_NATIVE(STRING_setUTCMilliseconds, + njs_date_prototype_set_fields, 1, + njs_date_magic2(NJS_DATE_MSEC, 1, 0)), - NJS_DECLARE_PROP_NATIVE("setSeconds", + NJS_DECLARE_PROP_NATIVE(STRING_setSeconds, njs_date_prototype_set_fields, 2, njs_date_magic2(NJS_DATE_SEC, 2, 1)), - NJS_DECLARE_PROP_NATIVE("setUTCSeconds", + NJS_DECLARE_PROP_NATIVE(STRING_setUTCSeconds, njs_date_prototype_set_fields, 2, njs_date_magic2(NJS_DATE_SEC, 2, 0)), - NJS_DECLARE_PROP_NATIVE("setMinutes", + NJS_DECLARE_PROP_NATIVE(STRING_setMinutes, njs_date_prototype_set_fields, 3, njs_date_magic2(NJS_DATE_MIN, 3, 1)), - NJS_DECLARE_PROP_NATIVE("setUTCMinutes", + NJS_DECLARE_PROP_NATIVE(STRING_setUTCMinutes, njs_date_prototype_set_fields, 3, njs_date_magic2(NJS_DATE_MIN, 3, 0)), - NJS_DECLARE_PROP_NATIVE("setHours", + NJS_DECLARE_PROP_NATIVE(STRING_setHours, njs_date_prototype_set_fields, 4, njs_date_magic2(NJS_DATE_HR, 4, 1)), - NJS_DECLARE_PROP_NATIVE("setUTCHours", + NJS_DECLARE_PROP_NATIVE(STRING_setUTCHours, njs_date_prototype_set_fields, 4, njs_date_magic2(NJS_DATE_HR, 4, 0)), - NJS_DECLARE_PROP_NATIVE("setDate", + NJS_DECLARE_PROP_NATIVE(STRING_setDate, njs_date_prototype_set_fields, 1, njs_date_magic2(NJS_DATE_DAY, 1, 1)), - NJS_DECLARE_PROP_NATIVE("setUTCDate", + NJS_DECLARE_PROP_NATIVE(STRING_setUTCDate, njs_date_prototype_set_fields, 1, njs_date_magic2(NJS_DATE_DAY, 1, 0)), - NJS_DECLARE_PROP_NATIVE("setMonth", + NJS_DECLARE_PROP_NATIVE(STRING_setMonth, njs_date_prototype_set_fields, 2, njs_date_magic2(NJS_DATE_MON, 2, 1)), - NJS_DECLARE_PROP_NATIVE("setUTCMonth", + NJS_DECLARE_PROP_NATIVE(STRING_setUTCMonth, njs_date_prototype_set_fields, 2, njs_date_magic2(NJS_DATE_MON, 2, 0)), - NJS_DECLARE_PROP_NATIVE("setFullYear", + NJS_DECLARE_PROP_NATIVE(STRING_setFullYear, njs_date_prototype_set_fields, 3, njs_date_magic2(NJS_DATE_YR, 3, 1)), - NJS_DECLARE_PROP_NATIVE("setUTCFullYear", + NJS_DECLARE_PROP_NATIVE(STRING_setUTCFullYear, njs_date_prototype_set_fields, 3, njs_date_magic2(NJS_DATE_YR, 3, 0)), }; diff --git a/src/njs_encoding.c b/src/njs_encoding.c index f70c084d..37bdecf3 100644 --- a/src/njs_encoding.c +++ b/src/njs_encoding.c @@ -100,7 +100,7 @@ njs_text_encoder_encode(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } } - (void) njs_string_prop(&prop, input); + (void) njs_string_prop(vm, &prop, input); if (prop.length != 0) { return njs_text_encoder_encode_utf8(vm, &prop, retval); @@ -164,13 +164,11 @@ njs_text_encoder_encode_into(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_int_t ret; njs_str_t str; njs_value_t *this, *input, *dest, value, read, written; + njs_object_t *object; const u_char *start, *end; njs_typed_array_t *array; njs_unicode_decode_t ctx; - static const njs_value_t read_str = njs_string("read"); - static const njs_value_t written_str = njs_string("written"); - this = njs_argument(args, 0); input = njs_arg(args, nargs, 1); dest = njs_arg(args, nargs, 2); @@ -195,7 +193,7 @@ njs_text_encoder_encode_into(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return NJS_ERROR; } - njs_string_get(input, &str); + njs_string_get(vm, input, &str); start = str.start; end = start + str.length; @@ -228,22 +226,41 @@ njs_text_encoder_encode_into(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, to = njs_utf8_encode(to, cp); } - return njs_vm_object_alloc(vm, retval, &read_str, &read, - &written_str, &written, NULL); + object = njs_object_alloc(vm); + if (njs_slow_path(object == NULL)) { + return NJS_ERROR; + } + + njs_set_object(retval, object); + + ret = njs_object_prop_define(vm, retval, NJS_ATOM_STRING_read, &read, + NJS_OBJECT_PROP_VALUE_CW); + if (njs_slow_path(ret != NJS_OK)) { + return ret; + } + + ret = njs_object_prop_define(vm, retval, NJS_ATOM_STRING_written, &written, + NJS_OBJECT_PROP_VALUE_CW); + if (njs_slow_path(ret != NJS_OK)) { + return ret; + } + + return NJS_OK; } -static const njs_object_prop_t njs_text_encoder_properties[] = +static const njs_object_prop_init_t njs_text_encoder_properties[] = { - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_VALUE("encoding", njs_string("utf-8"), 0), + NJS_DECLARE_PROP_VALUE(STRING_encoding, njs_ascii_strval("utf-8"), 0), - NJS_DECLARE_PROP_NATIVE("encode", njs_text_encoder_encode, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_encode, njs_text_encoder_encode, 0, 0), - NJS_DECLARE_PROP_NATIVE("encodeInto", njs_text_encoder_encode_into, 2, 0), + NJS_DECLARE_PROP_NATIVE(STRING_encodeInto, njs_text_encoder_encode_into, + 2, 0), }; @@ -253,13 +270,14 @@ const njs_object_init_t njs_text_encoder_init = { }; -static const njs_object_prop_t njs_text_encoder_constructor_properties[] = +static const njs_object_prop_init_t njs_text_encoder_constructor_properties[] = { NJS_DECLARE_PROP_LENGTH(0), NJS_DECLARE_PROP_NAME("TextEncoder"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), }; @@ -341,7 +359,7 @@ njs_text_decoder_arg_encoding(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } } - njs_string_get(value, &str); + njs_string_get(vm, value, &str); for (label = &njs_encoding_labels[0]; label->name.length != 0; label++) { if (njs_strstr_eq(&str, &label->name)) { @@ -363,9 +381,6 @@ njs_text_decoder_arg_options(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_int_t ret; njs_value_t retval, *value; - static const njs_value_t fatal_str = njs_string("fatal"); - static const njs_value_t ignore_bom_str = njs_string("ignoreBOM"); - if (nargs < 3) { data->fatal = 0; data->ignore_bom = 0; @@ -380,15 +395,14 @@ njs_text_decoder_arg_options(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return NJS_ERROR; } - ret = njs_value_property(vm, value, njs_value_arg(&fatal_str), &retval); + ret = njs_value_property(vm, value, NJS_ATOM_STRING_fatal, &retval); if (njs_slow_path(ret == NJS_ERROR)) { return ret; } data->fatal = njs_bool(&retval); - ret = njs_value_property(vm, value, njs_value_arg(&ignore_bom_str), - &retval); + ret = njs_value_property(vm, value, NJS_ATOM_STRING_ignoreBOM, &retval); if (njs_slow_path(ret == NJS_ERROR)) { return ret; } @@ -400,13 +414,11 @@ njs_text_decoder_arg_options(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, static njs_int_t -njs_text_decoder_encoding(njs_vm_t *vm, njs_object_prop_t *prop, +njs_text_decoder_encoding(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { njs_encoding_decode_t *data; - static const njs_value_t utf8_str = njs_string("utf-8"); - if (njs_slow_path(!njs_is_object_data(value, NJS_DATA_TAG_TEXT_DECODER))) { njs_set_undefined(retval); return NJS_DECLINED; @@ -416,7 +428,7 @@ njs_text_decoder_encoding(njs_vm_t *vm, njs_object_prop_t *prop, switch (data->encoding) { case NJS_ENCODING_UTF8: - *retval = utf8_str; + njs_atom_to_value(vm, retval, NJS_ATOM_STRING_utf_8); break; default: @@ -429,7 +441,7 @@ njs_text_decoder_encoding(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t -njs_text_decoder_fatal(njs_vm_t *vm, njs_object_prop_t *prop, +njs_text_decoder_fatal(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { njs_encoding_decode_t *data; @@ -449,7 +461,8 @@ njs_text_decoder_fatal(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t njs_text_decoder_ignore_bom(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { njs_encoding_decode_t *data; @@ -482,8 +495,6 @@ njs_text_decoder_decode(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, const njs_typed_array_t *array; const njs_array_buffer_t *buffer; - static const njs_value_t stream_str = njs_string("stream"); - start = NULL; end = NULL; @@ -527,8 +538,7 @@ njs_text_decoder_decode(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return NJS_ERROR; } - ret = njs_value_property(vm, options, njs_value_arg(&stream_str), - retval); + ret = njs_value_property(vm, options, NJS_ATOM_STRING_stream, retval); if (njs_slow_path(ret == NJS_ERROR)) { return ret; } @@ -568,19 +578,21 @@ njs_text_decoder_decode(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } -static const njs_object_prop_t njs_text_decoder_properties[] = +static const njs_object_prop_init_t njs_text_decoder_properties[] = { - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("encoding", njs_text_decoder_encoding, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_encoding, njs_text_decoder_encoding, 0, + 0), - NJS_DECLARE_PROP_HANDLER("fatal", njs_text_decoder_fatal, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_fatal, njs_text_decoder_fatal, 0, 0), - NJS_DECLARE_PROP_HANDLER("ignoreBOM", njs_text_decoder_ignore_bom, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_ignoreBOM, njs_text_decoder_ignore_bom, + 0, 0), - NJS_DECLARE_PROP_NATIVE("decode", njs_text_decoder_decode, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_decode, njs_text_decoder_decode, 0, 0), }; @@ -590,13 +602,14 @@ const njs_object_init_t njs_text_decoder_init = { }; -static const njs_object_prop_t njs_text_decoder_constructor_properties[] = +static const njs_object_prop_init_t njs_text_decoder_constructor_properties[] = { NJS_DECLARE_PROP_LENGTH(0), NJS_DECLARE_PROP_NAME("TextDecoder"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), }; diff --git a/src/njs_error.c b/src/njs_error.c index b9da6597..6e12aa61 100644 --- a/src/njs_error.c +++ b/src/njs_error.c @@ -30,12 +30,6 @@ static njs_int_t njs_backtrace_to_string(njs_vm_t *vm, njs_arr_t *backtrace, njs_str_t *dst); -static const njs_value_t njs_error_message_string = njs_string("message"); -static const njs_value_t njs_error_name_string = njs_string("name"); -static const njs_value_t njs_error_stack_string = njs_string("stack"); -static const njs_value_t njs_error_errors_string = njs_string("errors"); - - void njs_error_new(njs_vm_t *vm, njs_value_t *dst, njs_object_t *proto, u_char *start, size_t size) @@ -171,8 +165,7 @@ njs_error_stack(njs_vm_t *vm, njs_value_t *value, njs_value_t *stack) { njs_int_t ret; - ret = njs_value_property(vm, value, njs_value_arg(&njs_error_stack_string), - stack); + ret = njs_value_property(vm, value, NJS_ATOM_STRING_stack, stack); if (njs_slow_path(ret != NJS_OK)) { return ret; } @@ -189,11 +182,11 @@ njs_object_t * njs_error_alloc(njs_vm_t *vm, njs_object_t *proto, const njs_value_t *name, const njs_value_t *message, const njs_value_t *errors) { - njs_int_t ret; - njs_object_t *error; - njs_object_prop_t *prop; - njs_object_value_t *ov; - njs_lvlhsh_query_t lhq; + njs_int_t ret; + njs_object_t *error; + njs_object_prop_t *prop; + njs_object_value_t *ov; + njs_flathsh_query_t lhq; ov = njs_mp_alloc(vm->mem_pool, sizeof(njs_object_value_t)); if (njs_slow_path(ov == NULL)) { @@ -219,17 +212,15 @@ njs_error_alloc(njs_vm_t *vm, njs_object_t *proto, const njs_value_t *name, lhq.proto = &njs_object_hash_proto; if (name != NULL) { - lhq.key = njs_str_value("name"); - lhq.key_hash = NJS_NAME_HASH; - - prop = njs_object_prop_alloc(vm, &njs_error_name_string, name, 1); + prop = njs_object_prop_alloc(vm, name, 1); if (njs_slow_path(prop == NULL)) { goto memory_error; } lhq.value = prop; + lhq.key_hash = NJS_ATOM_STRING_name; - ret = njs_lvlhsh_insert(&error->hash, &lhq); + ret = njs_flathsh_unique_insert(&error->hash, &lhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "lvlhsh insert failed"); return NULL; @@ -237,10 +228,7 @@ njs_error_alloc(njs_vm_t *vm, njs_object_t *proto, const njs_value_t *name, } if (message!= NULL) { - lhq.key = njs_str_value("message"); - lhq.key_hash = NJS_MESSAGE_HASH; - - prop = njs_object_prop_alloc(vm, &njs_error_message_string, message, 1); + prop = njs_object_prop_alloc(vm, message, 1); if (njs_slow_path(prop == NULL)) { goto memory_error; } @@ -248,8 +236,9 @@ njs_error_alloc(njs_vm_t *vm, njs_object_t *proto, const njs_value_t *name, prop->enumerable = 0; lhq.value = prop; + lhq.key_hash = NJS_ATOM_STRING_message; - ret = njs_lvlhsh_insert(&error->hash, &lhq); + ret = njs_flathsh_unique_insert(&error->hash, &lhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "lvlhsh insert failed"); return NULL; @@ -257,10 +246,7 @@ njs_error_alloc(njs_vm_t *vm, njs_object_t *proto, const njs_value_t *name, } if (errors != NULL) { - lhq.key = njs_str_value("errors"); - lhq.key_hash = NJS_ERRORS_HASH; - - prop = njs_object_prop_alloc(vm, &njs_error_errors_string, errors, 1); + prop = njs_object_prop_alloc(vm, errors, 1); if (njs_slow_path(prop == NULL)) { goto memory_error; } @@ -268,8 +254,9 @@ njs_error_alloc(njs_vm_t *vm, njs_object_t *proto, const njs_value_t *name, prop->enumerable = 0; lhq.value = prop; + lhq.key_hash = NJS_ATOM_STRING_errors; - ret = njs_lvlhsh_insert(&error->hash, &lhq); + ret = njs_flathsh_unique_insert(&error->hash, &lhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "lvlhsh insert failed"); return NULL; @@ -340,13 +327,14 @@ njs_error_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } -static const njs_object_prop_t njs_error_constructor_properties[] = +static const njs_object_prop_init_t njs_error_constructor_properties[] = { NJS_DECLARE_PROP_LENGTH(1), NJS_DECLARE_PROP_NAME("Error"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), }; @@ -356,13 +344,14 @@ const njs_object_init_t njs_error_constructor_init = { }; -static const njs_object_prop_t njs_eval_error_constructor_properties[] = +static const njs_object_prop_init_t njs_eval_error_constructor_properties[] = { NJS_DECLARE_PROP_LENGTH(1), NJS_DECLARE_PROP_NAME("EvalError"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), }; @@ -372,13 +361,14 @@ const njs_object_init_t njs_eval_error_constructor_init = { }; -static const njs_object_prop_t njs_internal_error_constructor_properties[] = +static const njs_object_prop_init_t njs_internal_error_constructor_properties[] = { NJS_DECLARE_PROP_LENGTH(1), NJS_DECLARE_PROP_NAME("InternalError"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), }; @@ -388,13 +378,14 @@ const njs_object_init_t njs_internal_error_constructor_init = { }; -static const njs_object_prop_t njs_range_error_constructor_properties[] = +static const njs_object_prop_init_t njs_range_error_constructor_properties[] = { NJS_DECLARE_PROP_LENGTH(1), NJS_DECLARE_PROP_NAME("RangeError"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), }; @@ -404,13 +395,14 @@ const njs_object_init_t njs_range_error_constructor_init = { }; -static const njs_object_prop_t njs_reference_error_constructor_properties[] = +static const njs_object_prop_init_t njs_reference_error_constructor_properties[] = { NJS_DECLARE_PROP_LENGTH(1), NJS_DECLARE_PROP_NAME("ReferenceError"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), }; @@ -420,13 +412,14 @@ const njs_object_init_t njs_reference_error_constructor_init = { }; -static const njs_object_prop_t njs_syntax_error_constructor_properties[] = +static const njs_object_prop_init_t njs_syntax_error_constructor_properties[] = { NJS_DECLARE_PROP_LENGTH(1), NJS_DECLARE_PROP_NAME("SyntaxError"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), }; @@ -436,13 +429,14 @@ const njs_object_init_t njs_syntax_error_constructor_init = { }; -static const njs_object_prop_t njs_type_error_constructor_properties[] = +static const njs_object_prop_init_t njs_type_error_constructor_properties[] = { NJS_DECLARE_PROP_LENGTH(1), NJS_DECLARE_PROP_NAME("TypeError"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), }; @@ -452,13 +446,14 @@ const njs_object_init_t njs_type_error_constructor_init = { }; -static const njs_object_prop_t njs_uri_error_constructor_properties[] = +static const njs_object_prop_init_t njs_uri_error_constructor_properties[] = { NJS_DECLARE_PROP_LENGTH(1), NJS_DECLARE_PROP_NAME("URIError"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), }; @@ -468,13 +463,14 @@ const njs_object_init_t njs_uri_error_constructor_init = { }; -static const njs_object_prop_t njs_aggregate_error_constructor_properties[] = +static const njs_object_prop_init_t njs_aggregate_error_constructor_properties[] = { NJS_DECLARE_PROP_LENGTH(1), NJS_DECLARE_PROP_NAME("AggregateError"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), }; @@ -532,7 +528,8 @@ njs_memory_error_constructor(njs_vm_t *vm, njs_value_t *args, static njs_int_t njs_memory_error_prototype_create(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { int32_t index; njs_function_t *function; @@ -555,14 +552,14 @@ njs_memory_error_prototype_create(njs_vm_t *vm, njs_object_prop_t *prop, } -static const njs_object_prop_t njs_memory_error_constructor_properties[] = +static const njs_object_prop_init_t njs_memory_error_constructor_properties[] = { NJS_DECLARE_PROP_LENGTH(1), NJS_DECLARE_PROP_NAME("MemoryError"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_memory_error_prototype_create, - 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, + njs_memory_error_prototype_create, 0, 0), }; @@ -593,9 +590,6 @@ njs_error_to_string2(njs_vm_t *vm, njs_value_t *retval, njs_value_t *name_value, *message_value; njs_string_prop_t name, message; - static const njs_value_t string_message = njs_string("message"); - static const njs_value_t default_name = njs_string("Error"); - njs_assert(njs_is_object(error)); if (want_stack) { @@ -609,34 +603,38 @@ njs_error_to_string2(njs_vm_t *vm, njs_value_t *retval, } } - ret = njs_value_property(vm, (njs_value_t *) error, - njs_value_arg(&njs_string_name), + ret = njs_value_property(vm, (njs_value_t *) error, NJS_ATOM_STRING_name, &value1); if (njs_slow_path(ret == NJS_ERROR)) { return ret; } - name_value = (ret == NJS_OK) ? &value1 : njs_value_arg(&default_name); + if (ret == NJS_DECLINED) { + njs_atom_to_value(vm, &value1, NJS_ATOM_STRING_Error); + } + + name_value = &value1; if (njs_slow_path(!njs_is_string(name_value))) { ret = njs_value_to_string(vm, &value1, name_value); if (njs_slow_path(ret != NJS_OK)) { return ret; } - - name_value = &value1; } - (void) njs_string_prop(&name, name_value); + (void) njs_string_prop(vm, &name, name_value); - ret = njs_value_property(vm, (njs_value_t *) error, - njs_value_arg(&string_message), &value2); + ret = njs_value_property(vm, (njs_value_t *) error, NJS_ATOM_STRING_message, + &value2); if (njs_slow_path(ret == NJS_ERROR)) { return ret; } - message_value = (ret == NJS_OK) ? &value2 - : njs_value_arg(&njs_string_empty); + if (ret == NJS_DECLINED) { + njs_set_empty_string(vm, &value2); + } + + message_value = &value2; if (njs_slow_path(!njs_is_string(message_value))) { ret = njs_value_to_string(vm, &value2, message_value); @@ -647,7 +645,7 @@ njs_error_to_string2(njs_vm_t *vm, njs_value_t *retval, message_value = &value2; } - (void) njs_string_prop(&message, message_value); + (void) njs_string_prop(vm, &message, message_value); if (name.size == 0) { *retval = *message_value; @@ -697,7 +695,7 @@ njs_error_prototype_to_string(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, static njs_int_t -njs_error_prototype_stack(njs_vm_t *vm, njs_object_prop_t *prop, +njs_error_prototype_stack(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { njs_int_t ret; @@ -750,7 +748,7 @@ njs_error_prototype_stack(njs_vm_t *vm, njs_object_prop_t *prop, return ret; } - njs_string_get(&rv, &string); + njs_string_get(vm, &rv, &string); ret = njs_backtrace_to_string(vm, backtrace, &string); @@ -794,23 +792,26 @@ njs_error_to_string(njs_vm_t *vm, njs_value_t *retval, const njs_value_t *error) } -static const njs_object_prop_t njs_error_prototype_properties[] = +static const njs_object_prop_init_t njs_error_prototype_properties[] = { - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_VALUE("name", njs_string("Error"), + NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval("Error"), NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_VALUE("message", njs_string(""), NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_VALUE(STRING_message, njs_ascii_strval(""), + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_NATIVE("valueOf", njs_error_prototype_value_of, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_valueOf, njs_error_prototype_value_of, + 0, 0), - NJS_DECLARE_PROP_NATIVE("toString", njs_error_prototype_to_string, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_toString, njs_error_prototype_to_string, + 0, 0), - NJS_DECLARE_PROP_HANDLER("stack", njs_error_prototype_stack, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_stack, njs_error_prototype_stack, + 0, NJS_OBJECT_PROP_VALUE_CW), }; @@ -829,16 +830,17 @@ const njs_object_type_init_t njs_error_type_init = { }; -static const njs_object_prop_t njs_eval_error_prototype_properties[] = +static const njs_object_prop_init_t njs_eval_error_prototype_properties[] = { - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_VALUE("name", njs_string("EvalError"), + NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval("EvalError"), NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_VALUE("message", njs_string(""), NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_VALUE(STRING_message, njs_ascii_strval(""), + NJS_OBJECT_PROP_VALUE_CW), }; @@ -861,12 +863,10 @@ static njs_int_t njs_internal_error_prototype_to_string(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval) { - static const njs_value_t name = njs_string("MemoryError"); - if (nargs >= 1 && njs_is_object(&args[0])) { /* MemoryError is a nonextensible internal error. */ if (!njs_object(&args[0])->extensible) { - njs_value_assign(retval, &name); + njs_atom_to_value(vm, retval, NJS_ATOM_STRING_MemoryError); return NJS_OK; } } @@ -875,15 +875,16 @@ njs_internal_error_prototype_to_string(njs_vm_t *vm, njs_value_t *args, } -static const njs_object_prop_t njs_internal_error_prototype_properties[] = +static const njs_object_prop_init_t njs_internal_error_prototype_properties[] = { - NJS_DECLARE_PROP_VALUE("name", njs_string("InternalError"), + NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval("InternalError"), NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_VALUE("message", njs_string(""), NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_VALUE(STRING_message, njs_ascii_strval(""), + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_NATIVE("toString", njs_internal_error_prototype_to_string, - 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_toString, + njs_internal_error_prototype_to_string, 0, 0), }; @@ -910,16 +911,17 @@ const njs_object_type_init_t njs_memory_error_type_init = { }; -static const njs_object_prop_t njs_range_error_prototype_properties[] = +static const njs_object_prop_init_t njs_range_error_prototype_properties[] = { - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_VALUE("name", njs_string("RangeError"), + NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval("RangeError"), NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_VALUE("message", njs_string(""), NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_VALUE(STRING_message, njs_ascii_strval(""), + NJS_OBJECT_PROP_VALUE_CW), }; @@ -938,16 +940,17 @@ const njs_object_type_init_t njs_range_error_type_init = { }; -static const njs_object_prop_t njs_reference_error_prototype_properties[] = +static const njs_object_prop_init_t njs_reference_error_prototype_properties[] = { - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_VALUE("name", njs_string("ReferenceError"), + NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval("ReferenceError"), NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_VALUE("message", njs_string(""), NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_VALUE(STRING_message, njs_ascii_strval(""), + NJS_OBJECT_PROP_VALUE_CW), }; @@ -966,16 +969,17 @@ const njs_object_type_init_t njs_reference_error_type_init = { }; -static const njs_object_prop_t njs_syntax_error_prototype_properties[] = +static const njs_object_prop_init_t njs_syntax_error_prototype_properties[] = { - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_VALUE("name", njs_string("SyntaxError"), + NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval("SyntaxError"), NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_VALUE("message", njs_string(""), NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_VALUE(STRING_message, njs_ascii_strval(""), + NJS_OBJECT_PROP_VALUE_CW), }; @@ -994,16 +998,17 @@ const njs_object_type_init_t njs_syntax_error_type_init = { }; -static const njs_object_prop_t njs_type_error_prototype_properties[] = +static const njs_object_prop_init_t njs_type_error_prototype_properties[] = { - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_VALUE("name", njs_string("TypeError"), + NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval("TypeError"), NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_VALUE("message", njs_string(""), NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_VALUE(STRING_message, njs_ascii_strval(""), + NJS_OBJECT_PROP_VALUE_CW), }; @@ -1022,16 +1027,17 @@ const njs_object_type_init_t njs_type_error_type_init = { }; -static const njs_object_prop_t njs_uri_error_prototype_properties[] = +static const njs_object_prop_init_t njs_uri_error_prototype_properties[] = { - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_VALUE("name", njs_string("URIError"), + NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval("URIError"), NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_VALUE("message", njs_string(""), NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_VALUE(STRING_message, njs_ascii_strval(""), + NJS_OBJECT_PROP_VALUE_CW), }; @@ -1050,16 +1056,17 @@ const njs_object_type_init_t njs_uri_error_type_init = { }; -static const njs_object_prop_t njs_aggregate_error_prototype_properties[] = +static const njs_object_prop_init_t njs_aggregate_error_prototype_properties[] = { - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_VALUE("name", njs_string("AggregateError"), + NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval("AggregateError"), NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_VALUE("message", njs_string(""), NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_VALUE(STRING_message, njs_ascii_strval(""), + NJS_OBJECT_PROP_VALUE_CW), }; diff --git a/src/njs_extern.c b/src/njs_extern.c index 621cb76d..077d2a5f 100644 --- a/src/njs_extern.c +++ b/src/njs_extern.c @@ -9,8 +9,8 @@ static njs_int_t njs_external_prop_handler(njs_vm_t *vm, - njs_object_prop_t *self, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *self, uint32_t atom_id, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); static njs_int_t @@ -19,12 +19,13 @@ njs_external_add(njs_vm_t *vm, njs_arr_t *protos, { size_t size; njs_int_t ret; - njs_lvlhsh_t *hash; + njs_value_t prop_name; const u_char *start; + njs_flathsh_t *hash; njs_function_t *function; njs_object_prop_t *prop; - njs_lvlhsh_query_t lhq; njs_exotic_slots_t *slot, *next; + njs_flathsh_query_t lhq; const njs_external_t *end; slot = njs_arr_add(protos); @@ -57,8 +58,7 @@ njs_external_add(njs_vm_t *vm, njs_arr_t *protos, continue; } - prop = njs_object_prop_alloc(vm, &njs_string_empty, - &njs_value_invalid, 1); + prop = njs_object_prop_alloc(vm, &njs_value_invalid, 1); if (njs_slow_path(prop == NULL)) { goto memory_error; } @@ -68,20 +68,17 @@ njs_external_add(njs_vm_t *vm, njs_arr_t *protos, prop->enumerable = external->enumerable; if (external->flags & NJS_EXTERN_SYMBOL) { - njs_set_symbol(&prop->name, external->name.symbol, NULL); - lhq.key_hash = external->name.symbol; } else { - ret = njs_string_create(vm, &prop->name, - external->name.string.start, - external->name.string.length); + ret = njs_atom_string_create(vm, &prop_name, + external->name.string.start, + external->name.string.length); if (njs_slow_path(ret != NJS_OK)) { return NJS_ERROR; } - lhq.key = external->name.string; - lhq.key_hash = njs_djb_hash(lhq.key.start, lhq.key.length); + lhq.key_hash = prop_name.atom_id; } lhq.value = prop; @@ -170,7 +167,7 @@ njs_external_add(njs_vm_t *vm, njs_arr_t *protos, break; } - ret = njs_lvlhsh_insert(hash, &lhq); + ret = njs_flathsh_unique_insert(hash, &lhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "lvlhsh insert failed"); return NJS_ERROR; @@ -191,14 +188,15 @@ memory_error: static njs_int_t njs_external_prop_handler(njs_vm_t *vm, njs_object_prop_t *self, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t atom_id, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { - njs_int_t ret; - njs_object_prop_t *prop; - njs_external_ptr_t external; - njs_object_value_t *ov; - njs_lvlhsh_query_t lhq; - njs_exotic_slots_t *slots; + njs_int_t ret; + njs_object_prop_t *prop; + njs_external_ptr_t external; + njs_object_value_t *ov; + njs_exotic_slots_t *slots; + njs_flathsh_query_t lhq; if (njs_slow_path(retval == NULL)) { return NJS_DECLINED; @@ -226,7 +224,7 @@ njs_external_prop_handler(njs_vm_t *vm, njs_object_prop_t *self, njs_set_object_value(retval, ov); } - prop = njs_object_prop_alloc(vm, &self->name, retval, 1); + prop = njs_object_prop_alloc(vm, retval, 1); if (njs_slow_path(prop == NULL)) { return NJS_ERROR; } @@ -236,13 +234,12 @@ njs_external_prop_handler(njs_vm_t *vm, njs_object_prop_t *self, prop->enumerable = self->enumerable; lhq.value = prop; - njs_string_get(&self->name, &lhq.key); - lhq.key_hash = njs_prop_magic32(self); + lhq.key_hash = atom_id; lhq.replace = 1; lhq.pool = vm->mem_pool; lhq.proto = &njs_object_hash_proto; - ret = njs_lvlhsh_insert(njs_object_hash(value), &lhq); + ret = njs_flathsh_unique_insert(njs_object_hash(value), &lhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "lvlhsh insert/replace failed"); return NJS_ERROR; @@ -315,7 +312,8 @@ njs_vm_external_prototype(njs_vm_t *vm, const njs_external_t *definition, static njs_int_t njs_vm_external_constructor_handler(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t atom_id, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { njs_set_function(retval, &njs_vm_ctor(vm, njs_prop_magic32(prop))); @@ -325,7 +323,7 @@ njs_vm_external_constructor_handler(njs_vm_t *vm, njs_object_prop_t *prop, njs_int_t njs_vm_external_constructor(njs_vm_t *vm, const njs_str_t *name, - njs_function_native_t native, const njs_external_t *ctor_props, + const njs_function_native_t native, const njs_external_t *ctor_props, njs_uint_t ctor_nprops, const njs_external_t *proto_props, njs_uint_t proto_nprops) { @@ -445,8 +443,8 @@ njs_value_external_tag(const njs_value_t *value) njs_int_t -njs_external_property(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t *value, - njs_value_t *setval, njs_value_t *retval) +njs_external_property(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, + njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { char *p; njs_int_t i; diff --git a/src/njs_flathsh.c b/src/njs_flathsh.c index c823c466..f2387c95 100644 --- a/src/njs_flathsh.c +++ b/src/njs_flathsh.c @@ -144,13 +144,6 @@ njs_flathsh_chunk(njs_flathsh_descr_t *h) } -njs_inline njs_flathsh_elt_t * -njs_hash_elts(njs_flathsh_descr_t *h) -{ - return (njs_flathsh_elt_t *) ((char *) h + sizeof(njs_flathsh_descr_t)); -} - - /* * Create a new empty flat hash. */ @@ -343,8 +336,6 @@ njs_flathsh_find(const njs_flathsh_t *fh, njs_flathsh_query_t *fhq) while (elt_num != 0) { e = &elts[elt_num - 1]; - /* TODO: need to be replaced by atomic test. */ - if (e->key_hash == fhq->key_hash && fhq->proto->test(fhq, e->value) == NJS_OK) { @@ -359,6 +350,37 @@ njs_flathsh_find(const njs_flathsh_t *fh, njs_flathsh_query_t *fhq) } +njs_int_t +njs_flathsh_unique_find(const njs_flathsh_t *fh, njs_flathsh_query_t *fhq) +{ + njs_int_t cell_num, elt_num; + njs_flathsh_elt_t *e, *elts; + njs_flathsh_descr_t *h; + + h = fh->slot; + if (njs_slow_path(h == NULL)) { + return NJS_DECLINED; + } + + cell_num = fhq->key_hash & h->hash_mask; + elt_num = njs_hash_cells_end(h)[-cell_num - 1]; + elts = njs_hash_elts(h); + + while (elt_num != 0) { + e = &elts[elt_num - 1]; + + if (e->key_hash == fhq->key_hash) { + fhq->value = e->value; + return NJS_OK; + } + + elt_num = e->next_elt; + } + + return NJS_DECLINED; +} + + njs_int_t njs_flathsh_insert(njs_flathsh_t *fh, njs_flathsh_query_t *fhq) { @@ -385,8 +407,6 @@ njs_flathsh_insert(njs_flathsh_t *fh, njs_flathsh_query_t *fhq) while (elt_num != 0) { elt = &elts[elt_num - 1]; - /* TODO: need to be replaced by atomic test. */ - if (elt->key_hash == fhq->key_hash && fhq->proto->test(fhq, elt->value) == NJS_OK) { @@ -418,6 +438,61 @@ njs_flathsh_insert(njs_flathsh_t *fh, njs_flathsh_query_t *fhq) } +njs_int_t +njs_flathsh_unique_insert(njs_flathsh_t *fh, njs_flathsh_query_t *fhq) +{ + void *tmp; + njs_int_t cell_num, elt_num; + njs_flathsh_elt_t *elt, *elts; + njs_flathsh_descr_t *h; + + h = fh->slot; + + if (h == NULL) { + h = njs_flathsh_new(fhq); + if (h == NULL) { + return NJS_ERROR; + } + + fh->slot = h; + } + + cell_num = fhq->key_hash & h->hash_mask; + elt_num = njs_hash_cells_end(h)[-cell_num - 1]; + elts = njs_hash_elts(h); + + while (elt_num != 0) { + elt = &elts[elt_num - 1]; + + if (elt->key_hash == fhq->key_hash) { + if (fhq->replace) { + tmp = fhq->value; + fhq->value = elt->value; + elt->value = tmp; + + return NJS_OK; + + } else { + fhq->value = elt->value; + + return NJS_DECLINED; + } + } + + elt_num = elt->next_elt; + } + + elt = njs_flathsh_add_elt(fh, fhq); + if (elt == NULL) { + return NJS_ERROR; + } + + elt->value = fhq->value; + + return NJS_OK; +} + + static njs_flathsh_descr_t * njs_shrink_elts(njs_flathsh_query_t *fhq, njs_flathsh_descr_t *h) { @@ -502,8 +577,6 @@ njs_flathsh_delete(njs_flathsh_t *fh, njs_flathsh_query_t *fhq) while (elt_num != 0) { elt = &elts[elt_num - 1]; - /* TODO: use atomic comparision. */ - if (elt->key_hash == fhq->key_hash && fhq->proto->test(fhq, elt->value) == NJS_OK) { @@ -550,11 +623,75 @@ njs_flathsh_delete(njs_flathsh_t *fh, njs_flathsh_query_t *fhq) } -void * +njs_int_t +njs_flathsh_unique_delete(njs_flathsh_t *fh, njs_flathsh_query_t *fhq) +{ + njs_int_t cell_num, elt_num; + njs_flathsh_elt_t *elt, *elt_prev, *elts; + njs_flathsh_descr_t *h; + + h = fh->slot; + + if (njs_slow_path(h == NULL)) { + return NJS_DECLINED; + } + + cell_num = fhq->key_hash & h->hash_mask; + elt_num = njs_hash_cells_end(h)[-cell_num - 1]; + elts = njs_hash_elts(h); + elt_prev = NULL; + + while (elt_num != 0) { + elt = &elts[elt_num - 1]; + + if (elt->key_hash == fhq->key_hash) { + fhq->value = elt->value; + + if (elt_prev != NULL) { + elt_prev->next_elt = elt->next_elt; + + } else { + njs_hash_cells_end(h)[-cell_num - 1] = elt->next_elt; + } + + h->elts_deleted_count++; + + elt->value = NULL; + + /* Shrink elts if elts_deleted_count is eligible. */ + + if (h->elts_deleted_count >= NJS_FLATHSH_ELTS_MINIMUM_TO_SHRINK + && h->elts_deleted_count + >= (h->elts_count / NJS_FLATHSH_ELTS_FRACTION_TO_SHRINK)) + { + h = njs_shrink_elts(fhq, h); + if (njs_slow_path(h == NULL)) { + return NJS_ERROR; + } + + fh->slot = h; + } + + if (h->elts_deleted_count == h->elts_count) { + njs_flathsh_free(fhq, njs_flathsh_chunk(h)); + fh->slot = NULL; + } + + return NJS_OK; + } + + elt_prev = elt; + elt_num = elt->next_elt; + } + + return NJS_DECLINED; +} + + +njs_flathsh_elt_t * njs_flathsh_each(const njs_flathsh_t *fh, njs_flathsh_each_t *fhe) { - void *v; - njs_flathsh_elt_t *elt; + njs_flathsh_elt_t *e, *elt; njs_flathsh_descr_t *h; h = fh->slot; @@ -565,9 +702,9 @@ njs_flathsh_each(const njs_flathsh_t *fh, njs_flathsh_each_t *fhe) elt = njs_hash_elts(h); while (fhe->cp < h->elts_count) { - v = elt[fhe->cp++].value; - if (v != NULL) { - return v; + e = &elt[fhe->cp++]; + if (e->value != NULL) { + return e; } } diff --git a/src/njs_flathsh.h b/src/njs_flathsh.h index d347bb81..651afcff 100644 --- a/src/njs_flathsh.h +++ b/src/njs_flathsh.h @@ -64,6 +64,10 @@ struct njs_flathsh_query_s { ((fhl)->slot == (fhr)->slot) +#define njs_hash_elts(h) \ + ((njs_flathsh_elt_t *) ((char *) (h) + 16 /* njs_flathsh_descr_t size */)) + + /* * njs_flathsh_find() finds a hash element. If the element has been * found then it is stored in the fhq->value and njs_flathsh_find() @@ -73,6 +77,11 @@ struct njs_flathsh_query_s { */ NJS_EXPORT njs_int_t njs_flathsh_find(const njs_flathsh_t *fh, njs_flathsh_query_t *fhq); +/* + * The same as njs_flathsh_find(), but for hashes with unique keys. + */ +NJS_EXPORT njs_int_t njs_flathsh_unique_find(const njs_flathsh_t *fh, + njs_flathsh_query_t *fhq); /* * njs_flathsh_insert() adds a hash element. If the element is already @@ -91,6 +100,11 @@ NJS_EXPORT njs_int_t njs_flathsh_find(const njs_flathsh_t *fh, */ NJS_EXPORT njs_int_t njs_flathsh_insert(njs_flathsh_t *fh, njs_flathsh_query_t *fhq); +/* + * The same as njs_flathsh_insert(), but for hashes with unique keys. + */ +NJS_EXPORT njs_int_t njs_flathsh_unique_insert(njs_flathsh_t *fh, + njs_flathsh_query_t *fhq); /* * njs_flathsh_delete() deletes a hash element. If the element has been @@ -102,11 +116,14 @@ NJS_EXPORT njs_int_t njs_flathsh_insert(njs_flathsh_t *fh, */ NJS_EXPORT njs_int_t njs_flathsh_delete(njs_flathsh_t *fh, njs_flathsh_query_t *fhq); +/* + * The same as njs_flathsh_delete(), but for hashes with unique keys. + */ +NJS_EXPORT njs_int_t njs_flathsh_unique_delete(njs_flathsh_t *fh, + njs_flathsh_query_t *fhq); typedef struct { - const njs_flathsh_proto_t *proto; - uint32_t key_hash; uint32_t cp; } njs_flathsh_each_t; @@ -114,11 +131,10 @@ typedef struct { #define njs_flathsh_each_init(lhe, _proto) \ do { \ njs_memzero(lhe, sizeof(njs_flathsh_each_t)); \ - (lhe)->proto = _proto; \ } while (0) -NJS_EXPORT void *njs_flathsh_each(const njs_flathsh_t *fh, +NJS_EXPORT njs_flathsh_elt_t *njs_flathsh_each(const njs_flathsh_t *fh, njs_flathsh_each_t *fhe); /* @@ -151,7 +167,19 @@ typedef struct njs_flathsh_proto_s njs_lvlhsh_proto_t; #define njs_lvlhsh_insert(lh, lhq) njs_flathsh_insert(lh, lhq) #define njs_lvlhsh_delete(lh, lhq) njs_flathsh_delete(lh, lhq) #define njs_lvlhsh_each_init(lhe, _proto) njs_flathsh_each_init(lhe, _proto) -#define njs_lvlhsh_each(lh, lhe) njs_flathsh_each(lh, lhe) + +njs_inline void * +njs_lvlhsh_each(const njs_flathsh_t *lh, njs_flathsh_each_t *lhe) +{ + njs_flathsh_elt_t *e; + + e = njs_flathsh_each(lh, lhe); + if (e == NULL) { + return NULL; + } + + return e->value; +} #endif /* _NJS_FLATHSH_H_INCLUDED_ */ diff --git a/src/njs_function.c b/src/njs_function.c index 326549f5..0840d437 100644 --- a/src/njs_function.c +++ b/src/njs_function.c @@ -118,15 +118,15 @@ njs_int_t njs_function_name_set(njs_vm_t *vm, njs_function_t *function, njs_value_t *name, const char *prefix) { - u_char *p; - size_t len, symbol; - njs_int_t ret; - njs_value_t value; - njs_string_prop_t string; - njs_object_prop_t *prop; - njs_lvlhsh_query_t lhq; - - prop = njs_object_prop_alloc(vm, &njs_string_name, name, 0); + u_char *p; + size_t len, symbol; + njs_int_t ret; + njs_value_t value; + njs_string_prop_t string; + njs_object_prop_t *prop; + njs_flathsh_query_t lhq; + + prop = njs_object_prop_alloc(vm, name, 0); if (njs_slow_path(prop == NULL)) { return NJS_ERROR; } @@ -142,7 +142,7 @@ njs_function_name_set(njs_vm_t *vm, njs_function_t *function, if (prefix != NULL || symbol != 0) { if (njs_is_defined(njs_prop_value(prop))) { njs_value_assign(&value, njs_prop_value(prop)); - (void) njs_string_prop(&string, &value); + (void) njs_string_prop(vm, &string, &value); len = (prefix != NULL) ? njs_strlen(prefix) + 1: 0; p = njs_string_alloc(vm, njs_prop_value(prop), @@ -168,20 +168,19 @@ njs_function_name_set(njs_vm_t *vm, njs_function_t *function, } } else { - njs_value_assign(njs_prop_value(prop), &njs_string_empty); + njs_set_empty_string(vm, njs_prop_value(prop)); } } prop->configurable = 1; - lhq.key_hash = NJS_NAME_HASH; - lhq.key = njs_str_value("name"); - lhq.replace = 0; lhq.value = prop; - lhq.proto = &njs_object_hash_proto; + lhq.key_hash = NJS_ATOM_STRING_name; + lhq.replace = 0; lhq.pool = vm->mem_pool; + lhq.proto = &njs_object_hash_proto; - ret = njs_lvlhsh_insert(&function->object.hash, &lhq); + ret = njs_flathsh_unique_insert(&function->object.hash, &lhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "lvlhsh insert failed"); return NJS_ERROR; @@ -251,8 +250,6 @@ njs_function_arguments_object_init(njs_vm_t *vm, njs_native_frame_t *frame) njs_value_t value, length; njs_object_t *arguments; - static const njs_value_t string_length = njs_string("length"); - arguments = njs_object_alloc(vm); if (njs_slow_path(arguments == NULL)) { return NJS_ERROR; @@ -263,9 +260,8 @@ njs_function_arguments_object_init(njs_vm_t *vm, njs_native_frame_t *frame) njs_set_object(&value, arguments); njs_set_number(&length, frame->nargs); - ret = njs_object_prop_define(vm, &value, njs_value_arg(&string_length), - &length, NJS_OBJECT_PROP_VALUE_CW, - NJS_LENGTH_HASH); + ret = njs_object_prop_define(vm, &value, NJS_ATOM_STRING_length, &length, + NJS_OBJECT_PROP_VALUE_CW); if (njs_slow_path(ret != NJS_OK)) { return NJS_ERROR; } @@ -328,14 +324,16 @@ njs_function_prototype_thrower(njs_vm_t *vm, njs_value_t *args, } -const njs_object_prop_t njs_arguments_object_instance_properties[] = +const njs_object_prop_init_t njs_arguments_object_instance_properties[] = { { - .type = NJS_ACCESSOR, - .name = njs_string("callee"), - .u.accessor = njs_accessor(njs_function_prototype_thrower, 0, - njs_function_prototype_thrower, 0), - .writable = NJS_ATTRIBUTE_UNSET, + .atom_id = NJS_ATOM_STRING_callee, + .desc = { + .type = NJS_ACCESSOR, + .u.accessor = njs_accessor(njs_function_prototype_thrower, 0, + njs_function_prototype_thrower, 0), + .writable = NJS_ATTRIBUTE_UNSET, + }, }, }; @@ -905,16 +903,14 @@ njs_function_capture_global_closures(njs_vm_t *vm, njs_function_t *function) static njs_value_t * -njs_function_property_prototype_set(njs_vm_t *vm, njs_lvlhsh_t *hash, +njs_function_property_prototype_set(njs_vm_t *vm, njs_flathsh_t *hash, njs_value_t *prototype) { - njs_int_t ret; - njs_object_prop_t *prop; - njs_lvlhsh_query_t lhq; + njs_int_t ret; + njs_object_prop_t *prop; + njs_flathsh_query_t lhq; - const njs_value_t proto_string = njs_string("prototype"); - - prop = njs_object_prop_alloc(vm, &proto_string, prototype, 0); + prop = njs_object_prop_alloc(vm, prototype, 0); if (njs_slow_path(prop == NULL)) { return NULL; } @@ -922,13 +918,12 @@ njs_function_property_prototype_set(njs_vm_t *vm, njs_lvlhsh_t *hash, prop->writable = 1; lhq.value = prop; - lhq.key_hash = NJS_PROTOTYPE_HASH; - lhq.key = njs_str_value("prototype"); + lhq.key_hash = NJS_ATOM_STRING_prototype; lhq.replace = 1; lhq.pool = vm->mem_pool; lhq.proto = &njs_object_hash_proto; - ret = njs_lvlhsh_insert(hash, &lhq); + ret = njs_flathsh_unique_insert(hash, &lhq); if (njs_fast_path(ret == NJS_OK)) { return njs_prop_value(prop); @@ -952,7 +947,8 @@ njs_function_property_prototype_set(njs_vm_t *vm, njs_lvlhsh_t *hash, njs_int_t njs_function_prototype_create(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { njs_value_t *proto, proto_value, *cons; njs_object_t *prototype; @@ -1002,6 +998,7 @@ njs_function_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_int_t ret; njs_str_t str, file; njs_uint_t i; + njs_value_t name; njs_parser_t parser; njs_vm_code_t *code; njs_function_t *function; @@ -1072,7 +1069,7 @@ njs_function_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, file = njs_str_value("runtime"); ret = njs_parser_init(vm, &parser, NULL, &file, str.start, - str.start + str.length, 1); + str.start + str.length); if (njs_slow_path(ret != NJS_OK)) { return ret; } @@ -1139,8 +1136,9 @@ njs_function_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, 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); + njs_atom_to_value(vm, &name, NJS_ATOM_STRING_anonymous); + + ret = njs_function_name_set(vm, function, &name, NULL); if (njs_slow_path(ret == NJS_ERROR)) { return ret; } @@ -1156,13 +1154,14 @@ fail: } -static const njs_object_prop_t njs_function_constructor_properties[] = +static const njs_object_prop_init_t njs_function_constructor_properties[] = { NJS_DECLARE_PROP_LENGTH(1), NJS_DECLARE_PROP_NAME("Function"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), }; @@ -1174,7 +1173,8 @@ const njs_object_init_t njs_function_constructor_init = { 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) + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { njs_function_t *function; @@ -1193,7 +1193,8 @@ njs_function_instance_length(njs_vm_t *vm, njs_object_prop_t *prop, 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) + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { njs_function_t *function; @@ -1209,7 +1210,7 @@ njs_function_instance_name(njs_vm_t *vm, njs_object_prop_t *prop, return NJS_OK; } - njs_value_assign(retval, &njs_string_empty); + njs_set_empty_string(vm, retval); return NJS_OK; } @@ -1376,14 +1377,13 @@ njs_function_prototype_bind(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, function->context = njs_function(&args[0]); - ret = njs_value_property(vm, &args[0], njs_value_arg(&njs_string_name), - &name); + ret = njs_value_property(vm, &args[0], NJS_ATOM_STRING_name, &name); if (njs_slow_path(ret == NJS_ERROR)) { return ret; } if (!njs_is_string(&name)) { - name = njs_string_empty; + njs_set_empty_string(vm, &name); } ret = njs_function_name_set(vm, function, &name, "bound"); @@ -1428,38 +1428,43 @@ njs_function_prototype_bind(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } -static const njs_object_prop_t njs_function_prototype_properties[] = +static const njs_object_prop_init_t njs_function_prototype_properties[] = { NJS_DECLARE_PROP_LENGTH(0), NJS_DECLARE_PROP_NAME(""), - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_NATIVE("call", njs_function_prototype_call, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_call, njs_function_prototype_call, 1, 0), - NJS_DECLARE_PROP_NATIVE("apply", njs_function_prototype_apply, 2, 0), + NJS_DECLARE_PROP_NATIVE(STRING_apply, njs_function_prototype_apply, 2, + 0), - NJS_DECLARE_PROP_NATIVE("bind", njs_function_prototype_bind, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_bind, njs_function_prototype_bind, 1, 0), { - .type = NJS_ACCESSOR, - .name = njs_string("caller"), - .u.accessor = njs_accessor(njs_function_prototype_thrower, 0, - njs_function_prototype_thrower, 0), - .writable = NJS_ATTRIBUTE_UNSET, - .configurable = 1, + .atom_id = NJS_ATOM_STRING_caller, + .desc = { + .type = NJS_ACCESSOR, + .u.accessor = njs_accessor(njs_function_prototype_thrower, 0, + njs_function_prototype_thrower, 0), + .writable = NJS_ATTRIBUTE_UNSET, + .configurable = 1, + }, }, { - .type = NJS_ACCESSOR, - .name = njs_string("arguments"), - .u.accessor = njs_accessor(njs_function_prototype_thrower, 0, - njs_function_prototype_thrower, 0), - .writable = NJS_ATTRIBUTE_UNSET, - .configurable = 1, + .atom_id = NJS_ATOM_STRING_arguments, + .desc = { + .type = NJS_ACCESSOR, + .u.accessor = njs_accessor(njs_function_prototype_thrower, 0, + njs_function_prototype_thrower, 0), + .writable = NJS_ATTRIBUTE_UNSET, + .configurable = 1, + }, }, }; @@ -1470,15 +1475,16 @@ const njs_object_init_t njs_function_prototype_init = { }; -const njs_object_prop_t njs_function_instance_properties[] = +const njs_object_prop_init_t njs_function_instance_properties[] = { - NJS_DECLARE_PROP_HANDLER("length", njs_function_instance_length, 0, 0, - NJS_OBJECT_PROP_VALUE_C), + NJS_DECLARE_PROP_HANDLER(STRING_length, njs_function_instance_length, + 0, NJS_OBJECT_PROP_VALUE_C), - NJS_DECLARE_PROP_HANDLER("name", njs_function_instance_name, 0, 0, + NJS_DECLARE_PROP_HANDLER(STRING_name, njs_function_instance_name, 0, NJS_OBJECT_PROP_VALUE_C), - NJS_DECLARE_PROP_HANDLER("prototype", njs_function_prototype_create, 0, 0, + NJS_DECLARE_PROP_HANDLER(STRING_prototype, + njs_function_prototype_create, 0, NJS_OBJECT_PROP_VALUE_W), }; @@ -1489,12 +1495,12 @@ const njs_object_init_t njs_function_instance_init = { }; -const njs_object_prop_t njs_arrow_instance_properties[] = +const njs_object_prop_init_t njs_arrow_instance_properties[] = { - NJS_DECLARE_PROP_HANDLER("length", njs_function_instance_length, 0, 0, - NJS_OBJECT_PROP_VALUE_C), + NJS_DECLARE_PROP_HANDLER(STRING_length, njs_function_instance_length, + 0, NJS_OBJECT_PROP_VALUE_C), - NJS_DECLARE_PROP_HANDLER("name", njs_function_instance_name, 0, 0, + NJS_DECLARE_PROP_HANDLER(STRING_name, njs_function_instance_name, 0, NJS_OBJECT_PROP_VALUE_C), }; diff --git a/src/njs_function.h b/src/njs_function.h index 0b316251..6516ff78 100644 --- a/src/njs_function.h +++ b/src/njs_function.h @@ -94,13 +94,16 @@ njs_int_t njs_function_arguments_object_init(njs_vm_t *vm, njs_int_t njs_function_rest_parameters_init(njs_vm_t *vm, njs_native_frame_t *frame); njs_int_t njs_function_prototype_create(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval); + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval); njs_int_t njs_function_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval); 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); + uint32_t unused, 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); + uint32_t unused, 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_value_t *retval); njs_int_t njs_function_native_frame(njs_vm_t *vm, njs_function_t *function, diff --git a/src/njs_generator.c b/src/njs_generator.c index 2e81a407..a2cc4b1c 100644 --- a/src/njs_generator.c +++ b/src/njs_generator.c @@ -1062,11 +1062,11 @@ 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; - const njs_lexer_entry_t *lex_entry; + njs_int_t ret; + njs_string_t name; + njs_variable_t *var; + njs_parser_node_t *lvalue, *expr; + njs_vmcode_move_t *move; lvalue = node->left; expr = node->right; @@ -1093,20 +1093,14 @@ njs_generate_var_statement_after(njs_vm_t *vm, njs_generator_t *generator, node->index = expr->index; node->temporary = expr->temporary; - if ((expr->token_type == NJS_TOKEN_FUNCTION_EXPRESSION + 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; - } + njs_string_get_unsafe(&expr->u.value.data.u.lambda->name, &name); - ret = njs_string_create(vm, &expr->u.value.data.u.lambda->name, - lex_entry->name.start, lex_entry->name.length); - if (njs_slow_path(ret != NJS_OK)) { - return NJS_ERROR; + if (name.length == 0) { + njs_atom_to_value(vm, &expr->u.value.data.u.lambda->name, + node->left->u.reference.atom_id); } } @@ -3023,11 +3017,9 @@ static njs_int_t njs_generate_global_property_set(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node_dst, njs_parser_node_t *node_src) { - njs_int_t ret; - njs_value_t property; - njs_variable_t *var; - njs_vmcode_prop_set_t *prop_set; - const njs_lexer_entry_t *lex_entry; + njs_value_t property; + njs_variable_t *var; + njs_vmcode_prop_set_t *prop_set; var = njs_variable_reference(vm, node_dst); if (var == NULL) { @@ -3037,16 +3029,7 @@ njs_generate_global_property_set(njs_vm_t *vm, njs_generator_t *generator, prop_set->value = node_dst->index; prop_set->object = njs_scope_global_this_index(); - lex_entry = njs_lexer_entry(node_dst->u.reference.unique_id); - if (njs_slow_path(lex_entry == NULL)) { - return NJS_ERROR; - } - - ret = njs_string_create(vm, &property, lex_entry->name.start, - lex_entry->name.length); - if (njs_slow_path(ret != NJS_OK)) { - return NJS_ERROR; - } + njs_atom_to_value(vm, &property,node_dst->u.reference.atom_id); prop_set->property = njs_scope_global_index(vm, &property, generator->runtime); @@ -3628,11 +3611,11 @@ static njs_int_t njs_generate_function_expression(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node) { - njs_int_t ret; - njs_variable_t *var; - njs_function_lambda_t *lambda; - njs_vmcode_function_t *function; - const njs_lexer_entry_t *lex_entry; + njs_int_t ret; + njs_str_t name; + njs_variable_t *var; + njs_function_lambda_t *lambda; + njs_vmcode_function_t *function; var = njs_variable_reference(vm, node->left); if (njs_slow_path(var == NULL)) { @@ -3646,23 +3629,14 @@ njs_generate_function_expression(njs_vm_t *vm, njs_generator_t *generator, lambda = node->u.value.data.u.lambda; - lex_entry = njs_lexer_entry(var->unique_id); - if (njs_slow_path(lex_entry == NULL)) { - return NJS_ERROR; - } + njs_atom_to_value(vm, &lambda->name, var->atom_id); + njs_string_get(vm, &lambda->name, &name); - ret = njs_generate_function_scope(vm, generator, lambda, node, - &lex_entry->name); + ret = njs_generate_function_scope(vm, generator, lambda, node, &name); if (njs_slow_path(ret != NJS_OK)) { return ret; } - ret = njs_string_create(vm, &lambda->name, lex_entry->name.start, - lex_entry->name.length); - if (njs_slow_path(ret != NJS_OK)) { - return NJS_ERROR; - } - njs_generate_code(generator, njs_vmcode_function_t, function, NJS_VMCODE_FUNCTION, node); function->lambda = lambda; @@ -4188,12 +4162,12 @@ static njs_int_t njs_generate_function_declaration(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node) { - njs_int_t ret; - njs_bool_t async; - njs_variable_t *var; - njs_function_t *function; - njs_function_lambda_t *lambda; - const njs_lexer_entry_t *lex_entry; + njs_int_t ret; + njs_str_t name; + njs_bool_t async; + njs_variable_t *var; + njs_function_t *function; + njs_function_lambda_t *lambda; var = njs_variable_reference(vm, node); if (njs_slow_path(var == NULL)) { @@ -4207,19 +4181,10 @@ njs_generate_function_declaration(njs_vm_t *vm, njs_generator_t *generator, lambda = njs_variable_lambda(var); - lex_entry = njs_lexer_entry(node->u.reference.unique_id); - if (njs_slow_path(lex_entry == NULL)) { - return NJS_ERROR; - } + njs_atom_to_value(vm, &lambda->name, node->u.reference.atom_id); + njs_string_get(vm, &lambda->name, &name); - ret = njs_string_create(vm, &lambda->name, lex_entry->name.start, - lex_entry->name.length); - if (njs_slow_path(ret != NJS_OK)) { - return NJS_ERROR; - } - - ret = njs_generate_function_scope(vm, generator, lambda, node, - &lex_entry->name); + ret = njs_generate_function_scope(vm, generator, lambda, node, &name); if (njs_slow_path(ret != NJS_OK)) { return ret; } @@ -5388,11 +5353,9 @@ static njs_int_t njs_generate_global_reference(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node, njs_bool_t exception) { - njs_int_t ret; - njs_index_t index; - njs_value_t property; - njs_vmcode_prop_get_t *prop_get; - const njs_lexer_entry_t *lex_entry; + njs_index_t index; + njs_value_t property; + njs_vmcode_prop_get_t *prop_get; index = njs_generate_temp_index_get(vm, generator, node); if (njs_slow_path(index == NJS_INDEX_ERROR)) { @@ -5410,16 +5373,7 @@ njs_generate_global_reference(njs_vm_t *vm, njs_generator_t *generator, return NJS_ERROR; } - lex_entry = njs_lexer_entry(node->u.reference.unique_id); - if (njs_slow_path(lex_entry == NULL)) { - return NJS_ERROR; - } - - ret = njs_string_create(vm, &property, lex_entry->name.start, - lex_entry->name.length); - if (njs_slow_path(ret != NJS_OK)) { - return NJS_ERROR; - } + njs_atom_to_value(vm, &property, node->u.reference.atom_id); prop_get->property = njs_scope_global_index(vm, &property, generator->runtime); @@ -5441,8 +5395,8 @@ static njs_int_t njs_generate_reference_error(njs_vm_t *vm, njs_generator_t *generator, njs_parser_node_t *node) { - njs_vmcode_error_t *ref_err; - const njs_lexer_entry_t *lex_entry; + njs_str_t entry; + njs_vmcode_error_t *ref_err; if (njs_slow_path(!node->u.reference.not_defined)) { njs_internal_error(vm, "variable is not defined but not_defined " @@ -5454,12 +5408,10 @@ njs_generate_reference_error(njs_vm_t *vm, njs_generator_t *generator, NULL); ref_err->type = NJS_OBJ_TYPE_REF_ERROR; - lex_entry = njs_lexer_entry(node->u.reference.unique_id); - if (njs_slow_path(lex_entry == NULL)) { - return NJS_ERROR; - } - return njs_name_copy(vm, &ref_err->u.name, &lex_entry->name); + njs_lexer_entry(vm, node->u.reference.atom_id, &entry); + + return njs_name_copy(vm, &ref_err->u.name, &entry); } diff --git a/src/njs_iterator.c b/src/njs_iterator.c index 34bb073e..7bb6a6ce 100644 --- a/src/njs_iterator.c +++ b/src/njs_iterator.c @@ -18,10 +18,6 @@ struct njs_value_iterator_s { typedef struct njs_value_iterator_s njs_array_iterator_t; -static const njs_value_t string_done = njs_string("done"); -static const njs_value_t string_value = njs_string("value"); - - static njs_int_t njs_iterator_object_handler(njs_vm_t *vm, njs_iterator_handler_t handler, njs_iterator_args_t *args, njs_value_t *key, int64_t i, njs_value_t *retval); @@ -179,15 +175,10 @@ njs_iterator_prototype_get_this(njs_vm_t *vm, njs_value_t *args, } -static const njs_object_prop_t njs_iterator_prototype_properties[] = +static const njs_object_prop_init_t njs_iterator_prototype_properties[] = { - { - .type = NJS_PROPERTY, - .name = njs_wellknown_symbol(NJS_SYMBOL_ITERATOR), - .u.value = njs_native_function(njs_iterator_prototype_get_this, 0), - .configurable = 1, - .writable = 1, - }, + NJS_DECLARE_PROP_NATIVE(SYMBOL_iterator, + njs_iterator_prototype_get_this, 0, 0), }; @@ -232,14 +223,12 @@ njs_array_iterator_prototype_next(njs_vm_t *vm, njs_value_t *args, njs_set_object(retval, object); - prop_value = njs_object_property_add(vm, retval, - njs_value_arg(&string_value), 0); + prop_value = njs_object_property_add(vm, retval, NJS_ATOM_STRING_value, 0); if (njs_slow_path(prop_value == NULL)) { return NJS_ERROR; } - prop_done = njs_object_property_add(vm, retval, - njs_value_arg(&string_done), 0); + prop_done = njs_object_property_add(vm, retval, NJS_ATOM_STRING_done, 0); if (njs_slow_path(prop_done == NULL)) { return NJS_ERROR; } @@ -262,17 +251,14 @@ njs_array_iterator_prototype_next(njs_vm_t *vm, njs_value_t *args, } -static const njs_object_prop_t njs_array_iterator_prototype_properties[] = +static const njs_object_prop_init_t njs_array_iterator_prototype_properties[] = { - NJS_DECLARE_PROP_NATIVE("next", njs_array_iterator_prototype_next, 0, - NJS_DATA_TAG_ARRAY_ITERATOR), - - { - .type = NJS_PROPERTY, - .name = njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG), - .u.value = njs_string("Array Iterator"), - .configurable = 1, - }, + NJS_DECLARE_PROP_NATIVE(STRING_next, njs_array_iterator_prototype_next, + 0, NJS_DATA_TAG_ARRAY_ITERATOR), + + NJS_DECLARE_PROP_VALUE(SYMBOL_toStringTag, + njs_ascii_strval("Array Iterator"), + NJS_OBJECT_PROP_VALUE_C), }; @@ -349,7 +335,7 @@ njs_object_iterate(njs_vm_t *vm, njs_iterator_args_t *args, value = njs_object_value(value); } - length = njs_string_prop(&string_prop, value); + length = njs_string_prop(vm, &string_prop, value); p = string_prop.start; end = p + string_prop.size; @@ -358,8 +344,10 @@ njs_object_iterate(njs_vm_t *vm, njs_iterator_args_t *args, /* ASCII string. */ for (i = from; i < to; i++) { - /* This cannot fail. */ - (void) njs_string_new(vm, &character, p + i, 1, 1); + ret = njs_string_new(vm, &character, p + i, 1, 1); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_ERROR; + } ret = handler(vm, args, &character, i, retval); if (njs_slow_path(ret != NJS_OK)) { @@ -377,8 +365,10 @@ njs_object_iterate(njs_vm_t *vm, njs_iterator_args_t *args, for (i = from; i < to; i++) { pos = njs_utf8_next(p, end); - /* This cannot fail. */ - (void) njs_string_new(vm, &character, p, pos - p, 1); + ret = njs_string_new(vm, &character, p, pos - p, 1); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_ERROR; + } ret = handler(vm, args, &character, i, retval); if (njs_slow_path(ret != NJS_OK)) { @@ -502,7 +492,7 @@ njs_object_iterate_reverse(njs_vm_t *vm, njs_iterator_args_t *args, value = njs_object_value(value); } - length = njs_string_prop(&string_prop, value); + length = njs_string_prop(vm, &string_prop, value); end = string_prop.start + string_prop.size; if ((size_t) length == string_prop.size) { @@ -513,8 +503,10 @@ njs_object_iterate_reverse(njs_vm_t *vm, njs_iterator_args_t *args, i = from + 1; while (i-- > to) { - /* This cannot fail. */ - (void) njs_string_new(vm, &character, p, 1, 1); + ret = njs_string_new(vm, &character, p, 1, 1); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_ERROR; + } ret = handler(vm, args, &character, i, retval); if (njs_slow_path(ret != NJS_OK)) { @@ -542,8 +534,10 @@ njs_object_iterate_reverse(njs_vm_t *vm, njs_iterator_args_t *args, while (i-- > to) { pos = njs_utf8_prev(p, string_prop.start); - /* This cannot fail. */ - (void) njs_string_new(vm, &character, pos, p - pos , 1); + ret = njs_string_new(vm, &character, pos, p - pos , 1); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_ERROR; + } ret = handler(vm, args, &character, i, retval); if (njs_slow_path(ret != NJS_OK)) { @@ -616,7 +610,8 @@ njs_iterator_object_handler(njs_vm_t *vm, njs_iterator_handler_t handler, njs_value_t prop, *entry; if (key != NULL) { - ret = njs_value_property(vm, njs_value_arg(&args->value), key, &prop); + ret = njs_value_property_val(vm, njs_value_arg(&args->value), key, + &prop); if (njs_slow_path(ret == NJS_ERROR)) { return ret; } diff --git a/src/njs_json.c b/src/njs_json.c index 8ba13314..e79b1eb4 100644 --- a/src/njs_json.c +++ b/src/njs_json.c @@ -63,7 +63,7 @@ static const u_char *njs_json_skip_space(const u_char *start, const u_char *end); static njs_int_t njs_json_internalize_property(njs_vm_t *vm, - njs_function_t *reviver, njs_value_t *holder, njs_value_t *name, + njs_function_t *reviver, njs_value_t *holder, uint32_t atom_id, njs_int_t depth, njs_value_t *retval); static void njs_json_parse_exception(njs_json_parse_ctx_t *ctx, const char *msg, const u_char *pos); @@ -80,15 +80,15 @@ static njs_int_t njs_json_stringify_array(njs_json_stringify_t *stringify); static njs_int_t njs_json_append_value(njs_vm_t *vm, njs_chb_t *chain, njs_value_t *value); -static void njs_json_append_string(njs_chb_t *chain, const njs_value_t *value, - char quote); +static void njs_json_append_string(njs_vm_t *vm, njs_chb_t *chain, + const njs_value_t *value, char quote); static void njs_json_append_number(njs_chb_t *chain, const njs_value_t *value); static njs_object_t *njs_json_wrap_value(njs_vm_t *vm, njs_value_t *wrapper, const njs_value_t *value); -static const njs_object_prop_t njs_json_object_properties[]; +static const njs_object_prop_init_t njs_json_object_properties[]; static njs_int_t @@ -112,7 +112,7 @@ njs_json_parse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } } - (void) njs_string_prop(&string, text); + (void) njs_string_prop(vm, &string, text); p = string.start; end = p + string.size; @@ -149,9 +149,8 @@ njs_json_parse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } return njs_json_internalize_property(vm, njs_function(reviver), - &wrapper, - njs_value_arg(&njs_string_empty), - 0, retval); + &wrapper, NJS_ATOM_STRING_empty, 0, + retval); } njs_value_assign(retval, &value); @@ -166,7 +165,7 @@ njs_vm_json_parse(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, { njs_function_t *parse; - parse = njs_function(&njs_json_object_properties[1].u.value); + parse = njs_function(&njs_json_object_properties[1].desc.u.value); return njs_vm_invoke(vm, parse, args, nargs, retval); } @@ -225,7 +224,7 @@ njs_json_stringify(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, switch (space->type) { case NJS_STRING: - length = njs_string_prop(&prop, space); + length = njs_string_prop(vm, &prop, space); p = njs_string_offset(&prop, njs_min(length, 10)); stringify->space.start = prop.start; @@ -272,7 +271,7 @@ njs_vm_json_stringify(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, { njs_function_t *stringify; - stringify = njs_function(&njs_json_object_properties[2].u.value); + stringify = njs_function(&njs_json_object_properties[2].desc.u.value); return njs_vm_invoke(vm, stringify, args, nargs, retval); } @@ -336,11 +335,11 @@ static const u_char * njs_json_parse_object(njs_json_parse_ctx_t *ctx, njs_value_t *value, const u_char *p) { - njs_int_t ret; - njs_object_t *object; - njs_value_t prop_name, prop_value; - njs_object_prop_t *prop; - njs_lvlhsh_query_t lhq; + njs_int_t ret; + njs_object_t *object; + njs_value_t prop_name, prop_value; + njs_object_prop_t *prop; + njs_flathsh_query_t lhq; if (njs_slow_path(--ctx->depth == 0)) { njs_json_parse_exception(ctx, "Nested too deep", p); @@ -395,19 +394,18 @@ njs_json_parse_object(njs_json_parse_ctx_t *ctx, njs_value_t *value, return NULL; } - prop = njs_object_prop_alloc(ctx->vm, &prop_name, &prop_value, 1); + prop = njs_object_prop_alloc(ctx->vm, &prop_value, 1); if (njs_slow_path(prop == NULL)) { goto memory_error; } - njs_string_get(&prop_name, &lhq.key); - lhq.key_hash = njs_djb_hash(lhq.key.start, lhq.key.length); lhq.value = prop; + lhq.key_hash = prop_name.atom_id; lhq.replace = 1; lhq.pool = ctx->pool; lhq.proto = &njs_object_hash_proto; - ret = njs_lvlhsh_insert(&object->hash, &lhq); + ret = njs_flathsh_unique_insert(&object->hash, &lhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(ctx->vm, "lvlhsh insert/replace failed"); return NULL; @@ -734,7 +732,7 @@ njs_json_parse_string(njs_json_parse_ctx_t *ctx, njs_value_t *value, start = dst; } - ret = njs_string_create(ctx->vm, value, (u_char *) start, size); + ret = njs_atom_string_create(ctx->vm, value, (u_char *) start, size); if (njs_slow_path(ret != NJS_OK)) { return NULL; } @@ -829,12 +827,12 @@ njs_json_skip_space(const u_char *start, const u_char *end) static njs_int_t njs_json_internalize_property(njs_vm_t *vm, njs_function_t *reviver, - njs_value_t *holder, njs_value_t *name, njs_int_t depth, + njs_value_t *holder, uint32_t atom_id, njs_int_t depth, njs_value_t *retval) { int64_t k, length; njs_int_t ret; - njs_value_t val, new_elem, index; + njs_value_t val, new_elem; njs_value_t arguments[3]; njs_array_t *keys; @@ -843,7 +841,7 @@ njs_json_internalize_property(njs_vm_t *vm, njs_function_t *reviver, return NJS_ERROR; } - ret = njs_value_property(vm, holder, name, &val); + ret = njs_value_property(vm, holder, atom_id, &val); if (njs_slow_path(ret == NJS_ERROR)) { return NJS_ERROR; } @@ -859,19 +857,21 @@ njs_json_internalize_property(njs_vm_t *vm, njs_function_t *reviver, for (k = 0; k < keys->length; k++) { ret = njs_json_internalize_property(vm, reviver, &val, - &keys->start[k], depth, - &new_elem); + keys->start[k].atom_id, + depth, &new_elem); if (njs_slow_path(ret != NJS_OK)) { goto done; } if (njs_is_undefined(&new_elem)) { - ret = njs_value_property_delete(vm, &val, &keys->start[k], + ret = njs_value_property_delete(vm, &val, + keys->start[k].atom_id, NULL, 0); } else { - ret = njs_value_property_set(vm, &val, &keys->start[k], + ret = njs_value_property_set(vm, &val, + keys->start[k].atom_id, &new_elem); } @@ -888,12 +888,8 @@ njs_json_internalize_property(njs_vm_t *vm, njs_function_t *reviver, } for (k = 0; k < length; k++) { - ret = njs_int64_to_string(vm, &index, k); - if (njs_slow_path(ret != NJS_OK)) { - return NJS_ERROR; - } - - ret = njs_json_internalize_property(vm, reviver, &val, &index, + ret = njs_json_internalize_property(vm, reviver, &val, + njs_number_atom(k), depth, &new_elem); if (njs_slow_path(ret != NJS_OK)) { @@ -901,10 +897,13 @@ njs_json_internalize_property(njs_vm_t *vm, njs_function_t *reviver, } if (njs_is_undefined(&new_elem)) { - ret = njs_value_property_delete(vm, &val, &index, NULL, 0); + ret = njs_value_property_delete(vm, &val, + njs_number_atom(k), NULL, + 0); } else { - ret = njs_value_property_set(vm, &val, &index, &new_elem); + ret = njs_value_property_set(vm, &val, njs_number_atom(k), + &new_elem); } if (njs_slow_path(ret == NJS_ERROR)) { @@ -915,7 +914,7 @@ njs_json_internalize_property(njs_vm_t *vm, njs_function_t *reviver, } njs_value_assign(&arguments[0], holder); - njs_value_assign(&arguments[1], name); + njs_atom_to_value(vm, &arguments[1], atom_id); njs_value_assign(&arguments[2], &val); ret = njs_function_apply(vm, reviver, arguments, 3, retval); @@ -1123,7 +1122,7 @@ njs_json_stringify_iterator(njs_json_stringify_t *stringify, key = &state->keys->start[state->index]; } - ret = njs_value_property(stringify->vm, &state->value, key, value); + ret = njs_value_property_val(stringify->vm, &state->value, key, value); if (njs_slow_path(ret == NJS_ERROR)) { return ret; } @@ -1161,7 +1160,7 @@ njs_json_stringify_iterator(njs_json_stringify_t *stringify, state->written = 1; if (!state->array) { - njs_json_append_string(&chain, key, '\"'); + njs_json_append_string(stringify->vm, &chain, key, '\"'); njs_chb_append_literal(&chain,":"); if (stringify->space.length != 0) { njs_chb_append_literal(&chain," "); @@ -1232,14 +1231,13 @@ memory_error: static njs_function_t * njs_object_to_json_function(njs_vm_t *vm, njs_value_t *value) { - njs_int_t ret; - njs_value_t retval; - njs_lvlhsh_query_t lhq; - - static const njs_value_t to_json_string = njs_string("toJSON"); + njs_int_t ret; + njs_value_t retval; + njs_flathsh_query_t lhq; if (njs_is_object(value)) { - njs_object_property_init(&lhq, &to_json_string, NJS_TO_JSON_HASH); + lhq.proto = &njs_object_hash_proto; + lhq.key_hash = NJS_ATOM_STRING_toJSON; ret = njs_object_property(vm, njs_object(value), &lhq, &retval); @@ -1258,6 +1256,7 @@ static njs_int_t njs_json_stringify_to_json(njs_json_stringify_t* stringify, njs_json_state_t *state, njs_value_t *key, njs_value_t *value) { + njs_int_t ret; njs_value_t arguments[2]; njs_function_t *to_json; @@ -1276,7 +1275,10 @@ njs_json_stringify_to_json(njs_json_stringify_t* stringify, arguments[1] = *key; } else { - njs_uint32_to_string(&arguments[1], state->index); + ret = njs_uint32_to_string(stringify->vm, &arguments[1], state->index); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_ERROR; + } } return njs_function_apply(stringify->vm, to_json, arguments, 2, @@ -1288,6 +1290,7 @@ static njs_int_t njs_json_stringify_replacer(njs_json_stringify_t* stringify, njs_json_state_t *state, njs_value_t *key, njs_value_t *value) { + njs_int_t ret; njs_value_t arguments[3]; if (!njs_is_function(&stringify->replacer)) { @@ -1301,7 +1304,10 @@ njs_json_stringify_replacer(njs_json_stringify_t* stringify, arguments[1] = *key; } else { - njs_uint32_to_string(&arguments[1], state->index); + ret = njs_uint32_to_string(stringify->vm, &arguments[1], state->index); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_ERROR; + } } return njs_function_apply(stringify->vm, njs_function(&stringify->replacer), @@ -1328,7 +1334,7 @@ njs_json_stringify_array(njs_json_stringify_t *stringify) } item = njs_array_push(stringify->vm, properties); - njs_value_assign(item, &njs_string_empty); + njs_set_empty_string(stringify->vm, item); for (i = 0; i < length; i++) { ret = njs_value_property_i64(stringify->vm, &stringify->replacer, i, @@ -1373,7 +1379,9 @@ njs_json_stringify_array(njs_json_stringify_t *stringify) } for (k = 0; k < properties->length; k++) { - if (njs_values_strict_equal(value, &properties->start[k]) == 1) { + if (njs_values_strict_equal(stringify->vm, value, + &properties->start[k]) == 1) + { break; } } @@ -1428,7 +1436,7 @@ njs_json_append_value(njs_vm_t *vm, njs_chb_t *chain, njs_value_t *value) switch (value->type) { case NJS_STRING: - njs_json_append_string(chain, value, '\"'); + njs_json_append_string(vm, chain, value, '\"'); break; case NJS_NUMBER: @@ -1459,7 +1467,8 @@ njs_json_append_value(njs_vm_t *vm, njs_chb_t *chain, njs_value_t *value) static void -njs_json_append_string(njs_chb_t *chain, const njs_value_t *value, char quote) +njs_json_append_string(njs_vm_t *vm, njs_chb_t *chain, const njs_value_t *value, + char quote) { size_t size; u_char c, *dst, *dst_end; @@ -1470,7 +1479,7 @@ njs_json_append_string(njs_chb_t *chain, const njs_value_t *value, char quote) static char hex2char[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; - (void) njs_string_prop(&string, value); + (void) njs_string_prop(vm, &string, value); p = string.start; end = p + string.size; @@ -1588,9 +1597,9 @@ static njs_object_t * njs_json_wrap_value(njs_vm_t *vm, njs_value_t *wrapper, const njs_value_t *value) { - njs_int_t ret; - njs_object_prop_t *prop; - njs_lvlhsh_query_t lhq; + njs_int_t ret; + njs_object_prop_t *prop; + njs_flathsh_query_t lhq; wrapper->data.u.object = njs_object_alloc(vm); if (njs_slow_path(njs_object(wrapper) == NULL)) { @@ -1600,20 +1609,18 @@ njs_json_wrap_value(njs_vm_t *vm, njs_value_t *wrapper, wrapper->type = NJS_OBJECT; wrapper->data.truth = 1; - lhq.replace = 0; - lhq.proto = &njs_object_hash_proto; - lhq.pool = vm->mem_pool; - lhq.key = njs_str_value(""); - lhq.key_hash = NJS_DJB_HASH_INIT; - - prop = njs_object_prop_alloc(vm, &njs_string_empty, value, 1); + prop = njs_object_prop_alloc(vm, value, 1); if (njs_slow_path(prop == NULL)) { return NULL; } lhq.value = prop; + lhq.key_hash = NJS_ATOM_STRING_empty; + lhq.replace = 0; + lhq.pool = vm->mem_pool; + lhq.proto = &njs_object_hash_proto; - ret = njs_lvlhsh_insert(njs_object_hash(wrapper), &lhq); + ret = njs_flathsh_unique_insert(njs_object_hash(wrapper), &lhq); if (njs_slow_path(ret != NJS_OK)) { return NULL; } @@ -1622,18 +1629,14 @@ njs_json_wrap_value(njs_vm_t *vm, njs_value_t *wrapper, } -static const njs_object_prop_t njs_json_object_properties[] = +static const njs_object_prop_init_t njs_json_object_properties[] = { - { - .type = NJS_PROPERTY, - .name = njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG), - .u.value = njs_string("JSON"), - .configurable = 1, - }, + NJS_DECLARE_PROP_VALUE(SYMBOL_toStringTag, njs_ascii_strval("JSON"), + NJS_OBJECT_PROP_VALUE_C), - NJS_DECLARE_PROP_NATIVE("parse", njs_json_parse, 2, 0), + NJS_DECLARE_PROP_NATIVE(STRING_parse, njs_json_parse, 2, 0), - NJS_DECLARE_PROP_NATIVE("stringify", njs_json_stringify, 3, 0), + NJS_DECLARE_PROP_NATIVE(STRING_stringify, njs_json_stringify, 3, 0), }; @@ -1653,8 +1656,6 @@ njs_dump_terminal(njs_json_stringify_t *stringify, njs_chb_t *chain, njs_typed_array_t *array; njs_string_prop_t string; - static const njs_value_t name_string = njs_string("name"); - njs_int_t (*to_string)(njs_vm_t *, njs_value_t *, const njs_value_t *); switch (value->type) { @@ -1677,10 +1678,10 @@ njs_dump_terminal(njs_json_stringify_t *stringify, njs_chb_t *chain, break; case NJS_STRING: - njs_string_get(value, &str); + njs_string_get(stringify->vm, value, &str); if (!console || stringify->depth != 0) { - njs_json_append_string(chain, value, '\''); + njs_json_append_string(stringify->vm, chain, value, '\''); return NJS_OK; } @@ -1694,7 +1695,7 @@ njs_dump_terminal(njs_json_stringify_t *stringify, njs_chb_t *chain, return NJS_ERROR; } - njs_string_get(&str_val, &str); + njs_string_get(stringify->vm, &str_val, &str); njs_chb_append_str(chain, &str); break; @@ -1731,7 +1732,7 @@ njs_dump_terminal(njs_json_stringify_t *stringify, njs_chb_t *chain, return NJS_ERROR; } - njs_string_get(&str_val, &str); + njs_string_get(stringify->vm, &str_val, &str); njs_chb_sprintf(chain, 16 + str.length, "[Number: %V]", &str); break; @@ -1741,7 +1742,7 @@ njs_dump_terminal(njs_json_stringify_t *stringify, njs_chb_t *chain, return NJS_ERROR; } - njs_string_get(&str_val, &str); + njs_string_get(stringify->vm, &str_val, &str); njs_chb_sprintf(chain, 16 + str.length, "[Symbol: %V]", &str); break; @@ -1749,7 +1750,7 @@ njs_dump_terminal(njs_json_stringify_t *stringify, njs_chb_t *chain, case NJS_STRING: default: njs_chb_append_literal(chain, "[String: "); - njs_json_append_string(chain, value, '\''); + njs_json_append_string(stringify->vm, chain, value, '\''); njs_chb_append_literal(chain, "]"); break; } @@ -1764,14 +1765,14 @@ njs_dump_terminal(njs_json_stringify_t *stringify, njs_chb_t *chain, str = njs_str_value(""); } - ret = njs_value_property(stringify->vm, value, - njs_value_arg(&name_string), &tag); + ret = njs_value_property(stringify->vm, value, NJS_ATOM_STRING_name, + &tag); if (njs_slow_path(ret == NJS_ERROR)) { return ret; } if (njs_is_string(&tag)) { - njs_string_get(&tag, &str); + njs_string_get(stringify->vm, &tag, &str); } if (str.length != 0) { @@ -1791,7 +1792,7 @@ njs_dump_terminal(njs_json_stringify_t *stringify, njs_chb_t *chain, } if (ret == NJS_OK) { - (void) njs_string_prop(&string, &tag); + (void) njs_string_prop(stringify->vm, &string, &tag); njs_chb_append(chain, string.start, string.size); njs_chb_append_literal(chain, " "); } @@ -1841,7 +1842,7 @@ njs_dump_terminal(njs_json_stringify_t *stringify, njs_chb_t *chain, return NJS_ERROR; } - njs_string_get(&str_val, &str); + njs_string_get(stringify->vm, &str_val, &str); njs_chb_append_str(chain, &str); break; @@ -1874,7 +1875,7 @@ njs_dump_visited(njs_vm_t *vm, njs_json_stringify_t *stringify, depth = stringify->depth - 1; for (; depth >= 0; depth--) { - if (njs_values_same(&stringify->states[depth].value, value)) { + if (njs_values_same(vm, &stringify->states[depth].value, value)) { return 1; } } @@ -1943,11 +1944,6 @@ njs_dump_empty(njs_json_stringify_t *stringify, njs_json_state_t *state, } -static const njs_value_t string_get = njs_string("[Getter]"); -static const njs_value_t string_set = njs_string("[Setter]"); -static const njs_value_t string_get_set = njs_long_string("[Getter/Setter]"); - - njs_int_t njs_vm_value_dump(njs_vm_t *vm, njs_str_t *retval, njs_value_t *value, njs_uint_t console, njs_uint_t indent) @@ -1955,7 +1951,7 @@ njs_vm_value_dump(njs_vm_t *vm, njs_str_t *retval, njs_value_t *value, njs_int_t ret; njs_chb_t chain; njs_str_t str; - njs_value_t *key, *val, tag, exception; + njs_value_t *key, *val, s, tag, exception; njs_json_state_t *state; njs_string_prop_t string; njs_object_prop_t *prop; @@ -2009,7 +2005,7 @@ njs_vm_value_dump(njs_vm_t *vm, njs_str_t *retval, njs_value_t *value, } if (ret == NJS_OK) { - (void) njs_string_prop(&string, &tag); + (void) njs_string_prop(vm, &string, &tag); njs_chb_append(&chain, string.start, string.size); njs_chb_append_literal(&chain, " "); } @@ -2032,22 +2028,17 @@ njs_vm_value_dump(njs_vm_t *vm, njs_str_t *retval, njs_value_t *value, continue; } - njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0, 0); + njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0); key = &state->keys->start[state->index++]; - if(state->array) { - if (key->type == NJS_STRING) { - njs_string_get(key, &str); - if (str.length == 6 && memcmp(str.start, "length", 6) == 0) { - continue; - } - } + if (state->array && key->atom_id == NJS_ATOM_STRING_length) { + continue; } state->key = key; - ret = njs_property_query(vm, &pq, &state->value, key); + ret = njs_property_query_val(vm, &pq, &state->value, key); if (njs_slow_path(ret != NJS_OK)) { if (ret == NJS_DECLINED) { continue; @@ -2074,7 +2065,7 @@ njs_vm_value_dump(njs_vm_t *vm, njs_str_t *retval, njs_value_t *value, njs_dump_empty(stringify, state, &chain, 1); if (!state->array || isnan(njs_key_to_index(key))) { - njs_key_string_get(vm, key, &pq.lhq.key); + njs_atom_string_get(vm, key->atom_id, &pq.lhq.key); njs_chb_append(&chain, pq.lhq.key.start, pq.lhq.key.length); njs_chb_append_literal(&chain, ":"); if (stringify->space.length != 0) { @@ -2087,7 +2078,8 @@ njs_vm_value_dump(njs_vm_t *vm, njs_str_t *retval, njs_value_t *value, if (prop->type == NJS_PROPERTY_HANDLER) { pq.scratch = *prop; prop = &pq.scratch; - ret = njs_prop_handler(prop)(vm, prop, &state->value, NULL, + ret = njs_prop_handler(prop)(vm, prop, pq.lhq.key_hash, + &state->value, NULL, njs_prop_value(prop)); if (njs_slow_path(ret == NJS_ERROR)) { @@ -2100,15 +2092,17 @@ njs_vm_value_dump(njs_vm_t *vm, njs_str_t *retval, njs_value_t *value, if (njs_is_accessor_descriptor(prop)) { if (njs_prop_getter(prop) != NULL) { if (njs_prop_setter(prop) != NULL) { - val = njs_value_arg(&string_get_set); + njs_atom_to_value(vm, &s, NJS_ATOM_STRING__Getter_Setter_); } else { - val = njs_value_arg(&string_get); + njs_atom_to_value(vm, &s, NJS_ATOM_STRING__Getter_); } } else { - val = njs_value_arg(&string_set); + njs_atom_to_value(vm, &s, NJS_ATOM_STRING__Setter_); } + + val = &s; } if (njs_dump_is_recursive(val)) { diff --git a/src/njs_lexer.c b/src/njs_lexer.c index 4a51c668..4131301d 100644 --- a/src/njs_lexer.c +++ b/src/njs_lexer.c @@ -18,7 +18,6 @@ struct njs_lexer_multi_s { }; -static njs_int_t njs_lexer_hash_test(njs_lvlhsh_query_t *lhq, void *data); static njs_int_t njs_lexer_word(njs_lexer_t *lexer, njs_lexer_token_t *token); static void njs_lexer_string(njs_lexer_t *lexer, njs_lexer_token_t *token, u_char quote); @@ -28,16 +27,6 @@ static void njs_lexer_multi(njs_lexer_t *lexer, njs_lexer_token_t *token, static void njs_lexer_division(njs_lexer_t *lexer, njs_lexer_token_t *token); -const njs_lvlhsh_proto_t njs_lexer_hash_proto - njs_aligned(64) = -{ - NJS_LVLHSH_DEFAULT, - njs_lexer_hash_test, - njs_lvlhsh_alloc, - njs_lvlhsh_free, -}; - - static const uint8_t njs_tokens[256] njs_aligned(64) = { NJS_TOKEN_ILLEGAL, NJS_TOKEN_ILLEGAL, @@ -290,21 +279,13 @@ static const njs_lexer_multi_t njs_assignment_token[] = { njs_int_t njs_lexer_init(njs_vm_t *vm, njs_lexer_t *lexer, njs_str_t *file, - u_char *start, u_char *end, njs_uint_t runtime, - njs_int_t init_lexer_memory) + u_char *start, u_char *end) { - if (init_lexer_memory) { - njs_memzero(lexer, sizeof(njs_lexer_t)); - - } - lexer->file = *file; lexer->start = start; lexer->end = end; lexer->line = 1; - lexer->keywords_hash = (runtime) ? &vm->keywords_hash - : &vm->shared->keywords_hash; - lexer->mem_pool = vm->mem_pool; + lexer->vm = vm; njs_queue_init(&lexer->preread); @@ -316,7 +297,7 @@ njs_int_t njs_lexer_in_stack_init(njs_lexer_t *lexer) { lexer->in_stack_size = 128; - lexer->in_stack = njs_mp_zalloc(lexer->mem_pool, lexer->in_stack_size); + lexer->in_stack = njs_mp_zalloc(lexer->vm->mem_pool, lexer->in_stack_size); if (lexer->in_stack == NULL) { return NJS_ERROR; } @@ -345,7 +326,7 @@ njs_lexer_in_stack_push(njs_lexer_t *lexer) size = lexer->in_stack_size; lexer->in_stack_size = size * 2; - tmp = njs_mp_alloc(lexer->mem_pool, size * 2); + tmp = njs_mp_alloc(lexer->vm->mem_pool, size * 2); if (tmp == NULL) { return NJS_ERROR; } @@ -353,7 +334,7 @@ njs_lexer_in_stack_push(njs_lexer_t *lexer) memcpy(tmp, lexer->in_stack, size); memset(&tmp[size], 0, size); - njs_mp_free(lexer->mem_pool, lexer->in_stack); + njs_mp_free(lexer->vm->mem_pool, lexer->in_stack); lexer->in_stack = tmp; return NJS_OK; @@ -417,7 +398,7 @@ njs_lexer_next_token(njs_lexer_t *lexer) njs_int_t ret; njs_lexer_token_t *token; - token = njs_mp_zalloc(lexer->mem_pool, sizeof(njs_lexer_token_t)); + token = njs_mp_zalloc(lexer->vm->mem_pool, sizeof(njs_lexer_token_t)); if (njs_slow_path(token == NULL)) { return NULL; } @@ -537,7 +518,7 @@ njs_lexer_consume_token(njs_lexer_t *lexer, unsigned length) njs_queue_remove(lnk); - njs_mp_free(lexer->mem_pool, token); + njs_mp_free(lexer->vm->mem_pool, token); } } @@ -709,76 +690,12 @@ njs_lexer_make_token(njs_lexer_t *lexer, njs_lexer_token_t *token) } -static njs_int_t -njs_lexer_hash_test(njs_lvlhsh_query_t *lhq, void *data) -{ - njs_lexer_entry_t *entry; - - entry = data; - - if (entry->name.length == lhq->key.length - && memcmp(entry->name.start, lhq->key.start, lhq->key.length) == 0) - { - return NJS_OK; - } - - return NJS_DECLINED; -} - - -static njs_lexer_entry_t * -njs_lexer_keyword_find(njs_lexer_t *lexer, u_char *key, size_t length, - uint32_t hash) -{ - njs_int_t ret; - njs_lexer_entry_t *entry; - njs_lvlhsh_query_t lhq; - - lhq.key.start = key; - lhq.key.length = length; - - lhq.key_hash = hash; - lhq.proto = &njs_lexer_hash_proto; - - ret = njs_lvlhsh_find(lexer->keywords_hash, &lhq); - if (ret == NJS_OK) { - return lhq.value; - } - - entry = njs_mp_alloc(lexer->mem_pool, sizeof(njs_lexer_entry_t)); - if (njs_slow_path(entry == NULL)) { - return NULL; - } - - entry->name.start = njs_mp_alloc(lexer->mem_pool, length + 1); - if (njs_slow_path(entry->name.start == NULL)) { - return NULL; - } - - memcpy(entry->name.start, key, length); - - entry->name.start[length] = '\0'; - entry->name.length = length; - - lhq.value = entry; - lhq.pool = lexer->mem_pool; - - ret = njs_lvlhsh_insert(lexer->keywords_hash, &lhq); - if (njs_slow_path(ret != NJS_OK)) { - return NULL; - } - - return entry; -} - - static njs_int_t njs_lexer_word(njs_lexer_t *lexer, njs_lexer_token_t *token) { - u_char *p, c; - uint32_t hash_id; - const njs_lexer_entry_t *entry; - const njs_lexer_keyword_entry_t *key_entry; + u_char *p, c; + uint32_t hash_id; + const njs_value_t *entry; /* TODO: UTF-8 */ @@ -817,27 +734,23 @@ njs_lexer_word(njs_lexer_t *lexer, njs_lexer_token_t *token) token->text.length = p - token->text.start; lexer->start = p; - key_entry = njs_lexer_keyword(token->text.start, token->text.length); - - if (key_entry == NULL) { - entry = njs_lexer_keyword_find(lexer, token->text.start, - token->text.length, hash_id); - if (njs_slow_path(entry == NULL)) { - return NJS_ERROR; - } + entry = njs_atom_find_or_add(lexer->vm, token->text.start, + token->text.length, token->text.length, + hash_id); + if (njs_slow_path(entry == NULL)) { + return NJS_ERROR; + } + if (entry->string.token_type == NJS_KEYWORD_TYPE_UNDEF) { token->type = NJS_TOKEN_NAME; token->keyword_type = NJS_KEYWORD_TYPE_UNDEF; } else { - entry = &key_entry->value->entry; - token->type = key_entry->value->type; - - token->keyword_type = NJS_KEYWORD_TYPE_KEYWORD; - token->keyword_type |= key_entry->value->reserved; + token->type = entry->string.token_id; + token->keyword_type = entry->string.token_type; } - token->unique_id = (uintptr_t) entry; + token->atom_id = entry->atom_id; return NJS_OK; } diff --git a/src/njs_lexer.h b/src/njs_lexer.h index 6b1d04b6..42f612a6 100644 --- a/src/njs_lexer.h +++ b/src/njs_lexer.h @@ -219,12 +219,6 @@ typedef enum { typedef struct { - njs_str_t name; -} njs_lexer_entry_t; - - -typedef struct { - njs_lexer_entry_t entry; njs_token_type_t type; njs_bool_t reserved; } njs_keyword_t; @@ -243,7 +237,7 @@ typedef struct { njs_token_type_t type:16; njs_keyword_type_t keyword_type; uint32_t line; - uintptr_t unique_id; + uint32_t atom_id; njs_str_t text; double number; njs_queue_link_t link; @@ -261,9 +255,7 @@ typedef struct { uint32_t line; njs_str_t file; - njs_lvlhsh_t *keywords_hash; - - njs_mp_t *mem_pool; + njs_vm_t *vm; u_char *start; u_char *end; @@ -276,8 +268,7 @@ typedef struct { njs_int_t njs_lexer_init(njs_vm_t *vm, njs_lexer_t *lexer, njs_str_t *file, - u_char *start, u_char *end, njs_uint_t runtime, - njs_int_t init_lexer_memory); + u_char *start, u_char *end); njs_lexer_token_t *njs_lexer_token(njs_lexer_t *lexer, njs_bool_t with_end_line); @@ -297,10 +288,13 @@ const njs_lexer_keyword_entry_t *njs_lexer_keyword(const u_char *key, njs_int_t njs_lexer_keywords(njs_arr_t *array); -njs_inline const njs_lexer_entry_t * -njs_lexer_entry(uintptr_t unique_id) +njs_inline void +njs_lexer_entry(njs_vm_t *vm, uintptr_t atom_id, njs_str_t *entry) { - return (const njs_lexer_entry_t *) unique_id; + njs_value_t value; + + njs_atom_to_value(vm, &value, atom_id); + njs_string_get(vm, &value, entry); } @@ -363,8 +357,4 @@ njs_lexer_token_is_identifier_reference(njs_lexer_token_t *token) return njs_lexer_token_is_binding_identifier(token); } - -extern const njs_lvlhsh_proto_t njs_lexer_hash_proto; - - #endif /* _NJS_LEXER_H_INCLUDED_ */ diff --git a/src/njs_lexer_tables.h b/src/njs_lexer_tables.h deleted file mode 100644 index e6503252..00000000 --- a/src/njs_lexer_tables.h +++ /dev/null @@ -1,445 +0,0 @@ - -/* - * Copyright (C) Nginx, Inc. - * - * Do not edit, generated by: utils/lexer_keyword.py. - */ - - -#ifndef _NJS_LEXER_TABLES_H_INCLUDED_ -#define _NJS_LEXER_TABLES_H_INCLUDED_ - - -static const njs_keyword_t njs_lexer_kws[54] = -{ - { - .entry = { njs_str("arguments") }, - .type = NJS_TOKEN_ARGUMENTS, - .reserved = 0 - }, - - { - .entry = { njs_str("async") }, - .type = NJS_TOKEN_ASYNC, - .reserved = 0 - }, - - { - .entry = { njs_str("await") }, - .type = NJS_TOKEN_AWAIT, - .reserved = 1 - }, - - { - .entry = { njs_str("break") }, - .type = NJS_TOKEN_BREAK, - .reserved = 1 - }, - - { - .entry = { njs_str("case") }, - .type = NJS_TOKEN_CASE, - .reserved = 1 - }, - - { - .entry = { njs_str("catch") }, - .type = NJS_TOKEN_CATCH, - .reserved = 1 - }, - - { - .entry = { njs_str("class") }, - .type = NJS_TOKEN_CLASS, - .reserved = 1 - }, - - { - .entry = { njs_str("const") }, - .type = NJS_TOKEN_CONST, - .reserved = 1 - }, - - { - .entry = { njs_str("continue") }, - .type = NJS_TOKEN_CONTINUE, - .reserved = 1 - }, - - { - .entry = { njs_str("debugger") }, - .type = NJS_TOKEN_DEBUGGER, - .reserved = 1 - }, - - { - .entry = { njs_str("default") }, - .type = NJS_TOKEN_DEFAULT, - .reserved = 1 - }, - - { - .entry = { njs_str("delete") }, - .type = NJS_TOKEN_DELETE, - .reserved = 1 - }, - - { - .entry = { njs_str("do") }, - .type = NJS_TOKEN_DO, - .reserved = 1 - }, - - { - .entry = { njs_str("else") }, - .type = NJS_TOKEN_ELSE, - .reserved = 1 - }, - - { - .entry = { njs_str("enum") }, - .type = NJS_TOKEN_ENUM, - .reserved = 1 - }, - - { - .entry = { njs_str("eval") }, - .type = NJS_TOKEN_EVAL, - .reserved = 0 - }, - - { - .entry = { njs_str("export") }, - .type = NJS_TOKEN_EXPORT, - .reserved = 1 - }, - - { - .entry = { njs_str("extends") }, - .type = NJS_TOKEN_EXTENDS, - .reserved = 1 - }, - - { - .entry = { njs_str("false") }, - .type = NJS_TOKEN_FALSE, - .reserved = 1 - }, - - { - .entry = { njs_str("finally") }, - .type = NJS_TOKEN_FINALLY, - .reserved = 1 - }, - - { - .entry = { njs_str("for") }, - .type = NJS_TOKEN_FOR, - .reserved = 1 - }, - - { - .entry = { njs_str("from") }, - .type = NJS_TOKEN_FROM, - .reserved = 0 - }, - - { - .entry = { njs_str("function") }, - .type = NJS_TOKEN_FUNCTION, - .reserved = 1 - }, - - { - .entry = { njs_str("if") }, - .type = NJS_TOKEN_IF, - .reserved = 1 - }, - - { - .entry = { njs_str("implements") }, - .type = NJS_TOKEN_IMPLEMENTS, - .reserved = 1 - }, - - { - .entry = { njs_str("import") }, - .type = NJS_TOKEN_IMPORT, - .reserved = 1 - }, - - { - .entry = { njs_str("in") }, - .type = NJS_TOKEN_IN, - .reserved = 1 - }, - - { - .entry = { njs_str("instanceof") }, - .type = NJS_TOKEN_INSTANCEOF, - .reserved = 1 - }, - - { - .entry = { njs_str("interface") }, - .type = NJS_TOKEN_INTERFACE, - .reserved = 1 - }, - - { - .entry = { njs_str("let") }, - .type = NJS_TOKEN_LET, - .reserved = 1 - }, - - { - .entry = { njs_str("meta") }, - .type = NJS_TOKEN_META, - .reserved = 0 - }, - - { - .entry = { njs_str("new") }, - .type = NJS_TOKEN_NEW, - .reserved = 1 - }, - - { - .entry = { njs_str("null") }, - .type = NJS_TOKEN_NULL, - .reserved = 1 - }, - - { - .entry = { njs_str("of") }, - .type = NJS_TOKEN_OF, - .reserved = 0 - }, - - { - .entry = { njs_str("package") }, - .type = NJS_TOKEN_PACKAGE, - .reserved = 1 - }, - - { - .entry = { njs_str("private") }, - .type = NJS_TOKEN_PRIVATE, - .reserved = 1 - }, - - { - .entry = { njs_str("protected") }, - .type = NJS_TOKEN_PROTECTED, - .reserved = 1 - }, - - { - .entry = { njs_str("public") }, - .type = NJS_TOKEN_PUBLIC, - .reserved = 1 - }, - - { - .entry = { njs_str("return") }, - .type = NJS_TOKEN_RETURN, - .reserved = 1 - }, - - { - .entry = { njs_str("static") }, - .type = NJS_TOKEN_STATIC, - .reserved = 1 - }, - - { - .entry = { njs_str("super") }, - .type = NJS_TOKEN_SUPER, - .reserved = 1 - }, - - { - .entry = { njs_str("switch") }, - .type = NJS_TOKEN_SWITCH, - .reserved = 1 - }, - - { - .entry = { njs_str("target") }, - .type = NJS_TOKEN_TARGET, - .reserved = 0 - }, - - { - .entry = { njs_str("this") }, - .type = NJS_TOKEN_THIS, - .reserved = 1 - }, - - { - .entry = { njs_str("throw") }, - .type = NJS_TOKEN_THROW, - .reserved = 1 - }, - - { - .entry = { njs_str("true") }, - .type = NJS_TOKEN_TRUE, - .reserved = 1 - }, - - { - .entry = { njs_str("try") }, - .type = NJS_TOKEN_TRY, - .reserved = 1 - }, - - { - .entry = { njs_str("typeof") }, - .type = NJS_TOKEN_TYPEOF, - .reserved = 1 - }, - - { - .entry = { njs_str("undefined") }, - .type = NJS_TOKEN_UNDEFINED, - .reserved = 0 - }, - - { - .entry = { njs_str("var") }, - .type = NJS_TOKEN_VAR, - .reserved = 1 - }, - - { - .entry = { njs_str("void") }, - .type = NJS_TOKEN_VOID, - .reserved = 1 - }, - - { - .entry = { njs_str("while") }, - .type = NJS_TOKEN_WHILE, - .reserved = 1 - }, - - { - .entry = { njs_str("with") }, - .type = NJS_TOKEN_WITH, - .reserved = 1 - }, - - { - .entry = { njs_str("yield") }, - .type = NJS_TOKEN_YIELD, - .reserved = 1 - }, -}; - - -static const njs_lexer_keyword_entry_t njs_lexer_keyword_entries[99] = -{ - { NULL, NULL, 98, 0 }, - { "continue", &njs_lexer_kws[8], 8, 0 }, - { "finally", &njs_lexer_kws[19], 7, 0 }, - { "return", &njs_lexer_kws[38], 6, 0 }, - { "static", &njs_lexer_kws[39], 6, 0 }, - { "async", &njs_lexer_kws[1], 5, 0 }, - { "break", &njs_lexer_kws[3], 5, 0 }, - { "interface", &njs_lexer_kws[28], 9, 0 }, - { "case", &njs_lexer_kws[4], 4, 0 }, - { "import", &njs_lexer_kws[25], 6, 0 }, - { "protected", &njs_lexer_kws[36], 9, 0 }, - { "switch", &njs_lexer_kws[41], 6, 0 }, - { "catch", &njs_lexer_kws[5], 5, 1 }, - { "delete", &njs_lexer_kws[11], 6, 0 }, - { "else", &njs_lexer_kws[13], 4, 0 }, - { "private", &njs_lexer_kws[35], 7, 0 }, - { "extends", &njs_lexer_kws[17], 7, 0 }, - { "this", &njs_lexer_kws[43], 4, 0 }, - { "false", &njs_lexer_kws[18], 5, 0 }, - { "await", &njs_lexer_kws[2], 5, 0 }, - { NULL, NULL, 0, 0 }, - { "public", &njs_lexer_kws[37], 6, 0 }, - { NULL, NULL, 0, 0 }, - { "class", &njs_lexer_kws[6], 5, 0 }, - { "const", &njs_lexer_kws[7], 5, 4 }, - { NULL, NULL, 0, 0 }, - { "try", &njs_lexer_kws[46], 3, 0 }, - { "null", &njs_lexer_kws[32], 4, 0 }, - { NULL, NULL, 0, 0 }, - { "do", &njs_lexer_kws[12], 2, 0 }, - { "var", &njs_lexer_kws[49], 3, 0 }, - { "if", &njs_lexer_kws[23], 2, 7 }, - { "implements", &njs_lexer_kws[24], 10, 0 }, - { "with", &njs_lexer_kws[52], 4, 0 }, - { NULL, NULL, 0, 0 }, - { "eval", &njs_lexer_kws[15], 4, 9 }, - { NULL, NULL, 0, 0 }, - { "target", &njs_lexer_kws[42], 6, 0 }, - { "enum", &njs_lexer_kws[14], 4, 10 }, - { "instanceof", &njs_lexer_kws[27], 10, 0 }, - { NULL, NULL, 0, 0 }, - { "debugger", &njs_lexer_kws[9], 8, 0 }, - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, - { "default", &njs_lexer_kws[10], 7, 0 }, - { "void", &njs_lexer_kws[50], 4, 0 }, - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, - { "undefined", &njs_lexer_kws[48], 9, 0 }, - { "from", &njs_lexer_kws[21], 4, 0 }, - { "package", &njs_lexer_kws[34], 7, 15 }, - { NULL, NULL, 0, 0 }, - { "yield", &njs_lexer_kws[53], 5, 0 }, - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, - { "of", &njs_lexer_kws[33], 2, 0 }, - { NULL, NULL, 0, 0 }, - { "function", &njs_lexer_kws[22], 8, 0 }, - { NULL, NULL, 0, 0 }, - { "true", &njs_lexer_kws[45], 4, 16 }, - { "new", &njs_lexer_kws[31], 3, 0 }, - { "export", &njs_lexer_kws[16], 6, 0 }, - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, - { "for", &njs_lexer_kws[20], 3, 0 }, - { "while", &njs_lexer_kws[51], 5, 0 }, - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, - { "typeof", &njs_lexer_kws[47], 6, 0 }, - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, - { "super", &njs_lexer_kws[40], 5, 0 }, - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, - { "let", &njs_lexer_kws[29], 3, 19 }, - { "in", &njs_lexer_kws[26], 2, 0 }, - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, - { "throw", &njs_lexer_kws[44], 5, 0 }, - { "arguments", &njs_lexer_kws[0], 9, 0 }, - { "meta", &njs_lexer_kws[30], 4, 0 }, - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, - { NULL, NULL, 0, 0 }, -}; - - -#endif /* _NJS_LEXER_TABLES_H_INCLUDED_ */ diff --git a/src/njs_main.h b/src/njs_main.h index 563065a1..e40fe085 100644 --- a/src/njs_main.h +++ b/src/njs_main.h @@ -45,6 +45,8 @@ #include #include #include +#include +#include #include #include #include @@ -56,9 +58,7 @@ #include #include -#include #include -#include #include #include #include diff --git a/src/njs_math.c b/src/njs_math.c index 6bc76fd1..b2892e7e 100644 --- a/src/njs_math.c +++ b/src/njs_math.c @@ -374,101 +374,132 @@ njs_object_math_random(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } -static const njs_object_prop_t njs_math_object_properties[] = +static const njs_object_prop_init_t njs_math_object_properties[] = { - { - .type = NJS_PROPERTY, - .name = njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG), - .u.value = njs_string("Math"), - .configurable = 1, - }, + NJS_DECLARE_PROP_VALUE(SYMBOL_toStringTag, njs_ascii_strval("Math"), + NJS_OBJECT_PROP_VALUE_C), - NJS_DECLARE_PROP_VALUE("E", njs_value(NJS_NUMBER, 1, M_E), 0), + NJS_DECLARE_PROP_VALUE(STRING_E, njs_value(NJS_NUMBER, 1, M_E), 0), - NJS_DECLARE_PROP_VALUE("LN10", njs_value(NJS_NUMBER, 1, M_LN10), 0), + NJS_DECLARE_PROP_VALUE(STRING_LN10, njs_value(NJS_NUMBER, 1, M_LN10), + 0), - NJS_DECLARE_PROP_VALUE("LN2", njs_value(NJS_NUMBER, 1, M_LN2), 0), + NJS_DECLARE_PROP_VALUE(STRING_LN2, njs_value(NJS_NUMBER, 1, M_LN2), 0), - NJS_DECLARE_PROP_VALUE("LOG10E", njs_value(NJS_NUMBER, 1, M_LOG10E), 0), + NJS_DECLARE_PROP_VALUE(STRING_LOG10E, + njs_value(NJS_NUMBER, 1, M_LOG10E), 0), - NJS_DECLARE_PROP_VALUE("LOG2E", njs_value(NJS_NUMBER, 1, M_LOG2E), 0), + NJS_DECLARE_PROP_VALUE(STRING_LOG2E, njs_value(NJS_NUMBER, 1, M_LOG2E), + 0), - NJS_DECLARE_PROP_VALUE("PI", njs_value(NJS_NUMBER, 1, M_PI), 0), + NJS_DECLARE_PROP_VALUE(STRING_PI, njs_value(NJS_NUMBER, 1, M_PI), 0), - NJS_DECLARE_PROP_VALUE("SQRT1_2", njs_value(NJS_NUMBER, 1, M_SQRT1_2), 0), + NJS_DECLARE_PROP_VALUE(STRING_SQRT1_2, + njs_value(NJS_NUMBER, 1, M_SQRT1_2), 0), - NJS_DECLARE_PROP_VALUE("SQRT2", njs_value(NJS_NUMBER, 1, M_SQRT2), 0), + NJS_DECLARE_PROP_VALUE(STRING_SQRT2, njs_value(NJS_NUMBER, 1, M_SQRT2), + 0), - NJS_DECLARE_PROP_NATIVE("abs", njs_object_math_func, 1, NJS_MATH_ABS), + NJS_DECLARE_PROP_NATIVE(STRING_abs, njs_object_math_func, 1, + NJS_MATH_ABS), - NJS_DECLARE_PROP_NATIVE("acos", njs_object_math_func, 1, NJS_MATH_ACOS), + NJS_DECLARE_PROP_NATIVE(STRING_acos, njs_object_math_func, 1, + NJS_MATH_ACOS), - NJS_DECLARE_PROP_NATIVE("acosh", njs_object_math_func, 1, NJS_MATH_ACOSH), + NJS_DECLARE_PROP_NATIVE(STRING_acosh, njs_object_math_func, 1, + NJS_MATH_ACOSH), - NJS_DECLARE_PROP_NATIVE("asin", njs_object_math_func, 1, NJS_MATH_ASIN), + NJS_DECLARE_PROP_NATIVE(STRING_asin, njs_object_math_func, 1, + NJS_MATH_ASIN), - NJS_DECLARE_PROP_NATIVE("asinh", njs_object_math_func, 1, NJS_MATH_ASINH), + NJS_DECLARE_PROP_NATIVE(STRING_asinh, njs_object_math_func, 1, + NJS_MATH_ASINH), - NJS_DECLARE_PROP_NATIVE("atan", njs_object_math_func, 1, NJS_MATH_ATAN), + NJS_DECLARE_PROP_NATIVE(STRING_atan, njs_object_math_func, 1, + NJS_MATH_ATAN), - NJS_DECLARE_PROP_NATIVE("atan2", njs_object_math_func, 2, NJS_MATH_ATAN2), + NJS_DECLARE_PROP_NATIVE(STRING_atan2, njs_object_math_func, 2, + NJS_MATH_ATAN2), - NJS_DECLARE_PROP_NATIVE("atanh", njs_object_math_func, 1, NJS_MATH_ATANH), + NJS_DECLARE_PROP_NATIVE(STRING_atanh, njs_object_math_func, 1, + NJS_MATH_ATANH), - NJS_DECLARE_PROP_NATIVE("cbrt", njs_object_math_func, 1, NJS_MATH_CBRT), + NJS_DECLARE_PROP_NATIVE(STRING_cbrt, njs_object_math_func, 1, + NJS_MATH_CBRT), - NJS_DECLARE_PROP_NATIVE("ceil", njs_object_math_func, 1, NJS_MATH_CEIL), + NJS_DECLARE_PROP_NATIVE(STRING_ceil, njs_object_math_func, 1, + NJS_MATH_CEIL), - NJS_DECLARE_PROP_NATIVE("clz32", njs_object_math_func, 1, NJS_MATH_CLZ32), + NJS_DECLARE_PROP_NATIVE(STRING_clz32, njs_object_math_func, 1, + NJS_MATH_CLZ32), - NJS_DECLARE_PROP_NATIVE("cos", njs_object_math_func, 1, NJS_MATH_COS), + NJS_DECLARE_PROP_NATIVE(STRING_cos, njs_object_math_func, 1, + NJS_MATH_COS), - NJS_DECLARE_PROP_NATIVE("cosh", njs_object_math_func, 1, NJS_MATH_COSH), + NJS_DECLARE_PROP_NATIVE(STRING_cosh, njs_object_math_func, 1, + NJS_MATH_COSH), - NJS_DECLARE_PROP_NATIVE("exp", njs_object_math_func, 1, NJS_MATH_EXP), + NJS_DECLARE_PROP_NATIVE(STRING_exp, njs_object_math_func, 1, + NJS_MATH_EXP), - NJS_DECLARE_PROP_NATIVE("expm1", njs_object_math_func, 1, NJS_MATH_EXPM1), + NJS_DECLARE_PROP_NATIVE(STRING_expm1, njs_object_math_func, 1, + NJS_MATH_EXPM1), - NJS_DECLARE_PROP_NATIVE("floor", njs_object_math_func, 1, NJS_MATH_FLOOR), + NJS_DECLARE_PROP_NATIVE(STRING_floor, njs_object_math_func, 1, + NJS_MATH_FLOOR), - NJS_DECLARE_PROP_NATIVE("fround", njs_object_math_func, 1, + NJS_DECLARE_PROP_NATIVE(STRING_fround, njs_object_math_func, 1, NJS_MATH_FROUND), - NJS_DECLARE_PROP_NATIVE("hypot", njs_object_math_hypot, 2, 0), + NJS_DECLARE_PROP_NATIVE(STRING_hypot, njs_object_math_hypot, 2, 0), - NJS_DECLARE_PROP_NATIVE("imul", njs_object_math_func, 2, NJS_MATH_IMUL), + NJS_DECLARE_PROP_NATIVE(STRING_imul, njs_object_math_func, 2, + NJS_MATH_IMUL), - NJS_DECLARE_PROP_NATIVE("log", njs_object_math_func, 1, NJS_MATH_LOG), + NJS_DECLARE_PROP_NATIVE(STRING_log, njs_object_math_func, 1, + NJS_MATH_LOG), - NJS_DECLARE_PROP_NATIVE("log10", njs_object_math_func, 1, NJS_MATH_LOG10), + NJS_DECLARE_PROP_NATIVE(STRING_log10, njs_object_math_func, 1, + NJS_MATH_LOG10), - NJS_DECLARE_PROP_NATIVE("log1p", njs_object_math_func, 1, NJS_MATH_LOG1P), + NJS_DECLARE_PROP_NATIVE(STRING_log1p, njs_object_math_func, 1, + NJS_MATH_LOG1P), - NJS_DECLARE_PROP_NATIVE("log2", njs_object_math_func, 1, NJS_MATH_LOG2), + NJS_DECLARE_PROP_NATIVE(STRING_log2, njs_object_math_func, 1, + NJS_MATH_LOG2), - NJS_DECLARE_PROP_NATIVE("max", njs_object_math_min_max, 2, 1), + NJS_DECLARE_PROP_NATIVE(STRING_max, njs_object_math_min_max, 2, 1), - NJS_DECLARE_PROP_NATIVE("min", njs_object_math_min_max, 2, 0), + NJS_DECLARE_PROP_NATIVE(STRING_min, njs_object_math_min_max, 2, 0), - NJS_DECLARE_PROP_NATIVE("pow", njs_object_math_func, 2, NJS_MATH_POW), + NJS_DECLARE_PROP_NATIVE(STRING_pow, njs_object_math_func, 2, + NJS_MATH_POW), - NJS_DECLARE_PROP_NATIVE("random", njs_object_math_random, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_random, njs_object_math_random, 0, 0), - NJS_DECLARE_PROP_NATIVE("round", njs_object_math_func, 1, NJS_MATH_ROUND), + NJS_DECLARE_PROP_NATIVE(STRING_round, njs_object_math_func, 1, + NJS_MATH_ROUND), - NJS_DECLARE_PROP_NATIVE("sign", njs_object_math_func, 1, NJS_MATH_SIGN), + NJS_DECLARE_PROP_NATIVE(STRING_sign, njs_object_math_func, 1, + NJS_MATH_SIGN), - NJS_DECLARE_PROP_NATIVE("sin", njs_object_math_func, 1, NJS_MATH_SIN), + NJS_DECLARE_PROP_NATIVE(STRING_sin, njs_object_math_func, 1, + NJS_MATH_SIN), - NJS_DECLARE_PROP_NATIVE("sinh", njs_object_math_func, 1, NJS_MATH_SINH), + NJS_DECLARE_PROP_NATIVE(STRING_sinh, njs_object_math_func, 1, + NJS_MATH_SINH), - NJS_DECLARE_PROP_NATIVE("sqrt", njs_object_math_func, 1, NJS_MATH_SQRT), + NJS_DECLARE_PROP_NATIVE(STRING_sqrt, njs_object_math_func, 1, + NJS_MATH_SQRT), - NJS_DECLARE_PROP_NATIVE("tan", njs_object_math_func, 1, NJS_MATH_TAN), + NJS_DECLARE_PROP_NATIVE(STRING_tan, njs_object_math_func, 1, + NJS_MATH_TAN), - NJS_DECLARE_PROP_NATIVE("tanh", njs_object_math_func, 1, NJS_MATH_TANH), + NJS_DECLARE_PROP_NATIVE(STRING_tanh, njs_object_math_func, 1, + NJS_MATH_TANH), - NJS_DECLARE_PROP_NATIVE("trunc", njs_object_math_func, 1, NJS_MATH_TRUNC), + NJS_DECLARE_PROP_NATIVE(STRING_trunc, njs_object_math_func, 1, + NJS_MATH_TRUNC), }; diff --git a/src/njs_module.c b/src/njs_module.c index 5d9c96ae..5af174f3 100644 --- a/src/njs_module.c +++ b/src/njs_module.c @@ -144,7 +144,7 @@ njs_module_require(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return ret; } - njs_string_get(path, &name); + njs_string_get(vm, path, &name); module = njs_module_find(vm, &name, 0); if (njs_slow_path(module == NULL)) { diff --git a/src/njs_number.c b/src/njs_number.c index 4ca6456d..29df50a5 100644 --- a/src/njs_number.c +++ b/src/njs_number.c @@ -217,23 +217,22 @@ njs_int_t njs_number_to_string(njs_vm_t *vm, njs_value_t *string, const njs_value_t *number) { - double num; - size_t size; - const njs_value_t *value; - u_char buf[128]; + double num; + size_t size; + u_char buf[128]; num = njs_number(number); if (isnan(num)) { - value = &njs_string_nan; + njs_atom_to_value(vm, string, NJS_ATOM_STRING_NaN); } else if (isinf(num)) { if (num < 0) { - value = &njs_string_minus_infinity; + njs_atom_to_value(vm, string, NJS_ATOM_STRING__Infinity); } else { - value = &njs_string_plus_infinity; + njs_atom_to_value(vm, string, NJS_ATOM_STRING_Infinity); } } else { @@ -242,8 +241,6 @@ njs_number_to_string(njs_vm_t *vm, njs_value_t *string, return njs_string_new(vm, string, buf, size, size); } - *string = *value; - return NJS_OK; } @@ -252,20 +249,8 @@ njs_int_t njs_int64_to_string(njs_vm_t *vm, njs_value_t *value, int64_t i64) { size_t size; - u_char *dst, *p; u_char buf[128]; - if (njs_fast_path(i64 >= 0 && i64 < 0x3fffffffffffLL)) { - /* Fits to short_string. */ - dst = njs_string_short_start(value); - - p = njs_sprintf(dst, dst + NJS_STRING_SHORT, "%L", i64); - - njs_string_short_set(value, p - dst, p - dst); - - return NJS_OK; - } - size = njs_dtoa(i64, (char *) buf); return njs_string_new(vm, value, buf, size, size); @@ -439,49 +424,55 @@ njs_number_is_finite(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } -static const njs_object_prop_t njs_number_constructor_properties[] = +static const njs_object_prop_init_t njs_number_constructor_properties[] = { NJS_DECLARE_PROP_LENGTH(1), NJS_DECLARE_PROP_NAME("Number"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), - NJS_DECLARE_PROP_VALUE("EPSILON", njs_value(NJS_NUMBER, 1, DBL_EPSILON), 0), + NJS_DECLARE_PROP_VALUE(STRING_EPSILON, + njs_value(NJS_NUMBER, 1, DBL_EPSILON), 0), - NJS_DECLARE_PROP_LVALUE("MAX_SAFE_INTEGER", - njs_value(NJS_NUMBER, 1, NJS_MAX_SAFE_INTEGER), 0), + NJS_DECLARE_PROP_VALUE(STRING_MAX_SAFE_INTEGER, + njs_value(NJS_NUMBER, 1, NJS_MAX_SAFE_INTEGER), 0), - NJS_DECLARE_PROP_LVALUE("MIN_SAFE_INTEGER", - njs_value(NJS_NUMBER, 1, -NJS_MAX_SAFE_INTEGER), 0), + NJS_DECLARE_PROP_VALUE(STRING_MIN_SAFE_INTEGER, + njs_value(NJS_NUMBER, 1, -NJS_MAX_SAFE_INTEGER), 0), - NJS_DECLARE_PROP_VALUE("MAX_VALUE", njs_value(NJS_NUMBER, 1, DBL_MAX), 0), + NJS_DECLARE_PROP_VALUE(STRING_MAX_VALUE, + njs_value(NJS_NUMBER, 1, DBL_MAX), 0), - NJS_DECLARE_PROP_VALUE("MIN_VALUE", njs_value(NJS_NUMBER, 1, DBL_MIN), 0), + NJS_DECLARE_PROP_VALUE(STRING_MIN_VALUE, + njs_value(NJS_NUMBER, 1, DBL_MIN), 0), - NJS_DECLARE_PROP_VALUE("NaN", njs_value(NJS_NUMBER, 0, NAN), 0), + NJS_DECLARE_PROP_VALUE(STRING_NaN, njs_value(NJS_NUMBER, 0, NAN), 0), - NJS_DECLARE_PROP_LVALUE("POSITIVE_INFINITY", - njs_value(NJS_NUMBER, 1, INFINITY), 0), + NJS_DECLARE_PROP_VALUE(STRING_POSITIVE_INFINITY, + njs_value(NJS_NUMBER, 1, INFINITY), 0), - NJS_DECLARE_PROP_LVALUE("NEGATIVE_INFINITY", - njs_value(NJS_NUMBER, 1, -INFINITY), 0), + NJS_DECLARE_PROP_VALUE(STRING_NEGATIVE_INFINITY, + njs_value(NJS_NUMBER, 1, -INFINITY), 0), - NJS_DECLARE_PROP_NATIVE("isFinite", njs_number_is_finite, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_isFinite, njs_number_is_finite, 1, 0), - NJS_DECLARE_PROP_NATIVE("isInteger", njs_number_is_integer, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_isInteger, njs_number_is_integer, 1, 0), - NJS_DECLARE_PROP_NATIVE("isSafeInteger", njs_number_is_safe_integer, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_isSafeInteger, + njs_number_is_safe_integer, 1, 0), - NJS_DECLARE_PROP_NATIVE("isNaN", njs_number_is_nan, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_isNaN, njs_number_is_nan, 1, 0), - NJS_DECLARE_PROP_NATIVE("parseFloat", njs_number_parse_float, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_parseFloat, njs_number_parse_float, 1, + 0), - NJS_DECLARE_PROP_NATIVE("parseInt", njs_number_parse_int, 2, 0), + NJS_DECLARE_PROP_NATIVE(STRING_parseInt, njs_number_parse_int, 2, 0), }; -const njs_object_init_t njs_number_constructor_init = { +static const njs_object_init_t njs_number_constructor_init = { njs_number_constructor_properties, njs_nitems(njs_number_constructor_properties), }; @@ -884,25 +875,29 @@ njs_number_to_string_radix(njs_vm_t *vm, njs_value_t *string, } -static const njs_object_prop_t njs_number_prototype_properties[] = +static const njs_object_prop_init_t njs_number_prototype_properties[] = { - NJS_DECLARE_PROP_HANDLER("__proto__", njs_primitive_prototype_get_proto, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING___proto__, + njs_primitive_prototype_get_proto, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_NATIVE("valueOf", njs_number_prototype_value_of, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_valueOf, njs_number_prototype_value_of, + 0, 0), - NJS_DECLARE_PROP_NATIVE("toString", njs_number_prototype_to_string, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_toString, + njs_number_prototype_to_string, 1, 0), - NJS_DECLARE_PROP_NATIVE("toFixed", njs_number_prototype_to_fixed, 1, 0), - - NJS_DECLARE_PROP_NATIVE("toPrecision", njs_number_prototype_to_precision, + NJS_DECLARE_PROP_NATIVE(STRING_toFixed, njs_number_prototype_to_fixed, 1, 0), - NJS_DECLARE_PROP_NATIVE("toExponential", + NJS_DECLARE_PROP_NATIVE(STRING_toPrecision, + njs_number_prototype_to_precision, 1, 0), + + NJS_DECLARE_PROP_NATIVE(STRING_toExponential, njs_number_prototype_to_exponential, 1, 0), }; @@ -970,7 +965,7 @@ njs_number_parse_int(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return ret; } - (void) njs_string_trim(value, &string, NJS_TRIM_START); + (void) njs_string_trim(vm, value, &string, NJS_TRIM_START); if (string.size == 0) { goto done; @@ -1048,7 +1043,7 @@ njs_number_parse_float(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return ret; } - (void) njs_string_trim(value, &string, NJS_TRIM_START); + (void) njs_string_trim(vm, value, &string, NJS_TRIM_START); p = string.start; end = p + string.size; diff --git a/src/njs_number.h b/src/njs_number.h index 98137a5d..d4c7a286 100644 --- a/src/njs_number.h +++ b/src/njs_number.h @@ -168,15 +168,30 @@ njs_char_to_hex(u_char c) } -njs_inline void -njs_uint32_to_string(njs_value_t *value, uint32_t u32) +njs_inline njs_int_t +njs_uint32_to_string(njs_vm_t *vm, njs_value_t *value, uint32_t u32) { - u_char *dst, *p; + size_t size; + u_char *p; + + if (!(u32 & 0x80000000)) { + value->type = NJS_STRING; + value->data.truth = (u32 != 0); + value->atom_id = njs_number_atom(u32); + value->string.data = NULL; + return NJS_OK; + } + + p = njs_string_alloc(vm, value, 10, 10); + if (njs_slow_path(p == NULL)) { + return NJS_ERROR; + } - dst = njs_string_short_start(value); - p = njs_sprintf(dst, dst + NJS_STRING_SHORT, "%uD", u32); + size = njs_sprintf(p, p + 10, "%uD", u32) - p; + value->string.data->length = size; + value->string.data->size = size; - njs_string_short_set(value, p - dst, p - dst); + return NJS_OK; } diff --git a/src/njs_object.c b/src/njs_object.c index b3eae9a8..63273628 100644 --- a/src/njs_object.c +++ b/src/njs_object.c @@ -14,9 +14,8 @@ typedef enum { } njs_object_integrity_level_t; -static njs_int_t njs_object_hash_test(njs_lvlhsh_query_t *lhq, void *data); static njs_object_prop_t *njs_object_exist_in_proto(const njs_object_t *begin, - const njs_object_t *end, njs_lvlhsh_query_t *lhq); + const njs_object_t *end, njs_flathsh_query_t *lhq); static njs_int_t njs_object_enumerate_array(njs_vm_t *vm, const njs_array_t *array, njs_array_t *items, uint32_t flags); static njs_int_t njs_object_enumerate_typed_array(njs_vm_t *vm, @@ -154,23 +153,21 @@ njs_object_value_alloc(njs_vm_t *vm, njs_uint_t prototype_index, size_t extra, 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_object_hash_create(njs_vm_t *vm, njs_flathsh_t *hash, + const njs_object_prop_init_t *prop, njs_uint_t n) { - njs_int_t ret; - njs_lvlhsh_query_t lhq; + njs_int_t ret; + njs_flathsh_query_t lhq; lhq.replace = 0; lhq.proto = &njs_object_hash_proto; lhq.pool = vm->mem_pool; while (n != 0) { - - njs_object_property_key_set(&lhq, &prop->name, 0); - + lhq.key_hash = prop->atom_id; lhq.value = (void *) prop; - ret = njs_lvlhsh_insert(hash, &lhq); + ret = njs_flathsh_unique_insert(hash, &lhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "lvlhsh insert failed"); return NJS_ERROR; @@ -184,59 +181,16 @@ njs_object_hash_create(njs_vm_t *vm, njs_lvlhsh_t *hash, } -const njs_lvlhsh_proto_t njs_object_hash_proto +const njs_flathsh_proto_t njs_object_hash_proto njs_aligned(64) = { - NJS_LVLHSH_DEFAULT, - njs_object_hash_test, + 0, + NULL, njs_lvlhsh_alloc, njs_lvlhsh_free, }; -static njs_int_t -njs_object_hash_test(njs_lvlhsh_query_t *lhq, void *data) -{ - size_t size; - u_char *start; - njs_value_t *name; - njs_object_prop_t *prop; - - prop = data; - name = &prop->name; - - if (njs_slow_path(njs_is_symbol(name))) { - return ((njs_symbol_key(name) == lhq->key_hash) - && lhq->key.start == NULL) ? NJS_OK : NJS_DECLINED; - } - - /* string. */ - - size = name->short_string.size; - - if (size != NJS_STRING_LONG) { - if (lhq->key.length != size) { - return NJS_DECLINED; - } - - start = name->short_string.start; - - } else { - if (lhq->key.length != name->long_string.size) { - return NJS_DECLINED; - } - - start = name->long_string.data->start; - } - - if (memcmp(start, lhq->key.start, lhq->key.length) == 0) { - return NJS_OK; - } - - return NJS_DECLINED; -} - - static njs_int_t njs_object_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval) @@ -417,13 +371,13 @@ njs_object_entries(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, static njs_object_prop_t * njs_object_exist_in_proto(const njs_object_t *object, const njs_object_t *end, - njs_lvlhsh_query_t *lhq) + njs_flathsh_query_t *lhq) { njs_int_t ret; njs_object_prop_t *prop; while (object != end) { - ret = njs_lvlhsh_find(&object->hash, lhq); + ret = njs_flathsh_unique_find(&object->hash, lhq); if (njs_fast_path(ret == NJS_OK)) { prop = lhq->value; @@ -435,7 +389,7 @@ njs_object_exist_in_proto(const njs_object_t *object, const njs_object_t *end, return lhq->value; } - ret = njs_lvlhsh_find(&object->shared_hash, lhq); + ret = njs_flathsh_unique_find(&object->shared_hash, lhq); if (njs_fast_path(ret == NJS_OK)) { return lhq->value; @@ -628,7 +582,11 @@ njs_object_enumerate_array(njs_vm_t *vm, const njs_array_t *array, return NJS_ERROR; } - njs_uint32_to_string(&items->start[items->length++], p - start); + ret = njs_uint32_to_string(vm, &items->start[items->length++], + p - start); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_ERROR; + } } p++; @@ -658,7 +616,11 @@ njs_object_enumerate_array(njs_vm_t *vm, const njs_array_t *array, return NJS_ERROR; } - njs_uint32_to_string(&entry->start[0], p - start); + ret = njs_uint32_to_string(vm, &entry->start[0], p - start); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_ERROR; + } + entry->start[1] = *p; ret = njs_array_expand(vm, items, 0, 1); @@ -700,7 +662,10 @@ njs_object_enumerate_typed_array(njs_vm_t *vm, const njs_typed_array_t *array, switch (njs_object_enum_kind(flags)) { case NJS_ENUM_KEYS: for (i = 0; i < length; i++) { - njs_uint32_to_string(item++, i); + ret = njs_uint32_to_string(vm, item++, i); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_ERROR; + } } break; @@ -719,7 +684,11 @@ njs_object_enumerate_typed_array(njs_vm_t *vm, const njs_typed_array_t *array, return NJS_ERROR; } - njs_uint32_to_string(&entry->start[0], i); + ret = njs_uint32_to_string(vm, &entry->start[0], i); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_ERROR; + } + njs_set_number(&entry->start[1], njs_typed_array_prop(array, i)); njs_set_array(item++, entry); @@ -738,7 +707,7 @@ static njs_int_t njs_object_enumerate_string(njs_vm_t *vm, const njs_value_t *value, njs_array_t *items, uint32_t flags) { - u_char *begin; + u_char buf[4], *c; uint32_t i, len, size; njs_int_t ret; njs_value_t *item, *string; @@ -746,7 +715,7 @@ njs_object_enumerate_string(njs_vm_t *vm, const njs_value_t *value, const u_char *src, *end; njs_string_prop_t str_prop; - len = (uint32_t) njs_string_prop(&str_prop, value); + len = (uint32_t) njs_string_prop(vm, &str_prop, value); ret = njs_array_expand(vm, items, 0, len); if (njs_slow_path(ret != NJS_OK)) { @@ -758,7 +727,10 @@ njs_object_enumerate_string(njs_vm_t *vm, const njs_value_t *value, switch (njs_object_enum_kind(flags)) { case NJS_ENUM_KEYS: for (i = 0; i < len; i++) { - njs_uint32_to_string(item++, i); + ret = njs_uint32_to_string(vm, item++, i); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_ERROR; + } } break; @@ -768,10 +740,10 @@ njs_object_enumerate_string(njs_vm_t *vm, const njs_value_t *value, /* ASCII string. */ for (i = 0; i < len; i++) { - begin = njs_string_short_start(item); - *begin = str_prop.start[i]; - - njs_string_short_set(item, 1, 1); + ret = njs_string_new(vm, item, &str_prop.start[i], 1, 1); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_ERROR; + } item++; } @@ -783,11 +755,15 @@ njs_object_enumerate_string(njs_vm_t *vm, const njs_value_t *value, end = src + str_prop.size; do { - begin = (u_char *) src; - njs_utf8_copy(njs_string_short_start(item), &src, end); - size = (uint32_t) (src - begin); + c = buf; - njs_string_short_set(item, size, 1); + c = njs_utf8_copy(c, &src, end); + size = c - buf; + + ret = njs_string_new(vm, item, buf, size, 1); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_ERROR; + } item++; @@ -807,14 +783,17 @@ njs_object_enumerate_string(njs_vm_t *vm, const njs_value_t *value, return NJS_ERROR; } - njs_uint32_to_string(&entry->start[0], i); + ret = njs_uint32_to_string(vm, &entry->start[0], i); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_ERROR; + } string = &entry->start[1]; - begin = njs_string_short_start(string); - *begin = str_prop.start[i]; - - njs_string_short_set(string, 1, 1); + ret = njs_string_new(vm, string, &str_prop.start[i], 1, 1); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_ERROR; + } njs_set_array(item, entry); @@ -834,15 +813,22 @@ njs_object_enumerate_string(njs_vm_t *vm, const njs_value_t *value, return NJS_ERROR; } - njs_uint32_to_string(&entry->start[0], i++); + ret = njs_uint32_to_string(vm, &entry->start[0], i++); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_ERROR; + } string = &entry->start[1]; - begin = (u_char *) src; - njs_utf8_copy(njs_string_short_start(string), &src, end); - size = (uint32_t) (src - begin); + c = buf; - njs_string_short_set(string, size, 1); + c = njs_utf8_copy(c, &src, end); + size = c - buf; + + ret = njs_string_new(vm, string, buf, size, 1); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_ERROR; + } njs_set_array(item, entry); @@ -887,14 +873,14 @@ njs_object_enumerate_object(njs_vm_t *vm, const njs_object_t *object, } -#define njs_process_prop(vm, prop, flags, items, items_symbol) \ - if (!(flags & NJS_ENUM_SYMBOL && njs_is_symbol(&prop->name))) { \ +#define njs_process_prop(vm, prop_name, flags, items, items_symbol) \ + if (!(flags & NJS_ENUM_SYMBOL && njs_is_symbol(prop_name))) { \ /* \ * prop from shared_hash is not symbol: \ * add to items before props from hash \ */ \ \ - ret = njs_array_add(vm, items, &prop->name); \ + ret = njs_array_add(vm, items, prop_name); \ if (njs_slow_path(ret != NJS_OK)) { \ return NJS_ERROR; \ } \ @@ -904,7 +890,7 @@ njs_object_enumerate_object(njs_vm_t *vm, const njs_object_t *object, * prop from shared_hash is symbol: \ * add to items_symbol \ */ \ - ret = njs_array_add(vm, items_symbol, &prop->name); \ + ret = njs_array_add(vm, items_symbol, prop_name); \ if (njs_slow_path(ret != NJS_OK)) { \ return NJS_ERROR; \ } \ @@ -915,14 +901,16 @@ static njs_int_t njs_get_own_ordered_keys(njs_vm_t *vm, const njs_object_t *object, const njs_object_t *parent, njs_array_t *items, uint32_t flags) { - double num; - uint32_t items_length; - njs_int_t ret; - njs_array_t *items_string, *items_symbol; - njs_lvlhsh_each_t lhe; - njs_object_prop_t *prop, *ext_prop; - njs_lvlhsh_query_t lhq; - const njs_lvlhsh_t *hash; + double num; + uint32_t items_length; + njs_int_t ret; + njs_array_t *items_string, *items_symbol; + njs_value_t prop_name; + njs_object_prop_t *prop, *ext_prop; + njs_flathsh_elt_t *elt; + njs_flathsh_each_t lhe; + const njs_flathsh_t *hash; + njs_flathsh_query_t lhq; items_length = items->length; @@ -938,7 +926,7 @@ njs_get_own_ordered_keys(njs_vm_t *vm, const njs_object_t *object, lhq.proto = &njs_object_hash_proto; - njs_lvlhsh_each_init(&lhe, &njs_object_hash_proto); + njs_flathsh_each_init(&lhe, &njs_object_hash_proto); hash = &object->shared_hash; if (flags & NJS_ENUM_NON_SHARED_ONLY) { @@ -946,24 +934,30 @@ njs_get_own_ordered_keys(njs_vm_t *vm, const njs_object_t *object, } for ( ;; ) { - prop = njs_lvlhsh_each(hash, &lhe); - - if (prop == NULL) { + elt = njs_flathsh_each(hash, &lhe); + if (elt == NULL) { break; } - if (!njs_is_enumerable(&prop->name, flags)) { + prop = elt->value; + + ret = njs_atom_to_value(vm, &prop_name, elt->key_hash); + if (ret != NJS_OK) { + return NJS_ERROR; + } + + if (!njs_is_enumerable(&prop_name, flags)) { continue; } - njs_object_property_key_set(&lhq, &prop->name, lhe.key_hash); + lhq.key_hash = elt->key_hash; ext_prop = njs_object_exist_in_proto(parent, object, &lhq); if (ext_prop != NULL) { continue; } - ret = njs_lvlhsh_find(&object->hash, &lhq); + ret = njs_flathsh_unique_find(&object->hash, &lhq); if (ret != NJS_OK) { if (!(prop->enumerable || !(flags & NJS_ENUM_ENUMERABLE_ONLY))) { @@ -972,12 +966,13 @@ njs_get_own_ordered_keys(njs_vm_t *vm, const njs_object_t *object, /* prop is: !in_hash && in_shared_hash */ - num = njs_string_to_index(&prop->name); + num = njs_string_to_index(&prop_name); if (!njs_number_is_integer_index(num)) { - njs_process_prop(vm, prop, flags, items_string, items_symbol); + njs_process_prop(vm, &prop_name, flags, items_string, + items_symbol); } else { - ret = njs_array_add(vm, items, &prop->name); + ret = njs_array_add(vm, items, &prop_name); if (njs_slow_path(ret != NJS_OK)) { return NJS_ERROR; } @@ -993,7 +988,7 @@ njs_get_own_ordered_keys(njs_vm_t *vm, const njs_object_t *object, /* prop is: in_hash && in_shared_hash */ - num = njs_string_to_index(&prop->name); + num = njs_string_to_index(&prop_name); if (!njs_number_is_integer_index(num)) { njs_object_prop_t *hash_prop = lhq.value; @@ -1005,7 +1000,7 @@ njs_get_own_ordered_keys(njs_vm_t *vm, const njs_object_t *object, if (hash_prop->type != NJS_WHITEOUT && !(hash_prop->enum_in_object_hash)) { - njs_process_prop(vm, prop, flags, items_string, + njs_process_prop(vm, &prop_name, flags, items_string, items_symbol); } } @@ -1014,56 +1009,60 @@ njs_get_own_ordered_keys(njs_vm_t *vm, const njs_object_t *object, local_hash: - njs_lvlhsh_each_init(&lhe, &njs_object_hash_proto); + njs_flathsh_each_init(&lhe, &njs_object_hash_proto); hash = &object->hash; for ( ;; ) { - prop = njs_lvlhsh_each(hash, &lhe); - - if (prop == NULL) { + elt = njs_flathsh_each(hash, &lhe); + if (elt == NULL) { break; } - if (!njs_is_enumerable(&prop->name, flags) || + prop = elt->value; + + ret = njs_atom_to_value(vm, &prop_name, elt->key_hash); + if (ret != NJS_OK) { + return NJS_ERROR; + } + + if (!njs_is_enumerable(&prop_name, flags) || !(prop->enumerable || !(flags & NJS_ENUM_ENUMERABLE_ONLY)) || prop->type == NJS_WHITEOUT) { continue; } - njs_object_property_key_set(&lhq, &prop->name, lhe.key_hash); + lhq.key_hash = elt->key_hash; ext_prop = njs_object_exist_in_proto(parent, object, &lhq); if (ext_prop != NULL) { continue; } - num = njs_string_to_index(&prop->name); + num = njs_string_to_index(&prop_name); if (njs_number_is_integer_index(num)) { - ret = njs_array_add(vm, items, &prop->name); + ret = njs_array_add(vm, items, &prop_name); if (njs_slow_path(ret != NJS_OK)) { return NJS_ERROR; } } else { - ret = njs_lvlhsh_find(&object->shared_hash, &lhq); + ret = njs_flathsh_unique_find(&object->shared_hash, &lhq); if (ret != NJS_OK) { /* prop is: in_hash && !in_shared_hash */ /* select names of not deleted props */ - - njs_process_prop(vm, prop, flags, items_string, + njs_process_prop(vm, &prop_name, flags, items_string, items_symbol); } else { /* prop is: in_hash && in_shared_hash */ /* select names of not deleted and created again */ - if (prop->enum_in_object_hash) { - njs_process_prop(vm, prop, flags, items_string, + njs_process_prop(vm, &prop_name, flags, items_string, items_symbol); } } @@ -1139,8 +1138,8 @@ njs_object_own_enumerate_object(njs_vm_t *vm, const njs_object_t *object, njs_set_object(&value, (njs_object_t *) object); for (i = 0; i< items_sorted->length; i++) { - ret = njs_value_property(vm, &value, &items_sorted->start[i], - &retval); + ret = njs_value_property_val(vm, &value, &items_sorted->start[i], + &retval); if (njs_slow_path(ret != NJS_OK)) { njs_array_destroy(vm, items_sorted); return NJS_ERROR; @@ -1221,8 +1220,10 @@ static njs_int_t njs_object_copy_shared_hash(njs_vm_t *vm, njs_object_t *object) { njs_int_t ret; + njs_value_t prop_name; njs_flathsh_t new_hash, *shared_hash; njs_object_prop_t *prop; + njs_flathsh_elt_t *elt; njs_flathsh_each_t fhe; njs_flathsh_query_t fhq; @@ -1236,24 +1237,30 @@ njs_object_copy_shared_hash(njs_vm_t *vm, njs_object_t *object) njs_flathsh_each_init(&fhe, &njs_object_hash_proto); for ( ;; ) { - prop = njs_flathsh_each(shared_hash, &fhe); - - if (prop == NULL) { + elt = njs_flathsh_each(shared_hash, &fhe); + if (elt == NULL) { break; } - if (njs_is_symbol(&prop->name)) { - fhq.key_hash = njs_symbol_key(&prop->name); + prop = elt->value; + + ret = njs_atom_to_value(vm, &prop_name, elt->key_hash); + if (ret != NJS_OK) { + return NJS_ERROR; + } + + if (njs_is_symbol(&prop_name)) { + fhq.key_hash = njs_symbol_key(&prop_name); fhq.key.start = NULL; } else { - njs_string_get(&prop->name, &fhq.key); - fhq.key_hash = njs_djb_hash(fhq.key.start, fhq.key.length); + njs_string_get(vm, &prop_name, &fhq.key); + fhq.key_hash = elt->key_hash; } fhq.value = prop; - ret = njs_flathsh_insert(&new_hash, &fhq); + ret = njs_flathsh_unique_insert(&new_hash, &fhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "flathsh insert failed"); return NJS_ERROR; @@ -1331,10 +1338,10 @@ njs_object_make_shared(njs_vm_t *vm, njs_object_t *object) } - njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0, 0); + njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0); key = &s->keys->start[s->index++]; - ret = njs_property_query(vm, &pq, &s->value, key); + ret = njs_property_query_val(vm, &pq, &s->value, key); if (njs_slow_path(ret != NJS_OK)) { if (ret == NJS_DECLINED) { continue; @@ -1346,7 +1353,8 @@ njs_object_make_shared(njs_vm_t *vm, njs_object_t *object) prop = pq.lhq.value; - ret = njs_flathsh_insert(&njs_object(&s->value)->shared_hash, &pq.lhq); + ret = njs_flathsh_unique_insert(&njs_object(&s->value)->shared_hash, + &pq.lhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "flathsh insert failed"); return NJS_ERROR; @@ -1445,10 +1453,10 @@ njs_object_traverse(njs_vm_t *vm, njs_object_t *object, void *ctx, continue; } - njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0, 0); + njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0); key = &s->keys->start[s->index++]; - ret = njs_property_query(vm, &pq, &s->value, key); + ret = njs_property_query_val(vm, &pq, &s->value, key); if (njs_slow_path(ret != NJS_OK)) { if (ret == NJS_DECLINED) { continue; @@ -1459,6 +1467,7 @@ njs_object_traverse(njs_vm_t *vm, njs_object_t *object, void *ctx, prop = pq.lhq.value; s->prop = prop; + s->atom_id = pq.lhq.key_hash; ret = cb(vm, s, ctx); if (njs_slow_path(ret != NJS_OK)) { @@ -1472,7 +1481,8 @@ njs_object_traverse(njs_vm_t *vm, njs_object_t *object, void *ctx, njs_value_assign(&value, njs_prop_value(prop)); if (prop->type == NJS_PROPERTY_HANDLER) { - ret = njs_prop_handler(prop)(vm, prop, &s->value, NULL, &value); + ret = njs_prop_handler(prop)(vm, prop, pq.lhq.key_hash, &s->value, + NULL, &value); if (njs_slow_path(ret == NJS_ERROR)) { return ret; @@ -1536,8 +1546,13 @@ njs_object_define_property(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, value = njs_argument(args, 1); name = njs_lvalue_arg(&lvalue, args, nargs, 2); - ret = njs_object_prop_define(vm, value, name, desc, - NJS_OBJECT_PROP_DESCRIPTOR, 0); + ret = njs_value_to_key(vm, name, name); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_ERROR; + } + + ret = njs_object_prop_define_val(vm, value, name, desc, + NJS_OBJECT_PROP_DESCRIPTOR); if (njs_slow_path(ret != NJS_OK)) { return NJS_ERROR; } @@ -1578,12 +1593,10 @@ njs_object_define_properties(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, length = keys->length; value = njs_argument(args, 1); - njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0, 0); + njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0); for (i = 0; i < length; i++) { - pq.lhq.key_hash = 0; - - ret = njs_property_query(vm, &pq, descs, &keys->start[i]); + ret = njs_property_query_val(vm, &pq, descs, &keys->start[i]); if (njs_slow_path(ret == NJS_ERROR)) { goto done; } @@ -1594,13 +1607,13 @@ njs_object_define_properties(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, continue; } - ret = njs_value_property(vm, descs, &keys->start[i], &desc); + ret = njs_value_property(vm, descs, keys->start[i].atom_id, &desc); if (njs_slow_path(ret == NJS_ERROR)) { goto done; } - ret = njs_object_prop_define(vm, value, &keys->start[i], &desc, - NJS_OBJECT_PROP_DESCRIPTOR, 0); + ret = njs_object_prop_define(vm, value, keys->start[i].atom_id, &desc, + NJS_OBJECT_PROP_DESCRIPTOR); if (njs_slow_path(ret != NJS_OK)) { goto done; } @@ -1641,13 +1654,13 @@ static njs_int_t njs_object_get_own_property_descriptors(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval) { - njs_int_t ret; - uint32_t i, length; - njs_array_t *names; - njs_value_t descriptor, *value, *key; - njs_object_t *descriptors; - njs_object_prop_t *pr; - njs_lvlhsh_query_t lhq; + uint32_t i, length; + njs_int_t ret; + njs_array_t *names; + njs_value_t descriptor, *value, *key; + njs_object_t *descriptors; + njs_object_prop_t *pr; + njs_flathsh_query_t lhq; value = njs_arg(args, nargs, 1); @@ -1684,16 +1697,16 @@ njs_object_get_own_property_descriptors(njs_vm_t *vm, njs_value_t *args, goto done; } - pr = njs_object_prop_alloc(vm, key, &descriptor, 1); + pr = njs_object_prop_alloc(vm, &descriptor, 1); if (njs_slow_path(pr == NULL)) { ret = NJS_ERROR; goto done; } - njs_object_property_key_set(&lhq, key, 0); + lhq.key_hash = key->atom_id; lhq.value = pr; - ret = njs_lvlhsh_insert(&descriptors->hash, &lhq); + ret = njs_flathsh_unique_insert(&descriptors->hash, &lhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "lvlhsh insert failed"); goto done; @@ -1748,7 +1761,7 @@ njs_object_get_prototype_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, value = njs_arg(args, nargs, 1); if (njs_is_object(value)) { - njs_object_prototype_proto(vm, NULL, value, NULL, retval); + njs_object_prototype_proto(vm, NULL, 0, value, NULL, retval); return NJS_OK; } @@ -1823,14 +1836,15 @@ static njs_int_t njs_object_set_integrity_level(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t level, njs_value_t *retval) { - uint32_t length; - njs_int_t ret; - njs_array_t *array; - njs_value_t *value; - njs_lvlhsh_t *hash; - njs_object_t *object; - njs_object_prop_t *prop; - njs_lvlhsh_each_t lhe; + uint32_t length; + njs_int_t ret; + njs_array_t *array; + njs_value_t *value; + njs_object_t *object; + njs_flathsh_t *hash; + njs_object_prop_t *prop; + njs_flathsh_elt_t *elt; + njs_flathsh_each_t lhe; value = njs_arg(args, nargs, 1); @@ -1865,17 +1879,18 @@ njs_object_set_integrity_level(njs_vm_t *vm, njs_value_t *args, object = njs_object(value); object->extensible = 0; - njs_lvlhsh_each_init(&lhe, &njs_object_hash_proto); + njs_flathsh_each_init(&lhe, &njs_object_hash_proto); hash = &object->hash; for ( ;; ) { - prop = njs_lvlhsh_each(hash, &lhe); - - if (prop == NULL) { + elt = njs_flathsh_each(hash, &lhe); + if (elt == NULL) { break; } + prop = elt->value; + if (level == NJS_OBJECT_INTEGRITY_FROZEN && !njs_is_accessor_descriptor(prop)) { @@ -1895,11 +1910,12 @@ static njs_int_t njs_object_test_integrity_level(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t level, njs_value_t *retval) { - njs_value_t *value; - njs_lvlhsh_t *hash; - njs_object_t *object; - njs_object_prop_t *prop; - njs_lvlhsh_each_t lhe; + njs_value_t *value; + njs_object_t *object; + njs_flathsh_t *hash; + njs_object_prop_t *prop; + njs_flathsh_elt_t *elt; + njs_flathsh_each_t lhe; value = njs_arg(args, nargs, 1); @@ -1923,17 +1939,18 @@ njs_object_test_integrity_level(njs_vm_t *vm, njs_value_t *args, goto done; } - njs_lvlhsh_each_init(&lhe, &njs_object_hash_proto); + njs_flathsh_each_init(&lhe, &njs_object_hash_proto); hash = &object->hash; for ( ;; ) { - prop = njs_lvlhsh_each(hash, &lhe); - - if (prop == NULL) { + elt = njs_flathsh_each(hash, &lhe); + if (elt == NULL) { break; } + prop = elt->value; + if (prop->configurable) { goto done; } @@ -2027,9 +2044,9 @@ njs_object_assign(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, for (j = 0; j < length; j++) { key = &names->start[j]; - njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0, 1); + njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 1); - ret = njs_property_query(vm, &pq, source, key); + ret = njs_property_query_val(vm, &pq, source, key); if (njs_slow_path(ret != NJS_OK)) { goto exception; } @@ -2039,12 +2056,12 @@ njs_object_assign(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, continue; } - ret = njs_value_property(vm, source, key, &setval); + ret = njs_value_property(vm, source, key->atom_id, &setval); if (njs_slow_path(ret != NJS_OK)) { goto exception; } - ret = njs_value_property_set(vm, value, key, &setval); + ret = njs_value_property_set(vm, value, key->atom_id, &setval); if (njs_slow_path(ret != NJS_OK)) { goto exception; } @@ -2069,8 +2086,8 @@ static njs_int_t njs_object_is(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval) { - njs_set_boolean(retval, njs_values_same(njs_arg(args, nargs, 1), - njs_arg(args, nargs, 2))); + njs_set_boolean(retval, njs_values_same(vm, njs_arg(args, nargs, 1), + njs_arg(args, nargs, 2))); return NJS_OK; } @@ -2084,7 +2101,8 @@ njs_object_is(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_int_t njs_primitive_prototype_get_proto(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { njs_uint_t index; njs_object_t *proto; @@ -2120,7 +2138,8 @@ njs_primitive_prototype_get_proto(njs_vm_t *vm, njs_object_prop_t *prop, njs_int_t njs_object_prototype_create(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { int64_t index; njs_function_t *function; @@ -2146,30 +2165,29 @@ njs_object_prototype_create(njs_vm_t *vm, njs_object_prop_t *prop, njs_value_t * -njs_property_prototype_create(njs_vm_t *vm, njs_lvlhsh_t *hash, +njs_property_prototype_create(njs_vm_t *vm, njs_flathsh_t *hash, njs_object_t *prototype) { - njs_int_t ret; - njs_object_prop_t *prop; - njs_lvlhsh_query_t lhq; - - static const njs_value_t proto_string = njs_string("prototype"); + njs_int_t ret; + njs_object_prop_t *prop; + njs_flathsh_query_t lhq; - prop = njs_object_prop_alloc(vm, &proto_string, &njs_value_undefined, 0); + prop = njs_object_prop_alloc(vm, &njs_value_undefined, 0); if (njs_slow_path(prop == NULL)) { return NULL; } + lhq.value = prop; + njs_set_type_object(njs_prop_value(prop), prototype, prototype->type); - lhq.value = prop; - lhq.key_hash = NJS_PROTOTYPE_HASH; - lhq.key = njs_str_value("prototype"); + lhq.key_hash = NJS_ATOM_STRING_prototype; + lhq.replace = 1; lhq.pool = vm->mem_pool; lhq.proto = &njs_object_hash_proto; - ret = njs_lvlhsh_insert(hash, &lhq); + ret = njs_flathsh_unique_insert(hash, &lhq); if (njs_fast_path(ret == NJS_OK)) { return njs_prop_value(prop); @@ -2181,65 +2199,70 @@ njs_property_prototype_create(njs_vm_t *vm, njs_lvlhsh_t *hash, } -static const njs_object_prop_t njs_object_constructor_properties[] = +static const njs_object_prop_init_t njs_object_constructor_properties[] = { NJS_DECLARE_PROP_LENGTH(1), NJS_DECLARE_PROP_NAME("Object"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), - NJS_DECLARE_PROP_NATIVE("create", njs_object_create, 2, 0), + NJS_DECLARE_PROP_NATIVE(STRING_create, njs_object_create, 2, 0), - NJS_DECLARE_PROP_NATIVE("keys", njs_object_keys, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_keys, njs_object_keys, 1, 0), - NJS_DECLARE_PROP_NATIVE("values", njs_object_values, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_values, njs_object_values, 1, 0), - NJS_DECLARE_PROP_NATIVE("entries", njs_object_entries, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_entries, njs_object_entries, 1, 0), - NJS_DECLARE_PROP_NATIVE("defineProperty", njs_object_define_property, 3, 0), + NJS_DECLARE_PROP_NATIVE(STRING_defineProperty, + njs_object_define_property, 3, 0), - NJS_DECLARE_PROP_LNATIVE("defineProperties", - njs_object_define_properties, 2, 0), + NJS_DECLARE_PROP_NATIVE(STRING_defineProperties, + njs_object_define_properties, 2, 0), - NJS_DECLARE_PROP_LNATIVE("getOwnPropertyDescriptor", - njs_object_get_own_property_descriptor, 2, 0), + NJS_DECLARE_PROP_NATIVE(STRING_getOwnPropertyDescriptor, + njs_object_get_own_property_descriptor, 2, 0), - NJS_DECLARE_PROP_LNATIVE("getOwnPropertyDescriptors", - njs_object_get_own_property_descriptors, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_getOwnPropertyDescriptors, + njs_object_get_own_property_descriptors, 1, 0), - NJS_DECLARE_PROP_LNATIVE("getOwnPropertyNames", - njs_object_get_own_property, 1, NJS_ENUM_STRING), + NJS_DECLARE_PROP_NATIVE(STRING_getOwnPropertyNames, + njs_object_get_own_property, 1, NJS_ENUM_STRING), - NJS_DECLARE_PROP_LNATIVE("getOwnPropertySymbols", - njs_object_get_own_property, 1, NJS_ENUM_SYMBOL), + NJS_DECLARE_PROP_NATIVE(STRING_getOwnPropertySymbols, + njs_object_get_own_property, 1, NJS_ENUM_SYMBOL), - NJS_DECLARE_PROP_NATIVE("getPrototypeOf", njs_object_get_prototype_of, 1, - 0), + NJS_DECLARE_PROP_NATIVE(STRING_getPrototypeOf, + njs_object_get_prototype_of, 1, 0), - NJS_DECLARE_PROP_NATIVE("setPrototypeOf", njs_object_set_prototype_of, 2, - 0), + NJS_DECLARE_PROP_NATIVE(STRING_setPrototypeOf, + njs_object_set_prototype_of, 2, 0), - NJS_DECLARE_PROP_NATIVE("freeze", njs_object_set_integrity_level, 1, - NJS_OBJECT_INTEGRITY_FROZEN), + NJS_DECLARE_PROP_NATIVE(STRING_freeze, njs_object_set_integrity_level, + 1, NJS_OBJECT_INTEGRITY_FROZEN), - NJS_DECLARE_PROP_NATIVE("isFrozen", njs_object_test_integrity_level, 1, + NJS_DECLARE_PROP_NATIVE(STRING_isFrozen, + njs_object_test_integrity_level, 1, NJS_OBJECT_INTEGRITY_FROZEN), - NJS_DECLARE_PROP_NATIVE("seal", njs_object_set_integrity_level, 1, + NJS_DECLARE_PROP_NATIVE(STRING_seal, njs_object_set_integrity_level, 1, NJS_OBJECT_INTEGRITY_SEALED), - NJS_DECLARE_PROP_NATIVE("isSealed", njs_object_test_integrity_level, 1, + NJS_DECLARE_PROP_NATIVE(STRING_isSealed, + njs_object_test_integrity_level, 1, NJS_OBJECT_INTEGRITY_SEALED), - NJS_DECLARE_PROP_LNATIVE("preventExtensions", njs_object_prevent_extensions, - 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_preventExtensions, + njs_object_prevent_extensions, 1, 0), - NJS_DECLARE_PROP_NATIVE("isExtensible", njs_object_is_extensible, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_isExtensible, njs_object_is_extensible, + 1, 0), - NJS_DECLARE_PROP_NATIVE("assign", njs_object_assign, 2, 0), + NJS_DECLARE_PROP_NATIVE(STRING_assign, njs_object_assign, 2, 0), - NJS_DECLARE_PROP_NATIVE("is", njs_object_is, 2, 0), + NJS_DECLARE_PROP_NATIVE(STRING_is, njs_object_is, 2, 0), }; @@ -2287,7 +2310,8 @@ njs_object_set_prototype(njs_vm_t *vm, njs_object_t *object, njs_int_t njs_object_prototype_proto(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { njs_int_t ret; njs_object_t *proto, *object; @@ -2334,7 +2358,8 @@ njs_object_prototype_proto(njs_vm_t *vm, njs_object_prop_t *prop, njs_int_t njs_object_prototype_create_constructor(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { int64_t index; njs_value_t *cons, constructor; @@ -2401,16 +2426,14 @@ found: njs_value_t * -njs_property_constructor_set(njs_vm_t *vm, njs_lvlhsh_t *hash, +njs_property_constructor_set(njs_vm_t *vm, njs_flathsh_t *hash, njs_value_t *constructor) { - njs_int_t ret; - njs_object_prop_t *prop; - njs_lvlhsh_query_t lhq; - - static const njs_value_t constructor_string = njs_string("constructor"); + njs_int_t ret; + njs_object_prop_t *prop; + njs_flathsh_query_t lhq; - prop = njs_object_prop_alloc(vm, &constructor_string, constructor, 1); + prop = njs_object_prop_alloc(vm, constructor, 1); if (njs_slow_path(prop == NULL)) { return NULL; } @@ -2419,14 +2442,14 @@ njs_property_constructor_set(njs_vm_t *vm, njs_lvlhsh_t *hash, prop->enumerable = 0; lhq.value = prop; - lhq.key_hash = NJS_CONSTRUCTOR_HASH; - lhq.key = njs_str_value("constructor"); + + lhq.key_hash = NJS_ATOM_STRING_constructor; + lhq.replace = 1; lhq.pool = vm->mem_pool; lhq.proto = &njs_object_hash_proto; - ret = njs_lvlhsh_insert(hash, &lhq); - + ret = njs_flathsh_unique_insert(hash, &lhq); if (njs_fast_path(ret == NJS_OK)) { return njs_prop_value(prop); } @@ -2457,30 +2480,6 @@ njs_object_prototype_value_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } -static const njs_value_t njs_object_null_string = njs_string("[object Null]"); -static const njs_value_t njs_object_undefined_string = - njs_long_string("[object Undefined]"); -static const njs_value_t njs_object_boolean_string = - njs_long_string("[object Boolean]"); -static const njs_value_t njs_object_number_string = - njs_long_string("[object Number]"); -static const njs_value_t njs_object_string_string = - njs_long_string("[object String]"); -static const njs_value_t njs_object_object_string = - njs_long_string("[object Object]"); -static const njs_value_t njs_object_array_string = - njs_string("[object Array]"); -static const njs_value_t njs_object_function_string = - njs_long_string("[object Function]"); -static const njs_value_t njs_object_regexp_string = - njs_long_string("[object RegExp]"); -static const njs_value_t njs_object_date_string = njs_string("[object Date]"); -static const njs_value_t njs_object_error_string = - njs_string("[object Error]"); -static const njs_value_t njs_object_arguments_string = - njs_long_string("[object Arguments]"); - - njs_int_t njs_object_prototype_to_string(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval) @@ -2493,16 +2492,15 @@ njs_int_t njs_object_to_string(njs_vm_t *vm, njs_value_t *this, njs_value_t *retval) { u_char *p; + uint32_t name; njs_int_t ret; njs_value_t tag; njs_string_prop_t string; - const njs_value_t *name; if (njs_is_null_or_undefined(this)) { - njs_value_assign(retval, - njs_is_null(this) ? &njs_object_null_string - : &njs_object_undefined_string); - + njs_atom_to_value(vm, retval, + njs_is_null(this) ? NJS_ATOM_STRING__object_Null_ + : NJS_ATOM_STRING__object_Undefined_); return NJS_OK; } @@ -2511,36 +2509,36 @@ njs_object_to_string(njs_vm_t *vm, njs_value_t *this, njs_value_t *retval) return ret; } - name = &njs_object_object_string; + name = NJS_ATOM_STRING__object_Object_; if (njs_is_array(this)) { - name = &njs_object_array_string; + name = NJS_ATOM_STRING__object_Array_; } else if (njs_is_object(this) && njs_lvlhsh_eq(&njs_object(this)->shared_hash, &vm->shared->arguments_object_instance_hash)) { - name = &njs_object_arguments_string; + name = NJS_ATOM_STRING__object_Arguments_; } else if (njs_is_function(this)) { - name = &njs_object_function_string; + name = NJS_ATOM_STRING__object_Function_; } else if (njs_is_error(this)) { - name = &njs_object_error_string; + name = NJS_ATOM_STRING__object_Error_; } else if (njs_is_object_value(this)) { switch (njs_object_value(this)->type) { case NJS_BOOLEAN: - name = &njs_object_boolean_string; + name = NJS_ATOM_STRING__object_Boolean_; break; case NJS_NUMBER: - name = &njs_object_number_string; + name = NJS_ATOM_STRING__object_Number_; break; case NJS_STRING: - name = &njs_object_string_string; + name = NJS_ATOM_STRING__object_String_; break; default: @@ -2548,10 +2546,10 @@ njs_object_to_string(njs_vm_t *vm, njs_value_t *this, njs_value_t *retval) } } else if (njs_is_date(this)) { - name = &njs_object_date_string; + name = NJS_ATOM_STRING__object_Date_; } else if (njs_is_regexp(this)) { - name = &njs_object_regexp_string; + name = NJS_ATOM_STRING__object_RegExp_; } ret = njs_object_string_tag(vm, this, &tag); @@ -2560,18 +2558,12 @@ njs_object_to_string(njs_vm_t *vm, njs_value_t *this, njs_value_t *retval) } if (ret == NJS_DECLINED) { - if (njs_slow_path(name == NULL)) { - njs_internal_error(vm, "Unknown value type"); - - return NJS_ERROR; - } - - njs_value_assign(retval, name); + njs_atom_to_value(vm, retval, name); return NJS_OK; } - (void) njs_string_prop(&string, &tag); + (void) njs_string_prop(vm, &string, &tag); p = njs_string_alloc(vm, retval, string.size + njs_length("[object ]"), string.length + njs_length("[object ]")); @@ -2612,9 +2604,9 @@ njs_object_prototype_has_own_property(njs_vm_t *vm, njs_value_t *args, } } - njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0, 1); + njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 1); - ret = njs_property_query(vm, &pq, value, property); + ret = njs_property_query_val(vm, &pq, value, property); switch (ret) { case NJS_OK: @@ -2658,9 +2650,9 @@ njs_object_prototype_prop_is_enumerable(njs_vm_t *vm, njs_value_t *args, } } - njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0, 1); + njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 1); - ret = njs_property_query(vm, &pq, value, property); + ret = njs_property_query_val(vm, &pq, value, property); switch (ret) { case NJS_OK: @@ -2717,26 +2709,28 @@ njs_object_prototype_is_prototype_of(njs_vm_t *vm, njs_value_t *args, } -static const njs_object_prop_t njs_object_prototype_properties[] = +static const njs_object_prop_init_t njs_object_prototype_properties[] = { - NJS_DECLARE_PROP_HANDLER("__proto__", njs_object_prototype_proto, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING___proto__, njs_object_prototype_proto, + 0, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_NATIVE("valueOf", njs_object_prototype_value_of, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_valueOf, njs_object_prototype_value_of, + 0, 0), - NJS_DECLARE_PROP_NATIVE("toString", njs_object_prototype_to_string, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_toString, njs_object_prototype_to_string, + 0, 0), - NJS_DECLARE_PROP_NATIVE("hasOwnProperty", + NJS_DECLARE_PROP_NATIVE(STRING_hasOwnProperty, njs_object_prototype_has_own_property, 1, 0), - NJS_DECLARE_PROP_LNATIVE("propertyIsEnumerable", - njs_object_prototype_prop_is_enumerable, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_propertyIsEnumerable, + njs_object_prototype_prop_is_enumerable, 1, 0), - NJS_DECLARE_PROP_NATIVE("isPrototypeOf", + NJS_DECLARE_PROP_NATIVE(STRING_isPrototypeOf, njs_object_prototype_is_prototype_of, 1, 0), }; @@ -2753,15 +2747,12 @@ njs_object_length(njs_vm_t *vm, njs_value_t *value, int64_t *length) njs_int_t ret; njs_value_t value_length; - const njs_value_t string_length = njs_string("length"); - if (njs_is_fast_array(value)) { *length = njs_array(value)->length; return NJS_OK; } - ret = njs_value_property(vm, value, njs_value_arg(&string_length), - &value_length); + ret = njs_value_property(vm, value, NJS_ATOM_STRING_length, &value_length); if (njs_slow_path(ret == NJS_ERROR)) { return ret; } diff --git a/src/njs_object.h b/src/njs_object.h index e3f58fdd..6b2438df 100644 --- a/src/njs_object.h +++ b/src/njs_object.h @@ -19,6 +19,7 @@ typedef enum { NJS_OBJECT_PROP_CONFIGURABLE = 16, NJS_OBJECT_PROP_WRITABLE = 32, NJS_OBJECT_PROP_UNSET = 64, + NJS_OBJECT_PROP_IS_STRING = 128, #define NJS_OBJECT_PROP_VALUE_ECW (NJS_OBJECT_PROP_VALUE \ | NJS_OBJECT_PROP_ENUMERABLE \ | NJS_OBJECT_PROP_CONFIGURABLE \ @@ -39,8 +40,8 @@ typedef enum { struct njs_object_init_s { - const njs_object_prop_t *properties; - njs_uint_t items; + const njs_object_prop_init_t *properties; + njs_uint_t items; }; @@ -49,6 +50,7 @@ typedef struct njs_traverse_s njs_traverse_t; struct njs_traverse_s { struct njs_traverse_s *parent; njs_object_prop_t *prop; + uint32_t atom_id; njs_value_t value; njs_array_t *keys; @@ -73,21 +75,23 @@ njs_array_t *njs_object_own_enumerate(njs_vm_t *vm, const njs_object_t *object, 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_make_shared(njs_vm_t *vm, njs_object_t *object); -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_hash_create(njs_vm_t *vm, njs_flathsh_t *hash, + const njs_object_prop_init_t *prop, njs_uint_t n); njs_int_t njs_primitive_prototype_get_proto(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, - njs_value_t *retval); + njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); njs_int_t njs_object_prototype_create(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval); -njs_value_t *njs_property_prototype_create(njs_vm_t *vm, njs_lvlhsh_t *hash, + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval); +njs_value_t *njs_property_prototype_create(njs_vm_t *vm, njs_flathsh_t *hash, njs_object_t *prototype); njs_int_t njs_object_prototype_proto(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_object_prototype_create_constructor(njs_vm_t *vm, - njs_object_prop_t *prop, njs_value_t *value, njs_value_t *setval, + uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval); -njs_value_t *njs_property_constructor_set(njs_vm_t *vm, njs_lvlhsh_t *hash, +njs_int_t njs_object_prototype_create_constructor(njs_vm_t *vm, + njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, + njs_value_t *setval, njs_value_t *retval); +njs_value_t *njs_property_constructor_set(njs_vm_t *vm, njs_flathsh_t *hash, njs_value_t *constructor); njs_int_t njs_object_to_string(njs_vm_t *vm, njs_value_t *value, njs_value_t *retval); @@ -97,21 +101,22 @@ njs_int_t njs_object_length(njs_vm_t *vm, njs_value_t *value, int64_t *dst); njs_int_t njs_prop_private_copy(njs_vm_t *vm, njs_property_query_t *pq, njs_object_t *proto); -njs_object_prop_t *njs_object_prop_alloc(njs_vm_t *vm, const njs_value_t *name, +njs_object_prop_t *njs_object_prop_alloc(njs_vm_t *vm, const njs_value_t *value, uint8_t attributes); njs_int_t njs_object_property(njs_vm_t *vm, njs_object_t *object, - njs_lvlhsh_query_t *lhq, njs_value_t *retval); + njs_flathsh_query_t *lhq, njs_value_t *retval); njs_object_prop_t *njs_object_property_add(njs_vm_t *vm, njs_value_t *object, - njs_value_t *key, njs_bool_t replace); + uint32_t atom_id, njs_bool_t replace); njs_int_t njs_object_prop_define(njs_vm_t *vm, njs_value_t *object, - njs_value_t *name, njs_value_t *value, unsigned flags, uint32_t hash); + uint32_t atom_id, njs_value_t *value, uint32_t flags); njs_int_t njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest, njs_value_t *value, njs_value_t *setval); njs_int_t njs_object_get_prototype_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval); const char *njs_prop_type_string(njs_object_prop_type_t type); njs_int_t njs_object_prop_init(njs_vm_t *vm, const njs_object_init_t* init, - const njs_object_prop_t *base, njs_value_t *value, njs_value_t *retval); + njs_object_prop_t *base, uint32_t atom_id, njs_value_t *value, + njs_value_t *retval); njs_inline njs_bool_t @@ -138,77 +143,38 @@ njs_is_generic_descriptor(njs_object_prop_t *prop) } -njs_inline void -njs_object_property_key_set(njs_lvlhsh_query_t *lhq, const njs_value_t *key, - uint32_t hash) -{ - if (njs_is_symbol(key)) { - - lhq->key.length = 0; - lhq->key.start = NULL; - lhq->key_hash = njs_symbol_key(key); - - } else { - - /* string. */ - - njs_string_get(key, &lhq->key); - - if (hash == 0) { - lhq->key_hash = njs_djb_hash(lhq->key.start, lhq->key.length); - - } else { - lhq->key_hash = hash; - } - } -} - - -njs_inline void -njs_object_property_init(njs_lvlhsh_query_t *lhq, const njs_value_t *key, - uint32_t hash) -{ - lhq->proto = &njs_object_hash_proto; - - njs_object_property_key_set(lhq, key, hash); -} - - njs_inline njs_int_t njs_primitive_value_to_key(njs_vm_t *vm, njs_value_t *dst, const njs_value_t *src) { - const njs_value_t *value; - switch (src->type) { - case NJS_NULL: - value = &njs_string_null; - break; + njs_atom_to_value(vm, dst, NJS_ATOM_STRING_null); + return NJS_OK; case NJS_UNDEFINED: - value = &njs_string_undefined; - break; + njs_atom_to_value(vm, dst, NJS_ATOM_STRING_undefined); + return NJS_OK; case NJS_BOOLEAN: - value = njs_is_true(src) ? &njs_string_true : &njs_string_false; - break; + if (njs_is_true(src)) { + njs_atom_to_value(vm, dst, NJS_ATOM_STRING_true); - case NJS_NUMBER: - return njs_number_to_string(vm, dst, src); + } else { + njs_atom_to_value(vm, dst, NJS_ATOM_STRING_false); + } + return NJS_OK; + + case NJS_NUMBER: case NJS_SYMBOL: case NJS_STRING: - value = src; - break; + *dst = *src; + return NJS_OK; default: return NJS_ERROR; } - - *dst = *value; - - return NJS_OK; } @@ -261,21 +227,63 @@ njs_key_string_get(njs_vm_t *vm, njs_value_t *key, njs_str_t *str) if (njs_slow_path(ret != NJS_OK)) { return ret; } + + } else if (njs_slow_path(!njs_is_string(key))) { + ret = njs_value_to_string(vm, key, key); + if (njs_slow_path(ret != NJS_OK)) { + return ret; + } + } + + njs_string_get(vm, key, str); + + return NJS_OK; +} + + +njs_inline njs_int_t +njs_atom_string_get(njs_vm_t *vm, uint32_t atom_id, njs_str_t *str) +{ + njs_value_t value; + + if (njs_atom_to_value(vm, &value, atom_id) != NJS_OK) { + return NJS_ERROR; } - njs_string_get(key, str); + njs_key_string_get(vm, &value, str); return NJS_OK; } +njs_inline njs_int_t +njs_object_prop_define_val(njs_vm_t *vm, njs_value_t *object, njs_value_t *name, + njs_value_t *value, unsigned flags) +{ + njs_int_t ret; + + if (njs_value_atom(name) == NJS_ATOM_STRING_unknown) { + ret = njs_atom_atomize_key(vm, name); + if (ret != NJS_OK) { + return ret; + } + } + + if (njs_is_string(name)) { + flags |= NJS_OBJECT_PROP_IS_STRING; + } + + return njs_object_prop_define(vm, object, name->atom_id, value, flags); +} + + njs_inline njs_int_t njs_value_create_data_prop(njs_vm_t *vm, njs_value_t *value, njs_value_t *name, njs_value_t *setval, uint32_t hash) { - return njs_object_prop_define(vm, value, name, setval, - NJS_OBJECT_PROP_CREATE - | NJS_OBJECT_PROP_VALUE_ECW, hash); + return njs_object_prop_define_val(vm, value, name, setval, + NJS_OBJECT_PROP_CREATE + | NJS_OBJECT_PROP_VALUE_ECW); } @@ -296,12 +304,9 @@ njs_object_length_set(njs_vm_t *vm, njs_value_t *value, int64_t length) { njs_value_t index; - static const njs_value_t string_length = njs_string("length"); - njs_value_number_set(&index, length); - return njs_value_property_set(vm, value, njs_value_arg(&string_length), - &index); + return njs_value_property_set(vm, value, NJS_ATOM_STRING_length, &index); } @@ -310,10 +315,7 @@ njs_object_string_tag(njs_vm_t *vm, njs_value_t *value, njs_value_t *tag) { njs_int_t ret; - static const njs_value_t to_string_tag = - njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG); - - ret = njs_value_property(vm, value, njs_value_arg(&to_string_tag), tag); + ret = njs_value_property(vm, value, NJS_ATOM_SYMBOL_toStringTag, tag); if (njs_slow_path(ret != NJS_OK)) { return ret; } diff --git a/src/njs_object_hash.h b/src/njs_object_hash.h deleted file mode 100644 index 163c814c..00000000 --- a/src/njs_object_hash.h +++ /dev/null @@ -1,842 +0,0 @@ - -/* - * Copyright (C) Igor Sysoev - * Copyright (C) NGINX, Inc. - */ - -#ifndef _NJS_OBJECT_HASH_H_INCLUDED_ -#define _NJS_OBJECT_HASH_H_INCLUDED_ - - -#define NJS___PROTO___HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - '_'), '_'), 'p'), 'r'), 'o'), 't'), 'o'), '_'), '_') - - -#define NJS_ARRAY_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'A'), 'r'), 'r'), 'a'), 'y') - - -#define NJS_ARGV_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'a'), 'r'), 'g'), 'v') - - -#define NJS_BOOLEAN_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'B'), 'o'), 'o'), 'l'), 'e'), 'a'), 'n') - - -#define NJS_CONFIGURABLE_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'c'), 'o'), 'n'), 'f'), 'i'), 'g'), 'u'), 'r'), 'a'), 'b'), 'l'), 'e') - - -#define NJS_CONSTRUCTOR_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'c'), 'o'), 'n'), 's'), 't'), 'r'), 'u'), 'c'), 't'), 'o'), 'r') - - -#define NJS_DATE_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'D'), 'a'), 't'), 'e') - - -#define NJS_PROMISE_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'P'), 'r'), 'o'), 'm'), 'i'), 's'), 'e') - - -#define NJS_ENUMERABLE_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'e'), 'n'), 'u'), 'm'), 'e'), 'r'), 'a'), 'b'), 'l'), 'e') - - -#define NJS_ERRNO_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'e'), 'r'), 'r'), 'n'), 'o') - - -#define NJS_ERROR_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'E'), 'r'), 'r'), 'o'), 'r') - - -#define NJS_ENCODING_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'e'), 'n'), 'c'), 'o'), 'd'), 'i'), 'n'), 'g') - - -#define NJS_ENV_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'e'), 'n'), 'v') - - -#define NJS_EVAL_ERROR_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'E'), 'v'), 'a'), 'l'), 'E'), 'r'), 'r'), 'o'), 'r') - - -#define NJS_FLAG_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'f'), 'l'), 'a'), 'g') - - -#define NJS_GET_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'g'), 'e'), 't') - - -#define NJS_GLOBAL_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'g'), 'l'), 'o'), 'b'), 'a'), 'l') - - -#define NJS_GLOBAL_THIS_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'g'), 'l'), 'o'), 'b'), 'a'), 'l'), 'T'), 'h'), 'i'), 's') - - -#define NJS_FUNCTION_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'F'), 'u'), 'n'), 'c'), 't'), 'i'), 'o'), 'n') - - -#define NJS_INDEX_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'i'), 'n'), 'd'), 'e'), 'x') - - -#define NJS_INPUT_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'i'), 'n'), 'p'), 'u'), 't') - - -#define NJS_INTERNAL_ERROR_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'I'), 'n'), 't'), 'e'), 'r'), 'n'), 'a'), 'l'), \ - 'E'), 'r'), 'r'), 'o'), 'r') - - -#define NJS_GROUPS_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'g'), 'r'), 'o'), 'u'), 'p'), 's') - - -#define NJS_JOIN_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'j'), 'o'), 'i'), 'n') - - -#define NJS_JSON_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'J'), 'S'), 'O'), 'N') - - -#define NJS_LENGTH_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'l'), 'e'), 'n'), 'g'), 't'), 'h') - - -#define NJS_NAME_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'n'), 'a'), 'm'), 'e') - - -#define NJS_NJS_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'n'), 'j'), 's') - - -#define NJS_262_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - '$'), '2'), '6'), '2') - - -#define NJS_NUMBER_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'N'), 'u'), 'm'), 'b'), 'e'), 'r') - - -#define NJS_MATH_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'M'), 'a'), 't'), 'h') - - -#define NJS_MEMORY_ERROR_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'M'), 'e'), 'm'), 'o'), 'r'), 'y'), \ - 'E'), 'r'), 'r'), 'o'), 'r') - - -#define NJS_AGGREGATE_ERROR_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'A'), 'g'), 'g'), 'r'), 'e'), 'g'), 'a'), 't'), 'e'), \ - 'E'), 'r'), 'r'), 'o'), 'r') - - -#define NJS_MESSAGE_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'm'), 'e'), 's'), 's'), 'a'), 'g'), 'e') - - -#define NJS_ERRORS_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'e'), 'r'), 'r'), 'o'), 'r'), 's') - - -#define NJS_MODE_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'm'), 'o'), 'd'), 'e') - - -#define NJS_OBJECT_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'O'), 'b'), 'j'), 'e'), 'c'), 't') - - -#define NJS_PATH_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'p'), 'a'), 't'), 'h') - - -#define NJS_PROCESS_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'p'), 'r'), 'o'), 'c'), 'e'), 's'), 's') - - -#define NJS_PROTOTYPE_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'p'), 'r'), 'o'), 't'), 'o'), 't'), 'y'), 'p'), 'e') - - -#define NJS_RANGE_ERROR_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'R'), 'a'), 'n'), 'g'), 'e'), 'E'), 'r'), 'r'), 'o'), 'r') - - -#define NJS_REF_ERROR_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'R'), 'e'), 'f'), 'e'), 'r'), 'e'), 'n'), 'c'), 'e'), \ - 'E'), 'r'), 'r'), 'o'), 'r') - - -#define NJS_REGEXP_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'R'), 'e'), 'g'), 'E'), 'x'), 'p') - - -#define NJS_SET_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 's'), 'e'), 't') - - -#define NJS_STACK_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 's'), 't'), 'a'), 'c'), 'k') - - -#define NJS_STRING_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'S'), 't'), 'r'), 'i'), 'n'), 'g') - - -#define NJS_SYMBOL_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'S'), 'y'), 'm'), 'b'), 'o'), 'l') - - -#define NJS_SYNTAX_ERROR_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'S'), 'y'), 'n'), 't'), 'a'), 'x'), \ - 'E'), 'r'), 'r'), 'o'), 'r') - - -#define NJS_SYSCALL_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 's'), 'y'), 's'), 'c'), 'a'), 'l'), 'l') - - -#define NJS_TO_JSON_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 't'), 'o'), 'J'), 'S'), 'O'), 'N') - - -#define NJS_TO_STRING_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 't'), 'o'), 'S'), 't'), 'r'), 'i'), 'n'), 'g') - - -#define NJS_TO_ISO_STRING_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 't'), 'o'), 'I'), 'S'), 'O'), 'S'), 't'), 'r'), 'i'), 'n'), 'g') - - -#define NJS_TYPE_ERROR_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'T'), 'y'), 'p'), 'e'), 'E'), 'r'), 'r'), 'o'), 'r') - - -#define NJS_VALUE_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'v'), 'a'), 'l'), 'u'), 'e') - - -#define NJS_VALUE_OF_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'v'), 'a'), 'l'), 'u'), 'e'), 'O'), 'f') - - -#define NJS_WRITABABLE_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'w'), 'r'), 'i'), 't'), 'a'), 'b'), 'l'), 'e') - - -#define NJS_URI_ERROR_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'U'), 'R'), 'I'), 'E'), 'r'), 'r'), 'o'), 'r') - - -#define NJS_ARRAY_BUFFER_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'A'), 'r'), 'r'), 'a'), 'y'), 'B'), 'u'), 'f'), 'f'), 'e'), 'r') - - -#define NJS_DATA_VIEW_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'D'), 'a'), 't'), 'a'), 'V'), 'i'), 'e'), 'w') - - -#define NJS_UINT8ARRAY_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'U'), 'i'), 'n'), 't'), '8'), 'A'), 'r'), 'r'), 'a'), 'y') - - -#define NJS_UINT16ARRAY_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'U'), 'i'), 'n'), 't'), '1'), '6'), 'A'), 'r'), 'r'), 'a'), 'y') - - -#define NJS_UINT32ARRAY_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'U'), 'i'), 'n'), 't'), '3'), '2'), 'A'), 'r'), 'r'), 'a'), 'y') - - -#define NJS_INT8ARRAY_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'I'), 'n'), 't'), '8'), 'A'), 'r'), 'r'), 'a'), 'y') - - -#define NJS_INT16ARRAY_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'I'), 'n'), 't'), '1'), '6'), 'A'), 'r'), 'r'), 'a'), 'y') - - -#define NJS_INT32ARRAY_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'I'), 'n'), 't'), '3'), '2'), 'A'), 'r'), 'r'), 'a'), 'y') - - -#define NJS_FLOAT32ARRAY_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'F'), 'l'), 'o'), 'a'), 't'), '3'), '2'), 'A'), 'r'), 'r'), 'a'), 'y') - - -#define NJS_FLOAT64ARRAY_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'F'), 'l'), 'o'), 'a'), 't'), '6'), '4'), 'A'), 'r'), 'r'), 'a'), 'y') - - -#define NJS_UINT8CLAMPEDARRAY_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'U'), 'i'), 'n'), 't'), '8'), 'C'), 'l'), 'a'), 'm'), 'p'), 'e'), \ - 'd'), 'A'), 'r'), 'r'), 'a'), 'y') - - -#define NJS_TEXT_DECODER_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'T'), 'e'), 'x'), 't'), 'D'), 'e'), 'c'), 'o'), 'd'), 'e'), 'r') - - -#define NJS_TEXT_ENCODER_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'T'), 'e'), 'x'), 't'), 'E'), 'n'), 'c'), 'o'), 'd'), 'e'), 'r') - - -#define NJS_BUFFER_HASH \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add( \ - njs_djb_hash_add(NJS_DJB_HASH_INIT, \ - 'B'), 'u'), 'f'), 'f'), 'e'), 'r') - - -#endif /* _NJS_OBJECT_HASH_H_INCLUDED_ */ diff --git a/src/njs_object_prop.c b/src/njs_object_prop.c index a24af753..d7c55d3a 100644 --- a/src/njs_object_prop.c +++ b/src/njs_object_prop.c @@ -9,13 +9,13 @@ static njs_object_prop_t *njs_object_prop_alloc2(njs_vm_t *vm, - const njs_value_t *name, njs_object_prop_type_t type, unsigned flags); + njs_object_prop_type_t type, unsigned flags); static njs_object_prop_t *njs_descriptor_prop(njs_vm_t *vm, - const njs_value_t *name, const njs_value_t *desc); + const njs_value_t *desc); njs_object_prop_t * -njs_object_prop_alloc(njs_vm_t *vm, const njs_value_t *name, +njs_object_prop_alloc(njs_vm_t *vm, const njs_value_t *value, uint8_t attributes) { unsigned flags; @@ -33,7 +33,7 @@ njs_object_prop_alloc(njs_vm_t *vm, const njs_value_t *name, break; } - prop = njs_object_prop_alloc2(vm, name, NJS_PROPERTY, flags); + prop = njs_object_prop_alloc2(vm, NJS_PROPERTY, flags); if (njs_slow_path(prop == NULL)) { return NULL; } @@ -45,10 +45,9 @@ njs_object_prop_alloc(njs_vm_t *vm, const njs_value_t *name, static njs_object_prop_t * -njs_object_prop_alloc2(njs_vm_t *vm, const njs_value_t *name, +njs_object_prop_alloc2(njs_vm_t *vm, njs_object_prop_type_t type, unsigned flags) { - njs_int_t ret; njs_object_prop_t *prop; prop = njs_mp_align(vm->mem_pool, sizeof(njs_value_t), @@ -58,15 +57,6 @@ njs_object_prop_alloc2(njs_vm_t *vm, const njs_value_t *name, return NULL; } - njs_value_assign(&prop->name, name); - - if (njs_slow_path(!njs_is_key(&prop->name))) { - ret = njs_value_to_key(vm, &prop->name, &prop->name); - if (njs_slow_path(ret != NJS_OK)) { - return NULL; - } - } - prop->type = type; prop->enum_in_object_hash = 0; @@ -92,15 +82,15 @@ njs_object_prop_alloc2(njs_vm_t *vm, const njs_value_t *name, njs_int_t -njs_object_property(njs_vm_t *vm, njs_object_t *object, njs_lvlhsh_query_t *lhq, - njs_value_t *retval) +njs_object_property(njs_vm_t *vm, njs_object_t *object, + njs_flathsh_query_t *lhq, njs_value_t *retval) { njs_int_t ret; njs_value_t value; njs_object_prop_t *prop; do { - ret = njs_lvlhsh_find(&object->hash, lhq); + ret = njs_flathsh_unique_find(&object->hash, lhq); if (njs_fast_path(ret == NJS_OK)) { prop = lhq->value; @@ -110,7 +100,7 @@ njs_object_property(njs_vm_t *vm, njs_object_t *object, njs_lvlhsh_query_t *lhq, } } - ret = njs_lvlhsh_find(&object->shared_hash, lhq); + ret = njs_flathsh_unique_find(&object->shared_hash, lhq); if (njs_fast_path(ret == NJS_OK)) { goto found; @@ -145,32 +135,25 @@ found: njs_object_prop_t * -njs_object_property_add(njs_vm_t *vm, njs_value_t *object, njs_value_t *key, +njs_object_property_add(njs_vm_t *vm, njs_value_t *object, unsigned atom_id, njs_bool_t replace) { - njs_int_t ret; - njs_value_t key_value; - njs_object_prop_t *prop; - njs_lvlhsh_query_t lhq; + njs_int_t ret; + njs_object_prop_t *prop; + njs_flathsh_query_t lhq; - prop = njs_object_prop_alloc(vm, key, &njs_value_invalid, 1); + prop = njs_object_prop_alloc(vm, &njs_value_invalid, 1); if (njs_slow_path(prop == NULL)) { return NULL; } - ret = njs_value_to_key(vm, &key_value, key); - if (njs_slow_path(ret != NJS_OK)) { - return NULL; - } - - lhq.proto = &njs_object_hash_proto; - njs_string_get(&key_value, &lhq.key); - lhq.key_hash = njs_djb_hash(lhq.key.start, lhq.key.length); lhq.value = prop; + lhq.key_hash = atom_id; lhq.replace = replace; lhq.pool = vm->mem_pool; + lhq.proto = &njs_object_hash_proto; - ret = njs_lvlhsh_insert(njs_object_hash(object), &lhq); + ret = njs_flathsh_unique_insert(njs_object_hash(object), &lhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "lvlhsh insert failed"); return NULL; @@ -184,32 +167,23 @@ njs_object_property_add(njs_vm_t *vm, njs_value_t *object, njs_value_t *key, * ES5.1, 8.12.9: [[DefineOwnProperty]] */ njs_int_t -njs_object_prop_define(njs_vm_t *vm, njs_value_t *object, - njs_value_t *name, njs_value_t *value, unsigned flags, uint32_t hash) +njs_object_prop_define(njs_vm_t *vm, njs_value_t *object, unsigned atom_id, + njs_value_t *value, unsigned flags) { uint32_t length, index; njs_int_t ret; njs_array_t *array; - njs_value_t retval; + njs_value_t key, retval; njs_object_prop_t *prop, *prev; njs_property_query_t pq; - static const njs_str_t length_key = njs_str("length"); - - if (njs_slow_path(!njs_is_index_or_key(name))) { - ret = njs_value_to_key(vm, name, name); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - } - again: - njs_property_query_init(&pq, NJS_PROPERTY_QUERY_SET, hash, 1); + njs_property_query_init(&pq, NJS_PROPERTY_QUERY_SET, 1); ret = (flags & NJS_OBJECT_PROP_CREATE) ? NJS_DECLINED - : njs_property_query(vm, &pq, object, name); + : njs_property_query(vm, &pq, object, atom_id); if (njs_slow_path(ret == NJS_ERROR)) { return ret; @@ -217,7 +191,7 @@ again: switch (njs_prop_type(flags)) { case NJS_OBJECT_PROP_DESCRIPTOR: - prop = njs_descriptor_prop(vm, name, value); + prop = njs_descriptor_prop(vm, value); if (njs_slow_path(prop == NULL)) { return NJS_ERROR; } @@ -227,20 +201,18 @@ again: case NJS_OBJECT_PROP_VALUE: if (((flags & NJS_OBJECT_PROP_VALUE_ECW) == NJS_OBJECT_PROP_VALUE_ECW) && njs_is_fast_array(object) - && njs_is_number(name)) + && njs_atom_is_number(atom_id)) { - if (njs_number_is_integer_index(njs_number(name))) { - array = njs_array(object); - index = (uint32_t) njs_number(name); + array = njs_array(object); + index = njs_atom_number(atom_id); - if (index < array->length) { - njs_value_assign(&array->start[index], value); - return NJS_OK; - } + if (index < array->length) { + njs_value_assign(&array->start[index], value); + return NJS_OK; } } - prop = njs_object_prop_alloc2(vm, name, NJS_PROPERTY, + prop = njs_object_prop_alloc2(vm, NJS_PROPERTY, flags & NJS_OBJECT_PROP_VALUE_ECW); if (njs_slow_path(prop == NULL)) { return NJS_ERROR; @@ -254,7 +226,7 @@ again: default: njs_assert(njs_is_function(value)); - prop = njs_object_prop_alloc2(vm, name, NJS_ACCESSOR, + prop = njs_object_prop_alloc2(vm, NJS_ACCESSOR, NJS_OBJECT_PROP_VALUE_EC); if (njs_slow_path(prop == NULL)) { return NJS_ERROR; @@ -277,17 +249,23 @@ again: set_prop: if (!njs_object(object)->extensible) { - njs_key_string_get(vm, name, &pq.lhq.key); + njs_atom_string_get(vm, atom_id, &pq.lhq.key); njs_type_error(vm, "Cannot add property \"%V\", " "object is not extensible", &pq.lhq.key); return NJS_ERROR; } - if (njs_slow_path(njs_is_typed_array(object) - && njs_is_string(name))) + if (njs_slow_path(njs_is_typed_array(object) && + (flags & NJS_OBJECT_PROP_IS_STRING))) { /* Integer-Indexed Exotic Objects [[DefineOwnProperty]]. */ - if (!isnan(njs_string_to_index(name))) { + + ret = njs_atom_to_value(vm, &key, atom_id); + if (njs_slow_path(ret != NJS_OK)) { + return ret; + } + + if (!isnan(njs_string_to_index(&key))) { njs_type_error(vm, "Invalid typed array index"); return NJS_ERROR; } @@ -332,32 +310,13 @@ set_prop: } else { - if ((flags & NJS_OBJECT_PROP_CREATE)) { - ret = njs_primitive_value_to_key(vm, &pq.key, name); - if (njs_slow_path(ret != NJS_OK)) { - return NJS_ERROR; - } - - if (njs_is_symbol(name)) { - pq.lhq.key_hash = njs_symbol_key(name); - pq.lhq.key.start = NULL; - - } else { - njs_string_get(&pq.key, &pq.lhq.key); - pq.lhq.key_hash = (hash == 0) - ? njs_djb_hash(pq.lhq.key.start, - pq.lhq.key.length) - : hash; - } - - pq.lhq.proto = &njs_object_hash_proto; - } - + pq.lhq.key_hash = atom_id; + pq.lhq.proto = &njs_object_hash_proto; pq.lhq.value = prop; pq.lhq.replace = 0; pq.lhq.pool = vm->mem_pool; - ret = njs_lvlhsh_insert(njs_object_hash(object), &pq.lhq); + ret = njs_flathsh_unique_insert(njs_object_hash(object), &pq.lhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "lvlhsh insert failed"); return NJS_ERROR; @@ -498,7 +457,8 @@ set_prop: if (njs_is_valid(njs_prop_value(prop)) && prev->type != NJS_PROPERTY_HANDLER - && !njs_values_same(njs_prop_value(prop), njs_prop_value(prev))) + && !njs_values_same(vm, njs_prop_value(prop), + njs_prop_value(prev))) { goto exception; } @@ -523,8 +483,7 @@ set_prop: done: if (njs_slow_path(njs_is_fast_array(object) - && pq.lhq.key_hash == NJS_LENGTH_HASH) - && njs_strstr_eq(&pq.lhq.key, &length_key) + && pq.lhq.key_hash == NJS_ATOM_STRING_length) && prop->writable == NJS_ATTRIBUTE_FALSE) { array = njs_array(object); @@ -558,7 +517,7 @@ done: if (prev->type == NJS_PROPERTY_HANDLER) { if (prev->writable) { - ret = njs_prop_handler(prev)(vm, prev, object, + ret = njs_prop_handler(prev)(vm, prev, atom_id, object, njs_prop_value(prop), &retval); if (njs_slow_path(ret == NJS_ERROR)) { return ret; @@ -578,13 +537,12 @@ done: } else { if (njs_slow_path(njs_is_array(object) - && pq.lhq.key_hash == NJS_LENGTH_HASH) - && njs_strstr_eq(&pq.lhq.key, &length_key)) + && pq.lhq.key_hash == NJS_ATOM_STRING_length)) { if (prev->configurable != NJS_ATTRIBUTE_TRUE && prev->writable != NJS_ATTRIBUTE_TRUE - && !njs_values_strict_equal(njs_prop_value(prev), - njs_prop_value(prop))) + && !njs_values_strict_equal(vm, njs_prop_value(prev), + njs_prop_value(prop))) { njs_type_error(vm, "Cannot redefine property: \"length\""); return NJS_ERROR; @@ -623,7 +581,7 @@ done: exception: - njs_key_string_get(vm, &pq.key, &pq.lhq.key); + njs_atom_string_get(vm, atom_id, &pq.lhq.key); njs_type_error(vm, "Cannot redefine property: \"%V\"", &pq.lhq.key); return NJS_ERROR; @@ -635,7 +593,7 @@ njs_prop_private_copy(njs_vm_t *vm, njs_property_query_t *pq, njs_object_t *proto) { njs_int_t ret; - njs_value_t *value; + njs_value_t *value, prop_name; njs_object_t *object; njs_function_t *function; njs_object_prop_t *prop, *shared; @@ -654,7 +612,7 @@ njs_prop_private_copy(njs_vm_t *vm, njs_property_query_t *pq, pq->lhq.value = prop; pq->lhq.pool = vm->mem_pool; - ret = njs_lvlhsh_insert(&proto->hash, &pq->lhq); + ret = njs_flathsh_unique_insert(&proto->hash, &pq->lhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "lvlhsh insert failed"); return NJS_ERROR; @@ -710,7 +668,12 @@ njs_prop_private_copy(njs_vm_t *vm, njs_property_query_t *pq, return NJS_ERROR; } - return njs_function_name_set(vm, function, &prop->name, NULL); + ret = njs_atom_to_value(vm, &prop_name, pq->lhq.key_hash); + if (ret != NJS_OK) { + return NJS_ERROR; + } + + return njs_function_name_set(vm, function, &prop_name, NULL); default: break; @@ -721,25 +684,22 @@ njs_prop_private_copy(njs_vm_t *vm, njs_property_query_t *pq, static njs_object_prop_t * -njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *name, - const njs_value_t *desc) +njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *desc) { - njs_int_t ret; - njs_bool_t data, accessor; - njs_value_t value; - njs_object_t *desc_object; - njs_function_t *getter, *setter; - njs_object_prop_t *prop; - njs_lvlhsh_query_t lhq; - - static const njs_value_t get_string = njs_string("get"); + njs_int_t ret; + njs_bool_t data, accessor; + njs_value_t value; + njs_object_t *desc_object; + njs_function_t *getter, *setter; + njs_object_prop_t *prop; + njs_flathsh_query_t lhq; if (!njs_is_object(desc)) { njs_type_error(vm, "property descriptor must be an object"); return NULL; } - prop = njs_object_prop_alloc(vm, name, &njs_value_invalid, + prop = njs_object_prop_alloc(vm, &njs_value_invalid, NJS_ATTRIBUTE_UNSET); if (njs_slow_path(prop == NULL)) { return NULL; @@ -751,7 +711,8 @@ njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *name, setter = NJS_PROP_PTR_UNSET; desc_object = njs_object(desc); - njs_object_property_init(&lhq, &get_string, NJS_GET_HASH); + lhq.proto = &njs_object_hash_proto; + lhq.key_hash = NJS_ATOM_STRING_get; ret = njs_object_property(vm, desc_object, &lhq, &value); if (njs_slow_path(ret == NJS_ERROR)) { @@ -768,8 +729,7 @@ njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *name, getter = njs_is_function(&value) ? njs_function(&value) : NULL; } - lhq.key = njs_str_value("set"); - lhq.key_hash = NJS_SET_HASH; + lhq.key_hash = NJS_ATOM_STRING_set; ret = njs_object_property(vm, desc_object, &lhq, &value); if (njs_slow_path(ret == NJS_ERROR)) { @@ -786,8 +746,7 @@ njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *name, setter = njs_is_function(&value) ? njs_function(&value) : NULL; } - lhq.key = njs_str_value("value"); - lhq.key_hash = NJS_VALUE_HASH; + lhq.key_hash = NJS_ATOM_STRING_value; ret = njs_object_property(vm, desc_object, &lhq, &value); if (njs_slow_path(ret == NJS_ERROR)) { @@ -799,8 +758,7 @@ njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *name, njs_value_assign(njs_prop_value(prop), &value); } - lhq.key = njs_str_value("writable"); - lhq.key_hash = NJS_WRITABABLE_HASH; + lhq.key_hash = NJS_ATOM_STRING_writable; ret = njs_object_property(vm, desc_object, &lhq, &value); if (njs_slow_path(ret == NJS_ERROR)) { @@ -818,8 +776,7 @@ njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *name, return NULL; } - lhq.key = njs_str_value("enumerable"); - lhq.key_hash = NJS_ENUMERABLE_HASH; + lhq.key_hash = NJS_ATOM_STRING_enumerable; ret = njs_object_property(vm, desc_object, &lhq, &value); if (njs_slow_path(ret == NJS_ERROR)) { @@ -830,8 +787,7 @@ njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *name, prop->enumerable = njs_is_true(&value); } - lhq.key = njs_str_value("configurable"); - lhq.key_hash = NJS_CONFIGURABLE_HASH; + lhq.key_hash = NJS_ATOM_STRING_configurable; ret = njs_object_property(vm, desc_object, &lhq, &value); if (njs_slow_path(ret == NJS_ERROR)) { @@ -852,17 +808,6 @@ njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *name, } -static const njs_value_t njs_object_value_string = njs_string("value"); -static const njs_value_t njs_object_get_string = njs_string("get"); -static const njs_value_t njs_object_set_string = njs_string("set"); -static const njs_value_t njs_object_writable_string = - njs_string("writable"); -static const njs_value_t njs_object_enumerable_string = - njs_string("enumerable"); -static const njs_value_t njs_object_configurable_string = - njs_string("configurable"); - - njs_int_t njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest, njs_value_t *value, njs_value_t *key) @@ -871,10 +816,10 @@ njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest, njs_object_t *desc; njs_object_prop_t *pr, *prop; const njs_value_t *setval; - njs_lvlhsh_query_t lhq; + njs_flathsh_query_t lhq; njs_property_query_t pq; - njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0, 1); + njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 1); if (njs_slow_path(!njs_is_key(key))) { ret = njs_value_to_key(vm, key, key); @@ -883,7 +828,7 @@ njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest, } } - ret = njs_property_query(vm, &pq, value, key); + ret = njs_property_query_val(vm, &pq, value, key); switch (ret) { case NJS_OK: @@ -897,7 +842,7 @@ njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest, case NJS_PROPERTY_HANDLER: pq.scratch = *prop; prop = &pq.scratch; - ret = njs_prop_handler(prop)(vm, prop, value, NULL, + ret = njs_prop_handler(prop)(vm, prop, key->atom_id, value, NULL, njs_prop_value(prop)); if (njs_slow_path(ret == NJS_ERROR)) { return ret; @@ -932,37 +877,33 @@ njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest, lhq.pool = vm->mem_pool; if (njs_is_data_descriptor(prop)) { + lhq.key_hash = NJS_ATOM_STRING_value; - lhq.key = njs_str_value("value"); - lhq.key_hash = NJS_VALUE_HASH; - - pr = njs_object_prop_alloc(vm, &njs_object_value_string, - njs_prop_value(prop), 1); + pr = njs_object_prop_alloc(vm, njs_prop_value(prop), 1); if (njs_slow_path(pr == NULL)) { return NJS_ERROR; } lhq.value = pr; - ret = njs_lvlhsh_insert(&desc->hash, &lhq); + ret = njs_flathsh_unique_insert(&desc->hash, &lhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "lvlhsh insert failed"); return NJS_ERROR; } - lhq.key = njs_str_value("writable"); - lhq.key_hash = NJS_WRITABABLE_HASH; + lhq.key_hash = NJS_ATOM_STRING_writable; setval = (prop->writable == 1) ? &njs_value_true : &njs_value_false; - pr = njs_object_prop_alloc(vm, &njs_object_writable_string, setval, 1); + pr = njs_object_prop_alloc(vm, setval, 1); if (njs_slow_path(pr == NULL)) { return NJS_ERROR; } lhq.value = pr; - ret = njs_lvlhsh_insert(&desc->hash, &lhq); + ret = njs_flathsh_unique_insert(&desc->hash, &lhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "lvlhsh insert failed"); return NJS_ERROR; @@ -970,11 +911,9 @@ njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest, } else { - lhq.key = njs_str_value("get"); - lhq.key_hash = NJS_GET_HASH; + lhq.key_hash = NJS_ATOM_STRING_get; - pr = njs_object_prop_alloc(vm, &njs_object_get_string, - &njs_value_undefined, 1); + pr = njs_object_prop_alloc(vm, &njs_value_undefined, 1); if (njs_slow_path(pr == NULL)) { return NJS_ERROR; } @@ -985,17 +924,15 @@ njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest, lhq.value = pr; - ret = njs_lvlhsh_insert(&desc->hash, &lhq); + ret = njs_flathsh_unique_insert(&desc->hash, &lhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "lvlhsh insert failed"); return NJS_ERROR; } - lhq.key = njs_str_value("set"); - lhq.key_hash = NJS_SET_HASH; + lhq.key_hash = NJS_ATOM_STRING_set; - pr = njs_object_prop_alloc(vm, &njs_object_set_string, - &njs_value_undefined, 1); + pr = njs_object_prop_alloc(vm, &njs_value_undefined, 1); if (njs_slow_path(pr == NULL)) { return NJS_ERROR; } @@ -1006,44 +943,42 @@ njs_object_prop_descriptor(njs_vm_t *vm, njs_value_t *dest, lhq.value = pr; - ret = njs_lvlhsh_insert(&desc->hash, &lhq); + ret = njs_flathsh_unique_insert(&desc->hash, &lhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "lvlhsh insert failed"); return NJS_ERROR; } } - lhq.key = njs_str_value("enumerable"); - lhq.key_hash = NJS_ENUMERABLE_HASH; + lhq.key_hash = NJS_ATOM_STRING_enumerable; setval = (prop->enumerable == 1) ? &njs_value_true : &njs_value_false; - pr = njs_object_prop_alloc(vm, &njs_object_enumerable_string, setval, 1); + pr = njs_object_prop_alloc(vm, setval, 1); if (njs_slow_path(pr == NULL)) { return NJS_ERROR; } lhq.value = pr; - ret = njs_lvlhsh_insert(&desc->hash, &lhq); + ret = njs_flathsh_unique_insert(&desc->hash, &lhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "lvlhsh insert failed"); return NJS_ERROR; } - lhq.key = njs_str_value("configurable"); - lhq.key_hash = NJS_CONFIGURABLE_HASH; + lhq.key_hash = NJS_ATOM_STRING_configurable; setval = (prop->configurable == 1) ? &njs_value_true : &njs_value_false; - pr = njs_object_prop_alloc(vm, &njs_object_configurable_string, setval, 1); + pr = njs_object_prop_alloc(vm, setval, 1); if (njs_slow_path(pr == NULL)) { return NJS_ERROR; } lhq.value = pr; - ret = njs_lvlhsh_insert(&desc->hash, &lhq); + ret = njs_flathsh_unique_insert(&desc->hash, &lhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "lvlhsh insert failed"); return NJS_ERROR; @@ -1080,12 +1015,13 @@ njs_prop_type_string(njs_object_prop_type_t type) njs_int_t njs_object_prop_init(njs_vm_t *vm, const njs_object_init_t* init, - const njs_object_prop_t *base, njs_value_t *value, njs_value_t *retval) + njs_object_prop_t *base, uint32_t atom_id, njs_value_t *value, + njs_value_t *retval) { - njs_int_t ret; - njs_object_t *object; - njs_object_prop_t *prop; - njs_lvlhsh_query_t lhq; + njs_int_t ret; + njs_object_t *object; + njs_object_prop_t *prop; + njs_flathsh_query_t lhq; object = njs_object_alloc(vm); if (object == NULL) { @@ -1110,14 +1046,13 @@ njs_object_prop_init(njs_vm_t *vm, const njs_object_init_t* init, prop->type = NJS_PROPERTY; njs_set_object(njs_prop_value(prop), object); - lhq.proto = &njs_object_hash_proto; - njs_string_get(&prop->name, &lhq.key); - lhq.key_hash = njs_djb_hash(lhq.key.start, lhq.key.length); lhq.value = prop; + lhq.key_hash = atom_id; lhq.replace = 1; lhq.pool = vm->mem_pool; + lhq.proto = &njs_object_hash_proto; - ret = njs_lvlhsh_insert(njs_object_hash(value), &lhq); + ret = njs_flathsh_unique_insert(njs_object_hash(value), &lhq); if (njs_fast_path(ret == NJS_OK)) { njs_value_assign(retval, njs_prop_value(prop)); return NJS_OK; diff --git a/src/njs_object_prop_declare.h b/src/njs_object_prop_declare.h index ecc0801c..f2f7a5eb 100644 --- a/src/njs_object_prop_declare.h +++ b/src/njs_object_prop_declare.h @@ -9,23 +9,14 @@ #define NJS_DECLARE_PROP_VALUE(_name, _v, _fl) \ { \ - .type = NJS_PROPERTY, \ - .name = njs_string(_name), \ - .u.value = _v, \ - .enumerable = !!(_fl & NJS_OBJECT_PROP_ENUMERABLE), \ - .configurable = !!(_fl & NJS_OBJECT_PROP_CONFIGURABLE), \ - .writable = !!(_fl & NJS_OBJECT_PROP_WRITABLE), \ - } - - -#define NJS_DECLARE_PROP_LVALUE(_name, _v, _fl) \ - { \ - .type = NJS_PROPERTY, \ - .name = njs_long_string(_name), \ - .u.value = _v, \ - .enumerable = !!(_fl & NJS_OBJECT_PROP_ENUMERABLE), \ - .configurable = !!(_fl & NJS_OBJECT_PROP_CONFIGURABLE), \ - .writable = !!(_fl & NJS_OBJECT_PROP_WRITABLE), \ + .atom_id = NJS_ATOM_ ## _name, \ + .desc = { \ + .type = NJS_PROPERTY, \ + .u.value = _v, \ + .enumerable = !!(_fl & NJS_OBJECT_PROP_ENUMERABLE), \ + .configurable = !!(_fl & NJS_OBJECT_PROP_CONFIGURABLE), \ + .writable = !!(_fl & NJS_OBJECT_PROP_WRITABLE), \ + }, \ } @@ -35,39 +26,39 @@ NJS_OBJECT_PROP_VALUE_CW) -#define NJS_DECLARE_PROP_LNATIVE(_name, _native, _nargs, _magic) \ - NJS_DECLARE_PROP_LVALUE(_name, \ - njs_native_function2(_native, _nargs, _magic), \ - NJS_OBJECT_PROP_VALUE_CW) - - -#define NJS_DECLARE_PROP_HANDLER(_name, _native, _m16, _m32, _fl) \ +#define NJS_DECLARE_PROP_HANDLER(_name, _native, _m16, _fl) \ { \ - .type = NJS_PROPERTY_HANDLER, \ - .name = njs_string(_name), \ - .u.value = njs_prop_handler2(_native, _m16, _m32), \ - .enumerable = !!(_fl & NJS_OBJECT_PROP_ENUMERABLE), \ - .configurable = !!(_fl & NJS_OBJECT_PROP_CONFIGURABLE), \ - .writable = !!(_fl & NJS_OBJECT_PROP_WRITABLE), \ + .atom_id = NJS_ATOM_ ## _name, \ + .desc = { \ + .type = NJS_PROPERTY_HANDLER, \ + .u.value = njs_prop_handler2(_native, _m16), \ + .enumerable = !!(_fl & NJS_OBJECT_PROP_ENUMERABLE), \ + .configurable = !!(_fl & NJS_OBJECT_PROP_CONFIGURABLE), \ + .writable = !!(_fl & NJS_OBJECT_PROP_WRITABLE), \ + }, \ } #define NJS_DECLARE_PROP_GETTER(_name, _native, _magic) \ { \ - .type = NJS_ACCESSOR, \ - .name = njs_string(_name), \ - .u.accessor = njs_getter(_native, _magic), \ - .writable = NJS_ATTRIBUTE_UNSET, \ - .configurable = 1, \ + .atom_id = NJS_ATOM_ ## _name, \ + .desc = { \ + .type = NJS_ACCESSOR, \ + .u.accessor = njs_getter(_native, _magic), \ + .writable = NJS_ATTRIBUTE_UNSET, \ + .configurable = 1, \ + }, \ } #define NJS_DECLARE_PROP_NAME(_name) \ - NJS_DECLARE_PROP_VALUE("name", njs_string(_name), NJS_OBJECT_PROP_VALUE_C) + NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval(_name), \ + NJS_OBJECT_PROP_VALUE_C) #define NJS_DECLARE_PROP_LENGTH(_v) \ - NJS_DECLARE_PROP_VALUE("length", njs_value(NJS_NUMBER, !!(_v), _v), \ + NJS_DECLARE_PROP_VALUE(STRING_length, \ + njs_value(NJS_NUMBER, !!(_v), _v), \ NJS_OBJECT_PROP_VALUE_C) diff --git a/src/njs_parser.c b/src/njs_parser.c index 7fe596c2..a3564396 100644 --- a/src/njs_parser.c +++ b/src/njs_parser.c @@ -451,7 +451,7 @@ static njs_int_t njs_parser_export_sink(njs_parser_t *parser); static njs_parser_node_t *njs_parser_return_set(njs_parser_t *parser, njs_parser_node_t *expr); static njs_parser_node_t *njs_parser_variable_node(njs_parser_t *parser, - uintptr_t unique_id, njs_variable_type_t type, njs_variable_t **retvar); + uintptr_t atom_id, njs_variable_type_t type, njs_variable_t **retvar); static njs_parser_node_t *njs_parser_reference(njs_parser_t *parser, njs_lexer_token_t *token); @@ -529,7 +529,7 @@ njs_parser_reject(njs_parser_t *parser) njs_int_t njs_parser_init(njs_vm_t *vm, njs_parser_t *parser, njs_parser_scope_t *scope, - njs_str_t *file, u_char *start, u_char *end, njs_uint_t runtime) + njs_str_t *file, u_char *start, u_char *end) { njs_lexer_t *lexer; @@ -542,17 +542,15 @@ njs_parser_init(njs_vm_t *vm, njs_parser_t *parser, njs_parser_scope_t *scope, parser->use_lhs = 0; - return njs_lexer_init(vm, lexer, file, start, end, runtime, 0); + return njs_lexer_init(vm, lexer, file, start, end); } njs_int_t njs_parser(njs_vm_t *vm, njs_parser_t *parser) { - njs_int_t ret; - njs_str_t str; - njs_lexer_token_t *token; - const njs_lexer_keyword_entry_t *keyword; + njs_int_t ret; + njs_lexer_token_t *token; parser->vm = vm; @@ -572,16 +570,6 @@ njs_parser(njs_vm_t *vm, njs_parser_t *parser) parser->ret = NJS_OK; } - /* Add this as first variable. */ - njs_string_get(&njs_string_undefined, &str); - - keyword = njs_lexer_keyword(str.start, str.length); - if (njs_slow_path(keyword == NULL)) { - return NJS_ERROR; - } - - parser->undefined_id = (uintptr_t) keyword->value; - njs_queue_init(&parser->stack); parser->target = NULL; @@ -665,11 +653,8 @@ static njs_int_t njs_parser_scope_begin(njs_parser_t *parser, njs_scope_t type, njs_bool_t init_this) { - njs_variable_t *var; - njs_parser_scope_t *scope, *parent; - const njs_lexer_keyword_entry_t *keyword; - - static const njs_str_t njs_this_str = njs_str("this"); + njs_variable_t *var; + njs_parser_scope_t *scope, *parent; scope = njs_mp_zalloc(parser->vm->mem_pool, sizeof(njs_parser_scope_t)); if (njs_slow_path(scope == NULL)) { @@ -689,13 +674,7 @@ njs_parser_scope_begin(njs_parser_t *parser, njs_scope_t type, if (type == NJS_SCOPE_FUNCTION || type == NJS_SCOPE_GLOBAL) { if (init_this) { /* Add this as first variable. */ - keyword = njs_lexer_keyword(njs_this_str.start, - njs_this_str.length); - if (njs_slow_path(keyword == NULL)) { - return NJS_ERROR; - } - - var = njs_variable_add(parser, scope, (uintptr_t) keyword->value, + var = njs_variable_add(parser, scope, NJS_ATOM_STRING_this, NJS_VARIABLE_VAR); if (njs_slow_path(var == NULL)) { return NJS_ERROR; @@ -1004,6 +983,13 @@ njs_parser_primary_expression_test(njs_parser_t *parser, } njs_set_number(&node->u.value, token->number); + + if (njs_number_is_integer_index(token->number) + && token->number < 0x80000000) + { + node->u.value.atom_id = njs_number_atom((uint32_t) token->number); + } + node->token_line = token->line; parser->node = node; @@ -1207,6 +1193,8 @@ reference: return NJS_ERROR; } + node->u.value.atom_id = token->atom_id; + node->token_line = token->line; parser->node = node; @@ -1230,8 +1218,6 @@ njs_parser_regexp_literal(njs_parser_t *parser, njs_lexer_token_t *token, njs_regex_flags_t flags; njs_regexp_pattern_t *pattern; - static const njs_value_t string_message = njs_string("message"); - value = &parser->node->u.value; lexer = parser->lexer; @@ -1302,13 +1288,12 @@ njs_parser_regexp_literal(njs_parser_t *parser, njs_lexer_token_t *token, if (njs_slow_path(pattern == NULL)) { retval = njs_vm_exception(parser->vm); ret = njs_value_property(parser->vm, &retval, - njs_value_arg(&string_message), - &retval); + NJS_ATOM_STRING_message, &retval); if (njs_slow_path(ret != NJS_OK)) { return NJS_ERROR; } - njs_string_get(&retval, &text); + njs_string_get(parser->vm, &retval, &text); njs_parser_syntax_error(parser, "%V", &text); @@ -2087,7 +2072,7 @@ njs_parser_property_definition_after(njs_parser_t *parser, if (property->index != NJS_TOKEN_OPEN_BRACKET && njs_is_string(&property->u.value)) { - njs_string_get(&property->u.value, &name); + njs_string_get(parser->vm, &property->u.value, &name); if (njs_slow_path(njs_strstr_eq(&name, &proto_string))) { if (temp->token_type == NJS_TOKEN_PROTO_INIT) { @@ -5092,7 +5077,7 @@ njs_parser_variable_declaration(njs_parser_t *parser, return NJS_DONE; } - name = njs_parser_variable_node(parser, token->unique_id, parser->var_type, + name = njs_parser_variable_node(parser, token->atom_id, parser->var_type, &var); if (name == NULL) { return NJS_ERROR; @@ -5879,8 +5864,7 @@ njs_parser_for_var_binding_or_var_list(njs_parser_t *parser, return NJS_ERROR; } - var = njs_parser_variable_node(parser, token->unique_id, - type, NULL); + var = njs_parser_variable_node(parser, token->atom_id, type, NULL); if (var == NULL) { return NJS_ERROR; } @@ -6257,8 +6241,8 @@ njs_parser_break_continue(njs_parser_t *parser, njs_lexer_token_t *token, return njs_parser_stack_pop(parser); } - if (njs_label_find(parser->vm, parser->scope, - token->unique_id) == NULL) + if (njs_label_find(parser->vm, parser->scope, token->atom_id) + == NULL) { njs_parser_syntax_error(parser, "Undefined label \"%V\"", &token->text); @@ -6671,19 +6655,19 @@ static njs_int_t njs_parser_labelled_statement(njs_parser_t *parser, njs_lexer_token_t *token, njs_queue_link_t *current) { - uintptr_t unique_id; - njs_variable_t *label; + uintptr_t atom_id; + njs_variable_t *label; - unique_id = token->unique_id; + atom_id = token->atom_id; - label = njs_label_find(parser->vm, parser->scope, unique_id); + label = njs_label_find(parser->vm, parser->scope, atom_id); if (label != NULL) { njs_parser_syntax_error(parser, "Label \"%V\" " "has already been declared", &token->text); return NJS_DONE; } - label = njs_label_add(parser->vm, parser->scope, unique_id); + label = njs_label_add(parser->vm, parser->scope, atom_id); if (label == NULL) { return NJS_ERROR; } @@ -6706,7 +6690,7 @@ njs_parser_labelled_statement(njs_parser_t *parser, njs_lexer_token_t *token, njs_parser_next(parser, njs_parser_statement_wo_node); } - return njs_parser_after(parser, current, (void *) unique_id, 1, + return njs_parser_after(parser, current, (void *) atom_id, 1, njs_parser_labelled_statement_after); } @@ -6715,10 +6699,11 @@ static njs_int_t njs_parser_labelled_statement_after(njs_parser_t *parser, njs_lexer_token_t *token, njs_queue_link_t *current) { - njs_int_t ret; - uintptr_t unique_id; - njs_parser_node_t *node; - const njs_lexer_entry_t *entry; + njs_int_t ret; + njs_str_t str; + uintptr_t atom_id; + njs_value_t entry; + njs_parser_node_t *node; node = parser->node; if (node == NULL) { @@ -6732,15 +6717,17 @@ njs_parser_labelled_statement_after(njs_parser_t *parser, parser->node = node; } - unique_id = (uintptr_t) parser->target; - entry = (const njs_lexer_entry_t *) unique_id; + atom_id = (uint32_t) (uintptr_t) parser->target; + + njs_atom_to_value(parser->vm, &entry, atom_id); + njs_string_get(parser->vm, &entry, &str); - ret = njs_name_copy(parser->vm, &parser->node->name, &entry->name); + ret = njs_name_copy(parser->vm, &parser->node->name, &str); if (ret != NJS_OK) { return NJS_ERROR; } - ret = njs_label_remove(parser->vm, parser->scope, unique_id); + ret = njs_label_remove(parser->vm, parser->scope, atom_id); if (ret != NJS_OK) { return NJS_ERROR; } @@ -6907,7 +6894,7 @@ njs_parser_catch_or_finally(njs_parser_t *parser, njs_lexer_token_t *token, try->right = catch; if (njs_lexer_token_is_binding_identifier(token)) { - node = njs_parser_variable_node(parser, token->unique_id, + node = njs_parser_variable_node(parser, token->atom_id, NJS_VARIABLE_CATCH, NULL); if (node == NULL) { return NJS_ERROR; @@ -7075,7 +7062,7 @@ njs_parser_function_declaration(njs_parser_t *parser, njs_lexer_token_t *token, njs_queue_link_t *current) { njs_int_t ret; - uintptr_t unique_id; + uintptr_t atom_id; njs_bool_t async; njs_variable_t *var; njs_parser_node_t *node; @@ -7091,7 +7078,7 @@ njs_parser_function_declaration(njs_parser_t *parser, njs_lexer_token_t *token, } node = parser->node; - unique_id = token->unique_id; + atom_id = token->atom_id; njs_lexer_consume_token(parser->lexer, 1); @@ -7106,7 +7093,7 @@ njs_parser_function_declaration(njs_parser_t *parser, njs_lexer_token_t *token, njs_lexer_consume_token(parser->lexer, 1); - var = njs_variable_function_add(parser, parser->scope, unique_id, + var = njs_variable_function_add(parser, parser->scope, atom_id, NJS_VARIABLE_FUNCTION); if (var == NULL) { return NJS_ERROR; @@ -7114,7 +7101,7 @@ njs_parser_function_declaration(njs_parser_t *parser, njs_lexer_token_t *token, node->u.value.data.u.lambda = njs_variable_lambda(var); - node->left = (njs_parser_node_t *) unique_id; + node->left = (njs_parser_node_t *) atom_id; parser->node = node; @@ -7138,16 +7125,16 @@ njs_parser_function_declaration_after(njs_parser_t *parser, njs_lexer_token_t *token, njs_queue_link_t *current) { njs_int_t ret; - uintptr_t unique_id; + uintptr_t atom_id; - unique_id = (uintptr_t) parser->node->left; + atom_id = (uint32_t) (uintptr_t) parser->node->left; parser->node->left = NULL; njs_value_null_set(&parser->node->u.value); ret = njs_parser_variable_reference(parser, parser->scope, parser->node, - unique_id, NJS_DECLARATION); + atom_id, NJS_DECLARATION); if (ret != NJS_OK) { return NJS_ERROR; } @@ -7170,18 +7157,12 @@ njs_parser_function_parse(njs_parser_t *parser, njs_lexer_token_t *token, } -static const njs_lexer_entry_t njs_parser_empty_entry = -{ - .name = njs_str("") -}; - - static njs_int_t njs_parser_function_expression(njs_parser_t *parser, njs_lexer_token_t *token, njs_queue_link_t *current) { njs_int_t ret; - uintptr_t unique_id; + uintptr_t atom_id; njs_bool_t async; njs_variable_t *var; njs_function_lambda_t *lambda; @@ -7197,7 +7178,7 @@ njs_parser_function_expression(njs_parser_t *parser, njs_lexer_token_t *token, var = NULL; if (njs_lexer_token_is_binding_identifier(token)) { - unique_id = token->unique_id; + atom_id = token->atom_id; njs_lexer_consume_token(parser->lexer, 1); @@ -7207,7 +7188,7 @@ njs_parser_function_expression(njs_parser_t *parser, njs_lexer_token_t *token, } } else { - unique_id = (uintptr_t) &njs_parser_empty_entry; + atom_id = NJS_ATOM_STRING_empty; } if (token->type != NJS_TOKEN_OPEN_PARENTHESIS) { @@ -7222,7 +7203,7 @@ njs_parser_function_expression(njs_parser_t *parser, njs_lexer_token_t *token, } var = njs_variable_scope_add(parser, parser->scope, parser->scope, - unique_id, NJS_VARIABLE_FUNCTION, 1); + atom_id, NJS_VARIABLE_FUNCTION, 1); if (var == NULL) { return NJS_ERROR; } @@ -7230,7 +7211,7 @@ njs_parser_function_expression(njs_parser_t *parser, njs_lexer_token_t *token, var->self = 1; ret = njs_parser_variable_reference(parser, parser->scope, - parser->node->left, unique_id, + parser->node->left, atom_id, NJS_DECLARATION); if (ret != NJS_OK) { return NJS_ERROR; @@ -7330,7 +7311,7 @@ njs_parser_formal_parameters(njs_parser_t *parser, njs_lexer_token_t *token, default: /* SingleNameBinding */ if (njs_lexer_token_is_binding_identifier(token)) { - var_node.key = token->unique_id; + var_node.key = token->atom_id; rb_node = njs_rbtree_find(&parser->scope->variables, &var_node.node); @@ -7347,7 +7328,7 @@ njs_parser_formal_parameters(njs_parser_t *parser, njs_lexer_token_t *token, } else { arg = njs_variable_add(parser, parser->scope, - token->unique_id, NJS_VARIABLE_VAR); + token->atom_id, NJS_VARIABLE_VAR); } if (arg == NULL) { @@ -7410,7 +7391,6 @@ njs_parser_arrow_function(njs_parser_t *parser, njs_lexer_token_t *token, njs_queue_link_t *current) { njs_int_t ret; - uintptr_t unique_id; njs_bool_t async; njs_variable_t *arg, *var; njs_parser_node_t *node, *name; @@ -7453,16 +7433,15 @@ njs_parser_arrow_function(njs_parser_t *parser, njs_lexer_token_t *token, node->left = name; - unique_id = (uintptr_t) &njs_parser_empty_entry; - var = njs_variable_scope_add(parser, parser->scope, parser->scope, - unique_id, NJS_VARIABLE_FUNCTION, 1); + NJS_ATOM_STRING_empty, NJS_VARIABLE_FUNCTION, + 1); if (var == NULL) { return NJS_ERROR; } ret = njs_parser_variable_reference(parser, parser->scope, node->left, - unique_id, NJS_DECLARATION); + NJS_ATOM_STRING_empty, NJS_DECLARATION); if (ret != NJS_OK) { return NJS_ERROR; } @@ -7490,7 +7469,7 @@ njs_parser_arrow_function(njs_parser_t *parser, njs_lexer_token_t *token, njs_parser_arrow_function_args_after); } else if (njs_lexer_token_is_binding_identifier(token)) { - arg = njs_variable_add(parser, parser->scope, token->unique_id, + arg = njs_variable_add(parser, parser->scope, token->atom_id, NJS_VARIABLE_VAR); if (arg == NULL) { return NJS_ERROR; @@ -8189,7 +8168,7 @@ njs_parser_import(njs_parser_t *parser, njs_lexer_token_t *token, return njs_parser_failed(parser); } - name = njs_parser_variable_node(parser, token->unique_id, NJS_VARIABLE_LET, + name = njs_parser_variable_node(parser, token->atom_id, NJS_VARIABLE_LET, &var); if (name == NULL) { return NJS_ERROR; @@ -8337,14 +8316,14 @@ njs_parser_return_set(njs_parser_t *parser, njs_parser_node_t *expr) static njs_parser_node_t * -njs_parser_variable_node(njs_parser_t *parser, uintptr_t unique_id, +njs_parser_variable_node(njs_parser_t *parser, uintptr_t atom_id, njs_variable_type_t type, njs_variable_t **retvar) { njs_int_t ret; njs_variable_t *var; njs_parser_node_t *node; - var = njs_variable_add(parser, parser->scope, unique_id, type); + var = njs_variable_add(parser, parser->scope, atom_id, type); if (njs_slow_path(var == NULL)) { return NULL; } @@ -8358,7 +8337,7 @@ njs_parser_variable_node(njs_parser_t *parser, uintptr_t unique_id, return NULL; } - ret = njs_parser_variable_reference(parser, parser->scope, node, unique_id, + ret = njs_parser_variable_reference(parser, parser->scope, node, atom_id, NJS_DECLARATION); if (njs_slow_path(ret != NJS_OK)) { return NULL; @@ -8371,14 +8350,11 @@ njs_parser_variable_node(njs_parser_t *parser, uintptr_t unique_id, static njs_parser_node_t * njs_parser_reference(njs_parser_t *parser, njs_lexer_token_t *token) { - njs_int_t ret; - njs_index_t index; - njs_variable_t *var; - njs_parser_node_t *node; - njs_parser_scope_t *scope; - const njs_lexer_keyword_entry_t *keyword; - - static const njs_str_t njs_undefined_str = njs_str("undefined"); + njs_int_t ret; + njs_index_t index; + njs_variable_t *var; + njs_parser_node_t *node; + njs_parser_scope_t *scope; node = njs_parser_node_new(parser, token->type); if (njs_slow_path(node == NULL)) { @@ -8402,19 +8378,13 @@ njs_parser_reference(njs_parser_t *parser, njs_lexer_token_t *token) } if (parser->vm->options.module) { - keyword = njs_lexer_keyword(njs_undefined_str.start, - njs_undefined_str.length); - if (njs_slow_path(keyword == NULL)) { - return NULL; - } - - token->unique_id = (uintptr_t) keyword->value; + token->atom_id = NJS_ATOM_STRING_undefined; } else if (!scope->arrow_function) { index = njs_scope_index(scope->type, 0, NJS_LEVEL_LOCAL, NJS_VARIABLE_VAR); - var = njs_variable_scope_add(parser, scope, scope, token->unique_id, + var = njs_variable_scope_add(parser, scope, scope, token->atom_id, NJS_VARIABLE_VAR, index); if (njs_slow_path(var == NULL)) { return NULL; @@ -8425,7 +8395,7 @@ njs_parser_reference(njs_parser_t *parser, njs_lexer_token_t *token) node->token_line = token->line; ret = njs_parser_variable_reference(parser, parser->scope, node, - token->unique_id, NJS_REFERENCE); + token->atom_id, NJS_REFERENCE); if (njs_slow_path(ret != NJS_OK)) { return NULL; } @@ -8450,12 +8420,12 @@ njs_parser_reference(njs_parser_t *parser, njs_lexer_token_t *token) node->token_line = token->line; ret = njs_parser_variable_reference(parser, parser->scope, node, - token->unique_id, NJS_REFERENCE); + token->atom_id, NJS_REFERENCE); if (njs_slow_path(ret != NJS_OK)) { return NULL; } - var = njs_variable_add(parser, scope, token->unique_id, + var = njs_variable_add(parser, scope, token->atom_id, NJS_VARIABLE_VAR); if (njs_slow_path(var == NULL)) { return NULL; @@ -8478,7 +8448,7 @@ njs_parser_reference(njs_parser_t *parser, njs_lexer_token_t *token) node->token_line = token->line; ret = njs_parser_variable_reference(parser, parser->scope, node, - token->unique_id, NJS_REFERENCE); + token->atom_id, NJS_REFERENCE); if (njs_slow_path(ret != NJS_OK)) { return NULL; } @@ -8735,6 +8705,7 @@ njs_parser_string_create(njs_vm_t *vm, njs_lexer_token_t *token, njs_value_t *value) { size_t length; + njs_int_t ret; njs_str_t dst; length = njs_decode_utf8_length(&token->text, &dst.length); @@ -8746,10 +8717,15 @@ njs_parser_string_create(njs_vm_t *vm, njs_lexer_token_t *token, njs_decode_utf8(&dst, &token->text); if (length > NJS_STRING_MAP_STRIDE && dst.length != length) { - njs_string_utf8_offset_map_init(value->long_string.data->start, + njs_string_utf8_offset_map_init(value->string.data->start, dst.length); } + ret = njs_atom_atomize_key(vm, value); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_TOKEN_ERROR; + } + return NJS_OK; } @@ -8994,6 +8970,11 @@ next_char: njs_string_utf8_offset_map_init(start, size); } + ret = njs_atom_atomize_key(parser->vm, value); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_TOKEN_ERROR; + } + return NJS_TOKEN_STRING; } @@ -9183,7 +9164,7 @@ njs_parser_has_side_effect(njs_parser_node_t *node) njs_int_t njs_parser_variable_reference(njs_parser_t *parser, njs_parser_scope_t *scope, - njs_parser_node_t *node, uintptr_t unique_id, njs_reference_type_t type) + njs_parser_node_t *node, uintptr_t atom_id, njs_reference_type_t type) { njs_rbtree_node_t *rb_node; njs_variable_reference_t *vr; @@ -9191,10 +9172,10 @@ njs_parser_variable_reference(njs_parser_t *parser, njs_parser_scope_t *scope, vr = &node->u.reference; - vr->unique_id = unique_id; + vr->atom_id = atom_id; vr->type = type; - parse_node.key = unique_id; + parse_node.key = atom_id; rb_node = njs_rbtree_find(&scope->references, &parse_node.node); if (rb_node != NULL) { @@ -9207,7 +9188,7 @@ njs_parser_variable_reference(njs_parser_t *parser, njs_parser_scope_t *scope, return NJS_ERROR; } - rb_parse_node->key = unique_id; + rb_parse_node->key = atom_id; rb_parse_node->index = NJS_INDEX_NONE; njs_rbtree_insert(&scope->references, &rb_parse_node->node); @@ -9241,9 +9222,6 @@ njs_parser_error(njs_vm_t *vm, njs_object_type_t type, njs_str_t *file, njs_int_t ret; njs_value_t value, error; - static const njs_value_t file_name = njs_string("fileName"); - static const njs_value_t line_number = njs_string("lineNumber"); - if (njs_slow_path(vm->top_frame == NULL)) { njs_vm_runtime_init(vm); } @@ -9269,13 +9247,12 @@ njs_parser_error(njs_vm_t *vm, njs_object_type_t type, njs_str_t *file, njs_error_new(vm, &error, njs_vm_proto(vm, type), msg, p - msg); njs_set_number(&value, line); - njs_value_property_set(vm, &error, njs_value_arg(&line_number), &value); + njs_value_property_set(vm, &error, NJS_ATOM_STRING_lineNumber, &value); if (file->length != 0) { ret = njs_string_create(vm, &value, file->start, file->length); if (ret == NJS_OK) { - njs_value_property_set(vm, &error, njs_value_arg(&file_name), - &value); + njs_value_property_set(vm, &error, NJS_ATOM_STRING_fileName, &value); } } @@ -9440,7 +9417,7 @@ njs_parser_serialize_tree(njs_chb_t *chain, njs_parser_node_t *node, njs_number(&node->u.value)); } else { - njs_string_get(&node->u.value, &str); + njs_string_get_unsafe(&node->u.value, &str); njs_chb_append_literal(chain, " \"value\": \""); njs_chb_append_str(chain, &str); njs_chb_append_literal(chain, "\""); diff --git a/src/njs_parser.h b/src/njs_parser.h index db4db02d..2f7cff79 100644 --- a/src/njs_parser.h +++ b/src/njs_parser.h @@ -80,7 +80,6 @@ struct njs_parser_s { njs_parser_scope_t *scope; njs_variable_type_t var_type; njs_int_t ret; - uintptr_t undefined_id; uint8_t use_lhs; @@ -125,8 +124,7 @@ njs_int_t njs_parser_failed_state(njs_parser_t *parser, intptr_t njs_parser_scope_rbtree_compare(njs_rbtree_node_t *node1, njs_rbtree_node_t *node2); njs_int_t njs_parser_init(njs_vm_t *vm, njs_parser_t *parser, - njs_parser_scope_t *scope, njs_str_t *file, u_char *start, u_char *end, - njs_uint_t runtime); + njs_parser_scope_t *scope, njs_str_t *file, u_char *start, u_char *end); njs_int_t njs_parser(njs_vm_t *vm, njs_parser_t *parser); njs_bool_t njs_variable_closure_test(njs_parser_scope_t *root, @@ -135,7 +133,7 @@ njs_variable_t *njs_variable_resolve(njs_vm_t *vm, njs_parser_node_t *node); njs_index_t njs_variable_index(njs_vm_t *vm, njs_parser_node_t *node); njs_bool_t njs_parser_has_side_effect(njs_parser_node_t *node); njs_int_t njs_parser_variable_reference(njs_parser_t *parser, - njs_parser_scope_t *scope, njs_parser_node_t *node, uintptr_t unique_id, + njs_parser_scope_t *scope, njs_parser_node_t *node, uintptr_t atom_id, njs_reference_type_t type); njs_token_type_t njs_parser_unexpected_token(njs_vm_t *vm, njs_parser_t *parser, njs_str_t *name, njs_token_type_t type); diff --git a/src/njs_promise.c b/src/njs_promise.c index 79b93a11..f8951cca 100644 --- a/src/njs_promise.c +++ b/src/njs_promise.c @@ -105,11 +105,6 @@ static njs_int_t njs_promise_perform_race_handler(njs_vm_t *vm, njs_value_t *retval); -static const njs_value_t string_resolve = njs_string("resolve"); -static const njs_value_t string_any_rejected = - njs_long_string("All promises were rejected"); - - static njs_promise_t * njs_promise_alloc(njs_vm_t *vm) { @@ -391,15 +386,12 @@ njs_promise_value_constructor(njs_vm_t *vm, njs_value_t *value, { njs_int_t ret; - static const njs_value_t string_constructor = njs_string("constructor"); - if (njs_is_function(value)) { *dst = *value; return NJS_OK; } - ret = njs_value_property(vm, value, njs_value_arg(&string_constructor), - dst); + ret = njs_value_property(vm, value, NJS_ATOM_STRING_constructor, dst); if (njs_slow_path(ret == NJS_ERROR)) { return ret; } @@ -552,10 +544,7 @@ njs_promise_invoke_then(njs_vm_t *vm, njs_value_t *promise, njs_value_t *args, njs_int_t ret; njs_value_t function; - static const njs_value_t string_then = njs_string("then"); - - ret = njs_value_property(vm, promise, njs_value_arg(&string_then), - &function); + ret = njs_value_property(vm, promise, NJS_ATOM_STRING_then, &function); if (njs_slow_path(ret != NJS_OK)) { if (ret == NJS_DECLINED) { goto failed; @@ -588,8 +577,6 @@ njs_promise_resolve_function(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_native_frame_t *active_frame; njs_promise_context_t *context; - static const njs_value_t string_then = njs_string("then"); - active_frame = vm->top_frame; context = active_frame->function->context; promise = njs_promise(&context->promise); @@ -603,7 +590,7 @@ njs_promise_resolve_function(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, resolution = njs_arg(args, nargs, 1); - if (njs_values_same(resolution, &context->promise)) { + if (njs_values_same(vm, resolution, &context->promise)) { njs_error_fmt_new(vm, &error, NJS_OBJ_TYPE_TYPE_ERROR, "promise self resolution"); if (njs_slow_path(!njs_is_error(&error))) { @@ -619,8 +606,7 @@ njs_promise_resolve_function(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, goto fulfill; } - ret = njs_value_property(vm, resolution, njs_value_arg(&string_then), - &then); + ret = njs_value_property(vm, resolution, NJS_ATOM_STRING_then, &then); if (njs_slow_path(ret == NJS_ERROR)) { if (njs_slow_path(njs_is_memory_error(vm, &vm->exception))) { return NJS_ERROR; @@ -693,16 +679,13 @@ njs_promise_resolve(njs_vm_t *vm, njs_value_t *constructor, njs_value_t *x, njs_value_t value; njs_promise_capability_t *capability; - static const njs_value_t string_constructor = njs_string("constructor"); - if (njs_is_promise(x)) { - ret = njs_value_property(vm, x, njs_value_arg(&string_constructor), - &value); + ret = njs_value_property(vm, x, NJS_ATOM_STRING_constructor, &value); if (njs_slow_path(ret == NJS_ERROR)) { return NJS_ERROR; } - if (njs_values_same(&value, constructor)) { + if (njs_values_same(vm, &value, constructor)) { njs_value_assign(retval, x); return NJS_OK; } @@ -1173,7 +1156,7 @@ njs_promise_all(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return NJS_ERROR; } - ret = njs_value_property(vm, promise_ctor, njs_value_arg(&string_resolve), + ret = njs_value_property(vm, promise_ctor, NJS_ATOM_STRING_resolve, &resolve); if (njs_slow_path(ret == NJS_ERROR)) { return ret; @@ -1213,7 +1196,7 @@ njs_promise_perform_all(njs_vm_t *vm, njs_value_t *iterator, { int64_t length; njs_int_t ret; - njs_value_t argument; + njs_value_t argument, message; njs_object_t *error; if (njs_slow_path(!njs_is_object(pargs->constructor))) { @@ -1253,11 +1236,13 @@ njs_promise_perform_all(njs_vm_t *vm, njs_value_t *iterator, njs_mp_free(vm->mem_pool, pargs->remaining); njs_set_array(&argument, pargs->args.data); + njs_atom_to_value(vm, &message, + NJS_ATOM_STRING_All_promises_were_rejected); if (handler == njs_promise_perform_any_handler) { error = njs_error_alloc(vm, njs_vm_proto(vm, NJS_OBJ_TYPE_AGGREGATE_ERROR), - NULL, &string_any_rejected, &argument); + NULL, &message, &argument); if (njs_slow_path(error == NULL)) { return NJS_ERROR; } @@ -1467,17 +1452,12 @@ njs_promise_all_settled_element_functions(njs_vm_t *vm, njs_value_t *retval) { njs_int_t ret; + uint32_t set_atom_id; + njs_value_t status; njs_value_t obj_value, arr_value; njs_object_t *obj; - const njs_value_t *status, *set; njs_promise_all_context_t *context; - static const njs_value_t string_status = njs_string("status"); - static const njs_value_t string_fulfilled = njs_string("fulfilled"); - static const njs_value_t string_value = njs_string("value"); - static const njs_value_t string_rejected = njs_string("rejected"); - static const njs_value_t string_reason = njs_string("reason"); - context = vm->top_frame->function->context; if (context->already_called) { @@ -1495,21 +1475,21 @@ njs_promise_all_settled_element_functions(njs_vm_t *vm, njs_set_object(&obj_value, obj); if (rejected) { - status = &string_rejected; - set = &string_reason; + njs_atom_to_value(vm, &status, NJS_ATOM_STRING_rejected); + set_atom_id = NJS_ATOM_STRING_reason; } else { - status = &string_fulfilled; - set = &string_value; + njs_atom_to_value(vm, &status, NJS_ATOM_STRING_fulfilled); + set_atom_id = NJS_ATOM_STRING_value; } - ret = njs_value_property_set(vm, &obj_value, njs_value_arg(&string_status), - njs_value_arg(status)); + ret = njs_value_property_set(vm, &obj_value, NJS_ATOM_STRING_status, + njs_value_arg(&status)); if (njs_slow_path(ret == NJS_ERROR)) { return ret; } - ret = njs_value_property_set(vm, &obj_value, njs_value_arg(set), + ret = njs_value_property_set(vm, &obj_value, set_atom_id, njs_arg(args, nargs, 1)); if (njs_slow_path(ret == NJS_ERROR)) { return ret; @@ -1609,7 +1589,7 @@ njs_promise_any_reject_element_functions(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval) { njs_int_t ret; - njs_value_t argument, arr_value; + njs_value_t argument, message, arr_value; njs_object_t *error; njs_promise_all_context_t *context; @@ -1633,9 +1613,12 @@ njs_promise_any_reject_element_functions(njs_vm_t *vm, njs_value_t *args, if (--(*context->remaining_elements) == 0) { njs_mp_free(vm->mem_pool, context->remaining_elements); + njs_atom_to_value(vm, &message, + NJS_ATOM_STRING_All_promises_were_rejected); + error = njs_error_alloc(vm, njs_vm_proto(vm, NJS_OBJ_TYPE_AGGREGATE_ERROR), - NULL, &string_any_rejected, &arr_value); + NULL, &message, &arr_value); if (njs_slow_path(error == NULL)) { return NJS_ERROR; } @@ -1670,7 +1653,7 @@ njs_promise_race(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return NJS_ERROR; } - ret = njs_value_property(vm, promise_ctor, njs_value_arg(&string_resolve), + ret = njs_value_property(vm, promise_ctor, NJS_ATOM_STRING_resolve, &resolve); if (njs_slow_path(ret == NJS_ERROR)) { return ret; @@ -1748,34 +1731,32 @@ njs_promise_species(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } -static const njs_object_prop_t njs_promise_constructor_properties[] = +static const njs_object_prop_init_t njs_promise_constructor_properties[] = { NJS_DECLARE_PROP_LENGTH(1), NJS_DECLARE_PROP_NAME("Promise"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), - NJS_DECLARE_PROP_NATIVE("resolve", njs_promise_object_resolve, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_resolve, njs_promise_object_resolve, 1, + 0), - NJS_DECLARE_PROP_NATIVE("reject", njs_promise_object_reject, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_reject, njs_promise_object_reject, 1, 0), - NJS_DECLARE_PROP_NATIVE("all", njs_promise_all, 1, NJS_PROMISE_ALL), + NJS_DECLARE_PROP_NATIVE(STRING_all, njs_promise_all, 1, + NJS_PROMISE_ALL), - NJS_DECLARE_PROP_NATIVE("allSettled", njs_promise_all, 1, + NJS_DECLARE_PROP_NATIVE(STRING_allSettled, njs_promise_all, 1, NJS_PROMISE_ALL_SETTLED), - NJS_DECLARE_PROP_NATIVE("any", njs_promise_all, 1, NJS_PROMISE_ANY), + NJS_DECLARE_PROP_NATIVE(STRING_any, njs_promise_all, 1, + NJS_PROMISE_ANY), - NJS_DECLARE_PROP_NATIVE("race", njs_promise_race, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_race, njs_promise_race, 1, 0), - { - .type = NJS_ACCESSOR, - .name = njs_wellknown_symbol(NJS_SYMBOL_SPECIES), - .u.accessor = njs_getter(njs_promise_species, 0), - .writable = NJS_ATTRIBUTE_UNSET, - .configurable = 1, - }, + NJS_DECLARE_PROP_GETTER(SYMBOL_species, njs_promise_species, 0), }; @@ -1785,24 +1766,22 @@ const njs_object_init_t njs_promise_constructor_init = { }; -static const njs_object_prop_t njs_promise_prototype_properties[] = +static const njs_object_prop_init_t njs_promise_prototype_properties[] = { - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - { - .type = NJS_PROPERTY, - .name = njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG), - .u.value = njs_string("Promise"), - .configurable = 1, - }, + NJS_DECLARE_PROP_VALUE(SYMBOL_toStringTag, njs_ascii_strval("Promise"), + NJS_OBJECT_PROP_VALUE_C), - NJS_DECLARE_PROP_NATIVE("then", njs_promise_prototype_then, 2, 0), + NJS_DECLARE_PROP_NATIVE(STRING_then, njs_promise_prototype_then, 2, 0), - NJS_DECLARE_PROP_NATIVE("catch", njs_promise_prototype_catch, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_catch, njs_promise_prototype_catch, 1, + 0), - NJS_DECLARE_PROP_NATIVE("finally", njs_promise_prototype_finally, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_finally, njs_promise_prototype_finally, + 1, 0), }; diff --git a/src/njs_regexp.c b/src/njs_regexp.c index 479f0b75..4f1bb180 100644 --- a/src/njs_regexp.c +++ b/src/njs_regexp.c @@ -32,9 +32,6 @@ static njs_array_t *njs_regexp_exec_result(njs_vm_t *vm, njs_value_t *r, njs_utf8_t utf8, njs_string_prop_t *string, njs_regex_match_data_t *data); -const njs_value_t njs_string_lindex = njs_string("lastIndex"); - - njs_int_t njs_regexp_init(njs_vm_t *vm) { @@ -134,9 +131,6 @@ njs_regexp_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, if (njs_slow_path(ret != NJS_OK)) { return ret; } - - } else { - pattern = njs_value_arg(&njs_string_empty); } re_flags = 0; @@ -150,7 +144,7 @@ njs_regexp_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return ret; } - njs_string_get(flags, &string); + njs_string_get(vm, flags, &string); start = string.start; @@ -163,7 +157,12 @@ njs_regexp_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } } - njs_string_get(pattern, &string); + if (njs_is_defined(pattern)) { + njs_string_get(vm, pattern, &string); + + } else { + string = njs_str_value(""); + } return njs_regexp_create(vm, retval, string.start, string.length, re_flags); @@ -513,7 +512,7 @@ njs_regexp_alloc(njs_vm_t *vm, njs_regexp_pattern_t *pattern) regexp->object.error_data = 0; njs_set_number(®exp->last_index, 0); regexp->pattern = pattern; - njs_string_short_set(®exp->string, 0, 0); + njs_set_empty_string(vm, ®exp->string); return regexp; } @@ -525,7 +524,8 @@ njs_regexp_alloc(njs_vm_t *vm, njs_regexp_pattern_t *pattern) static njs_int_t njs_regexp_prototype_last_index(njs_vm_t *vm, njs_object_prop_t *unused, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t unused2, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { njs_regexp_t *regexp; @@ -557,11 +557,6 @@ njs_regexp_prototype_flags(njs_vm_t *vm, njs_value_t *args, njs_value_t *this, value; u_char dst[4]; - static const njs_value_t string_global = njs_string("global"); - static const njs_value_t string_ignore_case = njs_string("ignoreCase"); - static const njs_value_t string_multiline = njs_string("multiline"); - static const njs_value_t string_sticky = njs_string("sticky"); - this = njs_argument(args, 0); if (njs_slow_path(!njs_is_object(this))) { njs_type_error(vm, "\"this\" argument is not an object"); @@ -570,8 +565,7 @@ njs_regexp_prototype_flags(njs_vm_t *vm, njs_value_t *args, p = &dst[0]; - ret = njs_value_property(vm, this, njs_value_arg(&string_global), - &value); + ret = njs_value_property(vm, this, NJS_ATOM_STRING_global, &value); if (njs_slow_path(ret == NJS_ERROR)) { return NJS_ERROR; } @@ -580,8 +574,7 @@ njs_regexp_prototype_flags(njs_vm_t *vm, njs_value_t *args, *p++ = 'g'; } - ret = njs_value_property(vm, this, njs_value_arg(&string_ignore_case), - &value); + ret = njs_value_property(vm, this, NJS_ATOM_STRING_ignoreCase, &value); if (njs_slow_path(ret == NJS_ERROR)) { return NJS_ERROR; } @@ -590,8 +583,7 @@ njs_regexp_prototype_flags(njs_vm_t *vm, njs_value_t *args, *p++ = 'i'; } - ret = njs_value_property(vm, this, njs_value_arg(&string_multiline), - &value); + ret = njs_value_property(vm, this, NJS_ATOM_STRING_multiline, &value); if (njs_slow_path(ret == NJS_ERROR)) { return NJS_ERROR; } @@ -600,8 +592,7 @@ njs_regexp_prototype_flags(njs_vm_t *vm, njs_value_t *args, *p++ = 'm'; } - ret = njs_value_property(vm, this, njs_value_arg(&string_sticky), - &value); + ret = njs_value_property(vm, this, NJS_ATOM_STRING_sticky, &value); if (njs_slow_path(ret == NJS_ERROR)) { return NJS_ERROR; } @@ -681,7 +672,7 @@ njs_regexp_prototype_source(njs_vm_t *vm, njs_value_t *args, if (njs_slow_path(!njs_is_regexp(this))) { if (njs_object(this) == njs_vm_proto(vm, NJS_OBJ_TYPE_REGEXP)) { - njs_value_assign(retval, &njs_string_empty_regexp); + njs_atom_to_value(vm, retval, NJS_ATOM_STRING_spec_EMPTY_REGEXP); return NJS_OK; } @@ -708,9 +699,6 @@ njs_regexp_prototype_to_string(njs_vm_t *vm, njs_value_t *args, njs_value_t *r, source, flags; njs_string_prop_t source_string, flags_string; - static const njs_value_t string_source = njs_string("source"); - static const njs_value_t string_flags = njs_string("flags"); - r = njs_argument(args, 0); if (njs_slow_path(!njs_is_object(r))) { @@ -718,8 +706,7 @@ njs_regexp_prototype_to_string(njs_vm_t *vm, njs_value_t *args, return NJS_ERROR; } - ret = njs_value_property(vm, r, njs_value_arg(&string_source), - &source); + ret = njs_value_property(vm, r, NJS_ATOM_STRING_source, &source); if (njs_slow_path(ret == NJS_ERROR)) { return NJS_ERROR; } @@ -729,8 +716,7 @@ njs_regexp_prototype_to_string(njs_vm_t *vm, njs_value_t *args, return NJS_ERROR; } - ret = njs_value_property(vm, r, njs_value_arg(&string_flags), - &flags); + ret = njs_value_property(vm, r, NJS_ATOM_STRING_flags, &flags); if (njs_slow_path(ret == NJS_ERROR)) { return NJS_ERROR; } @@ -740,8 +726,8 @@ njs_regexp_prototype_to_string(njs_vm_t *vm, njs_value_t *args, return NJS_ERROR; } - (void) njs_string_prop(&source_string, &source); - (void) njs_string_prop(&flags_string, &flags); + (void) njs_string_prop(vm, &source_string, &source); + (void) njs_string_prop(vm, &flags_string, &flags); size = source_string.size + flags_string.size + njs_length("//"); length = source_string.length + flags_string.length + njs_length("//"); @@ -879,8 +865,7 @@ njs_regexp_builtin_exec(njs_vm_t *vm, njs_value_t *r, njs_value_t *s, regexp->string = *s; pattern = regexp->pattern; - ret = njs_value_property(vm, r, njs_value_arg(&njs_string_lindex), - &value); + ret = njs_value_property(vm, r, NJS_ATOM_STRING_lastIndex, &value); if (njs_slow_path(ret == NJS_ERROR)) { return NJS_ERROR; } @@ -894,7 +879,7 @@ njs_regexp_builtin_exec(njs_vm_t *vm, njs_value_t *r, njs_value_t *s, last_index = 0; } - length = njs_string_prop(&string, s); + length = njs_string_prop(vm, &string, s); if (njs_slow_path((size_t) last_index > length)) { goto not_found; @@ -952,8 +937,7 @@ njs_regexp_builtin_exec(njs_vm_t *vm, njs_value_t *r, njs_value_t *s, } njs_set_number(&value, index); - ret = njs_value_property_set(vm, r, - njs_value_arg(&njs_string_lindex), + ret = njs_value_property_set(vm, r, NJS_ATOM_STRING_lastIndex, &value); if (njs_slow_path(ret != NJS_OK)) { njs_regex_match_data_free(match_data, vm->regex_generic_ctx); @@ -989,8 +973,7 @@ not_found: if (pattern->global || pattern->sticky) { njs_set_number(&value, 0); - ret = njs_value_property_set(vm, r, njs_value_arg(&njs_string_lindex), - &value); + ret = njs_value_property_set(vm, r, NJS_ATOM_STRING_lastIndex, &value); if (njs_slow_path(ret != NJS_OK)) { return NJS_ERROR; } @@ -1024,13 +1007,9 @@ njs_regexp_exec_result(njs_vm_t *vm, njs_value_t *r, njs_utf8_t utf8, njs_regexp_t *regexp; njs_object_prop_t *prop; njs_regexp_group_t *group; - njs_lvlhsh_query_t lhq; + njs_flathsh_query_t lhq; njs_regexp_pattern_t *pattern; - static const njs_value_t string_index = njs_string("index"); - static const njs_value_t string_input = njs_string("input"); - static const njs_value_t string_groups = njs_string("groups"); - regexp = njs_regexp(r); pattern = regexp->pattern; array = njs_array_alloc(vm, 0, pattern->ncaptures, 0); @@ -1059,7 +1038,7 @@ njs_regexp_exec_result(njs_vm_t *vm, njs_value_t *r, njs_utf8_t utf8, } /* FIXME: implement fast CreateDataPropertyOrThrow(). */ - prop = njs_object_prop_alloc(vm, &string_index, &njs_value_undefined, 1); + prop = njs_object_prop_alloc(vm, &njs_value_undefined, 1); if (njs_slow_path(prop == NULL)) { goto fail; } @@ -1075,42 +1054,39 @@ njs_regexp_exec_result(njs_vm_t *vm, njs_value_t *r, njs_utf8_t utf8, njs_set_number(&prop->u.value, index); - lhq.key_hash = NJS_INDEX_HASH; - lhq.key = njs_str_value("index"); + lhq.key_hash = NJS_ATOM_STRING_index; lhq.replace = 0; lhq.value = prop; lhq.pool = vm->mem_pool; lhq.proto = &njs_object_hash_proto; - ret = njs_lvlhsh_insert(&array->object.hash, &lhq); + ret = njs_flathsh_unique_insert(&array->object.hash, &lhq); if (njs_slow_path(ret != NJS_OK)) { goto insert_fail; } - prop = njs_object_prop_alloc(vm, &string_input, ®exp->string, 1); + prop = njs_object_prop_alloc(vm, ®exp->string, 1); if (njs_slow_path(prop == NULL)) { goto fail; } - lhq.key_hash = NJS_INPUT_HASH; - lhq.key = njs_str_value("input"); + lhq.key_hash = NJS_ATOM_STRING_input; lhq.value = prop; - ret = njs_lvlhsh_insert(&array->object.hash, &lhq); + ret = njs_flathsh_unique_insert(&array->object.hash, &lhq); if (njs_slow_path(ret != NJS_OK)) { goto insert_fail; } - prop = njs_object_prop_alloc(vm, &string_groups, &njs_value_undefined, 1); + prop = njs_object_prop_alloc(vm, &njs_value_undefined, 1); if (njs_slow_path(prop == NULL)) { goto fail; } - lhq.key_hash = NJS_GROUPS_HASH; - lhq.key = njs_str_value("groups"); + lhq.key_hash = NJS_ATOM_STRING_groups; lhq.value = prop; - ret = njs_lvlhsh_insert(&array->object.hash, &lhq); + ret = njs_flathsh_unique_insert(&array->object.hash, &lhq); if (njs_slow_path(ret != NJS_OK)) { goto insert_fail; } @@ -1128,23 +1104,21 @@ njs_regexp_exec_result(njs_vm_t *vm, njs_value_t *r, njs_utf8_t utf8, do { group = &pattern->groups[i]; - ret = njs_string_create(vm, &name, group->name.start, - group->name.length); + ret = njs_atom_string_create(vm, &name, group->name.start, + group->name.length); if (njs_slow_path(ret != NJS_OK)) { goto fail; } - prop = njs_object_prop_alloc(vm, &name, - &array->start[group->capture], 1); + prop = njs_object_prop_alloc(vm, &array->start[group->capture], 1); if (njs_slow_path(prop == NULL)) { goto fail; } - lhq.key_hash = group->hash; - lhq.key = group->name; + lhq.key_hash = name.atom_id; lhq.value = prop; - ret = njs_lvlhsh_insert(&groups->hash, &lhq); + ret = njs_flathsh_unique_insert(&groups->hash, &lhq); if (njs_slow_path(ret != NJS_OK)) { goto insert_fail; } @@ -1174,38 +1148,39 @@ done: static void njs_regexp_exec_result_free(njs_vm_t *vm, njs_array_t *result) { - njs_uint_t n; - njs_value_t *start; - njs_flathsh_t *hash; - njs_object_prop_t *prop; - njs_lvlhsh_each_t lhe; - njs_lvlhsh_query_t lhq; + njs_uint_t n; + njs_value_t *start; + njs_flathsh_t *hash; + njs_object_prop_t *prop; + njs_flathsh_elt_t *elt; + njs_flathsh_each_t lhe; + njs_flathsh_query_t lhq; if (result->object.fast_array) { start = result->start; for (n = 0; n < result->length; n++) { - if (start[n].short_string.size == NJS_STRING_LONG) { - njs_mp_free(vm->mem_pool, start[n].long_string.data); + if (start[n].type == NJS_STRING) { + njs_mp_free(vm->mem_pool, start[n].string.data); } } } - njs_lvlhsh_each_init(&lhe, &njs_object_hash_proto); + njs_flathsh_each_init(&lhe, &njs_object_hash_proto); hash = &result->object.hash; for ( ;; ) { - prop = njs_flathsh_each(hash, &lhe); - - if (prop == NULL) { + elt = njs_flathsh_each(hash, &lhe); + if (elt == NULL) { break; } + prop = elt->value; + njs_mp_free(vm->mem_pool, prop); } - lhq.pool = vm->mem_pool; lhq.proto = &njs_object_hash_proto; @@ -1257,9 +1232,7 @@ njs_regexp_exec(njs_vm_t *vm, njs_value_t *r, njs_value_t *s, unsigned flags, njs_value_t exec; njs_value_t arguments[2]; - static const njs_value_t string_exec = njs_string("exec"); - - ret = njs_value_property(vm, r, njs_value_arg(&string_exec), &exec); + ret = njs_value_property(vm, r, NJS_ATOM_STRING_exec, &exec); if (njs_slow_path(ret == NJS_ERROR)) { return NJS_ERROR; } @@ -1324,10 +1297,6 @@ njs_regexp_prototype_symbol_replace(njs_vm_t *vm, njs_value_t *args, njs_function_t *func_replace; njs_string_prop_t s; - static const njs_value_t string_global = njs_string("global"); - static const njs_value_t string_groups = njs_string("groups"); - static const njs_value_t string_index = njs_string("index"); - rx = njs_argument(args, 0); if (njs_slow_path(!njs_is_object(rx))) { @@ -1342,7 +1311,7 @@ njs_regexp_prototype_symbol_replace(njs_vm_t *vm, njs_value_t *args, return ret; } - length = njs_string_prop(&s, string); + length = njs_string_prop(vm, &s, string); rep.start = NULL; rep.length = 0; @@ -1357,7 +1326,7 @@ njs_regexp_prototype_symbol_replace(njs_vm_t *vm, njs_value_t *args, } } - ret = njs_value_property(vm, rx, njs_value_arg(&string_global), &value); + ret = njs_value_property(vm, rx, NJS_ATOM_STRING_global, &value); if (njs_slow_path(ret == NJS_ERROR)) { return NJS_ERROR; } @@ -1366,8 +1335,7 @@ njs_regexp_prototype_symbol_replace(njs_vm_t *vm, njs_value_t *args, if (global) { njs_set_number(&value, 0); - ret = njs_value_property_set(vm, rx, njs_value_arg(&njs_string_lindex), - &value); + ret = njs_value_property_set(vm, rx, NJS_ATOM_STRING_lastIndex, &value); if (njs_slow_path(ret != NJS_OK)) { return NJS_ERROR; } @@ -1418,12 +1386,13 @@ njs_regexp_prototype_symbol_replace(njs_vm_t *vm, njs_value_t *args, goto exception; } - if (njs_string_length(&value) != 0) { + njs_string_get(vm, &value, &m); + + if (m.length != 0) { continue; } - ret = njs_value_property(vm, rx, njs_value_arg(&njs_string_lindex), - &value); + ret = njs_value_property(vm, rx, NJS_ATOM_STRING_lastIndex, &value); if (njs_slow_path(ret == NJS_ERROR)) { goto exception; } @@ -1434,8 +1403,7 @@ njs_regexp_prototype_symbol_replace(njs_vm_t *vm, njs_value_t *args, } njs_set_number(&value, last_index + 1); - ret = njs_value_property_set(vm, rx, njs_value_arg(&njs_string_lindex), - &value); + ret = njs_value_property_set(vm, rx, NJS_ATOM_STRING_lastIndex, &value); if (njs_slow_path(ret != NJS_OK)) { goto exception; } @@ -1462,7 +1430,7 @@ njs_regexp_prototype_symbol_replace(njs_vm_t *vm, njs_value_t *args, goto exception; } - ret = njs_value_property(vm, r, njs_value_arg(&string_index), &value); + ret = njs_value_property(vm, r, NJS_ATOM_STRING_index, &value); if (njs_slow_path(ret == NJS_ERROR)) { goto exception; } @@ -1505,7 +1473,7 @@ njs_regexp_prototype_symbol_replace(njs_vm_t *vm, njs_value_t *args, } } - ret = njs_value_property(vm, r, njs_value_arg(&string_groups), &groups); + ret = njs_value_property(vm, r, NJS_ATOM_STRING_groups, &groups); if (njs_slow_path(ret == NJS_ERROR)) { goto exception; } @@ -1558,10 +1526,10 @@ njs_regexp_prototype_symbol_replace(njs_vm_t *vm, njs_value_t *args, if (p >= next) { njs_chb_append(&chain, next, p - next); - njs_string_get(retval, &rep); + njs_string_get(vm, retval, &rep); njs_chb_append_str(&chain, &rep); - njs_string_get(&matched, &m); + njs_string_get(vm, &matched, &m); next = p + m.length; } @@ -1616,9 +1584,6 @@ njs_regexp_prototype_symbol_split(njs_vm_t *vm, njs_value_t *args, njs_string_prop_t s, sv; njs_value_t arguments[2]; - static const njs_value_t string_lindex = njs_string("lastIndex"); - static const njs_value_t string_flags = njs_string("flags"); - rx = njs_argument(args, 0); if (njs_slow_path(!njs_is_object(rx))) { @@ -1640,7 +1605,7 @@ njs_regexp_prototype_symbol_split(njs_vm_t *vm, njs_value_t *args, return ret; } - ret = njs_value_property(vm, rx, njs_value_arg(&string_flags), retval); + ret = njs_value_property(vm, rx, NJS_ATOM_STRING_flags, retval); if (njs_slow_path(ret == NJS_ERROR)) { return NJS_ERROR; } @@ -1650,7 +1615,7 @@ njs_regexp_prototype_symbol_split(njs_vm_t *vm, njs_value_t *args, return ret; } - (void) njs_string_prop(&s, retval); + (void) njs_string_prop(vm, &s, retval); sticky = memchr(s.start, 'y', s.size) != NULL; @@ -1705,7 +1670,7 @@ njs_regexp_prototype_symbol_split(njs_vm_t *vm, njs_value_t *args, goto done; } - length = njs_string_prop(&s, string); + length = njs_string_prop(vm, &s, string); if (njs_slow_path(s.size == 0)) { ret = njs_regexp_exec(vm, rx, string, NJS_REGEXP_FLAG_TEST, &z); @@ -1731,8 +1696,7 @@ njs_regexp_prototype_symbol_split(njs_vm_t *vm, njs_value_t *args, while (q < length) { njs_set_number(&setval, q); - ret = njs_value_property_set(vm, rx, njs_value_arg(&string_lindex), - &setval); + ret = njs_value_property_set(vm, rx, NJS_ATOM_STRING_lastIndex, &setval); if (njs_slow_path(ret != NJS_OK)) { return NJS_ERROR; } @@ -1747,8 +1711,7 @@ njs_regexp_prototype_symbol_split(njs_vm_t *vm, njs_value_t *args, continue; } - ret = njs_value_property(vm, rx, njs_value_arg(&string_lindex), - retval); + ret = njs_value_property(vm, rx, NJS_ATOM_STRING_lastIndex, retval); if (njs_slow_path(ret == NJS_ERROR)) { return NJS_ERROR; } @@ -1808,7 +1771,7 @@ njs_regexp_prototype_symbol_split(njs_vm_t *vm, njs_value_t *args, return NJS_ERROR; } - (void) njs_string_prop(&sv, retval); + (void) njs_string_prop(vm, &sv, retval); ret = njs_array_string_add(vm, array, sv.start, sv.size, sv.length); @@ -1869,13 +1832,14 @@ done: } -static const njs_object_prop_t njs_regexp_constructor_properties[] = +static const njs_object_prop_init_t njs_regexp_constructor_properties[] = { NJS_DECLARE_PROP_LENGTH(2), NJS_DECLARE_PROP_NAME("RegExp"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), }; @@ -1885,56 +1849,48 @@ const njs_object_init_t njs_regexp_constructor_init = { }; -static const njs_object_prop_t njs_regexp_prototype_properties[] = +static const njs_object_prop_init_t njs_regexp_prototype_properties[] = { - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_GETTER("flags", njs_regexp_prototype_flags, 0), + NJS_DECLARE_PROP_GETTER(STRING_flags, njs_regexp_prototype_flags, 0), - NJS_DECLARE_PROP_GETTER("global", njs_regexp_prototype_flag, + NJS_DECLARE_PROP_GETTER(STRING_global, njs_regexp_prototype_flag, NJS_REGEX_GLOBAL), - NJS_DECLARE_PROP_GETTER("ignoreCase", njs_regexp_prototype_flag, + NJS_DECLARE_PROP_GETTER(STRING_ignoreCase, njs_regexp_prototype_flag, NJS_REGEX_IGNORE_CASE), - NJS_DECLARE_PROP_GETTER("multiline", njs_regexp_prototype_flag, + NJS_DECLARE_PROP_GETTER(STRING_multiline, njs_regexp_prototype_flag, NJS_REGEX_MULTILINE), - NJS_DECLARE_PROP_GETTER("source", njs_regexp_prototype_source, 0), + NJS_DECLARE_PROP_GETTER(STRING_source, njs_regexp_prototype_source, 0), - NJS_DECLARE_PROP_GETTER("sticky", njs_regexp_prototype_flag, + NJS_DECLARE_PROP_GETTER(STRING_sticky, njs_regexp_prototype_flag, NJS_REGEX_STICKY), - NJS_DECLARE_PROP_NATIVE("toString", njs_regexp_prototype_to_string, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_toString, + njs_regexp_prototype_to_string, 0, 0), - NJS_DECLARE_PROP_NATIVE("test", njs_regexp_prototype_test, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_test, njs_regexp_prototype_test, 1, 0), - NJS_DECLARE_PROP_NATIVE("exec", njs_regexp_prototype_exec, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_exec, njs_regexp_prototype_exec, 1, 0), - { - .type = NJS_PROPERTY, - .name = njs_wellknown_symbol(NJS_SYMBOL_REPLACE), - .u.value = njs_native_function(njs_regexp_prototype_symbol_replace, 2), - .writable = 1, - .configurable = 1, - }, + NJS_DECLARE_PROP_NATIVE(SYMBOL_replace, + njs_regexp_prototype_symbol_replace, 2, 0), - { - .type = NJS_PROPERTY, - .name = njs_wellknown_symbol(NJS_SYMBOL_SPLIT), - .u.value = njs_native_function(njs_regexp_prototype_symbol_split, 2), - .writable = 1, - .configurable = 1, - }, + NJS_DECLARE_PROP_NATIVE(SYMBOL_split, + njs_regexp_prototype_symbol_split, 2, 0), }; -const njs_object_prop_t njs_regexp_instance_properties[] = +const njs_object_prop_init_t njs_regexp_instance_properties[] = { - NJS_DECLARE_PROP_HANDLER("lastIndex", njs_regexp_prototype_last_index, - 0, 0, NJS_OBJECT_PROP_VALUE_W), + NJS_DECLARE_PROP_HANDLER(STRING_lastIndex, + njs_regexp_prototype_last_index, 0, + NJS_OBJECT_PROP_VALUE_W), }; diff --git a/src/njs_scope.c b/src/njs_scope.c index 36ba0ec5..304e4e33 100644 --- a/src/njs_scope.c +++ b/src/njs_scope.c @@ -127,7 +127,8 @@ njs_scope_values_hash_test(njs_lvlhsh_query_t *lhq, void *data) value = data; if (njs_is_string(value)) { - njs_string_get(value, &string); + /* parser strings are always initialized. */ + njs_string_get_unsafe(value, &string); } else { string.start = (u_char *) value; @@ -167,24 +168,23 @@ njs_scope_value_index(njs_vm_t *vm, const njs_value_t *src, njs_uint_t runtime, uint32_t value_size, size, length; njs_int_t ret; njs_str_t str; - njs_bool_t long_string; + njs_bool_t is_string; njs_value_t *value; njs_string_t *string; njs_lvlhsh_t *values_hash; njs_lvlhsh_query_t lhq; - long_string = 0; + is_string = 0; value_size = sizeof(njs_value_t); if (njs_is_string(src)) { - njs_string_get(src, &str); + /* parser strings are always initialized. */ + njs_string_get_unsafe(src, &str); size = (uint32_t) str.length; start = str.start; - if (src->short_string.size == NJS_STRING_LONG) { - long_string = 1; - } + is_string = 1; } else { size = value_size; @@ -207,8 +207,8 @@ njs_scope_value_index(njs_vm_t *vm, const njs_value_t *src, njs_uint_t runtime, *index = (njs_index_t *) ((u_char *) value + sizeof(njs_value_t)); } else { - if (long_string) { - length = src->long_string.data->length; + if (is_string) { + length = src->string.data->length; if (size != length && length > NJS_STRING_MAP_STRIDE) { size = njs_string_map_offset(size) @@ -227,14 +227,15 @@ njs_scope_value_index(njs_vm_t *vm, const njs_value_t *src, njs_uint_t runtime, *value = *src; - if (long_string) { + if (is_string) { string = (njs_string_t *) ((u_char *) value + sizeof(njs_value_t) + sizeof(njs_index_t)); - value->long_string.data = string; + value->string.data = string; string->start = (u_char *) string + sizeof(njs_string_t); - string->length = src->long_string.data->length; + string->length = src->string.data->length; + string->size = src->string.data->size; memcpy(string->start, start, size); } diff --git a/src/njs_string.c b/src/njs_string.c index 6a91cb4c..c38f455b 100644 --- a/src/njs_string.c +++ b/src/njs_string.c @@ -160,23 +160,8 @@ njs_string_alloc(njs_vm_t *vm, njs_value_t *value, uint64_t size, } value->type = NJS_STRING; - njs_string_truth(value, size); - - if (size <= NJS_STRING_SHORT) { - value->short_string.size = size; - value->short_string.length = length; - - return value->short_string.start; - } - - /* - * Setting UTF-8 length is not required here, it just allows - * to store the constant in whole byte instead of bit twiddling. - */ - value->short_string.size = NJS_STRING_LONG; - value->short_string.length = 0; - value->long_string.external = 0; - value->long_string.size = size; + value->truth = size != 0; + value->atom_id = NJS_ATOM_STRING_unknown; if (size != length && length > NJS_STRING_MAP_STRIDE) { map_offset = njs_string_map_offset(size); @@ -190,9 +175,10 @@ njs_string_alloc(njs_vm_t *vm, njs_value_t *value, uint64_t size, string = njs_mp_alloc(vm->mem_pool, sizeof(njs_string_t) + total); if (njs_fast_path(string != NULL)) { - value->long_string.data = string; + value->string.data = string; string->start = (u_char *) string + sizeof(njs_string_t); + string->size = size; string->length = length; if (map_offset != 0) { @@ -209,42 +195,23 @@ njs_string_alloc(njs_vm_t *vm, njs_value_t *value, uint64_t size, } -uint32_t -njs_string_length(njs_value_t *string) -{ - uint32_t length, size; - - if (string->short_string.size != NJS_STRING_LONG) { - size = string->short_string.size; - length = string->short_string.length; - - } else { - size = string->long_string.size; - length = string->long_string.data->length; - } - - return (length == 0) ? size : length; -} - - size_t -njs_string_prop(njs_string_prop_t *string, const njs_value_t *value) +njs_string_prop(njs_vm_t *vm, njs_string_prop_t *string, + const njs_value_t *value) { - size_t size; - uintptr_t length; - - size = value->short_string.size; + size_t size, length; + njs_value_t s; - if (size != NJS_STRING_LONG) { - string->start = (u_char *) value->short_string.start; - length = value->short_string.length; - - } else { - string->start = (u_char *) value->long_string.data->start; - size = value->long_string.size; - length = value->long_string.data->length; + if (njs_slow_path(value->string.data == NULL)) { + njs_assert(value->atom_id != NJS_ATOM_STRING_unknown); + (void) njs_atom_to_value(vm, &s, value->atom_id); + value = &s; } + string->start = (u_char *) value->string.data->start; + size = value->string.data->size; + length = value->string.data->length; + string->size = size; string->length = length; @@ -255,32 +222,8 @@ njs_string_prop(njs_string_prop_t *string, const njs_value_t *value) void njs_string_truncate(njs_value_t *value, uint32_t size, uint32_t length) { - u_char *dst, *src; - uint32_t n; - - if (size <= NJS_STRING_SHORT) { - if (value->short_string.size == NJS_STRING_LONG) { - dst = value->short_string.start; - src = value->long_string.data->start; - - n = size; - - while (n != 0) { - /* The maximum size is just 14 bytes. */ - njs_pragma_loop_disable_vectorization; - - *dst++ = *src++; - n--; - } - } - - value->short_string.size = size; - value->short_string.length = length; - - } else { - value->long_string.size = size; - value->long_string.data->length = length; - } + value->string.data->size = size; + value->string.data->length = length; } @@ -430,7 +373,7 @@ njs_string_base64(njs_vm_t *vm, njs_value_t *retval, const njs_str_t *src) length = njs_encode_base64_length(src, &dst.length); if (njs_slow_path(dst.length == 0)) { - njs_value_assign(retval, &njs_string_empty); + njs_set_empty_string(vm, retval); return NJS_OK; } @@ -452,7 +395,7 @@ njs_string_base64url(njs_vm_t *vm, njs_value_t *retval, const njs_str_t *src) njs_str_t dst; if (njs_slow_path(src->length == 0)) { - njs_value_assign(retval, &njs_string_empty); + njs_set_empty_string(vm, retval); return NJS_OK; } @@ -488,21 +431,21 @@ njs_string_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval) { njs_int_t ret; - njs_value_t *value; + njs_value_t value; njs_object_value_t *object; if (nargs == 1) { - value = njs_value_arg(&njs_string_empty); + njs_set_empty_string(vm, &value); } else { - value = &args[1]; + value = args[1]; - if (njs_slow_path(!njs_is_string(value))) { - if (!vm->top_frame->ctor && njs_is_symbol(value)) { - return njs_symbol_descriptive_string(vm, retval, value); + if (njs_slow_path(!njs_is_string(&value))) { + if (!vm->top_frame->ctor && njs_is_symbol(&value)) { + return njs_symbol_descriptive_string(vm, retval, &value); } - ret = njs_value_to_string(vm, value, value); + ret = njs_value_to_string(vm, &value, &value); if (njs_slow_path(ret != NJS_OK)) { return ret; } @@ -510,7 +453,7 @@ njs_string_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } if (vm->top_frame->ctor) { - object = njs_object_value_alloc(vm, NJS_OBJ_TYPE_STRING, 0, value); + object = njs_object_value_alloc(vm, NJS_OBJ_TYPE_STRING, 0, &value); if (njs_slow_path(object == NULL)) { return NJS_ERROR; } @@ -518,28 +461,31 @@ njs_string_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_set_object_value(retval, object); } else { - njs_value_assign(retval, value); + njs_value_assign(retval, &value); } return NJS_OK; } -static const njs_object_prop_t njs_string_constructor_properties[] = +static const njs_object_prop_init_t njs_string_constructor_properties[] = { NJS_DECLARE_PROP_LENGTH(1), NJS_DECLARE_PROP_NAME("String"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), - NJS_DECLARE_PROP_NATIVE("fromCharCode", njs_string_from_char_code, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_fromCharCode, njs_string_from_char_code, + 1, 0), - NJS_DECLARE_PROP_NATIVE("fromCodePoint", njs_string_from_char_code, 1, 1), + NJS_DECLARE_PROP_NATIVE(STRING_fromCodePoint, + njs_string_from_char_code, 1, 1), }; -const njs_object_init_t njs_string_constructor_init = { +static const njs_object_init_t njs_string_constructor_init = { njs_string_constructor_properties, njs_nitems(njs_string_constructor_properties), }; @@ -547,9 +493,9 @@ const njs_object_init_t njs_string_constructor_init = { static njs_int_t njs_string_instance_length(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { - size_t size; uintptr_t length; njs_object_value_t *ov; @@ -568,15 +514,12 @@ njs_string_instance_length(njs_vm_t *vm, njs_object_prop_t *prop, } if (njs_is_string(value)) { - size = value->short_string.size; - length = value->short_string.length; - - if (size == NJS_STRING_LONG) { - size = value->long_string.size; - length = value->long_string.data->length; + if (njs_slow_path(value->string.data == NULL)) { + njs_assert(value->atom_id != NJS_ATOM_STRING_unknown); + njs_atom_to_value(vm, value, value->atom_id); } - length = (length == 0) ? size : length; + length = value->string.data->length; } njs_set_number(retval, length); @@ -586,97 +529,37 @@ njs_string_instance_length(njs_vm_t *vm, njs_object_prop_t *prop, njs_bool_t -njs_string_eq(const njs_value_t *v1, const njs_value_t *v2) +njs_string_eq(njs_vm_t *vm, const njs_value_t *v1, const njs_value_t *v2) { - size_t size, length1, length2; - const u_char *start1, *start2; + njs_str_t s1, s2; - size = v1->short_string.size; + njs_string_get(vm, v1, &s1); + njs_string_get(vm, v2, &s2); - if (size != v2->short_string.size) { + if (s1.length != s2.length) { return 0; } - if (size != NJS_STRING_LONG) { - length1 = v1->short_string.length; - length2 = v2->short_string.length; - - /* - * Using full memcmp() comparison if at least one string - * is a Byte string. - */ - if (length1 != 0 && length2 != 0 && length1 != length2) { - return 0; - } - - start1 = v1->short_string.start; - start2 = v2->short_string.start; - - } else { - size = v1->long_string.size; - - if (size != v2->long_string.size) { - return 0; - } - - length1 = v1->long_string.data->length; - length2 = v2->long_string.data->length; - - /* - * Using full memcmp() comparison if at least one string - * is a Byte string. - */ - if (length1 != 0 && length2 != 0 && length1 != length2) { - return 0; - } - - start1 = v1->long_string.data->start; - start2 = v2->long_string.data->start; - } - - return (memcmp(start1, start2, size) == 0); + return (memcmp(s1.start, s2.start, s1.length) == 0); } njs_int_t -njs_string_cmp(const njs_value_t *v1, const njs_value_t *v2) +njs_string_cmp(njs_vm_t *vm, const njs_value_t *v1, const njs_value_t *v2) { - size_t size, size1, size2; - njs_int_t ret; - const u_char *start1, *start2; - - njs_assert(njs_is_string(v1)); - njs_assert(njs_is_string(v2)); - - size1 = v1->short_string.size; - - if (size1 != NJS_STRING_LONG) { - start1 = v1->short_string.start; - - } else { - size1 = v1->long_string.size; - start1 = v1->long_string.data->start; - } - - size2 = v2->short_string.size; - - if (size2 != NJS_STRING_LONG) { - start2 = v2->short_string.start; - - } else { - size2 = v2->long_string.size; - start2 = v2->long_string.data->start; - } + njs_int_t ret; + njs_str_t s1, s2; - size = njs_min(size1, size2); + njs_string_get(vm, v1, &s1); + njs_string_get(vm, v2, &s2); - ret = memcmp(start1, start2, size); + ret = memcmp(s1.start, s2.start, njs_min(s1.length, s2.length)); if (ret != 0) { return ret; } - return (size1 - size2); + return (s1.length - s2.length); } @@ -748,7 +631,7 @@ njs_string_prototype_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, mask = -1; for (i = 0; i < nargs; i++) { - (void) njs_string_prop(&string, &args[i]); + (void) njs_string_prop(vm, &string, &args[i]); size += string.size; length += string.length; @@ -764,7 +647,7 @@ njs_string_prototype_concat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, p = start; for (i = 0; i < nargs; i++) { - (void) njs_string_prop(&string, &args[i]); + (void) njs_string_prop(vm, &string, &args[i]); p = memcpy(p, string.start, string.size); p += string.size; @@ -832,7 +715,7 @@ njs_string_prototype_substring(njs_vm_t *vm, njs_value_t *args, return ret; } - length = njs_string_prop(&string, njs_argument(args, 0)); + length = njs_string_prop(vm, &string, njs_argument(args, 0)); slice.string_length = length; start = 0; @@ -910,7 +793,7 @@ njs_string_prototype_substr(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return ret; } - length = njs_string_prop(&string, njs_argument(args, 0)); + length = njs_string_prop(vm, &string, njs_argument(args, 0)); slice.string_length = length; start = 0; @@ -988,7 +871,7 @@ njs_string_prototype_char_at(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return ret; } - slice.string_length = njs_string_prop(&string, njs_argument(args, 0)); + slice.string_length = njs_string_prop(vm, &string, njs_argument(args, 0)); ret = njs_value_to_integer(vm, njs_arg(args, nargs, 1), &start); if (njs_slow_path(ret != NJS_OK)) { @@ -1013,7 +896,7 @@ static njs_int_t njs_string_slice_prop(njs_vm_t *vm, njs_string_prop_t *string, njs_slice_prop_t *slice, njs_value_t *args, njs_uint_t nargs) { - slice->string_length = njs_string_prop(string, &args[0]); + slice->string_length = njs_string_prop(vm, string, &args[0]); return njs_string_slice_args(vm, slice, args, nargs); } @@ -1153,7 +1036,7 @@ njs_string_slice(njs_vm_t *vm, njs_value_t *retval, return njs_string_new(vm, retval, prop.start, prop.size, prop.length); } - njs_value_assign(retval, &njs_string_empty); + njs_set_empty_string(vm, retval); return NJS_OK; } @@ -1177,7 +1060,7 @@ njs_string_prototype_char_code_at(njs_vm_t *vm, njs_value_t *args, return ret; } - length = njs_string_prop(&string, njs_argument(args, 0)); + length = njs_string_prop(vm, &string, njs_argument(args, 0)); ret = njs_value_to_integer(vm, njs_arg(args, nargs, 1), &index); if (njs_slow_path(ret != NJS_OK)) { @@ -1306,7 +1189,7 @@ njs_string_decode_hex(njs_vm_t *vm, njs_value_t *retval, const njs_str_t *src) length = njs_decode_hex_length(src, &size); if (njs_slow_path(size == 0)) { - njs_value_assign(retval, &njs_string_empty); + njs_set_empty_string(vm, retval); return NJS_OK; } @@ -1429,7 +1312,7 @@ njs_string_decode_base64_core(njs_vm_t *vm, njs_value_t *retval, length = njs_decode_base64_length_core(src, basis, &dst.length); if (njs_slow_path(dst.length == 0)) { - njs_value_assign(retval, &njs_string_empty); + njs_set_empty_string(vm, retval); return NJS_OK; } @@ -1660,8 +1543,8 @@ njs_string_prototype_index_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return ret; } - length = njs_string_prop(&string, this); - (void) njs_string_prop(&s, search); + length = njs_string_prop(vm, &string, this); + (void) njs_string_prop(vm, &s, search); from = njs_min(njs_max(from, 0), length); @@ -1713,11 +1596,11 @@ njs_string_prototype_last_index_of(njs_vm_t *vm, njs_value_t *args, start = INT64_MAX; } - length = njs_string_prop(&string, this); + length = njs_string_prop(vm, &string, this); start = njs_min(njs_max(start, 0), length); - search_length = njs_string_prop(&s, search); + search_length = njs_string_prop(vm, &s, search); index = length - search_length; @@ -1801,7 +1684,7 @@ njs_string_prototype_includes(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } } - search_length = njs_string_prop(&search, value); + search_length = njs_string_prop(vm, &search, value); if (nargs > 2) { value = njs_argument(args, 2); @@ -1828,7 +1711,7 @@ njs_string_prototype_includes(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return NJS_OK; } - length = njs_string_prop(&string, &args[0]); + length = njs_string_prop(vm, &string, &args[0]); if (length - index >= search_length) { end = string.start + string.size; @@ -1879,7 +1762,7 @@ njs_string_prototype_starts_or_ends_with(njs_vm_t *vm, njs_value_t *args, } } - search_length = njs_string_prop(&search, value); + search_length = njs_string_prop(vm, &search, value); value = njs_arg(args, nargs, 2); @@ -1902,7 +1785,7 @@ njs_string_prototype_starts_or_ends_with(njs_vm_t *vm, njs_value_t *args, } if (nargs > 1) { - length = njs_string_prop(&string, &args[0]); + length = njs_string_prop(vm, &string, &args[0]); if (starts) { if (index < 0) { @@ -2072,7 +1955,7 @@ njs_string_prototype_to_lower_case(njs_vm_t *vm, njs_value_t *args, return ret; } - (void) njs_string_prop(&string, njs_argument(args, 0)); + (void) njs_string_prop(vm, &string, njs_argument(args, 0)); if (njs_is_ascii_string(&string)) { @@ -2143,7 +2026,7 @@ njs_string_prototype_to_upper_case(njs_vm_t *vm, njs_value_t *args, return ret; } - (void) njs_string_prop(&string, njs_argument(args, 0)); + (void) njs_string_prop(vm, &string, njs_argument(args, 0)); if (njs_is_ascii_string(&string)) { @@ -2194,8 +2077,8 @@ njs_string_prototype_to_upper_case(njs_vm_t *vm, njs_value_t *args, uint32_t -njs_string_trim(const njs_value_t *value, njs_string_prop_t *string, - unsigned mode) +njs_string_trim(njs_vm_t *vm, const njs_value_t *value, + njs_string_prop_t *string, unsigned mode) { uint32_t cp, trim; const u_char *p, *prev, *start, *end; @@ -2203,7 +2086,7 @@ njs_string_trim(const njs_value_t *value, njs_string_prop_t *string, trim = 0; - njs_string_prop(string, value); + njs_string_prop(vm, string, value); start = string->start; end = string->start + string->size; @@ -2326,7 +2209,7 @@ njs_string_prototype_trim(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return ret; } - trim = njs_string_trim(value, &string, mode); + trim = njs_string_trim(vm, value, &string, mode); if (trim == 0) { njs_value_assign(retval, value); @@ -2334,7 +2217,7 @@ njs_string_prototype_trim(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } if (string.size == 0) { - njs_value_assign(retval, &njs_string_empty); + njs_set_empty_string(vm, retval); return NJS_OK; } @@ -2377,10 +2260,10 @@ njs_string_prototype_repeat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return NJS_ERROR; } - (void) njs_string_prop(&string, this); + (void) njs_string_prop(vm, &string, this); if (njs_slow_path(n == 0 || string.size == 0)) { - njs_value_assign(retval, &njs_string_empty); + njs_set_empty_string(vm, retval); return NJS_OK; } @@ -2422,14 +2305,12 @@ njs_string_prototype_pad(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, const u_char *end; njs_string_prop_t string, pad_string; - static const njs_value_t string_space = njs_string(" "); - ret = njs_string_object_validate(vm, njs_argument(args, 0)); if (njs_slow_path(ret != NJS_OK)) { return ret; } - length = njs_string_prop(&string, njs_argument(args, 0)); + length = njs_string_prop(vm, &string, njs_argument(args, 0)); new_length = 0; @@ -2465,19 +2346,22 @@ njs_string_prototype_pad(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, pad = njs_arg(args, nargs, 2); - if (njs_slow_path(!njs_is_string(pad))) { - if (njs_is_undefined(pad)) { - pad = njs_value_arg(&string_space); - - } else { - ret = njs_value_to_string(vm, pad, pad); - if (njs_slow_path(ret != NJS_OK)) { - return NJS_ERROR; - } + if (njs_slow_path(!njs_is_string(pad) && !njs_is_undefined(pad))) { + ret = njs_value_to_string(vm, pad, pad); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_ERROR; } } - pad_length = njs_string_prop(&pad_string, pad); + if (njs_slow_path(njs_is_undefined(pad))) { + pad_string.start = (u_char *) " "; + pad_string.size = 1; + pad_string.length = 1; + pad_length = 1; + + } else { + pad_length = njs_string_prop(vm, &pad_string, pad); + } if (pad_string.size == 0) { njs_value_assign(retval, njs_argument(args, 0)); @@ -2571,7 +2455,7 @@ njs_string_prototype_search(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } } - (void) njs_string_prop(&string, value); + (void) njs_string_prop(vm, &string, value); if (string.size != 0) { pattern = njs_regexp_pattern_create(vm, string.start, @@ -2588,7 +2472,7 @@ njs_string_prototype_search(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, index = -1; - (void) njs_string_prop(&string, &args[0]); + (void) njs_string_prop(vm, &string, &args[0]); n = (string.length != 0); @@ -2657,11 +2541,11 @@ njs_string_prototype_match(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return ret; } - njs_string_get(&args[1], &string); + njs_string_get(vm, &args[1], &string); } } else { - njs_string_get(&args[1], &string); + njs_string_get(vm, &args[1], &string); } /* A void value. */ @@ -2694,7 +2578,7 @@ njs_string_match_multiple(njs_vm_t *vm, njs_value_t *args, njs_set_number(&args[1].data.u.regexp->last_index, 0); njs_set_null(retval); - (void) njs_string_prop(&string, &args[0]); + (void) njs_string_prop(vm, &string, &args[0]); utf8 = NJS_STRING_ASCII; type = NJS_REGEXP_BYTE; @@ -2795,9 +2679,6 @@ njs_string_prototype_split(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_string_prop_t string, split; njs_value_t arguments[3]; - static const njs_value_t split_key = - njs_wellknown_symbol(NJS_SYMBOL_SPLIT); - this = njs_argument(args, 0); if (njs_slow_path(njs_is_null_or_undefined(this))) { @@ -2810,7 +2691,7 @@ njs_string_prototype_split(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, value = njs_lvalue_arg(&limit_lvalue, args, nargs, 2); if (!njs_is_null_or_undefined(separator)) { - ret = njs_value_method(vm, separator, njs_value_arg(&split_key), + ret = njs_value_method(vm, separator, NJS_ATOM_SYMBOL_split, &splitter); if (njs_slow_path(ret != NJS_OK)) { return ret; @@ -2859,8 +2740,8 @@ njs_string_prototype_split(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, goto single; } - (void) njs_string_prop(&string, this); - (void) njs_string_prop(&split, separator); + (void) njs_string_prop(vm, &string, this); + (void) njs_string_prop(vm, &split, separator); if (njs_slow_path(string.size == 0)) { if (split.size != 0) { @@ -2951,7 +2832,7 @@ njs_string_get_substitution(njs_vm_t *vm, njs_value_t *matched, njs_value_t name, value; njs_string_prop_t s, m; - njs_string_get(replacement, &rep); + njs_string_get(vm, replacement, &rep); p = rep.start; end = rep.start + rep.length; @@ -2981,21 +2862,21 @@ njs_string_get_substitution(njs_vm_t *vm, njs_value_t *matched, break; case '&': - (void) njs_string_prop(&m, matched); + (void) njs_string_prop(vm, &m, matched); njs_chb_append(&chain, m.start, m.size); p += 2; break; case '`': - (void) njs_string_prop(&s, string); + (void) njs_string_prop(vm, &s, string); n = njs_string_offset(&s, pos) - s.start; njs_chb_append(&chain, s.start, n); p += 2; break; case '\'': - length = njs_string_prop(&m, matched); - (void) njs_string_prop(&s, string); + length = njs_string_prop(vm, &m, matched); + (void) njs_string_prop(vm, &s, string); tail = njs_string_offset(&s, pos + length) - s.start; @@ -3021,7 +2902,7 @@ njs_string_get_substitution(njs_vm_t *vm, njs_value_t *matched, p = r + 1; - ret = njs_value_property(vm, groups, &name, &value); + ret = njs_value_property_val(vm, groups, &name, &value); if (njs_slow_path(ret == NJS_ERROR)) { goto exception; } @@ -3032,7 +2913,7 @@ njs_string_get_substitution(njs_vm_t *vm, njs_value_t *matched, goto exception; } - njs_string_get(&value, &str); + njs_string_get(vm, &value, &str); njs_chb_append_str(&chain, &str); } @@ -3062,7 +2943,7 @@ njs_string_get_substitution(njs_vm_t *vm, njs_value_t *matched, p += (c2 != 0) ? 3 : 2; if (njs_is_defined(&captures[n])) { - njs_string_get(&captures[n], &cap); + njs_string_get(vm, &captures[n], &cap); njs_chb_append_str(&chain, &cap); } @@ -3110,10 +2991,6 @@ njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_function_t *func_replace; njs_string_prop_t string, s, ret_string; - static const njs_value_t replace_key = - njs_wellknown_symbol(NJS_SYMBOL_REPLACE); - static const njs_value_t string_flags = njs_string("flags"); - this = njs_argument(args, 0); if (njs_slow_path(njs_is_null_or_undefined(this))) { @@ -3126,8 +3003,7 @@ njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, replace = njs_lvalue_arg(&replace_lvalue, args, nargs, 2); if (!njs_is_null_or_undefined(search)) { - ret = njs_value_method(vm, search, njs_value_arg(&replace_key), - &replacer); + ret = njs_value_method(vm, search, NJS_ATOM_SYMBOL_replace, &replacer); if (njs_slow_path(ret != NJS_OK)) { return ret; } @@ -3140,8 +3016,8 @@ njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, && njs_function(&replacer)->u.native == njs_regexp_prototype_symbol_replace) { - ret = njs_value_property(vm, search, - njs_value_arg(&string_flags), &value); + ret = njs_value_property(vm, search, NJS_ATOM_STRING_flags, + &value); if (njs_slow_path(ret == NJS_ERROR)) { return NJS_ERROR; } @@ -3151,7 +3027,7 @@ njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return NJS_ERROR; } - njs_string_get(&value, &str); + njs_string_get(vm, &value, &str); if (njs_strlchr(str.start, str.start + str.length, 'g') == NULL) @@ -3191,8 +3067,8 @@ njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_value_assign(&arguments[2], this); } - (void) njs_string_prop(&string, this); - (void) njs_string_prop(&s, search); + (void) njs_string_prop(vm, &string, this); + (void) njs_string_prop(vm, &s, search); pos = njs_string_index_of(&string, &s, 0); if (pos < 0) { @@ -3227,7 +3103,7 @@ njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, end = njs_string_offset(&string, pos); - (void) njs_string_prop(&ret_string, &value); + (void) njs_string_prop(vm, &ret_string, &value); size = string.size + ret_string.size - s.size; length = string.length + ret_string.length - s.length; @@ -3274,7 +3150,7 @@ njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } end = njs_string_offset(&string, pos); - (void) njs_string_prop(&ret_string, &value); + (void) njs_string_prop(vm, &ret_string, &value); njs_chb_append(&chain, start, end - start); njs_chb_append(&chain, ret_string.start, ret_string.size); @@ -3332,7 +3208,7 @@ njs_string_prototype_iterator_obj(njs_vm_t *vm, njs_value_t *args, double -njs_string_to_number(const njs_value_t *value) +njs_string_to_number(njs_vm_t *vm, const njs_value_t *value) { double num; njs_bool_t minus; @@ -3341,7 +3217,7 @@ njs_string_to_number(const njs_value_t *value) const size_t infinity = njs_length("Infinity"); - (void) njs_string_trim(value, &string, NJS_TRIM_START); + (void) njs_string_trim(vm, value, &string, NJS_TRIM_START); p = string.start; end = p + string.size; @@ -3413,16 +3289,17 @@ njs_string_to_index(const njs_value_t *value) const u_char *p, *start, *end; u_char buf[128]; - size = value->short_string.size; - - if (size != NJS_STRING_LONG) { - start = value->short_string.start; + if (njs_slow_path(value->type == NJS_SYMBOL)) { + return NAN; + } - } else { - size = value->long_string.size; - start = value->long_string.data->start; + if (njs_atom_is_number(value->atom_id)) { + return njs_atom_number(value->atom_id); } + size = value->string.data->size; + start = value->string.data->start; + p = start; end = p + size; minus = 0; @@ -3493,89 +3370,99 @@ njs_string_to_index(const njs_value_t *value) } -static const njs_object_prop_t njs_string_prototype_properties[] = +static const njs_object_prop_init_t njs_string_prototype_properties[] = { - NJS_DECLARE_PROP_HANDLER("__proto__", njs_primitive_prototype_get_proto, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING___proto__, + njs_primitive_prototype_get_proto, 0, + NJS_OBJECT_PROP_VALUE_CW), NJS_DECLARE_PROP_LENGTH(0), - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), - - NJS_DECLARE_PROP_NATIVE("valueOf", njs_string_prototype_value_of, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_NATIVE("toString", njs_string_prototype_to_string, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_valueOf, njs_string_prototype_value_of, + 0, 0), - NJS_DECLARE_PROP_NATIVE("concat", njs_string_prototype_concat, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_toString, + njs_string_prototype_to_string, 0, 0), - NJS_DECLARE_PROP_NATIVE("slice", njs_string_prototype_slice, 2, 0), + NJS_DECLARE_PROP_NATIVE(STRING_concat, + njs_string_prototype_concat, 1, 0), - NJS_DECLARE_PROP_NATIVE("substring", njs_string_prototype_substring, 2, 0), + NJS_DECLARE_PROP_NATIVE(STRING_slice, njs_string_prototype_slice, 2, + 0), - NJS_DECLARE_PROP_NATIVE("substr", njs_string_prototype_substr, 2, 0), + NJS_DECLARE_PROP_NATIVE(STRING_substring, + njs_string_prototype_substring, 2, 0), - NJS_DECLARE_PROP_NATIVE("charAt", njs_string_prototype_char_at, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_substr, njs_string_prototype_substr, 2, + 0), - NJS_DECLARE_PROP_NATIVE("charCodeAt", njs_string_prototype_char_code_at, 1, + NJS_DECLARE_PROP_NATIVE(STRING_charAt, njs_string_prototype_char_at, 1, 0), - NJS_DECLARE_PROP_NATIVE("codePointAt", njs_string_prototype_char_code_at, - 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_charCodeAt, + njs_string_prototype_char_code_at, 1, 0), - NJS_DECLARE_PROP_NATIVE("indexOf", njs_string_prototype_index_of, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_codePointAt, + njs_string_prototype_char_code_at, 1, 0), - NJS_DECLARE_PROP_NATIVE("lastIndexOf", njs_string_prototype_last_index_of, + NJS_DECLARE_PROP_NATIVE(STRING_indexOf, njs_string_prototype_index_of, 1, 0), - NJS_DECLARE_PROP_NATIVE("includes", njs_string_prototype_includes, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_lastIndexOf, + njs_string_prototype_last_index_of, 1, 0), - NJS_DECLARE_PROP_NATIVE("startsWith", + NJS_DECLARE_PROP_NATIVE(STRING_includes, njs_string_prototype_includes, + 1, 0), + + NJS_DECLARE_PROP_NATIVE(STRING_startsWith, njs_string_prototype_starts_or_ends_with, 1, 1), - NJS_DECLARE_PROP_NATIVE("endsWith", + NJS_DECLARE_PROP_NATIVE(STRING_endsWith, njs_string_prototype_starts_or_ends_with, 1, 0), - NJS_DECLARE_PROP_NATIVE("toLowerCase", njs_string_prototype_to_lower_case, - 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_toLowerCase, + njs_string_prototype_to_lower_case, 0, 0), - NJS_DECLARE_PROP_NATIVE("toUpperCase", njs_string_prototype_to_upper_case, - 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_toUpperCase, + njs_string_prototype_to_upper_case, 0, 0), - NJS_DECLARE_PROP_NATIVE("trim", njs_string_prototype_trim, 0, + NJS_DECLARE_PROP_NATIVE(STRING_trim, njs_string_prototype_trim, 0, NJS_TRIM_START | NJS_TRIM_END), - NJS_DECLARE_PROP_NATIVE("trimStart", njs_string_prototype_trim, 0, + NJS_DECLARE_PROP_NATIVE(STRING_trimStart, njs_string_prototype_trim, 0, NJS_TRIM_START), - NJS_DECLARE_PROP_NATIVE("trimEnd", njs_string_prototype_trim, 0, + NJS_DECLARE_PROP_NATIVE(STRING_trimEnd, njs_string_prototype_trim, 0, NJS_TRIM_END), - NJS_DECLARE_PROP_NATIVE("repeat", njs_string_prototype_repeat, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_repeat, njs_string_prototype_repeat, 1, + 0), - NJS_DECLARE_PROP_NATIVE("padStart", njs_string_prototype_pad, 1, 1), + NJS_DECLARE_PROP_NATIVE(STRING_padStart, njs_string_prototype_pad, 1, + 1), - NJS_DECLARE_PROP_NATIVE("padEnd", njs_string_prototype_pad, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_padEnd, njs_string_prototype_pad, 1, 0), - NJS_DECLARE_PROP_NATIVE("search", njs_string_prototype_search, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_search, njs_string_prototype_search, 1, + 0), - NJS_DECLARE_PROP_NATIVE("match", njs_string_prototype_match, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_match, njs_string_prototype_match, 1, 0), - NJS_DECLARE_PROP_NATIVE("split", njs_string_prototype_split, 2, 0), + NJS_DECLARE_PROP_NATIVE(STRING_split, njs_string_prototype_split, 2, 0), - NJS_DECLARE_PROP_NATIVE("replace", njs_string_prototype_replace, 2, 0), + NJS_DECLARE_PROP_NATIVE(STRING_replace, njs_string_prototype_replace, 2, + 0), - NJS_DECLARE_PROP_NATIVE("replaceAll", njs_string_prototype_replace, 2, 1), + NJS_DECLARE_PROP_NATIVE(STRING_replaceAll, njs_string_prototype_replace, + 2, 1), - { - .type = NJS_PROPERTY, - .name = njs_wellknown_symbol(NJS_SYMBOL_ITERATOR), - .u.value = njs_native_function2(njs_string_prototype_iterator_obj, 0, - NJS_ENUM_VALUES), - .writable = 1, - .configurable = 1, - }, + NJS_DECLARE_PROP_NATIVE(SYMBOL_iterator, + njs_string_prototype_iterator_obj, 0, + NJS_ENUM_VALUES), }; @@ -3585,9 +3472,10 @@ const njs_object_init_t njs_string_prototype_init = { }; -const njs_object_prop_t njs_string_instance_properties[] = +const njs_object_prop_init_t njs_string_instance_properties[] = { - NJS_DECLARE_PROP_HANDLER("length", njs_string_instance_length, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_length, njs_string_instance_length, 0, + 0), }; @@ -3649,7 +3537,7 @@ njs_string_encode_uri(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, }; if (nargs < 2) { - njs_value_assign(retval, &njs_string_undefined); + njs_atom_to_value(vm, retval, NJS_ATOM_STRING_undefined); return NJS_OK; } @@ -3663,7 +3551,7 @@ njs_string_encode_uri(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_prefetch(escape); - (void) njs_string_prop(&string, value); + (void) njs_string_prop(vm, &string, value); size = 0; src = string.start; @@ -3878,7 +3766,7 @@ njs_string_decode_uri(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, }; if (nargs < 2) { - njs_value_assign(retval, &njs_string_undefined); + njs_atom_to_value(vm, retval, NJS_ATOM_STRING_undefined); return NJS_OK; } @@ -3893,7 +3781,7 @@ njs_string_decode_uri(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_prefetch(reserve); njs_prefetch(&hex['0']); - (void) njs_string_prop(&string, value); + (void) njs_string_prop(vm, &string, value); length = 0; src = string.start; @@ -4023,7 +3911,7 @@ njs_string_btoa(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, return ret; } - len = njs_string_prop(&string, value); + len = njs_string_prop(vm, &string, value); p = string.start; end = string.start + string.size; @@ -4121,7 +4009,7 @@ njs_string_atob(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, /* Forgiving-base64 decode. */ b64 = njs_basis64; - njs_string_get(value, &str); + njs_string_get(vm, value, &str); tmp = njs_mp_alloc(vm->mem_pool, str.length); if (tmp == NULL) { @@ -4208,7 +4096,7 @@ njs_string_atob(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } if (size == 0) { - njs_value_assign(retval, &njs_string_empty); + njs_set_empty_string(vm, retval); return NJS_OK; } @@ -4237,7 +4125,6 @@ const njs_object_type_init_t njs_string_type_init = { .constructor_props = &njs_string_constructor_init, .prototype_props = &njs_string_prototype_init, .prototype_value = { .object_value = { - .value = njs_string(""), .object = { .type = NJS_OBJECT_VALUE } } }, }; diff --git a/src/njs_string.h b/src/njs_string.h index 686a5a74..1961152f 100644 --- a/src/njs_string.h +++ b/src/njs_string.h @@ -73,6 +73,7 @@ struct njs_string_s { u_char *start; uint32_t length; /* Length in UTF-8 characters. */ + uint32_t size; }; @@ -111,8 +112,8 @@ njs_int_t njs_string_create(njs_vm_t *vm, njs_value_t *value, const u_char *src, njs_int_t njs_string_create_chb(njs_vm_t *vm, njs_value_t *value, njs_chb_t *chain); -uint32_t njs_string_length(njs_value_t *string); -size_t njs_string_prop(njs_string_prop_t *string, const njs_value_t *value); +size_t njs_string_prop(njs_vm_t *vm, njs_string_prop_t *string, + const njs_value_t *value); void njs_encode_hex(njs_str_t *dst, const njs_str_t *src); size_t njs_encode_hex_length(const njs_str_t *src, size_t *out_size); @@ -143,10 +144,11 @@ njs_int_t njs_string_decode_base64(njs_vm_t *vm, njs_value_t *value, njs_int_t njs_string_decode_base64url(njs_vm_t *vm, njs_value_t *value, const njs_str_t *src); void njs_string_truncate(njs_value_t *value, uint32_t size, uint32_t length); -uint32_t njs_string_trim(const njs_value_t *value, njs_string_prop_t *string, - unsigned mode); +uint32_t njs_string_trim(njs_vm_t *vm, const njs_value_t *value, + njs_string_prop_t *string, unsigned mode); void njs_string_copy(njs_value_t *dst, njs_value_t *src); -njs_int_t njs_string_cmp(const njs_value_t *val1, const njs_value_t *val2); +njs_int_t njs_string_cmp(njs_vm_t *vm, const njs_value_t *val1, + const njs_value_t *val2); void njs_string_slice_string_prop(njs_string_prop_t *dst, const njs_string_prop_t *string, const njs_slice_prop_t *slice); njs_int_t njs_string_slice(njs_vm_t *vm, njs_value_t *dst, @@ -172,6 +174,21 @@ njs_int_t njs_string_get_substitution(njs_vm_t *vm, njs_value_t *matched, njs_value_t *groups, njs_value_t *replacement, njs_value_t *retval); +njs_inline njs_int_t +njs_atom_string_create(njs_vm_t *vm, njs_value_t *value, const u_char *src, + size_t size) +{ + njs_int_t ret; + + ret = njs_string_create(vm, value, src, size); + if (njs_slow_path(ret != NJS_OK)) { + return ret; + } + + return njs_atom_atomize_key(vm, value); +} + + njs_inline njs_bool_t njs_is_ascii_string(njs_string_prop_t *string) { diff --git a/src/njs_symbol.c b/src/njs_symbol.c index a284d4e9..46634a61 100644 --- a/src/njs_symbol.c +++ b/src/njs_symbol.c @@ -8,63 +8,9 @@ #include -static const njs_value_t njs_symbol_async_iterator_name = - njs_long_string("Symbol.asyncIterator"); -static const njs_value_t njs_symbol_has_instance_name = - njs_long_string("Symbol.hasInstance"); -static const njs_value_t njs_symbol_is_concat_spreadable_name = - njs_long_string("Symbol.isConcatSpreadable"); -static const njs_value_t njs_symbol_iterator_name = - njs_long_string("Symbol.iterator"); -static const njs_value_t njs_symbol_match_name = - njs_string("Symbol.match"); -static const njs_value_t njs_symbol_match_all_name = - njs_long_string("Symbol.matchAll"); -static const njs_value_t njs_symbol_replace_name = - njs_string("Symbol.replace"); -static const njs_value_t njs_symbol_search_name = - njs_string("Symbol.search"); -static const njs_value_t njs_symbol_species_name = - njs_string("Symbol.species"); -static const njs_value_t njs_symbol_split_name = - njs_string("Symbol.split"); -static const njs_value_t njs_symbol_to_primitive_name = - njs_long_string("Symbol.toPrimitive"); -static const njs_value_t njs_symbol_to_string_tag_name = - njs_long_string("Symbol.toStringTag"); -static const njs_value_t njs_symbol_unscopables_name = - njs_long_string("Symbol.unscopables"); - - -static const njs_value_t *njs_symbol_names[NJS_SYMBOL_KNOWN_MAX] = { - &njs_string_invalid, - &njs_symbol_async_iterator_name, - &njs_symbol_has_instance_name, - &njs_symbol_is_concat_spreadable_name, - &njs_symbol_iterator_name, - &njs_symbol_match_name, - &njs_symbol_match_all_name, - &njs_symbol_replace_name, - &njs_symbol_search_name, - &njs_symbol_species_name, - &njs_symbol_split_name, - &njs_symbol_to_primitive_name, - &njs_symbol_to_string_tag_name, - &njs_symbol_unscopables_name, -}; - - const njs_value_t * njs_symbol_description(const njs_value_t *value) { - uint32_t key; - - key = njs_symbol_key(value); - - if (key < NJS_SYMBOL_KNOWN_MAX) { - return njs_symbol_names[key]; - } - return value->data.u.value != NULL ? value->data.u.value : &njs_value_undefined; } @@ -80,11 +26,14 @@ njs_symbol_descriptive_string(njs_vm_t *vm, njs_value_t *dst, description = njs_symbol_description(value); - if (njs_is_undefined(description)) { - description = &njs_string_empty; - } + if (!njs_is_undefined(description)) { + (void) njs_string_prop(vm, &string, description); - (void) njs_string_prop(&string, description); + } else { + string.start = (u_char *) ""; + string.size = 0; + string.length = 0; + } string.length += njs_length("Symbol()"); @@ -105,7 +54,6 @@ static njs_int_t njs_symbol_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval) { - uint64_t key; njs_int_t ret; njs_value_t *value, *name; @@ -125,13 +73,6 @@ njs_symbol_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } } - key = ++vm->symbol_generator; - - if (njs_slow_path(key >= UINT32_MAX)) { - njs_internal_error(vm, "Symbol generator overflow"); - return NJS_ERROR; - } - name = njs_mp_alloc(vm->mem_pool, sizeof(njs_value_t)); if (njs_slow_path(name == NULL)) { njs_memory_error(vm); @@ -139,7 +80,12 @@ njs_symbol_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } njs_value_assign(name, value); - njs_set_symbol(retval, key, name); + njs_set_symbol(retval, 0, name); + + ret = njs_atom_symbol_add(vm, retval); + if (ret != NJS_OK) { + return NJS_ERROR; + } return NJS_OK; } @@ -149,7 +95,6 @@ static njs_int_t njs_symbol_for(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval) { - uint64_t key; njs_int_t ret; njs_value_t *value, lvalue; njs_rbtree_node_t *rb_node; @@ -171,7 +116,7 @@ njs_symbol_for(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, node = (njs_rb_symbol_node_t *) rb_node; if (njs_is_string(&node->name) - && njs_string_cmp(value, &node->name) == 0) + && njs_string_cmp(vm, value, &node->name) == 0) { njs_set_symbol(retval, node->key, &node->name); return NJS_OK; @@ -180,25 +125,23 @@ njs_symbol_for(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, rb_node = njs_rbtree_node_successor(&vm->global_symbols, rb_node); } - key = ++vm->symbol_generator; - - if (njs_slow_path(key >= UINT32_MAX)) { - njs_internal_error(vm, "Symbol generator overflow"); - return NJS_ERROR; - } - node = njs_mp_alloc(vm->mem_pool, sizeof(njs_rb_symbol_node_t)); if (njs_slow_path(node == NULL)) { njs_memory_error(vm); return NJS_ERROR; } - node->key = key; njs_value_assign(&node->name, value); + njs_set_symbol(retval, 0, &node->name); - njs_rbtree_insert(&vm->global_symbols, &node->node); + ret = njs_atom_symbol_add(vm, retval); + if (ret != NJS_OK) { + return NJS_ERROR; + } + + node->key = retval->atom_id; - njs_set_symbol(retval, key, &node->name); + njs_rbtree_insert(&vm->global_symbols, &node->node); return NJS_OK; } @@ -229,56 +172,60 @@ njs_symbol_key_for(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } -static const njs_object_prop_t njs_symbol_constructor_properties[] = +static const njs_object_prop_init_t njs_symbol_constructor_properties[] = { NJS_DECLARE_PROP_LENGTH(0), NJS_DECLARE_PROP_NAME("Symbol"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), - NJS_DECLARE_PROP_NATIVE("for", njs_symbol_for, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_for, njs_symbol_for, 1, 0), - NJS_DECLARE_PROP_NATIVE("keyFor", njs_symbol_key_for, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_keyFor, njs_symbol_key_for, 1, 0), - NJS_DECLARE_PROP_VALUE("asyncIterator", - njs_wellknown_symbol(NJS_SYMBOL_ASYNC_ITERATOR), 0), + NJS_DECLARE_PROP_VALUE(STRING_asyncIterator, + njs_symval(asyncIterator, "Symbol.asyncIterator"), + 0), - NJS_DECLARE_PROP_VALUE("hasInstance", - njs_wellknown_symbol(NJS_SYMBOL_HAS_INSTANCE), 0), + NJS_DECLARE_PROP_VALUE(STRING_hasInstance, + njs_symval(hasInstance, "Symbol.hasInstance"), + 0), - NJS_DECLARE_PROP_LVALUE("isConcatSpreadable", - njs_wellknown_symbol(NJS_SYMBOL_IS_CONCAT_SPREADABLE), 0), + NJS_DECLARE_PROP_VALUE(STRING_isConcatSpreadable, + njs_symval(isConcatSpreadable, "Symbol.isConcatSpreadable"), + 0), - NJS_DECLARE_PROP_VALUE("iterator", - njs_wellknown_symbol(NJS_SYMBOL_ITERATOR), 0), + NJS_DECLARE_PROP_VALUE(STRING_iterator, + njs_symval(iterator, "Symbol.iterator"), 0), - NJS_DECLARE_PROP_VALUE("match", - njs_wellknown_symbol(NJS_SYMBOL_MATCH), 0), + NJS_DECLARE_PROP_VALUE(STRING_match, njs_symval(match, "Symbol.match"), 0), - NJS_DECLARE_PROP_VALUE("matchAll", - njs_wellknown_symbol(NJS_SYMBOL_MATCH_ALL), 0), + NJS_DECLARE_PROP_VALUE(STRING_matchAll, + njs_symval(matchAll, "Symbol.matchAll"), 0), - NJS_DECLARE_PROP_VALUE("replace", - njs_wellknown_symbol(NJS_SYMBOL_REPLACE), 0), + NJS_DECLARE_PROP_VALUE(STRING_replace, + njs_symval(replace, "Symbol.replace"), 0), - NJS_DECLARE_PROP_VALUE("search", - njs_wellknown_symbol(NJS_SYMBOL_SEARCH), 0), + NJS_DECLARE_PROP_VALUE(STRING_search, + njs_symval(search, "Symbol.search"), 0), - NJS_DECLARE_PROP_VALUE("species", - njs_wellknown_symbol(NJS_SYMBOL_SPECIES), 0), + NJS_DECLARE_PROP_VALUE(STRING_species, + njs_symval(species, "Symbol.species"), 0), - NJS_DECLARE_PROP_VALUE("split", - njs_wellknown_symbol(NJS_SYMBOL_SPLIT), 0), + NJS_DECLARE_PROP_VALUE(STRING_split, njs_symval(split, "Symbol.split"), 0), - NJS_DECLARE_PROP_VALUE("toPrimitive", - njs_wellknown_symbol(NJS_SYMBOL_TO_PRIMITIVE), 0), + NJS_DECLARE_PROP_VALUE(STRING_toPrimitive, + njs_symval(toPrimitive, "Symbol.toPrimitive"), + 0), - NJS_DECLARE_PROP_VALUE("toStringTag", - njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG), 0), + NJS_DECLARE_PROP_VALUE(STRING_toStringTag, + njs_symval(toStringTag, "Symbol.toStringTag"), 0), - NJS_DECLARE_PROP_VALUE("unscopables", - njs_wellknown_symbol(NJS_SYMBOL_UNSCOPABLES), 0), + NJS_DECLARE_PROP_VALUE(STRING_unscopables, + njs_symval(unscopables, "Symbol.unscopables"), + 0), }; @@ -347,27 +294,27 @@ njs_symbol_prototype_description(njs_vm_t *vm, njs_value_t *args, } -static const njs_object_prop_t njs_symbol_prototype_properties[] = +static const njs_object_prop_init_t njs_symbol_prototype_properties[] = { - { - .type = NJS_PROPERTY, - .name = njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG), - .u.value = njs_string("Symbol"), - .configurable = 1, - }, + NJS_DECLARE_PROP_VALUE(SYMBOL_toStringTag, njs_ascii_strval("Symbol"), + NJS_OBJECT_PROP_VALUE_C), - NJS_DECLARE_PROP_HANDLER("__proto__", njs_primitive_prototype_get_proto, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING___proto__, + njs_primitive_prototype_get_proto, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_NATIVE("valueOf", njs_symbol_prototype_value_of, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_valueOf, njs_symbol_prototype_value_of, + 0, 0), - NJS_DECLARE_PROP_NATIVE("toString", njs_symbol_prototype_to_string, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_toString, + njs_symbol_prototype_to_string, 0, 0), - NJS_DECLARE_PROP_GETTER("description", njs_symbol_prototype_description, 0), + NJS_DECLARE_PROP_GETTER(STRING_description, + njs_symbol_prototype_description, 0), }; diff --git a/src/njs_typed_array.c b/src/njs_typed_array.c index 5930dcb0..19399e3b 100644 --- a/src/njs_typed_array.c +++ b/src/njs_typed_array.c @@ -433,37 +433,22 @@ njs_typed_array_writable(njs_vm_t *vm, njs_typed_array_t *array) } -static const njs_value_t njs_typed_array_uint8_tag = njs_string("Uint8Array"); -static const njs_value_t njs_typed_array_uint8_clamped_tag = - njs_long_string("Uint8ClampedArray"); -static const njs_value_t njs_typed_array_int8_tag = njs_string("Int8Array"); -static const njs_value_t njs_typed_array_uint16_tag = - njs_string("Uint16Array"); -static const njs_value_t njs_typed_array_int16_tag = njs_string("Int16Array"); -static const njs_value_t njs_typed_array_uint32_tag = - njs_string("Uint32Array"); -static const njs_value_t njs_typed_array_int32_tag = njs_string("Int32Array"); -static const njs_value_t njs_typed_array_float32_tag = - njs_string("Float32Array"); -static const njs_value_t njs_typed_array_float64_tag = - njs_string("Float64Array"); - static njs_int_t njs_typed_array_get_string_tag(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval) { njs_value_t *this; - static const njs_value_t *tags[NJS_OBJ_TYPE_TYPED_ARRAY_SIZE] = { - &njs_typed_array_uint8_tag, - &njs_typed_array_uint8_clamped_tag, - &njs_typed_array_int8_tag, - &njs_typed_array_uint16_tag, - &njs_typed_array_int16_tag, - &njs_typed_array_uint32_tag, - &njs_typed_array_int32_tag, - &njs_typed_array_float32_tag, - &njs_typed_array_float64_tag, + static const uint32_t tags[NJS_OBJ_TYPE_TYPED_ARRAY_SIZE] = { + NJS_ATOM_STRING_Uint8Array, + NJS_ATOM_STRING_Uint8ClampedArray, + NJS_ATOM_STRING_Int8Array, + NJS_ATOM_STRING_Uint16Array, + NJS_ATOM_STRING_Int16Array, + NJS_ATOM_STRING_Uint32Array, + NJS_ATOM_STRING_Int32Array, + NJS_ATOM_STRING_Float32Array, + NJS_ATOM_STRING_Float64Array, }; this = njs_argument(args, 0); @@ -473,8 +458,8 @@ njs_typed_array_get_string_tag(njs_vm_t *vm, njs_value_t *args, return NJS_OK; } - njs_value_assign(retval, - tags[njs_typed_array_index(njs_typed_array(this)->type)]); + njs_atom_to_value(vm, retval, + tags[njs_typed_array_index(njs_typed_array(this)->type)]); return NJS_OK; } @@ -2062,11 +2047,15 @@ njs_typed_array_to_chain(njs_vm_t *vm, njs_chb_t *chain, uint32_t i; njs_string_prop_t separator; - if (sep == NULL) { - sep = njs_value_arg(&njs_string_comma); + if (sep != NULL && njs_is_string(sep)) { + (void) njs_string_prop(vm, &separator, sep); + + } else { + separator.start = (u_char *) ","; + separator.size = 1; + separator.length = 1; } - (void) njs_string_prop(&separator, sep); length = njs_typed_array_length(array); @@ -2110,10 +2099,7 @@ njs_typed_array_prototype_join(njs_vm_t *vm, njs_value_t *args, separator = njs_arg(args, nargs, 1); if (njs_slow_path(!njs_is_string(separator))) { - if (njs_is_undefined(separator)) { - separator = njs_value_arg(&njs_string_comma); - - } else { + if (njs_is_defined(separator)) { ret = njs_value_to_string(vm, separator, separator); if (njs_slow_path(ret != NJS_OK)) { return ret; @@ -2122,7 +2108,7 @@ njs_typed_array_prototype_join(njs_vm_t *vm, njs_value_t *args, } if (length == 0) { - njs_value_assign(retval, &njs_string_empty); + njs_set_empty_string(vm, retval); return NJS_OK; } @@ -2176,26 +2162,20 @@ njs_typed_array_constructor_intrinsic(njs_vm_t *vm, njs_value_t *args, } -static const njs_object_prop_t njs_typed_array_constructor_props[] = +static const njs_object_prop_init_t njs_typed_array_constructor_props[] = { NJS_DECLARE_PROP_LENGTH(0), NJS_DECLARE_PROP_NAME("TypedArray"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), - { - .type = NJS_ACCESSOR, - .name = njs_wellknown_symbol(NJS_SYMBOL_SPECIES), - .u.accessor = njs_getter(njs_typed_array_get_this, 0), - .writable = NJS_ATTRIBUTE_UNSET, - .configurable = 1, - .enumerable = 0, - }, + NJS_DECLARE_PROP_GETTER(SYMBOL_species, njs_typed_array_get_this, 0), - NJS_DECLARE_PROP_NATIVE("of", njs_typed_array_of, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_of, njs_typed_array_of, 0, 0), - NJS_DECLARE_PROP_NATIVE("from", njs_typed_array_from, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_from, njs_typed_array_from, 1, 0), }; @@ -2205,118 +2185,120 @@ static const njs_object_init_t njs_typed_array_constructor_init = { }; -static const njs_object_prop_t njs_typed_array_prototype_properties[] = +static const njs_object_prop_init_t njs_typed_array_prototype_properties[] = { - { - .type = NJS_ACCESSOR, - .name = njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG), - .u.accessor = njs_getter(njs_typed_array_get_string_tag, 0), - .writable = NJS_ATTRIBUTE_UNSET, - .configurable = 1, - .enumerable = 0, - }, + NJS_DECLARE_PROP_GETTER(SYMBOL_toStringTag, + njs_typed_array_get_string_tag, 0), - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_GETTER("buffer", njs_typed_array_prototype_buffer, 0), + NJS_DECLARE_PROP_GETTER(STRING_buffer, njs_typed_array_prototype_buffer, + 0), - NJS_DECLARE_PROP_GETTER("byteLength", + NJS_DECLARE_PROP_GETTER(STRING_byteLength, njs_typed_array_prototype_byte_length, 0), - NJS_DECLARE_PROP_GETTER("byteOffset", + NJS_DECLARE_PROP_GETTER(STRING_byteOffset, njs_typed_array_prototype_byte_offset, 0), - NJS_DECLARE_PROP_GETTER("length", njs_typed_array_prototype_length, 0), + NJS_DECLARE_PROP_GETTER(STRING_length, njs_typed_array_prototype_length, + 0), - NJS_DECLARE_PROP_NATIVE("copyWithin", + NJS_DECLARE_PROP_NATIVE(STRING_copyWithin, njs_typed_array_prototype_copy_within, 2, 0), - NJS_DECLARE_PROP_NATIVE("entries", + NJS_DECLARE_PROP_NATIVE(STRING_entries, njs_typed_array_prototype_iterator_obj, 0, NJS_ENUM_BOTH), - NJS_DECLARE_PROP_NATIVE("every", + NJS_DECLARE_PROP_NATIVE(STRING_every, njs_typed_array_prototype_iterator, 1, NJS_ARRAY_EVERY), - NJS_DECLARE_PROP_NATIVE("filter", + NJS_DECLARE_PROP_NATIVE(STRING_filter, njs_typed_array_prototype_iterator, 1, NJS_ARRAY_FILTER), - NJS_DECLARE_PROP_NATIVE("find", + NJS_DECLARE_PROP_NATIVE(STRING_find, njs_typed_array_prototype_iterator, 1, NJS_ARRAY_FIND), - NJS_DECLARE_PROP_NATIVE("findIndex", + NJS_DECLARE_PROP_NATIVE(STRING_findIndex, njs_typed_array_prototype_iterator, 1, NJS_ARRAY_FIND_INDEX), - NJS_DECLARE_PROP_NATIVE("forEach", + NJS_DECLARE_PROP_NATIVE(STRING_forEach, njs_typed_array_prototype_iterator, 1, NJS_ARRAY_FOR_EACH), - NJS_DECLARE_PROP_NATIVE("includes", - njs_typed_array_prototype_index_of, 1, 1), + NJS_DECLARE_PROP_NATIVE(STRING_includes, + njs_typed_array_prototype_index_of, 1, 1), - NJS_DECLARE_PROP_NATIVE("indexOf", - njs_typed_array_prototype_index_of, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_indexOf, + njs_typed_array_prototype_index_of, 1, 0), - NJS_DECLARE_PROP_NATIVE("join", njs_typed_array_prototype_join, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_join, + njs_typed_array_prototype_join, 1, 0), - NJS_DECLARE_PROP_NATIVE("fill", njs_typed_array_prototype_fill, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_fill, + njs_typed_array_prototype_fill, 1, 0), - NJS_DECLARE_PROP_NATIVE("keys", njs_typed_array_prototype_iterator_obj, 0, + NJS_DECLARE_PROP_NATIVE(STRING_keys, + njs_typed_array_prototype_iterator_obj, 0, NJS_ENUM_KEYS), - NJS_DECLARE_PROP_NATIVE("lastIndexOf", + NJS_DECLARE_PROP_NATIVE(STRING_lastIndexOf, njs_typed_array_prototype_index_of, 1, 2), - NJS_DECLARE_PROP_NATIVE("map", + NJS_DECLARE_PROP_NATIVE(STRING_map, njs_typed_array_prototype_iterator, 1, NJS_ARRAY_MAP), - NJS_DECLARE_PROP_NATIVE("reduce", njs_typed_array_prototype_reduce, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_reduce, + njs_typed_array_prototype_reduce, 1, 0), - NJS_DECLARE_PROP_NATIVE("reduceRight", njs_typed_array_prototype_reduce, - 1, 1), + NJS_DECLARE_PROP_NATIVE(STRING_reduceRight, + njs_typed_array_prototype_reduce, 1, 1), - NJS_DECLARE_PROP_NATIVE("reverse", njs_typed_array_prototype_reverse, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_reverse, + njs_typed_array_prototype_reverse, 0, 0), - NJS_DECLARE_PROP_NATIVE("set", njs_typed_array_prototype_set, 2, 0), + NJS_DECLARE_PROP_NATIVE(STRING_set, + njs_typed_array_prototype_set, 2, 0), - NJS_DECLARE_PROP_NATIVE("slice", njs_typed_array_prototype_slice, 2, 1), + NJS_DECLARE_PROP_NATIVE(STRING_slice, + njs_typed_array_prototype_slice, 2, 1), - NJS_DECLARE_PROP_NATIVE("some", + NJS_DECLARE_PROP_NATIVE(STRING_some, njs_typed_array_prototype_iterator, 1, NJS_ARRAY_SOME), - NJS_DECLARE_PROP_NATIVE("sort", njs_typed_array_prototype_sort, 1, 0), + NJS_DECLARE_PROP_NATIVE(STRING_sort, + njs_typed_array_prototype_sort, 1, 0), - NJS_DECLARE_PROP_NATIVE("subarray", njs_typed_array_prototype_slice, 2, 0), + NJS_DECLARE_PROP_NATIVE(STRING_subarray, + njs_typed_array_prototype_slice, 2, 0), - NJS_DECLARE_PROP_NATIVE("toReversed", njs_typed_array_prototype_reverse, 0, - 1), + NJS_DECLARE_PROP_NATIVE(STRING_toReversed, + njs_typed_array_prototype_reverse, 0, 1), - NJS_DECLARE_PROP_NATIVE("toSorted", njs_typed_array_prototype_sort, 1, 1), + NJS_DECLARE_PROP_NATIVE(STRING_toSorted, + njs_typed_array_prototype_sort, 1, 1), - NJS_DECLARE_PROP_NATIVE("toString", njs_array_prototype_to_string, 0, 0), + NJS_DECLARE_PROP_NATIVE(STRING_toString, njs_array_prototype_to_string, + 0, 0), - NJS_DECLARE_PROP_NATIVE("values", njs_typed_array_prototype_iterator_obj, - 0, NJS_ENUM_VALUES), + NJS_DECLARE_PROP_NATIVE(STRING_values, + njs_typed_array_prototype_iterator_obj, 0, + NJS_ENUM_VALUES), - { - .type = NJS_PROPERTY, - .name = njs_wellknown_symbol(NJS_SYMBOL_ITERATOR), - .u.value = njs_native_function2(njs_typed_array_prototype_iterator_obj, - 0, NJS_ENUM_VALUES), - .writable = 1, - .configurable = 1, - }, + NJS_DECLARE_PROP_NATIVE(SYMBOL_iterator, + njs_typed_array_prototype_iterator_obj, 0, + NJS_ENUM_VALUES), }; - static const njs_object_init_t njs_typed_array_prototype_init = { njs_typed_array_prototype_properties, njs_nitems(njs_typed_array_prototype_properties), @@ -2413,13 +2395,14 @@ memory_error: } -static const njs_object_prop_t njs_data_view_constructor_props[] = +static const njs_object_prop_init_t njs_data_view_constructor_props[] = { NJS_DECLARE_PROP_LENGTH(1), NJS_DECLARE_PROP_NAME("DataView"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), }; @@ -2658,74 +2641,71 @@ njs_data_view_prototype_set(njs_vm_t *vm, njs_value_t *args, } -static const njs_object_prop_t njs_data_view_prototype_properties[] = +static const njs_object_prop_init_t njs_data_view_prototype_properties[] = { - { - .type = NJS_PROPERTY, - .name = njs_wellknown_symbol(NJS_SYMBOL_TO_STRING_TAG), - .u.value = njs_string("DataView"), - .configurable = 1, - }, + NJS_DECLARE_PROP_VALUE(SYMBOL_toStringTag, njs_ascii_strval("DataView"), + NJS_OBJECT_PROP_VALUE_C), - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_GETTER("buffer", njs_typed_array_prototype_buffer, 0), + NJS_DECLARE_PROP_GETTER(STRING_buffer, njs_typed_array_prototype_buffer, + 0), - NJS_DECLARE_PROP_GETTER("byteLength", + NJS_DECLARE_PROP_GETTER(STRING_byteLength, njs_typed_array_prototype_byte_length, 0), - NJS_DECLARE_PROP_GETTER("byteOffset", + NJS_DECLARE_PROP_GETTER(STRING_byteOffset, njs_typed_array_prototype_byte_offset, 0), - NJS_DECLARE_PROP_NATIVE("getUint8", njs_data_view_prototype_get, 1, + NJS_DECLARE_PROP_NATIVE(STRING_getUint8, njs_data_view_prototype_get, 1, NJS_OBJ_TYPE_UINT8_ARRAY), - NJS_DECLARE_PROP_NATIVE("getInt8", njs_data_view_prototype_get, 1, + NJS_DECLARE_PROP_NATIVE(STRING_getInt8, njs_data_view_prototype_get, 1, NJS_OBJ_TYPE_INT8_ARRAY), - NJS_DECLARE_PROP_NATIVE("getUint16", njs_data_view_prototype_get, 1, - NJS_OBJ_TYPE_UINT16_ARRAY), + NJS_DECLARE_PROP_NATIVE(STRING_getUint16, njs_data_view_prototype_get, + 1, NJS_OBJ_TYPE_UINT16_ARRAY), - NJS_DECLARE_PROP_NATIVE("getInt16", njs_data_view_prototype_get, 1, + NJS_DECLARE_PROP_NATIVE(STRING_getInt16, njs_data_view_prototype_get, 1, NJS_OBJ_TYPE_INT16_ARRAY), - NJS_DECLARE_PROP_NATIVE("getUint32", njs_data_view_prototype_get, 1, - NJS_OBJ_TYPE_UINT32_ARRAY), + NJS_DECLARE_PROP_NATIVE(STRING_getUint32, njs_data_view_prototype_get, + 1, NJS_OBJ_TYPE_UINT32_ARRAY), - NJS_DECLARE_PROP_NATIVE("getInt32", njs_data_view_prototype_get, 1, + NJS_DECLARE_PROP_NATIVE(STRING_getInt32, njs_data_view_prototype_get, 1, NJS_OBJ_TYPE_INT32_ARRAY), - NJS_DECLARE_PROP_NATIVE("getFloat32", njs_data_view_prototype_get, 1, - NJS_OBJ_TYPE_FLOAT32_ARRAY), + NJS_DECLARE_PROP_NATIVE(STRING_getFloat32, njs_data_view_prototype_get, + 1, NJS_OBJ_TYPE_FLOAT32_ARRAY), - NJS_DECLARE_PROP_NATIVE("getFloat64", njs_data_view_prototype_get, 1, - NJS_OBJ_TYPE_FLOAT64_ARRAY), + NJS_DECLARE_PROP_NATIVE(STRING_getFloat64, njs_data_view_prototype_get, + 1, NJS_OBJ_TYPE_FLOAT64_ARRAY), - NJS_DECLARE_PROP_NATIVE("setUint8", njs_data_view_prototype_set, 2, + NJS_DECLARE_PROP_NATIVE(STRING_setUint8, njs_data_view_prototype_set, 2, NJS_OBJ_TYPE_UINT8_ARRAY), - NJS_DECLARE_PROP_NATIVE("setInt8", njs_data_view_prototype_set, 2, + NJS_DECLARE_PROP_NATIVE(STRING_setInt8, njs_data_view_prototype_set, 2, NJS_OBJ_TYPE_INT8_ARRAY), - NJS_DECLARE_PROP_NATIVE("setUint16", njs_data_view_prototype_set, 2, - NJS_OBJ_TYPE_UINT16_ARRAY), + NJS_DECLARE_PROP_NATIVE(STRING_setUint16, njs_data_view_prototype_set, + 2, NJS_OBJ_TYPE_UINT16_ARRAY), - NJS_DECLARE_PROP_NATIVE("setInt16", njs_data_view_prototype_set, 2, + NJS_DECLARE_PROP_NATIVE(STRING_setInt16, njs_data_view_prototype_set, 2, NJS_OBJ_TYPE_INT16_ARRAY), - NJS_DECLARE_PROP_NATIVE("setUint32", njs_data_view_prototype_set, 2, - NJS_OBJ_TYPE_UINT32_ARRAY), + NJS_DECLARE_PROP_NATIVE(STRING_setUint32, njs_data_view_prototype_set, + 2, NJS_OBJ_TYPE_UINT32_ARRAY), - NJS_DECLARE_PROP_NATIVE("setInt32", njs_data_view_prototype_set, 2, + NJS_DECLARE_PROP_NATIVE(STRING_setInt32, njs_data_view_prototype_set, 2, NJS_OBJ_TYPE_INT32_ARRAY), - NJS_DECLARE_PROP_NATIVE("setFloat32", njs_data_view_prototype_set, 2, - NJS_OBJ_TYPE_FLOAT32_ARRAY), + NJS_DECLARE_PROP_NATIVE(STRING_setFloat32, njs_data_view_prototype_set, + 2, NJS_OBJ_TYPE_FLOAT32_ARRAY), - NJS_DECLARE_PROP_NATIVE("setFloat64", njs_data_view_prototype_set, 2, - NJS_OBJ_TYPE_FLOAT64_ARRAY), + NJS_DECLARE_PROP_NATIVE(STRING_setFloat64, njs_data_view_prototype_set, + 2, NJS_OBJ_TYPE_FLOAT64_ARRAY), }; @@ -2743,16 +2723,17 @@ const njs_object_type_init_t njs_data_view_type_init = { }; -static const njs_object_prop_t njs_typed_array_u8_constructor_props[] = +static const njs_object_prop_init_t njs_typed_array_u8_constructor_props[] = { NJS_DECLARE_PROP_LENGTH(3), NJS_DECLARE_PROP_NAME("Uint8Array"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 1), - 0), + NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT, + njs_value(NJS_NUMBER, 1, 1), 0), }; @@ -2762,14 +2743,14 @@ static const njs_object_init_t njs_typed_array_u8_constructor_init = { }; -static const njs_object_prop_t njs_typed_array_u8_prototype_properties[] = +static const njs_object_prop_init_t njs_typed_array_u8_prototype_properties[] = { - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 1), - 0), + NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT, + njs_value(NJS_NUMBER, 1, 1), 0), }; @@ -2788,21 +2769,18 @@ const njs_object_type_init_t njs_typed_array_u8_type_init = { }; -static const njs_object_prop_t njs_typed_array_u8c_constructor_props[] = +static const njs_object_prop_init_t njs_typed_array_u8c_constructor_props[] = { - { - .type = NJS_PROPERTY, - .name = njs_string("name"), - .u.value = njs_long_string("Uint8ClampedArray"), - .configurable = 1, - }, + NJS_DECLARE_PROP_VALUE(STRING_name, njs_ascii_strval("Uint8ClampedArray"), + NJS_OBJECT_PROP_VALUE_C), NJS_DECLARE_PROP_LENGTH(3), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 1), - 0), + NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT, + njs_value(NJS_NUMBER, 1, 1), 0), }; @@ -2812,14 +2790,14 @@ static const njs_object_init_t njs_typed_array_u8c_constructor_init = { }; -static const njs_object_prop_t njs_typed_array_u8c_prototype_properties[] = +static const njs_object_prop_init_t njs_typed_array_u8c_prototype_properties[] = { - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 1), - 0), + NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT, + njs_value(NJS_NUMBER, 1, 1), 0), }; @@ -2838,16 +2816,17 @@ const njs_object_type_init_t njs_typed_array_u8clamped_type_init = { }; -static const njs_object_prop_t njs_typed_array_i8_constructor_props[] = +static const njs_object_prop_init_t njs_typed_array_i8_constructor_props[] = { NJS_DECLARE_PROP_LENGTH(3), NJS_DECLARE_PROP_NAME("Int8Array"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 1), - 0), + NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT, + njs_value(NJS_NUMBER, 1, 1), 0), }; @@ -2857,14 +2836,14 @@ static const njs_object_init_t njs_typed_array_i8_constructor_init = { }; -static const njs_object_prop_t njs_typed_array_i8_prototype_properties[] = +static const njs_object_prop_init_t njs_typed_array_i8_prototype_properties[] = { - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 1), - 0), + NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT, + njs_value(NJS_NUMBER, 1, 1), 0), }; @@ -2883,16 +2862,17 @@ const njs_object_type_init_t njs_typed_array_i8_type_init = { }; -static const njs_object_prop_t njs_typed_array_u16_constructor_props[] = +static const njs_object_prop_init_t njs_typed_array_u16_constructor_props[] = { NJS_DECLARE_PROP_LENGTH(3), NJS_DECLARE_PROP_NAME("Uint16Array"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 2), - 0), + NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT, + njs_value(NJS_NUMBER, 1, 2), 0), }; @@ -2902,14 +2882,14 @@ static const njs_object_init_t njs_typed_array_u16_constructor_init = { }; -static const njs_object_prop_t njs_typed_array_u16_prototype_properties[] = +static const njs_object_prop_init_t njs_typed_array_u16_prototype_properties[] = { - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 2), - 0), + NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT, + njs_value(NJS_NUMBER, 1, 2), 0), }; @@ -2928,16 +2908,17 @@ const njs_object_type_init_t njs_typed_array_u16_type_init = { }; -static const njs_object_prop_t njs_typed_array_i16_constructor_props[] = +static const njs_object_prop_init_t njs_typed_array_i16_constructor_props[] = { NJS_DECLARE_PROP_LENGTH(3), NJS_DECLARE_PROP_NAME("Int16Array"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 2), - 0), + NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT, + njs_value(NJS_NUMBER, 1, 2), 0), }; @@ -2947,14 +2928,14 @@ static const njs_object_init_t njs_typed_array_i16_constructor_init = { }; -static const njs_object_prop_t njs_typed_array_i16_prototype_properties[] = +static const njs_object_prop_init_t njs_typed_array_i16_prototype_properties[] = { - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 2), - 0), + NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT, + njs_value(NJS_NUMBER, 1, 2), 0), }; @@ -2973,16 +2954,17 @@ const njs_object_type_init_t njs_typed_array_i16_type_init = { }; -static const njs_object_prop_t njs_typed_array_u32_constructor_props[] = +static const njs_object_prop_init_t njs_typed_array_u32_constructor_props[] = { NJS_DECLARE_PROP_LENGTH(3), NJS_DECLARE_PROP_NAME("Uint32Array"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 4), - 0), + NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT, + njs_value(NJS_NUMBER, 1, 4), 0), }; @@ -2992,14 +2974,14 @@ static const njs_object_init_t njs_typed_array_u32_constructor_init = { }; -static const njs_object_prop_t njs_typed_array_u32_prototype_properties[] = +static const njs_object_prop_init_t njs_typed_array_u32_prototype_properties[] = { - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 4), - 0), + NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT, + njs_value(NJS_NUMBER, 1, 4), 0), }; @@ -3018,16 +3000,17 @@ const njs_object_type_init_t njs_typed_array_u32_type_init = { }; -static const njs_object_prop_t njs_typed_array_i32_constructor_props[] = +static const njs_object_prop_init_t njs_typed_array_i32_constructor_props[] = { NJS_DECLARE_PROP_LENGTH(3), NJS_DECLARE_PROP_NAME("Int32Array"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 4), - 0), + NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT, + njs_value(NJS_NUMBER, 1, 4), 0), }; @@ -3037,14 +3020,14 @@ static const njs_object_init_t njs_typed_array_i32_constructor_init = { }; -static const njs_object_prop_t njs_typed_array_i32_prototype_properties[] = +static const njs_object_prop_init_t njs_typed_array_i32_prototype_properties[] = { - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 4), - 0), + NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT, + njs_value(NJS_NUMBER, 1, 4), 0), }; @@ -3063,16 +3046,17 @@ const njs_object_type_init_t njs_typed_array_i32_type_init = { }; -static const njs_object_prop_t njs_typed_array_f32_constructor_props[] = +static const njs_object_prop_init_t njs_typed_array_f32_constructor_props[] = { NJS_DECLARE_PROP_LENGTH(3), NJS_DECLARE_PROP_NAME("Float32Array"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, njs_object_prototype_create, + 0, 0), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 4), - 0), + NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT, + njs_value(NJS_NUMBER, 1, 4), 0), }; @@ -3082,14 +3066,14 @@ static const njs_object_init_t njs_typed_array_f32_constructor_init = { }; -static const njs_object_prop_t njs_typed_array_f32_prototype_properties[] = +static const njs_object_prop_init_t njs_typed_array_f32_prototype_properties[] = { - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 4), - 0), + NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT, + njs_value(NJS_NUMBER, 1, 4), 0), }; @@ -3108,16 +3092,17 @@ const njs_object_type_init_t njs_typed_array_f32_type_init = { }; -static const njs_object_prop_t njs_typed_array_f64_constructor_props[] = +static const njs_object_prop_init_t njs_typed_array_f64_constructor_props[] = { NJS_DECLARE_PROP_LENGTH(3), NJS_DECLARE_PROP_NAME("Float64Array"), - NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), + NJS_DECLARE_PROP_HANDLER(STRING_prototype, + njs_object_prototype_create, 0, 0), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 8), - 0), + NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT, + njs_value(NJS_NUMBER, 1, 8), 0), }; @@ -3127,14 +3112,14 @@ static const njs_object_init_t njs_typed_array_f64_constructor_init = { }; -static const njs_object_prop_t njs_typed_array_f64_prototype_properties[] = +static const njs_object_prop_init_t njs_typed_array_f64_prototype_properties[] = { - NJS_DECLARE_PROP_HANDLER("constructor", - njs_object_prototype_create_constructor, - 0, 0, NJS_OBJECT_PROP_VALUE_CW), + NJS_DECLARE_PROP_HANDLER(STRING_constructor, + njs_object_prototype_create_constructor, 0, + NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 8), - 0), + NJS_DECLARE_PROP_VALUE(STRING_BYTES_PER_ELEMENT, + njs_value(NJS_NUMBER, 1, 8), 0), }; diff --git a/src/njs_value.c b/src/njs_value.c index a575f9af..dcdab5a2 100644 --- a/src/njs_value.c +++ b/src/njs_value.c @@ -9,10 +9,10 @@ static njs_int_t njs_object_property_query(njs_vm_t *vm, - njs_property_query_t *pq, njs_object_t *object, - const njs_value_t *key); + njs_property_query_t *pq, njs_object_t *object, uint32_t atom_id); static njs_int_t njs_array_property_query(njs_vm_t *vm, - njs_property_query_t *pq, njs_array_t *array, uint32_t index); + njs_property_query_t *pq, njs_array_t *array, uint32_t index, + uint32_t atom_id); static njs_int_t njs_typed_array_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_typed_array_t *array, uint32_t index); static njs_int_t njs_string_property_query(njs_vm_t *vm, @@ -29,35 +29,6 @@ const njs_value_t njs_value_zero = njs_value(NJS_NUMBER, 0, 0.0); const njs_value_t njs_value_nan = njs_value(NJS_NUMBER, 0, NAN); const njs_value_t njs_value_invalid = njs_value(NJS_INVALID, 0, 0.0); -const njs_value_t njs_string_empty = njs_string(""); -const njs_value_t njs_string_empty_regexp = - njs_string("(?:)"); -const njs_value_t njs_string_comma = njs_string(","); -const njs_value_t njs_string_null = njs_string("null"); -const njs_value_t njs_string_undefined = njs_string("undefined"); -const njs_value_t njs_string_boolean = njs_string("boolean"); -const njs_value_t njs_string_false = njs_string("false"); -const njs_value_t njs_string_true = njs_string("true"); -const njs_value_t njs_string_number = njs_string("number"); -const njs_value_t njs_string_minus_zero = njs_string("-0"); -const njs_value_t njs_string_minus_infinity = - njs_string("-Infinity"); -const njs_value_t njs_string_plus_infinity = - njs_string("Infinity"); -const njs_value_t njs_string_nan = njs_string("NaN"); -const njs_value_t njs_string_symbol = njs_string("symbol"); -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_type = njs_string("type"); -const njs_value_t njs_string_external = 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"); - - /* * A hint value is 0 for numbers and 1 for strings. The value chooses * method calls order specified by ECMAScript 5.1: "valueOf", "toString" @@ -68,22 +39,16 @@ njs_int_t njs_value_to_primitive(njs_vm_t *vm, njs_value_t *dst, njs_value_t *value, njs_uint_t hint) { - njs_int_t ret; - njs_uint_t tries; - njs_value_t method, retval; - njs_lvlhsh_query_t lhq; - - static const uint32_t hashes[] = { - NJS_VALUE_OF_HASH, - NJS_TO_STRING_HASH, - }; - - static const njs_str_t names[] = { - njs_str("valueOf"), - njs_str("toString"), + njs_int_t ret; + njs_uint_t tries; + njs_value_t method, retval; + njs_flathsh_query_t lhq; + + static const uint32_t atoms[] = { + NJS_ATOM_STRING_valueOf, + NJS_ATOM_STRING_toString, }; - if (njs_is_primitive(value)) { *dst = *value; return NJS_OK; @@ -98,8 +63,7 @@ njs_value_to_primitive(njs_vm_t *vm, njs_value_t *dst, njs_value_t *value, if (njs_is_object(value) && tries < 2) { hint ^= tries++; - lhq.key_hash = hashes[hint]; - lhq.key = names[hint]; + lhq.key_hash = atoms[hint]; ret = njs_object_property(vm, njs_object(value), &lhq, &method); @@ -207,7 +171,7 @@ njs_value_own_enumerate(njs_vm_t *vm, njs_value_t *value, uint32_t flags) dst = values->start; while (k < end) { - ret = njs_value_property(vm, value, k++, dst++); + ret = njs_value_property_val(vm, value, k++, dst++); if (njs_slow_path(ret != NJS_OK)) { return NULL; } @@ -234,7 +198,7 @@ njs_value_own_enumerate(njs_vm_t *vm, njs_value_t *value, uint32_t flags) return NULL; } - ret = njs_value_property(vm, value, k, &entry->start[1]); + ret = njs_value_property_val(vm, value, k, &entry->start[1]); if (njs_slow_path(ret != NJS_OK)) { return NULL; } @@ -265,14 +229,11 @@ njs_value_of(njs_vm_t *vm, njs_value_t *value, njs_value_t *retval) njs_int_t ret; - static const njs_value_t value_of = njs_string("valueOf"); - if (njs_slow_path(!njs_is_object(value))) { return NJS_DECLINED; } - ret = njs_value_property(vm, value, njs_value_arg(&value_of), - retval); + ret = njs_value_property(vm, value, NJS_ATOM_STRING_valueOf, retval); if (njs_slow_path(ret != NJS_OK)) { return ret; } @@ -292,7 +253,7 @@ njs_value_length(njs_vm_t *vm, njs_value_t *value, int64_t *length) njs_string_prop_t string_prop; if (njs_is_string(value)) { - *length = njs_string_prop(&string_prop, value); + *length = njs_string_prop(vm, &string_prop, value); } else if (njs_is_primitive(value)) { *length = 0; @@ -595,15 +556,15 @@ njs_value_is_data_view(const njs_value_t *value) njs_int_t njs_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_value_t *value, - njs_value_t *key) + uint32_t atom_id) { - double num; uint32_t index; njs_int_t ret; + njs_value_t key; njs_object_t *obj; njs_function_t *function; - njs_assert(njs_is_index_or_key(key)); + njs_assert(atom_id != NJS_ATOM_STRING_unknown); switch (value->type) { case NJS_BOOLEAN: @@ -614,11 +575,9 @@ njs_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_value_t *value, break; case NJS_STRING: - if (njs_fast_path(!njs_is_null_or_undefined_or_boolean(key))) { - num = njs_key_to_index(key); - if (njs_fast_path(njs_key_is_integer_index(num, key))) { - return njs_string_property_query(vm, pq, value, num); - } + if (njs_atom_is_number(atom_id)) { + return njs_string_property_query(vm, pq, value, + njs_atom_number(atom_id)); } obj = &vm->string_object; @@ -648,10 +607,10 @@ njs_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_value_t *value, case NJS_UNDEFINED: case NJS_NULL: default: - ret = njs_primitive_value_to_string(vm, &pq->key, key); + ret = njs_atom_to_value(vm, &key, atom_id); if (njs_fast_path(ret == NJS_OK)) { - njs_string_get(&pq->key, &pq->lhq.key); + njs_string_get(vm, &key, &pq->lhq.key); njs_type_error(vm, "cannot get property \"%V\" of %s", &pq->lhq.key, njs_is_null(value) ? "null" : "undefined"); @@ -664,41 +623,24 @@ njs_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_value_t *value, return NJS_ERROR; } - ret = njs_primitive_value_to_key(vm, &pq->key, key); - - if (njs_fast_path(ret == NJS_OK)) { + ret = njs_object_property_query(vm, pq, obj, atom_id); - if (njs_is_symbol(key)) { - pq->lhq.key_hash = njs_symbol_key(key); - pq->lhq.key.start = NULL; - - } else { - njs_string_get(&pq->key, &pq->lhq.key); - - if (pq->lhq.key_hash == 0) { - pq->lhq.key_hash = njs_djb_hash(pq->lhq.key.start, - pq->lhq.key.length); - } - } - - ret = njs_object_property_query(vm, pq, obj, key); - - if (njs_slow_path(ret == NJS_DECLINED && obj->slots != NULL)) { - return njs_external_property_query(vm, pq, value); - } + if (njs_slow_path(ret == NJS_DECLINED && obj->slots != NULL)) { + return njs_external_property_query(vm, pq, value); } return ret; } -static njs_int_t +njs_inline njs_int_t njs_object_property_query(njs_vm_t *vm, njs_property_query_t *pq, - njs_object_t *object, const njs_value_t *key) + njs_object_t *object, uint32_t atom_id) { double num; njs_int_t ret; njs_bool_t own; + njs_value_t key; njs_array_t *array; njs_object_t *proto; njs_object_prop_t *prop; @@ -716,10 +658,24 @@ njs_object_property_query(njs_vm_t *vm, njs_property_query_t *pq, switch (proto->type) { case NJS_ARRAY: array = (njs_array_t *) proto; - num = njs_key_to_index(key); - if (njs_fast_path(njs_key_is_integer_index(num, key))) { - ret = njs_array_property_query(vm, pq, array, num); + if (njs_fast_path(njs_atom_is_number(atom_id))) { + ret = njs_array_property_query(vm, pq, array, + njs_atom_number(atom_id), atom_id); + if (njs_fast_path(ret != NJS_DECLINED)) { + return (ret == NJS_DONE) ? NJS_DECLINED : ret; + } + } + + ret = njs_atom_to_value(vm, &key, atom_id); + if (njs_slow_path(ret != NJS_OK)) { + return ret; + } + + num = njs_key_to_index(&key); + + if (njs_key_is_integer_index(num, &key)) { + ret = njs_array_property_query(vm, pq, array, num, atom_id); if (njs_fast_path(ret != NJS_DECLINED)) { return (ret == NJS_DONE) ? NJS_DECLINED : ret; } @@ -728,12 +684,19 @@ njs_object_property_query(njs_vm_t *vm, njs_property_query_t *pq, break; case NJS_TYPED_ARRAY: - num = njs_key_to_index(key); - if (njs_fast_path(njs_key_is_integer_index(num, key))) { + if (njs_fast_path(njs_atom_is_number(atom_id))) { tarray = (njs_typed_array_t *) proto; - return njs_typed_array_property_query(vm, pq, tarray, num); + return njs_typed_array_property_query(vm, pq, tarray, + njs_atom_number(atom_id)); } + ret = njs_atom_to_value(vm, &key, atom_id); + if (njs_slow_path(ret != NJS_OK)) { + return ret; + } + + num = njs_key_to_index(&key); + if (!isnan(num)) { return NJS_DECLINED; } @@ -746,10 +709,10 @@ njs_object_property_query(njs_vm_t *vm, njs_property_query_t *pq, break; } - num = njs_key_to_index(key); - if (njs_fast_path(njs_key_is_integer_index(num, key))) { + if (njs_fast_path(njs_atom_is_number(atom_id))) { ov = (njs_object_value_t *) proto; - ret = njs_string_property_query(vm, pq, &ov->value, num); + ret = njs_string_property_query(vm, pq, &ov->value, + njs_atom_number(atom_id)); if (njs_fast_path(ret != NJS_DECLINED)) { return ret; } @@ -761,7 +724,9 @@ njs_object_property_query(njs_vm_t *vm, njs_property_query_t *pq, break; } - ret = njs_lvlhsh_find(&proto->hash, &pq->lhq); + pq->lhq.key_hash = atom_id; + + ret = njs_flathsh_unique_find(&proto->hash, &pq->lhq); if (ret == NJS_OK) { prop = pq->lhq.value; @@ -775,8 +740,7 @@ njs_object_property_query(njs_vm_t *vm, njs_property_query_t *pq, } } else { - ret = njs_lvlhsh_find(&proto->shared_hash, &pq->lhq); - + ret = njs_flathsh_unique_find(&proto->shared_hash, &pq->lhq); if (ret == NJS_OK) { return njs_prop_private_copy(vm, pq, proto); } @@ -797,7 +761,7 @@ njs_object_property_query(njs_vm_t *vm, njs_property_query_t *pq, static njs_int_t njs_array_property_query(njs_vm_t *vm, njs_property_query_t *pq, - njs_array_t *array, uint32_t index) + njs_array_t *array, uint32_t index, uint32_t atom_id) { int64_t length; uint64_t size; @@ -858,7 +822,9 @@ njs_array_property_query(njs_vm_t *vm, njs_property_query_t *pq, } } - ret = njs_lvlhsh_find(&array->object.hash, &pq->lhq); + pq->lhq.key_hash = atom_id; + + ret = njs_flathsh_unique_find(&array->object.hash, &pq->lhq); if (ret == NJS_OK) { prop = pq->lhq.value; @@ -901,8 +867,6 @@ prop: prop->type = resized ? NJS_PROPERTY_PLACE_REF : NJS_PROPERTY_REF; } - njs_set_number(&prop->name, index); - prop->writable = 1; prop->enumerable = 1; prop->configurable = 1; @@ -963,7 +927,7 @@ njs_string_property_query(njs_vm_t *vm, njs_property_query_t *pq, slice.start = index; slice.length = 1; - slice.string_length = njs_string_prop(&string, object); + slice.string_length = njs_string_prop(vm, &string, object); if (slice.start < slice.string_length) { /* @@ -979,12 +943,6 @@ njs_string_property_query(njs_vm_t *vm, njs_property_query_t *pq, pq->lhq.value = prop; - if (pq->query != NJS_PROPERTY_QUERY_GET) { - /* pq->lhq.key is used by NJS_VMCODE_PROPERTY_SET for TypeError */ - njs_uint32_to_string(&pq->key, index); - njs_string_get(&pq->key, &pq->lhq.key); - } - return NJS_OK; } @@ -1018,7 +976,6 @@ njs_external_property_query(njs_vm_t *vm, njs_property_query_t *pq, */ njs_prop_magic32(prop) = slots->magic32; - prop->name = pq->key; pq->lhq.value = prop; @@ -1029,7 +986,8 @@ njs_external_property_query(njs_vm_t *vm, njs_property_query_t *pq, switch (pq->query) { case NJS_PROPERTY_QUERY_GET: - return slots->prop_handler(vm, prop, value, NULL, njs_prop_value(prop)); + return slots->prop_handler(vm, prop, pq->lhq.key_hash, value, NULL, + njs_prop_value(prop)); case NJS_PROPERTY_QUERY_SET: if (slots->writable == 0) { @@ -1054,10 +1012,9 @@ njs_external_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_int_t -njs_value_property(njs_vm_t *vm, njs_value_t *value, njs_value_t *key, +njs_value_property(njs_vm_t *vm, njs_value_t *value, uint32_t atom_id, njs_value_t *retval) { - double num; uint32_t index; njs_int_t ret; njs_array_t *array; @@ -1065,16 +1022,8 @@ njs_value_property(njs_vm_t *vm, njs_value_t *value, njs_value_t *key, njs_typed_array_t *tarray; njs_property_query_t pq; - njs_assert(njs_is_index_or_key(key)); - - if (njs_fast_path(njs_is_number(key))) { - num = njs_number(key); - - if (njs_slow_path(!njs_number_is_integer_index(num))) { - goto slow_path; - } - - index = (uint32_t) num; + if (njs_fast_path(njs_atom_is_number(atom_id))) { + index = njs_atom_number(atom_id); if (njs_is_typed_array(value)) { tarray = njs_typed_array(value); @@ -1116,9 +1065,9 @@ njs_value_property(njs_vm_t *vm, njs_value_t *value, njs_value_t *key, slow_path: - njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0, 0); + njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0); - ret = njs_property_query(vm, &pq, value, key); + ret = njs_property_query(vm, &pq, value, atom_id); switch (ret) { @@ -1144,7 +1093,7 @@ slow_path: case NJS_PROPERTY_HANDLER: pq.scratch = *prop; prop = &pq.scratch; - ret = njs_prop_handler(prop)(vm, prop, value, NULL, + ret = njs_prop_handler(prop)(vm, prop, atom_id, value, NULL, njs_prop_value(prop)); if (njs_slow_path(ret != NJS_OK)) { @@ -1185,32 +1134,21 @@ slow_path: njs_int_t -njs_value_property_set(njs_vm_t *vm, njs_value_t *value, njs_value_t *key, +njs_value_property_set(njs_vm_t *vm, njs_value_t *value, uint32_t atom_id, njs_value_t *setval) { - double num; uint32_t index; njs_int_t ret; njs_array_t *array; - njs_value_t retval; - njs_flathsh_elt_t *elt; + njs_value_t retval, key; njs_object_prop_t *prop; njs_typed_array_t *tarray; + njs_flathsh_elt_t *elt; njs_flathsh_descr_t *h; njs_property_query_t pq; - static const njs_str_t length_key = njs_str("length"); - - njs_assert(njs_is_index_or_key(key)); - - if (njs_fast_path(njs_is_number(key))) { - num = njs_number(key); - - if (njs_slow_path(!njs_number_is_integer_index(num))) { - goto slow_path; - } - - index = (uint32_t) num; + if (njs_fast_path(njs_atom_is_number(atom_id))) { + index = njs_atom_number(atom_id); if (njs_is_typed_array(value)) { tarray = njs_typed_array(value); @@ -1249,9 +1187,9 @@ slow_path: return NJS_ERROR; } - njs_property_query_init(&pq, NJS_PROPERTY_QUERY_SET, 0, 0); + njs_property_query_init(&pq, NJS_PROPERTY_QUERY_SET, 0); - ret = njs_property_query(vm, &pq, value, key); + ret = njs_property_query(vm, &pq, value, atom_id); switch (ret) { @@ -1260,7 +1198,7 @@ slow_path: if (njs_is_data_descriptor(prop)) { if (!prop->writable) { - njs_key_string_get(vm, &pq.key, &pq.lhq.key); + njs_atom_string_get(vm, atom_id, &pq.lhq.key); njs_type_error(vm, "Cannot assign to read-only property \"%V\" of %s", &pq.lhq.key, njs_type_string(value->type)); @@ -1273,7 +1211,7 @@ slow_path: value, setval, 1, &retval); } - njs_key_string_get(vm, &pq.key, &pq.lhq.key); + njs_atom_string_get(vm, atom_id, &pq.lhq.key); njs_type_error(vm, "Cannot set property \"%V\" of %s which has only a getter", &pq.lhq.key, njs_type_string(value->type)); @@ -1281,7 +1219,8 @@ slow_path: } if (prop->type == NJS_PROPERTY_HANDLER) { - ret = njs_prop_handler(prop)(vm, prop, value, setval, &retval); + ret = njs_prop_handler(prop)(vm, prop, atom_id, value, + setval, &retval); if (njs_slow_path(ret != NJS_DECLINED)) { return ret; } @@ -1291,10 +1230,8 @@ slow_path: switch (prop->type) { case NJS_PROPERTY: if (njs_is_array(value)) { - if (njs_slow_path(pq.lhq.key_hash == NJS_LENGTH_HASH)) { - if (njs_strstr_eq(&pq.lhq.key, &length_key)) { - return njs_array_length_set(vm, value, prop, setval); - } + if (njs_slow_path(atom_id == NJS_ATOM_STRING_length)) { + return njs_array_length_set(vm, value, prop, setval); } } @@ -1340,7 +1277,7 @@ slow_path: pq.lhq.pool = vm->mem_pool; - int rc = njs_lvlhsh_delete(pq.own_whiteout, &pq.lhq); + int rc = njs_flathsh_unique_delete(pq.own_whiteout, &pq.lhq); if (rc != NJS_OK) { return NJS_ERROR; } @@ -1374,10 +1311,16 @@ slow_path: } if (njs_slow_path(pq.own && njs_is_typed_array(value) - && njs_is_string(key))) + && !njs_atom_is_number(atom_id))) { /* Integer-Indexed Exotic Objects [[DefineOwnProperty]]. */ - if (!isnan(njs_string_to_index(key))) { + + ret = njs_atom_to_value(vm, &key, atom_id); + if (njs_slow_path(ret != NJS_OK)) { + return ret; + } + + if (!isnan(njs_string_to_index(&key))) { return NJS_OK; } } @@ -1394,16 +1337,17 @@ slow_path: goto fail; } - prop = njs_object_prop_alloc(vm, &pq.key, &njs_value_undefined, 1); + prop = njs_object_prop_alloc(vm, &njs_value_undefined, 1); if (njs_slow_path(prop == NULL)) { return NJS_ERROR; } pq.lhq.replace = 0; pq.lhq.value = prop; + pq.lhq.key_hash = atom_id; pq.lhq.pool = vm->mem_pool; - ret = njs_lvlhsh_insert(njs_object_hash(value), &pq.lhq); + ret = njs_flathsh_unique_insert(njs_object_hash(value), &pq.lhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "lvlhsh insert failed"); return NJS_ERROR; @@ -1417,7 +1361,7 @@ found: fail: - njs_key_string_get(vm, &pq.key, &pq.lhq.key); + njs_atom_string_get(vm, atom_id, &pq.lhq.key); njs_type_error(vm, "Cannot add property \"%V\", object is not extensible", &pq.lhq.key); @@ -1426,30 +1370,21 @@ fail: njs_int_t -njs_value_property_delete(njs_vm_t *vm, njs_value_t *value, njs_value_t *key, +njs_value_property_delete(njs_vm_t *vm, njs_value_t *value, uint32_t atom_id, njs_value_t *removed, njs_bool_t thrw) { - double num; uint32_t index; njs_int_t ret; njs_array_t *array; njs_object_prop_t *prop; njs_property_query_t pq; - njs_assert(njs_is_index_or_key(key)); - - if (njs_fast_path(njs_is_number(key))) { + if (njs_fast_path(njs_atom_is_number(atom_id))) { if (njs_slow_path(!(njs_is_fast_array(value)))) { goto slow_path; } - num = njs_number(key); - - if (njs_slow_path(!njs_number_is_integer_index(num))) { - goto slow_path; - } - - index = (uint32_t) num; + index = (uint32_t) njs_atom_number(atom_id); array = njs_array(value); @@ -1464,9 +1399,9 @@ njs_value_property_delete(njs_vm_t *vm, njs_value_t *value, njs_value_t *key, slow_path: - njs_property_query_init(&pq, NJS_PROPERTY_QUERY_DELETE, 0, 1); + njs_property_query_init(&pq, NJS_PROPERTY_QUERY_DELETE, 1); - ret = njs_property_query(vm, &pq, value, key); + ret = njs_property_query(vm, &pq, value, atom_id); if (njs_slow_path(ret != NJS_OK)) { return ret; } @@ -1475,7 +1410,7 @@ slow_path: if (njs_slow_path(!prop->configurable)) { if (thrw) { - njs_key_string_get(vm, &pq.key, &pq.lhq.key); + njs_atom_string_get(vm, atom_id, &pq.lhq.key); njs_type_error(vm, "Cannot delete property \"%V\" of %s", &pq.lhq.key, njs_type_string(value->type)); return NJS_ERROR; @@ -1487,7 +1422,8 @@ slow_path: switch (prop->type) { case NJS_PROPERTY_HANDLER: if (njs_is_object(value) && njs_object_slots(value) != NULL) { - ret = njs_prop_handler(prop)(vm, prop, value, NULL, NULL); + ret = njs_prop_handler(prop)(vm, prop, atom_id, value, NULL, + NULL); if (njs_slow_path(ret != NJS_DECLINED)) { return ret; } @@ -1550,16 +1486,22 @@ njs_primitive_value_to_string(njs_vm_t *vm, njs_value_t *dst, switch (src->type) { case NJS_NULL: - value = &njs_string_null; - break; + njs_atom_to_value(vm, dst, NJS_ATOM_STRING_null); + return NJS_OK; case NJS_UNDEFINED: - value = &njs_string_undefined; - break; + njs_atom_to_value(vm, dst, NJS_ATOM_STRING_undefined); + return NJS_OK; case NJS_BOOLEAN: - value = njs_is_true(src) ? &njs_string_true : &njs_string_false; - break; + if (njs_is_true(src)) { + njs_atom_to_value(vm, dst, NJS_ATOM_STRING_true); + + } else { + njs_atom_to_value(vm, dst, NJS_ATOM_STRING_false); + } + + return NJS_OK; case NJS_NUMBER: return njs_number_to_string(vm, dst, src); @@ -1616,7 +1558,7 @@ njs_primitive_value_to_chain(njs_vm_t *vm, njs_chb_t *chain, return NJS_ERROR; case NJS_STRING: - (void) njs_string_prop(&string, src); + (void) njs_string_prop(vm, &string, src); njs_chb_append(chain, string.start, string.size); return string.length; @@ -1712,11 +1654,7 @@ njs_value_species_constructor(njs_vm_t *vm, njs_value_t *object, njs_int_t ret; njs_value_t constructor, retval; - static const njs_value_t string_constructor = njs_string("constructor"); - static const njs_value_t string_species = - njs_wellknown_symbol(NJS_SYMBOL_SPECIES); - - ret = njs_value_property(vm, object, njs_value_arg(&string_constructor), + ret = njs_value_property(vm, object, NJS_ATOM_STRING_constructor, &constructor); if (njs_slow_path(ret == NJS_ERROR)) { return NJS_ERROR; @@ -1731,7 +1669,7 @@ njs_value_species_constructor(njs_vm_t *vm, njs_value_t *object, return NJS_ERROR; } - ret = njs_value_property(vm, &constructor, njs_value_arg(&string_species), + ret = njs_value_property(vm, &constructor, NJS_ATOM_SYMBOL_species, &retval); if (njs_slow_path(ret == NJS_ERROR)) { return NJS_ERROR; @@ -1759,7 +1697,7 @@ default_constructor: njs_int_t -njs_value_method(njs_vm_t *vm, njs_value_t *value, njs_value_t *key, +njs_value_method(njs_vm_t *vm, njs_value_t *value, uint32_t atom_id, njs_value_t *retval) { njs_int_t ret; @@ -1769,7 +1707,7 @@ njs_value_method(njs_vm_t *vm, njs_value_t *value, njs_value_t *key, return ret; } - ret = njs_value_property(vm, value, key, retval); + ret = njs_value_property(vm, value, atom_id, retval); if (njs_slow_path(ret != NJS_OK)) { return (ret == NJS_DECLINED) ? NJS_OK : ret; } diff --git a/src/njs_value.h b/src/njs_value.h index 3751db71..7bc9eff3 100644 --- a/src/njs_value.h +++ b/src/njs_value.h @@ -91,33 +91,18 @@ typedef struct njs_property_next_s njs_property_next_t; union njs_value_s { - /* - * The njs_value_t size is 16 bytes and must be aligned to 16 bytes - * to provide 4 bits to encode scope in njs_index_t. This space is - * used to store short strings. The maximum size of a short string - * is 14 (NJS_STRING_SHORT). If the short_string.size field is 15 - * (NJS_STRING_LONG) then the size is in the long_string.size field - * and the long_string.data field points to a long string. - * - * The number of the string types is limited to 2 types to minimize - * overhead of processing string fields. It is also possible to add - * strings with size from 14 to 254 which size and length are stored in - * the string_size and string_length byte wide fields. This will lessen - * the maximum size of short string to 13. - */ struct { - njs_value_type_t type:8; /* 6 bits */ + uint32_t magic32; + njs_value_type_t type:8; /* 5 bits */ + /* * The truth field is set during value assignment and then can be * quickly tested by logical and conditional operations regardless - * of value type. The truth field coincides with short_string.size - * and short_string.length so when string size and length are zero - * the string's value is false. + * of value type. */ uint8_t truth; uint16_t magic16; - uint32_t magic32; union { double number; @@ -139,30 +124,19 @@ union njs_value_s { } data; struct { - njs_value_type_t type:8; /* 6 bits */ - -#define NJS_STRING_SHORT 14 -#define NJS_STRING_LONG 15 - - uint8_t size:4; - uint8_t length:4; - - u_char start[NJS_STRING_SHORT]; - } short_string; - - struct { - njs_value_type_t type:8; /* 6 bits */ + uint32_t atom_id; + njs_value_type_t type:8; /* 5 bits */ uint8_t truth; - - /* 0xff if data is external string. */ - uint8_t external; - uint8_t _spare; - - uint32_t size; + uint8_t token_type; + uint8_t token_id; njs_string_t *data; - } long_string; + } string; - njs_value_type_t type:8; /* 6 bits */ + struct { + uint32_t atom_id; + njs_value_type_t type:8; /* 5 bits */ + uint8_t truth; + }; }; @@ -177,16 +151,16 @@ typedef struct { njs_exotic_keys_t keys; /* A shared hash of njs_object_prop_t for externals. */ - njs_lvlhsh_t external_shared_hash; + njs_flathsh_t external_shared_hash; } njs_exotic_slots_t; struct njs_object_s { /* A private hash of njs_object_prop_t. */ - njs_lvlhsh_t hash; + njs_flathsh_t hash; /* A shared hash of njs_object_prop_t. */ - njs_lvlhsh_t shared_hash; + njs_flathsh_t shared_hash; njs_object_t *__proto__; njs_exotic_slots_t *slots; @@ -315,10 +289,11 @@ struct njs_object_type_init_s { typedef enum { NJS_PROPERTY = 0, NJS_ACCESSOR, + NJS_PROPERTY_HANDLER, + NJS_PROPERTY_REF, NJS_PROPERTY_PLACE_REF, NJS_PROPERTY_TYPED_ARRAY_REF, - NJS_PROPERTY_HANDLER, NJS_WHITEOUT, } njs_object_prop_type_t; @@ -345,8 +320,6 @@ typedef enum { struct njs_object_prop_s { - njs_value_t name; - union { njs_value_t value; struct { @@ -374,23 +347,28 @@ struct njs_object_prop_s { }; +struct njs_object_prop_init_s { + struct njs_object_prop_s desc; + uint32_t atom_id; +}; + + typedef struct { - njs_lvlhsh_query_t lhq; + njs_flathsh_query_t lhq; uint8_t query; /* scratch is used to get the value of an NJS_PROPERTY_HANDLER property. */ njs_object_prop_t scratch; - njs_value_t key; - njs_lvlhsh_t *own_whiteout; + njs_flathsh_t *own_whiteout; uint8_t temp; uint8_t own; } njs_property_query_t; -#define njs_value(_type, _truth, _number) { \ +#define njs_value(_type, _truth, _number) (njs_value_t) { \ .data = { \ .type = _type, \ .truth = _truth, \ @@ -399,37 +377,26 @@ typedef struct { } -#define njs_wellknown_symbol(key) { \ +#define njs_symval(_sym_id, _s) { \ .data = { \ .type = NJS_SYMBOL, \ .truth = 1, \ - .magic32 = key, \ - .u = { .value = NULL } \ - } \ -} - - -#define njs_string(s) { \ - .short_string = { \ - .type = NJS_STRING, \ - .size = njs_length(s), \ - .length = njs_length(s), \ - .start = s, \ + .magic32 = NJS_ATOM_SYMBOL_ ## _sym_id, \ + .u = { .value = (njs_value_t *) &njs_ascii_strval(_s) } \ } \ } -/* NJS_STRING_LONG is set for both big and little endian platforms. */ - -#define njs_long_string(s) { \ - .long_string = { \ +#define njs_ascii_strval(_s) (njs_value_t) { \ + .string = { \ + .atom_id = NJS_ATOM_STRING_unknown, \ .type = NJS_STRING, \ - .truth = (NJS_STRING_LONG << 4) | NJS_STRING_LONG, \ - .size = njs_length(s), \ + .truth = njs_length(_s) ? 1 : 0, \ .data = & (njs_string_t) { \ - .start = (u_char *) s, \ - .length = njs_length(s), \ - } \ + .start = (u_char *) _s, \ + .length = njs_length(_s), \ + .size = njs_length(_s), \ + }, \ } \ } @@ -446,7 +413,7 @@ typedef struct { } -#define _njs_native_function(_func, _args, _ctor, _magic) { \ +#define _njs_native_function(_func, _args, _ctor, _magic) (njs_value_t) { \ .data = { \ .type = NJS_FUNCTION, \ .truth = 1, \ @@ -464,30 +431,28 @@ typedef struct { _njs_native_function(_function, _args_count, 0, _magic) -#define njs_getter(_function, _magic) \ - { \ - .getter = & (njs_function_t) _njs_function(_function, 0, 0, _magic), \ - .setter = NULL, \ - } +#define njs_getter(_function, _magic) { \ + .getter = & (njs_function_t) _njs_function(_function, 0, 0, _magic), \ + .setter = NULL, \ +} -#define njs_accessor(_getter, _m1, _setter, _m2) \ - { \ - .getter = & (njs_function_t) _njs_function(_getter, 0, 0, _m1), \ - .setter = & (njs_function_t) _njs_function(_setter, 0, 0, _m2), \ - } +#define njs_accessor(_getter, _m1, _setter, _m2) { \ + .getter = & (njs_function_t) _njs_function(_getter, 0, 0, _m1), \ + .setter = & (njs_function_t) _njs_function(_setter, 0, 0, _m2), \ +} #define njs_native_ctor(_function, _args_count, _magic) \ _njs_function(_function, _args_count, 1, _magic) -#define njs_prop_handler2(_handler, _magic16, _magic32) { \ +#define njs_prop_handler2(_handler, _magic16) (njs_value_t) { \ .data = { \ .type = NJS_INVALID, \ .truth = 1, \ .magic16 = _magic16, \ - .magic32 = _magic32, \ + .magic32 = 2, \ .u = { .prop_handler = _handler } \ } \ } @@ -551,50 +516,32 @@ typedef struct { (njs_is_number(value) || njs_is_key(value)) -/* - * The truth field coincides with short_string.size and short_string.length - * so when string size and length are zero the string's value is false and - * otherwise is true. - */ -#define njs_string_truth(value, size) - - -#define njs_string_get(value, str) \ +#define njs_string_get_unsafe(value, str) \ do { \ - if ((value)->short_string.size != NJS_STRING_LONG) { \ - (str)->length = (value)->short_string.size; \ - (str)->start = (u_char *) (value)->short_string.start; \ - \ - } else { \ - (str)->length = (value)->long_string.size; \ - (str)->start = (u_char *) (value)->long_string.data->start; \ - } \ + njs_assert((value)->string.data != NULL); \ + (str)->length = (value)->string.data->size; \ + (str)->start = (u_char *) (value)->string.data->start; \ } while (0) -#define njs_string_short_start(value) \ - (value)->short_string.start - - -#define njs_string_short_set(value, _size, _length) \ - do { \ - (value)->type = NJS_STRING; \ - njs_string_truth(value, _size); \ - (value)->short_string.size = _size; \ - (value)->short_string.length = _length; \ - } while (0) - - -#define njs_string_length_set(value, _length) \ +#define njs_string_get(vm, value, str) \ do { \ - if ((value)->short_string.size != NJS_STRING_LONG) { \ - (value)->short_string.length = length; \ + njs_value_t _dst; \ + \ + njs_assert(njs_is_string(value)); \ + \ + if (njs_slow_path((value)->string.data == NULL)) { \ + njs_assert((value)->atom_id != 0 /* NJS_ATOM_STRING_unknown */); \ + njs_atom_to_value(vm, &_dst, (value)->atom_id); \ + njs_assert(njs_is_string(&_dst)); \ + njs_string_get_unsafe(&_dst, str); \ \ } else { \ - (value)->long_string.data->length = length; \ + njs_string_get_unsafe(value, str); \ } \ } while (0) + #define njs_is_primitive(value) \ ((value)->type <= NJS_STRING) @@ -828,32 +775,6 @@ extern const njs_value_t njs_value_zero; extern const njs_value_t njs_value_nan; extern const njs_value_t njs_value_invalid; -extern const njs_value_t njs_string_empty; -extern const njs_value_t njs_string_empty_regexp; -extern const njs_value_t njs_string_comma; -extern const njs_value_t njs_string_null; -extern const njs_value_t njs_string_undefined; -extern const njs_value_t njs_string_boolean; -extern const njs_value_t njs_string_false; -extern const njs_value_t njs_string_true; -extern const njs_value_t njs_string_number; -extern const njs_value_t njs_string_minus_zero; -extern const njs_value_t njs_string_minus_infinity; -extern const njs_value_t njs_string_plus_infinity; -extern const njs_value_t njs_string_nan; -extern const njs_value_t njs_string_symbol; -extern const njs_value_t njs_string_string; -extern const njs_value_t njs_string_data; -extern const njs_value_t njs_string_type; -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; -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; - - njs_inline void njs_set_boolean(njs_value_t *value, unsigned yn) { @@ -872,15 +793,21 @@ njs_set_number(njs_value_t *value, double num) value->data.u.number = num; value->type = NJS_NUMBER; value->data.truth = njs_is_number_true(num); + value->atom_id = 0 /* NJS_ATOM_STRING_unknown */; } +#define njs_set_empty_string(vm, value) \ + njs_atom_to_value(vm, value, NJS_ATOM_STRING_empty) + + njs_inline void njs_set_int32(njs_value_t *value, int32_t num) { value->data.u.number = num; value->type = NJS_NUMBER; value->data.truth = (num != 0); + value->atom_id = 0 /* NJS_ATOM_STRING_unknown */; } @@ -890,6 +817,7 @@ njs_set_uint32(njs_value_t *value, uint32_t num) value->data.u.number = num; value->type = NJS_NUMBER; value->data.truth = (num != 0); + value->atom_id = 0 /* NJS_ATOM_STRING_unknown */; } @@ -1030,20 +958,18 @@ njs_int_t njs_primitive_value_to_string(njs_vm_t *vm, njs_value_t *dst, const njs_value_t *src); njs_int_t njs_primitive_value_to_chain(njs_vm_t *vm, njs_chb_t *chain, const njs_value_t *src); -double njs_string_to_number(const njs_value_t *value); +double njs_string_to_number(njs_vm_t *vm, const njs_value_t *value); njs_int_t njs_int64_to_string(njs_vm_t *vm, njs_value_t *value, int64_t i64); -njs_bool_t njs_string_eq(const njs_value_t *v1, const njs_value_t *v2); +njs_bool_t njs_string_eq(njs_vm_t *vm, const njs_value_t *v1, + const njs_value_t *v2); njs_int_t njs_property_query(njs_vm_t *vm, njs_property_query_t *pq, - njs_value_t *value, njs_value_t *key); - -njs_int_t njs_value_property(njs_vm_t *vm, njs_value_t *value, - njs_value_t *key, njs_value_t *retval); + njs_value_t *value, uint32_t atom_id); njs_int_t njs_value_property_set(njs_vm_t *vm, njs_value_t *value, - njs_value_t *key, njs_value_t *setval); + uint32_t atom_id, njs_value_t *setval); njs_int_t njs_value_property_delete(njs_vm_t *vm, njs_value_t *value, - njs_value_t *key, njs_value_t *removed, njs_bool_t thrw); + uint32_t atom_id, njs_value_t *removed, njs_bool_t thrw); njs_int_t njs_value_to_object(njs_vm_t *vm, njs_value_t *value); void njs_symbol_conversion_failed(njs_vm_t *vm, njs_bool_t to_string); @@ -1053,16 +979,15 @@ njs_int_t njs_value_construct(njs_vm_t *vm, njs_value_t *constructor, njs_int_t njs_value_species_constructor(njs_vm_t *vm, njs_value_t *object, njs_value_t *default_constructor, njs_value_t *dst); -njs_int_t njs_value_method(njs_vm_t *vm, njs_value_t *value, njs_value_t *key, +njs_int_t njs_value_method(njs_vm_t *vm, njs_value_t *value, uint32_t atom_id, njs_value_t *retval); njs_inline void njs_property_query_init(njs_property_query_t *pq, njs_prop_query_t query, - uint32_t hash, uint8_t own) + uint8_t own) { pq->query = query; - pq->lhq.key_hash = hash; pq->own = own; if (query == NJS_PROPERTY_QUERY_SET) { @@ -1073,15 +998,36 @@ njs_property_query_init(njs_property_query_t *pq, njs_prop_query_t query, } +njs_inline njs_int_t +njs_property_query_val(njs_vm_t *vm, njs_property_query_t *pq, + njs_value_t *value, njs_value_t *key) +{ + njs_int_t ret; + + if (njs_value_atom(key) == 0 /* NJS_ATOM_STRING_unknown */) { + ret = njs_atom_atomize_key(vm, key); + if (ret != NJS_OK) { + return ret; + } + } + + return njs_property_query(vm, pq, value, key->atom_id); +} + + njs_inline njs_int_t njs_value_property_i64(njs_vm_t *vm, njs_value_t *value, int64_t index, njs_value_t *retval) { njs_value_t key; + if (index < 0x80000000) { + return njs_value_property(vm, value, njs_number_atom(index), retval); + } + njs_set_number(&key, index); - return njs_value_property(vm, value, &key, retval); + return njs_value_property_val(vm, value, &key, retval); } @@ -1091,9 +1037,31 @@ njs_value_property_i64_set(njs_vm_t *vm, njs_value_t *value, int64_t index, { njs_value_t key; + if (index < 0x80000000) { + return njs_value_property_set(vm, value, njs_number_atom(index), + setval); + } + njs_set_number(&key, index); - return njs_value_property_set(vm, value, &key, setval); + return njs_value_property_val_set(vm, value, &key, setval); +} + + +njs_inline njs_int_t +njs_value_property_val_delete(njs_vm_t *vm, njs_value_t *value, + njs_value_t *key, njs_value_t *removed, njs_bool_t thrw) +{ + njs_int_t ret; + + if (njs_value_atom(key) == 0 /* NJS_ATOM_STRING_unknown */) { + ret = njs_atom_atomize_key(vm, key); + if (ret != NJS_OK) { + return ret; + } + } + + return njs_value_property_delete(vm, value, key->atom_id, removed, thrw); } @@ -1103,17 +1071,23 @@ njs_value_property_i64_delete(njs_vm_t *vm, njs_value_t *value, int64_t index, { njs_value_t key; + if (index < 0x80000000) { + return njs_value_property_delete(vm, value, njs_number_atom(index), + removed, 1); + } + njs_set_number(&key, index); - return njs_value_property_delete(vm, value, &key, removed, 1); + return njs_value_property_val_delete(vm, value, &key, removed, 1); } njs_inline njs_bool_t -njs_values_same_non_numeric(const njs_value_t *val1, const njs_value_t *val2) +njs_values_same_non_numeric(njs_vm_t *vm, const njs_value_t *val1, + const njs_value_t *val2) { if (njs_is_string(val1)) { - return njs_string_eq(val1, val2); + return njs_string_eq(vm, val1, val2); } if (njs_is_symbol(val1)) { @@ -1125,7 +1099,8 @@ njs_values_same_non_numeric(const njs_value_t *val1, const njs_value_t *val2) njs_inline njs_bool_t -njs_values_strict_equal(const njs_value_t *val1, const njs_value_t *val2) +njs_values_strict_equal(njs_vm_t *vm, const njs_value_t *val1, + const njs_value_t *val2) { if (val1->type != val2->type) { return 0; @@ -1141,12 +1116,12 @@ njs_values_strict_equal(const njs_value_t *val1, const njs_value_t *val2) return (njs_number(val1) == njs_number(val2)); } - return njs_values_same_non_numeric(val1, val2); + return njs_values_same_non_numeric(vm, val1, val2); } njs_inline njs_bool_t -njs_values_same(const njs_value_t *val1, const njs_value_t *val2) +njs_values_same(njs_vm_t *vm, const njs_value_t *val1, const njs_value_t *val2) { double num1, num2; @@ -1177,12 +1152,13 @@ njs_values_same(const njs_value_t *val1, const njs_value_t *val2) return num1 == num2; } - return njs_values_same_non_numeric(val1, val2); + return njs_values_same_non_numeric(vm, val1, val2); } njs_inline njs_bool_t -njs_values_same_zero(const njs_value_t *val1, const njs_value_t *val2) +njs_values_same_zero(njs_vm_t *vm, const njs_value_t *val1, + const njs_value_t *val2) { double num1, num2; @@ -1207,7 +1183,7 @@ njs_values_same_zero(const njs_value_t *val1, const njs_value_t *val2) return num1 == num2; } - return njs_values_same_non_numeric(val1, val2); + return njs_values_same_non_numeric(vm, val1, val2); } diff --git a/src/njs_value_conversion.h b/src/njs_value_conversion.h index 24483aa2..80c08b45 100644 --- a/src/njs_value_conversion.h +++ b/src/njs_value_conversion.h @@ -33,7 +33,7 @@ njs_value_to_number(njs_vm_t *vm, njs_value_t *value, double *dst) *dst = NAN; if (njs_is_string(value)) { - *dst = njs_string_to_number(value); + *dst = njs_string_to_number(vm, value); } return NJS_OK; diff --git a/src/njs_variable.c b/src/njs_variable.c index 85fd235a..78bd2afb 100644 --- a/src/njs_variable.c +++ b/src/njs_variable.c @@ -12,31 +12,31 @@ static njs_declaration_t *njs_variable_scope_function_add(njs_parser_t *parser, njs_parser_scope_t *scope); static njs_parser_scope_t *njs_variable_scope_find(njs_parser_t *parser, - njs_parser_scope_t *scope, uintptr_t unique_id, njs_variable_type_t type); -static njs_variable_t *njs_variable_alloc(njs_vm_t *vm, uintptr_t unique_id, + njs_parser_scope_t *scope, uintptr_t atom_id, njs_variable_type_t type); +static njs_variable_t *njs_variable_alloc(njs_vm_t *vm, uintptr_t atom_id, njs_variable_type_t type); njs_variable_t * njs_variable_add(njs_parser_t *parser, njs_parser_scope_t *scope, - uintptr_t unique_id, njs_variable_type_t type) + uintptr_t atom_id, njs_variable_type_t type) { njs_parser_scope_t *root; - root = njs_variable_scope_find(parser, scope, unique_id, type); + root = njs_variable_scope_find(parser, scope, atom_id, type); if (njs_slow_path(root == NULL)) { njs_parser_ref_error(parser, "scope not found"); return NULL; } - return njs_variable_scope_add(parser, root, scope, unique_id, type, + return njs_variable_scope_add(parser, root, scope, atom_id, type, NJS_INDEX_NONE); } njs_variable_t * njs_variable_function_add(njs_parser_t *parser, njs_parser_scope_t *scope, - uintptr_t unique_id, njs_variable_type_t type) + uintptr_t atom_id, njs_variable_type_t type) { njs_bool_t ctor; njs_variable_t *var; @@ -44,13 +44,13 @@ njs_variable_function_add(njs_parser_t *parser, njs_parser_scope_t *scope, njs_parser_scope_t *root; njs_function_lambda_t *lambda; - root = njs_variable_scope_find(parser, scope, unique_id, type); + root = njs_variable_scope_find(parser, scope, atom_id, type); if (njs_slow_path(root == NULL)) { njs_parser_ref_error(parser, "scope not found"); return NULL; } - var = njs_variable_scope_add(parser, root, scope, unique_id, type, + var = njs_variable_scope_add(parser, root, scope, atom_id, type, NJS_INDEX_ERROR); if (njs_slow_path(var == NULL)) { return NULL; @@ -107,7 +107,7 @@ njs_variable_scope_function_add(njs_parser_t *parser, njs_parser_scope_t *scope) static njs_parser_scope_t * -njs_variable_scope(njs_parser_scope_t *scope, uintptr_t unique_id, +njs_variable_scope(njs_parser_scope_t *scope, uintptr_t atom_id, njs_variable_t **retvar, njs_variable_type_t type) { njs_variable_t *var; @@ -116,7 +116,7 @@ njs_variable_scope(njs_parser_scope_t *scope, uintptr_t unique_id, *retvar = NULL; - var_node.key = unique_id; + var_node.key = atom_id; do { node = njs_rbtree_find(&scope->variables, &var_node.node); @@ -146,14 +146,14 @@ njs_variable_scope(njs_parser_scope_t *scope, uintptr_t unique_id, static njs_parser_scope_t * njs_variable_scope_find(njs_parser_t *parser, njs_parser_scope_t *scope, - uintptr_t unique_id, njs_variable_type_t type) + uintptr_t atom_id, njs_variable_type_t type) { - njs_bool_t module; - njs_variable_t *var; - njs_parser_scope_t *root; - const njs_lexer_entry_t *entry; + njs_str_t entry; + njs_bool_t module; + njs_variable_t *var; + njs_parser_scope_t *root; - root = njs_variable_scope(scope, unique_id, &var, type); + root = njs_variable_scope(scope, atom_id, &var, type); if (njs_slow_path(root == NULL)) { return NULL; } @@ -162,7 +162,7 @@ njs_variable_scope_find(njs_parser_t *parser, njs_parser_scope_t *scope, case NJS_VARIABLE_CONST: case NJS_VARIABLE_LET: if (scope->type == NJS_SCOPE_GLOBAL - && parser->undefined_id == unique_id) + && atom_id == NJS_ATOM_STRING_undefined) { goto failed; } @@ -239,17 +239,16 @@ njs_variable_scope_find(njs_parser_t *parser, njs_parser_scope_t *scope, failed: - entry = njs_lexer_entry(unique_id); + njs_lexer_entry(parser->vm, atom_id, &entry); - njs_parser_syntax_error(parser, "\"%V\" has already been declared", - &entry->name); + njs_parser_syntax_error(parser, "\"%V\" has already been declared", &entry); return NULL; } njs_variable_t * njs_variable_scope_add(njs_parser_t *parser, njs_parser_scope_t *scope, - njs_parser_scope_t *original, uintptr_t unique_id, + njs_parser_scope_t *original, uintptr_t atom_id, njs_variable_type_t type, njs_index_t index) { njs_variable_t *var; @@ -257,7 +256,7 @@ njs_variable_scope_add(njs_parser_t *parser, njs_parser_scope_t *scope, njs_parser_scope_t *root; njs_variable_node_t var_node, *var_node_new; - var_node.key = unique_id; + var_node.key = atom_id; node = njs_rbtree_find(&scope->variables, &var_node.node); @@ -265,7 +264,7 @@ njs_variable_scope_add(njs_parser_t *parser, njs_parser_scope_t *scope, return ((njs_variable_node_t *) node)->variable; } - var = njs_variable_alloc(parser->vm, unique_id, type); + var = njs_variable_alloc(parser->vm, atom_id, type); if (njs_slow_path(var == NULL)) { goto memory_error; } @@ -285,7 +284,7 @@ njs_variable_scope_add(njs_parser_t *parser, njs_parser_scope_t *scope, root->items++; } - var_node_new = njs_variable_node_alloc(parser->vm, var, unique_id); + var_node_new = njs_variable_node_alloc(parser->vm, var, atom_id); if (njs_slow_path(var_node_new == NULL)) { goto memory_error; } @@ -303,13 +302,13 @@ memory_error: njs_variable_t * -njs_label_add(njs_vm_t *vm, njs_parser_scope_t *scope, uintptr_t unique_id) +njs_label_add(njs_vm_t *vm, njs_parser_scope_t *scope, uintptr_t atom_id) { njs_variable_t *label; njs_rbtree_node_t *node; njs_variable_node_t var_node, *var_node_new; - var_node.key = unique_id; + var_node.key = atom_id; node = njs_rbtree_find(&scope->labels, &var_node.node); @@ -317,12 +316,12 @@ njs_label_add(njs_vm_t *vm, njs_parser_scope_t *scope, uintptr_t unique_id) return ((njs_variable_node_t *) node)->variable; } - label = njs_variable_alloc(vm, unique_id, NJS_VARIABLE_CONST); + label = njs_variable_alloc(vm, atom_id, NJS_VARIABLE_CONST); if (njs_slow_path(label == NULL)) { goto memory_error; } - var_node_new = njs_variable_node_alloc(vm, label, unique_id); + var_node_new = njs_variable_node_alloc(vm, label, atom_id); if (njs_slow_path(var_node_new == NULL)) { goto memory_error; } @@ -340,12 +339,12 @@ memory_error: njs_int_t -njs_label_remove(njs_vm_t *vm, njs_parser_scope_t *scope, uintptr_t unique_id) +njs_label_remove(njs_vm_t *vm, njs_parser_scope_t *scope, uintptr_t atom_id) { njs_rbtree_node_t *node; njs_variable_node_t var_node; - var_node.key = unique_id; + var_node.key = atom_id; node = njs_rbtree_find(&scope->labels, &var_node.node); if (njs_slow_path(node == NULL)) { @@ -391,7 +390,7 @@ njs_variable_resolve(njs_vm_t *vm, njs_parser_node_t *node) ref = &node->u.reference; scope = node->scope; - var_node.key = ref->unique_id; + var_node.key = ref->atom_id; do { rb_node = njs_rbtree_find(&scope->variables, &var_node.node); @@ -420,7 +419,7 @@ njs_variable_closure(njs_vm_t *vm, njs_variable_t *var, #define NJS_VAR_MAX_DEPTH 32 njs_parser_scope_t *list[NJS_VAR_MAX_DEPTH]; - ref_node.key = var->unique_id; + ref_node.key = var->atom_id; p = list; @@ -485,7 +484,7 @@ njs_variable_closure(njs_vm_t *vm, njs_variable_t *var, return NJS_INDEX_ERROR; } - parse_node->key = var->unique_id; + parse_node->key = var->atom_id; njs_rbtree_insert(&scope->references, &parse_node->node); } @@ -524,7 +523,7 @@ njs_variable_reference(njs_vm_t *vm, njs_parser_node_t *node) closure = njs_variable_closure_test(node->scope, ref->variable->scope); ref->scope = node->scope; - ref_node.key = ref->unique_id; + ref_node.key = ref->atom_id; rb_node = njs_rbtree_find(&scope->references, &ref_node.node); if (njs_slow_path(rb_node == NULL)) { @@ -557,12 +556,12 @@ njs_variable_reference(njs_vm_t *vm, njs_parser_node_t *node) njs_variable_t * -njs_label_find(njs_vm_t *vm, njs_parser_scope_t *scope, uintptr_t unique_id) +njs_label_find(njs_vm_t *vm, njs_parser_scope_t *scope, uintptr_t atom_id) { njs_rbtree_node_t *node; njs_variable_node_t var_node; - var_node.key = unique_id; + var_node.key = atom_id; do { node = njs_rbtree_find(&scope->labels, &var_node.node); @@ -580,7 +579,7 @@ njs_label_find(njs_vm_t *vm, njs_parser_scope_t *scope, uintptr_t unique_id) static njs_variable_t * -njs_variable_alloc(njs_vm_t *vm, uintptr_t unique_id, njs_variable_type_t type) +njs_variable_alloc(njs_vm_t *vm, uintptr_t atom_id, njs_variable_type_t type) { njs_variable_t *var; @@ -590,7 +589,7 @@ njs_variable_alloc(njs_vm_t *vm, uintptr_t unique_id, njs_variable_type_t type) return NULL; } - var->unique_id = unique_id; + var->atom_id = atom_id; var->type = type; return var; diff --git a/src/njs_variable.h b/src/njs_variable.h index dfcc99f3..2ed5220a 100644 --- a/src/njs_variable.h +++ b/src/njs_variable.h @@ -18,7 +18,7 @@ typedef enum { typedef struct { - uintptr_t unique_id; + uintptr_t atom_id; njs_variable_type_t type:8; /* 3 bits */ njs_bool_t argument; @@ -45,7 +45,7 @@ typedef enum { typedef struct { njs_reference_type_t type; - uintptr_t unique_id; + uintptr_t atom_id; njs_variable_t *variable; njs_parser_scope_t *scope; njs_bool_t not_defined; @@ -60,19 +60,19 @@ typedef struct { njs_variable_t *njs_variable_add(njs_parser_t *parser, - njs_parser_scope_t *scope, uintptr_t unique_id, njs_variable_type_t type); + njs_parser_scope_t *scope, uintptr_t atom_id, njs_variable_type_t type); njs_variable_t *njs_variable_function_add(njs_parser_t *parser, - njs_parser_scope_t *scope, uintptr_t unique_id, njs_variable_type_t type); + njs_parser_scope_t *scope, uintptr_t atom_id, njs_variable_type_t type); njs_variable_t * njs_label_add(njs_vm_t *vm, njs_parser_scope_t *scope, - uintptr_t unique_id); + uintptr_t atom_id); njs_variable_t *njs_label_find(njs_vm_t *vm, njs_parser_scope_t *scope, - uintptr_t unique_id); + uintptr_t atom_id); njs_int_t njs_label_remove(njs_vm_t *vm, njs_parser_scope_t *scope, - uintptr_t unique_id); + uintptr_t atom_id); njs_variable_t *njs_variable_reference(njs_vm_t *vm, njs_parser_node_t *node); njs_variable_t *njs_variable_scope_add(njs_parser_t *parser, njs_parser_scope_t *scope, njs_parser_scope_t *original, - uintptr_t unique_id, njs_variable_type_t type, njs_index_t index); + uintptr_t atom_id, njs_variable_type_t type, njs_index_t index); njs_int_t njs_name_copy(njs_vm_t *vm, njs_str_t *dst, const njs_str_t *src); diff --git a/src/njs_vm.c b/src/njs_vm.c index 43b2ccc2..008f9d04 100644 --- a/src/njs_vm.c +++ b/src/njs_vm.c @@ -138,8 +138,6 @@ njs_vm_create(njs_vm_opt_t *options) } } - vm->symbol_generator = NJS_SYMBOL_KNOWN_MAX; - if (njs_scope_undefined_index(vm, 0) == NJS_INDEX_ERROR) { return NULL; } @@ -222,7 +220,7 @@ njs_vm_compile(njs_vm_t *vm, u_char **start, u_char *end) global_items = (vm->global_scope != NULL) ? vm->global_scope->items : 0; ret = njs_parser_init(vm, &parser, vm->global_scope, &vm->options.file, - *start, end, 0); + *start, end); if (njs_slow_path(ret != NJS_OK)) { return NJS_ERROR; } @@ -330,7 +328,7 @@ njs_vm_compile_module(njs_vm_t *vm, njs_str_t *name, u_char **start, return NULL; } - ret = njs_parser_init(vm, &parser, NULL, name, *start, end, 1); + ret = njs_parser_init(vm, &parser, NULL, name, *start, end); if (njs_slow_path(ret != NJS_OK)) { return NULL; } @@ -419,6 +417,11 @@ njs_vm_clone(njs_vm_t *vm, njs_external_ptr_t external) nvm->trace.data = nvm; nvm->external = external; + nvm->shared_atom_count = vm->atom_id_generator; + + njs_lvlhsh_init(&nvm->atom_hash); + nvm->atom_hash_current = &nvm->atom_hash; + ret = njs_vm_runtime_init(nvm); if (njs_slow_path(ret != NJS_OK)) { goto fail; @@ -495,7 +498,7 @@ njs_vm_runtime_init(njs_vm_t *vm) } njs_lvlhsh_init(&vm->values_hash); - njs_lvlhsh_init(&vm->keywords_hash); + njs_lvlhsh_init(&vm->modules_hash); njs_rbtree_init(&vm->global_symbols, njs_symbol_rbtree_cmp); @@ -874,12 +877,13 @@ njs_vm_value(njs_vm_t *vm, const njs_str_t *path, njs_value_t *retval) return NJS_ERROR; } - ret = njs_string_create(vm, &key, start, size); + ret = njs_atom_string_create(vm, &key, start, size); if (njs_slow_path(ret != NJS_OK)) { return NJS_ERROR; } - ret = njs_value_property(vm, &value, &key, njs_value_arg(retval)); + ret = njs_value_property(vm, &value, key.atom_id, + njs_value_arg(retval)); if (njs_slow_path(ret == NJS_ERROR)) { return ret; } @@ -900,19 +904,20 @@ static njs_int_t njs_vm_bind2(njs_vm_t *vm, const njs_str_t *var_name, njs_object_prop_t *prop, njs_bool_t shared) { - njs_int_t ret; - njs_object_t *global; - njs_lvlhsh_t *hash; - njs_lvlhsh_query_t lhq; + njs_int_t ret; + njs_value_t prop_name; + njs_object_t *global; + njs_flathsh_t *hash; + njs_flathsh_query_t lhq; - ret = njs_string_create(vm, &prop->name, var_name->start, var_name->length); + ret = njs_atom_string_create(vm, &prop_name, var_name->start, + var_name->length); if (njs_slow_path(ret != NJS_OK)) { return NJS_ERROR; } lhq.value = prop; - lhq.key = *var_name; - lhq.key_hash = njs_djb_hash(lhq.key.start, lhq.key.length); + lhq.key_hash = prop_name.atom_id; lhq.replace = 1; lhq.pool = vm->mem_pool; lhq.proto = &njs_object_hash_proto; @@ -920,7 +925,7 @@ njs_vm_bind2(njs_vm_t *vm, const njs_str_t *var_name, njs_object_prop_t *prop, global = &vm->global_object; hash = shared ? &global->shared_hash : &global->hash; - ret = njs_lvlhsh_insert(hash, &lhq); + ret = njs_flathsh_unique_insert(hash, &lhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "lvlhsh insert failed"); return ret; @@ -936,7 +941,7 @@ njs_vm_bind(njs_vm_t *vm, const njs_str_t *var_name, const njs_value_t *value, { njs_object_prop_t *prop; - prop = njs_object_prop_alloc(vm, &njs_value_undefined, value, 1); + prop = njs_object_prop_alloc(vm, value, 1); if (njs_slow_path(prop == NULL)) { return NJS_ERROR; } @@ -952,8 +957,7 @@ njs_vm_bind_handler(njs_vm_t *vm, const njs_str_t *var_name, { njs_object_prop_t *prop; - prop = njs_object_prop_alloc(vm, &njs_string_empty, - &njs_value_invalid, 1); + prop = njs_object_prop_alloc(vm, &njs_value_invalid, 1); if (njs_slow_path(prop == NULL)) { return NJS_ERROR; } @@ -970,9 +974,9 @@ njs_vm_bind_handler(njs_vm_t *vm, const njs_str_t *var_name, void -njs_value_string_get(njs_value_t *value, njs_str_t *dst) +njs_value_string_get(njs_vm_t *vm, njs_value_t *value, njs_str_t *dst) { - njs_string_get(value, dst); + njs_string_get(vm, value, dst); } @@ -1050,13 +1054,21 @@ njs_vm_prop_magic32(njs_object_prop_t *prop) njs_int_t -njs_vm_prop_name(njs_vm_t *vm, njs_object_prop_t *prop, njs_str_t *dst) +njs_vm_prop_name(njs_vm_t *vm, uint32_t atom_id, njs_str_t *dst) { - if (njs_slow_path(!njs_is_string(&prop->name))) { + njs_int_t ret; + njs_value_t prop_name; + + ret = njs_atom_to_value(vm, &prop_name, atom_id); + if (ret != NJS_OK) { return NJS_ERROR; } - njs_string_get(&prop->name, dst); + if (njs_slow_path(!njs_is_string(&prop_name))) { + return NJS_ERROR; + } + + njs_string_get(vm, &prop_name, dst); return NJS_OK; } @@ -1090,7 +1102,7 @@ njs_vm_value_string(njs_vm_t *vm, njs_str_t *dst, njs_value_t *src) && njs_number(src) == 0 && signbit(njs_number(src)))) { - njs_string_get(&njs_string_minus_zero, dst); + *dst = njs_str_value("-0"); return NJS_OK; } @@ -1134,22 +1146,18 @@ njs_value_t * njs_vm_value_enumerate(njs_vm_t *vm, njs_value_t *value, uint32_t flags, njs_value_t *retval) { - njs_int_t ret; - njs_value_t *val; - njs_array_t *keys; - njs_rbtree_t *variables; - njs_rbtree_node_t *rb_node; - njs_variable_node_t *node; - const njs_lexer_entry_t *lex_entry; - - static const njs_str_t njs_this_str = njs_str("this"); + njs_value_t *val; + njs_array_t *keys; + njs_rbtree_t *variables; + njs_rbtree_node_t *rb_node; + njs_variable_node_t *node; keys = njs_value_enumerate(vm, value, flags); if (njs_slow_path(keys == NULL)) { return NULL; } - if (!njs_values_same(value, &vm->global_value) + if (!njs_values_same(vm, value, &vm->global_value) || vm->global_scope == NULL) { goto done; @@ -1163,12 +1171,7 @@ njs_vm_value_enumerate(njs_vm_t *vm, njs_value_t *value, uint32_t flags, while (njs_rbtree_is_there_successor(variables, rb_node)) { node = (njs_variable_node_t *) rb_node; - lex_entry = njs_lexer_entry(node->variable->unique_id); - if (njs_slow_path(lex_entry == NULL)) { - return NULL; - } - - if (njs_strstr_eq(&lex_entry->name, &njs_this_str)) { + if (node->variable->atom_id == NJS_ATOM_STRING_this) { rb_node = njs_rbtree_node_successor(variables, rb_node); continue; } @@ -1178,11 +1181,7 @@ njs_vm_value_enumerate(njs_vm_t *vm, njs_value_t *value, uint32_t flags, return NULL; } - ret = njs_string_create(vm, val, lex_entry->name.start, - lex_entry->name.length); - if (njs_slow_path(ret != NJS_OK)) { - return NULL; - } + njs_atom_to_value(vm, val, node->variable->atom_id); rb_node = njs_rbtree_node_successor(variables, rb_node); } @@ -1215,12 +1214,12 @@ njs_vm_value_own_enumerate(njs_vm_t *vm, njs_value_t *value, uint32_t flags, njs_int_t njs_vm_object_alloc(njs_vm_t *vm, njs_value_t *retval, ...) { - va_list args; - njs_int_t ret; - njs_value_t *name, *value; - njs_object_t *object; - njs_object_prop_t *prop; - njs_lvlhsh_query_t lhq; + va_list args; + njs_int_t ret; + njs_value_t *name, *value; + njs_object_t *object; + njs_object_prop_t *prop; + njs_flathsh_query_t lhq; object = njs_object_alloc(vm); if (njs_slow_path(object == NULL)) { @@ -1248,21 +1247,25 @@ njs_vm_object_alloc(njs_vm_t *vm, njs_value_t *retval, ...) goto done; } - lhq.replace = 0; - lhq.pool = vm->mem_pool; - lhq.proto = &njs_object_hash_proto; - - njs_string_get(name, &lhq.key); - lhq.key_hash = njs_djb_hash(lhq.key.start, lhq.key.length); - - prop = njs_object_prop_alloc(vm, name, value, 1); + prop = njs_object_prop_alloc(vm, value, 1); if (njs_slow_path(prop == NULL)) { goto done; } + if (name->atom_id == NJS_ATOM_STRING_unknown) { + ret = njs_atom_atomize_key(vm, name); + if (ret != NJS_OK) { + goto done; + } + } + lhq.value = prop; + lhq.key_hash = name->atom_id; + lhq.replace = 0; + lhq.pool = vm->mem_pool; + lhq.proto = &njs_object_hash_proto; - ret = njs_lvlhsh_insert(&object->hash, &lhq); + ret = njs_flathsh_unique_insert(&object->hash, &lhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, NULL); goto done; @@ -1357,7 +1360,7 @@ njs_vm_object_prop(njs_vm_t *vm, njs_value_t *value, const njs_str_t *prop, return NULL; } - ret = njs_value_property(vm, value, &key, njs_value_arg(retval)); + ret = njs_value_property_val(vm, value, &key, njs_value_arg(retval)); if (njs_slow_path(ret != NJS_OK)) { return NULL; } @@ -1378,12 +1381,13 @@ njs_vm_object_prop_set(njs_vm_t *vm, njs_value_t *value, const njs_str_t *prop, return NJS_ERROR; } - ret = njs_vm_value_string_create(vm, &key, prop->start, prop->length); + ret = njs_atom_string_create(vm, &key, prop->start, prop->length); if (njs_slow_path(ret != NJS_OK)) { return NJS_ERROR; } - ret = njs_value_property_set(vm, value, &key, njs_value_arg(setval)); + ret = njs_value_property_set(vm, value, key.atom_id, + njs_value_arg(setval)); if (njs_slow_path(ret != NJS_OK)) { return NJS_ERROR; } @@ -1473,8 +1477,6 @@ njs_vm_date_alloc(njs_vm_t *vm, njs_value_t *retval, double time) njs_int_t njs_vm_value_to_string(njs_vm_t *vm, njs_str_t *dst, njs_value_t *src) { - u_char *start; - size_t size; njs_int_t ret; njs_value_t value, stack; @@ -1484,7 +1486,7 @@ njs_vm_value_to_string(njs_vm_t *vm, njs_str_t *dst, njs_value_t *src) if (njs_is_error(src)) { if (njs_is_memory_error(vm, src)) { - njs_string_get(&njs_string_memory_error, dst); + *dst = njs_str_value("MemoryError"); return NJS_OK; } @@ -1503,24 +1505,7 @@ njs_vm_value_to_string(njs_vm_t *vm, njs_str_t *dst, njs_value_t *src) ret = njs_value_to_string(vm, &value, &value); if (njs_fast_path(ret == NJS_OK)) { - size = value.short_string.size; - - if (size != NJS_STRING_LONG) { - start = njs_mp_alloc(vm->mem_pool, size); - if (njs_slow_path(start == NULL)) { - njs_memory_error(vm); - return NJS_ERROR; - } - - memcpy(start, value.short_string.start, size); - - } else { - size = value.long_string.size; - start = value.long_string.data->start; - } - - dst->length = size; - dst->start = start; + njs_string_get(vm, &value, dst); } return ret; @@ -1535,24 +1520,12 @@ njs_vm_value_to_string(njs_vm_t *vm, njs_str_t *dst, njs_value_t *src) const char * njs_vm_value_to_c_string(njs_vm_t *vm, njs_value_t *value) { - u_char *p, *data, *start; + u_char *p, *data; size_t size; njs_assert(njs_is_string(value)); - if (value->short_string.size != NJS_STRING_LONG) { - start = value->short_string.start; - size = value->short_string.size; - - if (size < NJS_STRING_SHORT) { - start[size] = '\0'; - return (const char *) start; - } - - } else { - start = value->long_string.data->start; - size = value->long_string.size; - } + size = value->string.data->size; data = njs_mp_alloc(vm->mem_pool, size + njs_length("\0")); if (njs_slow_path(data == NULL)) { @@ -1560,7 +1533,7 @@ njs_vm_value_to_c_string(njs_vm_t *vm, njs_value_t *value) return NULL; } - p = njs_cpymem(data, start, size); + p = njs_cpymem(data, value->string.data->start, size); *p++ = '\0'; return (const char *) data; @@ -1595,8 +1568,7 @@ njs_value_to_string(njs_vm_t *vm, njs_value_t *dst, njs_value_t *value) njs_int_t njs_vm_value_to_bytes(njs_vm_t *vm, njs_str_t *dst, njs_value_t *src) { - u_char *start; - size_t size, length, offset; + size_t length, offset; njs_int_t ret; njs_value_t value; njs_typed_array_t *array; @@ -1647,24 +1619,8 @@ njs_vm_value_to_bytes(njs_vm_t *vm, njs_str_t *dst, njs_value_t *src) return NJS_ERROR; } - size = value.short_string.size; - - if (size != NJS_STRING_LONG) { - start = njs_mp_alloc(vm->mem_pool, size); - if (njs_slow_path(start == NULL)) { - njs_memory_error(vm); - return NJS_ERROR; - } - - memcpy(start, value.short_string.start, size); - - } else { - size = value.long_string.size; - start = value.long_string.data->start; - } - - dst->length = size; - dst->start = start; + dst->length = value.string.data->size; + dst->start = value.string.data->start; } return ret; @@ -1672,9 +1628,10 @@ njs_vm_value_to_bytes(njs_vm_t *vm, njs_str_t *dst, njs_value_t *src) njs_int_t -njs_vm_string_compare(const njs_value_t *v1, const njs_value_t *v2) +njs_vm_string_compare(njs_vm_t *vm, const njs_value_t *v1, + const njs_value_t *v2) { - return njs_string_cmp(v1, v2); + return njs_string_cmp(vm, v1, v2); } diff --git a/src/njs_vm.h b/src/njs_vm.h index a3f2b5a9..3e21fdf2 100644 --- a/src/njs_vm.h +++ b/src/njs_vm.h @@ -128,7 +128,12 @@ struct njs_vm_s { njs_native_frame_t *top_frame; njs_frame_t *active_frame; - njs_lvlhsh_t keywords_hash; + njs_lvlhsh_t atom_hash_shared; + njs_lvlhsh_t atom_hash; + njs_lvlhsh_t *atom_hash_current; + uint32_t shared_atom_count; + uint32_t atom_id_generator; + njs_lvlhsh_t values_hash; njs_arr_t *modules; @@ -178,7 +183,6 @@ struct njs_vm_s { njs_random_t random; njs_rbtree_t global_symbols; - uint64_t symbol_generator; njs_module_loader_t module_loader; void *module_loader_opaque; @@ -203,21 +207,20 @@ typedef struct { struct njs_vm_shared_s { - njs_lvlhsh_t keywords_hash; njs_lvlhsh_t values_hash; - njs_lvlhsh_t array_instance_hash; - njs_lvlhsh_t string_instance_hash; - njs_lvlhsh_t function_instance_hash; - njs_lvlhsh_t async_function_instance_hash; - njs_lvlhsh_t arrow_instance_hash; - njs_lvlhsh_t arguments_object_instance_hash; - njs_lvlhsh_t regexp_instance_hash; + njs_flathsh_t array_instance_hash; + njs_flathsh_t string_instance_hash; + njs_flathsh_t function_instance_hash; + njs_flathsh_t async_function_instance_hash; + njs_flathsh_t arrow_instance_hash; + njs_flathsh_t arguments_object_instance_hash; + njs_flathsh_t regexp_instance_hash; size_t module_items; njs_lvlhsh_t modules_hash; - njs_lvlhsh_t env_hash; + njs_flathsh_t env_hash; njs_object_t string_object; njs_object_t objects[NJS_OBJECT_MAX]; @@ -261,7 +264,7 @@ extern const njs_str_t njs_entry_native; extern const njs_str_t njs_entry_unknown; extern const njs_str_t njs_entry_anonymous; -extern const njs_lvlhsh_proto_t njs_object_hash_proto; +extern const njs_flathsh_proto_t njs_object_hash_proto; #endif /* _NJS_VM_H_INCLUDED_ */ diff --git a/src/njs_vmcode.c b/src/njs_vmcode.c index dbf7b116..07054f67 100644 --- a/src/njs_vmcode.c +++ b/src/njs_vmcode.c @@ -272,7 +272,22 @@ NEXT_LBL; value2 = &primitive1; } - ret = njs_value_property(vm, value1, value2, retval); + if (value2->atom_id == NJS_ATOM_STRING_unknown) { + num = njs_number(value2); + u32 = (uint32_t) num; + + if (njs_fast_path(u32 == num && (u32 < 0x80000000))) { + value2->atom_id = njs_number_atom(u32); + + } else { + ret = njs_atom_atomize_key(vm, value2); + if (njs_slow_path(ret != NJS_OK)) { + goto error; + } + } + } + + ret = njs_value_property(vm, value1, value2->atom_id, retval); if (njs_slow_path(ret == NJS_ERROR)) { goto error; } @@ -397,7 +412,7 @@ NEXT_LBL; get = (njs_vmcode_prop_get_t *) pc; njs_vmcode_operand(vm, get->value, retval); - ret = njs_value_property(vm, value1, value2, retval); + ret = njs_value_property_val(vm, value1, value2, retval); if (njs_slow_path(ret == NJS_ERROR)) { goto error; } @@ -921,7 +936,7 @@ NEXT_LBL; value2 = &primitive1; } - ret = njs_value_property_delete(vm, value1, value2, NULL, 1); + ret = njs_value_property_val_delete(vm, value1, value2, NULL, 1); if (njs_slow_path(ret == NJS_ERROR)) { goto error; } @@ -951,7 +966,7 @@ NEXT_LBL; njs_vmcode_operand(vm, vmcode->operand3, value2); njs_vmcode_operand(vm, vmcode->operand2, value1); - ret = njs_values_strict_equal(value1, value2); + ret = njs_values_strict_equal(vm, value1, value2); njs_vmcode_operand(vm, vmcode->operand1, retval); njs_set_boolean(retval, ret); @@ -965,7 +980,7 @@ NEXT_LBL; njs_vmcode_operand(vm, vmcode->operand3, value2); njs_vmcode_operand(vm, vmcode->operand2, value1); - ret = njs_values_strict_equal(value1, value2); + ret = njs_values_strict_equal(vm, value1, value2); njs_vmcode_operand(vm, vmcode->operand1, retval); njs_set_boolean(retval, !ret); @@ -1255,7 +1270,22 @@ NEXT_LBL; value2 = &primitive2; } - ret = njs_value_property_set(vm, value1, value2, retval); + if (value2->atom_id == NJS_ATOM_STRING_unknown) { + num = njs_number(value2); + u32 = (uint32_t) num; + + if (njs_fast_path(u32 == num && (u32 < 0x80000000))) { + value2->atom_id = njs_number_atom(u32); + + } else { + ret = njs_atom_atomize_key(vm, value2); + if (njs_slow_path(ret != NJS_OK)) { + goto error; + } + } + } + + ret = njs_value_property_set(vm, value1, value2->atom_id, retval); if (njs_slow_path(ret == NJS_ERROR)) { goto error; } @@ -1280,8 +1310,8 @@ NEXT_LBL; goto error; } - ret = njs_object_prop_define(vm, value1, &name, function, - accessor->type, 0); + ret = njs_object_prop_define_val(vm, value1, &name, function, + accessor->type); if (njs_slow_path(ret != NJS_OK)) { goto error; } @@ -1321,7 +1351,7 @@ NEXT_LBL; njs_vmcode_operand(vm, vmcode->operand3, value2); njs_vmcode_operand(vm, vmcode->operand2, value1); - if (njs_values_strict_equal(value1, value2)) { + if (njs_values_strict_equal(vm, value1, value2)) { equal = (njs_vmcode_equal_jump_t *) pc; ret = equal->offset; @@ -1411,7 +1441,7 @@ NEXT_LBL; value2 = &primitive1; } - ret = njs_value_property(vm, value1, value2, &dst); + ret = njs_value_property_val(vm, value1, value2, &dst); if (njs_slow_path(ret == NJS_ERROR)) { goto error; } @@ -1946,6 +1976,7 @@ njs_vmcode_template_literal(njs_vm_t *vm, njs_value_t *retval) { njs_array_t *array; njs_jump_off_t ret; + njs_value_t arguments[1]; static const njs_function_t concat = { .native = 1, @@ -1956,7 +1987,9 @@ njs_vmcode_template_literal(njs_vm_t *vm, njs_value_t *retval) array = njs_array(retval); - ret = njs_function_call(vm, (njs_function_t *) &concat, &njs_string_empty, + njs_set_empty_string(vm, &arguments[0]); + + ret = njs_function_call(vm, (njs_function_t *) &concat, &arguments[0], array->start, array->length, retval); if (njs_slow_path(ret != NJS_OK)) { return ret; @@ -1991,13 +2024,13 @@ static njs_jump_off_t njs_vmcode_property_init(njs_vm_t *vm, njs_value_t *value, njs_value_t *key, njs_value_t *init) { - double num; - uint32_t index, size; - njs_int_t ret; - njs_array_t *array; - njs_value_t *val, name; - njs_object_prop_t *prop; - njs_lvlhsh_query_t lhq; + double num; + uint32_t index, size; + njs_int_t ret; + njs_array_t *array; + njs_value_t *val, name; + njs_object_prop_t *prop; + njs_flathsh_query_t lhq; switch (value->type) { case NJS_ARRAY: @@ -2035,24 +2068,39 @@ njs_vmcode_property_init(njs_vm_t *vm, njs_value_t *value, njs_value_t *key, break; case NJS_OBJECT: + if (key->type == NJS_STRING) { + if (key->atom_id == NJS_ATOM_STRING_unknown) { + ret = njs_atom_atomize_key(vm, key); + if (ret != NJS_OK) { + return ret; + } + } + } + ret = njs_value_to_key(vm, &name, key); if (njs_slow_path(ret != NJS_OK)) { return NJS_ERROR; } - njs_object_property_key_set(&lhq, &name, 0); - lhq.proto = &njs_object_hash_proto; - lhq.pool = vm->mem_pool; + if (name.atom_id == NJS_ATOM_STRING_unknown) { + ret = njs_atom_atomize_key(vm, &name); + if (ret != NJS_OK) { + return ret; + } + } - prop = njs_object_prop_alloc(vm, &name, init, 1); + prop = njs_object_prop_alloc(vm, init, 1); if (njs_slow_path(prop == NULL)) { return NJS_ERROR; } lhq.value = prop; + lhq.key_hash = name.atom_id; lhq.replace = 1; + lhq.pool = vm->mem_pool; + lhq.proto = &njs_object_hash_proto; - ret = njs_lvlhsh_insert(njs_object_hash(value), &lhq); + ret = njs_flathsh_unique_insert(njs_object_hash(value), &lhq); if (njs_slow_path(ret != NJS_OK)) { njs_internal_error(vm, "lvlhsh insert/replace failed"); return NJS_ERROR; @@ -2076,20 +2124,19 @@ static njs_jump_off_t njs_vmcode_proto_init(njs_vm_t *vm, njs_value_t *value, njs_value_t *unused, njs_value_t *init) { - njs_object_t *obj; - njs_value_t retval; - njs_jump_off_t ret; - njs_object_prop_t *prop; - njs_lvlhsh_query_t lhq; - - lhq.key = njs_str_value("__proto__"); - lhq.key_hash = NJS___PROTO___HASH; + njs_object_t *obj; + njs_value_t retval; + njs_jump_off_t ret; + njs_object_prop_t *prop; + njs_flathsh_query_t lhq; + + lhq.key_hash = NJS_ATOM_STRING___proto__; lhq.proto = &njs_object_hash_proto; lhq.pool = vm->mem_pool; obj = njs_object(value); - ret = njs_lvlhsh_find(&obj->__proto__->shared_hash, &lhq); + ret = njs_flathsh_unique_find(&obj->__proto__->shared_hash, &lhq); if (njs_slow_path(ret != NJS_OK)) { goto fail; } @@ -2100,7 +2147,7 @@ njs_vmcode_proto_init(njs_vm_t *vm, njs_value_t *value, njs_value_t *unused, goto fail; } - ret = njs_prop_handler(prop)(vm, prop, value, init, &retval); + ret = njs_prop_handler(prop)(vm, prop, lhq.key_hash, value, init, &retval); if (njs_slow_path(ret != NJS_OK)) { goto fail; } @@ -2137,9 +2184,9 @@ njs_vmcode_property_in(njs_vm_t *vm, njs_value_t *value, njs_value_t *key, key = &primitive; } - njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0, 0); + njs_property_query_init(&pq, NJS_PROPERTY_QUERY_GET, 0); - ret = njs_property_query(vm, &pq, value, key); + ret = njs_property_query_val(vm, &pq, value, key); if (njs_slow_path(ret == NJS_ERROR)) { return ret; } @@ -2190,8 +2237,6 @@ njs_vmcode_instance_of(njs_vm_t *vm, njs_value_t *object, njs_function_t *function; njs_jump_off_t ret; - static const njs_value_t prototype_string = njs_string("prototype"); - if (!njs_is_function(constructor)) { njs_type_error(vm, "right argument is not callable"); return NJS_ERROR; @@ -2206,8 +2251,8 @@ njs_vmcode_instance_of(njs_vm_t *vm, njs_value_t *object, } if (njs_is_object(object)) { - ret = njs_value_property(vm, constructor, - njs_value_arg(&prototype_string), &value); + ret = njs_value_property(vm, constructor, NJS_ATOM_STRING_prototype, + &value); if (njs_slow_path(ret == NJS_ERROR)) { return ret; @@ -2246,37 +2291,37 @@ njs_vmcode_typeof(njs_vm_t *vm, njs_value_t *value, njs_value_t *retval) { /* ECMAScript 5.1: null, array and regexp are objects. */ - static const njs_value_t *types[NJS_VALUE_TYPE_MAX] = { - &njs_string_object, - &njs_string_undefined, - &njs_string_boolean, - &njs_string_number, - &njs_string_symbol, - &njs_string_string, - &njs_string_data, - &njs_string_external, - &njs_string_invalid, - &njs_string_undefined, - &njs_string_undefined, - &njs_string_undefined, - &njs_string_undefined, - &njs_string_undefined, - &njs_string_undefined, - &njs_string_undefined, - - &njs_string_object, - &njs_string_object, - &njs_string_function, - &njs_string_object, - &njs_string_object, - &njs_string_object, - &njs_string_object, - &njs_string_object, - &njs_string_object, - &njs_string_object, + static const uint32_t types[NJS_VALUE_TYPE_MAX] = { + NJS_ATOM_STRING_object, + NJS_ATOM_STRING_undefined, + NJS_ATOM_STRING_boolean, + NJS_ATOM_STRING_number, + NJS_ATOM_STRING_symbol, + NJS_ATOM_STRING_string, + NJS_ATOM_STRING_data, + NJS_ATOM_STRING_external, + NJS_ATOM_STRING_unknown, + NJS_ATOM_STRING_undefined, + NJS_ATOM_STRING_undefined, + NJS_ATOM_STRING_undefined, + NJS_ATOM_STRING_undefined, + NJS_ATOM_STRING_undefined, + NJS_ATOM_STRING_undefined, + NJS_ATOM_STRING_undefined, + + NJS_ATOM_STRING_object, + NJS_ATOM_STRING_object, + NJS_ATOM_STRING_function, + NJS_ATOM_STRING_object, + NJS_ATOM_STRING_object, + NJS_ATOM_STRING_object, + NJS_ATOM_STRING_object, + NJS_ATOM_STRING_object, + NJS_ATOM_STRING_object, + NJS_ATOM_STRING_object, }; - njs_value_assign(retval, types[value->type]); + njs_atom_to_value(vm, retval, types[value->type]); return sizeof(njs_vmcode_2addr_t); } @@ -2314,8 +2359,8 @@ njs_string_concat(njs_vm_t *vm, njs_value_t *val1, njs_value_t *val2, size_t size, length; njs_string_prop_t string1, string2; - (void) njs_string_prop(&string1, val1); - (void) njs_string_prop(&string2, val2); + (void) njs_string_prop(vm, &string1, val1); + (void) njs_string_prop(vm, &string2, val2); length = string1.length + string2.length; size = string1.size + string2.size; @@ -2358,7 +2403,7 @@ again: if (val1->type == val2->type) { if (njs_is_string(val1)) { - return njs_string_eq(val1, val2); + return njs_string_eq(vm, val1, val2); } if (njs_is_symbol(val1)) { @@ -2392,7 +2437,7 @@ again: /* If "hv" is a string then "lv" can be a numeric or symbol. */ if (njs_is_string(hv)) { return !njs_is_symbol(lv) - && (njs_number(lv) == njs_string_to_number(hv)); + && (njs_number(lv) == njs_string_to_number(vm, hv)); } /* "hv" is an object and "lv" is either a string or a symbol or a numeric. */ @@ -2429,15 +2474,15 @@ njs_primitive_values_compare(njs_vm_t *vm, njs_value_t *val1, njs_value_t *val2) num2 = njs_number(val2); } else { - num2 = njs_string_to_number(val2); + num2 = njs_string_to_number(vm, val2); } } else if (njs_is_numeric(val2)) { - num1 = njs_string_to_number(val1); + num1 = njs_string_to_number(vm, val1); num2 = njs_number(val2); } else { - return (njs_string_cmp(val1, val2) < 0) ? 1 : 0; + return (njs_string_cmp(vm, val1, val2) < 0) ? 1 : 0; } /* NaN and void values are not comparable with anything. */ @@ -2521,8 +2566,6 @@ njs_function_new_object(njs_vm_t *vm, njs_value_t *constructor) njs_function_t *function; njs_jump_off_t ret; - const njs_value_t prototype_string = njs_string("prototype"); - object = njs_object_alloc(vm); if (njs_slow_path(object == NULL)) { return NULL; @@ -2538,8 +2581,7 @@ njs_function_new_object(njs_vm_t *vm, njs_value_t *constructor) constructor = &bound; } - ret = njs_value_property(vm, constructor, njs_value_arg(&prototype_string), - &proto); + ret = njs_value_property(vm, constructor, NJS_ATOM_STRING_prototype, &proto); if (njs_slow_path(ret == NJS_ERROR)) { return NULL; diff --git a/src/test/njs_benchmark.c b/src/test/njs_benchmark.c index 66c4e84b..7f1a7400 100644 --- a/src/test/njs_benchmark.c +++ b/src/test/njs_benchmark.c @@ -728,9 +728,9 @@ njs_benchmark_string(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_str_t s, mode; njs_opaque_value_t value; - njs_value_string_get(njs_arg(args, nargs, 1), &mode); + njs_value_string_get(vm, njs_arg(args, nargs, 1), &mode); - njs_value_string_get(njs_arg(args, nargs, 2), &s); + njs_value_string_get(vm, njs_arg(args, nargs, 2), &s); if (njs_value_to_integer(vm, njs_arg(args, nargs, 3), &n) != NJS_OK) { return NJS_ERROR; diff --git a/src/test/njs_externals_test.c b/src/test/njs_externals_test.c index 33f0020a..8d71aae7 100644 --- a/src/test/njs_externals_test.c +++ b/src/test/njs_externals_test.c @@ -146,7 +146,7 @@ lvlhsh_unit_test_add(njs_mp_t *pool, njs_unit_test_req_t *r, static njs_int_t -njs_unit_test_r_uri(njs_vm_t *vm, njs_object_prop_t *prop, +njs_unit_test_r_uri(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { char *p; @@ -169,8 +169,8 @@ njs_unit_test_r_uri(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t -njs_unit_test_r_a(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *unused, njs_value_t *retval) +njs_unit_test_r_a(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, + njs_value_t *value, njs_value_t *unused2, njs_value_t *retval) { u_char *p; njs_unit_test_req_t *r; @@ -189,8 +189,8 @@ njs_unit_test_r_a(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t -njs_unit_test_r_b(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *unused, njs_value_t *retval) +njs_unit_test_r_b(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, + njs_value_t *value, njs_value_t *unused2, njs_value_t *retval) { njs_value_number_set(retval, njs_vm_prop_magic32(prop)); @@ -199,8 +199,8 @@ njs_unit_test_r_b(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t -njs_unit_test_r_d(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *unused, njs_value_t *retval) +njs_unit_test_r_d(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, + njs_value_t *value, njs_value_t *unused2, njs_value_t *retval) { njs_unit_test_req_t *r; @@ -217,7 +217,7 @@ njs_unit_test_r_d(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t -njs_unit_test_r_host(njs_vm_t *vm, njs_object_prop_t *prop, +njs_unit_test_r_host(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { return njs_vm_value_string_create(vm, retval, (u_char *) "АБВГДЕЁЖЗИЙ", 22); @@ -225,7 +225,7 @@ njs_unit_test_r_host(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t -njs_unit_test_r_buffer(njs_vm_t *vm, njs_object_prop_t *prop, +njs_unit_test_r_buffer(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { return njs_vm_value_buffer_set(vm, retval, (u_char *) "АБВГДЕЁЖЗИЙ", 22); @@ -233,7 +233,7 @@ njs_unit_test_r_buffer(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t -njs_unit_test_r_vars(njs_vm_t *vm, njs_object_prop_t *self, +njs_unit_test_r_vars(njs_vm_t *vm, njs_object_prop_t *self, uint32_t atom_id, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { njs_int_t ret; @@ -247,7 +247,7 @@ njs_unit_test_r_vars(njs_vm_t *vm, njs_object_prop_t *self, return NJS_DECLINED; } - ret = njs_vm_prop_name(vm, self, &lhq.key); + ret = njs_vm_prop_name(vm, atom_id, &lhq.key); if (ret != NJS_OK) { if (setval == NULL && retval != NULL) { /* Get. */ @@ -314,14 +314,14 @@ njs_unit_test_r_vars(njs_vm_t *vm, njs_object_prop_t *self, static njs_int_t -njs_unit_test_r_header(njs_vm_t *vm, njs_object_prop_t *prop, +njs_unit_test_r_header(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t atom_id, njs_value_t *value, njs_value_t *unused, njs_value_t *retval) { njs_int_t ret; njs_str_t h; njs_chb_t chain; - ret = njs_vm_prop_name(vm, prop, &h); + ret = njs_vm_prop_name(vm, atom_id, &h); if (ret == NJS_OK) { NJS_CHB_MP_INIT(&chain, njs_vm_memory_pool(vm)); @@ -640,7 +640,7 @@ njs_unit_test_constructor(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, static njs_int_t -njs_unit_test_error_name(njs_vm_t *vm, njs_object_prop_t *prop, +njs_unit_test_error_name(njs_vm_t *vm, njs_object_prop_t *prop, uint32_t unused, njs_value_t *value, njs_value_t *setval, njs_value_t *retval) { return njs_vm_value_string_create(vm, retval, (u_char *) "ExternalError", @@ -650,7 +650,8 @@ njs_unit_test_error_name(njs_vm_t *vm, njs_object_prop_t *prop, static njs_int_t njs_unit_test_error_message(njs_vm_t *vm, njs_object_prop_t *prop, - njs_value_t *value, njs_value_t *setval, njs_value_t *retval) + uint32_t unused, njs_value_t *value, njs_value_t *setval, + njs_value_t *retval) { return njs_vm_value_string_create(vm, retval, (u_char *) "", 0); } diff --git a/src/test/njs_unit_test.c b/src/test/njs_unit_test.c index 9c935e5b..cc1cc4c9 100644 --- a/src/test/njs_unit_test.c +++ b/src/test/njs_unit_test.c @@ -4172,6 +4172,11 @@ static njs_unit_test_t njs_test[] = { njs_str("var a = [ 1, 2, 3 ]; a[4294967296] = 4; a + a[4294967296]"), njs_str("1,2,34") }, + { njs_str("var x = []; var k = 1;" + "for (var i = 0; i < 32; i++) { k = k * 2; x[k - 2] = k; };" + "k = 1; for (i = 0; i < 32; i++) { k = k * 2; if (x[k - 2] != k) { throw 'error'; } }"), + njs_str("undefined") }, + { njs_str("delete[]['4e9']"), njs_str("true") }, @@ -5880,6 +5885,11 @@ static njs_unit_test_t njs_test[] = " return njs.dump(a) === `${v.name} [1,1,1]`})"), njs_str("true") }, + { njs_str(NJS_TYPED_ARRAY_LIST + ".every(v=>{var a = new v([0]); var desc = Object.getOwnPropertyDescriptor(a, '0');" + " try { Object.defineProperty(a, '1', desc) } catch (e) { return e.name == 'TypeError' }})"), + njs_str("true") }, + { njs_str(NJS_TYPED_ARRAY_LIST ".every(v=>{try {var a = new v([1,1]); Object.defineProperty(a, '1', {configurable:true})} " " catch (e) { return e.message == 'Cannot redefine property: \"1\"'}})"), @@ -14324,6 +14334,9 @@ static njs_unit_test_t njs_test[] = { njs_str("Object.prototype.toString.call()"), njs_str("[object Undefined]") }, + { njs_str("Object.prototype.toString.call().length"), + njs_str("18") }, + { njs_str("Object.prototype.toString.call(undefined)"), njs_str("[object Undefined]") },