[njs] Added implementation of functions: ToInt32, ToUint32, ToLength.
Alexander Borisov
alexander.borisov at nginx.com
Mon Apr 15 14:45:49 UTC 2019
details: https://hg.nginx.org/njs/rev/381086beb15f
branches:
changeset: 894:381086beb15f
user: Alexander Borisov <alexander.borisov at nginx.com>
date: Mon Apr 15 17:23:02 2019 +0300
description:
Added implementation of functions: ToInt32, ToUint32, ToLength.
According to ES6 type conversion: 7.1.5, 7.1.6, and 7.1.15.
diffstat:
njs/njs_array.c | 2 +-
njs/njs_function.c | 2 +-
njs/njs_math.c | 6 ++--
njs/njs_number.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++
njs/njs_number.h | 7 +++++-
njs/njs_string.c | 2 +-
njs/njs_vm.c | 19 +++++++--------
njs/test/njs_unit_test.c | 2 +-
8 files changed, 78 insertions(+), 18 deletions(-)
diffs (221 lines):
diff -r f0b5b01a7c55 -r 381086beb15f njs/njs_array.c
--- a/njs/njs_array.c Mon Apr 15 17:23:21 2019 +0300
+++ b/njs/njs_array.c Mon Apr 15 17:23:02 2019 +0300
@@ -494,7 +494,7 @@ njs_array_prototype_slice_continuation(n
}
start = njs_primitive_value_to_integer(njs_arg(args, nargs, 1));
- length = njs_primitive_value_to_integer(&slice->length);
+ length = njs_primitive_value_to_length(&slice->length);
if (start < 0) {
start += length;
diff -r f0b5b01a7c55 -r 381086beb15f njs/njs_function.c
--- a/njs/njs_function.c Mon Apr 15 17:23:21 2019 +0300
+++ b/njs/njs_function.c Mon Apr 15 17:23:02 2019 +0300
@@ -1022,7 +1022,7 @@ njs_function_prototype_apply(njs_vm_t *v
return NXT_ERROR;
}
- nargs = njs_primitive_value_to_number(&length);
+ nargs = njs_primitive_value_to_length(&length);
arr = njs_array_alloc(vm, nargs, NJS_ARRAY_SPARE);
if (nxt_slow_path(arr == NULL)) {
diff -r f0b5b01a7c55 -r 381086beb15f njs/njs_math.c
--- a/njs/njs_math.c Mon Apr 15 17:23:21 2019 +0300
+++ b/njs/njs_math.c Mon Apr 15 17:23:02 2019 +0300
@@ -227,7 +227,7 @@ njs_object_math_clz32(njs_vm_t *vm, njs_
uint32_t ui32;
if (nargs > 1) {
- ui32 = njs_number_to_integer(args[1].data.u.number);
+ ui32 = njs_number_to_uint32(args[1].data.u.number);
num = nxt_leading_zeros(ui32);
} else {
@@ -393,8 +393,8 @@ njs_object_math_imul(njs_vm_t *vm, njs_v
uint32_t a, b;
if (nargs > 2) {
- a = njs_number_to_integer(args[1].data.u.number);
- b = njs_number_to_integer(args[2].data.u.number);
+ a = njs_number_to_uint32(args[1].data.u.number);
+ b = njs_number_to_uint32(args[2].data.u.number);
num = (int32_t) (a * b);
diff -r f0b5b01a7c55 -r 381086beb15f njs/njs_number.c
--- a/njs/njs_number.c Mon Apr 15 17:23:21 2019 +0300
+++ b/njs/njs_number.c Mon Apr 15 17:23:02 2019 +0300
@@ -80,6 +80,27 @@ njs_primitive_value_to_integer(const njs
}
+int32_t
+njs_primitive_value_to_int32(const njs_value_t *value)
+{
+ return njs_number_to_int32(njs_primitive_value_to_number(value));
+}
+
+
+uint32_t
+njs_primitive_value_to_uint32(const njs_value_t *value)
+{
+ return njs_number_to_uint32(njs_primitive_value_to_number(value));
+}
+
+
+uint32_t
+njs_primitive_value_to_length(const njs_value_t *value)
+{
+ return njs_number_to_length(njs_primitive_value_to_number(value));
+}
+
+
double
njs_number_dec_parse(const u_char **start, const u_char *end)
{
@@ -822,6 +843,41 @@ njs_number_to_integer(double num)
}
+nxt_noinline int32_t
+njs_number_to_int32(double num)
+{
+ return (int32_t) njs_number_to_int64(num);
+}
+
+
+nxt_noinline uint32_t
+njs_number_to_uint32(double num)
+{
+ return (uint32_t) njs_number_to_int64(num);
+}
+
+
+nxt_noinline uint32_t
+njs_number_to_length(double num)
+{
+#if (NXT_NAN_TO_UINT_CONVERSION != 0)
+ if (isnan(num)) {
+ return 0;
+ }
+#endif
+
+ if (num > UINT32_MAX) {
+ return UINT32_MAX;
+
+ } else if (num < 0.0) {
+ return 0;
+ }
+
+ return (uint32_t) (int64_t) num;
+}
+
+
+
static const njs_object_prop_t njs_is_nan_function_properties[] =
{
/* isNaN.name == "isNaN". */
diff -r f0b5b01a7c55 -r 381086beb15f njs/njs_number.h
--- a/njs/njs_number.h Mon Apr 15 17:23:21 2019 +0300
+++ b/njs/njs_number.h Mon Apr 15 17:23:02 2019 +0300
@@ -14,6 +14,9 @@
uint32_t njs_value_to_index(const njs_value_t *value);
double njs_primitive_value_to_number(const njs_value_t *value);
int32_t njs_primitive_value_to_integer(const njs_value_t *value);
+int32_t njs_primitive_value_to_int32(const njs_value_t *value);
+uint32_t njs_primitive_value_to_uint32(const njs_value_t *value);
+uint32_t njs_primitive_value_to_length(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);
@@ -33,7 +36,9 @@ njs_ret_t njs_number_parse_int(njs_vm_t
njs_ret_t njs_number_parse_float(njs_vm_t *vm, njs_value_t *args,
nxt_uint_t nargs, njs_index_t unused);
nxt_noinline int32_t njs_number_to_integer(double num);
-
+nxt_noinline int32_t njs_number_to_int32(double num);
+nxt_noinline uint32_t njs_number_to_uint32(double num);
+nxt_noinline uint32_t njs_number_to_length(double num);
nxt_inline nxt_int_t
njs_char_to_hex(u_char c)
diff -r f0b5b01a7c55 -r 381086beb15f njs/njs_string.c
--- a/njs/njs_string.c Mon Apr 15 17:23:21 2019 +0300
+++ b/njs/njs_string.c Mon Apr 15 17:23:02 2019 +0300
@@ -1445,7 +1445,7 @@ njs_string_bytes_from_array(njs_vm_t *vm
octet = array->start;
while (length != 0) {
- *p++ = (u_char) njs_number_to_integer(octet->data.u.number);
+ *p++ = (u_char) njs_number_to_uint32(octet->data.u.number);
octet++;
length--;
}
diff -r f0b5b01a7c55 -r 381086beb15f njs/njs_vm.c
--- a/njs/njs_vm.c Mon Apr 15 17:23:21 2019 +0300
+++ b/njs/njs_vm.c Mon Apr 15 17:23:02 2019 +0300
@@ -1303,8 +1303,8 @@ njs_vmcode_left_shift(njs_vm_t *vm, njs_
if (nxt_fast_path(njs_is_numeric(val1) && njs_is_numeric(val2))) {
- num1 = njs_number_to_integer(val1->data.u.number);
- num2 = njs_number_to_integer(val2->data.u.number);
+ num1 = njs_number_to_int32(val1->data.u.number);
+ num2 = njs_number_to_uint32(val2->data.u.number);
njs_value_number_set(&vm->retval, num1 << (num2 & 0x1f));
return sizeof(njs_vmcode_3addr_t);
@@ -1322,8 +1322,8 @@ njs_vmcode_right_shift(njs_vm_t *vm, njs
if (nxt_fast_path(njs_is_numeric(val1) && njs_is_numeric(val2))) {
- num1 = njs_number_to_integer(val1->data.u.number);
- num2 = njs_number_to_integer(val2->data.u.number);
+ num1 = njs_number_to_int32(val1->data.u.number);
+ num2 = njs_number_to_uint32(val2->data.u.number);
njs_value_number_set(&vm->retval, num1 >> (num2 & 0x1f));
return sizeof(njs_vmcode_3addr_t);
@@ -1337,13 +1337,12 @@ njs_ret_t
njs_vmcode_unsigned_right_shift(njs_vm_t *vm, njs_value_t *val1,
njs_value_t *val2)
{
- int32_t num2;
- uint32_t num1;
+ uint32_t num1, num2;
if (nxt_fast_path(njs_is_numeric(val1) && njs_is_numeric(val2))) {
- num1 = njs_number_to_integer(val1->data.u.number);
- num2 = njs_number_to_integer(val2->data.u.number);
+ num1 = njs_number_to_uint32(val1->data.u.number);
+ num2 = njs_number_to_uint32(val2->data.u.number);
njs_value_number_set(&vm->retval, num1 >> (num2 & 0x1f));
return sizeof(njs_vmcode_3addr_t);
@@ -1462,8 +1461,8 @@ njs_vmcode_bitwise_or(njs_vm_t *vm, njs_
if (nxt_fast_path(njs_is_numeric(val1) && njs_is_numeric(val2))) {
- num1 = njs_number_to_integer(val1->data.u.number);
- num2 = njs_number_to_integer(val2->data.u.number);
+ num1 = njs_number_to_uint32(val1->data.u.number);
+ num2 = njs_number_to_uint32(val2->data.u.number);
njs_value_number_set(&vm->retval, num1 | num2);
return sizeof(njs_vmcode_3addr_t);
diff -r f0b5b01a7c55 -r 381086beb15f njs/test/njs_unit_test.c
--- a/njs/test/njs_unit_test.c Mon Apr 15 17:23:21 2019 +0300
+++ b/njs/test/njs_unit_test.c Mon Apr 15 17:23:02 2019 +0300
@@ -3617,7 +3617,7 @@ static njs_unit_test_t njs_test[] =
nxt_string("TypeError: Cannot convert object to primitive value") },
{ nxt_string("Array.prototype.slice.call({length:-1})"),
- nxt_string("MemoryError") },
+ nxt_string("") },
{ nxt_string("Array.prototype.slice.call('αβZγ')"),
nxt_string("α,β,Z,γ") },
More information about the nginx-devel
mailing list