Implement AsyncIteratorClose for for-await-of statement. (#3955)
JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
@@ -937,7 +937,7 @@ ecma_gc_free_executable_object (ecma_object_t *object_p) /**< object */
|
||||
|
||||
do
|
||||
{
|
||||
context_top_p[-1] &= (uint32_t) ~(VM_CONTEXT_HAS_LEX_ENV | VM_CONTEXT_CLOSE_ITERATOR);
|
||||
context_top_p[-1] &= (uint32_t) ~VM_CONTEXT_HAS_LEX_ENV;
|
||||
|
||||
uint32_t offsets = vm_get_context_value_offsets (context_top_p);
|
||||
|
||||
|
||||
@@ -1884,6 +1884,7 @@ typedef enum
|
||||
ECMA_AWAIT_YIELD_OPERATION, /**< wait for the generator operation (next/throw/return) */
|
||||
ECMA_AWAIT_YIELD_CLOSE, /**< wait for the result of iterator close operation */
|
||||
/* After adding new ECMA_AWAIT_YIELD items, the ECMA_AWAIT_YIELD_END should be updated. */
|
||||
ECMA_AWAIT_FOR_CLOSE, /**< wait for a close iterator result object of for-await-of statement */
|
||||
ECMA_AWAIT_FOR_NEXT, /**< wait for an iterator result object of for-await-of statement */
|
||||
} ecma_await_states_t;
|
||||
|
||||
|
||||
@@ -450,10 +450,24 @@ ecma_await_continue (vm_executable_object_t *executable_object_p, /**< executabl
|
||||
ecma_free_value (value);
|
||||
return ecma_raise_type_error (msg_p);
|
||||
}
|
||||
case ECMA_AWAIT_FOR_CLOSE:
|
||||
{
|
||||
bool is_value_object = ecma_is_value_object (value);
|
||||
ecma_free_value (value);
|
||||
ECMA_EXECUTABLE_OBJECT_RESUME_EXEC (executable_object_p);
|
||||
|
||||
if (!is_value_object
|
||||
&& VM_GET_CONTEXT_TYPE (executable_object_p->frame_ctx.stack_top_p[-1]) != VM_CONTEXT_FINALLY_THROW)
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Iterator return() result is not object"));
|
||||
}
|
||||
return ECMA_VALUE_EMPTY;
|
||||
}
|
||||
default:
|
||||
{
|
||||
JERRY_ASSERT (state == ECMA_AWAIT_FOR_NEXT);
|
||||
JERRY_ASSERT (VM_GET_CONTEXT_TYPE (executable_object_p->frame_ctx.stack_top_p[-1]) == VM_CONTEXT_FOR_AWAIT_OF);
|
||||
JERRY_ASSERT (!(executable_object_p->frame_ctx.stack_top_p[-1] & VM_CONTEXT_CLOSE_ITERATOR));
|
||||
|
||||
if (!ecma_is_value_object (value))
|
||||
{
|
||||
@@ -491,6 +505,7 @@ ecma_await_continue (vm_executable_object_t *executable_object_p, /**< executabl
|
||||
/* It seems browsers call Await(result) here, although the standard does not
|
||||
* requests to do so. The following code might follow browsers in the future. */
|
||||
ecma_deref_if_object (result);
|
||||
stack_top_p[-1] |= VM_CONTEXT_CLOSE_ITERATOR;
|
||||
stack_top_p[-2] = result;
|
||||
ECMA_EXECUTABLE_OBJECT_RESUME_EXEC (executable_object_p);
|
||||
return ECMA_VALUE_EMPTY;
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "ecma-promise-object.h"
|
||||
#include "jcontext.h"
|
||||
#include "opcodes.h"
|
||||
#include "vm-stack.h"
|
||||
|
||||
#if ENABLED (JERRY_BUILTIN_PROMISE)
|
||||
|
||||
@@ -280,6 +281,12 @@ ecma_process_promise_async_reaction_job (ecma_job_promise_async_reaction_t *job_
|
||||
|| ecma_is_value_object (executable_object_p->frame_ctx.stack_top_p[-1]));
|
||||
executable_object_p->frame_ctx.stack_top_p--;
|
||||
}
|
||||
else if (ECMA_AWAIT_GET_STATE (executable_object_p) == ECMA_AWAIT_FOR_CLOSE
|
||||
&& VM_GET_CONTEXT_TYPE (executable_object_p->frame_ctx.stack_top_p[-1]) == VM_CONTEXT_FINALLY_THROW)
|
||||
{
|
||||
ecma_free_value (job_p->argument);
|
||||
job_p->argument = ecma_copy_value (executable_object_p->frame_ctx.stack_top_p[-2]);
|
||||
}
|
||||
|
||||
/* Exception: Abort iterators, clear all status. */
|
||||
executable_object_p->extended_object.u.class_prop.extra_info &= ECMA_AWAIT_CLEAR_MASK;
|
||||
|
||||
Reference in New Issue
Block a user