Skip to content

Commit 6fb7fcd

Browse files
committed
Implement async function execution.
JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg [email protected]
1 parent 1b2e0ae commit 6fb7fcd

File tree

18 files changed

+610
-172
lines changed

18 files changed

+610
-172
lines changed

jerry-core/ecma/base/ecma-gc.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,11 @@ ecma_gc_mark_executable_object (ecma_object_t *object_p) /**< object */
463463

464464
register_p++;
465465
}
466+
467+
if (ecma_is_value_object (executable_object_p->frame_ctx.block_result))
468+
{
469+
ecma_gc_set_object_visited (ecma_get_object_from_value (executable_object_p->frame_ctx.block_result));
470+
}
466471
} /* ecma_gc_mark_executable_object */
467472

468473
#endif /* ENABLED (JERRY_ESNEXT) */

jerry-core/ecma/builtin-objects/ecma-builtin-generator-prototype.c

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,6 @@ static const uint8_t ecma_builtin_generator_prototype_return[2] =
5050
CBC_EXT_OPCODE, CBC_EXT_RETURN
5151
};
5252

53-
/**
54-
* Byte code sequence which throws an exception.
55-
*/
56-
static const uint8_t ecma_builtin_generator_prototype_throw[1] =
57-
{
58-
CBC_THROW
59-
};
60-
6153
/**
6254
* Helper function for next / return / throw
6355
*
@@ -148,7 +140,7 @@ ecma_builtin_generator_prototype_object_do (ecma_value_t this_arg, /**< this arg
148140
}
149141
else if (resume_mode == ECMA_ITERATOR_THROW)
150142
{
151-
executable_object_p->frame_ctx.byte_code_p = ecma_builtin_generator_prototype_throw;
143+
executable_object_p->frame_ctx.byte_code_p = opfunc_resume_executable_object_with_throw;
152144
}
153145

154146
ecma_value_t value = opfunc_resume_executable_object (executable_object_p, arg);

jerry-core/ecma/operations/ecma-function-object.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1289,6 +1289,11 @@ ecma_op_function_construct (ecma_object_t *func_obj_p, /**< Function object */
12891289
message_p = ECMA_ERR_MSG ("Generator functions cannot be invoked with 'new'.");
12901290
break;
12911291
}
1292+
case CBC_FUNCTION_ASYNC:
1293+
{
1294+
message_p = ECMA_ERR_MSG ("Async functions cannot be invoked with 'new'.");
1295+
break;
1296+
}
12921297
case CBC_FUNCTION_ARROW:
12931298
{
12941299
message_p = ECMA_ERR_MSG ("Arrow functions cannot be invoked with 'new'.");

jerry-core/ecma/operations/ecma-jobqueue.c

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "ecma-objects.h"
2121
#include "ecma-promise-object.h"
2222
#include "jcontext.h"
23+
#include "opcodes.h"
2324

2425
#if ENABLED (JERRY_BUILTIN_PROMISE)
2526

@@ -46,6 +47,16 @@ typedef struct
4647
ecma_value_t argument; /**< argument for the reaction */
4748
} ecma_job_promise_reaction_t;
4849

50+
/**
51+
* Description of the PromiseAsyncReactionJob
52+
*/
53+
typedef struct
54+
{
55+
ecma_job_queue_item_t header; /**< job queue item header */
56+
ecma_value_t executable_object; /**< executable object */
57+
ecma_value_t argument; /**< argument for the reaction */
58+
} ecma_job_promise_async_reaction_t;
59+
4960
/**
5061
* Description of the PromiseResolveThenableJob
5162
*/
@@ -103,6 +114,21 @@ ecma_free_promise_reaction_job (ecma_job_promise_reaction_t *job_p) /**< points
103114
jmem_heap_free_block (job_p, sizeof (ecma_job_promise_reaction_t));
104115
} /* ecma_free_promise_reaction_job */
105116

117+
/**
118+
* Free the heap and the member of the PromiseAsyncReactionJob.
119+
*/
120+
static void
121+
ecma_free_promise_async_reaction_job (ecma_job_promise_async_reaction_t *job_p) /**< points to the
122+
* PromiseAsyncReactionJob */
123+
{
124+
JERRY_ASSERT (job_p != NULL);
125+
126+
ecma_free_value (job_p->executable_object);
127+
ecma_free_value (job_p->argument);
128+
129+
jmem_heap_free_block (job_p, sizeof (ecma_job_promise_async_reaction_t));
130+
} /* ecma_free_promise_async_reaction_job */
131+
106132
/**
107133
* Free the heap and the member of the PromiseResolveThenableJob.
108134
*/
@@ -196,6 +222,29 @@ ecma_process_promise_reaction_job (ecma_job_promise_reaction_t *job_p) /**< the
196222
return status;
197223
} /* ecma_process_promise_reaction_job */
198224

225+
/**
226+
* The processor for PromiseAsyncReactionJob.
227+
*
228+
* @return ecma value
229+
* Returned value must be freed with ecma_free_value
230+
*/
231+
static ecma_value_t
232+
ecma_process_promise_async_reaction_job (ecma_job_promise_async_reaction_t *job_p) /**< the job to be operated */
233+
{
234+
ecma_object_t *object_p = ecma_get_object_from_value (job_p->executable_object);
235+
vm_executable_object_t *executable_object_p = (vm_executable_object_t *) object_p;
236+
237+
if (ecma_job_queue_get_type (&job_p->header) == ECMA_JOB_PROMISE_ASYNC_REACTION_REJECTED)
238+
{
239+
executable_object_p->frame_ctx.byte_code_p = opfunc_resume_executable_object_with_throw;
240+
}
241+
242+
ecma_value_t result = opfunc_resume_executable_object (executable_object_p, job_p->argument);
243+
ecma_free_promise_async_reaction_job (job_p);
244+
245+
return result;
246+
} /* ecma_process_promise_async_reaction_job */
247+
199248
/**
200249
* Process the PromiseResolveThenableJob.
201250
*
@@ -273,7 +322,7 @@ ecma_enqueue_job (ecma_job_queue_item_t *job_p) /**< the job */
273322
} /* ecma_enqueue_job */
274323

275324
/**
276-
* Enqueue a PromiseReactionJob into the jobqueue.
325+
* Enqueue a PromiseReactionJob into the job queue.
277326
*/
278327
void
279328
ecma_enqueue_promise_reaction_job (ecma_value_t capability, /**< capability object */
@@ -291,7 +340,25 @@ ecma_enqueue_promise_reaction_job (ecma_value_t capability, /**< capability obje
291340
} /* ecma_enqueue_promise_reaction_job */
292341

293342
/**
294-
* Enqueue a PromiseResolveThenableJob into the jobqueue.
343+
* Enqueue a PromiseAsyncReactionJob into the job queue.
344+
*/
345+
void
346+
ecma_enqueue_promise_async_reaction_job (ecma_value_t executable_object, /**< executable object */
347+
ecma_value_t argument, /**< argument */
348+
bool is_rejected) /**< is_fulfilled */
349+
{
350+
ecma_job_promise_async_reaction_t *job_p;
351+
job_p = (ecma_job_promise_async_reaction_t *) jmem_heap_alloc_block (sizeof (ecma_job_promise_async_reaction_t));
352+
job_p->header.next_and_type = (is_rejected ? ECMA_JOB_PROMISE_ASYNC_REACTION_REJECTED
353+
: ECMA_JOB_PROMISE_ASYNC_REACTION_FULFILLED);
354+
job_p->executable_object = ecma_copy_value (executable_object);
355+
job_p->argument = ecma_copy_value (argument);
356+
357+
ecma_enqueue_job (&job_p->header);
358+
} /* ecma_enqueue_promise_async_reaction_job */
359+
360+
/**
361+
* Enqueue a PromiseResolveThenableJob into the job queue.
295362
*/
296363
void
297364
ecma_enqueue_promise_resolve_thenable_job (ecma_value_t promise, /**< promise to be resolved */
@@ -338,6 +405,12 @@ ecma_process_all_enqueued_jobs (void)
338405
ret = ecma_process_promise_reaction_job ((ecma_job_promise_reaction_t *) job_p);
339406
break;
340407
}
408+
case ECMA_JOB_PROMISE_ASYNC_REACTION_FULFILLED:
409+
case ECMA_JOB_PROMISE_ASYNC_REACTION_REJECTED:
410+
{
411+
ret = ecma_process_promise_async_reaction_job ((ecma_job_promise_async_reaction_t *) job_p);
412+
break;
413+
}
341414
default:
342415
{
343416
JERRY_ASSERT (ecma_job_queue_get_type (job_p) == ECMA_JOB_PROMISE_THENABLE);
@@ -369,6 +442,12 @@ ecma_free_all_enqueued_jobs (void)
369442
ecma_free_promise_reaction_job ((ecma_job_promise_reaction_t *) job_p);
370443
break;
371444
}
445+
case ECMA_JOB_PROMISE_ASYNC_REACTION_FULFILLED:
446+
case ECMA_JOB_PROMISE_ASYNC_REACTION_REJECTED:
447+
{
448+
ecma_free_promise_async_reaction_job ((ecma_job_promise_async_reaction_t *) job_p);
449+
break;
450+
}
372451
default:
373452
{
374453
JERRY_ASSERT (ecma_job_queue_get_type (job_p) == ECMA_JOB_PROMISE_THENABLE);

jerry-core/ecma/operations/ecma-jobqueue.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
typedef enum
3232
{
3333
ECMA_JOB_PROMISE_REACTION, /**< promise reaction job */
34+
ECMA_JOB_PROMISE_ASYNC_REACTION_FULFILLED, /**< fulfilled promise async reaction job */
35+
ECMA_JOB_PROMISE_ASYNC_REACTION_REJECTED, /**< rejected promise async reaction job */
3436
ECMA_JOB_PROMISE_THENABLE, /**< promise thenable job */
3537
} ecma_job_queue_item_type_t;
3638

@@ -45,6 +47,8 @@ typedef struct
4547
void ecma_job_queue_init (void);
4648

4749
void ecma_enqueue_promise_reaction_job (ecma_value_t capability, ecma_value_t handler, ecma_value_t argument);
50+
void ecma_enqueue_promise_async_reaction_job (ecma_value_t executable_object,
51+
ecma_value_t argument, bool is_rejected);
4852
void ecma_enqueue_promise_resolve_thenable_job (ecma_value_t promise, ecma_value_t thenable, ecma_value_t then);
4953
void ecma_free_all_enqueued_jobs (void);
5054

0 commit comments

Comments
 (0)