Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions jerry-core/ecma/base/ecma-gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,11 @@ ecma_gc_mark_executable_object (ecma_object_t *object_p) /**< object */

register_p++;
}

if (ecma_is_value_object (executable_object_p->frame_ctx.block_result))
{
ecma_gc_set_object_visited (ecma_get_object_from_value (executable_object_p->frame_ctx.block_result));
}
} /* ecma_gc_mark_executable_object */

#endif /* ENABLED (JERRY_ESNEXT) */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,6 @@ static const uint8_t ecma_builtin_generator_prototype_return[2] =
CBC_EXT_OPCODE, CBC_EXT_RETURN
};

/**
* Byte code sequence which throws an exception.
*/
static const uint8_t ecma_builtin_generator_prototype_throw[1] =
{
CBC_THROW
};

/**
* Helper function for next / return / throw
*
Expand Down Expand Up @@ -148,7 +140,7 @@ ecma_builtin_generator_prototype_object_do (ecma_value_t this_arg, /**< this arg
}
else if (resume_mode == ECMA_ITERATOR_THROW)
{
executable_object_p->frame_ctx.byte_code_p = ecma_builtin_generator_prototype_throw;
executable_object_p->frame_ctx.byte_code_p = opfunc_resume_executable_object_with_throw;
}

ecma_value_t value = opfunc_resume_executable_object (executable_object_p, arg);
Expand Down
5 changes: 5 additions & 0 deletions jerry-core/ecma/operations/ecma-function-object.c
Original file line number Diff line number Diff line change
Expand Up @@ -1289,6 +1289,11 @@ ecma_op_function_construct (ecma_object_t *func_obj_p, /**< Function object */
message_p = ECMA_ERR_MSG ("Generator functions cannot be invoked with 'new'.");
break;
}
case CBC_FUNCTION_ASYNC:
{
message_p = ECMA_ERR_MSG ("Async functions cannot be invoked with 'new'.");
break;
}
case CBC_FUNCTION_ARROW:
{
message_p = ECMA_ERR_MSG ("Arrow functions cannot be invoked with 'new'.");
Expand Down
85 changes: 83 additions & 2 deletions jerry-core/ecma/operations/ecma-jobqueue.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "ecma-objects.h"
#include "ecma-promise-object.h"
#include "jcontext.h"
#include "opcodes.h"

#if ENABLED (JERRY_BUILTIN_PROMISE)

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

/**
* Description of the PromiseAsyncReactionJob
*/
typedef struct
{
ecma_job_queue_item_t header; /**< job queue item header */
ecma_value_t executable_object; /**< executable object */
ecma_value_t argument; /**< argument for the reaction */
} ecma_job_promise_async_reaction_t;

/**
* Description of the PromiseResolveThenableJob
*/
Expand Down Expand Up @@ -103,6 +114,21 @@ ecma_free_promise_reaction_job (ecma_job_promise_reaction_t *job_p) /**< points
jmem_heap_free_block (job_p, sizeof (ecma_job_promise_reaction_t));
} /* ecma_free_promise_reaction_job */

/**
* Free the heap and the member of the PromiseAsyncReactionJob.
*/
static void
ecma_free_promise_async_reaction_job (ecma_job_promise_async_reaction_t *job_p) /**< points to the
* PromiseAsyncReactionJob */
{
JERRY_ASSERT (job_p != NULL);

ecma_free_value (job_p->executable_object);
ecma_free_value (job_p->argument);

jmem_heap_free_block (job_p, sizeof (ecma_job_promise_async_reaction_t));
} /* ecma_free_promise_async_reaction_job */

/**
* Free the heap and the member of the PromiseResolveThenableJob.
*/
Expand Down Expand Up @@ -196,6 +222,31 @@ ecma_process_promise_reaction_job (ecma_job_promise_reaction_t *job_p) /**< the
return status;
} /* ecma_process_promise_reaction_job */

/**
* The processor for PromiseAsyncReactionJob.
*
* @return ecma value
* Returned value must be freed with ecma_free_value
*/
static ecma_value_t
ecma_process_promise_async_reaction_job (ecma_job_promise_async_reaction_t *job_p) /**< the job to be operated */
{
ecma_object_t *object_p = ecma_get_object_from_value (job_p->executable_object);
vm_executable_object_t *executable_object_p = (vm_executable_object_t *) object_p;

if (ecma_job_queue_get_type (&job_p->header) == ECMA_JOB_PROMISE_ASYNC_REACTION_REJECTED)
{
executable_object_p->frame_ctx.byte_code_p = opfunc_resume_executable_object_with_throw;
}

ecma_value_t result = opfunc_resume_executable_object (executable_object_p, job_p->argument);
/* Argument reference is taken by opfunc_resume_executable_object. */
job_p->argument = ECMA_VALUE_UNDEFINED;
ecma_free_promise_async_reaction_job (job_p);

return result;
} /* ecma_process_promise_async_reaction_job */

/**
* Process the PromiseResolveThenableJob.
*
Expand Down Expand Up @@ -273,7 +324,7 @@ ecma_enqueue_job (ecma_job_queue_item_t *job_p) /**< the job */
} /* ecma_enqueue_job */

/**
* Enqueue a PromiseReactionJob into the jobqueue.
* Enqueue a PromiseReactionJob into the job queue.
*/
void
ecma_enqueue_promise_reaction_job (ecma_value_t capability, /**< capability object */
Expand All @@ -291,7 +342,25 @@ ecma_enqueue_promise_reaction_job (ecma_value_t capability, /**< capability obje
} /* ecma_enqueue_promise_reaction_job */

/**
* Enqueue a PromiseResolveThenableJob into the jobqueue.
* Enqueue a PromiseAsyncReactionJob into the job queue.
*/
void
ecma_enqueue_promise_async_reaction_job (ecma_value_t executable_object, /**< executable object */
ecma_value_t argument, /**< argument */
bool is_rejected) /**< is_fulfilled */
{
ecma_job_promise_async_reaction_t *job_p;
job_p = (ecma_job_promise_async_reaction_t *) jmem_heap_alloc_block (sizeof (ecma_job_promise_async_reaction_t));
job_p->header.next_and_type = (is_rejected ? ECMA_JOB_PROMISE_ASYNC_REACTION_REJECTED
: ECMA_JOB_PROMISE_ASYNC_REACTION_FULFILLED);
job_p->executable_object = ecma_copy_value (executable_object);
job_p->argument = ecma_copy_value (argument);

ecma_enqueue_job (&job_p->header);
} /* ecma_enqueue_promise_async_reaction_job */

/**
* Enqueue a PromiseResolveThenableJob into the job queue.
*/
void
ecma_enqueue_promise_resolve_thenable_job (ecma_value_t promise, /**< promise to be resolved */
Expand Down Expand Up @@ -338,6 +407,12 @@ ecma_process_all_enqueued_jobs (void)
ret = ecma_process_promise_reaction_job ((ecma_job_promise_reaction_t *) job_p);
break;
}
case ECMA_JOB_PROMISE_ASYNC_REACTION_FULFILLED:
case ECMA_JOB_PROMISE_ASYNC_REACTION_REJECTED:
{
ret = ecma_process_promise_async_reaction_job ((ecma_job_promise_async_reaction_t *) job_p);
break;
}
default:
{
JERRY_ASSERT (ecma_job_queue_get_type (job_p) == ECMA_JOB_PROMISE_THENABLE);
Expand Down Expand Up @@ -369,6 +444,12 @@ ecma_free_all_enqueued_jobs (void)
ecma_free_promise_reaction_job ((ecma_job_promise_reaction_t *) job_p);
break;
}
case ECMA_JOB_PROMISE_ASYNC_REACTION_FULFILLED:
case ECMA_JOB_PROMISE_ASYNC_REACTION_REJECTED:
{
ecma_free_promise_async_reaction_job ((ecma_job_promise_async_reaction_t *) job_p);
break;
}
default:
{
JERRY_ASSERT (ecma_job_queue_get_type (job_p) == ECMA_JOB_PROMISE_THENABLE);
Expand Down
4 changes: 4 additions & 0 deletions jerry-core/ecma/operations/ecma-jobqueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@
typedef enum
{
ECMA_JOB_PROMISE_REACTION, /**< promise reaction job */
ECMA_JOB_PROMISE_ASYNC_REACTION_FULFILLED, /**< fulfilled promise async reaction job */
ECMA_JOB_PROMISE_ASYNC_REACTION_REJECTED, /**< rejected promise async reaction job */
ECMA_JOB_PROMISE_THENABLE, /**< promise thenable job */
} ecma_job_queue_item_type_t;

Expand All @@ -45,6 +47,8 @@ typedef struct
void ecma_job_queue_init (void);

void ecma_enqueue_promise_reaction_job (ecma_value_t capability, ecma_value_t handler, ecma_value_t argument);
void ecma_enqueue_promise_async_reaction_job (ecma_value_t executable_object,
ecma_value_t argument, bool is_rejected);
void ecma_enqueue_promise_resolve_thenable_job (ecma_value_t promise, ecma_value_t thenable, ecma_value_t then);
void ecma_free_all_enqueued_jobs (void);

Expand Down
Loading