Add builtin GeneratorFunction support (#3499)
JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu
This commit is contained in:
@@ -990,8 +990,7 @@ jerry_snapshot_result (const uint32_t *snapshot_p, /**< snapshot */
|
||||
if (as_function)
|
||||
{
|
||||
ecma_object_t *lex_env_p = ecma_get_global_environment ();
|
||||
ecma_object_t *func_obj_p = ecma_op_create_function_object (lex_env_p,
|
||||
bytecode_p);
|
||||
ecma_object_t *func_obj_p = ecma_op_create_simple_function_object (lex_env_p, bytecode_p);
|
||||
|
||||
if (!(bytecode_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION))
|
||||
{
|
||||
|
||||
@@ -457,8 +457,7 @@ jerry_parse (const jerry_char_t *resource_name_p, /**< resource name (usually a
|
||||
ecma_free_value (parse_status);
|
||||
|
||||
ecma_object_t *lex_env_p = ecma_get_global_environment ();
|
||||
ecma_object_t *func_obj_p = ecma_op_create_function_object (lex_env_p,
|
||||
bytecode_data_p);
|
||||
ecma_object_t *func_obj_p = ecma_op_create_simple_function_object (lex_env_p, bytecode_data_p);
|
||||
ecma_bytecode_deref (bytecode_data_p);
|
||||
|
||||
return ecma_make_object_value (func_obj_p);
|
||||
@@ -539,8 +538,7 @@ jerry_parse_function (const jerry_char_t *resource_name_p, /**< resource name (u
|
||||
ecma_free_value (parse_status);
|
||||
|
||||
ecma_object_t *lex_env_p = ecma_get_global_environment ();
|
||||
ecma_object_t *func_obj_p = ecma_op_create_function_object (lex_env_p,
|
||||
bytecode_data_p);
|
||||
ecma_object_t *func_obj_p = ecma_op_create_simple_function_object (lex_env_p, bytecode_data_p);
|
||||
ecma_bytecode_deref (bytecode_data_p);
|
||||
|
||||
return ecma_make_object_value (func_obj_p);
|
||||
|
||||
@@ -108,6 +108,7 @@ typedef enum
|
||||
ECMA_PARSE_EVAL = (1u << 6), /**< eval is called */
|
||||
ECMA_PARSE_MODULE = (1u << 7), /**< module is parsed */
|
||||
ECMA_PARSE_FUNCTION = (1u << 8), /**< a function body is parsed or the code is inside a function */
|
||||
ECMA_PARSE_GENERATOR_FUNCTION = (1u << 9), /**< generator function is parsed */
|
||||
} ecma_parse_opts_t;
|
||||
|
||||
/**
|
||||
|
||||
@@ -57,6 +57,7 @@ ecma_init (void)
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
JERRY_CONTEXT (current_new_target) = JERRY_CONTEXT_INVALID_NEW_TARGET;
|
||||
JERRY_CONTEXT (current_function_obj_p) = NULL;
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
} /* ecma_init */
|
||||
|
||||
@@ -68,6 +69,7 @@ ecma_finalize (void)
|
||||
{
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
JERRY_ASSERT (JERRY_CONTEXT (current_new_target) == JERRY_CONTEXT_INVALID_NEW_TARGET);
|
||||
JERRY_ASSERT (JERRY_CONTEXT (current_function_obj_p) == NULL);
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
ecma_finalize_global_lex_env ();
|
||||
|
||||
@@ -59,58 +59,6 @@ ecma_builtin_function_dispatch_call (const ecma_value_t *arguments_list_p, /**<
|
||||
return ecma_builtin_function_dispatch_construct (arguments_list_p, arguments_list_len);
|
||||
} /* ecma_builtin_function_dispatch_call */
|
||||
|
||||
/**
|
||||
* Helper method to count and convert the arguments for the Function constructor call.
|
||||
*
|
||||
* Performs the operation described in ECMA 262 v5.1 15.3.2.1 steps 5.a-d
|
||||
*
|
||||
*
|
||||
* @return ecma value - concatenated arguments as a string.
|
||||
* Returned value must be freed with ecma_free_value.
|
||||
*/
|
||||
static ecma_value_t
|
||||
ecma_builtin_function_helper_get_function_arguments (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);
|
||||
|
||||
if (arguments_list_len <= 1)
|
||||
{
|
||||
return ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY);
|
||||
}
|
||||
|
||||
ecma_string_t *final_str_p = ecma_op_to_string (arguments_list_p[0]);
|
||||
|
||||
if (JERRY_UNLIKELY (final_str_p == NULL))
|
||||
{
|
||||
return ECMA_VALUE_ERROR;
|
||||
}
|
||||
|
||||
if (arguments_list_len == 2)
|
||||
{
|
||||
return ecma_make_string_value (final_str_p);
|
||||
}
|
||||
|
||||
for (ecma_length_t idx = 1; idx < arguments_list_len - 1; idx++)
|
||||
{
|
||||
ecma_string_t *new_str_p = ecma_op_to_string (arguments_list_p[idx]);
|
||||
|
||||
if (JERRY_UNLIKELY (new_str_p == NULL))
|
||||
{
|
||||
ecma_deref_ecma_string (final_str_p);
|
||||
return ECMA_VALUE_ERROR;
|
||||
}
|
||||
|
||||
final_str_p = ecma_append_magic_string_to_string (final_str_p,
|
||||
LIT_MAGIC_STRING_COMMA_CHAR);
|
||||
|
||||
final_str_p = ecma_concat_ecma_strings (final_str_p, new_str_p);
|
||||
ecma_deref_ecma_string (new_str_p);
|
||||
}
|
||||
|
||||
return ecma_make_string_value (final_str_p);
|
||||
} /* ecma_builtin_function_helper_get_function_arguments */
|
||||
|
||||
/**
|
||||
* Handle calling [[Construct]] of built-in Function object
|
||||
*
|
||||
@@ -123,70 +71,7 @@ ecma_value_t
|
||||
ecma_builtin_function_dispatch_construct (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);
|
||||
|
||||
ecma_value_t arguments_value = ecma_builtin_function_helper_get_function_arguments (arguments_list_p,
|
||||
arguments_list_len);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (arguments_value))
|
||||
{
|
||||
return arguments_value;
|
||||
}
|
||||
|
||||
ecma_string_t *function_body_str_p;
|
||||
|
||||
if (arguments_list_len > 0)
|
||||
{
|
||||
function_body_str_p = ecma_op_to_string (arguments_list_p[arguments_list_len - 1]);
|
||||
|
||||
if (JERRY_UNLIKELY (function_body_str_p == NULL))
|
||||
{
|
||||
ecma_free_value (arguments_value);
|
||||
return ECMA_VALUE_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Very unlikely code path, not optimized. */
|
||||
function_body_str_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
|
||||
}
|
||||
|
||||
ecma_string_t *arguments_str_p = ecma_get_string_from_value (arguments_value);
|
||||
|
||||
ECMA_STRING_TO_UTF8_STRING (arguments_str_p, arguments_buffer_p, arguments_buffer_size);
|
||||
ECMA_STRING_TO_UTF8_STRING (function_body_str_p, function_body_buffer_p, function_body_buffer_size);
|
||||
|
||||
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
|
||||
JERRY_CONTEXT (resource_name) = ecma_make_magic_string_value (LIT_MAGIC_STRING_RESOURCE_ANON);
|
||||
#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
|
||||
|
||||
ecma_compiled_code_t *bytecode_data_p = NULL;
|
||||
|
||||
ecma_value_t ret_value = parser_parse_script (arguments_buffer_p,
|
||||
arguments_buffer_size,
|
||||
function_body_buffer_p,
|
||||
function_body_buffer_size,
|
||||
ECMA_PARSE_NO_OPTS,
|
||||
&bytecode_data_p);
|
||||
|
||||
if (!ECMA_IS_VALUE_ERROR (ret_value))
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_true (ret_value));
|
||||
|
||||
ecma_object_t *func_obj_p = ecma_op_create_function_object (ecma_get_global_environment (),
|
||||
bytecode_data_p);
|
||||
|
||||
ecma_bytecode_deref (bytecode_data_p);
|
||||
ret_value = ecma_make_object_value (func_obj_p);
|
||||
}
|
||||
|
||||
ECMA_FINALIZE_UTF8_STRING (function_body_buffer_p, function_body_buffer_size);
|
||||
ECMA_FINALIZE_UTF8_STRING (arguments_buffer_p, arguments_buffer_size);
|
||||
|
||||
ecma_deref_ecma_string (arguments_str_p);
|
||||
ecma_deref_ecma_string (function_body_str_p);
|
||||
|
||||
return ret_value;
|
||||
return ecma_op_create_dynamic_function (arguments_list_p, arguments_list_len, ECMA_PARSE_NO_OPTS);
|
||||
} /* ecma_builtin_function_dispatch_construct */
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/* 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_ES2015)
|
||||
|
||||
#define ECMA_BUILTINS_INTERNAL
|
||||
#include "ecma-builtins-internal.h"
|
||||
#include "ecma-function-object.h"
|
||||
|
||||
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-generator-function.inc.h"
|
||||
#define BUILTIN_UNDERSCORED_ID generator_function
|
||||
#include "ecma-builtin-internal-routines-template.inc.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup ecmabuiltins
|
||||
* @{
|
||||
*
|
||||
* \addtogroup generator ECMA GeneratorFunction object built-in
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handle calling [[Call]] of built-in GeneratorFunction object
|
||||
*
|
||||
* @return constructed generator function object - if success
|
||||
* raised error otherwise
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_builtin_generator_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_GENERATOR_FUNCTION);
|
||||
} /* ecma_builtin_generator_function_dispatch_call */
|
||||
|
||||
/**
|
||||
* Handle calling [[Construct]] of built-in GeneratorFunction object
|
||||
*
|
||||
* @return constructed generator function object - if success
|
||||
* raised error otherwise
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_builtin_generator_function_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
|
||||
ecma_length_t arguments_list_len) /**< number of arguments */
|
||||
{
|
||||
return ecma_builtin_generator_function_dispatch_call (arguments_list_p, arguments_list_len);
|
||||
} /* ecma_builtin_generator_function_dispatch_construct */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* %GeneratorFunction% built-in description
|
||||
*/
|
||||
|
||||
#include "ecma-builtin-helpers-macro-defines.inc.h"
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
|
||||
/* ECMA-262 v6, 25.2.2 */
|
||||
STRING_VALUE (LIT_MAGIC_STRING_NAME,
|
||||
LIT_MAGIC_STRING_GENERATOR_FUNCTION_UL,
|
||||
ECMA_PROPERTY_FLAG_CONFIGURABLE)
|
||||
|
||||
/* ECMA-262 v6, 25.2.2 */
|
||||
NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
|
||||
1,
|
||||
ECMA_PROPERTY_FLAG_CONFIGURABLE)
|
||||
|
||||
/* ECMA-262 v6, 25.2.2.2 */
|
||||
OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
|
||||
ECMA_BUILTIN_ID_GENERATOR,
|
||||
ECMA_PROPERTY_FIXED)
|
||||
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
#include "ecma-builtin-helpers-macro-undefs.inc.h"
|
||||
@@ -38,7 +38,7 @@
|
||||
* \addtogroup ecmabuiltins
|
||||
* @{
|
||||
*
|
||||
* \addtogroup generator ECMA Generator object built-in
|
||||
* \addtogroup generator ECMA Generator.prototype object built-in
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
@@ -29,6 +29,11 @@ STRING_VALUE (LIT_GLOBAL_SYMBOL_TO_STRING_TAG,
|
||||
LIT_MAGIC_STRING_GENERATOR_UL,
|
||||
ECMA_PROPERTY_FLAG_CONFIGURABLE)
|
||||
|
||||
/* ECMA-262 v6, 25.2.3.1 */
|
||||
OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
|
||||
ECMA_BUILTIN_ID_GENERATOR,
|
||||
ECMA_PROPERTY_FLAG_CONFIGURABLE)
|
||||
|
||||
/* Routine properties:
|
||||
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
|
||||
ROUTINE (LIT_MAGIC_STRING_NEXT, ecma_builtin_generator_prototype_object_next, 1, 1)
|
||||
|
||||
@@ -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_ES2015)
|
||||
|
||||
#define ECMA_BUILTINS_INTERNAL
|
||||
#include "ecma-builtins-internal.h"
|
||||
|
||||
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-generator.inc.h"
|
||||
#define BUILTIN_UNDERSCORED_ID generator
|
||||
#include "ecma-builtin-internal-routines-template.inc.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
* @{
|
||||
*
|
||||
* \addtogroup ecmabuiltins
|
||||
* @{
|
||||
*
|
||||
* \addtogroup generator ECMA Generator object built-in
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* %Generator% built-in description (GeneratorFunction.prototype)
|
||||
*/
|
||||
|
||||
#include "ecma-builtin-helpers-macro-defines.inc.h"
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
|
||||
/* ECMA-262 v6, 25.3.2.3.1 */
|
||||
OBJECT_VALUE (LIT_MAGIC_STRING_CONSTRUCTOR,
|
||||
ECMA_BUILTIN_ID_GENERATOR_FUNCTION,
|
||||
ECMA_PROPERTY_FLAG_CONFIGURABLE)
|
||||
|
||||
/* ECMA-262 v6, 25.3.2.3.2 */
|
||||
OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
|
||||
ECMA_BUILTIN_ID_GENERATOR_PROTOTYPE,
|
||||
ECMA_PROPERTY_FLAG_CONFIGURABLE)
|
||||
|
||||
/* ECMA-262 v6, 25.3.2.3.3 */
|
||||
STRING_VALUE (LIT_GLOBAL_SYMBOL_TO_STRING_TAG,
|
||||
LIT_MAGIC_STRING_GENERATOR_FUNCTION_UL,
|
||||
ECMA_PROPERTY_FLAG_CONFIGURABLE)
|
||||
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
#include "ecma-builtin-helpers-macro-undefs.inc.h"
|
||||
@@ -552,6 +552,21 @@ BUILTIN (ECMA_BUILTIN_ID_STRING_ITERATOR_PROTOTYPE,
|
||||
true,
|
||||
string_iterator_prototype)
|
||||
|
||||
/* The %(GeneratorFunction)% object */
|
||||
BUILTIN_ROUTINE (ECMA_BUILTIN_ID_GENERATOR_FUNCTION,
|
||||
ECMA_OBJECT_TYPE_FUNCTION,
|
||||
ECMA_BUILTIN_ID_FUNCTION,
|
||||
true,
|
||||
generator_function)
|
||||
|
||||
/* The %(Generator)% object */
|
||||
BUILTIN (ECMA_BUILTIN_ID_GENERATOR,
|
||||
ECMA_OBJECT_TYPE_GENERAL,
|
||||
ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE,
|
||||
true,
|
||||
generator)
|
||||
|
||||
/* The %(Generator).prototype% object */
|
||||
BUILTIN (ECMA_BUILTIN_ID_GENERATOR_PROTOTYPE,
|
||||
ECMA_OBJECT_TYPE_GENERAL,
|
||||
ECMA_BUILTIN_ID_ITERATOR_PROTOTYPE,
|
||||
|
||||
@@ -15,11 +15,11 @@
|
||||
|
||||
#include "ecma-alloc.h"
|
||||
#include "ecma-builtin-helpers.h"
|
||||
#include "ecma-builtins.h"
|
||||
#include "ecma-exceptions.h"
|
||||
#include "ecma-function-object.h"
|
||||
#include "ecma-gc.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "lit-char-helpers.h"
|
||||
#include "ecma-lex-env.h"
|
||||
#include "ecma-objects.h"
|
||||
#include "ecma-objects-general.h"
|
||||
@@ -143,6 +143,152 @@ ecma_is_constructor (ecma_value_t value) /**< ecma value */
|
||||
&& ecma_object_is_constructor (ecma_get_object_from_value (value)));
|
||||
} /* ecma_is_constructor */
|
||||
|
||||
/**
|
||||
* Helper method to count and convert the arguments for the Function/GeneratorFunction constructor call.
|
||||
*
|
||||
* See also:
|
||||
* ECMA 262 v5.1 15.3.2.1 steps 5.a-d
|
||||
* ECMA 262 v6 19.2.1.1.1 steps 8
|
||||
*
|
||||
* @return ecma value - concatenated arguments as a string.
|
||||
* Returned value must be freed with ecma_free_value.
|
||||
*/
|
||||
static ecma_string_t *
|
||||
ecma_op_create_dynamic_function_arguments_helper (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);
|
||||
|
||||
if (arguments_list_len <= 1)
|
||||
{
|
||||
return ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
|
||||
}
|
||||
|
||||
ecma_string_t *str_p = ecma_op_to_string (arguments_list_p[0]);
|
||||
|
||||
if (JERRY_UNLIKELY (str_p == NULL))
|
||||
{
|
||||
return str_p;
|
||||
}
|
||||
|
||||
if (arguments_list_len == 2)
|
||||
{
|
||||
return str_p;
|
||||
}
|
||||
|
||||
ecma_stringbuilder_t builder = ecma_stringbuilder_create_from (str_p);
|
||||
ecma_deref_ecma_string (str_p);
|
||||
|
||||
for (ecma_length_t idx = 1; idx < arguments_list_len - 1; idx++)
|
||||
{
|
||||
str_p = ecma_op_to_string (arguments_list_p[idx]);
|
||||
|
||||
if (JERRY_UNLIKELY (str_p == NULL))
|
||||
{
|
||||
ecma_stringbuilder_destroy (&builder);
|
||||
return str_p;
|
||||
}
|
||||
|
||||
ecma_stringbuilder_append_char (&builder, LIT_CHAR_COMMA);
|
||||
ecma_stringbuilder_append (&builder, str_p);
|
||||
ecma_deref_ecma_string (str_p);
|
||||
}
|
||||
|
||||
return ecma_stringbuilder_finalize (&builder);
|
||||
} /* ecma_op_create_dynamic_function_arguments_helper */
|
||||
|
||||
/**
|
||||
* CreateDynamicFunction operation
|
||||
*
|
||||
* See also:
|
||||
* ECMA-262 v5, 15.3.
|
||||
* ECMA-262 v6, 19.2.1.1
|
||||
*
|
||||
* @return ECMA_VALUE_ERROR - if the operation fails
|
||||
* constructed function object - otherwise
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_op_create_dynamic_function (const ecma_value_t *arguments_list_p, /**< arguments list */
|
||||
ecma_length_t arguments_list_len, /**< number of arguments */
|
||||
ecma_parse_opts_t parse_opts) /**< parse options */
|
||||
{
|
||||
JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL);
|
||||
|
||||
ecma_string_t *arguments_str_p = ecma_op_create_dynamic_function_arguments_helper (arguments_list_p,
|
||||
arguments_list_len);
|
||||
|
||||
if (JERRY_UNLIKELY (arguments_str_p == NULL))
|
||||
{
|
||||
return ECMA_VALUE_ERROR;
|
||||
}
|
||||
|
||||
ecma_string_t *function_body_str_p;
|
||||
|
||||
if (arguments_list_len > 0)
|
||||
{
|
||||
function_body_str_p = ecma_op_to_string (arguments_list_p[arguments_list_len - 1]);
|
||||
|
||||
if (JERRY_UNLIKELY (function_body_str_p == NULL))
|
||||
{
|
||||
ecma_deref_ecma_string (arguments_str_p);
|
||||
return ECMA_VALUE_ERROR;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Very unlikely code path, not optimized. */
|
||||
function_body_str_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY);
|
||||
}
|
||||
|
||||
ECMA_STRING_TO_UTF8_STRING (arguments_str_p, arguments_buffer_p, arguments_buffer_size);
|
||||
ECMA_STRING_TO_UTF8_STRING (function_body_str_p, function_body_buffer_p, function_body_buffer_size);
|
||||
|
||||
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
|
||||
JERRY_CONTEXT (resource_name) = ecma_make_magic_string_value (LIT_MAGIC_STRING_RESOURCE_ANON);
|
||||
#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
|
||||
|
||||
ecma_compiled_code_t *bytecode_data_p = NULL;
|
||||
|
||||
ecma_value_t ret_value = parser_parse_script (arguments_buffer_p,
|
||||
arguments_buffer_size,
|
||||
function_body_buffer_p,
|
||||
function_body_buffer_size,
|
||||
parse_opts,
|
||||
&bytecode_data_p);
|
||||
|
||||
if (!ECMA_IS_VALUE_ERROR (ret_value))
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_true (ret_value));
|
||||
|
||||
ecma_object_t *func_obj_p;
|
||||
ecma_object_t *global_env_p = ecma_get_global_environment ();
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
if (parse_opts & ECMA_PARSE_GENERATOR_FUNCTION)
|
||||
{
|
||||
func_obj_p = ecma_op_create_generator_function_object (global_env_p, bytecode_data_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
func_obj_p = ecma_op_create_simple_function_object (global_env_p, bytecode_data_p);
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
ecma_bytecode_deref (bytecode_data_p);
|
||||
ret_value = ecma_make_object_value (func_obj_p);
|
||||
}
|
||||
|
||||
ECMA_FINALIZE_UTF8_STRING (function_body_buffer_p, function_body_buffer_size);
|
||||
ECMA_FINALIZE_UTF8_STRING (arguments_buffer_p, arguments_buffer_size);
|
||||
|
||||
ecma_deref_ecma_string (arguments_str_p);
|
||||
ecma_deref_ecma_string (function_body_str_p);
|
||||
|
||||
return ret_value;
|
||||
} /* ecma_op_create_dynamic_function */
|
||||
|
||||
/**
|
||||
* Function object creation operation.
|
||||
*
|
||||
@@ -150,14 +296,15 @@ ecma_is_constructor (ecma_value_t value) /**< ecma value */
|
||||
*
|
||||
* @return pointer to newly created Function object
|
||||
*/
|
||||
ecma_object_t *
|
||||
static ecma_object_t *
|
||||
ecma_op_create_function_object (ecma_object_t *scope_p, /**< function's scope */
|
||||
const ecma_compiled_code_t *bytecode_data_p) /**< byte-code array */
|
||||
const ecma_compiled_code_t *bytecode_data_p, /**< byte-code array */
|
||||
ecma_builtin_id_t proto_id) /**< builtin id of the prototype object */
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_lexical_environment (scope_p));
|
||||
|
||||
/* 1., 4., 13. */
|
||||
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
|
||||
ecma_object_t *prototype_obj_p = ecma_builtin_get (proto_id);
|
||||
|
||||
size_t function_object_size = sizeof (ecma_extended_object_t);
|
||||
|
||||
@@ -219,8 +366,36 @@ ecma_op_create_function_object (ecma_object_t *scope_p, /**< function's scope */
|
||||
return func_p;
|
||||
} /* ecma_op_create_function_object */
|
||||
|
||||
/**
|
||||
* Function object creation operation.
|
||||
*
|
||||
* See also: ECMA-262 v5, 13.2
|
||||
*
|
||||
* @return pointer to newly created Function object
|
||||
*/
|
||||
ecma_object_t *
|
||||
ecma_op_create_simple_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_FUNCTION_PROTOTYPE);
|
||||
} /* ecma_op_create_simple_function_object */
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
|
||||
/**
|
||||
* GeneratorFunction object creation operation.
|
||||
*
|
||||
* See also: ECMA-262 v5, 13.2
|
||||
*
|
||||
* @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 */
|
||||
{
|
||||
return ecma_op_create_function_object (scope_p, bytecode_data_p, ECMA_BUILTIN_ID_GENERATOR);
|
||||
} /* ecma_op_create_generator_function_object */
|
||||
|
||||
/**
|
||||
* Arrow function object creation operation.
|
||||
*
|
||||
@@ -722,6 +897,43 @@ ecma_op_set_class_prototype (ecma_value_t completion_value, /**< completion_valu
|
||||
|
||||
completion_obj_p->u2.prototype_cp = prototype_obj_cp;
|
||||
} /* ecma_op_set_class_prototype */
|
||||
|
||||
/**
|
||||
* Ordinary internal method: GetPrototypeFromConstructor (constructor, intrinsicDefaultProto)
|
||||
*
|
||||
* See also: ECMAScript v6, 9.1.15
|
||||
*
|
||||
* @return NULL - if the operation fail (exception on the global context is raised)
|
||||
* pointer to the prototype object - otherwise
|
||||
*/
|
||||
ecma_object_t *
|
||||
ecma_op_get_prototype_from_constructor (ecma_object_t *ctor_obj_p, /**< constructor to get prototype from */
|
||||
ecma_builtin_id_t default_proto_id) /**< intrinsicDefaultProto */
|
||||
{
|
||||
JERRY_ASSERT (ecma_object_is_constructor (ctor_obj_p));
|
||||
JERRY_ASSERT (default_proto_id < ECMA_BUILTIN_ID__COUNT);
|
||||
|
||||
ecma_value_t proto = ecma_op_object_get_by_magic_id (ctor_obj_p, LIT_MAGIC_STRING_PROTOTYPE);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (proto))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ecma_object_t *proto_obj_p;
|
||||
|
||||
if (!ecma_is_value_object (proto))
|
||||
{
|
||||
proto_obj_p = ecma_builtin_get (default_proto_id);
|
||||
ecma_ref_object (proto_obj_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
proto_obj_p = ecma_get_object_from_value (proto);
|
||||
}
|
||||
|
||||
return proto_obj_p;
|
||||
} /* ecma_op_get_prototype_from_constructor */
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
/**
|
||||
@@ -776,10 +988,16 @@ ecma_op_function_call_simple (ecma_object_t *func_obj_p, /**< Function object */
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Class constructor cannot be invoked without 'new'."));
|
||||
}
|
||||
if (is_construct_call && (status_flags & CBC_CODE_FLAGS_GENERATOR))
|
||||
|
||||
if (status_flags & CBC_CODE_FLAGS_GENERATOR)
|
||||
{
|
||||
if (is_construct_call)
|
||||
{
|
||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Generator functions cannot be invoked with 'new'."));
|
||||
}
|
||||
|
||||
JERRY_CONTEXT (current_function_obj_p) = func_obj_p;
|
||||
}
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
@@ -835,6 +1053,13 @@ ecma_op_function_call_simple (ecma_object_t *func_obj_p, /**< Function object */
|
||||
arguments_list_p,
|
||||
arguments_list_len);
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
if (JERRY_UNLIKELY (status_flags & CBC_CODE_FLAGS_GENERATOR))
|
||||
{
|
||||
JERRY_CONTEXT (current_function_obj_p) = NULL;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
if (!(status_flags & CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED))
|
||||
{
|
||||
ecma_deref_object (local_env_p);
|
||||
@@ -1324,10 +1549,33 @@ ecma_op_lazy_instantiate_prototype_object (ecma_object_t *object_p) /**< the fun
|
||||
|| ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
|
||||
|
||||
/* ECMA-262 v5, 13.2, 16-18 */
|
||||
/* 16. */
|
||||
ecma_object_t *proto_object_p = ecma_op_create_object_object_noarg ();
|
||||
|
||||
ecma_object_t *proto_object_p = NULL;
|
||||
bool init_constructor = true;
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_FUNCTION)
|
||||
{
|
||||
const ecma_compiled_code_t *byte_code_p = ecma_op_function_get_compiled_code ((ecma_extended_object_t *) object_p);
|
||||
|
||||
if (byte_code_p->status_flags & CBC_CODE_FLAGS_GENERATOR)
|
||||
{
|
||||
proto_object_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_GENERATOR_PROTOTYPE),
|
||||
0,
|
||||
ECMA_OBJECT_TYPE_GENERAL);
|
||||
init_constructor = false;
|
||||
}
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
if (proto_object_p == NULL)
|
||||
{
|
||||
proto_object_p = ecma_op_create_object_object_noarg ();
|
||||
}
|
||||
|
||||
/* 17. */
|
||||
if (init_constructor)
|
||||
{
|
||||
ecma_property_value_t *constructor_prop_value_p;
|
||||
constructor_prop_value_p = ecma_create_named_data_property (proto_object_p,
|
||||
ecma_get_magic_string (LIT_MAGIC_STRING_CONSTRUCTOR),
|
||||
@@ -1335,6 +1583,7 @@ ecma_op_lazy_instantiate_prototype_object (ecma_object_t *object_p) /**< the fun
|
||||
NULL);
|
||||
|
||||
constructor_prop_value_p->value = ecma_make_object_value (object_p);
|
||||
}
|
||||
|
||||
/* 18. */
|
||||
ecma_property_t *prototype_prop_p;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#define ECMA_FUNCTION_OBJECT_H
|
||||
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-builtins.h"
|
||||
#include "vm.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
@@ -38,8 +39,7 @@ bool ecma_is_constructor (ecma_value_t value);
|
||||
bool ecma_object_is_constructor (ecma_object_t *obj_p);
|
||||
|
||||
ecma_object_t *
|
||||
ecma_op_create_function_object (ecma_object_t *scope_p, const ecma_compiled_code_t *bytecode_data_p);
|
||||
|
||||
ecma_op_create_simple_function_object (ecma_object_t *scope_p, const ecma_compiled_code_t *bytecode_data_p);
|
||||
|
||||
ecma_object_t *
|
||||
ecma_op_create_external_function_object (ecma_external_handler_t handler_cb);
|
||||
@@ -47,6 +47,11 @@ ecma_op_create_external_function_object (ecma_external_handler_t handler_cb);
|
||||
const ecma_compiled_code_t *
|
||||
ecma_op_function_get_compiled_code (ecma_extended_object_t *function_p);
|
||||
|
||||
ecma_value_t
|
||||
ecma_op_create_dynamic_function (const ecma_value_t *arguments_list_p,
|
||||
ecma_length_t arguments_list_len,
|
||||
ecma_parse_opts_t opts);
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
void
|
||||
ecma_op_set_super_called (ecma_object_t *lex_env_p);
|
||||
@@ -69,6 +74,12 @@ ecma_op_function_implicit_constructor_handler_cb (const ecma_value_t function_ob
|
||||
void
|
||||
ecma_op_set_class_prototype (ecma_value_t completion_value, ecma_value_t this_arg);
|
||||
|
||||
ecma_object_t *
|
||||
ecma_op_get_prototype_from_constructor (ecma_object_t *ctor_obj_p, ecma_builtin_id_t default_proto_id);
|
||||
|
||||
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_arrow_function_object (ecma_object_t *scope_p, const ecma_compiled_code_t *bytecode_data_p,
|
||||
ecma_value_t this_binding);
|
||||
|
||||
@@ -2471,6 +2471,12 @@ ecma_object_get_class_name (ecma_object_t *obj_p) /**< object */
|
||||
return LIT_MAGIC_STRING_REFLECT_UL;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015_BUILTIN_REFLECT) */
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
case ECMA_BUILTIN_ID_GENERATOR:
|
||||
{
|
||||
return LIT_MAGIC_STRING_GENERATOR_UL;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
#if ENABLED (JERRY_BUILTIN_JSON)
|
||||
case ECMA_BUILTIN_ID_JSON:
|
||||
{
|
||||
|
||||
@@ -229,6 +229,8 @@ struct jerry_context_t
|
||||
* * Any other valid function object pointer: the current "new.target" is valid and it is constructor call.
|
||||
*/
|
||||
ecma_object_t *current_new_target;
|
||||
ecma_object_t *current_function_obj_p; /** currently invoked function object
|
||||
(Note: currently used only in generator functions) */
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
};
|
||||
|
||||
|
||||
@@ -25,7 +25,10 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_RIGHT_PAREN, ")")
|
||||
#if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_ASTERIX_CHAR, "*")
|
||||
#endif
|
||||
#if ENABLED (JERRY_BUILTIN_ARRAY) \
|
||||
|| ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_COMMA_CHAR, ",")
|
||||
#endif
|
||||
#if ENABLED (JERRY_LINE_INFO)
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_COLON_CHAR, ":")
|
||||
#endif
|
||||
@@ -772,6 +775,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_DEFINE_PROPERTIES_UL, "defineProperties")
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_BYTES_PER_ELEMENT_U, "BYTES_PER_ELEMENT")
|
||||
#endif
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_GENERATOR_FUNCTION_UL, "GeneratorFunction")
|
||||
#endif
|
||||
#if ENABLED (JERRY_BUILTIN_NUMBER)
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_NEGATIVE_INFINITY_U, "NEGATIVE_INFINITY")
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_POSITIVE_INFINITY_U, "POSITIVE_INFINITY")
|
||||
@@ -916,6 +922,8 @@ LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (16, LIT_MAGIC_STRING_DEFINE_PROPERTIES_
|
||||
#endif
|
||||
#if ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
|
||||
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (17, LIT_MAGIC_STRING_BYTES_PER_ELEMENT_U)
|
||||
#elif ENABLED (JERRY_ES2015)
|
||||
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (17, LIT_MAGIC_STRING_GENERATOR_FUNCTION_UL)
|
||||
#elif ENABLED (JERRY_BUILTIN_NUMBER)
|
||||
LIT_MAGIC_STRING_FIRST_STRING_WITH_SIZE (17, LIT_MAGIC_STRING_NEGATIVE_INFINITY_U)
|
||||
#elif ENABLED (JERRY_ES2015_BUILTIN_TYPEDARRAY)
|
||||
|
||||
@@ -325,6 +325,7 @@ LIT_MAGIC_STRING_MIN_SAFE_INTEGER_U = "MIN_SAFE_INTEGER"
|
||||
LIT_MAGIC_STRING_BYTES_PER_ELEMENT_U = "BYTES_PER_ELEMENT"
|
||||
LIT_MAGIC_STRING_NEGATIVE_INFINITY_U = "NEGATIVE_INFINITY"
|
||||
LIT_MAGIC_STRING_POSITIVE_INFINITY_U = "POSITIVE_INFINITY"
|
||||
LIT_MAGIC_STRING_GENERATOR_FUNCTION_UL = "GeneratorFunction"
|
||||
LIT_MAGIC_STRING_UINT8_CLAMPED_ARRAY_UL = "Uint8ClampedArray"
|
||||
LIT_MAGIC_STRING_GET_TIMEZONE_OFFSET_UL = "getTimezoneOffset"
|
||||
LIT_MAGIC_STRING_PREVENT_EXTENSIONS_UL = "preventExtensions"
|
||||
|
||||
@@ -1915,7 +1915,20 @@ parser_parse_source (const uint8_t *arg_list_p, /**< function argument list */
|
||||
error_location_p->error = PARSER_ERR_NO_ERROR;
|
||||
}
|
||||
|
||||
context.status_flags = (arg_list_p == NULL) ? 0 : PARSER_IS_FUNCTION;
|
||||
if (arg_list_p == NULL)
|
||||
{
|
||||
context.status_flags = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
context.status_flags = PARSER_IS_FUNCTION;
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
if (parse_opts & ECMA_PARSE_GENERATOR_FUNCTION)
|
||||
{
|
||||
context.status_flags |= PARSER_IS_GENERATOR_FUNCTION;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
}
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
context.status_flags |= PARSER_GET_CLASS_PARSER_OPTS (parse_opts);
|
||||
|
||||
@@ -3071,7 +3071,6 @@ scan_completed:
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
JERRY_ASSERT (scanner_context.active_binding_list_p == NULL);
|
||||
JERRY_ASSERT (!(context_p->status_flags & PARSER_IS_GENERATOR_FUNCTION));
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
JERRY_ASSERT (scanner_context.active_literal_pool_p == NULL);
|
||||
|
||||
|
||||
@@ -571,10 +571,15 @@ opfunc_create_executable_object (vm_frame_ctx_t *frame_ctx_p) /**< frame context
|
||||
|
||||
size_t total_size = JERRY_ALIGNUP (sizeof (vm_executable_object_t) + size, sizeof (uintptr_t));
|
||||
|
||||
ecma_object_t *object_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_GENERATOR_PROTOTYPE),
|
||||
ecma_object_t *proto_p = ecma_op_get_prototype_from_constructor (JERRY_CONTEXT (current_function_obj_p),
|
||||
ECMA_BUILTIN_ID_GENERATOR_PROTOTYPE);
|
||||
|
||||
ecma_object_t *object_p = ecma_create_object (proto_p,
|
||||
total_size,
|
||||
ECMA_OBJECT_TYPE_CLASS);
|
||||
|
||||
ecma_deref_object (proto_p);
|
||||
|
||||
vm_executable_object_t *executable_object_p = (vm_executable_object_t *) object_p;
|
||||
|
||||
executable_object_p->extended_object.u.class_prop.class_id = LIT_MAGIC_STRING_GENERATOR_UL;
|
||||
|
||||
+19
-9
@@ -414,19 +414,22 @@ vm_construct_literal_object (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
|
||||
ecma_object_t *func_obj_p;
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
if (!(bytecode_p->status_flags & CBC_CODE_FLAGS_ARROW_FUNCTION))
|
||||
{
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
func_obj_p = ecma_op_create_function_object (frame_ctx_p->lex_env_p,
|
||||
bytecode_p);
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
}
|
||||
else
|
||||
if (bytecode_p->status_flags & CBC_CODE_FLAGS_ARROW_FUNCTION)
|
||||
{
|
||||
func_obj_p = ecma_op_create_arrow_function_object (frame_ctx_p->lex_env_p,
|
||||
bytecode_p,
|
||||
frame_ctx_p->this_binding);
|
||||
}
|
||||
else if (bytecode_p->status_flags & CBC_CODE_FLAGS_GENERATOR)
|
||||
{
|
||||
func_obj_p = ecma_op_create_generator_function_object (frame_ctx_p->lex_env_p, bytecode_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
func_obj_p = ecma_op_create_simple_function_object (frame_ctx_p->lex_env_p, bytecode_p);
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
return ecma_make_object_value (func_obj_p);
|
||||
@@ -2077,7 +2080,14 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
frame_ctx_p->call_operation = VM_EXEC_RETURN;
|
||||
frame_ctx_p->byte_code_p = byte_code_p;
|
||||
frame_ctx_p->stack_top_p = stack_top_p;
|
||||
return opfunc_create_executable_object (frame_ctx_p);
|
||||
result = opfunc_create_executable_object (frame_ctx_p);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (result))
|
||||
{
|
||||
goto error;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
case VM_OC_YIELD:
|
||||
{
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
// 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.
|
||||
|
||||
|
||||
// Test %GeneratorPrototype%
|
||||
(function () {
|
||||
function* generatorFn(){}
|
||||
var ownProto = Object.getPrototypeOf(generatorFn());
|
||||
var sharedProto = Object.getPrototypeOf(ownProto);
|
||||
|
||||
assert(ownProto === generatorFn.prototype);
|
||||
assert(sharedProto !== Object.prototype);
|
||||
assert(sharedProto === Object.getPrototypeOf(function*(){}.prototype));
|
||||
assert(sharedProto.hasOwnProperty('next'));
|
||||
})();
|
||||
|
||||
// Test %GeneratorPrototype% prototype chain
|
||||
(function () {
|
||||
function* generatorFn(){}
|
||||
var g = generatorFn();
|
||||
var ownProto = Object.getPrototypeOf(g);
|
||||
var sharedProto = Object.getPrototypeOf(ownProto);
|
||||
var iterProto = Object.getPrototypeOf(sharedProto);
|
||||
|
||||
assert(ownProto === generatorFn.prototype);
|
||||
assert(iterProto.hasOwnProperty(Symbol.iterator));
|
||||
assert(!sharedProto.hasOwnProperty(Symbol.iterator));
|
||||
assert(!ownProto.hasOwnProperty(Symbol.iterator));
|
||||
assert(g[Symbol.iterator]() === g);
|
||||
})();
|
||||
|
||||
// Test %GeneratorPrototype% prototype chain
|
||||
(function () {
|
||||
function* g(){}
|
||||
var iterator = new g.constructor("a","b","c","yield a; yield b; yield c;")(1,2,3);
|
||||
|
||||
var item = iterator.next();
|
||||
assert(item.value === 1);
|
||||
assert(item.done === false);
|
||||
|
||||
item = iterator.next();
|
||||
assert(item.value === 2);
|
||||
assert(item.done === false);
|
||||
|
||||
item = iterator.next();
|
||||
assert(item.value === 3);
|
||||
assert(item.done === false);
|
||||
|
||||
item = iterator.next();
|
||||
assert(item.value === undefined);
|
||||
assert(item.done === true);
|
||||
|
||||
assert(g.constructor === (function*(){}).constructor);
|
||||
})();
|
||||
|
||||
// Test GeneratorFunction parsing
|
||||
(function () {
|
||||
function *f() {};
|
||||
|
||||
try {
|
||||
Object.getPrototypeOf(f).constructor("yield", "");
|
||||
} catch (e) {
|
||||
assert(e instanceof SyntaxError);
|
||||
}
|
||||
})();
|
||||
|
||||
// Test correct property membership
|
||||
(function () {
|
||||
function *f() {};
|
||||
|
||||
Object.getPrototypeOf(f).xx = 5;
|
||||
assert(Object.getPrototypeOf(f).prototype.constructor.xx === 5);
|
||||
})();
|
||||
|
||||
// Test GetPrototypeFromConstructor
|
||||
(function () {
|
||||
function *f() {};
|
||||
|
||||
var originalProto = f.prototype;
|
||||
f.prototype = 5;
|
||||
assert(Object.getPrototypeOf(f()) === Object.getPrototypeOf(originalProto));
|
||||
var fakeProto = { x : 6 };
|
||||
f.prototype = fakeProto;
|
||||
assert(Object.getPrototypeOf(f()) === fakeProto);
|
||||
assert(f.next === undefined);
|
||||
})();
|
||||
@@ -29,6 +29,10 @@ catch (e)
|
||||
assert (e instanceof ReferenceError);
|
||||
}
|
||||
|
||||
var singleArgFunction = new Function ('arg', 'return arg');
|
||||
|
||||
assert (singleArgFunction (5) === 5);
|
||||
|
||||
for (i = 1; i < 10; i ++)
|
||||
{
|
||||
var f = new Function ('a', 'b', 'var q = a; b++; function f (k) {return q + k + b++;}; return f;');
|
||||
|
||||
Reference in New Issue
Block a user