1
2 /*
3 * Copyright (C) Igor Sysoev
4 * Copyright (C) NGINX, Inc.
5 */
6
7 #ifndef _NJS_VALUE_CONVERSION_H_INCLUDED_
8 #define _NJS_VALUE_CONVERSION_H_INCLUDED_
9
10
11 njs_inline njs_int_t
njs_value_to_number(njs_vm_t * vm,njs_value_t * value,double * dst)12 njs_value_to_number(njs_vm_t *vm, njs_value_t *value, double *dst)
13 {
14 njs_int_t ret;
15 njs_value_t primitive;
16
17 if (njs_slow_path(!njs_is_primitive(value))) {
18 ret = njs_value_to_primitive(vm, &primitive, value, 0);
19 if (njs_slow_path(ret != NJS_OK)) {
20 return ret;
21 }
22
23 value = &primitive;
24 }
25
26 if (njs_slow_path(!njs_is_numeric(value))) {
27
28 if (njs_slow_path(njs_is_symbol(value))) {
29 njs_symbol_conversion_failed(vm, 0);
30 return NJS_ERROR;
31 }
32
33 *dst = NAN;
34
35 if (njs_is_string(value)) {
36 *dst = njs_string_to_number(value, 0);
37 }
38
39 return NJS_OK;
40 }
41
42 *dst = njs_number(value);
43
44 return NJS_OK;
45 }
46
47
48 njs_inline njs_int_t
njs_value_to_numeric(njs_vm_t * vm,njs_value_t * value,njs_value_t * dst)49 njs_value_to_numeric(njs_vm_t *vm, njs_value_t *value, njs_value_t *dst)
50 {
51 double num;
52 njs_int_t ret;
53
54 ret = njs_value_to_number(vm, value, &num);
55 if (njs_slow_path(ret != NJS_OK)) {
56 return ret;
57 }
58
59 njs_set_number(dst, num);
60
61 return NJS_OK;
62 }
63
64
65 njs_inline njs_int_t
njs_value_to_integer(njs_vm_t * vm,njs_value_t * value,int64_t * dst)66 njs_value_to_integer(njs_vm_t *vm, njs_value_t *value, int64_t *dst)
67 {
68 double num;
69 njs_int_t ret;
70
71 ret = njs_value_to_number(vm, value, &num);
72 if (njs_slow_path(ret != NJS_OK)) {
73 return ret;
74 }
75
76 *dst = njs_number_to_integer(num);
77
78 return NJS_OK;
79 }
80
81
82 njs_inline njs_int_t
njs_value_to_length(njs_vm_t * vm,njs_value_t * value,int64_t * dst)83 njs_value_to_length(njs_vm_t *vm, njs_value_t *value, int64_t *dst)
84 {
85 double num;
86 njs_int_t ret;
87
88 ret = njs_value_to_number(vm, value, &num);
89 if (njs_slow_path(ret != NJS_OK)) {
90 return ret;
91 }
92
93 *dst = njs_number_to_length(num);
94
95 return NJS_OK;
96 }
97
98
99 njs_inline njs_int_t
njs_value_to_index(njs_vm_t * vm,njs_value_t * value,uint64_t * dst)100 njs_value_to_index(njs_vm_t *vm, njs_value_t *value, uint64_t *dst)
101 {
102 int64_t integer_index;
103 njs_int_t ret;
104
105 if (njs_slow_path(njs_is_undefined(value))) {
106 *dst = 0;
107
108 } else {
109 ret = njs_value_to_integer(vm, value, &integer_index);
110 if (njs_slow_path(ret != NJS_OK)) {
111 return ret;
112 }
113
114 if (integer_index < 0 || integer_index > UINT32_MAX) {
115 njs_range_error(vm, "invalid index");
116 return NJS_ERROR;
117 }
118
119 *dst = integer_index;
120 }
121
122 return NJS_OK;
123 }
124
125
126 njs_inline njs_int_t
njs_value_to_int32(njs_vm_t * vm,njs_value_t * value,int32_t * dst)127 njs_value_to_int32(njs_vm_t *vm, njs_value_t *value, int32_t *dst)
128 {
129 double num;
130 njs_int_t ret;
131
132 ret = njs_value_to_number(vm, value, &num);
133 if (njs_slow_path(ret != NJS_OK)) {
134 return ret;
135 }
136
137 *dst = njs_number_to_int32(num);
138
139 return NJS_OK;
140 }
141
142
143 njs_inline njs_int_t
njs_value_to_uint32(njs_vm_t * vm,njs_value_t * value,uint32_t * dst)144 njs_value_to_uint32(njs_vm_t *vm, njs_value_t *value, uint32_t *dst)
145 {
146 double num;
147 njs_int_t ret;
148
149 ret = njs_value_to_number(vm, value, &num);
150 if (njs_slow_path(ret != NJS_OK)) {
151 return ret;
152 }
153
154 *dst = njs_number_to_uint32(num);
155
156 return NJS_OK;
157 }
158
159
160 njs_inline njs_int_t
njs_value_to_uint16(njs_vm_t * vm,njs_value_t * value,uint16_t * dst)161 njs_value_to_uint16(njs_vm_t *vm, njs_value_t *value, uint16_t *dst)
162 {
163 double num;
164 njs_int_t ret;
165
166 ret = njs_value_to_number(vm, value, &num);
167 if (njs_slow_path(ret != NJS_OK)) {
168 return ret;
169 }
170
171 *dst = njs_number_to_uint16(num);
172
173 return NJS_OK;
174 }
175
176
177 njs_inline njs_int_t
njs_value_to_string(njs_vm_t * vm,njs_value_t * dst,njs_value_t * value)178 njs_value_to_string(njs_vm_t *vm, njs_value_t *dst, njs_value_t *value)
179 {
180 njs_int_t ret;
181 njs_value_t primitive;
182
183 if (njs_slow_path(!njs_is_primitive(value))) {
184 if (njs_slow_path(njs_is_object_symbol(value))) {
185 /* should fail */
186 value = njs_object_value(value);
187
188 } else {
189 ret = njs_value_to_primitive(vm, &primitive, value, 1);
190 if (njs_slow_path(ret != NJS_OK)) {
191 return ret;
192 }
193
194 value = &primitive;
195 }
196 }
197
198 return njs_primitive_value_to_string(vm, dst, value);
199 }
200
201
202 /*
203 * retval >= 0 is length (UTF8 characters) value of appended string.
204 */
205 njs_inline njs_int_t
njs_value_to_chain(njs_vm_t * vm,njs_chb_t * chain,njs_value_t * value)206 njs_value_to_chain(njs_vm_t *vm, njs_chb_t *chain, njs_value_t *value)
207 {
208 njs_int_t ret;
209 njs_value_t primitive;
210
211 if (njs_slow_path(!njs_is_primitive(value))) {
212 if (njs_slow_path(njs_is_object_symbol(value))) {
213 /* should fail */
214 value = njs_object_value(value);
215
216 } else {
217 ret = njs_value_to_primitive(vm, &primitive, value, 1);
218 if (njs_slow_path(ret != NJS_OK)) {
219 return ret;
220 }
221
222 value = &primitive;
223 }
224 }
225
226 return njs_primitive_value_to_chain(vm, chain, value);
227 }
228
229
230 #endif /* _NJS_VALUE_CONVERSION_H_INCLUDED_ */
231