1425bb815Sopenharmony_ci/* Copyright JS Foundation and other contributors, http://js.foundation
2425bb815Sopenharmony_ci *
3425bb815Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4425bb815Sopenharmony_ci * you may not use this file except in compliance with the License.
5425bb815Sopenharmony_ci * You may obtain a copy of the License at
6425bb815Sopenharmony_ci *
7425bb815Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8425bb815Sopenharmony_ci *
9425bb815Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10425bb815Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS
11425bb815Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12425bb815Sopenharmony_ci * See the License for the specific language governing permissions and
13425bb815Sopenharmony_ci * limitations under the License.
14425bb815Sopenharmony_ci */
15425bb815Sopenharmony_ci
16425bb815Sopenharmony_ci#include "ecma-function-object.h"
17425bb815Sopenharmony_ci#include "ecma-globals.h"
18425bb815Sopenharmony_ci#include "ecma-helpers.h"
19425bb815Sopenharmony_ci#include "ecma-jobqueue.h"
20425bb815Sopenharmony_ci#include "ecma-objects.h"
21425bb815Sopenharmony_ci#include "ecma-promise-object.h"
22425bb815Sopenharmony_ci#include "jcontext.h"
23425bb815Sopenharmony_ci
24425bb815Sopenharmony_ci#if ENABLED (JERRY_ES2015_BUILTIN_PROMISE)
25425bb815Sopenharmony_ci
26425bb815Sopenharmony_ci/**
27425bb815Sopenharmony_ci * Mask for job queue type.
28425bb815Sopenharmony_ci */
29425bb815Sopenharmony_ci#define ECMA_JOB_QUEURE_TYPE_MASK ((uintptr_t) 0x07)
30425bb815Sopenharmony_ci
31425bb815Sopenharmony_ci/** \addtogroup ecma ECMA
32425bb815Sopenharmony_ci * @{
33425bb815Sopenharmony_ci *
34425bb815Sopenharmony_ci * \addtogroup ecmajobqueue ECMA Job Queue related routines
35425bb815Sopenharmony_ci * @{
36425bb815Sopenharmony_ci */
37425bb815Sopenharmony_ci
38425bb815Sopenharmony_ci/**
39425bb815Sopenharmony_ci * Description of the PromiseReactionJob
40425bb815Sopenharmony_ci */
41425bb815Sopenharmony_citypedef struct
42425bb815Sopenharmony_ci{
43425bb815Sopenharmony_ci  ecma_job_queue_item_t header; /**< job queue item header */
44425bb815Sopenharmony_ci  ecma_value_t capability; /**< capability object */
45425bb815Sopenharmony_ci  ecma_value_t handler; /**< handler function */
46425bb815Sopenharmony_ci  ecma_value_t argument; /**< argument for the reaction */
47425bb815Sopenharmony_ci} ecma_job_promise_reaction_t;
48425bb815Sopenharmony_ci
49425bb815Sopenharmony_ci/**
50425bb815Sopenharmony_ci * Description of the PromiseResolveThenableJob
51425bb815Sopenharmony_ci */
52425bb815Sopenharmony_citypedef struct
53425bb815Sopenharmony_ci{
54425bb815Sopenharmony_ci  ecma_job_queue_item_t header; /**< job queue item header */
55425bb815Sopenharmony_ci  ecma_value_t promise; /**< promise to be resolved */
56425bb815Sopenharmony_ci  ecma_value_t thenable; /**< thenable object */
57425bb815Sopenharmony_ci  ecma_value_t then; /**< 'then' function */
58425bb815Sopenharmony_ci} ecma_job_promise_resolve_thenable_t;
59425bb815Sopenharmony_ci
60425bb815Sopenharmony_ci/**
61425bb815Sopenharmony_ci * Initialize the jobqueue.
62425bb815Sopenharmony_ci */
63425bb815Sopenharmony_civoid ecma_job_queue_init (void)
64425bb815Sopenharmony_ci{
65425bb815Sopenharmony_ci  JERRY_CONTEXT (job_queue_head_p) = NULL;
66425bb815Sopenharmony_ci  JERRY_CONTEXT (job_queue_tail_p) = NULL;
67425bb815Sopenharmony_ci} /* ecma_job_queue_init */
68425bb815Sopenharmony_ci
69425bb815Sopenharmony_ci/**
70425bb815Sopenharmony_ci * Get the type of the job.
71425bb815Sopenharmony_ci *
72425bb815Sopenharmony_ci * @return type of the job
73425bb815Sopenharmony_ci */
74425bb815Sopenharmony_cistatic inline ecma_job_queue_item_type_t JERRY_ATTR_ALWAYS_INLINE
75425bb815Sopenharmony_ciecma_job_queue_get_type (ecma_job_queue_item_t *job_p) /**< the job */
76425bb815Sopenharmony_ci{
77425bb815Sopenharmony_ci  return (ecma_job_queue_item_type_t) (job_p->next_and_type & ECMA_JOB_QUEURE_TYPE_MASK);
78425bb815Sopenharmony_ci} /* ecma_job_queue_get_type */
79425bb815Sopenharmony_ci
80425bb815Sopenharmony_ci/**
81425bb815Sopenharmony_ci * Get the next job of the job queue.
82425bb815Sopenharmony_ci *
83425bb815Sopenharmony_ci * @return next job
84425bb815Sopenharmony_ci */
85425bb815Sopenharmony_cistatic inline ecma_job_queue_item_t *JERRY_ATTR_ALWAYS_INLINE
86425bb815Sopenharmony_ciecma_job_queue_get_next (ecma_job_queue_item_t *job_p) /**< the job */
87425bb815Sopenharmony_ci{
88425bb815Sopenharmony_ci  return (ecma_job_queue_item_t *) (job_p->next_and_type & ~ECMA_JOB_QUEURE_TYPE_MASK);
89425bb815Sopenharmony_ci} /* ecma_job_queue_get_next */
90425bb815Sopenharmony_ci
91425bb815Sopenharmony_ci/**
92425bb815Sopenharmony_ci * Free the heap and the member of the PromiseReactionJob.
93425bb815Sopenharmony_ci */
94425bb815Sopenharmony_cistatic void
95425bb815Sopenharmony_ciecma_free_promise_reaction_job (ecma_job_promise_reaction_t *job_p) /**< points to the PromiseReactionJob */
96425bb815Sopenharmony_ci{
97425bb815Sopenharmony_ci  JERRY_ASSERT (job_p != NULL);
98425bb815Sopenharmony_ci
99425bb815Sopenharmony_ci  ecma_free_value (job_p->capability);
100425bb815Sopenharmony_ci  ecma_free_value (job_p->handler);
101425bb815Sopenharmony_ci  ecma_free_value (job_p->argument);
102425bb815Sopenharmony_ci
103425bb815Sopenharmony_ci  jmem_heap_free_block (job_p, sizeof (ecma_job_promise_reaction_t));
104425bb815Sopenharmony_ci} /* ecma_free_promise_reaction_job */
105425bb815Sopenharmony_ci
106425bb815Sopenharmony_ci/**
107425bb815Sopenharmony_ci * Free the heap and the member of the PromiseResolveThenableJob.
108425bb815Sopenharmony_ci */
109425bb815Sopenharmony_cistatic void
110425bb815Sopenharmony_ciecma_free_promise_resolve_thenable_job (ecma_job_promise_resolve_thenable_t *job_p) /**< points to the
111425bb815Sopenharmony_ci                                                                                     *   PromiseResolveThenableJob */
112425bb815Sopenharmony_ci{
113425bb815Sopenharmony_ci  JERRY_ASSERT (job_p != NULL);
114425bb815Sopenharmony_ci
115425bb815Sopenharmony_ci  ecma_free_value (job_p->promise);
116425bb815Sopenharmony_ci  ecma_free_value (job_p->thenable);
117425bb815Sopenharmony_ci  ecma_free_value (job_p->then);
118425bb815Sopenharmony_ci
119425bb815Sopenharmony_ci  jmem_heap_free_block (job_p, sizeof (ecma_job_promise_resolve_thenable_t));
120425bb815Sopenharmony_ci} /* ecma_free_promise_resolve_thenable_job */
121425bb815Sopenharmony_ci
122425bb815Sopenharmony_ci/**
123425bb815Sopenharmony_ci * The processor for PromiseReactionJob.
124425bb815Sopenharmony_ci *
125425bb815Sopenharmony_ci * See also: ES2015 25.4.2.1
126425bb815Sopenharmony_ci *
127425bb815Sopenharmony_ci * @return ecma value
128425bb815Sopenharmony_ci *         Returned value must be freed with ecma_free_value
129425bb815Sopenharmony_ci */
130425bb815Sopenharmony_cistatic ecma_value_t
131425bb815Sopenharmony_ciecma_process_promise_reaction_job (ecma_job_promise_reaction_t *job_p) /**< the job to be operated */
132425bb815Sopenharmony_ci{
133425bb815Sopenharmony_ci  ecma_string_t *resolve_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_RESOLVE);
134425bb815Sopenharmony_ci  ecma_string_t *reject_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_REJECT);
135425bb815Sopenharmony_ci
136425bb815Sopenharmony_ci  /* 2. */
137425bb815Sopenharmony_ci  ecma_value_t capability = job_p->capability;
138425bb815Sopenharmony_ci  /* 3. */
139425bb815Sopenharmony_ci  ecma_value_t handler = job_p->handler;
140425bb815Sopenharmony_ci
141425bb815Sopenharmony_ci  JERRY_ASSERT (ecma_is_value_boolean (handler) || ecma_op_is_callable (handler));
142425bb815Sopenharmony_ci
143425bb815Sopenharmony_ci  ecma_value_t handler_result;
144425bb815Sopenharmony_ci
145425bb815Sopenharmony_ci  if (ecma_is_value_boolean (handler))
146425bb815Sopenharmony_ci  {
147425bb815Sopenharmony_ci    /* 4-5. True indicates "identity" and false indicates "thrower" */
148425bb815Sopenharmony_ci    handler_result = ecma_copy_value (job_p->argument);
149425bb815Sopenharmony_ci  }
150425bb815Sopenharmony_ci  else
151425bb815Sopenharmony_ci  {
152425bb815Sopenharmony_ci    /* 6. */
153425bb815Sopenharmony_ci    handler_result = ecma_op_function_call (ecma_get_object_from_value (handler),
154425bb815Sopenharmony_ci                                            ECMA_VALUE_UNDEFINED,
155425bb815Sopenharmony_ci                                            &(job_p->argument),
156425bb815Sopenharmony_ci                                            1);
157425bb815Sopenharmony_ci  }
158425bb815Sopenharmony_ci
159425bb815Sopenharmony_ci  ecma_value_t status;
160425bb815Sopenharmony_ci
161425bb815Sopenharmony_ci  if (ecma_is_value_false (handler) || ECMA_IS_VALUE_ERROR (handler_result))
162425bb815Sopenharmony_ci  {
163425bb815Sopenharmony_ci    if (ECMA_IS_VALUE_ERROR (handler_result))
164425bb815Sopenharmony_ci    {
165425bb815Sopenharmony_ci      handler_result = jcontext_take_exception ();
166425bb815Sopenharmony_ci    }
167425bb815Sopenharmony_ci
168425bb815Sopenharmony_ci    /* 7. */
169425bb815Sopenharmony_ci    ecma_value_t reject = ecma_op_object_get (ecma_get_object_from_value (capability), reject_str_p);
170425bb815Sopenharmony_ci
171425bb815Sopenharmony_ci    JERRY_ASSERT (ecma_op_is_callable (reject));
172425bb815Sopenharmony_ci
173425bb815Sopenharmony_ci    status = ecma_op_function_call (ecma_get_object_from_value (reject),
174425bb815Sopenharmony_ci                                    ECMA_VALUE_UNDEFINED,
175425bb815Sopenharmony_ci                                    &handler_result,
176425bb815Sopenharmony_ci                                    1);
177425bb815Sopenharmony_ci    ecma_free_value (reject);
178425bb815Sopenharmony_ci  }
179425bb815Sopenharmony_ci  else
180425bb815Sopenharmony_ci  {
181425bb815Sopenharmony_ci    /* 8. */
182425bb815Sopenharmony_ci    ecma_value_t resolve = ecma_op_object_get (ecma_get_object_from_value (capability), resolve_str_p);
183425bb815Sopenharmony_ci
184425bb815Sopenharmony_ci    JERRY_ASSERT (ecma_op_is_callable (resolve));
185425bb815Sopenharmony_ci
186425bb815Sopenharmony_ci    status = ecma_op_function_call (ecma_get_object_from_value (resolve),
187425bb815Sopenharmony_ci                                    ECMA_VALUE_UNDEFINED,
188425bb815Sopenharmony_ci                                    &handler_result,
189425bb815Sopenharmony_ci                                    1);
190425bb815Sopenharmony_ci    ecma_free_value (resolve);
191425bb815Sopenharmony_ci  }
192425bb815Sopenharmony_ci
193425bb815Sopenharmony_ci  ecma_free_value (handler_result);
194425bb815Sopenharmony_ci  ecma_free_promise_reaction_job (job_p);
195425bb815Sopenharmony_ci
196425bb815Sopenharmony_ci  return status;
197425bb815Sopenharmony_ci} /* ecma_process_promise_reaction_job */
198425bb815Sopenharmony_ci
199425bb815Sopenharmony_ci/**
200425bb815Sopenharmony_ci * Process the PromiseResolveThenableJob.
201425bb815Sopenharmony_ci *
202425bb815Sopenharmony_ci * See also: ES2015 25.4.2.2
203425bb815Sopenharmony_ci *
204425bb815Sopenharmony_ci * @return ecma value
205425bb815Sopenharmony_ci *         Returned value must be freed with ecma_free_value
206425bb815Sopenharmony_ci */
207425bb815Sopenharmony_cistatic ecma_value_t
208425bb815Sopenharmony_ciecma_process_promise_resolve_thenable_job (ecma_job_promise_resolve_thenable_t *job_p) /**< the job to be operated */
209425bb815Sopenharmony_ci{
210425bb815Sopenharmony_ci  ecma_object_t *promise_p = ecma_get_object_from_value (job_p->promise);
211425bb815Sopenharmony_ci  ecma_promise_resolving_functions_t funcs;
212425bb815Sopenharmony_ci  ecma_promise_create_resolving_functions (promise_p, &funcs, true);
213425bb815Sopenharmony_ci
214425bb815Sopenharmony_ci  ecma_string_t *str_resolve_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_RESOLVE_FUNCTION);
215425bb815Sopenharmony_ci  ecma_string_t *str_reject_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_REJECT_FUNCTION);
216425bb815Sopenharmony_ci
217425bb815Sopenharmony_ci  ecma_op_object_put (promise_p,
218425bb815Sopenharmony_ci                      str_resolve_p,
219425bb815Sopenharmony_ci                      funcs.resolve,
220425bb815Sopenharmony_ci                      false);
221425bb815Sopenharmony_ci  ecma_op_object_put (promise_p,
222425bb815Sopenharmony_ci                      str_reject_p,
223425bb815Sopenharmony_ci                      funcs.reject,
224425bb815Sopenharmony_ci                      false);
225425bb815Sopenharmony_ci
226425bb815Sopenharmony_ci  ecma_value_t argv[] = { funcs.resolve, funcs.reject };
227425bb815Sopenharmony_ci  ecma_value_t ret;
228425bb815Sopenharmony_ci  ecma_value_t then_call_result = ecma_op_function_call (ecma_get_object_from_value (job_p->then),
229425bb815Sopenharmony_ci                                                         job_p->thenable,
230425bb815Sopenharmony_ci                                                         argv,
231425bb815Sopenharmony_ci                                                         2);
232425bb815Sopenharmony_ci
233425bb815Sopenharmony_ci  ret = then_call_result;
234425bb815Sopenharmony_ci
235425bb815Sopenharmony_ci  if (ECMA_IS_VALUE_ERROR (then_call_result))
236425bb815Sopenharmony_ci  {
237425bb815Sopenharmony_ci    then_call_result = jcontext_take_exception ();
238425bb815Sopenharmony_ci
239425bb815Sopenharmony_ci    ret = ecma_op_function_call (ecma_get_object_from_value (funcs.reject),
240425bb815Sopenharmony_ci                                 ECMA_VALUE_UNDEFINED,
241425bb815Sopenharmony_ci                                 &then_call_result,
242425bb815Sopenharmony_ci                                 1);
243425bb815Sopenharmony_ci
244425bb815Sopenharmony_ci    ecma_free_value (then_call_result);
245425bb815Sopenharmony_ci  }
246425bb815Sopenharmony_ci
247425bb815Sopenharmony_ci  ecma_promise_free_resolving_functions (&funcs);
248425bb815Sopenharmony_ci  ecma_free_promise_resolve_thenable_job (job_p);
249425bb815Sopenharmony_ci
250425bb815Sopenharmony_ci  return ret;
251425bb815Sopenharmony_ci} /* ecma_process_promise_resolve_thenable_job */
252425bb815Sopenharmony_ci
253425bb815Sopenharmony_ci/**
254425bb815Sopenharmony_ci * Enqueue a Promise job into the jobqueue.
255425bb815Sopenharmony_ci */
256425bb815Sopenharmony_cistatic void
257425bb815Sopenharmony_ciecma_enqueue_job (ecma_job_queue_item_t *job_p) /**< the job */
258425bb815Sopenharmony_ci{
259425bb815Sopenharmony_ci  JERRY_ASSERT (job_p->next_and_type <= ECMA_JOB_QUEURE_TYPE_MASK);
260425bb815Sopenharmony_ci
261425bb815Sopenharmony_ci  if (JERRY_CONTEXT (job_queue_head_p) == NULL)
262425bb815Sopenharmony_ci  {
263425bb815Sopenharmony_ci    JERRY_CONTEXT (job_queue_head_p) = job_p;
264425bb815Sopenharmony_ci    JERRY_CONTEXT (job_queue_tail_p) = job_p;
265425bb815Sopenharmony_ci  }
266425bb815Sopenharmony_ci  else
267425bb815Sopenharmony_ci  {
268425bb815Sopenharmony_ci    JERRY_ASSERT ((JERRY_CONTEXT (job_queue_tail_p)->next_and_type & ~ECMA_JOB_QUEURE_TYPE_MASK) == 0);
269425bb815Sopenharmony_ci
270425bb815Sopenharmony_ci    JERRY_CONTEXT (job_queue_tail_p)->next_and_type |= (uintptr_t) job_p;
271425bb815Sopenharmony_ci    JERRY_CONTEXT (job_queue_tail_p) = job_p;
272425bb815Sopenharmony_ci  }
273425bb815Sopenharmony_ci} /* ecma_enqueue_job */
274425bb815Sopenharmony_ci
275425bb815Sopenharmony_ci/**
276425bb815Sopenharmony_ci * Enqueue a PromiseReactionJob into the jobqueue.
277425bb815Sopenharmony_ci */
278425bb815Sopenharmony_civoid
279425bb815Sopenharmony_ciecma_enqueue_promise_reaction_job (ecma_value_t capability, /**< capability object */
280425bb815Sopenharmony_ci                                   ecma_value_t handler, /**< handler function */
281425bb815Sopenharmony_ci                                   ecma_value_t argument) /**< argument for the reaction */
282425bb815Sopenharmony_ci{
283425bb815Sopenharmony_ci  ecma_job_promise_reaction_t *job_p;
284425bb815Sopenharmony_ci  job_p = (ecma_job_promise_reaction_t *) jmem_heap_alloc_block (sizeof (ecma_job_promise_reaction_t));
285425bb815Sopenharmony_ci  job_p->header.next_and_type = ECMA_JOB_PROMISE_REACTION;
286425bb815Sopenharmony_ci  job_p->capability = ecma_copy_value (capability);
287425bb815Sopenharmony_ci  job_p->handler = ecma_copy_value (handler);
288425bb815Sopenharmony_ci  job_p->argument = ecma_copy_value (argument);
289425bb815Sopenharmony_ci
290425bb815Sopenharmony_ci  ecma_enqueue_job (&job_p->header);
291425bb815Sopenharmony_ci} /* ecma_enqueue_promise_reaction_job */
292425bb815Sopenharmony_ci
293425bb815Sopenharmony_ci/**
294425bb815Sopenharmony_ci * Enqueue a PromiseResolveThenableJob into the jobqueue.
295425bb815Sopenharmony_ci */
296425bb815Sopenharmony_civoid
297425bb815Sopenharmony_ciecma_enqueue_promise_resolve_thenable_job (ecma_value_t promise, /**< promise to be resolved */
298425bb815Sopenharmony_ci                                           ecma_value_t thenable, /**< thenable object */
299425bb815Sopenharmony_ci                                           ecma_value_t then) /**< 'then' function */
300425bb815Sopenharmony_ci{
301425bb815Sopenharmony_ci  JERRY_ASSERT (ecma_is_promise (ecma_get_object_from_value (promise)));
302425bb815Sopenharmony_ci  JERRY_ASSERT (ecma_is_value_object (thenable));
303425bb815Sopenharmony_ci  JERRY_ASSERT (ecma_op_is_callable (then));
304425bb815Sopenharmony_ci
305425bb815Sopenharmony_ci  ecma_job_promise_resolve_thenable_t *job_p;
306425bb815Sopenharmony_ci  job_p = (ecma_job_promise_resolve_thenable_t *) jmem_heap_alloc_block (sizeof (ecma_job_promise_resolve_thenable_t));
307425bb815Sopenharmony_ci  job_p->header.next_and_type = ECMA_JOB_PROMISE_THENABLE;
308425bb815Sopenharmony_ci  job_p->promise = ecma_copy_value (promise);
309425bb815Sopenharmony_ci  job_p->thenable = ecma_copy_value (thenable);
310425bb815Sopenharmony_ci  job_p->then = ecma_copy_value (then);
311425bb815Sopenharmony_ci
312425bb815Sopenharmony_ci  ecma_enqueue_job (&job_p->header);
313425bb815Sopenharmony_ci} /* ecma_enqueue_promise_resolve_thenable_job */
314425bb815Sopenharmony_ci
315425bb815Sopenharmony_ci/**
316425bb815Sopenharmony_ci * Process enqueued Promise jobs until the first thrown error or until the
317425bb815Sopenharmony_ci * jobqueue becomes empty.
318425bb815Sopenharmony_ci *
319425bb815Sopenharmony_ci * @return result of the last processed job - if the jobqueue was non-empty,
320425bb815Sopenharmony_ci *         undefined - otherwise.
321425bb815Sopenharmony_ci */
322425bb815Sopenharmony_ciecma_value_t
323425bb815Sopenharmony_ciecma_process_all_enqueued_jobs (void)
324425bb815Sopenharmony_ci{
325425bb815Sopenharmony_ci  ecma_value_t ret = ECMA_VALUE_UNDEFINED;
326425bb815Sopenharmony_ci
327425bb815Sopenharmony_ci  while (JERRY_CONTEXT (job_queue_head_p) != NULL && !ECMA_IS_VALUE_ERROR (ret))
328425bb815Sopenharmony_ci  {
329425bb815Sopenharmony_ci    ecma_job_queue_item_t *job_p = JERRY_CONTEXT (job_queue_head_p);
330425bb815Sopenharmony_ci    JERRY_CONTEXT (job_queue_head_p) = ecma_job_queue_get_next (job_p);
331425bb815Sopenharmony_ci
332425bb815Sopenharmony_ci    ecma_fast_free_value (ret);
333425bb815Sopenharmony_ci
334425bb815Sopenharmony_ci    switch (ecma_job_queue_get_type (job_p))
335425bb815Sopenharmony_ci    {
336425bb815Sopenharmony_ci      case ECMA_JOB_PROMISE_REACTION:
337425bb815Sopenharmony_ci      {
338425bb815Sopenharmony_ci        ret = ecma_process_promise_reaction_job ((ecma_job_promise_reaction_t *) job_p);
339425bb815Sopenharmony_ci        break;
340425bb815Sopenharmony_ci      }
341425bb815Sopenharmony_ci      default:
342425bb815Sopenharmony_ci      {
343425bb815Sopenharmony_ci        JERRY_ASSERT (ecma_job_queue_get_type (job_p) == ECMA_JOB_PROMISE_THENABLE);
344425bb815Sopenharmony_ci
345425bb815Sopenharmony_ci        ret = ecma_process_promise_resolve_thenable_job ((ecma_job_promise_resolve_thenable_t *) job_p);
346425bb815Sopenharmony_ci        break;
347425bb815Sopenharmony_ci      }
348425bb815Sopenharmony_ci    }
349425bb815Sopenharmony_ci  }
350425bb815Sopenharmony_ci
351425bb815Sopenharmony_ci  return ret;
352425bb815Sopenharmony_ci} /* ecma_process_all_enqueued_jobs */
353425bb815Sopenharmony_ci
354425bb815Sopenharmony_ci/**
355425bb815Sopenharmony_ci * Release enqueued Promise jobs.
356425bb815Sopenharmony_ci */
357425bb815Sopenharmony_civoid
358425bb815Sopenharmony_ciecma_free_all_enqueued_jobs (void)
359425bb815Sopenharmony_ci{
360425bb815Sopenharmony_ci  while (JERRY_CONTEXT (job_queue_head_p) != NULL)
361425bb815Sopenharmony_ci  {
362425bb815Sopenharmony_ci    ecma_job_queue_item_t *job_p = JERRY_CONTEXT (job_queue_head_p);
363425bb815Sopenharmony_ci    JERRY_CONTEXT (job_queue_head_p) = ecma_job_queue_get_next (job_p);
364425bb815Sopenharmony_ci
365425bb815Sopenharmony_ci    switch (ecma_job_queue_get_type (job_p))
366425bb815Sopenharmony_ci    {
367425bb815Sopenharmony_ci      case ECMA_JOB_PROMISE_REACTION:
368425bb815Sopenharmony_ci      {
369425bb815Sopenharmony_ci        ecma_free_promise_reaction_job ((ecma_job_promise_reaction_t *) job_p);
370425bb815Sopenharmony_ci        break;
371425bb815Sopenharmony_ci      }
372425bb815Sopenharmony_ci      default:
373425bb815Sopenharmony_ci      {
374425bb815Sopenharmony_ci        JERRY_ASSERT (ecma_job_queue_get_type (job_p) == ECMA_JOB_PROMISE_THENABLE);
375425bb815Sopenharmony_ci
376425bb815Sopenharmony_ci        ecma_free_promise_resolve_thenable_job ((ecma_job_promise_resolve_thenable_t *) job_p);
377425bb815Sopenharmony_ci        break;
378425bb815Sopenharmony_ci      }
379425bb815Sopenharmony_ci    }
380425bb815Sopenharmony_ci  }
381425bb815Sopenharmony_ci} /* ecma_free_all_enqueued_jobs */
382425bb815Sopenharmony_ci
383425bb815Sopenharmony_ci/**
384425bb815Sopenharmony_ci * @}
385425bb815Sopenharmony_ci * @}
386425bb815Sopenharmony_ci */
387425bb815Sopenharmony_ci#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROMISE) */
388