• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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-array-object.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-globals.h"
22 #include "ecma-iterator-object.h"
23 #include "ecma-number-object.h"
24 #include "ecma-promise-object.h"
25 #include "jcontext.h"
26 
27 #if ENABLED (JERRY_ES2015_BUILTIN_PROMISE)
28 
29 #define ECMA_BUILTINS_INTERNAL
30 #include "ecma-builtins-internal.h"
31 
32 #define BUILTIN_INC_HEADER_NAME "ecma-builtin-promise.inc.h"
33 #define BUILTIN_UNDERSCORED_ID promise
34 #include "ecma-builtin-internal-routines-template.inc.h"
35 
36 /** \addtogroup ecma ECMA
37  * @{
38  *
39  * \addtogroup ecmabuiltins
40  * @{
41  *
42  * \addtogroup promise ECMA Promise object built-in
43  * @{
44  */
45 
46 /**
47  * Reject the promise if the value is error.
48  *
49  * See also:
50  *         ES2015 25.4.1.1.1
51  *
52  * @return ecma value of the new promise.
53  *         Returned value must be freed with ecma_free_value.
54  */
55 inline static ecma_value_t
ecma_builtin_promise_reject_abrupt(ecma_value_t value,ecma_value_t capability)56 ecma_builtin_promise_reject_abrupt (ecma_value_t value, /**< value */
57                                     ecma_value_t capability) /**< capability */
58 {
59   if (!ECMA_IS_VALUE_ERROR (value))
60   {
61     return value;
62   }
63 
64   ecma_value_t reason = jcontext_take_exception ();
65   ecma_value_t reject = ecma_op_object_get_by_magic_id (ecma_get_object_from_value (capability),
66                                                         LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_REJECT);
67 
68   ecma_value_t call_ret = ecma_op_function_call (ecma_get_object_from_value (reject),
69                                                  ECMA_VALUE_UNDEFINED,
70                                                  &reason,
71                                                  1);
72   ecma_free_value (reject);
73   ecma_free_value (reason);
74 
75   if (ECMA_IS_VALUE_ERROR (call_ret))
76   {
77     return call_ret;
78   }
79 
80   ecma_free_value (call_ret);
81 
82   return ecma_op_object_get_by_magic_id (ecma_get_object_from_value (capability),
83                                          LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_PROMISE);
84 } /* ecma_builtin_promise_reject_abrupt */
85 
86 /**
87  * The Promise.reject routine.
88  *
89  * See also:
90  *         ES2015 25.4.4.4
91  *
92  * @return ecma value of the new promise.
93  *         Returned value must be freed with ecma_free_value.
94  */
95 static ecma_value_t
ecma_builtin_promise_reject(ecma_value_t this_arg,ecma_value_t reason)96 ecma_builtin_promise_reject (ecma_value_t this_arg, /**< 'this' argument */
97                              ecma_value_t reason) /**< the reason for reject */
98 {
99   return ecma_promise_reject_or_resolve (this_arg, reason, false);
100 } /* ecma_builtin_promise_reject */
101 
102 /**
103  * The Promise.resolve routine.
104  *
105  * See also:
106  *         ES2015 25.4.4.5
107  *
108  * @return ecma value of the new promise.
109  *         Returned value must be freed with ecma_free_value.
110  */
111 static ecma_value_t
ecma_builtin_promise_resolve(ecma_value_t this_arg,ecma_value_t argument)112 ecma_builtin_promise_resolve (ecma_value_t this_arg, /**< 'this' argument */
113                               ecma_value_t argument) /**< the argument for resolve */
114 {
115   return ecma_promise_reject_or_resolve (this_arg, argument, true);
116 } /* ecma_builtin_promise_resolve */
117 
118 /**
119  * Runtime Semantics: PerformPromiseRace.
120  *
121  * See also:
122  *         ES2015 25.4.4.3.1
123  *
124  * @return ecma value of the new promise.
125  *         Returned value must be freed with ecma_free_value.
126  */
127 inline static ecma_value_t
ecma_builtin_promise_perform_race(ecma_value_t iterator,ecma_value_t capability,ecma_value_t ctor,bool * done_p)128 ecma_builtin_promise_perform_race (ecma_value_t iterator, /**< the iterator for race */
129                                    ecma_value_t capability, /**< PromiseCapability record */
130                                    ecma_value_t ctor, /**< Constructor value */
131                                    bool *done_p) /**< [out] iteratorRecord[[done]] */
132 {
133   JERRY_ASSERT (ecma_is_value_object (iterator)
134                 && ecma_is_value_object (capability));
135 
136   ecma_object_t *capability_obj_p = ecma_get_object_from_value (capability);
137   /* 1. */
138   while (true)
139   {
140     /* a. */
141     ecma_value_t next = ecma_op_iterator_step (iterator);
142     /* b, c. */
143     if (ECMA_IS_VALUE_ERROR (next))
144     {
145       *done_p = true;
146       return next;
147     }
148 
149     /* d. */
150     if (ecma_is_value_false (next))
151     {
152       /* i. */
153       *done_p = true;
154       /* ii. */
155       return ecma_op_object_get_by_magic_id (capability_obj_p, LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_PROMISE);
156     }
157 
158     /* e. */
159     ecma_value_t next_val = ecma_op_iterator_value (next);
160     ecma_free_value (next);
161 
162     /* f, g. */
163     if (ECMA_IS_VALUE_ERROR (next_val))
164     {
165       *done_p = true;
166       return next_val;
167     }
168 
169     /* h. */
170     ecma_value_t next_promise = ecma_op_invoke_by_magic_id (ctor, LIT_MAGIC_STRING_RESOLVE, &next_val, 1);
171     ecma_free_value (next_val);
172 
173     /* i. */
174     if (ECMA_IS_VALUE_ERROR (next_promise))
175     {
176       return next_promise;
177     }
178 
179     /* j. */
180     ecma_value_t args[2];
181     args[0] = ecma_op_object_get_by_magic_id (capability_obj_p, LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_RESOLVE);
182     args[1] = ecma_op_object_get_by_magic_id (capability_obj_p, LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_REJECT);
183     ecma_value_t result = ecma_op_invoke_by_magic_id (next_promise, LIT_MAGIC_STRING_THEN, args, 2);
184     ecma_free_value (next_promise);
185 
186     for (uint8_t i = 0; i < 2; i++)
187     {
188       ecma_free_value (args[i]);
189     }
190 
191     /* k. */
192     if (ECMA_IS_VALUE_ERROR (result))
193     {
194       return result;
195     }
196 
197     ecma_free_value (result);
198   }
199 
200   JERRY_UNREACHABLE ();
201 } /* ecma_builtin_promise_perform_race */
202 
203 /**
204  * Helper function for increase or decrease the remaining count.
205  *
206  * @return the current remaining count after increase or decrease.
207  */
208 static ecma_length_t
ecma_builtin_promise_remaining_inc_or_dec(ecma_value_t remaining,bool is_inc)209 ecma_builtin_promise_remaining_inc_or_dec (ecma_value_t remaining, /**< the remaining count */
210                                            bool is_inc) /**< whether to increase the count */
211 {
212   JERRY_ASSERT (ecma_is_value_object (remaining));
213 
214   ecma_object_t *remaining_p = ecma_get_object_from_value (remaining);
215   ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) remaining_p;
216 
217   JERRY_ASSERT (ext_object_p->u.class_prop.class_id == LIT_MAGIC_STRING_NUMBER_UL);
218 
219   JERRY_ASSERT (ecma_is_value_integer_number (ext_object_p->u.class_prop.u.value));
220 
221   ecma_length_t current = (ecma_length_t) ecma_get_integer_from_value (ext_object_p->u.class_prop.u.value);
222 
223   if (is_inc)
224   {
225     current++;
226   }
227   else
228   {
229     current--;
230   }
231   ext_object_p->u.class_prop.u.value = ecma_make_uint32_value (current);
232 
233   return current;
234 } /* ecma_builtin_promise_remaining_inc_or_dec */
235 
236 /**
237  * Native handler for Promise.all Resolve Element Function.
238  *
239  * See also:
240  *         ES2015 25.4.4.1.2
241  *
242  * @return ecma value of undefined.
243  */
244 static ecma_value_t
ecma_builtin_promise_all_handler(const ecma_value_t function,const ecma_value_t this,const ecma_value_t argv[],const ecma_length_t argc)245 ecma_builtin_promise_all_handler (const ecma_value_t function, /**< the function itself */
246                                   const ecma_value_t this, /**< this_arg of the function */
247                                   const ecma_value_t argv[], /**< argument list */
248                                   const ecma_length_t argc) /**< argument number */
249 {
250   JERRY_UNUSED (this);
251   JERRY_UNUSED (argc);
252 
253   /* 1. */
254   ecma_object_t *function_p = ecma_get_object_from_value (function);
255   ecma_string_t *already_called_str_p;
256   already_called_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_ALREADY_CALLED);
257   ecma_value_t already_called = ecma_op_object_get (function_p, already_called_str_p);
258 
259   JERRY_ASSERT (ecma_is_value_boolean (already_called));
260 
261   /* 2. */
262   if (ecma_is_value_true (already_called))
263   {
264     return ECMA_VALUE_UNDEFINED;
265   }
266 
267   /* 3. */
268   ecma_op_object_put (function_p,
269                       already_called_str_p,
270                       ECMA_VALUE_TRUE,
271                       false);
272 
273   ecma_string_t *str_index_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_INDEX);
274   ecma_string_t *str_value_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_VALUE);
275   ecma_string_t *str_capability_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_CAPABILITY);
276   ecma_string_t *str_remaining_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_REMAINING_ELEMENT);
277 
278   /* 4-7. */
279   ecma_value_t index_val = ecma_op_object_get (function_p, str_index_p);
280   ecma_value_t values_array = ecma_op_object_get (function_p, str_value_p);
281   ecma_value_t capability = ecma_op_object_get (function_p, str_capability_p);
282   ecma_value_t remaining = ecma_op_object_get (function_p, str_remaining_p);
283 
284   JERRY_ASSERT (ecma_is_value_integer_number (index_val));
285 
286   /* 8. */
287   ecma_op_object_put_by_uint32_index (ecma_get_object_from_value (values_array),
288                                       (uint32_t) ecma_get_integer_from_value (index_val),
289                                       argv[0],
290                                       false);
291 
292   /* 9-10. */
293   ecma_value_t ret = ECMA_VALUE_UNDEFINED;
294   if (ecma_builtin_promise_remaining_inc_or_dec (remaining, false) == 0)
295   {
296     ecma_value_t resolve = ecma_op_object_get_by_magic_id (ecma_get_object_from_value (capability),
297                                                            LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_RESOLVE);
298     ret = ecma_op_function_call (ecma_get_object_from_value (resolve),
299                                  ECMA_VALUE_UNDEFINED,
300                                  &values_array,
301                                  1);
302     ecma_free_value (resolve);
303   }
304 
305   ecma_free_value (remaining);
306   ecma_free_value (capability);
307   ecma_free_value (values_array);
308   ecma_free_value (index_val);
309 
310   return ret;
311 } /* ecma_builtin_promise_all_handler */
312 
313 /**
314  * Runtime Semantics: PerformPromiseAll.
315  *
316  * See also:
317  *         ES2015 25.4.4.1.1
318  *
319  * @return ecma value of the new promise.
320  *         Returned value must be freed with ecma_free_value.
321  */
322 inline static ecma_value_t
ecma_builtin_promise_perform_all(ecma_value_t iterator,ecma_value_t ctor,ecma_value_t capability,bool * done_p)323 ecma_builtin_promise_perform_all (ecma_value_t iterator, /**< iteratorRecord */
324                                   ecma_value_t ctor, /**< the caller of Promise.race */
325                                   ecma_value_t capability,  /**< PromiseCapability record */
326                                   bool *done_p) /**< [out] iteratorRecord[[done]] */
327 {
328   /* 1. - 2. */
329   JERRY_ASSERT (ecma_is_value_object (capability) && ecma_is_constructor (ctor));
330 
331   /* 3. */
332   ecma_object_t *values_array_obj_p = ecma_op_new_fast_array_object (0);
333   ecma_value_t values_array = ecma_make_object_value (values_array_obj_p);
334   /* 4. */
335   ecma_value_t remaining = ecma_op_create_number_object (ecma_make_integer_value (1));
336   /* 5. */
337   uint32_t idx = 0;
338 
339   ecma_value_t ret_value = ECMA_VALUE_ERROR;
340   ecma_object_t *capability_obj_p = ecma_get_object_from_value (capability);
341 
342   ecma_string_t *already_called_str_p;
343   already_called_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_ALREADY_CALLED);
344   ecma_string_t *index_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_INDEX);
345   ecma_string_t *value_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_VALUE);
346   ecma_string_t *capability_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_CAPABILITY);
347   ecma_string_t *remaining_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_REMAINING_ELEMENT);
348 
349   /* 6. */
350   while (true)
351   {
352     /* a. */
353     ecma_value_t next = ecma_op_iterator_step (iterator);
354     /* b. - c. */
355     if (ECMA_IS_VALUE_ERROR (next))
356     {
357       *done_p = true;
358       break;
359     }
360 
361     /* d. */
362     if (ecma_is_value_false (next))
363     {
364       /* i. */
365       *done_p = true;
366 
367       /* ii. - iii. */
368       if (ecma_builtin_promise_remaining_inc_or_dec (remaining, false) == 0)
369       {
370         /* 2. */
371         ecma_value_t resolve = ecma_op_object_get_by_magic_id (capability_obj_p,
372                                                                LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_RESOLVE);
373         ecma_value_t resolve_result = ecma_op_function_call (ecma_get_object_from_value (resolve),
374                                                              ECMA_VALUE_UNDEFINED,
375                                                              &values_array,
376                                                              1);
377         ecma_free_value (resolve);
378 
379         /* 3. */
380         if (ECMA_IS_VALUE_ERROR (resolve_result))
381         {
382           break;
383         }
384 
385         ecma_free_value (resolve_result);
386       }
387 
388       /* iv. */
389       ret_value = ecma_op_object_get_by_magic_id (capability_obj_p,
390                                                   LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_PROMISE);
391       break;
392     }
393 
394     /* e. */
395     ecma_value_t next_value = ecma_op_iterator_value (next);
396     ecma_free_value (next);
397 
398     /* f. - g. */
399     if (ECMA_IS_VALUE_ERROR (next_value))
400     {
401       *done_p = true;
402       break;
403     }
404 
405     /* h. */
406     ecma_builtin_helper_def_prop_by_index (values_array_obj_p,
407                                            idx,
408                                            ECMA_VALUE_UNDEFINED,
409                                            ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE_WRITABLE);
410 
411     /* i. */
412     ecma_value_t next_promise = ecma_op_invoke_by_magic_id (ctor, LIT_MAGIC_STRING_RESOLVE, &next_value, 1);
413     ecma_free_value (next_value);
414 
415     /* j. */
416     if (ECMA_IS_VALUE_ERROR (next_promise))
417     {
418       break;
419     }
420 
421     /* k. */
422     ecma_object_t *res_ele_p;
423     res_ele_p = ecma_op_create_external_function_object (ecma_builtin_promise_all_handler);
424     /* l. */
425     ecma_op_object_put (res_ele_p,
426                         already_called_str_p,
427                         ECMA_VALUE_FALSE,
428                         false);
429     /* m. */
430     ecma_value_t idx_value = ecma_make_uint32_value (idx);
431     ecma_op_object_put (res_ele_p,
432                         index_str_p,
433                         idx_value,
434                         false);
435     ecma_free_value (idx_value);
436 
437     /* n. */
438     ecma_op_object_put (res_ele_p,
439                         value_str_p,
440                         values_array,
441                         false);
442 
443     /* o. */
444     ecma_op_object_put (res_ele_p,
445                         capability_str_p,
446                         capability,
447                         false);
448     /* p. */
449     ecma_op_object_put (res_ele_p,
450                         remaining_str_p,
451                         remaining,
452                         false);
453 
454     /* q. */
455     ecma_builtin_promise_remaining_inc_or_dec (remaining, true);
456 
457     /* r. */
458     ecma_value_t args[2];
459     args[0] = ecma_make_object_value (res_ele_p);
460     args[1] = ecma_op_object_get_by_magic_id (capability_obj_p, LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_REJECT);
461     ecma_value_t result = ecma_op_invoke_by_magic_id (next_promise, LIT_MAGIC_STRING_THEN, args, 2);
462     ecma_free_value (next_promise);
463 
464     for (uint8_t i = 0; i < 2; i++)
465     {
466       ecma_free_value (args[i]);
467     }
468 
469     /* s. */
470     if (ECMA_IS_VALUE_ERROR (result))
471     {
472       break;
473     }
474 
475     ecma_free_value (result);
476 
477     /* t. */
478     idx++;
479   }
480 
481   ecma_free_value (remaining);
482   ecma_deref_object (values_array_obj_p);
483   return ret_value;
484 } /* ecma_builtin_promise_perform_all */
485 
486 /**
487  * The common function for both Promise.race and Promise.all.
488  *
489  * @return ecma value of the new promise.
490  *         Returned value must be freed with ecma_free_value.
491  */
492 static ecma_value_t
ecma_builtin_promise_race_or_all(ecma_value_t this_arg,ecma_value_t iterable,bool is_race)493 ecma_builtin_promise_race_or_all (ecma_value_t this_arg, /**< 'this' argument */
494                                   ecma_value_t iterable, /**< the items to be resolved */
495                                   bool is_race) /**< indicates whether it is race function */
496 {
497   if (!ecma_is_value_object (this_arg))
498   {
499     return ecma_raise_type_error (ECMA_ERR_MSG ("'this' is not an object."));
500   }
501 
502   ecma_object_t *this_obj_p = ecma_get_object_from_value (this_arg);
503   ecma_value_t species_symbol = ecma_op_object_get_by_magic_id (this_obj_p,
504                                                                 LIT_MAGIC_STRING_SYMBOL);
505 
506   if (ECMA_IS_VALUE_ERROR (species_symbol))
507   {
508     return species_symbol;
509   }
510 
511   ecma_value_t constructor_value = this_arg;
512 
513   if (!ecma_is_value_null (species_symbol) && !ecma_is_value_undefined (species_symbol))
514   {
515     constructor_value = species_symbol;
516   }
517   else
518   {
519     ecma_ref_object (this_obj_p);
520   }
521 
522   ecma_value_t capability = ecma_promise_new_capability (constructor_value);
523 
524   if (ECMA_IS_VALUE_ERROR (capability))
525   {
526     ecma_free_value (constructor_value);
527     return capability;
528   }
529 
530   ecma_value_t iterator = ecma_builtin_promise_reject_abrupt (ecma_op_get_iterator (iterable, ECMA_VALUE_EMPTY),
531                                                               capability);
532 
533   if (ECMA_IS_VALUE_ERROR (iterator))
534   {
535     ecma_free_value (constructor_value);
536     ecma_free_value (capability);
537     return iterator;
538   }
539 
540   ecma_value_t ret = ECMA_VALUE_EMPTY;
541   bool is_done = false;
542 
543   if (is_race)
544   {
545     ret = ecma_builtin_promise_perform_race (iterator, capability, constructor_value, &is_done);
546   }
547   else
548   {
549     ret = ecma_builtin_promise_perform_all (iterator, constructor_value, capability, &is_done);
550   }
551 
552   ecma_free_value (constructor_value);
553 
554   if (ECMA_IS_VALUE_ERROR (ret))
555   {
556     if (!is_done)
557     {
558       ret = ecma_op_iterator_close (iterator);
559     }
560 
561     ret = ecma_builtin_promise_reject_abrupt (ret, capability);
562   }
563 
564   ecma_free_value (iterator);
565   ecma_free_value (capability);
566 
567   return ret;
568 } /* ecma_builtin_promise_race_or_all */
569 
570 /**
571  * The Promise.race routine.
572  *
573  * See also:
574  *         ES2015 25.4.4.3
575  *
576  * @return ecma value of the new promise.
577  *         Returned value must be freed with ecma_free_value.
578  */
579 static ecma_value_t
ecma_builtin_promise_race(ecma_value_t this_arg,ecma_value_t array)580 ecma_builtin_promise_race (ecma_value_t this_arg, /**< 'this' argument */
581                            ecma_value_t array) /**< the items to be resolved */
582 {
583   return ecma_builtin_promise_race_or_all (this_arg, array, true);
584 } /* ecma_builtin_promise_race */
585 
586 /**
587  * The Promise.all routine.
588  *
589  * See also:
590  *         ES2015 25.4.4.1
591  *
592  * @return ecma value of the new promise.
593  *         Returned value must be freed with ecma_free_value.
594  */
595 static ecma_value_t
ecma_builtin_promise_all(ecma_value_t this_arg,ecma_value_t array)596 ecma_builtin_promise_all (ecma_value_t this_arg, /**< 'this' argument */
597                            ecma_value_t array) /**< the items to be resolved */
598 {
599   return ecma_builtin_promise_race_or_all (this_arg, array, false);
600 } /* ecma_builtin_promise_all */
601 
602 /**
603  * Handle calling [[Call]] of built-in Promise object.
604  *
605  * ES2015 25.4.3 Promise is not intended to be called
606  * as a function and will throw an exception when called
607  * in that manner.
608  *
609  * @return ecma value
610  */
611 ecma_value_t
ecma_builtin_promise_dispatch_call(const ecma_value_t * arguments_list_p,ecma_length_t arguments_list_len)612 ecma_builtin_promise_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */
613                                     ecma_length_t arguments_list_len) /**< number of arguments */
614 {
615   JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
616 
617   return ecma_raise_type_error (ECMA_ERR_MSG ("Constructor Promise requires 'new'."));
618 } /* ecma_builtin_promise_dispatch_call */
619 
620 /**
621  * Handle calling [[Construct]] of built-in Promise object.
622  *
623  * @return ecma value
624  */
625 ecma_value_t
ecma_builtin_promise_dispatch_construct(const ecma_value_t * arguments_list_p,ecma_length_t arguments_list_len)626 ecma_builtin_promise_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
627                                          ecma_length_t arguments_list_len) /**< number of arguments */
628 {
629   JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
630 
631   if (arguments_list_len == 0 || !ecma_op_is_callable (arguments_list_p[0]))
632   {
633     return ecma_raise_type_error (ECMA_ERR_MSG ("First parameter must be callable."));
634   }
635 
636   return ecma_op_create_promise_object (arguments_list_p[0], ECMA_PROMISE_EXECUTOR_FUNCTION);
637 } /* ecma_builtin_promise_dispatch_construct */
638 
639 /**
640  * 25.4.4.6 get Promise [ @@species ] accessor
641  *
642  * @return ecma_value
643  *         returned value must be freed with ecma_free_value
644  */
645 ecma_value_t
ecma_builtin_promise_species_get(ecma_value_t this_value)646 ecma_builtin_promise_species_get (ecma_value_t this_value) /**< This Value */
647 {
648   return ecma_copy_value (this_value);
649 } /* ecma_builtin_promise_species_get */
650 
651 /**
652  * @}
653  * @}
654  * @}
655  */
656 
657 #endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */
658