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 */
66enum
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 */
88const 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 */
232ecma_value_t
233DISPATCH_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