1 /* Copyright JS Foundation and other contributors, http://js.foundation
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef BUILTIN_UNDERSCORED_ID
17 # error "Please, define BUILTIN_UNDERSCORED_ID"
18 #endif /* !BUILTIN_UNDERSCORED_ID */
19
20 #ifndef BUILTIN_INC_HEADER_NAME
21 # error "Please, define BUILTIN_INC_HEADER_NAME"
22 #endif /* !BUILTIN_INC_HEADER_NAME */
23
24 #include "ecma-objects.h"
25
26 #define PASTE__(x, y) x ## y
27 #define PASTE_(x, y) PASTE__ (x, y)
28 #define PASTE(x, y) PASTE_ (x, y)
29
30 #define PROPERTY_DESCRIPTOR_LIST_NAME \
31 PASTE (PASTE (ecma_builtin_, BUILTIN_UNDERSCORED_ID), _property_descriptor_list)
32 #define DISPATCH_ROUTINE_ROUTINE_NAME \
33 PASTE (PASTE (ecma_builtin_, BUILTIN_UNDERSCORED_ID), _dispatch_routine)
34
35 #ifndef BUILTIN_CUSTOM_DISPATCH
36
37 #define ROUTINE_ARG(n) , ecma_value_t arg ## n
38 #define ROUTINE_ARG_LIST_0 ecma_value_t this_arg
39 #define ROUTINE_ARG_LIST_1 ROUTINE_ARG_LIST_0 ROUTINE_ARG(1)
40 #define ROUTINE_ARG_LIST_2 ROUTINE_ARG_LIST_1 ROUTINE_ARG(2)
41 #define ROUTINE_ARG_LIST_3 ROUTINE_ARG_LIST_2 ROUTINE_ARG(3)
42 #define ROUTINE_ARG_LIST_NON_FIXED ROUTINE_ARG_LIST_0, \
43 const ecma_value_t *arguments_list_p, ecma_length_t arguments_list_len
44 #define ROUTINE(name, c_function_name, args_number, length_prop_value) \
45 static ecma_value_t c_function_name (ROUTINE_ARG_LIST_ ## args_number);
46 #define ROUTINE_CONFIGURABLE_ONLY(name, c_function_name, args_number, length_prop_value) \
47 static ecma_value_t c_function_name (ROUTINE_ARG_LIST_ ## args_number);
48 #define ROUTINE_WITH_FLAGS(name, c_function_name, args_number, length_prop_value, flags) \
49 static ecma_value_t c_function_name (ROUTINE_ARG_LIST_ ## args_number);
50 #define ACCESSOR_READ_WRITE(name, c_getter_func_name, c_setter_func_name, prop_attributes) \
51 static ecma_value_t c_getter_func_name (ROUTINE_ARG_LIST_0); \
52 static ecma_value_t c_setter_func_name (ROUTINE_ARG_LIST_1);
53 #define ACCESSOR_READ_ONLY(name, c_getter_func_name, prop_attributes) \
54 static ecma_value_t c_getter_func_name (ROUTINE_ARG_LIST_0);
55 #include BUILTIN_INC_HEADER_NAME
56 #undef ROUTINE_ARG_LIST_NON_FIXED
57 #undef ROUTINE_ARG_LIST_3
58 #undef ROUTINE_ARG_LIST_2
59 #undef ROUTINE_ARG_LIST_1
60 #undef ROUTINE_ARG_LIST_0
61 #undef ROUTINE_ARG
62
63 /**
64 * List of built-in routine identifiers.
65 */
66 enum
67 {
68 PASTE (ECMA_ROUTINE_START_, BUILTIN_UNDERSCORED_ID) = ECMA_BUILTIN_ID__COUNT - 1,
69 #define ROUTINE(name, c_function_name, args_number, length_prop_value) \
70 ECMA_ROUTINE_ ## name ## c_function_name,
71 #define ROUTINE_CONFIGURABLE_ONLY(name, c_function_name, args_number, length_prop_value) \
72 ECMA_ROUTINE_ ## name ## c_function_name,
73 #define ROUTINE_WITH_FLAGS(name, c_function_name, args_number, length_prop_value, flags) \
74 ECMA_ROUTINE_ ## name ## c_function_name,
75 #define ACCESSOR_READ_WRITE(name, c_getter_func_name, c_setter_func_name, prop_attributes) \
76 ECMA_ACCESSOR_ ## name ## c_getter_func_name, \
77 ECMA_ACCESSOR_ ## name ## c_setter_func_name,
78 #define ACCESSOR_READ_ONLY(name, c_getter_func_name, prop_attributes) \
79 ECMA_ACCESSOR_ ## name ## c_getter_func_name,
80 #include BUILTIN_INC_HEADER_NAME
81 };
82
83 #endif /* !BUILTIN_CUSTOM_DISPATCH */
84
85 /**
86 * Built-in property list of the built-in object.
87 */
88 const ecma_builtin_property_descriptor_t PROPERTY_DESCRIPTOR_LIST_NAME[] =
89 {
90 #ifndef BUILTIN_CUSTOM_DISPATCH
91 #define ROUTINE(name, c_function_name, args_number, length_prop_value) \
92 { \
93 name, \
94 ECMA_BUILTIN_PROPERTY_ROUTINE, \
95 ECMA_PROPERTY_CONFIGURABLE_WRITABLE, \
96 ECMA_ROUTINE_VALUE (ECMA_ROUTINE_ ## name ## c_function_name, length_prop_value) \
97 },
98 #define ROUTINE_CONFIGURABLE_ONLY(name, c_function_name, args_number, length_prop_value) \
99 { \
100 name, \
101 ECMA_BUILTIN_PROPERTY_ROUTINE, \
102 ECMA_PROPERTY_FLAG_CONFIGURABLE, \
103 ECMA_ROUTINE_VALUE (ECMA_ROUTINE_ ## name ## c_function_name, length_prop_value) \
104 },
105 #define ROUTINE_WITH_FLAGS(name, c_function_name, args_number, length_prop_value, flags) \
106 { \
107 name, \
108 ECMA_BUILTIN_PROPERTY_ROUTINE, \
109 flags, \
110 ECMA_ROUTINE_VALUE (ECMA_ROUTINE_ ## name ## c_function_name, length_prop_value) \
111 },
112 #define ACCESSOR_READ_ONLY(name, c_getter_func_name, prop_attributes) \
113 { \
114 name, \
115 ECMA_BUILTIN_PROPERTY_ACCESSOR_READ_ONLY, \
116 prop_attributes, \
117 ECMA_ACCESSOR_ ## name ## c_getter_func_name \
118 },
119 #define ACCESSOR_READ_WRITE(name, c_getter_func_name, c_setter_func_name, prop_attributes) \
120 { \
121 name, \
122 ECMA_BUILTIN_PROPERTY_ACCESSOR_READ_WRITE, \
123 prop_attributes, \
124 ECMA_ACCESSOR_READ_WRITE (ECMA_ACCESSOR_ ## name ## c_getter_func_name, \
125 ECMA_ACCESSOR_ ## name ## c_setter_func_name) \
126 },
127 #else /* BUILTIN_CUSTOM_DISPATCH */
128 #define ROUTINE(name, c_function_name, args_number, length_prop_value) \
129 { \
130 name, \
131 ECMA_BUILTIN_PROPERTY_ROUTINE, \
132 ECMA_PROPERTY_CONFIGURABLE_WRITABLE, \
133 ECMA_ROUTINE_VALUE (c_function_name, length_prop_value) \
134 },
135 #define ROUTINE_CONFIGURABLE_ONLY(name, c_function_name, args_number, length_prop_value) \
136 { \
137 name, \
138 ECMA_BUILTIN_PROPERTY_ROUTINE, \
139 ECMA_PROPERTY_FLAG_CONFIGURABLE, \
140 ECMA_ROUTINE_VALUE (c_function_name, length_prop_value) \
141 },
142 #define ROUTINE_WITH_FLAGS(name, c_function_name, args_number, length_prop_value, flags) \
143 { \
144 name, \
145 ECMA_BUILTIN_PROPERTY_ROUTINE, \
146 flags, \
147 ECMA_ROUTINE_VALUE (c_function_name, length_prop_value) \
148 },
149 #define ACCESSOR_READ_ONLY(name, c_getter_func_name, prop_attributes) \
150 { \
151 name, \
152 ECMA_BUILTIN_PROPERTY_ACCESSOR_READ_ONLY, \
153 prop_attributes, \
154 c_getter_func_name \
155 },
156 #define ACCESSOR_READ_WRITE(name, c_getter_func_name, c_setter_func_name, prop_attributes) \
157 { \
158 name, \
159 ECMA_BUILTIN_PROPERTY_ACCESSOR_READ_WRITE, \
160 prop_attributes, \
161 ECMA_ACCESSOR_READ_WRITE (c_getter_func_name, c_setter_func_name) \
162 },
163 #endif /* !BUILTIN_CUSTOM_DISPATCH */
164 #define OBJECT_VALUE(name, obj_builtin_id, prop_attributes) \
165 { \
166 name, \
167 ECMA_BUILTIN_PROPERTY_OBJECT, \
168 prop_attributes, \
169 obj_builtin_id \
170 },
171 #define SIMPLE_VALUE(name, simple_value, prop_attributes) \
172 { \
173 name, \
174 ECMA_BUILTIN_PROPERTY_SIMPLE, \
175 prop_attributes, \
176 simple_value \
177 },
178 #define NUMBER_VALUE(name, number_value, prop_attributes) \
179 { \
180 name, \
181 ECMA_BUILTIN_PROPERTY_NUMBER, \
182 prop_attributes, \
183 number_value \
184 },
185 #define STRING_VALUE(name, magic_string_id, prop_attributes) \
186 { \
187 name, \
188 ECMA_BUILTIN_PROPERTY_STRING, \
189 prop_attributes, \
190 magic_string_id \
191 },
192 #if ENABLED (JERRY_ES2015)
193 #define SYMBOL_VALUE(symbol, desc_magic_string_id) \
194 { \
195 symbol, \
196 ECMA_BUILTIN_PROPERTY_SYMBOL, \
197 ECMA_PROPERTY_FIXED, \
198 desc_magic_string_id \
199 },
200 #define INTRINSIC_PROPERTY(name, magic_string_id, prop_attributes) \
201 { \
202 name, \
203 ECMA_BUILTIN_PROPERTY_INTRINSIC_PROPERTY, \
204 prop_attributes, \
205 magic_string_id \
206 },
207 #define ACCESSOR_BUILTIN_FUNCTION(name, getter_builtin_id, setter_builtin_id, prop_attributes) \
208 { \
209 name, \
210 ECMA_BUILTIN_PROPERTY_ACCESSOR_BUILTIN_FUNCTION, \
211 prop_attributes, \
212 ECMA_ACCESSOR_READ_WRITE (getter_builtin_id, setter_builtin_id) \
213 },
214 #endif /* ENABLED (JERRY_ES2015) */
215 #include BUILTIN_INC_HEADER_NAME
216 {
217 LIT_MAGIC_STRING__COUNT,
218 ECMA_BUILTIN_PROPERTY_END,
219 0,
220 0
221 }
222 };
223
224 #ifndef BUILTIN_CUSTOM_DISPATCH
225
226 /**
227 * Dispatcher of the built-in's routines
228 *
229 * @return ecma value
230 * Returned value must be freed with ecma_free_value.
231 */
232 ecma_value_t
DISPATCH_ROUTINE_ROUTINE_NAME(uint16_t builtin_routine_id,ecma_value_t this_arg_value,const ecma_value_t arguments_list[],ecma_length_t arguments_number)233 DISPATCH_ROUTINE_ROUTINE_NAME (uint16_t builtin_routine_id, /**< built-in wide routine
234 identifier */
235 ecma_value_t this_arg_value, /**< 'this' argument
236 value */
237 const ecma_value_t arguments_list[], /**< list of arguments
238 passed to routine */
239 ecma_length_t arguments_number) /**< length of
240 arguments' list */
241 {
242 /* the arguments may be unused for some built-ins */
243 JERRY_UNUSED (this_arg_value);
244 JERRY_UNUSED (arguments_list);
245 JERRY_UNUSED (arguments_number);
246
247 switch (builtin_routine_id)
248 {
249 #define ROUTINE_ARG(n) (arguments_list[n - 1])
250 #define ROUTINE_ARG_LIST_0
251 #define ROUTINE_ARG_LIST_1 , ROUTINE_ARG(1)
252 #define ROUTINE_ARG_LIST_2 ROUTINE_ARG_LIST_1, ROUTINE_ARG(2)
253 #define ROUTINE_ARG_LIST_3 ROUTINE_ARG_LIST_2, ROUTINE_ARG(3)
254 #define ROUTINE_ARG_LIST_NON_FIXED , arguments_list, arguments_number
255 #define ROUTINE(name, c_function_name, args_number, length_prop_value) \
256 case ECMA_ROUTINE_ ## name ## c_function_name: \
257 { \
258 return c_function_name (this_arg_value ROUTINE_ARG_LIST_ ## args_number); \
259 }
260 #define ROUTINE_CONFIGURABLE_ONLY(name, c_function_name, args_number, length_prop_value) \
261 case ECMA_ROUTINE_ ## name ## c_function_name: \
262 { \
263 return c_function_name (this_arg_value ROUTINE_ARG_LIST_ ## args_number); \
264 }
265 #define ROUTINE_WITH_FLAGS(name, c_function_name, args_number, length_prop_value, flags) \
266 case ECMA_ROUTINE_ ## name ## c_function_name: \
267 { \
268 return c_function_name (this_arg_value ROUTINE_ARG_LIST_ ## args_number); \
269 }
270 #define ACCESSOR_READ_WRITE(name, c_getter_func_name, c_setter_func_name, prop_attributes) \
271 case ECMA_ACCESSOR_ ## name ## c_getter_func_name: \
272 { \
273 return c_getter_func_name(this_arg_value); \
274 } \
275 case ECMA_ACCESSOR_ ## name ## c_setter_func_name: \
276 { \
277 return c_setter_func_name(this_arg_value ROUTINE_ARG_LIST_1); \
278 }
279 #define ACCESSOR_READ_ONLY(name, c_getter_func_name, prop_attributes) \
280 case ECMA_ACCESSOR_ ## name ## c_getter_func_name: \
281 { \
282 return c_getter_func_name(this_arg_value); \
283 }
284 #include BUILTIN_INC_HEADER_NAME
285 #undef ROUTINE_ARG
286 #undef ROUTINE_ARG_LIST_0
287 #undef ROUTINE_ARG_LIST_1
288 #undef ROUTINE_ARG_LIST_2
289 #undef ROUTINE_ARG_LIST_3
290 #undef ROUTINE_ARG_LIST_NON_FIXED
291
292 default:
293 {
294 JERRY_UNREACHABLE ();
295 }
296 }
297 } /* DISPATCH_ROUTINE_ROUTINE_NAME */
298
299 #endif /* !BUILTIN_CUSTOM_DISPATCH */
300
301 #undef BUILTIN_INC_HEADER_NAME
302 #undef BUILTIN_CUSTOM_DISPATCH
303 #undef BUILTIN_UNDERSCORED_ID
304 #undef DISPATCH_ROUTINE_ROUTINE_NAME
305 #undef ECMA_BUILTIN_PROPERTY_NAME_INDEX
306 #undef PASTE__
307 #undef PASTE_
308 #undef PASTE
309 #undef PROPERTY_DESCRIPTOR_LIST_NAME
310