From: Dmitry Volyntsev Date: Fri, 6 Dec 2019 11:44:54 +0000 (+0300) Subject: Introduced ToIndex() conversion primitive from the spec. X-Git-Url: http://www.kaiwu.me/postgresql/commit/?a=commitdiff_plain;h=da9af0a25bda1bc967408b9ae35688c065bcc8be;p=njs.git Introduced ToIndex() conversion primitive from the spec. --- diff --git a/src/njs_main.h b/src/njs_main.h index 4b9c3d17..fc83fc4d 100644 --- a/src/njs_main.h +++ b/src/njs_main.h @@ -44,6 +44,9 @@ #include #include +#include +#include +#include #include #include #include @@ -51,14 +54,12 @@ #include #include -#include #include #include #include #include #include #include -#include #include #include #include diff --git a/src/njs_number.c b/src/njs_number.c index 8e3476d9..60a850c7 100644 --- a/src/njs_number.c +++ b/src/njs_number.c @@ -21,7 +21,7 @@ static njs_int_t njs_number_to_string_radix(njs_vm_t *vm, njs_value_t *string, uint32_t -njs_value_to_index(const njs_value_t *value) +njs_key_to_index(const njs_value_t *value) { double num; njs_array_t *array; @@ -47,7 +47,7 @@ njs_value_to_index(const njs_value_t *value) if (array->length == 1 && njs_is_valid(&array->start[0])) { /* A single value array is the zeroth array value. */ - return njs_value_to_index(&array->start[0]); + return njs_key_to_index(&array->start[0]); } } } diff --git a/src/njs_number.h b/src/njs_number.h index dcce83fc..ea0f021a 100644 --- a/src/njs_number.h +++ b/src/njs_number.h @@ -8,7 +8,7 @@ #define _NJS_NUMBER_H_INCLUDED_ -uint32_t njs_value_to_index(const njs_value_t *value); +uint32_t njs_key_to_index(const njs_value_t *value); double njs_number_dec_parse(const u_char **start, const u_char *end); uint64_t njs_number_oct_parse(const u_char **start, const u_char *end); uint64_t njs_number_bin_parse(const u_char **start, const u_char *end); diff --git a/src/njs_value.c b/src/njs_value.c index b822a67d..7f2b653a 100644 --- a/src/njs_value.c +++ b/src/njs_value.c @@ -535,7 +535,7 @@ njs_property_query(njs_vm_t *vm, njs_property_query_t *pq, njs_value_t *value, case NJS_STRING: if (njs_fast_path(!njs_is_null_or_undefined_or_boolean(key))) { - index = njs_value_to_index(key); + index = njs_key_to_index(key); if (njs_fast_path(index < NJS_STRING_MAX_LENGTH)) { return njs_string_property_query(vm, pq, value, index); @@ -637,7 +637,7 @@ njs_object_property_query(njs_vm_t *vm, njs_property_query_t *pq, if (!njs_is_null_or_undefined_or_boolean(key)) { switch (proto->type) { case NJS_ARRAY: - index = njs_value_to_index(key); + index = njs_key_to_index(key); if (njs_fast_path(index < NJS_ARRAY_MAX_INDEX)) { array = (njs_array_t *) proto; return njs_array_property_query(vm, pq, array, index); @@ -646,7 +646,7 @@ njs_object_property_query(njs_vm_t *vm, njs_property_query_t *pq, break; case NJS_OBJECT_STRING: - index = njs_value_to_index(key); + index = njs_key_to_index(key); if (njs_fast_path(index < NJS_STRING_MAX_LENGTH)) { ov = (njs_object_value_t *) proto; ret = njs_string_property_query(vm, pq, &ov->value, index); diff --git a/src/njs_value.h b/src/njs_value.h index d9cc6a34..77790ba4 100644 --- a/src/njs_value.h +++ b/src/njs_value.h @@ -913,173 +913,6 @@ njs_int_t njs_value_species_constructor(njs_vm_t *vm, njs_value_t *object, njs_value_t *default_constructor, njs_value_t *dst); -#include "njs_number.h" - - -njs_inline njs_int_t -njs_value_to_number(njs_vm_t *vm, njs_value_t *value, double *dst) -{ - njs_int_t ret; - njs_value_t primitive; - - if (njs_slow_path(!njs_is_primitive(value))) { - ret = njs_value_to_primitive(vm, &primitive, value, 0); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - - value = &primitive; - } - - if (njs_slow_path(!njs_is_numeric(value))) { - - if (njs_slow_path(njs_is_symbol(value))) { - njs_symbol_conversion_failed(vm, 0); - return NJS_ERROR; - } - - *dst = NAN; - - if (njs_is_string(value)) { - *dst = njs_string_to_number(value, 0); - } - - return NJS_OK; - } - - *dst = njs_number(value); - - return NJS_OK; -} - - -njs_inline njs_int_t -njs_value_to_numeric(njs_vm_t *vm, njs_value_t *value, njs_value_t *dst) -{ - double num; - njs_int_t ret; - - ret = njs_value_to_number(vm, value, &num); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - - njs_set_number(dst, num); - - return NJS_OK; -} - - -njs_inline njs_int_t -njs_value_to_integer(njs_vm_t *vm, njs_value_t *value, int64_t *dst) -{ - double num; - njs_int_t ret; - - ret = njs_value_to_number(vm, value, &num); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - - *dst = njs_number_to_integer(num); - - return NJS_OK; -} - - -njs_inline njs_int_t -njs_value_to_length(njs_vm_t *vm, njs_value_t *value, uint32_t *dst) -{ - double num; - njs_int_t ret; - - ret = njs_value_to_number(vm, value, &num); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - - *dst = njs_number_to_length(num); - - return NJS_OK; -} - - -njs_inline njs_int_t -njs_value_to_int32(njs_vm_t *vm, njs_value_t *value, int32_t *dst) -{ - double num; - njs_int_t ret; - - ret = njs_value_to_number(vm, value, &num); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - - *dst = njs_number_to_int32(num); - - return NJS_OK; -} - - -njs_inline njs_int_t -njs_value_to_uint32(njs_vm_t *vm, njs_value_t *value, uint32_t *dst) -{ - double num; - njs_int_t ret; - - ret = njs_value_to_number(vm, value, &num); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - - *dst = njs_number_to_uint32(num); - - return NJS_OK; -} - - -njs_inline njs_int_t -njs_value_to_uint16(njs_vm_t *vm, njs_value_t *value, uint16_t *dst) -{ - double num; - njs_int_t ret; - - ret = njs_value_to_number(vm, value, &num); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - - *dst = njs_number_to_uint16(num); - - return NJS_OK; -} - - -njs_inline njs_int_t -njs_value_to_string(njs_vm_t *vm, njs_value_t *dst, njs_value_t *value) -{ - njs_int_t ret; - njs_value_t primitive; - - if (njs_slow_path(!njs_is_primitive(value))) { - if (njs_slow_path(value->type == NJS_OBJECT_SYMBOL)) { - /* should fail */ - value = njs_object_value(value); - - } else { - ret = njs_value_to_primitive(vm, &primitive, value, 1); - if (njs_slow_path(ret != NJS_OK)) { - return ret; - } - - value = &primitive; - } - } - - return njs_primitive_value_to_string(vm, dst, value); -} - - njs_inline njs_bool_t njs_values_same_non_numeric(const njs_value_t *val1, const njs_value_t *val2) { diff --git a/src/njs_value_conversion.h b/src/njs_value_conversion.h new file mode 100644 index 00000000..5cc5cfcb --- /dev/null +++ b/src/njs_value_conversion.h @@ -0,0 +1,202 @@ + +/* + * Copyright (C) Igor Sysoev + * Copyright (C) NGINX, Inc. + */ + +#ifndef _NJS_VALUE_CONVERSION_H_INCLUDED_ +#define _NJS_VALUE_CONVERSION_H_INCLUDED_ + + +njs_inline njs_int_t +njs_value_to_number(njs_vm_t *vm, njs_value_t *value, double *dst) +{ + njs_int_t ret; + njs_value_t primitive; + + if (njs_slow_path(!njs_is_primitive(value))) { + ret = njs_value_to_primitive(vm, &primitive, value, 0); + if (njs_slow_path(ret != NJS_OK)) { + return ret; + } + + value = &primitive; + } + + if (njs_slow_path(!njs_is_numeric(value))) { + + if (njs_slow_path(njs_is_symbol(value))) { + njs_symbol_conversion_failed(vm, 0); + return NJS_ERROR; + } + + *dst = NAN; + + if (njs_is_string(value)) { + *dst = njs_string_to_number(value, 0); + } + + return NJS_OK; + } + + *dst = njs_number(value); + + return NJS_OK; +} + + +njs_inline njs_int_t +njs_value_to_numeric(njs_vm_t *vm, njs_value_t *value, njs_value_t *dst) +{ + double num; + njs_int_t ret; + + ret = njs_value_to_number(vm, value, &num); + if (njs_slow_path(ret != NJS_OK)) { + return ret; + } + + njs_set_number(dst, num); + + return NJS_OK; +} + + +njs_inline njs_int_t +njs_value_to_integer(njs_vm_t *vm, njs_value_t *value, int64_t *dst) +{ + double num; + njs_int_t ret; + + ret = njs_value_to_number(vm, value, &num); + if (njs_slow_path(ret != NJS_OK)) { + return ret; + } + + *dst = njs_number_to_integer(num); + + return NJS_OK; +} + + +njs_inline njs_int_t +njs_value_to_length(njs_vm_t *vm, njs_value_t *value, uint32_t *dst) +{ + double num; + njs_int_t ret; + + ret = njs_value_to_number(vm, value, &num); + if (njs_slow_path(ret != NJS_OK)) { + return ret; + } + + *dst = njs_number_to_length(num); + + return NJS_OK; +} + + +njs_inline njs_int_t +njs_value_to_index(njs_vm_t *vm, njs_value_t *value, uint32_t *dst) +{ + int64_t integer_index; + njs_int_t ret; + + if (njs_slow_path(njs_is_undefined(value))) { + *dst = 0; + + } else { + ret = njs_value_to_integer(vm, value, &integer_index); + if (njs_slow_path(ret != NJS_OK)) { + return ret; + } + + if (integer_index < 0 || integer_index > UINT32_MAX) { + njs_range_error(vm, "invalid index"); + return NJS_ERROR; + } + + *dst = (uint32_t) integer_index; + } + + return NJS_OK; +} + + +njs_inline njs_int_t +njs_value_to_int32(njs_vm_t *vm, njs_value_t *value, int32_t *dst) +{ + double num; + njs_int_t ret; + + ret = njs_value_to_number(vm, value, &num); + if (njs_slow_path(ret != NJS_OK)) { + return ret; + } + + *dst = njs_number_to_int32(num); + + return NJS_OK; +} + + +njs_inline njs_int_t +njs_value_to_uint32(njs_vm_t *vm, njs_value_t *value, uint32_t *dst) +{ + double num; + njs_int_t ret; + + ret = njs_value_to_number(vm, value, &num); + if (njs_slow_path(ret != NJS_OK)) { + return ret; + } + + *dst = njs_number_to_uint32(num); + + return NJS_OK; +} + + +njs_inline njs_int_t +njs_value_to_uint16(njs_vm_t *vm, njs_value_t *value, uint16_t *dst) +{ + double num; + njs_int_t ret; + + ret = njs_value_to_number(vm, value, &num); + if (njs_slow_path(ret != NJS_OK)) { + return ret; + } + + *dst = njs_number_to_uint16(num); + + return NJS_OK; +} + + +njs_inline njs_int_t +njs_value_to_string(njs_vm_t *vm, njs_value_t *dst, njs_value_t *value) +{ + njs_int_t ret; + njs_value_t primitive; + + if (njs_slow_path(!njs_is_primitive(value))) { + if (njs_slow_path(value->type == NJS_OBJECT_SYMBOL)) { + /* should fail */ + value = njs_object_value(value); + + } else { + ret = njs_value_to_primitive(vm, &primitive, value, 1); + if (njs_slow_path(ret != NJS_OK)) { + return ret; + } + + value = &primitive; + } + } + + return njs_primitive_value_to_string(vm, dst, value); +} + + +#endif /* _NJS_VALUE_CONVERSION_H_INCLUDED_ */ diff --git a/src/njs_vmcode.c b/src/njs_vmcode.c index 725727e4..4cddea08 100644 --- a/src/njs_vmcode.c +++ b/src/njs_vmcode.c @@ -1146,7 +1146,7 @@ njs_vmcode_property_init(njs_vm_t *vm, njs_value_t *value, njs_value_t *key, switch (value->type) { case NJS_ARRAY: - index = njs_value_to_index(key); + index = njs_key_to_index(key); if (njs_slow_path(index == NJS_ARRAY_INVALID_INDEX)) { njs_internal_error(vm, "invalid index while property initialization");