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