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 #include "ecma-alloc.h"
17 #include "ecma-builtin-helpers.h"
18 #include "ecma-exceptions.h"
19 #include "ecma-function-object.h"
20 #include "ecma-gc.h"
21 #include "ecma-helpers.h"
22 #include "lit-char-helpers.h"
23 #include "ecma-lex-env.h"
24 #include "ecma-objects.h"
25 #include "ecma-objects-general.h"
26 #include "ecma-objects-arguments.h"
27 #include "ecma-proxy-object.h"
28 #include "ecma-try-catch-macro.h"
29 #include "jcontext.h"
30
31 /** \addtogroup ecma ECMA
32 * @{
33 *
34 * \addtogroup ecmafunctionobject ECMA Function object related routines
35 * @{
36 */
37
38 #if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
39 /**
40 * Get the resource name from the compiled code header
41 *
42 * @return resource name as ecma-string
43 */
44 ecma_value_t
ecma_op_resource_name(const ecma_compiled_code_t * bytecode_header_p)45 ecma_op_resource_name (const ecma_compiled_code_t *bytecode_header_p)
46 {
47 JERRY_ASSERT (bytecode_header_p != NULL);
48
49 uint8_t *byte_p = (uint8_t *) bytecode_header_p;
50 byte_p += ((size_t) bytecode_header_p->size) << JMEM_ALIGNMENT_LOG;
51
52 ecma_value_t *resource_name_p = (ecma_value_t *) byte_p;
53 resource_name_p -= ecma_compiled_code_get_formal_params (bytecode_header_p);
54
55 #if ENABLED (JERRY_ES2015)
56 if (bytecode_header_p->status_flags & CBC_CODE_FLAG_HAS_TAGGED_LITERALS)
57 {
58 resource_name_p--;
59 }
60 #endif /* ENABLED (JERRY_ES2015) */
61
62 return resource_name_p[-1];
63 } /* ecma_op_resource_name */
64 #endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
65
66 /**
67 * IsCallable operation.
68 *
69 * See also: ECMA-262 v5, 9.11
70 *
71 * @return true - if the given object is callable;
72 * false - otherwise
73 */
74 inline bool JERRY_ATTR_ALWAYS_INLINE
ecma_op_object_is_callable(ecma_object_t * obj_p)75 ecma_op_object_is_callable (ecma_object_t *obj_p) /**< ecma object */
76 {
77 JERRY_ASSERT (!ecma_is_lexical_environment (obj_p));
78
79 const ecma_object_type_t type = ecma_get_object_type (obj_p);
80
81 #if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
82 if (ECMA_OBJECT_TYPE_IS_PROXY (type))
83 {
84 return ecma_op_is_callable (((ecma_proxy_object_t *) obj_p)->target);
85 }
86 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
87
88 return type >= ECMA_OBJECT_TYPE_FUNCTION;
89 } /* ecma_op_object_is_callable */
90
91 /**
92 * IsCallable operation.
93 *
94 * See also: ECMA-262 v5, 9.11
95 *
96 * @return true - if value is callable object;
97 * false - otherwise
98 */
99 bool
ecma_op_is_callable(ecma_value_t value)100 ecma_op_is_callable (ecma_value_t value) /**< ecma value */
101 {
102 return (ecma_is_value_object (value)
103 && ecma_op_object_is_callable (ecma_get_object_from_value (value)));
104 } /* ecma_op_is_callable */
105
106 /**
107 * Checks whether the given object implements [[Construct]].
108 *
109 * @return true - if the given object is constructor;
110 * false - otherwise
111 */
112 inline bool JERRY_ATTR_ALWAYS_INLINE
ecma_object_is_constructor(ecma_object_t * obj_p)113 ecma_object_is_constructor (ecma_object_t *obj_p) /**< ecma object */
114 {
115 JERRY_ASSERT (!ecma_is_lexical_environment (obj_p));
116
117 ecma_object_type_t type = ecma_get_object_type (obj_p);
118
119 while (type == ECMA_OBJECT_TYPE_BOUND_FUNCTION)
120 {
121 ecma_bound_function_t *bound_func_p = (ecma_bound_function_t *) obj_p;
122
123 obj_p = ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_object_t,
124 bound_func_p->header.u.bound_function.target_function);
125
126 type = ecma_get_object_type (obj_p);
127 }
128
129 #if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
130 if (ECMA_OBJECT_TYPE_IS_PROXY (type))
131 {
132 return ecma_is_constructor (((ecma_proxy_object_t *) obj_p)->target);
133 }
134 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
135
136 if (type == ECMA_OBJECT_TYPE_FUNCTION)
137 {
138 return (!ecma_get_object_is_builtin (obj_p) || !ecma_builtin_function_is_routine (obj_p));
139 }
140
141 return (type >= ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
142 } /* ecma_object_is_constructor */
143
144 /**
145 * Checks whether the value is Object that implements [[Construct]].
146 *
147 * @return true - if value is constructor object;
148 * false - otherwise
149 */
150 bool
ecma_is_constructor(ecma_value_t value)151 ecma_is_constructor (ecma_value_t value) /**< ecma value */
152 {
153 return (ecma_is_value_object (value)
154 && ecma_object_is_constructor (ecma_get_object_from_value (value)));
155 } /* ecma_is_constructor */
156
157 /**
158 * Helper method to count and convert the arguments for the Function/GeneratorFunction constructor call.
159 *
160 * See also:
161 * ECMA 262 v5.1 15.3.2.1 steps 5.a-d
162 * ECMA 262 v6 19.2.1.1.1 steps 8
163 *
164 * @return ecma value - concatenated arguments as a string.
165 * Returned value must be freed with ecma_free_value.
166 */
167 static ecma_string_t *
ecma_op_create_dynamic_function_arguments_helper(const ecma_value_t * arguments_list_p,ecma_length_t arguments_list_len)168 ecma_op_create_dynamic_function_arguments_helper (const ecma_value_t *arguments_list_p, /**< arguments list */
169 ecma_length_t arguments_list_len) /**< number of arguments */
170 {
171 JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
172
173 if (arguments_list_len <= 1)
174 {
175 return ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
176 }
177
178 ecma_string_t *str_p = ecma_op_to_string (arguments_list_p[0]);
179
180 if (JERRY_UNLIKELY (str_p == NULL))
181 {
182 return str_p;
183 }
184
185 if (arguments_list_len == 2)
186 {
187 return str_p;
188 }
189
190 ecma_stringbuilder_t builder = ecma_stringbuilder_create_from (str_p);
191 ecma_deref_ecma_string (str_p);
192
193 for (ecma_length_t idx = 1; idx < arguments_list_len - 1; idx++)
194 {
195 str_p = ecma_op_to_string (arguments_list_p[idx]);
196
197 if (JERRY_UNLIKELY (str_p == NULL))
198 {
199 ecma_stringbuilder_destroy (&builder);
200 return str_p;
201 }
202
203 ecma_stringbuilder_append_char (&builder, LIT_CHAR_COMMA);
204 ecma_stringbuilder_append (&builder, str_p);
205 ecma_deref_ecma_string (str_p);
206 }
207
208 return ecma_stringbuilder_finalize (&builder);
209 } /* ecma_op_create_dynamic_function_arguments_helper */
210
211 /**
212 * Function object creation operation.
213 *
214 * See also: ECMA-262 v5, 13.2
215 *
216 * @return pointer to newly created Function object
217 */
218 static ecma_object_t *
ecma_op_create_function_object(ecma_object_t * scope_p,const ecma_compiled_code_t * bytecode_data_p,ecma_builtin_id_t proto_id)219 ecma_op_create_function_object (ecma_object_t *scope_p, /**< function's scope */
220 const ecma_compiled_code_t *bytecode_data_p, /**< byte-code array */
221 ecma_builtin_id_t proto_id) /**< builtin id of the prototype object */
222 {
223 JERRY_ASSERT (ecma_is_lexical_environment (scope_p));
224
225 /* 1., 4., 13. */
226 ecma_object_t *prototype_obj_p = ecma_builtin_get (proto_id);
227
228 size_t function_object_size = sizeof (ecma_extended_object_t);
229
230 #if ENABLED (JERRY_SNAPSHOT_EXEC)
231 if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION)
232 {
233 function_object_size = sizeof (ecma_static_function_t);
234 }
235 #endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
236
237 ecma_object_t *func_p = ecma_create_object (prototype_obj_p,
238 function_object_size,
239 ECMA_OBJECT_TYPE_FUNCTION);
240
241 /* 2., 6., 7., 8. */
242 /*
243 * We don't setup [[Get]], [[Call]], [[Construct]], [[HasInstance]] for each function object.
244 * Instead we set the object's type to ECMA_OBJECT_TYPE_FUNCTION
245 * that defines which version of the routine should be used on demand.
246 */
247
248 /* 3. */
249 /*
250 * [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_FUNCTION type.
251 *
252 * See also: ecma_object_get_class_name
253 */
254
255 ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) func_p;
256
257 /* 9. */
258 ECMA_SET_NON_NULL_POINTER_TAG (ext_func_p->u.function.scope_cp, scope_p, 0);
259
260 /* 10., 11., 12. */
261
262 #if ENABLED (JERRY_SNAPSHOT_EXEC)
263 if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION)
264 {
265 ext_func_p->u.function.bytecode_cp = ECMA_NULL_POINTER;
266 ((ecma_static_function_t *) func_p)->bytecode_p = bytecode_data_p;
267 }
268 else
269 #endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
270 {
271 ECMA_SET_INTERNAL_VALUE_POINTER (ext_func_p->u.function.bytecode_cp, bytecode_data_p);
272 ecma_bytecode_ref ((ecma_compiled_code_t *) bytecode_data_p);
273 }
274
275 /* 14., 15., 16., 17., 18. */
276 /*
277 * 'length' and 'prototype' properties are instantiated lazily
278 *
279 * See also: ecma_op_function_try_to_lazy_instantiate_property
280 */
281
282 return func_p;
283 } /* ecma_op_create_function_object */
284
285 /**
286 * CreateDynamicFunction operation
287 *
288 * See also:
289 * ECMA-262 v5, 15.3.
290 * ECMA-262 v6, 19.2.1.1
291 *
292 * @return ECMA_VALUE_ERROR - if the operation fails
293 * constructed function object - otherwise
294 */
295 ecma_value_t
ecma_op_create_dynamic_function(const ecma_value_t * arguments_list_p,ecma_length_t arguments_list_len,ecma_parse_opts_t parse_opts)296 ecma_op_create_dynamic_function (const ecma_value_t *arguments_list_p, /**< arguments list */
297 ecma_length_t arguments_list_len, /**< number of arguments */
298 ecma_parse_opts_t parse_opts) /**< parse options */
299 {
300 JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
301
302 ecma_string_t *arguments_str_p = ecma_op_create_dynamic_function_arguments_helper (arguments_list_p,
303 arguments_list_len);
304
305 if (JERRY_UNLIKELY (arguments_str_p == NULL))
306 {
307 return ECMA_VALUE_ERROR;
308 }
309
310 ecma_string_t *function_body_str_p;
311
312 if (arguments_list_len > 0)
313 {
314 function_body_str_p = ecma_op_to_string (arguments_list_p[arguments_list_len - 1]);
315
316 if (JERRY_UNLIKELY (function_body_str_p == NULL))
317 {
318 ecma_deref_ecma_string (arguments_str_p);
319 return ECMA_VALUE_ERROR;
320 }
321 }
322 else
323 {
324 /* Very unlikely code path, not optimized. */
325 function_body_str_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
326 }
327
328 ECMA_STRING_TO_UTF8_STRING (arguments_str_p, arguments_buffer_p, arguments_buffer_size);
329 ECMA_STRING_TO_UTF8_STRING (function_body_str_p, function_body_buffer_p, function_body_buffer_size);
330
331 #if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
332 JERRY_CONTEXT (resource_name) = ecma_make_magic_string_value (LIT_MAGIC_STRING_RESOURCE_ANON);
333 #endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
334
335 ecma_compiled_code_t *bytecode_data_p = NULL;
336
337 ecma_value_t ret_value = parser_parse_script (arguments_buffer_p,
338 arguments_buffer_size,
339 function_body_buffer_p,
340 function_body_buffer_size,
341 parse_opts,
342 &bytecode_data_p);
343
344 if (!ECMA_IS_VALUE_ERROR (ret_value))
345 {
346 JERRY_ASSERT (ecma_is_value_true (ret_value));
347
348 ecma_object_t *global_env_p = ecma_get_global_environment ();
349 ecma_builtin_id_t fallback_proto = ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE;
350
351 #if ENABLED (JERRY_ES2015)
352 ecma_object_t *new_target_p = JERRY_CONTEXT (current_new_target);
353 bool is_generator_func = parse_opts & ECMA_PARSE_GENERATOR_FUNCTION;
354
355 if (is_generator_func)
356 {
357 fallback_proto = ECMA_BUILTIN_ID_GENERATOR;
358 }
359
360 if (new_target_p == NULL)
361 {
362 if (is_generator_func)
363 {
364 new_target_p = ecma_builtin_get (ECMA_BUILTIN_ID_GENERATOR_FUNCTION);
365 }
366 else
367 {
368 new_target_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION);
369 }
370 }
371
372 ecma_object_t *proto = ecma_op_get_prototype_from_constructor (new_target_p, fallback_proto);
373
374 if (JERRY_UNLIKELY (proto == NULL))
375 {
376 ecma_bytecode_deref (bytecode_data_p);
377 ecma_deref_ecma_string (arguments_str_p);
378 ecma_deref_ecma_string (function_body_str_p);
379 return ECMA_VALUE_ERROR;
380 }
381 #endif /* ENABLED (JERRY_ES2015) */
382
383 ecma_object_t *func_obj_p = ecma_op_create_function_object (global_env_p, bytecode_data_p, fallback_proto);
384
385 #if ENABLED (JERRY_ES2015)
386 ECMA_SET_NON_NULL_POINTER (func_obj_p->u2.prototype_cp, proto);
387 ecma_deref_object (proto);
388 #endif /* ENABLED (JERRY_ES2015) */
389
390 ecma_bytecode_deref (bytecode_data_p);
391 ret_value = ecma_make_object_value (func_obj_p);
392 }
393
394 ECMA_FINALIZE_UTF8_STRING (function_body_buffer_p, function_body_buffer_size);
395 ECMA_FINALIZE_UTF8_STRING (arguments_buffer_p, arguments_buffer_size);
396
397 ecma_deref_ecma_string (arguments_str_p);
398 ecma_deref_ecma_string (function_body_str_p);
399
400 return ret_value;
401 } /* ecma_op_create_dynamic_function */
402
403 /**
404 * Function object creation operation.
405 *
406 * See also: ECMA-262 v5, 13.2
407 *
408 * @return pointer to newly created Function object
409 */
410 ecma_object_t *
ecma_op_create_simple_function_object(ecma_object_t * scope_p,const ecma_compiled_code_t * bytecode_data_p)411 ecma_op_create_simple_function_object (ecma_object_t *scope_p, /**< function's scope */
412 const ecma_compiled_code_t *bytecode_data_p) /**< byte-code array */
413 {
414 return ecma_op_create_function_object (scope_p, bytecode_data_p, ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
415 } /* ecma_op_create_simple_function_object */
416
417 #if ENABLED (JERRY_ES2015)
418
419 /**
420 * GeneratorFunction object creation operation.
421 *
422 * See also: ECMA-262 v5, 13.2
423 *
424 * @return pointer to newly created Function object
425 */
426 ecma_object_t *
ecma_op_create_generator_function_object(ecma_object_t * scope_p,const ecma_compiled_code_t * bytecode_data_p)427 ecma_op_create_generator_function_object (ecma_object_t *scope_p, /**< function's scope */
428 const ecma_compiled_code_t *bytecode_data_p) /**< byte-code array */
429 {
430 return ecma_op_create_function_object (scope_p, bytecode_data_p, ECMA_BUILTIN_ID_GENERATOR);
431 } /* ecma_op_create_generator_function_object */
432
433 /**
434 * Arrow function object creation operation.
435 *
436 * See also: ES2015, 9.2.12
437 *
438 * @return pointer to newly created Function object
439 */
440 ecma_object_t *
ecma_op_create_arrow_function_object(ecma_object_t * scope_p,const ecma_compiled_code_t * bytecode_data_p,ecma_value_t this_binding)441 ecma_op_create_arrow_function_object (ecma_object_t *scope_p, /**< function's scope */
442 const ecma_compiled_code_t *bytecode_data_p, /**< byte-code array */
443 ecma_value_t this_binding) /**< value of 'this' binding */
444 {
445 ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
446
447 size_t arrow_function_object_size = sizeof (ecma_arrow_function_t);
448
449 #if ENABLED (JERRY_SNAPSHOT_EXEC)
450 if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION)
451 {
452 arrow_function_object_size = sizeof (ecma_static_arrow_function_t);
453 }
454 #endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
455
456 ecma_object_t *func_p = ecma_create_object (prototype_obj_p,
457 arrow_function_object_size,
458 ECMA_OBJECT_TYPE_FUNCTION);
459
460 ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) func_p;
461
462 ECMA_SET_NON_NULL_POINTER_TAG (arrow_func_p->header.u.function.scope_cp, scope_p, 0);
463
464 #if ENABLED (JERRY_SNAPSHOT_EXEC)
465 if ((bytecode_data_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION))
466 {
467 arrow_func_p->header.u.function.bytecode_cp = ECMA_NULL_POINTER;
468 ((ecma_static_arrow_function_t *) func_p)->bytecode_p = bytecode_data_p;
469 }
470 else
471 {
472 #endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
473 ECMA_SET_INTERNAL_VALUE_POINTER (arrow_func_p->header.u.function.bytecode_cp, bytecode_data_p);
474 ecma_bytecode_ref ((ecma_compiled_code_t *) bytecode_data_p);
475 #if ENABLED (JERRY_SNAPSHOT_EXEC)
476 }
477 #endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
478
479 arrow_func_p->this_binding = ecma_copy_value_if_not_object (this_binding);
480 arrow_func_p->new_target = ECMA_VALUE_UNDEFINED;
481
482 if (JERRY_CONTEXT (current_new_target) != NULL)
483 {
484 arrow_func_p->new_target = ecma_make_object_value (JERRY_CONTEXT (current_new_target));
485 }
486 return func_p;
487 } /* ecma_op_create_arrow_function_object */
488
489 #endif /* ENABLED (JERRY_ES2015) */
490
491 /**
492 * External function object creation operation.
493 *
494 * Note:
495 * external function object is implementation-defined object type
496 * that represent functions implemented in native code, using Embedding API
497 *
498 * @return pointer to newly created external function object
499 */
500 ecma_object_t *
ecma_op_create_external_function_object(ecma_external_handler_t handler_cb)501 ecma_op_create_external_function_object (ecma_external_handler_t handler_cb) /**< pointer to external native handler */
502 {
503 ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
504
505 ecma_object_t *function_obj_p;
506 function_obj_p = ecma_create_object (prototype_obj_p,
507 sizeof (ecma_extended_object_t),
508 ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
509
510 /*
511 * [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION type.
512 *
513 * See also: ecma_object_get_class_name
514 */
515
516 ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) function_obj_p;
517 ext_func_obj_p->u.external_handler_cb = handler_cb;
518
519 return function_obj_p;
520 } /* ecma_op_create_external_function_object */
521
522 /**
523 * Get compiled code of a function object.
524 *
525 * @return compiled code
526 */
527 inline const ecma_compiled_code_t * JERRY_ATTR_ALWAYS_INLINE
ecma_op_function_get_compiled_code(ecma_extended_object_t * function_p)528 ecma_op_function_get_compiled_code (ecma_extended_object_t *function_p) /**< function pointer */
529 {
530 #if ENABLED (JERRY_SNAPSHOT_EXEC)
531 if (function_p->u.function.bytecode_cp != ECMA_NULL_POINTER)
532 {
533 return ECMA_GET_INTERNAL_VALUE_POINTER (const ecma_compiled_code_t,
534 function_p->u.function.bytecode_cp);
535 }
536 else
537 {
538 return ((ecma_static_function_t *) function_p)->bytecode_p;
539 }
540 #else /* !ENABLED (JERRY_SNAPSHOT_EXEC) */
541 return ECMA_GET_INTERNAL_VALUE_POINTER (const ecma_compiled_code_t,
542 function_p->u.function.bytecode_cp);
543 #endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
544 } /* ecma_op_function_get_compiled_code */
545
546 #if ENABLED (JERRY_ES2015)
547 /**
548 * Check whether the given object [[FunctionKind]] internal slot value is "generator".
549 *
550 * @return true - if the given object is a generator function
551 * false - otherwise
552 */
553 bool
ecma_op_function_is_generator(ecma_object_t * obj_p)554 ecma_op_function_is_generator (ecma_object_t *obj_p) /**< object */
555 {
556 if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION
557 && !ecma_get_object_is_builtin (obj_p))
558 {
559 ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) obj_p;
560 const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_obj_p);
561
562 return (bytecode_data_p->status_flags & CBC_CODE_FLAGS_GENERATOR) != 0;
563 }
564
565 return false;
566 } /* ecma_op_function_is_generator */
567
568 #endif /* ENABLED (JERRY_ES2015) */
569
570 /**
571 * 15.3.5.3 implementation of [[HasInstance]] for Function objects
572 *
573 * @return true/false - if arguments are valid
574 * error - otherwise
575 * Returned value must be freed with ecma_free_value
576 */
577 ecma_value_t
ecma_op_function_has_instance(ecma_object_t * func_obj_p,ecma_value_t value)578 ecma_op_function_has_instance (ecma_object_t *func_obj_p, /**< Function object */
579 ecma_value_t value) /**< argument 'V' */
580 {
581 JERRY_ASSERT (func_obj_p != NULL
582 && !ecma_is_lexical_environment (func_obj_p));
583
584 if (!ecma_is_value_object (value))
585 {
586 return ECMA_VALUE_FALSE;
587 }
588
589 while (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION)
590 {
591 JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION);
592
593 /* 1. 3. */
594 ecma_bound_function_t *bound_func_p = (ecma_bound_function_t *) func_obj_p;
595
596 func_obj_p = ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_object_t,
597 bound_func_p->header.u.bound_function.target_function);
598 }
599
600 JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION
601 || ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION
602 || ECMA_OBJECT_IS_PROXY (func_obj_p));
603
604 ecma_object_t *v_obj_p = ecma_get_object_from_value (value);
605
606 ecma_value_t prototype_obj_value = ecma_op_object_get_by_magic_id (func_obj_p,
607 LIT_MAGIC_STRING_PROTOTYPE);
608
609 if (ECMA_IS_VALUE_ERROR (prototype_obj_value))
610 {
611 return prototype_obj_value;
612 }
613
614 if (!ecma_is_value_object (prototype_obj_value))
615 {
616 ecma_free_value (prototype_obj_value);
617 return ecma_raise_type_error (ECMA_ERR_MSG ("Object expected."));
618 }
619
620 ecma_object_t *prototype_obj_p = ecma_get_object_from_value (prototype_obj_value);
621 JERRY_ASSERT (prototype_obj_p != NULL);
622
623 #if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
624 ecma_value_t result = ECMA_VALUE_ERROR;
625 #else /* !ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
626 ecma_value_t result = ECMA_VALUE_FALSE;
627 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
628
629 while (true)
630 {
631 jmem_cpointer_t v_obj_cp;
632 #if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
633 if (ECMA_OBJECT_IS_PROXY (v_obj_p))
634 {
635 ecma_value_t parent = ecma_proxy_object_get_prototype_of (v_obj_p);
636
637 if (ECMA_IS_VALUE_ERROR (parent))
638 {
639 break;
640 }
641
642 v_obj_cp = ecma_proxy_object_prototype_to_cp (parent);
643 }
644 else
645 {
646 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
647 v_obj_cp = ecma_op_ordinary_object_get_prototype_of (v_obj_p);
648 #if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
649 }
650 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
651
652 if (v_obj_cp == JMEM_CP_NULL)
653 {
654 #if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
655 result = ECMA_VALUE_FALSE;
656 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
657 break;
658 }
659
660 v_obj_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, v_obj_cp);
661
662 if (v_obj_p == prototype_obj_p)
663 {
664 result = ECMA_VALUE_TRUE;
665 break;
666 }
667 }
668
669 ecma_deref_object (prototype_obj_p);
670 return result;
671 } /* ecma_op_function_has_instance */
672
673 #if ENABLED (JERRY_ES2015)
674
675 /**
676 * GetSuperConstructor operation for class methods
677 *
678 * See also: ECMAScript v6, 12.3.5.2
679 *
680 * @return ECMA_VALUE_ERROR - if the operation fails
681 * super constructor - otherwise
682 */
683 ecma_value_t
ecma_op_function_get_super_constructor(ecma_object_t * func_obj_p)684 ecma_op_function_get_super_constructor (ecma_object_t *func_obj_p) /**< function object */
685 {
686 ecma_object_t *super_ctor_p;
687
688 #if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
689 if (ECMA_OBJECT_IS_PROXY (func_obj_p))
690 {
691 ecma_value_t super_ctor = ecma_proxy_object_get_prototype_of (func_obj_p);
692
693 if (ECMA_IS_VALUE_ERROR (super_ctor))
694 {
695 return super_ctor;
696 }
697
698 super_ctor_p = ecma_is_value_null (super_ctor) ? NULL : ecma_get_object_from_value (super_ctor);
699 }
700 else
701 {
702 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
703 jmem_cpointer_t proto_cp = ecma_op_ordinary_object_get_prototype_of (func_obj_p);
704 if (proto_cp == JMEM_CP_NULL)
705 {
706 super_ctor_p = NULL;
707 }
708 else
709 {
710 super_ctor_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, proto_cp);
711 ecma_ref_object (super_ctor_p);
712 }
713 #if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
714 }
715 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
716
717 if (super_ctor_p == NULL || !ecma_object_is_constructor (super_ctor_p))
718 {
719 if (super_ctor_p != NULL)
720 {
721 ecma_deref_object (super_ctor_p);
722 }
723 return ecma_raise_type_error (ECMA_ERR_MSG ("Super binding must be a constructor."));
724 }
725
726 return ecma_make_object_value (super_ctor_p);
727 } /* ecma_op_function_get_super_constructor */
728 #endif /* ENABLED (JERRY_ES2015) */
729
730 /**
731 * Ordinary internal method: GetPrototypeFromConstructor (constructor, intrinsicDefaultProto)
732 *
733 * See also: ECMAScript v6, 9.1.15
734 *
735 * @return NULL - if the operation fail (exception on the global context is raised)
736 * pointer to the prototype object - otherwise
737 */
738 ecma_object_t *
ecma_op_get_prototype_from_constructor(ecma_object_t * ctor_obj_p,ecma_builtin_id_t default_proto_id)739 ecma_op_get_prototype_from_constructor (ecma_object_t *ctor_obj_p, /**< constructor to get prototype from */
740 ecma_builtin_id_t default_proto_id) /**< intrinsicDefaultProto */
741 {
742 JERRY_ASSERT (ecma_object_is_constructor (ctor_obj_p));
743 JERRY_ASSERT (default_proto_id < ECMA_BUILTIN_ID__COUNT);
744
745 ecma_value_t proto = ecma_op_object_get_by_magic_id (ctor_obj_p, LIT_MAGIC_STRING_PROTOTYPE);
746
747 if (ECMA_IS_VALUE_ERROR (proto))
748 {
749 return NULL;
750 }
751
752 ecma_object_t *proto_obj_p;
753
754 if (!ecma_is_value_object (proto))
755 {
756 ecma_free_value (proto);
757 proto_obj_p = ecma_builtin_get (default_proto_id);
758 ecma_ref_object (proto_obj_p);
759 }
760 else
761 {
762 proto_obj_p = ecma_get_object_from_value (proto);
763 }
764
765 return proto_obj_p;
766 } /* ecma_op_get_prototype_from_constructor */
767
768 /**
769 * Perform a JavaScript function object method call.
770 *
771 * The input function object should be a pure JavaScript method
772 *
773 * @return the result of the function call.
774 */
775 static ecma_value_t
ecma_op_function_call_simple(ecma_object_t * func_obj_p,ecma_value_t this_arg_value,const ecma_value_t * arguments_list_p,ecma_length_t arguments_list_len)776 ecma_op_function_call_simple (ecma_object_t *func_obj_p, /**< Function object */
777 ecma_value_t this_arg_value, /**< 'this' argument's value */
778 const ecma_value_t *arguments_list_p, /**< arguments list */
779 ecma_length_t arguments_list_len) /**< length of arguments list */
780 {
781 JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION);
782
783 if (JERRY_UNLIKELY (ecma_get_object_is_builtin (func_obj_p)))
784 {
785 return ecma_builtin_dispatch_call (func_obj_p, this_arg_value, arguments_list_p, arguments_list_len);
786 }
787
788 /* Entering Function Code (ECMA-262 v5, 10.4.3) */
789 ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) func_obj_p;
790
791 ecma_object_t *scope_p = ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_object_t,
792 ext_func_p->u.function.scope_cp);
793
794 /* 8. */
795 ecma_value_t this_binding = this_arg_value;
796 bool free_this_binding = false;
797
798 const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p);
799 uint16_t status_flags = bytecode_data_p->status_flags;
800
801 #if ENABLED (JERRY_ES2015)
802 bool is_construct_call = JERRY_CONTEXT (current_new_target) != NULL;
803 if (JERRY_UNLIKELY (status_flags & (CBC_CODE_FLAGS_CLASS_CONSTRUCTOR | CBC_CODE_FLAGS_GENERATOR)))
804 {
805 if (!is_construct_call && (status_flags & CBC_CODE_FLAGS_CLASS_CONSTRUCTOR))
806 {
807 return ecma_raise_type_error (ECMA_ERR_MSG ("Class constructor cannot be invoked without 'new'."));
808 }
809
810 if ((status_flags & CBC_CODE_FLAGS_GENERATOR) && is_construct_call)
811 {
812 return ecma_raise_type_error (ECMA_ERR_MSG ("Generator functions cannot be invoked with 'new'."));
813 }
814 }
815 #endif /* ENABLED (JERRY_ES2015) */
816
817 /* 1. */
818 #if ENABLED (JERRY_ES2015)
819 ecma_object_t *old_function_object_p = JERRY_CONTEXT (current_function_obj_p);
820
821 if (JERRY_UNLIKELY (status_flags & CBC_CODE_FLAGS_ARROW_FUNCTION))
822 {
823 ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) func_obj_p;
824
825 if (ecma_is_value_undefined (arrow_func_p->new_target))
826 {
827 JERRY_CONTEXT (current_new_target) = NULL;
828 }
829 else
830 {
831 JERRY_CONTEXT (current_new_target) = ecma_get_object_from_value (arrow_func_p->new_target);
832 }
833 this_binding = arrow_func_p->this_binding;
834 }
835 else
836 {
837 JERRY_CONTEXT (current_function_obj_p) = func_obj_p;
838 #endif /* ENABLED (JERRY_ES2015) */
839 if (!(status_flags & CBC_CODE_FLAGS_STRICT_MODE))
840 {
841 if (ecma_is_value_undefined (this_binding)
842 || ecma_is_value_null (this_binding))
843 {
844 /* 2. */
845 this_binding = ecma_make_object_value (ecma_builtin_get_global ());
846 }
847 else if (!ecma_is_value_object (this_binding))
848 {
849 /* 3., 4. */
850 this_binding = ecma_op_to_object (this_binding);
851 free_this_binding = true;
852
853 JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (this_binding));
854 }
855 }
856 #if ENABLED (JERRY_ES2015)
857 }
858 #endif /* ENABLED (JERRY_ES2015) */
859
860 /* 5. */
861 ecma_object_t *local_env_p;
862 if (status_flags & CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED)
863 {
864 local_env_p = scope_p;
865 }
866 else
867 {
868 local_env_p = ecma_create_decl_lex_env (scope_p);
869 if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_IS_ARGUMENTS_NEEDED)
870 {
871 ecma_op_create_arguments_object (func_obj_p,
872 local_env_p,
873 arguments_list_p,
874 arguments_list_len,
875 bytecode_data_p);
876 }
877 #if ENABLED (JERRY_ES2015)
878 // ECMAScript v6, 9.2.2.8
879 if (JERRY_UNLIKELY (status_flags & CBC_CODE_FLAGS_CLASS_CONSTRUCTOR))
880 {
881 ecma_value_t lexical_this;
882 lexical_this = (ECMA_GET_THIRD_BIT_FROM_POINTER_TAG (ext_func_p->u.function.scope_cp) ? ECMA_VALUE_UNINITIALIZED
883 : this_binding);
884 ecma_op_init_this_binding (local_env_p, lexical_this);
885 }
886 #endif /* ENABLED (JERRY_ES2015) */
887 }
888
889 ecma_value_t ret_value = vm_run (bytecode_data_p,
890 this_binding,
891 local_env_p,
892 arguments_list_p,
893 arguments_list_len);
894
895 #if ENABLED (JERRY_ES2015)
896 JERRY_CONTEXT (current_function_obj_p) = old_function_object_p;
897
898 /* ECMAScript v6, 9.2.2.13 */
899 if (ECMA_GET_THIRD_BIT_FROM_POINTER_TAG (ext_func_p->u.function.scope_cp))
900 {
901 if (!ECMA_IS_VALUE_ERROR (ret_value) && !ecma_is_value_object (ret_value))
902 {
903 if (!ecma_is_value_undefined (ret_value))
904 {
905 ecma_free_value (ret_value);
906 ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Derived constructors may only return object or undefined."));
907 }
908 else
909 {
910 ret_value = ecma_op_get_this_binding (local_env_p);
911 }
912 }
913 }
914
915 #endif /* ENABLED (JERRY_ES2015) */
916
917 if (!(status_flags & CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED))
918 {
919 ecma_deref_object (local_env_p);
920 }
921
922 if (JERRY_UNLIKELY (free_this_binding))
923 {
924 ecma_free_value (this_binding);
925 }
926
927 return ret_value;
928 } /* ecma_op_function_call_simple */
929
930 /**
931 * Perform a native C method call which was registered via the API.
932 *
933 * @return the result of the function call.
934 */
935 static ecma_value_t JERRY_ATTR_NOINLINE
ecma_op_function_call_external(ecma_object_t * func_obj_p,ecma_value_t this_arg_value,const ecma_value_t * arguments_list_p,ecma_length_t arguments_list_len)936 ecma_op_function_call_external (ecma_object_t *func_obj_p, /**< Function object */
937 ecma_value_t this_arg_value, /**< 'this' argument's value */
938 const ecma_value_t *arguments_list_p, /**< arguments list */
939 ecma_length_t arguments_list_len) /**< length of arguments list */
940
941 {
942 JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
943 ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) func_obj_p;
944 JERRY_ASSERT (ext_func_obj_p->u.external_handler_cb != NULL);
945
946 ecma_value_t ret_value = ext_func_obj_p->u.external_handler_cb (ecma_make_object_value (func_obj_p),
947 this_arg_value,
948 arguments_list_p,
949 arguments_list_len);
950 if (JERRY_UNLIKELY (ecma_is_value_error_reference (ret_value)))
951 {
952 ecma_raise_error_from_error_reference (ret_value);
953 return ECMA_VALUE_ERROR;
954 }
955
956 #if ENABLED (JERRY_DEBUGGER)
957 JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_EXCEPTION_THROWN);
958 #endif /* ENABLED (JERRY_DEBUGGER) */
959 return ret_value;
960 } /* ecma_op_function_call_external */
961
962 /**
963 * Append the bound arguments into the given collection
964 *
965 * Note:
966 * - The whole bound chain is resolved
967 * - The first element of the collection contains the bounded this value
968 *
969 * @return target function of the bound function
970 */
971 JERRY_ATTR_NOINLINE static ecma_object_t *
ecma_op_bound_function_get_argument_list(ecma_object_t * func_obj_p,ecma_collection_t * list_p)972 ecma_op_bound_function_get_argument_list (ecma_object_t *func_obj_p, /**< bound bunction object */
973 ecma_collection_t *list_p) /**< list of arguments */
974 {
975 JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION);
976
977 ecma_bound_function_t *bound_func_p = (ecma_bound_function_t *) func_obj_p;
978
979 func_obj_p = ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_object_t,
980 bound_func_p->header.u.bound_function.target_function);
981
982 ecma_value_t args_len_or_this = bound_func_p->header.u.bound_function.args_len_or_this;
983
984 ecma_length_t args_length = 1;
985
986 if (ecma_is_value_integer_number (args_len_or_this))
987 {
988 args_length = (ecma_length_t) ecma_get_integer_from_value (args_len_or_this);
989 }
990
991 /* 5. */
992 if (args_length != 1)
993 {
994 const ecma_value_t *args_p = (const ecma_value_t *) (bound_func_p + 1);
995 list_p->buffer_p[0] = *args_p;
996
997 if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION)
998 {
999 func_obj_p = ecma_op_bound_function_get_argument_list (func_obj_p, list_p);
1000 }
1001 ecma_collection_append (list_p, args_p + 1, args_length - 1);
1002 }
1003 else
1004 {
1005 list_p->buffer_p[0] = args_len_or_this;
1006 }
1007
1008 return func_obj_p;
1009 } /* ecma_op_bound_function_get_argument_list */
1010
1011 /**
1012 * [[Call]] internal method for bound function objects
1013 *
1014 * @return ecma value
1015 * Returned value must be freed with ecma_free_value
1016 */
1017 static ecma_value_t JERRY_ATTR_NOINLINE
ecma_op_function_call_bound(ecma_object_t * func_obj_p,const ecma_value_t * arguments_list_p,ecma_length_t arguments_list_len)1018 ecma_op_function_call_bound (ecma_object_t *func_obj_p, /**< Function object */
1019 const ecma_value_t *arguments_list_p, /**< arguments list */
1020 ecma_length_t arguments_list_len) /**< length of arguments list */
1021 {
1022 JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION);
1023
1024 JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_DIRECT_EVAL;
1025
1026 ecma_collection_t *bound_arg_list_p = ecma_new_collection ();
1027 ecma_collection_push_back (bound_arg_list_p, ECMA_VALUE_EMPTY);
1028
1029 ecma_object_t *target_obj_p = ecma_op_bound_function_get_argument_list (func_obj_p, bound_arg_list_p);
1030
1031 ecma_collection_append (bound_arg_list_p, arguments_list_p, arguments_list_len);
1032
1033 JERRY_ASSERT (!ecma_is_value_empty (bound_arg_list_p->buffer_p[0]));
1034
1035 ecma_value_t ret_value = ecma_op_function_call (target_obj_p,
1036 bound_arg_list_p->buffer_p[0],
1037 bound_arg_list_p->buffer_p + 1,
1038 (ecma_length_t) (bound_arg_list_p->item_count - 1));
1039
1040 ecma_collection_destroy (bound_arg_list_p);
1041
1042 return ret_value;
1043 } /* ecma_op_function_call_bound */
1044
1045 /**
1046 * [[Call]] implementation for Function objects,
1047 * created through 13.2 (ECMA_OBJECT_TYPE_FUNCTION)
1048 * or 15.3.4.5 (ECMA_OBJECT_TYPE_BOUND_FUNCTION),
1049 * and for built-in Function objects
1050 * from section 15 (ECMA_OBJECT_TYPE_FUNCTION).
1051 *
1052 * @return ecma value
1053 * Returned value must be freed with ecma_free_value
1054 */
1055 ecma_value_t
ecma_op_function_call(ecma_object_t * func_obj_p,ecma_value_t this_arg_value,const ecma_value_t * arguments_list_p,ecma_length_t arguments_list_len)1056 ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
1057 ecma_value_t this_arg_value, /**< 'this' argument's value */
1058 const ecma_value_t *arguments_list_p, /**< arguments list */
1059 ecma_length_t arguments_list_len) /**< length of arguments list */
1060 {
1061 JERRY_ASSERT (func_obj_p != NULL
1062 && !ecma_is_lexical_environment (func_obj_p));
1063 JERRY_ASSERT (ecma_op_object_is_callable (func_obj_p));
1064
1065 ECMA_CHECK_STACK_USAGE ();
1066
1067 const ecma_object_type_t type = ecma_get_object_type (func_obj_p);
1068
1069 #if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
1070 if (ECMA_OBJECT_TYPE_IS_PROXY (type))
1071 {
1072 return ecma_proxy_object_call (func_obj_p, this_arg_value, arguments_list_p, arguments_list_len);
1073 }
1074 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
1075
1076 #if ENABLED (JERRY_ES2015)
1077 ecma_object_t *old_new_target_p = JERRY_CONTEXT (current_new_target);
1078 if (JERRY_UNLIKELY (!(JERRY_CONTEXT (status_flags) & ECMA_STATUS_DIRECT_EVAL)))
1079 {
1080 JERRY_CONTEXT (current_new_target) = NULL;
1081 }
1082 #endif /* ENABLED (JERRY_ES2015) */
1083
1084 ecma_value_t result;
1085
1086 if (JERRY_LIKELY (type == ECMA_OBJECT_TYPE_FUNCTION))
1087 {
1088 result = ecma_op_function_call_simple (func_obj_p, this_arg_value, arguments_list_p, arguments_list_len);
1089 }
1090 else if (type == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION)
1091 {
1092 result = ecma_op_function_call_external (func_obj_p, this_arg_value, arguments_list_p, arguments_list_len);
1093 }
1094 else
1095 {
1096 result = ecma_op_function_call_bound (func_obj_p, arguments_list_p, arguments_list_len);
1097 }
1098
1099 #if ENABLED (JERRY_ES2015)
1100 JERRY_CONTEXT (current_new_target) = old_new_target_p;
1101 #endif /* ENABLED (JERRY_ES2015) */
1102
1103 return result;
1104 } /* ecma_op_function_call */
1105
1106 /**
1107 * [[Construct]] internal method for bound function objects
1108 *
1109 * @return ecma value
1110 * Returned value must be freed with ecma_free_value
1111 */
1112 static ecma_value_t JERRY_ATTR_NOINLINE
ecma_op_function_construct_bound(ecma_object_t * func_obj_p,ecma_object_t * new_target_p,const ecma_value_t * arguments_list_p,ecma_length_t arguments_list_len)1113 ecma_op_function_construct_bound (ecma_object_t *func_obj_p, /**< Function object */
1114 ecma_object_t *new_target_p, /**< new target */
1115 const ecma_value_t *arguments_list_p, /**< arguments list */
1116 ecma_length_t arguments_list_len) /**< length of arguments list */
1117 {
1118 JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION);
1119
1120 ecma_collection_t *bound_arg_list_p = ecma_new_collection ();
1121 ecma_collection_push_back (bound_arg_list_p, ECMA_VALUE_EMPTY);
1122
1123 ecma_object_t *target_obj_p = ecma_op_bound_function_get_argument_list (func_obj_p, bound_arg_list_p);
1124
1125 ecma_collection_append (bound_arg_list_p, arguments_list_p, arguments_list_len);
1126
1127 if (func_obj_p == new_target_p)
1128 {
1129 new_target_p = target_obj_p;
1130 }
1131
1132 ecma_value_t ret_value = ecma_op_function_construct (target_obj_p,
1133 new_target_p,
1134 bound_arg_list_p->buffer_p + 1,
1135 (ecma_length_t) (bound_arg_list_p->item_count - 1));
1136
1137 ecma_collection_destroy (bound_arg_list_p);
1138
1139 return ret_value;
1140 } /* ecma_op_function_construct_bound */
1141
1142 /**
1143 * [[Construct]] internal method for external function objects
1144 *
1145 * @return ecma value
1146 * Returned value must be freed with ecma_free_value
1147 */
1148 static ecma_value_t JERRY_ATTR_NOINLINE
ecma_op_function_construct_external(ecma_object_t * func_obj_p,ecma_object_t * new_target_p,const ecma_value_t * arguments_list_p,ecma_length_t arguments_list_len)1149 ecma_op_function_construct_external (ecma_object_t *func_obj_p, /**< Function object */
1150 ecma_object_t *new_target_p, /**< new target */
1151 const ecma_value_t *arguments_list_p, /**< arguments list */
1152 ecma_length_t arguments_list_len) /**< length of arguments list */
1153 {
1154 JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
1155
1156 ecma_object_t *proto_p = ecma_op_get_prototype_from_constructor (new_target_p, ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
1157
1158 if (JERRY_UNLIKELY (proto_p == NULL))
1159 {
1160 return ECMA_VALUE_ERROR;
1161 }
1162
1163 ecma_object_t *new_this_obj_p = ecma_create_object (proto_p, 0, ECMA_OBJECT_TYPE_GENERAL);
1164 ecma_value_t this_arg = ecma_make_object_value (new_this_obj_p);
1165 ecma_deref_object (proto_p);
1166
1167 #if ENABLED (JERRY_ES2015)
1168 ecma_object_t *old_new_target_p = JERRY_CONTEXT (current_new_target);
1169 JERRY_CONTEXT (current_new_target) = new_target_p;
1170 #endif /* ENABLED (JERRY_ES2015) */
1171
1172 ecma_value_t ret_value = ecma_op_function_call_external (func_obj_p, this_arg, arguments_list_p, arguments_list_len);
1173
1174 #if ENABLED (JERRY_ES2015)
1175 JERRY_CONTEXT (current_new_target) = old_new_target_p;
1176 #endif /* ENABLED (JERRY_ES2015) */
1177
1178 if (ECMA_IS_VALUE_ERROR (ret_value) || ecma_is_value_object (ret_value))
1179 {
1180 ecma_deref_object (new_this_obj_p);
1181 return ret_value;
1182 }
1183
1184 ecma_free_value (ret_value);
1185
1186 return this_arg;
1187 } /* ecma_op_function_construct_external */
1188
1189 /**
1190 * General [[Construct]] implementation function objects
1191 *
1192 * See also: ECMAScript v6, 9.2.2
1193 *
1194 * @return ecma value
1195 * Returned value must be freed with ecma_free_value
1196 */
1197 ecma_value_t
ecma_op_function_construct(ecma_object_t * func_obj_p,ecma_object_t * new_target_p,const ecma_value_t * arguments_list_p,ecma_length_t arguments_list_len)1198 ecma_op_function_construct (ecma_object_t *func_obj_p, /**< Function object */
1199 ecma_object_t *new_target_p, /**< new target */
1200 const ecma_value_t *arguments_list_p, /**< arguments list */
1201 ecma_length_t arguments_list_len) /**< length of arguments list */
1202 {
1203 JERRY_ASSERT (func_obj_p != NULL
1204 && !ecma_is_lexical_environment (func_obj_p));
1205
1206 const ecma_object_type_t type = ecma_get_object_type (func_obj_p);
1207
1208 #if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
1209 if (ECMA_OBJECT_TYPE_IS_PROXY (type))
1210 {
1211 return ecma_proxy_object_construct (func_obj_p,
1212 new_target_p,
1213 arguments_list_p,
1214 arguments_list_len);
1215 }
1216 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
1217
1218 if (JERRY_UNLIKELY (type == ECMA_OBJECT_TYPE_BOUND_FUNCTION))
1219 {
1220 return ecma_op_function_construct_bound (func_obj_p, new_target_p, arguments_list_p, arguments_list_len);
1221 }
1222
1223 if (JERRY_UNLIKELY (type == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION))
1224 {
1225 return ecma_op_function_construct_external (func_obj_p, new_target_p, arguments_list_p, arguments_list_len);
1226 }
1227
1228 JERRY_ASSERT (type == ECMA_OBJECT_TYPE_FUNCTION);
1229
1230 if (JERRY_UNLIKELY (ecma_get_object_is_builtin (func_obj_p)))
1231 {
1232 return ecma_builtin_dispatch_construct (func_obj_p, new_target_p, arguments_list_p, arguments_list_len);
1233 }
1234
1235 ecma_object_t *new_this_obj_p = NULL;
1236 ecma_value_t this_arg;
1237 ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) func_obj_p;
1238 const ecma_compiled_code_t *byte_code_p = ecma_op_function_get_compiled_code (ext_func_obj_p);
1239
1240 if (byte_code_p->status_flags & (CBC_CODE_FLAGS_ARROW_FUNCTION | CBC_CODE_FLAGS_ACCESSOR))
1241 {
1242 if (byte_code_p->status_flags & CBC_CODE_FLAGS_ARROW_FUNCTION)
1243 {
1244 return ecma_raise_type_error (ECMA_ERR_MSG ("Arrow functions have no constructor."));
1245 }
1246
1247 return ecma_raise_type_error (ECMA_ERR_MSG ("Expected a constructor."));
1248 }
1249
1250 #if ENABLED (JERRY_ES2015)
1251 /* 6. */
1252 ecma_object_t *old_new_target_p = JERRY_CONTEXT (current_new_target);
1253 JERRY_CONTEXT (current_new_target) = new_target_p;
1254
1255 /* 5. */
1256 if (!ECMA_GET_THIRD_BIT_FROM_POINTER_TAG (ext_func_obj_p->u.function.scope_cp))
1257 {
1258 #endif /* ENABLED (JERRY_ES2015) */
1259 /* 5.a */
1260 ecma_object_t *proto_p = ecma_op_get_prototype_from_constructor (new_target_p, ECMA_BUILTIN_ID_OBJECT_PROTOTYPE);
1261
1262 /* 5.b */
1263 if (JERRY_UNLIKELY (proto_p == NULL))
1264 {
1265 return ECMA_VALUE_ERROR;
1266 }
1267
1268 new_this_obj_p = ecma_create_object (proto_p, 0, ECMA_OBJECT_TYPE_GENERAL);
1269 ecma_deref_object (proto_p);
1270 this_arg = ecma_make_object_value (new_this_obj_p);
1271 #if ENABLED (JERRY_ES2015)
1272 }
1273 else
1274 {
1275 this_arg = ECMA_VALUE_UNDEFINED;
1276 }
1277 #endif /* ENABLED (JERRY_ES2015) */
1278
1279 ecma_value_t ret_value = ecma_op_function_call_simple (func_obj_p, this_arg, arguments_list_p, arguments_list_len);
1280
1281 #if ENABLED (JERRY_ES2015)
1282 JERRY_CONTEXT (current_new_target) = old_new_target_p;
1283 #endif /* ENABLED (JERRY_ES2015) */
1284
1285 /* 13.a */
1286 if (ECMA_IS_VALUE_ERROR (ret_value) || ecma_is_value_object (ret_value))
1287 {
1288 #if ENABLED (JERRY_ES2015)
1289 if (new_this_obj_p != NULL)
1290 {
1291 ecma_deref_object (new_this_obj_p);
1292 }
1293 #else /* !ENABLED (JERRY_ES2015) */
1294 ecma_deref_object (new_this_obj_p);
1295 #endif /* ENABLED (JERRY_ES2015) */
1296 return ret_value;
1297 }
1298
1299 /* 13.b */
1300 ecma_free_value (ret_value);
1301 return this_arg;
1302 } /* ecma_op_function_construct */
1303
1304 /**
1305 * Lazy instantiation of 'prototype' property for non-builtin and external functions
1306 *
1307 * @return pointer to newly instantiated property
1308 */
1309 static ecma_property_t *
ecma_op_lazy_instantiate_prototype_object(ecma_object_t * object_p)1310 ecma_op_lazy_instantiate_prototype_object (ecma_object_t *object_p) /**< the function object */
1311 {
1312 JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION
1313 || ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
1314
1315 /* ECMA-262 v5, 13.2, 16-18 */
1316
1317 ecma_object_t *proto_object_p = NULL;
1318 bool init_constructor = true;
1319
1320 #if ENABLED (JERRY_ES2015)
1321 if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION)
1322 {
1323 const ecma_compiled_code_t *byte_code_p = ecma_op_function_get_compiled_code ((ecma_extended_object_t *) object_p);
1324
1325 if (byte_code_p->status_flags & CBC_CODE_FLAGS_GENERATOR)
1326 {
1327 proto_object_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_GENERATOR_PROTOTYPE),
1328 0,
1329 ECMA_OBJECT_TYPE_GENERAL);
1330 init_constructor = false;
1331 }
1332 else if (byte_code_p->status_flags & (CBC_CODE_FLAGS_ARROW_FUNCTION | CBC_CODE_FLAGS_ACCESSOR))
1333 {
1334 return NULL;
1335 }
1336 }
1337 #endif /* ENABLED (JERRY_ES2015) */
1338
1339 #if ENABLED (JERRY_ES2015)
1340 if (proto_object_p == NULL)
1341 #endif /* ENABLED (JERRY_ES2015) */
1342 {
1343 proto_object_p = ecma_op_create_object_object_noarg ();
1344 }
1345
1346 /* 17. */
1347 if (init_constructor)
1348 {
1349 ecma_property_value_t *constructor_prop_value_p;
1350 constructor_prop_value_p = ecma_create_named_data_property (proto_object_p,
1351 ecma_get_magic_string (LIT_MAGIC_STRING_CONSTRUCTOR),
1352 ECMA_PROPERTY_CONFIGURABLE_WRITABLE,
1353 NULL);
1354
1355 constructor_prop_value_p->value = ecma_make_object_value (object_p);
1356 }
1357
1358 /* 18. */
1359 ecma_property_t *prototype_prop_p;
1360 ecma_property_value_t *prototype_prop_value_p;
1361 prototype_prop_value_p = ecma_create_named_data_property (object_p,
1362 ecma_get_magic_string (LIT_MAGIC_STRING_PROTOTYPE),
1363 ECMA_PROPERTY_FLAG_WRITABLE,
1364 &prototype_prop_p);
1365
1366 prototype_prop_value_p->value = ecma_make_object_value (proto_object_p);
1367
1368 ecma_deref_object (proto_object_p);
1369
1370 return prototype_prop_p;
1371 } /* ecma_op_lazy_instantiate_prototype_object */
1372
1373 /**
1374 * Lazy instantiation of non-builtin ecma function object's properties
1375 *
1376 * Warning:
1377 * Only non-configurable properties could be instantiated lazily in this function,
1378 * as configurable properties could be deleted and it would be incorrect
1379 * to reinstantiate them in the function in second time.
1380 *
1381 * @return pointer to newly instantiated property, if a property was instantiated,
1382 * NULL - otherwise
1383 */
1384 ecma_property_t *
ecma_op_function_try_to_lazy_instantiate_property(ecma_object_t * object_p,ecma_string_t * property_name_p)1385 ecma_op_function_try_to_lazy_instantiate_property (ecma_object_t *object_p, /**< the function object */
1386 ecma_string_t *property_name_p) /**< property name */
1387 {
1388 JERRY_ASSERT (!ecma_get_object_is_builtin (object_p));
1389
1390 #if ENABLED (JERRY_ES2015)
1391 if (ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_LENGTH))
1392 {
1393 ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
1394 if (!ECMA_GET_FIRST_BIT_FROM_POINTER_TAG (ext_func_p->u.function.scope_cp))
1395 {
1396 /* Initialize 'length' property */
1397 const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p);
1398 uint32_t len;
1399 if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
1400 {
1401 cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) bytecode_data_p;
1402 len = args_p->argument_end;
1403 }
1404 else
1405 {
1406 cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) bytecode_data_p;
1407 len = args_p->argument_end;
1408 }
1409
1410 /* Set tag bit to represent initialized 'length' property */
1411 ECMA_SET_FIRST_BIT_TO_POINTER_TAG (ext_func_p->u.function.scope_cp);
1412 ecma_property_t *value_prop_p;
1413 ecma_property_value_t *value_p = ecma_create_named_data_property (object_p,
1414 property_name_p,
1415 ECMA_PROPERTY_FLAG_CONFIGURABLE,
1416 &value_prop_p);
1417 value_p->value = ecma_make_uint32_value (len);
1418 return value_prop_p;
1419 }
1420
1421 return NULL;
1422 }
1423 #endif /* ENABLED (JERRY_ES2015) */
1424
1425 if (ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_PROTOTYPE)
1426 && ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION)
1427 {
1428 return ecma_op_lazy_instantiate_prototype_object (object_p);
1429 }
1430
1431 if (ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_CALLER)
1432 || ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_ARGUMENTS))
1433 {
1434 const ecma_compiled_code_t *bytecode_data_p;
1435 bytecode_data_p = ecma_op_function_get_compiled_code ((ecma_extended_object_t *) object_p);
1436
1437 #if ENABLED (JERRY_ES2015)
1438 if (!(bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE))
1439 {
1440 ecma_property_t *value_prop_p;
1441 /* The property_name_p argument contans the name. */
1442 ecma_property_value_t *value_p = ecma_create_named_data_property (object_p,
1443 property_name_p,
1444 ECMA_PROPERTY_FIXED,
1445 &value_prop_p);
1446 value_p->value = ECMA_VALUE_NULL;
1447 return value_prop_p;
1448 }
1449 #else /* !ENABLED (JERRY_ES2015) */
1450 if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE)
1451 {
1452 ecma_object_t *thrower_p = ecma_builtin_get (ECMA_BUILTIN_ID_TYPE_ERROR_THROWER);
1453
1454 ecma_property_t *caller_prop_p;
1455 /* The property_name_p argument contans the name. */
1456 ecma_create_named_accessor_property (object_p,
1457 property_name_p,
1458 thrower_p,
1459 thrower_p,
1460 ECMA_PROPERTY_FIXED,
1461 &caller_prop_p);
1462 return caller_prop_p;
1463 }
1464 #endif /* ENABLED (JERRY_ES2015) */
1465
1466 }
1467
1468 return NULL;
1469 } /* ecma_op_function_try_to_lazy_instantiate_property */
1470
1471 /**
1472 * Create specification defined non-configurable properties for external functions.
1473 *
1474 * See also:
1475 * ECMA-262 v5, 15.3.4.5
1476 *
1477 * @return pointer property, if one was instantiated,
1478 * NULL - otherwise.
1479 */
1480 ecma_property_t *
ecma_op_external_function_try_to_lazy_instantiate_property(ecma_object_t * object_p,ecma_string_t * property_name_p)1481 ecma_op_external_function_try_to_lazy_instantiate_property (ecma_object_t *object_p, /**< object */
1482 ecma_string_t *property_name_p) /**< property's name */
1483 {
1484 JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
1485
1486 if (ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_PROTOTYPE))
1487 {
1488 return ecma_op_lazy_instantiate_prototype_object (object_p);
1489 }
1490
1491 return NULL;
1492 } /* ecma_op_external_function_try_to_lazy_instantiate_property */
1493
1494 /**
1495 * Create specification defined non-configurable properties for bound functions.
1496 *
1497 * See also:
1498 * ECMA-262 v5, 15.3.4.5
1499 *
1500 * @return pointer property, if one was instantiated,
1501 * NULL - otherwise.
1502 */
1503 ecma_property_t *
ecma_op_bound_function_try_to_lazy_instantiate_property(ecma_object_t * object_p,ecma_string_t * property_name_p)1504 ecma_op_bound_function_try_to_lazy_instantiate_property (ecma_object_t *object_p, /**< object */
1505 ecma_string_t *property_name_p) /**< property's name */
1506 {
1507 JERRY_ASSERT (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION);
1508
1509 if (ecma_string_is_length (property_name_p))
1510 {
1511 ecma_bound_function_t *bound_func_p = (ecma_bound_function_t *) object_p;
1512 ecma_value_t args_len_or_this = bound_func_p->header.u.bound_function.args_len_or_this;
1513 ecma_integer_value_t length = 0;
1514 ecma_integer_value_t args_length = 1;
1515 uint8_t length_attributes;
1516
1517 if (ecma_is_value_integer_number (args_len_or_this))
1518 {
1519 args_length = ecma_get_integer_from_value (args_len_or_this);
1520 }
1521
1522 #if ENABLED (JERRY_ES2015)
1523 if (ECMA_GET_FIRST_BIT_FROM_POINTER_TAG (bound_func_p->header.u.bound_function.target_function))
1524 {
1525 return NULL;
1526 }
1527
1528 length_attributes = ECMA_PROPERTY_FLAG_CONFIGURABLE;
1529 length = bound_func_p->target_length - (args_length - 1);
1530
1531 /* Set tag bit to represent initialized 'length' property */
1532 ECMA_SET_FIRST_BIT_TO_POINTER_TAG (bound_func_p->header.u.bound_function.target_function);
1533 #else /* !ENABLED (JERRY_ES2015) */
1534 length_attributes = ECMA_PROPERTY_FIXED;
1535
1536 ecma_object_t *target_func_p;
1537 target_func_p = ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_object_t,
1538 bound_func_p->header.u.bound_function.target_function);
1539
1540 if (ecma_object_get_class_name (target_func_p) == LIT_MAGIC_STRING_FUNCTION_UL)
1541 {
1542 /* The property_name_p argument contains the 'length' string. */
1543 ecma_value_t get_len_value = ecma_op_object_get (target_func_p, property_name_p);
1544
1545 JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (get_len_value));
1546 JERRY_ASSERT (ecma_is_value_integer_number (get_len_value));
1547
1548 length = ecma_get_integer_from_value (get_len_value) - (args_length - 1);
1549 }
1550 #endif /* ENABLED (JERRY_ES2015) */
1551
1552 if (length < 0)
1553 {
1554 length = 0;
1555 }
1556
1557 ecma_property_t *len_prop_p;
1558 ecma_property_value_t *len_prop_value_p = ecma_create_named_data_property (object_p,
1559 property_name_p,
1560 length_attributes,
1561 &len_prop_p);
1562
1563 len_prop_value_p->value = ecma_make_integer_value (length);
1564 return len_prop_p;
1565 }
1566
1567 if (ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_CALLER)
1568 || ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_ARGUMENTS))
1569 {
1570 ecma_object_t *thrower_p = ecma_builtin_get (ECMA_BUILTIN_ID_TYPE_ERROR_THROWER);
1571
1572 ecma_property_t *caller_prop_p;
1573 /* The string_p argument contans the name. */
1574 ecma_create_named_accessor_property (object_p,
1575 property_name_p,
1576 thrower_p,
1577 thrower_p,
1578 ECMA_PROPERTY_FIXED,
1579 &caller_prop_p);
1580 return caller_prop_p;
1581 }
1582
1583 return NULL;
1584 } /* ecma_op_bound_function_try_to_lazy_instantiate_property */
1585
1586 /**
1587 * List names of a Function object's lazy instantiated properties,
1588 * adding them to corresponding string collections
1589 *
1590 * See also:
1591 * ecma_op_function_try_to_lazy_instantiate_property
1592 */
1593 void
ecma_op_function_list_lazy_property_names(ecma_object_t * object_p,uint32_t opts,ecma_collection_t * main_collection_p,ecma_collection_t * non_enum_collection_p)1594 ecma_op_function_list_lazy_property_names (ecma_object_t *object_p, /**< functionobject */
1595 uint32_t opts, /**< listing options using flags
1596 * from ecma_list_properties_options_t */
1597 ecma_collection_t *main_collection_p, /**< 'main' collection */
1598 ecma_collection_t *non_enum_collection_p) /**< skipped
1599 * 'non-enumerable'
1600 * collection */
1601 {
1602 JERRY_UNUSED (main_collection_p);
1603
1604 ecma_collection_t *for_non_enumerable_p = (opts & ECMA_LIST_ENUMERABLE) ? non_enum_collection_p : main_collection_p;
1605
1606 #if ENABLED (JERRY_ES2015)
1607 ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
1608 if (!ECMA_GET_FIRST_BIT_FROM_POINTER_TAG (ext_func_p->u.function.scope_cp))
1609 {
1610 /* Unintialized 'length' property is non-enumerable (ECMA-262 v6, 19.2.4.1) */
1611 ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH));
1612 }
1613 #else /* !ENABLED (JERRY_ES2015) */
1614 /* 'length' property is non-enumerable (ECMA-262 v5, 13.2.5) */
1615 ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH));
1616 #endif /* ENABLED (JERRY_ES2015) */
1617
1618 const ecma_compiled_code_t *bytecode_data_p;
1619 bytecode_data_p = ecma_op_function_get_compiled_code ((ecma_extended_object_t *) object_p);
1620
1621 #if ENABLED (JERRY_ES2015)
1622 if (bytecode_data_p->status_flags & (CBC_CODE_FLAGS_ARROW_FUNCTION | CBC_CODE_FLAGS_ACCESSOR))
1623 {
1624 return;
1625 }
1626 #endif /* ENABLED (JERRY_ES2015) */
1627
1628 /* 'prototype' property is non-enumerable (ECMA-262 v5, 13.2.18) */
1629 ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_PROTOTYPE));
1630
1631 #if ENABLED (JERRY_ES2015)
1632 bool append_caller_and_arguments = !(bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE);
1633 #else /* !ENABLED (JERRY_ES2015) */
1634 bool append_caller_and_arguments = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_STRICT_MODE);
1635 #endif /* ENABLED (JERRY_ES2015) */
1636
1637 if (append_caller_and_arguments)
1638 {
1639 /* 'caller' property is non-enumerable (ECMA-262 v5, 13.2.5) */
1640 ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_CALLER));
1641
1642 /* 'arguments' property is non-enumerable (ECMA-262 v5, 13.2.5) */
1643 ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_ARGUMENTS));
1644 }
1645 } /* ecma_op_function_list_lazy_property_names */
1646
1647 /**
1648 * List names of an External Function object's lazy instantiated properties,
1649 * adding them to corresponding string collections
1650 *
1651 * See also:
1652 * ecma_op_external_function_try_to_lazy_instantiate_property
1653 */
1654 void
ecma_op_external_function_list_lazy_property_names(ecma_object_t * object_p,uint32_t opts,ecma_collection_t * main_collection_p,ecma_collection_t * non_enum_collection_p)1655 ecma_op_external_function_list_lazy_property_names (ecma_object_t *object_p, /**< function object */
1656 uint32_t opts, /**< listing options using flags
1657 * from ecma_list_properties_options_t */
1658 ecma_collection_t *main_collection_p, /**< 'main' collection */
1659 ecma_collection_t *non_enum_collection_p) /**< skipped
1660 * collection */
1661 {
1662 JERRY_UNUSED (main_collection_p);
1663
1664 ecma_collection_t *for_non_enumerable_p = (opts & ECMA_LIST_ENUMERABLE) ? non_enum_collection_p : main_collection_p;
1665
1666 #if !ENABLED (JERRY_ES2015)
1667 JERRY_UNUSED (object_p);
1668 #else /* ENABLED (JERRY_ES2015) */
1669 if (!ecma_op_ordinary_object_has_own_property (object_p, ecma_get_magic_string (LIT_MAGIC_STRING_PROTOTYPE)))
1670 #endif /* !ENABLED (JERRY_ES2015) */
1671 {
1672 /* 'prototype' property is non-enumerable (ECMA-262 v5, 13.2.18) */
1673 ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_PROTOTYPE));
1674 }
1675 } /* ecma_op_external_function_list_lazy_property_names */
1676
1677 /**
1678 * List names of a Bound Function object's lazy instantiated properties,
1679 * adding them to corresponding string collections
1680 *
1681 * See also:
1682 * ecma_op_bound_function_try_to_lazy_instantiate_property
1683 */
1684 void
ecma_op_bound_function_list_lazy_property_names(ecma_object_t * object_p,uint32_t opts,ecma_collection_t * main_collection_p,ecma_collection_t * non_enum_collection_p)1685 ecma_op_bound_function_list_lazy_property_names (ecma_object_t *object_p, /**< bound function object*/
1686 uint32_t opts, /**< listing options using flags
1687 * from ecma_list_properties_options_t */
1688 ecma_collection_t *main_collection_p, /**< 'main' collection */
1689 ecma_collection_t *non_enum_collection_p) /**< skipped
1690 * 'non-enumerable'
1691 * collection */
1692 {
1693 JERRY_UNUSED (main_collection_p);
1694
1695 ecma_collection_t *for_non_enumerable_p = (opts & ECMA_LIST_ENUMERABLE) ? non_enum_collection_p : main_collection_p;
1696
1697 #if ENABLED (JERRY_ES2015)
1698 /* Unintialized 'length' property is non-enumerable (ECMA-262 v6, 19.2.4.1) */
1699 ecma_bound_function_t *bound_func_p = (ecma_bound_function_t *) object_p;
1700 if (!ECMA_GET_FIRST_BIT_FROM_POINTER_TAG (bound_func_p->header.u.bound_function.target_function))
1701 {
1702 ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH));
1703 }
1704 #else /* !ENABLED (JERRY_ES2015) */
1705 JERRY_UNUSED (object_p);
1706 /* 'length' property is non-enumerable (ECMA-262 v5, 13.2.5) */
1707 ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH));
1708 #endif /* ENABLED (JERRY_ES2015) */
1709
1710 /* 'caller' property is non-enumerable (ECMA-262 v5, 13.2.5) */
1711 ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_CALLER));
1712
1713 /* 'arguments' property is non-enumerable (ECMA-262 v5, 13.2.5) */
1714 ecma_collection_push_back (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_ARGUMENTS));
1715 } /* ecma_op_bound_function_list_lazy_property_names */
1716
1717 /**
1718 * @}
1719 * @}
1720 */
1721