Implement missing async function and async iterator prototypes. (#3962)

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2020-07-03 11:04:27 +02:00
committed by GitHub
parent f86b78a886
commit 80716cca90
22 changed files with 509 additions and 72 deletions
+2 -2
View File
@@ -733,7 +733,7 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
#if ENABLED (JERRY_ESNEXT)
const ecma_compiled_code_t *byte_code_p = ecma_op_function_get_compiled_code (ext_func_p);
if (CBC_FUNCTION_GET_TYPE (byte_code_p->status_flags) == CBC_FUNCTION_ARROW)
if (CBC_FUNCTION_IS_ARROW (byte_code_p->status_flags))
{
ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) object_p;
@@ -1269,7 +1269,7 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
ext_func_p->u.function.bytecode_cp));
#if ENABLED (JERRY_ESNEXT)
if (CBC_FUNCTION_GET_TYPE (byte_code_p->status_flags) == CBC_FUNCTION_ARROW)
if (CBC_FUNCTION_IS_ARROW (byte_code_p->status_flags))
{
ecma_free_value_if_not_object (((ecma_arrow_function_t *) object_p)->this_binding);
ecma_free_value_if_not_object (((ecma_arrow_function_t *) object_p)->new_target);
@@ -0,0 +1,43 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecma-globals.h"
#if ENABLED (JERRY_ESNEXT)
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-async-function-prototype.inc.h"
#define BUILTIN_UNDERSCORED_ID async_function_prototype
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup asyncfunctionprototype ECMA AsyncFunction.prototype object built-in
* @{
*/
/**
* @}
* @}
* @}
*/
#endif /* ENABLED (JERRY_ESNEXT) */
@@ -0,0 +1,36 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* %AsyncFunctionPrototype% built-in description (AsyncFunction.prototype)
*/
#include "ecma-builtin-helpers-macro-defines.inc.h"
#if ENABLED (JERRY_ESNEXT)
/* ECMA-262 v11, 25.7.3.1 */
OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
ECMA_BUILTIN_ID_ASYNC_FUNCTION,
ECMA_PROPERTY_FLAG_CONFIGURABLE)
/* ECMA-262 v11, 25.7.3.2 */
STRING_VALUE (LIT_GLOBAL_SYMBOL_TO_STRING_TAG,
LIT_MAGIC_STRING_ASYNC_FUNCTION_UL,
ECMA_PROPERTY_FLAG_CONFIGURABLE)
#endif /* ENABLED (JERRY_ESNEXT) */
#include "ecma-builtin-helpers-macro-undefs.inc.h"
@@ -0,0 +1,74 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecma-globals.h"
#if ENABLED (JERRY_ESNEXT)
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#include "ecma-function-object.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-async-function.inc.h"
#define BUILTIN_UNDERSCORED_ID async_function
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup asyncfunction ECMA AsyncFunction object built-in
* @{
*/
/**
* Handle calling [[Call]] of built-in AsyncFunction object
*
* @return constructed async function object - if success
* raised error otherwise
*/
ecma_value_t
ecma_builtin_async_function_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
return ecma_op_create_dynamic_function (arguments_list_p,
arguments_list_len,
ECMA_PARSE_ASYNC_FUNCTION);
} /* ecma_builtin_async_function_dispatch_call */
/**
* Handle calling [[Construct]] of built-in AsyncFunction object
*
* @return constructed async function object - if success
* raised error otherwise
*/
ecma_value_t
ecma_builtin_async_function_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
return ecma_builtin_async_function_dispatch_call (arguments_list_p, arguments_list_len);
} /* ecma_builtin_async_function_dispatch_construct */
/**
* @}
* @}
* @}
*/
#endif /* ENABLED (JERRY_ESNEXT) */
@@ -0,0 +1,41 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* %AsyncFunction% built-in description
*/
#include "ecma-builtin-helpers-macro-defines.inc.h"
#if ENABLED (JERRY_ESNEXT)
/* ECMA-262 v11, 25.7.2 */
STRING_VALUE (LIT_MAGIC_STRING_NAME,
LIT_MAGIC_STRING_ASYNC_FUNCTION_UL,
ECMA_PROPERTY_FLAG_CONFIGURABLE)
/* ECMA-262 v11, 25.7.2.1 */
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
1,
ECMA_PROPERTY_FLAG_CONFIGURABLE)
/* ECMA-262 v10, 25.7.2.2 */
OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
ECMA_BUILTIN_ID_ASYNC_FUNCTION,
ECMA_PROPERTY_FIXED)
#endif /* ENABLED (JERRY_ESNEXT) */
#include "ecma-builtin-helpers-macro-undefs.inc.h"
@@ -0,0 +1,63 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecma-builtin-helpers.h"
#include "ecma-builtins.h"
#include "ecma-iterator-object.h"
#if ENABLED (JERRY_ESNEXT)
#define ECMA_BUILTINS_INTERNAL
#include "ecma-builtins-internal.h"
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-async-iterator-prototype.inc.h"
#define BUILTIN_UNDERSCORED_ID async_iterator_prototype
#include "ecma-builtin-internal-routines-template.inc.h"
/** \addtogroup ecma ECMA
* @{
*
* \addtogroup ecmabuiltins
* @{
*
* \addtogroup %asynciteratorprototype% ECMA %AsyncIteratorPrototype% object built-in
* @{
*/
/**
* The %AsyncIteratorPrototype% object's '@@asyncIterator' routine
*
* See also:
* ECMA-262 v10, 25.1.3.1
*
* Note:
* Returned value must be freed with ecma_free_value.
*
* @return the given this value
*/
static ecma_value_t
ecma_builtin_async_iterator_prototype_object_async_iterator (ecma_value_t this_val) /**< this argument */
{
/* 1. */
return ecma_copy_value (this_val);
} /* ecma_builtin_async_iterator_prototype_object_async_iterator */
/**
* @}
* @}
* @}
*/
#endif /* ENABLED (JERRY_ESNEXT) */
@@ -0,0 +1,30 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* %AsyncIteratorPrototype% built-in description
*/
#include "ecma-builtin-helpers-macro-defines.inc.h"
#if ENABLED (JERRY_ESNEXT)
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
ROUTINE (LIT_GLOBAL_SYMBOL_ASYNC_ITERATOR, ecma_builtin_async_iterator_prototype_object_async_iterator, 0, 0)
#endif /* ENABLED (JERRY_ESNEXT) */
#include "ecma-builtin-helpers-macro-undefs.inc.h"
@@ -576,6 +576,20 @@ BUILTIN_ROUTINE (ECMA_BUILTIN_ID_SYMBOL,
true,
symbol)
/* The %AsyncFunction% object (ECMA-262 v11, 25.7.2) */
BUILTIN_ROUTINE (ECMA_BUILTIN_ID_ASYNC_FUNCTION,
ECMA_OBJECT_TYPE_FUNCTION,
ECMA_BUILTIN_ID_FUNCTION,
true,
async_function)
/* The %AsyncFunctionPrototype% object (ECMA-262 v11, 25.7.3) */
BUILTIN (ECMA_BUILTIN_ID_ASYNC_FUNCTION_PROTOTYPE,
ECMA_OBJECT_TYPE_GENERAL,
ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE,
true,
async_function_prototype)
/* The %IteratorPrototype% object (ECMA-262 v6, 25.1.2) */
BUILTIN (ECMA_BUILTIN_ID_ITERATOR_PROTOTYPE,
ECMA_OBJECT_TYPE_GENERAL,
@@ -597,6 +611,13 @@ BUILTIN (ECMA_BUILTIN_ID_STRING_ITERATOR_PROTOTYPE,
true,
string_iterator_prototype)
/* The %AsyncIteratorPrototype% object (ECMA-262 v10, 25.1.3) */
BUILTIN (ECMA_BUILTIN_ID_ASYNC_ITERATOR_PROTOTYPE,
ECMA_OBJECT_TYPE_GENERAL,
ECMA_BUILTIN_ID_OBJECT_PROTOTYPE,
true,
async_iterator_prototype)
/* The %(GeneratorFunction)% object */
BUILTIN_ROUTINE (ECMA_BUILTIN_ID_GENERATOR_FUNCTION,
ECMA_OBJECT_TYPE_FUNCTION,
@@ -635,7 +656,7 @@ BUILTIN (ECMA_BUILTIN_ID_ASYNC_GENERATOR,
/* The %(AsyncGenerator).prototype% object */
BUILTIN (ECMA_BUILTIN_ID_ASYNC_GENERATOR_PROTOTYPE,
ECMA_OBJECT_TYPE_GENERAL,
ECMA_BUILTIN_ID_ITERATOR_PROTOTYPE,
ECMA_BUILTIN_ID_ASYNC_ITERATOR_PROTOTYPE,
true,
async_generator_prototype)
@@ -186,8 +186,11 @@ ecma_async_yield_throw (vm_executable_object_t *async_generator_object_p, /**< a
/**
* Execute the next task in the command queue of the async generator
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
void
ecma_value_t
ecma_async_generator_run (vm_executable_object_t *async_generator_object_p) /**< async generator */
{
JERRY_ASSERT (async_generator_object_p->extended_object.u.class_prop.class_id
@@ -250,7 +253,7 @@ ecma_async_generator_run (vm_executable_object_t *async_generator_object_p) /**<
if (result == ECMA_VALUE_UNDEFINED)
{
return;
return ECMA_VALUE_UNDEFINED;
}
JERRY_ASSERT (ECMA_IS_VALUE_ERROR (result));
@@ -287,7 +290,10 @@ ecma_async_generator_run (vm_executable_object_t *async_generator_object_p) /**<
{
JERRY_ASSERT (head == async_generator_object_p->extended_object.u.class_prop.u.head);
ecma_async_generator_finalize (async_generator_object_p, result);
result = ECMA_VALUE_UNDEFINED;
}
return result;
} /* ecma_async_generator_run */
/**
@@ -78,7 +78,7 @@ typedef enum
ecma_value_t ecma_async_generator_enqueue (vm_executable_object_t *async_generator_object_p,
ecma_async_generator_operation_type_t operation, ecma_value_t value);
void ecma_async_generator_run (vm_executable_object_t *async_generator_object_p);
ecma_value_t ecma_async_generator_run (vm_executable_object_t *async_generator_object_p);
void ecma_async_generator_finalize (vm_executable_object_t *async_generator_object_p, ecma_value_t value);
ecma_value_t ecma_await_continue (vm_executable_object_t *async_generator_object_p, ecma_value_t value);
@@ -442,32 +442,42 @@ ecma_op_create_simple_function_object (ecma_object_t *scope_p, /**< function's s
#if ENABLED (JERRY_ESNEXT)
/**
* GeneratorFunction object creation operation.
*
* See also: ECMA-262 v5, 13.2
* Create a function object with the appropriate prototype.
*
* @return pointer to newly created Function object
*/
ecma_object_t *
ecma_op_create_generator_function_object (ecma_object_t *scope_p, /**< function's scope */
const ecma_compiled_code_t *bytecode_data_p) /**< byte-code array */
ecma_op_create_any_function_object (ecma_object_t *scope_p, /**< function's scope */
const ecma_compiled_code_t *bytecode_data_p) /**< byte-code array */
{
return ecma_op_create_function_object (scope_p, bytecode_data_p, ECMA_BUILTIN_ID_GENERATOR);
} /* ecma_op_create_generator_function_object */
ecma_builtin_id_t proto_id;
/**
* AsyncGeneratorFunction object creation operation.
*
* See also: ECMA-262 v10, 25.3
*
* @return pointer to newly created Function object
*/
ecma_object_t *
ecma_op_create_async_generator_function_object (ecma_object_t *scope_p, /**< function's scope */
const ecma_compiled_code_t *bytecode_data_p) /**< byte-code array */
{
return ecma_op_create_function_object (scope_p, bytecode_data_p, ECMA_BUILTIN_ID_ASYNC_GENERATOR);
} /* ecma_op_create_async_generator_function_object */
switch (CBC_FUNCTION_GET_TYPE (bytecode_data_p->status_flags))
{
case CBC_FUNCTION_GENERATOR:
{
proto_id = ECMA_BUILTIN_ID_GENERATOR;
break;
}
case CBC_FUNCTION_ASYNC:
{
proto_id = ECMA_BUILTIN_ID_ASYNC_FUNCTION_PROTOTYPE;
break;
}
case CBC_FUNCTION_ASYNC_GENERATOR:
{
proto_id = ECMA_BUILTIN_ID_ASYNC_GENERATOR;
break;
}
default:
{
proto_id = ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE;
break;
}
}
return ecma_op_create_function_object (scope_p, bytecode_data_p, proto_id);
} /* ecma_op_create_any_function_object */
/**
* Arrow function object creation operation.
@@ -481,7 +491,17 @@ ecma_op_create_arrow_function_object (ecma_object_t *scope_p, /**< function's sc
const ecma_compiled_code_t *bytecode_data_p, /**< byte-code array */
ecma_value_t this_binding) /**< value of 'this' binding */
{
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
ecma_object_t *prototype_obj_p;
if (CBC_FUNCTION_GET_TYPE (bytecode_data_p->status_flags) == CBC_FUNCTION_ARROW)
{
prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
}
else
{
JERRY_ASSERT (CBC_FUNCTION_GET_TYPE (bytecode_data_p->status_flags) == CBC_FUNCTION_ASYNC_ARROW);
prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_ASYNC_FUNCTION_PROTOTYPE);
}
size_t arrow_function_object_size = sizeof (ecma_arrow_function_t);
@@ -851,7 +871,7 @@ ecma_op_function_call_simple (ecma_object_t *func_obj_p, /**< Function object */
#if ENABLED (JERRY_ESNEXT)
ecma_object_t *old_function_object_p = JERRY_CONTEXT (current_function_obj_p);
if (JERRY_UNLIKELY (function_type == CBC_FUNCTION_ARROW))
if (JERRY_UNLIKELY (CBC_FUNCTION_IS_ARROW (status_flags)))
{
ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) func_obj_p;
@@ -1298,6 +1318,11 @@ ecma_op_function_construct (ecma_object_t *func_obj_p, /**< Function object */
message_p = ECMA_ERR_MSG ("Arrow functions cannot be invoked with 'new'.");
break;
}
case CBC_FUNCTION_ASYNC_ARROW:
{
message_p = ECMA_ERR_MSG ("Async arrow functions cannot be invoked with 'new'.");
break;
}
default:
{
JERRY_ASSERT (CBC_FUNCTION_GET_TYPE (byte_code_p->status_flags) == CBC_FUNCTION_ACCESSOR);
@@ -55,10 +55,7 @@ ecma_value_t
ecma_op_function_get_super_constructor (ecma_object_t *func_obj_p);
ecma_object_t *
ecma_op_create_generator_function_object (ecma_object_t *scope_p, const ecma_compiled_code_t *bytecode_data_p);
ecma_object_t *
ecma_op_create_async_generator_function_object (ecma_object_t *scope_p, const ecma_compiled_code_t *bytecode_data_p);
ecma_op_create_any_function_object (ecma_object_t *scope_p, const ecma_compiled_code_t *bytecode_data_p);
ecma_object_t *
ecma_op_create_arrow_function_object (ecma_object_t *scope_p, const ecma_compiled_code_t *bytecode_data_p,
+7 -3
View File
@@ -343,16 +343,20 @@ ecma_process_promise_async_reaction_job (ecma_job_promise_async_reaction_t *job_
/**
* The processor for PromiseAsyncGeneratorJob.
*
* @return ecma value
* Returned value must be freed with ecma_free_value
*/
static void
static ecma_value_t
ecma_process_promise_async_generator_job (ecma_job_promise_async_generator_t *job_p) /**< the job to be operated */
{
ecma_object_t *object_p = ecma_get_object_from_value (job_p->executable_object);
ecma_async_generator_run ((vm_executable_object_t *) object_p);
ecma_value_t result = ecma_async_generator_run ((vm_executable_object_t *) object_p);
ecma_free_value (job_p->executable_object);
jmem_heap_free_block (job_p, sizeof (ecma_job_promise_async_generator_t));
return result;
} /* ecma_process_promise_async_generator_job */
/**
@@ -537,7 +541,7 @@ ecma_process_all_enqueued_jobs (void)
}
case ECMA_JOB_PROMISE_ASYNC_GENERATOR:
{
ecma_process_promise_async_generator_job ((ecma_job_promise_async_generator_t *) job_p);
ret = ecma_process_promise_async_generator_job ((ecma_job_promise_async_generator_t *) job_p);
break;
}
default: