diff --git a/src/njs_array.c b/src/njs_array.c index 15a6b6d30..67fadba7a 100644 --- a/src/njs_array.c +++ b/src/njs_array.c @@ -139,6 +139,7 @@ njs_int_t njs_array_convert_to_slow_array(njs_vm_t *vm, njs_array_t *array) { uint32_t i, length; + njs_int_t ret; njs_value_t index, value; njs_object_prop_t *prop; @@ -153,7 +154,10 @@ 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); + ret = njs_uint32_to_string(vm, &index, i); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_ERROR; + } prop = njs_object_property_add(vm, &value, &index, 0); if (njs_slow_path(prop == NULL)) { return NJS_ERROR; @@ -176,8 +180,6 @@ 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"); @@ -787,8 +789,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; @@ -828,10 +830,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); @@ -1603,6 +1609,9 @@ njs_array_prototype_to_reversed(njs_vm_t *vm, njs_value_t *args, } +static const njs_value_t join_string = njs_string("join"); + + 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) @@ -1611,8 +1620,6 @@ njs_array_prototype_to_string(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_value_t value; njs_lvlhsh_query_t lhq; - static const njs_value_t join_string = njs_string("join"); - if (njs_is_object(njs_argument(args, 0))) { njs_object_property_init(&lhq, &join_string, NJS_JOIN_HASH); @@ -2776,7 +2783,10 @@ 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_uint32_to_string(vm, &key, i); + if (njs_slow_path(ret != NJS_OK)) { + goto exception; + } ret = njs_value_property(vm, obj, &key, &p->value); if (njs_slow_path(ret == NJS_ERROR)) { goto exception; diff --git a/src/njs_buffer.c b/src/njs_buffer.c index 07054bf05..5559895f5 100644 --- a/src/njs_buffer.c +++ b/src/njs_buffer.c @@ -337,6 +337,9 @@ njs_buffer_from(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } +static const njs_str_t str_buffer = njs_str("Buffer"); + + static njs_int_t njs_buffer_from_object(njs_vm_t *vm, njs_value_t *value, njs_value_t *retval) { @@ -349,9 +352,6 @@ 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), @@ -2358,6 +2358,9 @@ njs_buffer_prototype_swap(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } +static const njs_value_t string_buffer = njs_string("Buffer"); + + static njs_int_t njs_buffer_prototype_to_json(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval) @@ -2371,8 +2374,6 @@ njs_buffer_prototype_to_json(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, 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; @@ -2660,7 +2661,7 @@ static const njs_object_prop_t njs_buffer_constructor_properties[] = NJS_DECLARE_PROP_NATIVE("allocUnsafe", njs_buffer_alloc_safe, 0, 0), - NJS_DECLARE_PROP_LNATIVE("allocUnsafeSlow", njs_buffer_alloc_safe, 1, 0), + NJS_DECLARE_PROP_NATIVE("allocUnsafeSlow", njs_buffer_alloc_safe, 1, 0), NJS_DECLARE_PROP_NATIVE("byteLength", njs_buffer_byte_length, 1, 0), @@ -2695,9 +2696,9 @@ static const njs_object_prop_t njs_buffer_constants_properties[] = NJS_DECLARE_PROP_VALUE("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("MAX_STRING_LENGTH", + njs_value(NJS_NUMBER, 1, NJS_STRING_MAX_LENGTH), + NJS_OBJECT_PROP_VALUE_E), }; diff --git a/src/njs_builtin.c b/src/njs_builtin.c index 3ff6f5475..7e15aea0f 100644 --- a/src/njs_builtin.c +++ b/src/njs_builtin.c @@ -650,6 +650,12 @@ njs_ext_on(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } +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"); + + 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) @@ -659,11 +665,6 @@ njs_ext_memory_stats(njs_vm_t *vm, njs_object_prop_t *prop, 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; @@ -729,7 +730,12 @@ njs_global_this_prop_handler(njs_vm_t *vm, njs_object_prop_t *prop, return NJS_DECLINED; } + if (njs_slow_path(prop->name.type == NJS_SYMBOL)) { + 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; @@ -954,11 +960,11 @@ static const njs_object_prop_t njs_global_this_object_properties[] = NJS_DECLARE_PROP_NATIVE("encodeURI", njs_string_encode_uri, 1, 0), - NJS_DECLARE_PROP_LNATIVE("encodeURIComponent", njs_string_encode_uri, 1, 1), + NJS_DECLARE_PROP_NATIVE("encodeURIComponent", njs_string_encode_uri, 1, 1), NJS_DECLARE_PROP_NATIVE("decodeURI", njs_string_decode_uri, 1, 0), - NJS_DECLARE_PROP_LNATIVE("decodeURIComponent", njs_string_decode_uri, 1, 1), + NJS_DECLARE_PROP_NATIVE("decodeURIComponent", njs_string_decode_uri, 1, 1), NJS_DECLARE_PROP_NATIVE("atob", njs_string_atob, 1, 0), @@ -1056,7 +1062,7 @@ static const njs_object_prop_t njs_global_this_object_properties[] = { .type = NJS_PROPERTY_HANDLER, - .name = njs_long_string("Uint8ClampedArray"), + .name = njs_string("Uint8ClampedArray"), .u.value = njs_prop_handler2(njs_top_level_constructor, NJS_OBJ_TYPE_UINT8_CLAMPED_ARRAY, NJS_UINT8CLAMPEDARRAY_HASH), @@ -1181,6 +1187,9 @@ static const njs_object_init_t njs_njs_object_init = { }; +static const njs_value_t argv_string = njs_string("argv"); + + 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) @@ -1192,8 +1201,6 @@ njs_process_object_argv(njs_vm_t *vm, njs_object_prop_t *pr, njs_object_prop_t *prop; njs_lvlhsh_query_t lhq; - static const njs_value_t argv_string = njs_string("argv"); - argv = njs_array_alloc(vm, 1, vm->options.argc, 0); if (njs_slow_path(argv == NULL)) { return NJS_ERROR; @@ -1315,6 +1322,9 @@ njs_env_hash_init(njs_vm_t *vm, njs_lvlhsh_t *hash, char **environment) } +static const njs_value_t env_string = njs_string("env"); + + 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) @@ -1324,8 +1334,6 @@ njs_process_object_env(njs_vm_t *vm, njs_object_prop_t *pr, njs_object_prop_t *prop; njs_lvlhsh_query_t lhq; - static const njs_value_t env_string = njs_string("env"); - env = njs_object_alloc(vm); if (njs_slow_path(env == NULL)) { return NJS_ERROR; diff --git a/src/njs_date.c b/src/njs_date.c index cd10abd57..b4c93f37c 100644 --- a/src/njs_date.c +++ b/src/njs_date.c @@ -1439,6 +1439,9 @@ njs_date_prototype_set_fields(njs_vm_t *vm, njs_value_t *args, } +static const njs_value_t to_iso_string = njs_string("toISOString"); + + 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) @@ -1447,8 +1450,6 @@ njs_date_prototype_to_json(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_value_t value; njs_lvlhsh_query_t lhq; - static const njs_value_t to_iso_string = njs_string("toISOString"); - if (njs_is_object(njs_argument(args, 0))) { njs_object_property_init(&lhq, &to_iso_string, NJS_TO_ISO_STRING_HASH); @@ -1494,13 +1495,13 @@ static const njs_object_prop_t njs_date_prototype_properties[] = NJS_DECLARE_PROP_NATIVE("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("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("toLocaleTimeString", + njs_date_prototype_to_string, 0, + NJS_DATE_FMT_TO_TIME_STRING), NJS_DECLARE_PROP_NATIVE("toUTCString", njs_date_prototype_to_string, 0, @@ -1570,26 +1571,26 @@ static const njs_object_prop_t njs_date_prototype_properties[] = 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("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("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("getTimezoneOffset", + njs_date_prototype_get_timezone_offset, 0, 0), NJS_DECLARE_PROP_NATIVE("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("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("setUTCMilliseconds", + njs_date_prototype_set_fields, 1, + njs_date_magic2(NJS_DATE_MSEC, 1, 0)), NJS_DECLARE_PROP_NATIVE("setSeconds", njs_date_prototype_set_fields, 2, diff --git a/src/njs_encoding.c b/src/njs_encoding.c index 98a733383..9e1f9a5ae 100644 --- a/src/njs_encoding.c +++ b/src/njs_encoding.c @@ -154,6 +154,10 @@ njs_text_encoder_encode_utf8(njs_vm_t *vm, njs_string_prop_t *prop, } +static const njs_value_t read_str = njs_string("read"); +static const njs_value_t written_str = njs_string("written"); + + static njs_int_t njs_text_encoder_encode_into(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval) @@ -168,9 +172,6 @@ njs_text_encoder_encode_into(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, 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); @@ -357,6 +358,10 @@ njs_text_decoder_arg_encoding(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } +static const njs_value_t fatal_str = njs_string("fatal"); +static const njs_value_t ignore_bom_str = njs_string("ignoreBOM"); + + static njs_int_t njs_text_decoder_arg_options(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_encoding_decode_t *data) @@ -364,9 +369,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; @@ -400,14 +402,15 @@ njs_text_decoder_arg_options(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } +static const njs_value_t utf8_str = njs_string("utf-8"); + + static njs_int_t njs_text_decoder_encoding(njs_vm_t *vm, njs_object_prop_t *prop, 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; @@ -467,6 +470,9 @@ njs_text_decoder_ignore_bom(njs_vm_t *vm, njs_object_prop_t *prop, } +static const njs_value_t stream_str = njs_string("stream"); + + static njs_int_t njs_text_decoder_decode(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval) @@ -483,8 +489,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; diff --git a/src/njs_error.c b/src/njs_error.c index 376205d72..2590ccad4 100644 --- a/src/njs_error.c +++ b/src/njs_error.c @@ -577,6 +577,10 @@ njs_error_prototype_value_of(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } +static const njs_value_t string_message = njs_string("message"); +static const njs_value_t default_name = njs_string("Error"); + + static njs_int_t njs_error_to_string2(njs_vm_t *vm, njs_value_t *retval, const njs_value_t *error, njs_bool_t want_stack) @@ -588,9 +592,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) { @@ -763,12 +764,13 @@ const njs_object_type_init_t njs_eval_error_type_init = { }; +static const njs_value_t name = njs_string("MemoryError"); + + 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) { diff --git a/src/njs_function.c b/src/njs_function.c index c677be573..cfc4c0984 100644 --- a/src/njs_function.c +++ b/src/njs_function.c @@ -251,8 +251,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; @@ -904,6 +902,9 @@ njs_function_capture_global_closures(njs_vm_t *vm, njs_function_t *function) } +static const njs_value_t proto_string = njs_string("prototype"); + + static njs_value_t * njs_function_property_prototype_set(njs_vm_t *vm, njs_lvlhsh_t *hash, njs_value_t *prototype) @@ -912,8 +913,6 @@ njs_function_property_prototype_set(njs_vm_t *vm, njs_lvlhsh_t *hash, njs_object_prop_t *prop; njs_lvlhsh_query_t lhq; - const njs_value_t proto_string = njs_string("prototype"); - prop = njs_object_prop_alloc(vm, &proto_string, prototype, 0); if (njs_slow_path(prop == NULL)) { return NULL; diff --git a/src/njs_iterator.c b/src/njs_iterator.c index 34bb073eb..9546fbfe3 100644 --- a/src/njs_iterator.c +++ b/src/njs_iterator.c @@ -358,8 +358,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 +379,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)) { @@ -513,8 +517,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 +548,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)) { diff --git a/src/njs_json.c b/src/njs_json.c index 85c5d0e8d..7ae7f7ccc 100644 --- a/src/njs_json.c +++ b/src/njs_json.c @@ -1229,6 +1229,9 @@ njs_json_stringify_iterator(njs_json_stringify_t *stringify, } +static const njs_value_t to_json_string = njs_string("toJSON"); + + static njs_function_t * njs_object_to_json_function(njs_vm_t *vm, njs_value_t *value) { @@ -1236,8 +1239,6 @@ njs_object_to_json_function(njs_vm_t *vm, njs_value_t *value) njs_value_t retval; njs_lvlhsh_query_t lhq; - static const njs_value_t to_json_string = njs_string("toJSON"); - if (njs_is_object(value)) { njs_object_property_init(&lhq, &to_json_string, NJS_TO_JSON_HASH); @@ -1258,6 +1259,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 +1278,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 +1293,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 +1307,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), @@ -1643,6 +1652,9 @@ const njs_object_init_t njs_json_object_init = { }; +static const njs_value_t name_string = njs_string("name"); + + static njs_int_t njs_dump_terminal(njs_json_stringify_t *stringify, njs_chb_t *chain, njs_value_t *value, njs_uint_t console) @@ -1653,8 +1665,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) { @@ -1945,7 +1955,7 @@ 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]"); +static const njs_value_t string_get_set = njs_string("[Getter/Setter]"); njs_int_t diff --git a/src/njs_main.h b/src/njs_main.h index 563065a11..d30c73162 100644 --- a/src/njs_main.h +++ b/src/njs_main.h @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -56,7 +57,6 @@ #include #include -#include #include #include #include diff --git a/src/njs_number.c b/src/njs_number.c index 4ca6456d0..799cfa70e 100644 --- a/src/njs_number.c +++ b/src/njs_number.c @@ -252,20 +252,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); @@ -449,11 +437,11 @@ static const njs_object_prop_t njs_number_constructor_properties[] = NJS_DECLARE_PROP_VALUE("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("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("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), @@ -461,11 +449,11 @@ static const njs_object_prop_t njs_number_constructor_properties[] = NJS_DECLARE_PROP_VALUE("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("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("NEGATIVE_INFINITY", + njs_value(NJS_NUMBER, 1, -INFINITY), 0), NJS_DECLARE_PROP_NATIVE("isFinite", njs_number_is_finite, 1, 0), diff --git a/src/njs_number.h b/src/njs_number.h index 98137a5dd..2ff1844eb 100644 --- a/src/njs_number.h +++ b/src/njs_number.h @@ -168,15 +168,22 @@ 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; + + 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 f2aa46a36..a16556769 100644 --- a/src/njs_object.c +++ b/src/njs_object.c @@ -173,7 +173,6 @@ const njs_lvlhsh_proto_t njs_object_hash_proto 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; @@ -188,23 +187,12 @@ njs_object_hash_test(njs_lvlhsh_query_t *lhq, void *data) /* 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 (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; } @@ -604,7 +592,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++; @@ -634,7 +626,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); @@ -676,7 +672,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; @@ -695,7 +694,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); @@ -714,7 +717,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; @@ -734,7 +737,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; @@ -744,10 +750,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++; } @@ -759,11 +765,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++; @@ -783,14 +793,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); @@ -810,15 +823,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); @@ -1932,6 +1952,9 @@ njs_object_prototype_create(njs_vm_t *vm, njs_object_prop_t *prop, } +static const njs_value_t proto_string = njs_string("prototype"); + + njs_value_t * njs_property_prototype_create(njs_vm_t *vm, njs_lvlhsh_t *hash, njs_object_t *prototype) @@ -1940,8 +1963,6 @@ njs_property_prototype_create(njs_vm_t *vm, njs_lvlhsh_t *hash, njs_object_prop_t *prop; njs_lvlhsh_query_t lhq; - static const njs_value_t proto_string = njs_string("prototype"); - prop = njs_object_prop_alloc(vm, &proto_string, &njs_value_undefined, 0); if (njs_slow_path(prop == NULL)) { return NULL; @@ -1986,20 +2007,20 @@ static const njs_object_prop_t njs_object_constructor_properties[] = NJS_DECLARE_PROP_NATIVE("defineProperty", njs_object_define_property, 3, 0), - NJS_DECLARE_PROP_LNATIVE("defineProperties", - njs_object_define_properties, 2, 0), + NJS_DECLARE_PROP_NATIVE("defineProperties", + njs_object_define_properties, 2, 0), - NJS_DECLARE_PROP_LNATIVE("getOwnPropertyDescriptor", - njs_object_get_own_property_descriptor, 2, 0), + NJS_DECLARE_PROP_NATIVE("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("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("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("getOwnPropertySymbols", + njs_object_get_own_property, 1, NJS_ENUM_SYMBOL), NJS_DECLARE_PROP_NATIVE("getPrototypeOf", njs_object_get_prototype_of, 1, 0), @@ -2019,8 +2040,8 @@ static const njs_object_prop_t njs_object_constructor_properties[] = NJS_DECLARE_PROP_NATIVE("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("preventExtensions", njs_object_prevent_extensions, + 1, 0), NJS_DECLARE_PROP_NATIVE("isExtensible", njs_object_is_extensible, 1, 0), @@ -2185,6 +2206,9 @@ njs_object_prototype_create_constructor(njs_vm_t *vm, njs_object_prop_t *prop, } +static const njs_value_t constructor_string = njs_string("constructor"); + + njs_value_t * njs_property_constructor_set(njs_vm_t *vm, njs_lvlhsh_t *hash, njs_value_t *constructor) @@ -2193,8 +2217,6 @@ njs_property_constructor_set(njs_vm_t *vm, njs_lvlhsh_t *hash, njs_object_prop_t *prop; njs_lvlhsh_query_t lhq; - static const njs_value_t constructor_string = njs_string("constructor"); - prop = njs_object_prop_alloc(vm, &constructor_string, constructor, 1); if (njs_slow_path(prop == NULL)) { return NULL; @@ -2244,26 +2266,26 @@ 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]"); + njs_string("[object Undefined]"); static const njs_value_t njs_object_boolean_string = - njs_long_string("[object Boolean]"); + njs_string("[object Boolean]"); static const njs_value_t njs_object_number_string = - njs_long_string("[object Number]"); + njs_string("[object Number]"); static const njs_value_t njs_object_string_string = - njs_long_string("[object String]"); + njs_string("[object String]"); static const njs_value_t njs_object_object_string = - njs_long_string("[object Object]"); + njs_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]"); + njs_string("[object Function]"); static const njs_value_t njs_object_regexp_string = - njs_long_string("[object RegExp]"); + njs_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_string("[object Arguments]"); njs_int_t @@ -2518,8 +2540,8 @@ static const njs_object_prop_t njs_object_prototype_properties[] = NJS_DECLARE_PROP_NATIVE("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("propertyIsEnumerable", + njs_object_prototype_prop_is_enumerable, 1, 0), NJS_DECLARE_PROP_NATIVE("isPrototypeOf", njs_object_prototype_is_prototype_of, 1, 0), @@ -2538,8 +2560,6 @@ 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; diff --git a/src/njs_object.h b/src/njs_object.h index c6ae14b86..242a30753 100644 --- a/src/njs_object.h +++ b/src/njs_object.h @@ -290,13 +290,13 @@ njs_value_create_data_prop_i64(njs_vm_t *vm, njs_value_t *value, int64_t index, } +static const njs_value_t string_length = njs_string("length"); + njs_inline njs_int_t 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), diff --git a/src/njs_object_prop.c b/src/njs_object_prop.c index c9147bba1..9f8f6502e 100644 --- a/src/njs_object_prop.c +++ b/src/njs_object_prop.c @@ -719,6 +719,9 @@ njs_prop_private_copy(njs_vm_t *vm, njs_property_query_t *pq, } +static const njs_value_t get_string = njs_string("get"); + + static njs_object_prop_t * njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *name, const njs_value_t *desc) @@ -731,8 +734,6 @@ njs_descriptor_prop(njs_vm_t *vm, const njs_value_t *name, njs_object_prop_t *prop; njs_lvlhsh_query_t lhq; - static const njs_value_t get_string = njs_string("get"); - if (!njs_is_object(desc)) { njs_type_error(vm, "property descriptor must be an object"); return NULL; diff --git a/src/njs_object_prop_declare.h b/src/njs_object_prop_declare.h index ecc0801cc..358f8143c 100644 --- a/src/njs_object_prop_declare.h +++ b/src/njs_object_prop_declare.h @@ -18,29 +18,12 @@ } -#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), \ - } - - #define NJS_DECLARE_PROP_NATIVE(_name, _native, _nargs, _magic) \ NJS_DECLARE_PROP_VALUE(_name, \ njs_native_function2(_native, _nargs, _magic), \ 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) \ { \ .type = NJS_PROPERTY_HANDLER, \ diff --git a/src/njs_parser.c b/src/njs_parser.c index 7eb6292e4..74134c62d 100644 --- a/src/njs_parser.c +++ b/src/njs_parser.c @@ -1218,6 +1218,9 @@ njs_parser_primary_expression_test(njs_parser_t *parser, } +static const njs_value_t string_message = njs_string("message"); + + static njs_int_t njs_parser_regexp_literal(njs_parser_t *parser, njs_lexer_token_t *token, njs_queue_link_t *current) @@ -1230,8 +1233,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; @@ -8725,7 +8726,7 @@ 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); } @@ -9210,6 +9211,10 @@ njs_parser_unexpected_token(njs_vm_t *vm, njs_parser_t *parser, } +static const njs_value_t file_name = njs_string("fileName"); +static const njs_value_t line_number = njs_string("lineNumber"); + + static void njs_parser_error(njs_vm_t *vm, njs_object_type_t type, njs_str_t *file, uint32_t line, const char *fmt, va_list args) @@ -9220,9 +9225,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); } diff --git a/src/njs_promise.c b/src/njs_promise.c index 54da0a025..c7bc1ef31 100644 --- a/src/njs_promise.c +++ b/src/njs_promise.c @@ -107,7 +107,7 @@ static njs_int_t njs_promise_perform_race_handler(njs_vm_t *vm, 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"); + njs_string("All promises were rejected"); static njs_promise_t * @@ -391,14 +391,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), + ret = njs_value_property(vm, value, njs_value_arg(&njs_string_ctor), dst); if (njs_slow_path(ret == NJS_ERROR)) { return ret; @@ -545,6 +543,9 @@ njs_promise_reject(njs_vm_t *vm, njs_promise_t *promise, njs_value_t *reason) } +static const njs_value_t string_then = njs_string("then"); + + static njs_int_t njs_promise_invoke_then(njs_vm_t *vm, njs_value_t *promise, njs_value_t *args, njs_int_t nargs, njs_value_t *retval) @@ -552,8 +553,6 @@ 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); if (njs_slow_path(ret != NJS_OK)) { @@ -588,8 +587,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); @@ -701,10 +698,8 @@ 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), + ret = njs_value_property(vm, x, njs_value_arg(&njs_string_ctor), &value); if (njs_slow_path(ret == NJS_ERROR)) { return NULL; @@ -1470,6 +1465,13 @@ njs_promise_perform_all_settled_handler(njs_vm_t *vm, njs_iterator_args_t *args, } +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"); + + static njs_int_t njs_promise_all_settled_element_functions(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t rejected, @@ -1481,12 +1483,6 @@ njs_promise_all_settled_element_functions(njs_vm_t *vm, 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) { diff --git a/src/njs_regexp.c b/src/njs_regexp.c index 1c7cfe87c..2be756562 100644 --- a/src/njs_regexp.c +++ b/src/njs_regexp.c @@ -513,7 +513,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); + regexp->string = njs_string_empty; return regexp; } @@ -548,6 +548,12 @@ njs_regexp_prototype_last_index(njs_vm_t *vm, njs_object_prop_t *unused, } +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"); + + static njs_int_t njs_regexp_prototype_flags(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval) @@ -557,11 +563,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"); @@ -698,6 +699,10 @@ njs_regexp_prototype_source(njs_vm_t *vm, njs_value_t *args, } +static const njs_value_t string_source = njs_string("source"); +static const njs_value_t string_flags = njs_string("flags"); + + static njs_int_t njs_regexp_prototype_to_string(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval) @@ -708,9 +713,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))) { @@ -1008,6 +1010,11 @@ static njs_exotic_slots_t njs_regexp_prototype_exotic_slots = { }; +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"); + + 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 *match_data) @@ -1027,10 +1034,6 @@ njs_regexp_exec_result(njs_vm_t *vm, njs_value_t *r, njs_utf8_t utf8, njs_lvlhsh_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); @@ -1185,8 +1188,8 @@ njs_regexp_exec_result_free(njs_vm_t *vm, njs_array_t *result) 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); } } } @@ -1249,6 +1252,9 @@ njs_regexp_prototype_exec(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } +static const njs_value_t string_exec = njs_string("exec"); + + static njs_int_t njs_regexp_exec(njs_vm_t *vm, njs_value_t *r, njs_value_t *s, unsigned flags, njs_value_t *retval) @@ -1257,8 +1263,6 @@ 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); if (njs_slow_path(ret == NJS_ERROR)) { return NJS_ERROR; @@ -1324,10 +1328,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))) { @@ -1597,6 +1597,9 @@ njs_regexp_prototype_symbol_replace(njs_vm_t *vm, njs_value_t *args, } +static const njs_value_t string_lindex = njs_string("lastIndex"); + + static njs_int_t njs_regexp_prototype_symbol_split(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t unused, njs_value_t *retval) @@ -1616,9 +1619,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))) { diff --git a/src/njs_scope.c b/src/njs_scope.c index 36ba0ec5c..5126a00ca 100644 --- a/src/njs_scope.c +++ b/src/njs_scope.c @@ -167,13 +167,13 @@ 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)) { @@ -182,9 +182,7 @@ njs_scope_value_index(njs_vm_t *vm, const njs_value_t *src, njs_uint_t runtime, 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 +205,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 +225,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 ea22755b7..b87c14adb 100644 --- a/src/njs_string.c +++ b/src/njs_string.c @@ -78,49 +78,22 @@ njs_int_t njs_string_set(njs_vm_t *vm, njs_value_t *value, const u_char *start, uint32_t size) { - u_char *dst; - const u_char *src; njs_string_t *string; value->type = NJS_STRING; - njs_string_truth(value, size); + value->truth = size != 0; - if (size <= NJS_STRING_SHORT) { - value->short_string.size = size; - value->short_string.length = 0; - - dst = value->short_string.start; - src = start; - - while (size != 0) { - /* The maximum size is just 14 bytes. */ - njs_pragma_loop_disable_vectorization; - - *dst++ = *src++; - size--; - } - - } else { - /* - * 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 = 0xff; - value->long_string.size = size; - - string = njs_mp_alloc(vm->mem_pool, sizeof(njs_string_t)); - if (njs_slow_path(string == NULL)) { - njs_memory_error(vm); - return NJS_ERROR; - } + string = njs_mp_alloc(vm->mem_pool, sizeof(njs_string_t)); + if (njs_slow_path(string == NULL)) { + njs_memory_error(vm); + return NJS_ERROR; + } - value->long_string.data = string; + value->string.data = string; - string->start = (u_char *) start; - string->length = 0; - } + string->size = size; + string->start = (u_char *) start; + string->length = 0; return NJS_OK; } @@ -212,23 +185,7 @@ 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; if (size != length && length > NJS_STRING_MAP_STRIDE) { map_offset = njs_string_map_offset(size); @@ -242,9 +199,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) { @@ -266,14 +224,8 @@ 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; - } + size = string->string.data->size; + length = string->string.data->length; return (length == 0) ? size : length; } @@ -285,17 +237,9 @@ njs_string_prop(njs_string_prop_t *string, const njs_value_t *value) size_t size; uintptr_t length; - size = value->short_string.size; - - 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; - } + string->start = (u_char *) value->string.data->start; + size = value->string.data->size; + length = value->string.data->length; string->size = size; string->length = length; @@ -307,32 +251,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; } @@ -601,7 +521,6 @@ 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) { - size_t size; uintptr_t length; njs_object_value_t *ov; @@ -620,15 +539,7 @@ 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; - } - - length = (length == 0) ? size : length; + length = value->string.data->length; } njs_set_number(retval, length); @@ -640,89 +551,40 @@ 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) { - size_t size, length1, length2; - const u_char *start1, *start2; + size_t size, length1, length2; - size = v1->short_string.size; + size = v1->string.data->size; - if (size != v2->short_string.size) { + if (size != v2->string.data->size) { 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; - } + length1 = v1->string.data->length; + length2 = v2->string.data->length; - 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; + if (length1 != 0 && length2 != 0 && length1 != length2) { + return 0; } - return (memcmp(start1, start2, size) == 0); + return (memcmp(v1->string.data->start, v2->string.data->start, size) == 0); } njs_int_t njs_string_cmp(const njs_value_t *v1, const njs_value_t *v2) { - size_t size, size1, size2; - njs_int_t ret; - const u_char *start1, *start2; + size_t size, size1, size2; + njs_int_t ret; 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; - } + size1 = v1->string.data->size; + size2 = v2->string.data->size; size = njs_min(size1, size2); - ret = memcmp(start1, start2, size); + ret = memcmp(v1->string.data->start, v2->string.data->start, size); if (ret != 0) { return ret; @@ -2461,6 +2323,9 @@ njs_string_prototype_repeat(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, } +static const njs_value_t string_space = njs_string(" "); + + static njs_int_t njs_string_prototype_pad(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t pad_start, njs_value_t *retval) @@ -2474,8 +2339,6 @@ 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; @@ -3145,6 +3008,9 @@ njs_string_get_substitution(njs_vm_t *vm, njs_value_t *matched, } +static const njs_value_t string_flags = njs_string("flags"); + + static njs_int_t njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, njs_index_t replaceAll, njs_value_t *retval) @@ -3164,7 +3030,6 @@ njs_string_prototype_replace(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs, 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); @@ -3465,16 +3330,13 @@ 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; - - } else { - size = value->long_string.size; - start = value->long_string.data->start; + if (njs_slow_path(value->type == NJS_SYMBOL)) { + return NAN; } + size = value->string.data->size; + start = value->string.data->start; + p = start; end = p + size; minus = 0; diff --git a/src/njs_string.h b/src/njs_string.h index 9b4788750..a4c40f3de 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; }; diff --git a/src/njs_symbol.c b/src/njs_symbol.c index a284d4e97..c9ce8d8d8 100644 --- a/src/njs_symbol.c +++ b/src/njs_symbol.c @@ -9,17 +9,17 @@ static const njs_value_t njs_symbol_async_iterator_name = - njs_long_string("Symbol.asyncIterator"); + njs_string("Symbol.asyncIterator"); static const njs_value_t njs_symbol_has_instance_name = - njs_long_string("Symbol.hasInstance"); + njs_string("Symbol.hasInstance"); static const njs_value_t njs_symbol_is_concat_spreadable_name = - njs_long_string("Symbol.isConcatSpreadable"); + njs_string("Symbol.isConcatSpreadable"); static const njs_value_t njs_symbol_iterator_name = - njs_long_string("Symbol.iterator"); + njs_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"); + njs_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 = @@ -29,11 +29,11 @@ static const njs_value_t njs_symbol_species_name = 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"); + njs_string("Symbol.toPrimitive"); static const njs_value_t njs_symbol_to_string_tag_name = - njs_long_string("Symbol.toStringTag"); + njs_string("Symbol.toStringTag"); static const njs_value_t njs_symbol_unscopables_name = - njs_long_string("Symbol.unscopables"); + njs_string("Symbol.unscopables"); static const njs_value_t *njs_symbol_names[NJS_SYMBOL_KNOWN_MAX] = { @@ -247,7 +247,7 @@ static const njs_object_prop_t njs_symbol_constructor_properties[] = NJS_DECLARE_PROP_VALUE("hasInstance", njs_wellknown_symbol(NJS_SYMBOL_HAS_INSTANCE), 0), - NJS_DECLARE_PROP_LVALUE("isConcatSpreadable", + NJS_DECLARE_PROP_VALUE("isConcatSpreadable", njs_wellknown_symbol(NJS_SYMBOL_IS_CONCAT_SPREADABLE), 0), NJS_DECLARE_PROP_VALUE("iterator", diff --git a/src/njs_typed_array.c b/src/njs_typed_array.c index 2a485a199..60bd60c69 100644 --- a/src/njs_typed_array.c +++ b/src/njs_typed_array.c @@ -435,7 +435,7 @@ 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"); + njs_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"); @@ -2751,8 +2751,7 @@ static const njs_object_prop_t njs_typed_array_u8_constructor_props[] = NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 1), - 0), + NJS_DECLARE_PROP_VALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 1), 0), }; @@ -2768,8 +2767,7 @@ static const njs_object_prop_t njs_typed_array_u8_prototype_properties[] = njs_object_prototype_create_constructor, 0, 0, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 1), - 0), + NJS_DECLARE_PROP_VALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 1), 0), }; @@ -2793,7 +2791,7 @@ static const njs_object_prop_t njs_typed_array_u8c_constructor_props[] = { .type = NJS_PROPERTY, .name = njs_string("name"), - .u.value = njs_long_string("Uint8ClampedArray"), + .u.value = njs_string("Uint8ClampedArray"), .configurable = 1, }, @@ -2801,8 +2799,7 @@ static const njs_object_prop_t njs_typed_array_u8c_constructor_props[] = NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 1), - 0), + NJS_DECLARE_PROP_VALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 1), 0), }; @@ -2818,8 +2815,7 @@ static const njs_object_prop_t njs_typed_array_u8c_prototype_properties[] = njs_object_prototype_create_constructor, 0, 0, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 1), - 0), + NJS_DECLARE_PROP_VALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 1), 0), }; @@ -2846,8 +2842,7 @@ static const njs_object_prop_t njs_typed_array_i8_constructor_props[] = NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 1), - 0), + NJS_DECLARE_PROP_VALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 1), 0), }; @@ -2863,8 +2858,7 @@ static const njs_object_prop_t njs_typed_array_i8_prototype_properties[] = njs_object_prototype_create_constructor, 0, 0, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 1), - 0), + NJS_DECLARE_PROP_VALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 1), 0), }; @@ -2891,8 +2885,7 @@ static const njs_object_prop_t njs_typed_array_u16_constructor_props[] = NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 2), - 0), + NJS_DECLARE_PROP_VALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 2), 0), }; @@ -2908,8 +2901,7 @@ static const njs_object_prop_t njs_typed_array_u16_prototype_properties[] = njs_object_prototype_create_constructor, 0, 0, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 2), - 0), + NJS_DECLARE_PROP_VALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 2), 0), }; @@ -2936,8 +2928,7 @@ static const njs_object_prop_t njs_typed_array_i16_constructor_props[] = NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 2), - 0), + NJS_DECLARE_PROP_VALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 2), 0), }; @@ -2953,8 +2944,7 @@ static const njs_object_prop_t njs_typed_array_i16_prototype_properties[] = njs_object_prototype_create_constructor, 0, 0, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 2), - 0), + NJS_DECLARE_PROP_VALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 2), 0), }; @@ -2981,8 +2971,7 @@ static const njs_object_prop_t njs_typed_array_u32_constructor_props[] = NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 4), - 0), + NJS_DECLARE_PROP_VALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 4), 0), }; @@ -2998,8 +2987,7 @@ static const njs_object_prop_t njs_typed_array_u32_prototype_properties[] = njs_object_prototype_create_constructor, 0, 0, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 4), - 0), + NJS_DECLARE_PROP_VALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 4), 0), }; @@ -3026,8 +3014,7 @@ static const njs_object_prop_t njs_typed_array_i32_constructor_props[] = NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 4), - 0), + NJS_DECLARE_PROP_VALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 4), 0), }; @@ -3043,8 +3030,7 @@ static const njs_object_prop_t njs_typed_array_i32_prototype_properties[] = njs_object_prototype_create_constructor, 0, 0, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 4), - 0), + NJS_DECLARE_PROP_VALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 4), 0), }; @@ -3071,8 +3057,7 @@ static const njs_object_prop_t njs_typed_array_f32_constructor_props[] = NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 4), - 0), + NJS_DECLARE_PROP_VALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 4), 0), }; @@ -3088,8 +3073,7 @@ static const njs_object_prop_t njs_typed_array_f32_prototype_properties[] = njs_object_prototype_create_constructor, 0, 0, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 4), - 0), + NJS_DECLARE_PROP_VALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 4), 0), }; @@ -3116,8 +3100,7 @@ static const njs_object_prop_t njs_typed_array_f64_constructor_props[] = NJS_DECLARE_PROP_HANDLER("prototype", njs_object_prototype_create, 0, 0, 0), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 8), - 0), + NJS_DECLARE_PROP_VALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 8), 0), }; @@ -3133,8 +3116,7 @@ static const njs_object_prop_t njs_typed_array_f64_prototype_properties[] = njs_object_prototype_create_constructor, 0, 0, NJS_OBJECT_PROP_VALUE_CW), - NJS_DECLARE_PROP_LVALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 8), - 0), + NJS_DECLARE_PROP_VALUE("BYTES_PER_ELEMENT", njs_value(NJS_NUMBER, 1, 8), 0), }; diff --git a/src/njs_value.c b/src/njs_value.c index a575f9af2..eb8861a03 100644 --- a/src/njs_value.c +++ b/src/njs_value.c @@ -56,6 +56,9 @@ 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"); +const njs_value_t njs_string_value_of = njs_string("valueOf"); +const njs_value_t njs_string_ctor = njs_string("constructor"); +const njs_value_t njs_string_prototype = njs_string("prototype"); /* @@ -265,13 +268,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), + ret = njs_value_property(vm, value, njs_value_arg(&njs_string_value_of), retval); if (njs_slow_path(ret != NJS_OK)) { return ret; @@ -955,6 +956,7 @@ static njs_int_t njs_string_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_value_t *object, uint32_t index) { + njs_int_t ret; njs_slice_prop_t slice; njs_object_prop_t *prop; njs_string_prop_t string; @@ -981,7 +983,11 @@ njs_string_property_query(njs_vm_t *vm, njs_property_query_t *pq, 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); + ret = njs_uint32_to_string(vm, &pq->key, index); + if (njs_slow_path(ret != NJS_OK)) { + return NJS_ERROR; + } + njs_string_get(&pq->key, &pq->lhq.key); } @@ -1712,11 +1718,10 @@ 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_value_arg(&njs_string_ctor), &constructor); if (njs_slow_path(ret == NJS_ERROR)) { return NJS_ERROR; diff --git a/src/njs_value.h b/src/njs_value.h index 3751db719..3ad406e67 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,21 @@ 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; + uint8_t _spare1_; + uint8_t _spare2_; - uint32_t size; 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; + }; }; @@ -409,27 +385,16 @@ typedef struct { } +/* Declares an ASCII string value for which size == length. */ #define njs_string(s) { \ - .short_string = { \ + .string = { \ .type = NJS_STRING, \ - .size = njs_length(s), \ - .length = njs_length(s), \ - .start = s, \ - } \ -} - - -/* NJS_STRING_LONG is set for both big and little endian platforms. */ - -#define njs_long_string(s) { \ - .long_string = { \ - .type = NJS_STRING, \ - .truth = (NJS_STRING_LONG << 4) | NJS_STRING_LONG, \ - .size = njs_length(s), \ - .data = & (njs_string_t) { \ + .truth = njs_length(s) ? 1 : 0, \ + .data = &(njs_string_t) { \ .start = (u_char *) s, \ .length = njs_length(s), \ - } \ + .size = njs_length(s), \ + }, \ } \ } @@ -551,50 +516,13 @@ 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) \ 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; \ - } \ + (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) \ - do { \ - if ((value)->short_string.size != NJS_STRING_LONG) { \ - (value)->short_string.length = length; \ - \ - } else { \ - (value)->long_string.data->length = length; \ - } \ - } while (0) - #define njs_is_primitive(value) \ ((value)->type <= NJS_STRING) @@ -852,6 +780,9 @@ 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; +extern const njs_value_t njs_string_value_of; +extern const njs_value_t njs_string_ctor; +extern const njs_value_t njs_string_prototype; njs_inline void diff --git a/src/njs_vm.c b/src/njs_vm.c index 908c40c86..3c39b7145 100644 --- a/src/njs_vm.c +++ b/src/njs_vm.c @@ -1442,8 +1442,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; @@ -1472,24 +1470,8 @@ 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; + dst->length = value.string.data->size; + dst->start = value.string.data->start; } return ret; @@ -1504,24 +1486,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)) { @@ -1529,7 +1499,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; @@ -1564,8 +1534,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; @@ -1616,24 +1585,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; diff --git a/src/njs_vmcode.c b/src/njs_vmcode.c index a95171a39..c7b42b04d 100644 --- a/src/njs_vmcode.c +++ b/src/njs_vmcode.c @@ -2190,8 +2190,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; @@ -2207,7 +2205,7 @@ 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); + njs_value_arg(&njs_string_prototype), &value); if (njs_slow_path(ret == NJS_ERROR)) { return ret; @@ -2521,8 +2519,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 +2534,8 @@ 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_value_arg(&njs_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 f957dc566..dd8a584fa 100644 --- a/src/test/njs_benchmark.c +++ b/src/test/njs_benchmark.c @@ -94,6 +94,10 @@ njs_time(void) } +static const njs_value_t name_key = njs_string("name"); +static const njs_value_t usec_key = njs_string("usec"); +static const njs_value_t times_key = njs_string("times"); + static njs_int_t njs_benchmark_test(njs_vm_t *parent, njs_opts_t *opts, njs_value_t *report, njs_benchmark_test_t *test) @@ -108,10 +112,6 @@ njs_benchmark_test(njs_vm_t *parent, njs_opts_t *opts, njs_value_t *report, njs_value_t *result, retval, name, usec, times; njs_vm_opt_t options; - static const njs_value_t name_key = njs_string("name"); - static const njs_value_t usec_key = njs_string("usec"); - static const njs_value_t times_key = njs_string("times"); - njs_vm_opt_init(&options); options.addons = njs_benchmark_addon_external_modules; @@ -493,6 +493,9 @@ static njs_str_t code = njs_str( "}"); +static const njs_str_t compare = njs_str("compare"); + + int njs_cdecl main(int argc, char **argv) { @@ -518,8 +521,6 @@ main(int argc, char **argv) " -c compare with previous report.\n" " -h this help.\n"; - static const njs_str_t compare = njs_str("compare"); - njs_memzero(&opts, sizeof(njs_opts_t)); opts.prefix = ""; @@ -682,14 +683,15 @@ njs_benchmark_preinit(njs_vm_t *vm) } +static const njs_str_t benchmark = njs_str("benchmark"); + + static njs_int_t njs_benchmark_init(njs_vm_t *vm) { njs_int_t ret; njs_opaque_value_t value; - static const njs_str_t benchmark = njs_str("benchmark"); - ret = njs_vm_external_create(vm, njs_value_arg(&value), njs_benchmark_proto_id, NULL, 1); if (njs_slow_path(ret != NJS_OK)) {