njs_array_length(njs_vm_t *vm, njs_value_t *value, njs_value_t *setval,
njs_value_t *retval)
{
- double num;
- int64_t size;
- uint32_t length;
- njs_int_t ret;
- njs_value_t *val;
- njs_array_t *array;
- njs_object_t *proto;
- njs_value_t val_length;
+ double num;
+ int64_t size;
+ uint32_t length;
+ njs_int_t ret;
+ njs_value_t *val;
+ njs_array_t *array;
+ njs_object_t *proto;
proto = njs_object(value);
}
if (njs_slow_path(!njs_is_number(setval))) {
- ret = njs_value_to_numeric(vm, &val_length, setval);
- if (ret != NJS_OK) {
+ ret = njs_value_to_number(vm, setval, &num);
+ if (njs_slow_path(ret != NJS_OK)) {
return ret;
}
- num = njs_number(&val_length);
-
} else {
num = njs_number(setval);
}
- length = njs_number_to_uint32(num);
+ length = njs_number_to_length(num);
if ((double) length != num) {
njs_range_error(vm, "Invalid array length");
njs_array_prototype_slice(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
njs_index_t unused)
{
- int64_t start, end, length;
- njs_int_t ret;
- njs_value_t prop_length;
-
- static const njs_value_t string_length = njs_string("length");
+ int64_t start, end, length;
+ uint32_t object_length;
+ njs_int_t ret;
- ret = njs_value_property(vm, &args[0], njs_value_arg(&string_length),
- &prop_length);
+ ret = njs_object_length(vm, njs_arg(args, nargs, 0), &object_length);
if (njs_slow_path(ret == NJS_ERROR)) {
return ret;
}
- if (njs_slow_path(!njs_is_primitive(&prop_length))) {
- ret = njs_value_to_numeric(vm, &prop_length, &prop_length);
- if (ret != NJS_OK) {
- return ret;
- }
- }
+ length = object_length;
- start = njs_primitive_value_to_integer(njs_arg(args, nargs, 1));
- length = njs_primitive_value_to_length(&prop_length);
+ ret = njs_value_to_integer(vm, njs_arg(args, nargs, 1), &start);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return ret;
+ }
if (start < 0) {
start += length;
} else {
if (njs_is_defined(njs_arg(args, nargs, 2))) {
- end = njs_primitive_value_to_integer(njs_argument(args, 2));
+ ret = njs_value_to_integer(vm, njs_argument(args, 2), &end);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return ret;
+ }
} else {
end = length;
return ret;
}
- from = njs_primitive_value_to_integer(njs_arg(args, nargs, 2));
+ ret = njs_value_to_integer(vm, njs_arg(args, nargs, 2), &from);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return ret;
+ }
if (length == 0 || from >= (int64_t) length) {
goto not_found;
}
if (nargs > 2) {
- from = njs_primitive_value_to_integer(njs_arg(args, nargs, 2));
+ ret = njs_value_to_integer(vm, njs_arg(args, nargs, 2), &from);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return ret;
+ }
} else {
from = length - 1;
goto not_found;
}
- from = njs_primitive_value_to_integer(njs_arg(args, nargs, 2));
+ ret = njs_value_to_integer(vm, njs_arg(args, nargs, 2), &from);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return ret;
+ }
if (from < 0) {
from += length;
njs_array_prototype_fill(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
njs_index_t unused)
{
- njs_int_t ret;
- njs_int_t i, start, end, length;
+ int64_t start, end;
+ uint32_t length;
+ njs_int_t i, ret;
njs_array_t *array;
- njs_value_t name, prop_length, *this, *value;
+ njs_value_t name, *this, *value;
njs_object_t *object;
- static const njs_value_t string_length = njs_string("length");
-
this = njs_arg(args, nargs, 0);
if (njs_is_primitive(this)) {
length = array->length;
} else {
- ret = njs_value_property(vm, this, njs_value_arg(&string_length),
- &prop_length);
+ ret = njs_object_length(vm, this, &length);
if (njs_slow_path(ret == NJS_ERROR)) {
return ret;
}
+ }
- if (njs_slow_path(!njs_is_primitive(&prop_length))) {
- ret = njs_value_to_numeric(vm, &prop_length, &prop_length);
- if (ret != NJS_OK) {
- return ret;
- }
- }
-
- length = njs_primitive_value_to_length(&prop_length);
+ ret = njs_value_to_integer(vm, njs_arg(args, nargs, 2), &start);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return ret;
}
- start = njs_primitive_value_to_integer(njs_arg(args, nargs, 2));
start = (start < 0) ? njs_max(length + start, 0) : njs_min(start, length);
if (njs_is_undefined(njs_arg(args, nargs, 3))) {
end = length;
} else {
- end = njs_primitive_value_to_integer(njs_arg(args, nargs, 3));
+ ret = njs_value_to_integer(vm, njs_arg(args, nargs, 3), &end);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return ret;
+ }
}
end = (end < 0) ? njs_max(length + end, 0) : njs_min(end, length);
njs_dump_value(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
njs_index_t unused)
{
+ uint32_t n;
+ njs_int_t ret;
njs_str_t str;
- njs_uint_t n;
njs_value_t *value, *indent;
value = njs_arg(args, nargs, 1);
indent = njs_arg(args, nargs, 2);
- n = njs_primitive_value_to_integer(indent);
+ ret = njs_value_to_uint32(vm, indent, &n);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return ret;
+ }
+
n = njs_min(n, 5);
if (njs_vm_value_dump(vm, &str, value, 1, n) != NJS_OK) {
njs_uint_t nargs, njs_index_t unused)
{
u_char *p;
- int32_t frac;
+ int64_t frac;
double number;
size_t length, size;
- njs_int_t point, prefix, postfix;
+ njs_int_t ret, point, prefix, postfix;
njs_value_t *value;
u_char buf[128], buf2[128];
}
}
- frac = njs_primitive_value_to_integer(njs_arg(args, nargs, 1));
+ ret = njs_value_to_integer(vm, njs_arg(args, nargs, 1), &frac);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return ret;
+ }
+
if (njs_slow_path(frac < 0 || frac > 100)) {
njs_range_error(vm, "digits argument must be between 0 and 100");
return NJS_ERROR;
}
point = 0;
- length = njs_fixed_dtoa(number, frac, (char *) buf, &point);
+ length = njs_fixed_dtoa(number, (njs_int_t) frac, (char *) buf, &point);
prefix = 0;
postfix = 0;
{
double number;
size_t size;
- int32_t precision;
+ int64_t precision;
+ njs_int_t ret;
njs_value_t *value;
u_char buf[128];
return njs_number_to_string(vm, &vm->retval, value);
}
- precision = njs_primitive_value_to_integer(njs_argument(args, 1));
+ ret = njs_value_to_integer(vm, njs_argument(args, 1), &precision);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return ret;
+ }
+
if (njs_slow_path(precision < 1 || precision > 100)) {
njs_range_error(vm, "precision argument must be between 1 and 100");
return NJS_ERROR;
}
- size = njs_dtoa_precision(number, (char *) buf, precision);
+ size = njs_dtoa_precision(number, (char *) buf, (size_t) precision);
return njs_string_new(vm, &vm->retval, buf, size, size);
}
{
double number;
size_t size;
- int32_t frac;
+ int64_t frac;
+ njs_int_t ret;
njs_value_t *value;
u_char buf[128];
}
if (njs_is_defined(njs_arg(args, nargs, 1))) {
- frac = njs_primitive_value_to_integer(njs_argument(args, 1));
+ ret = njs_value_to_integer(vm, njs_argument(args, 1), &frac);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return ret;
+ }
+
if (njs_slow_path(frac < 0 || frac > 100)) {
njs_range_error(vm, "digits argument must be between 0 and 100");
return NJS_ERROR;
frac = -1;
}
- size = njs_dtoa_exponential(number, (char *) buf, frac);
+ size = njs_dtoa_exponential(number, (char *) buf, (njs_int_t) frac);
return njs_string_new(vm, &vm->retval, buf, size, size);
}
}
-njs_inline int32_t
+njs_inline int64_t
njs_number_to_integer(double num)
{
- return (int32_t) njs_number_to_int64(num);
+ if (njs_slow_path(isinf(num))) {
+ if (num < 0) {
+ return INT64_MIN;
+ }
+
+ return INT64_MAX;
+
+ } else if (njs_slow_path(isnan(num))) {
+ return 0;
+ }
+
+ return njs_number_to_int64(num);
}
return c;
}
-
-njs_inline double
-njs_primitive_value_to_number(const njs_value_t *value)
-{
- if (njs_fast_path(njs_is_numeric(value))) {
- return njs_number(value);
- }
-
- return njs_string_to_number(value, 0);
-}
-
-
-njs_inline int32_t
-njs_primitive_value_to_integer(const njs_value_t *value)
-{
- return njs_number_to_integer(njs_primitive_value_to_number(value));
-}
-
-
-njs_inline int32_t
-njs_primitive_value_to_int32(const njs_value_t *value)
-{
- return njs_number_to_int32(njs_primitive_value_to_number(value));
-}
-
-
-njs_inline uint32_t
-njs_primitive_value_to_uint32(const njs_value_t *value)
-{
- return njs_number_to_uint32(njs_primitive_value_to_number(value));
-}
-
-
-njs_inline uint32_t
-njs_primitive_value_to_length(const njs_value_t *value)
-{
- return njs_number_to_length(njs_primitive_value_to_number(value));
-}
-
-
njs_inline void
njs_uint32_to_string(njs_value_t *value, uint32_t u32)
{
return ret;
}
- if (!njs_is_primitive(&value_length)) {
- ret = njs_value_to_numeric(vm, &value_length, &value_length);
- if (njs_slow_path(ret != NJS_OK)) {
- return ret;
- }
- }
-
- *length = njs_primitive_value_to_length(&value_length);
-
- return NJS_OK;
+ return njs_value_to_length(vm, &value_length, length);
}
njs_string_prototype_char_at(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
njs_index_t unused)
{
- ssize_t start, length;
+ size_t length;
+ int64_t start;
+ njs_int_t ret;
njs_slice_prop_t slice;
njs_string_prop_t string;
slice.string_length = njs_string_prop(&string, &args[0]);
- start = njs_primitive_value_to_integer(njs_arg(args, nargs, 1));
+ ret = njs_value_to_integer(vm, njs_arg(args, nargs, 1), &start);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return ret;
+ }
+
length = 1;
- if (start < 0 || start >= (ssize_t) slice.string_length) {
+ if (start < 0 || start >= (int64_t) slice.string_length) {
start = 0;
length = 0;
}
njs_uint_t nargs, njs_index_t unused)
{
double num;
- ssize_t index, length;
+ size_t length;
+ int64_t index;
uint32_t code;
+ njs_int_t ret;
const u_char *start, *end;
njs_string_prop_t string;
length = njs_string_prop(&string, &args[0]);
- index = njs_primitive_value_to_integer(njs_arg(args, nargs, 1));
+ ret = njs_value_to_integer(vm, njs_arg(args, nargs, 1), &index);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return ret;
+ }
- if (njs_slow_path(index < 0 || index >= length)) {
+ if (njs_slow_path(index < 0 || index >= (int64_t) length)) {
num = NAN;
goto done;
}
- if ((uint32_t) length == string.size) {
+ if (length == string.size) {
/* Byte or ASCII string. */
code = string.start[index];
njs_index_t unused)
{
u_char *p, *start;
- int32_t n, max;
- uint32_t size, length;
+ int64_t n, max;
+ uint64_t size, length;
+ njs_int_t ret;
njs_string_prop_t string;
- n = njs_primitive_value_to_integer(njs_arg(args, nargs, 1));
+ ret = njs_value_to_integer(vm, njs_arg(args, nargs, 1), &n);
+ if (njs_slow_path(ret != NJS_OK)) {
+ return ret;
+ }
(void) njs_string_prop(&string, &args[0]);
njs_value_t *key, njs_value_t *removed);
+#include "njs_number.h"
+
+
njs_inline njs_int_t
-njs_value_to_numeric(njs_vm_t *vm, njs_value_t *dst, njs_value_t *value)
+njs_value_to_number(njs_vm_t *vm, njs_value_t *value, double *dst)
{
- double num;
njs_int_t ret;
njs_value_t primitive;
}
if (njs_slow_path(!njs_is_numeric(value))) {
- num = NAN;
+ *dst = NAN;
if (njs_is_string(value)) {
- num = njs_string_to_number(value, 0);
+ *dst = njs_string_to_number(value, 0);
}
- } else {
- num = njs_number(value);
+ 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);
}
+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)
{
case NJS_VMCODE_DECREMENT:
case NJS_VMCODE_POST_DECREMENT:
if (njs_slow_path(!njs_is_numeric(value2))) {
- ret = njs_value_to_numeric(vm, &numeric1, value2);
+ ret = njs_value_to_numeric(vm, value2, &numeric1);
if (njs_slow_path(ret != NJS_OK)) {
goto error;
}
case NJS_VMCODE_RIGHT_SHIFT:
case NJS_VMCODE_UNSIGNED_RIGHT_SHIFT:
if (njs_slow_path(!njs_is_numeric(value1))) {
- ret = njs_value_to_numeric(vm, &numeric1, value1);
- if (ret != NJS_OK) {
+ ret = njs_value_to_numeric(vm, value1, &numeric1);
+ if (njs_slow_path(ret != NJS_OK)) {
goto error;
}
}
if (njs_slow_path(!njs_is_numeric(value2))) {
- ret = njs_value_to_numeric(vm, &numeric2, value2);
- if (ret != NJS_OK) {
+ ret = njs_value_to_numeric(vm, value2, &numeric2);
+ if (njs_slow_path(ret != NJS_OK)) {
goto error;
}
case NJS_VMCODE_UNARY_NEGATION:
case NJS_VMCODE_BITWISE_NOT:
if (njs_slow_path(!njs_is_numeric(value1))) {
- ret = njs_value_to_numeric(vm, &numeric1, value1);
- if (ret != NJS_OK) {
+ ret = njs_value_to_numeric(vm, value1, &numeric1);
+ if (njs_slow_path(ret != NJS_OK)) {
goto error;
}
break;
case NJS_VMCODE_BITWISE_NOT:
- njs_set_int32(retval, ~njs_number_to_integer(num));
+ njs_set_int32(retval, ~njs_number_to_uint32(num));
}
pc += sizeof(njs_vmcode_2addr_t);