blob: d684578119d859fa434ddeb94a4b9d192ca85892 [file] [log] [blame]
/*
* 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, uint64_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 = 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);
}
/*
* retval >= 0 is length (UTF8 characters) value of appended string.
*/
njs_inline njs_int_t
njs_value_to_chain(njs_vm_t *vm, njs_chb_t *chain, 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_chain(vm, chain, value);
}
#endif /* _NJS_VALUE_CONVERSION_H_INCLUDED_ */