Create namespace with references for modules (#4646)

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg 2021-04-12 15:58:56 +02:00 committed by GitHub
parent ef35c0329c
commit b3ec217b50
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 1378 additions and 479 deletions

View File

@ -861,9 +861,10 @@ jerry_module_get_namespace (const jerry_value_t module_val) /**< module */
if (module_p->namespace_object_p == NULL)
{
if (module_p->header.u.cls.u1.module_state != JERRY_MODULE_STATE_EVALUATED)
if (module_p->header.u.cls.u1.module_state < JERRY_MODULE_STATE_LINKED
|| module_p->header.u.cls.u1.module_state > JERRY_MODULE_STATE_EVALUATED)
{
return jerry_throw (ecma_raise_range_error (ECMA_ERR_MSG ("Namespace object has not been created yet")));
return jerry_throw (ecma_raise_range_error (ECMA_ERR_MSG ("Namespace object cannot be created")));
}
ecma_module_create_namespace_object (module_p);
@ -1264,6 +1265,9 @@ static const uint8_t jerry_class_object_type[] =
#if JERRY_BUILTIN_TYPEDARRAY
JERRY_OBJECT_TYPE_TYPEDARRAY, /**< type of ECMA_OBJECT_CLASS_TYPEDARRAY */
#endif /* JERRY_BUILTIN_TYPEDARRAY */
#if JERRY_MODULE_SYSTEM
JERRY_OBJECT_TYPE_GENERIC, /**< type of ECMA_OBJECT_CLASS_MODULE_NAMESPACE */
#endif
/* These objects are marked by Garbage Collector. */
#if JERRY_ESNEXT
@ -5130,9 +5134,7 @@ jerry_realm_set_this (jerry_value_t realm_value, /**< realm value */
ecma_global_object_t *global_object_p = (ecma_global_object_t *) object_p;
global_object_p->this_binding = this_value;
ecma_object_t *global_lex_env_p = ecma_create_object_lex_env (NULL,
ecma_get_object_from_value (this_value),
ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
ecma_object_t *global_lex_env_p = ecma_create_object_lex_env (NULL, ecma_get_object_from_value (this_value));
ECMA_SET_NON_NULL_POINTER (global_object_p->global_env_cp, global_lex_env_p);
#if JERRY_ESNEXT

View File

@ -138,12 +138,22 @@ const char * const ecma_error_local_variable_is_redeclared = "Local variable is
*/
const char * const ecma_error_expected_a_function = "Expected a function";
#if JERRY_ESNEXT
/**
* Error message, class constructor invoked without new keyword
*/
const char * const ecma_error_class_constructor_new = "Class constructor cannot be invoked without 'new'";
#endif /* JERRY_ERROR_MESSAGES */
/**
* Error message, variables declared by let/const must be initialized before reading their value
*/
const char * const ecma_error_let_const_not_initialized = ("Variables declared by let/const must be"
" initialized before reading their value");
#endif /* JERRY_ESNEXT */
#endif /* JERRY_ERROR_MESSAGES */
#if JERRY_SNAPSHOT_SAVE || JERRY_SNAPSHOT_EXEC

View File

@ -18,6 +18,8 @@
#ifndef ECMA_ERRORS_H
#define ECMA_ERRORS_H
#if JERRY_ERROR_MESSAGES
extern const char * const ecma_error_value_msg_p;
extern const char * const ecma_error_wrong_args_msg_p;
@ -65,7 +67,13 @@ extern const char * const ecma_error_argument_is_not_an_regexp;
extern const char * const ecma_error_invalid_array_length;
extern const char * const ecma_error_local_variable_is_redeclared;
extern const char * const ecma_error_expected_a_function;
#if JERRY_ESNEXT
extern const char * const ecma_error_class_constructor_new;
extern const char * const ecma_error_let_const_not_initialized;
#endif /* JERRY_ESNEXT */
#endif /* JERRY_ERROR_MESSAGES */
/* snapshot errors */
extern const char * const ecma_error_maximum_snapshot_size;

View File

@ -293,6 +293,55 @@ ecma_gc_mark_properties (ecma_property_pair_t *property_pair_p) /**< property pa
}
} /* ecma_gc_mark_properties */
#if JERRY_MODULE_SYSTEM
/**
* Mark objects with references (e.g. namespace objects)
*/
static void
ecma_gc_mark_properties_with_references (ecma_object_t *object_p) /**< object */
{
jmem_cpointer_t prop_iter_cp = object_p->u1.property_list_cp;
#if JERRY_PROPRETY_HASHMAP
if (prop_iter_cp != JMEM_CP_NULL)
{
ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t,
prop_iter_cp);
if (prop_iter_p->types[0] == ECMA_PROPERTY_TYPE_HASHMAP)
{
prop_iter_cp = object_p->u1.property_list_cp;
}
}
#endif /* JERRY_PROPRETY_HASHMAP */
while (prop_iter_cp != JMEM_CP_NULL)
{
ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp);
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
{
ecma_property_t *property_p = (ecma_property_t *) (prop_iter_p->types + i);
if (ECMA_PROPERTY_IS_RAW (*property_p)
&& (*property_p & ECMA_PROPERTY_FLAG_DATA))
{
ecma_value_t value = ((ecma_property_pair_t *) prop_iter_p)->values[i].value;
if (ecma_is_value_object (value))
{
ecma_gc_set_object_visited (ecma_get_object_from_value (value));
}
}
}
prop_iter_cp = prop_iter_p->next_property_cp;
}
} /* ecma_gc_mark_properties_with_references */
#endif /* JERRY_MODULE_SYSTEM */
/**
* Mark objects referenced by bound function object.
*/
@ -659,11 +708,32 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
ecma_gc_set_object_visited (ECMA_GET_NON_NULL_POINTER (ecma_object_t, outer_lex_env_cp));
}
if (ecma_get_lex_env_type (object_p) != ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
switch (ecma_get_lex_env_type (object_p))
{
ecma_object_t *binding_object_p = ecma_get_lex_env_binding_object (object_p);
ecma_gc_set_object_visited (binding_object_p);
return;
#if JERRY_ESNEXT
case ECMA_LEXICAL_ENVIRONMENT_CLASS:
{
#if JERRY_MODULE_SYSTEM
if (object_p->type_flags_refs & ECMA_OBJECT_FLAG_LEXICAL_ENV_HAS_DATA)
{
ecma_gc_mark_properties_with_references (object_p);
ecma_gc_set_object_visited (((ecma_lexical_environment_class_t *) object_p)->module_p);
return;
}
#endif /* JERRY_MODULE_SYSTEM */
/* FALLTHRU */
}
#endif /* JERRY_ESNEXT */
case ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND:
{
ecma_object_t *binding_object_p = ecma_get_lex_env_binding_object (object_p);
ecma_gc_set_object_visited (binding_object_p);
return;
}
default:
{
break;
}
}
}
else
@ -733,10 +803,32 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
break;
}
#endif /* JERRY_BUILTIN_TYPEDARRAY */
#if JERRY_MODULE_SYSTEM
case ECMA_OBJECT_CLASS_MODULE_NAMESPACE:
{
JERRY_ASSERT (proto_cp == JMEM_CP_NULL);
ecma_gc_set_object_visited (ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
ext_object_p->u.cls.u3.value));
ecma_gc_mark_properties_with_references (object_p);
return;
}
#endif /* JERRY_MODULE_SYSTEM */
#if JERRY_MODULE_SYSTEM
case ECMA_OBJECT_CLASS_MODULE:
{
ecma_module_node_t *node_p = ((ecma_module_t *) ext_object_p)->imports_p;
ecma_module_t *module_p = ((ecma_module_t *) ext_object_p);
if (module_p->scope_p != NULL)
{
ecma_gc_set_object_visited (((ecma_module_t *) ext_object_p)->scope_p);
}
if (module_p->namespace_object_p != NULL)
{
ecma_gc_set_object_visited (((ecma_module_t *) ext_object_p)->namespace_object_p);
}
ecma_module_node_t *node_p = module_p->imports_p;
while (node_p != NULL)
{
@ -1083,21 +1175,16 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
* Free the native handle/pointer by calling its free callback.
*/
static void
ecma_gc_free_native_pointer (ecma_property_t *property_p) /**< property */
ecma_gc_free_native_pointer (ecma_value_t value) /**< property value */
{
JERRY_ASSERT (property_p != NULL);
ecma_property_value_t *value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
if (value_p->value == JMEM_CP_NULL)
if (value == JMEM_CP_NULL)
{
return;
}
ecma_native_pointer_t *native_pointer_p;
native_pointer_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_native_pointer_t,
value_p->value);
native_pointer_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_native_pointer_t, value);
JERRY_ASSERT (native_pointer_p != NULL);
do
@ -1317,11 +1404,132 @@ ecma_gc_free_executable_object (ecma_object_t *object_p) /**< object */
#endif /* JERRY_ESNEXT */
JERRY_STATIC_ASSERT (!ECMA_PROPERTY_IS_RAW (ECMA_PROPERTY_TYPE_DELETED),
ecma_property_type_deleted_must_not_be_raw_property);
JERRY_STATIC_ASSERT ((ECMA_PROPERTY_TYPE_DELETED & ECMA_PROPERTY_FLAG_LCACHED) == 0,
ecma_property_type_deleted_must_not_have_lcached_flag);
JERRY_STATIC_ASSERT (ECMA_GC_FREE_SECOND_PROPERTY == 1,
ecma_gc_free_second_must_be_one);
/**
* Free property of an object
*/
void
ecma_gc_free_property (ecma_object_t *object_p, /**< object */
ecma_property_pair_t *prop_pair_p, /**< property pair */
uint32_t options) /**< option bits including property index */
{
/* Both cannot be deleted. */
JERRY_ASSERT (prop_pair_p->header.types[0] != ECMA_PROPERTY_TYPE_DELETED
|| prop_pair_p->header.types[1] != ECMA_PROPERTY_TYPE_DELETED);
JERRY_ASSERT (prop_pair_p->header.types[0] != ECMA_PROPERTY_TYPE_HASHMAP);
uint32_t index = (options & ECMA_GC_FREE_SECOND_PROPERTY);
jmem_cpointer_t name_cp = prop_pair_p->names_cp[index];
ecma_property_t *property_p = prop_pair_p->header.types + index;
ecma_property_t property = *property_p;
#if JERRY_LCACHE
if ((property & ECMA_PROPERTY_FLAG_LCACHED) != 0)
{
ecma_lcache_invalidate (object_p, name_cp, property_p);
}
#endif /* JERRY_LCACHE */
if (ECMA_PROPERTY_IS_RAW (property))
{
if (ECMA_PROPERTY_GET_NAME_TYPE (property) == ECMA_DIRECT_STRING_PTR)
{
ecma_string_t *prop_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, name_cp);
ecma_deref_ecma_string (prop_name_p);
}
if (property & ECMA_PROPERTY_FLAG_DATA)
{
ecma_free_value_if_not_object (prop_pair_p->values[index].value);
return;
}
if (JERRY_UNLIKELY (options & ECMA_GC_FREE_REFERENCES))
{
return;
}
#if JERRY_CPOINTER_32_BIT
ecma_getter_setter_pointers_t *getter_setter_pair_p;
getter_setter_pair_p = ECMA_GET_NON_NULL_POINTER (ecma_getter_setter_pointers_t,
prop_pair_p->values[index].getter_setter_pair_cp);
jmem_pools_free (getter_setter_pair_p, sizeof (ecma_getter_setter_pointers_t));
#endif /* JERRY_CPOINTER_32_BIT */
return;
}
if (property == ECMA_PROPERTY_TYPE_DELETED)
{
return;
}
ecma_value_t value = prop_pair_p->values[index].value;
switch (name_cp)
{
#if JERRY_ESNEXT
case LIT_INTERNAL_MAGIC_STRING_ENVIRONMENT_RECORD:
{
ecma_environment_record_t *environment_record_p;
environment_record_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_environment_record_t, value);
jmem_heap_free_block (environment_record_p, sizeof (ecma_environment_record_t));
break;
}
case LIT_INTERNAL_MAGIC_STRING_CLASS_FIELD_COMPUTED:
{
ecma_value_t *compact_collection_p;
compact_collection_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_value_t, value);
ecma_compact_collection_free (compact_collection_p);
break;
}
#endif /* JERRY_ESNEXT */
#if JERRY_BUILTIN_WEAKMAP || JERRY_BUILTIN_WEAKSET || JERRY_BUILTIN_WEAKREF
case LIT_INTERNAL_MAGIC_STRING_WEAK_REFS:
{
ecma_collection_t *refs_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, value);
for (uint32_t j = 0; j < refs_p->item_count; j++)
{
const ecma_value_t reference_value = refs_p->buffer_p[j];
if (!ecma_is_value_empty (reference_value))
{
ecma_object_t *obj_p = ecma_get_object_from_value (reference_value);
if (ecma_object_class_is (obj_p, ECMA_OBJECT_CLASS_WEAKREF))
{
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p;
ext_obj_p->u.cls.u3.target = ECMA_VALUE_UNDEFINED;
continue;
}
ecma_op_container_remove_weak_entry (obj_p, ecma_make_object_value (object_p));
}
}
ecma_collection_destroy (refs_p);
break;
}
#endif /* JERRY_BUILTIN_WEAKMAP || JERRY_BUILTIN_WEAKSET || JERRY_BUILTIN_WEAKREF */
default:
{
JERRY_ASSERT (name_cp == LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER);
ecma_gc_free_native_pointer (value);
break;
}
}
} /* ecma_gc_free_property */
/**
* Free properties of an object
*/
void
ecma_gc_free_properties (ecma_object_t *object_p) /**< object */
ecma_gc_free_properties (ecma_object_t *object_p, /**< object */
uint32_t options) /**< option bits */
{
jmem_cpointer_t prop_iter_cp = object_p->u1.property_list_cp;
@ -1343,89 +1551,11 @@ ecma_gc_free_properties (ecma_object_t *object_p) /**< object */
ecma_property_header_t *prop_iter_p = ECMA_GET_NON_NULL_POINTER (ecma_property_header_t, prop_iter_cp);
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (prop_iter_p));
/* Both cannot be deleted. */
JERRY_ASSERT (prop_iter_p->types[0] != ECMA_PROPERTY_TYPE_DELETED
|| prop_iter_p->types[1] != ECMA_PROPERTY_TYPE_DELETED);
ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) prop_iter_p;
for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
for (uint32_t i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
{
ecma_property_t *property_p = (ecma_property_t *) (prop_iter_p->types + i);
jmem_cpointer_t name_cp = prop_pair_p->names_cp[i];
if (*property_p == ECMA_PROPERTY_TYPE_DELETED)
{
continue;
}
if (!ECMA_PROPERTY_IS_INTERNAL (*property_p))
{
ecma_free_property (object_p, name_cp, property_p);
continue;
}
/* Call the native's free callback. */
switch (name_cp)
{
#if JERRY_ESNEXT
case LIT_INTERNAL_MAGIC_STRING_ENVIRONMENT_RECORD:
{
ecma_environment_record_t *environment_record_p;
environment_record_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_environment_record_t,
prop_pair_p->values[i].value);
jmem_heap_free_block (environment_record_p, sizeof (ecma_environment_record_t));
break;
}
case LIT_INTERNAL_MAGIC_STRING_CLASS_FIELD_COMPUTED:
{
ecma_value_t *compact_collection_p;
compact_collection_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_value_t,
prop_pair_p->values[i].value);
ecma_compact_collection_free (compact_collection_p);
break;
}
#endif /* JERRY_ESNEXT */
#if JERRY_BUILTIN_WEAKMAP || JERRY_BUILTIN_WEAKSET || JERRY_BUILTIN_WEAKREF
case LIT_INTERNAL_MAGIC_STRING_WEAK_REFS:
{
ecma_collection_t *refs_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t,
prop_pair_p->values[i].value);
for (uint32_t j = 0; j < refs_p->item_count; j++)
{
const ecma_value_t value = refs_p->buffer_p[j];
if (!ecma_is_value_empty (value))
{
ecma_object_t *obj_p = ecma_get_object_from_value (value);
if (ecma_object_class_is (obj_p, ECMA_OBJECT_CLASS_WEAKREF))
{
ecma_extended_object_t *ext_obj_p = (ecma_extended_object_t *) obj_p;
ext_obj_p->u.cls.u3.target = ECMA_VALUE_UNDEFINED;
continue;
}
ecma_op_container_remove_weak_entry (obj_p, ecma_make_object_value (object_p));
}
}
ecma_collection_destroy (refs_p);
break;
}
#endif /* JERRY_BUILTIN_WEAKMAP || JERRY_BUILTIN_WEAKSET || JERRY_BUILTIN_WEAKREF */
default:
{
JERRY_ASSERT (name_cp == LIT_INTERNAL_MAGIC_STRING_NATIVE_POINTER);
ecma_gc_free_native_pointer (property_p);
break;
}
}
#if JERRY_LCACHE
if (ecma_is_property_lcached (property_p))
{
ecma_lcache_invalidate (object_p, name_cp, property_p);
}
#endif /* JERRY_LCACHE */
ecma_gc_free_property (object_p, prop_pair_p, i | options);
}
prop_iter_cp = prop_iter_p->next_property_cp;
@ -1447,9 +1577,19 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
if (ecma_is_lexical_environment (object_p))
{
#if JERRY_MODULE_SYSTEM
if (ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_CLASS
&& (object_p->type_flags_refs & ECMA_OBJECT_FLAG_LEXICAL_ENV_HAS_DATA))
{
ecma_gc_free_properties (object_p, ECMA_GC_FREE_REFERENCES);
ecma_dealloc_extended_object (object_p, sizeof (ecma_lexical_environment_class_t));
return;
}
#endif /* JERRY_MODULE_SYSTEM */
if (ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
{
ecma_gc_free_properties (object_p);
ecma_gc_free_properties (object_p, ECMA_GC_FREE_NO_OPTIONS);
}
ecma_dealloc_object (object_p);
@ -1538,9 +1678,7 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
ext_object_size += sizeof (uint64_t) * (length_and_bitset_size >> ECMA_BUILT_IN_BITSET_SHIFT);
}
ecma_gc_free_properties (object_p);
ecma_dealloc_extended_object (object_p, ext_object_size);
return;
goto free_properties;
}
}
@ -1548,7 +1686,7 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
{
case ECMA_OBJECT_TYPE_GENERAL:
{
ecma_gc_free_properties (object_p);
ecma_gc_free_properties (object_p, ECMA_GC_FREE_NO_OPTIONS);
ecma_dealloc_object (object_p);
return;
}
@ -1599,6 +1737,14 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
break;
}
#endif /* JERRY_BUILTIN_TYPEDARRAY */
#if JERRY_MODULE_SYSTEM
case ECMA_OBJECT_CLASS_MODULE_NAMESPACE:
{
ecma_gc_free_properties (object_p, ECMA_GC_FREE_REFERENCES);
ecma_dealloc_extended_object (object_p, sizeof (ecma_extended_object_t));
return;
}
#endif /* JERRY_MODULE_SYSTEM */
#if JERRY_PARSER
case ECMA_OBJECT_CLASS_SCRIPT:
{
@ -1832,7 +1978,8 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
}
}
ecma_gc_free_properties (object_p);
free_properties:
ecma_gc_free_properties (object_p, ECMA_GC_FREE_NO_OPTIONS);
ecma_dealloc_extended_object (object_p, ext_object_size);
} /* ecma_gc_free_object */

View File

@ -26,11 +26,22 @@
* @{
*/
/**
* Free option flags
*/
typedef enum
{
ECMA_GC_FREE_NO_OPTIONS = 0, /**< no options */
ECMA_GC_FREE_SECOND_PROPERTY = (1 << 0), /**< free second property of a property pair */
ECMA_GC_FREE_REFERENCES = (1 << 1), /**< free references */
} ecma_gc_free_options_t;
void ecma_init_gc_info (ecma_object_t *object_p);
void ecma_ref_object (ecma_object_t *object_p);
void ecma_ref_object_inline (ecma_object_t *object_p);
void ecma_deref_object (ecma_object_t *object_p);
void ecma_gc_free_properties (ecma_object_t *object_p);
void ecma_gc_free_property (ecma_object_t *object_p, ecma_property_pair_t *prop_pair_p, uint32_t options);
void ecma_gc_free_properties (ecma_object_t *object_p, uint32_t options);
void ecma_gc_run (void);
void ecma_free_unused_memory (jmem_pressure_t pressure);

View File

@ -711,6 +711,9 @@ typedef enum
#if JERRY_BUILTIN_TYPEDARRAY
ECMA_OBJECT_CLASS_TYPEDARRAY, /**< TypedArray which does NOT need extra space to store length and offset */
#endif /* JERRY_BUILTIN_TYPEDARRAY */
#if JERRY_MODULE_SYSTEM
ECMA_OBJECT_CLASS_MODULE_NAMESPACE, /**< Module Namespace (ECMAScript v11, 9.4.6) */
#endif /* JERRY_MODULE_SYSTEM */
/* These objects are marked by Garbage Collector. */
#if JERRY_ESNEXT
@ -776,14 +779,14 @@ typedef enum
/* Types between 0 - 12 are ecma_object_type_t which can have a built-in flag. */
ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE = 13, /**< declarative lexical environment */
ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND = 14, /**< object-bound lexical environment
* with provideThis flag */
ECMA_LEXICAL_ENVIRONMENT_HOME_OBJECT_BOUND = 15, /**< object-bound lexical environment
* with provided home object reference */
#if JERRY_ESNEXT
ECMA_LEXICAL_ENVIRONMENT_CLASS = 14, /**< lexical environment with class */
#endif /* JERRY_ESNEXT */
ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND = 15, /**< object-bound lexical environment */
ECMA_LEXICAL_ENVIRONMENT_TYPE_START = ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE, /**< first lexical
* environment type */
ECMA_LEXICAL_ENVIRONMENT_TYPE__MAX = ECMA_LEXICAL_ENVIRONMENT_HOME_OBJECT_BOUND /**< maximum value */
ECMA_LEXICAL_ENVIRONMENT_TYPE__MAX = ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND /**< maximum value */
} ecma_lexical_environment_type_t;
#if JERRY_ESNEXT
@ -848,10 +851,15 @@ typedef enum
#define ECMA_OBJECT_FLAG_EXTENSIBLE 0x20
/**
* Lexical environments created for non-closure code blocks
* Declarative lexical environments created for non-closure code blocks
*/
#define ECMA_OBJECT_FLAG_BLOCK ECMA_OBJECT_FLAG_EXTENSIBLE
/**
* Lexical environments with class has extra data
*/
#define ECMA_OBJECT_FLAG_LEXICAL_ENV_HAS_DATA ECMA_OBJECT_FLAG_EXTENSIBLE
/**
* Bitshift index for an ecma-object reference count field
*/
@ -1142,6 +1150,16 @@ typedef struct
#define ECMA_BUILTIN_IS_EXTENDED_BUILT_IN(object_type) \
((object_type) == ECMA_OBJECT_TYPE_CLASS || (object_type) == ECMA_OBJECT_TYPE_ARRAY)
/**
* Description of lexical environment with class
*/
typedef struct
{
ecma_object_t lexical_env; /**< lexical environment header */
ecma_object_t *module_p; /**< module reference */
} ecma_lexical_environment_class_t;
/**
* Description of native functions
*/

View File

@ -123,7 +123,7 @@ ecma_create_decl_lex_env (ecma_object_t *outer_lexical_environment_p) /**< outer
/**
* Create a object lexical environment with specified outer lexical environment
* (or NULL if the environment is not nested), binding object and provided type flag.
* (or NULL if the environment is not nested), and binding object.
*
* See also: ECMA-262 v5, 10.2.1.2
*
@ -133,23 +133,15 @@ ecma_create_decl_lex_env (ecma_object_t *outer_lexical_environment_p) /**< outer
*/
ecma_object_t *
ecma_create_object_lex_env (ecma_object_t *outer_lexical_environment_p, /**< outer lexical environment */
ecma_object_t *binding_obj_p, /**< binding object */
ecma_lexical_environment_type_t type) /**< type of the new lexical environment */
ecma_object_t *binding_obj_p) /**< binding object */
{
#if JERRY_ESNEXT
JERRY_ASSERT (type == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND
|| type == ECMA_LEXICAL_ENVIRONMENT_HOME_OBJECT_BOUND);
#else /* !JERRY_ESNEXT */
JERRY_ASSERT (type == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
#endif /* JERRY_ESNEXT */
JERRY_ASSERT (binding_obj_p != NULL
&& !ecma_is_lexical_environment (binding_obj_p));
ecma_object_t *new_lexical_environment_p = ecma_alloc_object ();
const ecma_object_descriptor_t lexical_env_flag = ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV;
new_lexical_environment_p->type_flags_refs = (ecma_object_descriptor_t) (type | lexical_env_flag);
new_lexical_environment_p->type_flags_refs = (ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV
| ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
ecma_init_gc_info (new_lexical_environment_p);
@ -161,6 +153,45 @@ ecma_create_object_lex_env (ecma_object_t *outer_lexical_environment_p, /**< out
return new_lexical_environment_p;
} /* ecma_create_object_lex_env */
#if JERRY_ESNEXT
/**
* Create a lexical environment with a specified size.
*
* @return pointer to the descriptor of the lexical environment
*/
ecma_object_t *
ecma_create_lex_env_class (ecma_object_t *outer_lexical_environment_p, /**< outer lexical environment */
size_t lexical_env_size) /**< size of the lexical environment */
{
ecma_object_t *new_lexical_environment_p;
ecma_object_descriptor_t type_flags_refs = (ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV
| ECMA_LEXICAL_ENVIRONMENT_CLASS);
if (lexical_env_size > 0)
{
new_lexical_environment_p = (ecma_object_t *) ecma_alloc_extended_object (lexical_env_size);
type_flags_refs |= ECMA_OBJECT_FLAG_LEXICAL_ENV_HAS_DATA;
}
else
{
new_lexical_environment_p = ecma_alloc_object ();
}
new_lexical_environment_p->type_flags_refs = type_flags_refs;
ecma_init_gc_info (new_lexical_environment_p);
new_lexical_environment_p->u1.property_list_cp = JMEM_CP_NULL;
ECMA_SET_POINTER (new_lexical_environment_p->u2.outer_reference_cp, outer_lexical_environment_p);
return new_lexical_environment_p;
} /* ecma_create_lex_env_class */
#endif /* JERRY_ESNEXT */
/**
* Check if the object is lexical environment.
*
@ -203,6 +234,29 @@ ecma_get_object_type (const ecma_object_t *object_p) /**< object */
return (ecma_object_type_t) (object_p->type_flags_refs & ECMA_OBJECT_TYPE_MASK);
} /* ecma_get_object_type */
/**
* Get value of an object if the class matches
*
* @return value of the object if the class matches
* ECMA_VALUE_NOT_FOUND otherwise
*/
extern inline bool JERRY_ATTR_ALWAYS_INLINE
ecma_object_class_is (ecma_object_t *object_p, /**< object */
ecma_object_class_type_t class_id) /**< class id */
{
if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_CLASS)
{
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
if (ext_object_p->u.cls.type == (uint8_t) class_id)
{
return true;
}
}
return false;
} /* ecma_object_class_is */
/**
* Check if the object is a built-in object
*
@ -286,7 +340,8 @@ ecma_get_lex_env_binding_object (const ecma_object_t *object_p) /**< object-boun
JERRY_ASSERT (ecma_is_lexical_environment (object_p));
#if JERRY_ESNEXT
JERRY_ASSERT (ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND
|| ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_HOME_OBJECT_BOUND);
|| (ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_CLASS
&& (object_p->type_flags_refs & ECMA_OBJECT_FLAG_LEXICAL_ENV_HAS_DATA) == 0));
#else /* !JERRY_ESNEXT */
JERRY_ASSERT (ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
#endif /* JERRY_ESNEXT */
@ -568,6 +623,51 @@ ecma_create_named_accessor_property (ecma_object_t *object_p, /**< object */
return ecma_create_property (object_p, name_p, type_and_flags, value, out_prop_p);
} /* ecma_create_named_accessor_property */
#if JERRY_MODULE_SYSTEM
/**
* Create property reference
*/
void
ecma_create_named_reference_property (ecma_object_t *object_p, /**< object */
ecma_string_t *name_p, /**< property name */
ecma_property_t *property_p) /**< referenced property */
{
JERRY_ASSERT (object_p != NULL && name_p != NULL && property_p != NULL);
JERRY_ASSERT (*property_p & ECMA_PROPERTY_FLAG_DATA);
JERRY_ASSERT (ecma_find_named_property (object_p, name_p) == NULL);
JERRY_ASSERT ((ecma_is_lexical_environment (object_p)
&& ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_CLASS
&& (object_p->type_flags_refs & ECMA_OBJECT_FLAG_LEXICAL_ENV_HAS_DATA))
|| ecma_object_class_is (object_p, ECMA_OBJECT_CLASS_MODULE_NAMESPACE));
uint8_t type_and_flags = ECMA_PROPERTY_CONFIGURABLE_ENUMERABLE;
ecma_property_value_t *value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
jmem_cpointer_tag_t offset = (jmem_cpointer_tag_t) (((uintptr_t) property_p) & 0x1);
#if JERRY_CPOINTER_32_BIT
if (offset != 0)
{
--value_p;
}
#else /* !JERRY_CPOINTER_32_BIT */
if (offset == 0)
{
++value_p;
}
#endif /* JERRY_CPOINTER_32_BIT */
JERRY_ASSERT ((((uintptr_t) value_p) & (((uintptr_t) 1 << JMEM_ALIGNMENT_LOG) - 1)) == 0);
ecma_property_value_t value;
ECMA_SET_NON_NULL_POINTER_TAG (value.value, value_p, offset);
ecma_create_property (object_p, name_p, type_and_flags, value, NULL);
} /* ecma_create_named_reference_property */
#endif /* JERRY_MODULE_SYSTEM */
/**
* Find named data property or named accessor property in a specified object.
*
@ -748,48 +848,6 @@ ecma_get_named_data_property (ecma_object_t *obj_p, /**< object to find property
return ECMA_PROPERTY_VALUE_PTR (property_p);
} /* ecma_get_named_data_property */
/**
* Free property values and change their type to deleted.
*
* Note:
* internal properties are not supported
*/
void
ecma_free_property (ecma_object_t *object_p, /**< object the property belongs to */
jmem_cpointer_t name_cp, /**< name of the property or ECMA_NULL_POINTER */
ecma_property_t *property_p) /**< property */
{
JERRY_ASSERT (object_p != NULL && property_p != NULL);
JERRY_ASSERT (ECMA_PROPERTY_IS_RAW (*property_p));
if (*property_p & ECMA_PROPERTY_FLAG_DATA)
{
ecma_free_value_if_not_object (ECMA_PROPERTY_VALUE_PTR (property_p)->value);
}
else
{
#if JERRY_CPOINTER_32_BIT
ecma_getter_setter_pointers_t *getter_setter_pair_p;
getter_setter_pair_p = ECMA_GET_NON_NULL_POINTER (ecma_getter_setter_pointers_t,
ECMA_PROPERTY_VALUE_PTR (property_p)->getter_setter_pair_cp);
jmem_pools_free (getter_setter_pair_p, sizeof (ecma_getter_setter_pointers_t));
#endif /* JERRY_CPOINTER_32_BIT */
}
#if JERRY_LCACHE
if (ecma_is_property_lcached (property_p))
{
ecma_lcache_invalidate (object_p, name_cp, property_p);
}
#endif /* JERRY_LCACHE */
if (ECMA_PROPERTY_GET_NAME_TYPE (*property_p) == ECMA_DIRECT_STRING_PTR)
{
ecma_string_t *prop_name_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, name_cp);
ecma_deref_ecma_string (prop_name_p);
}
} /* ecma_free_property */
/**
* Delete the object's property referenced by its value pointer.
*
@ -829,7 +887,7 @@ ecma_delete_property (ecma_object_t *object_p, /**< object */
ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) cur_prop_p;
for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
for (uint32_t i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
{
if ((prop_pair_p->values + i) == prop_value_p)
{
@ -844,7 +902,7 @@ ecma_delete_property (ecma_object_t *object_p, /**< object */
}
#endif /* JERRY_PROPRETY_HASHMAP */
ecma_free_property (object_p, prop_pair_p->names_cp[i], cur_prop_p->types + i);
ecma_gc_free_property (object_p, prop_pair_p, i);
cur_prop_p->types[i] = ECMA_PROPERTY_TYPE_DELETED;
prop_pair_p->names_cp[i] = LIT_INTERNAL_MAGIC_STRING_DELETED;
@ -1008,6 +1066,36 @@ ecma_set_named_accessor_property_setter (ecma_object_t *object_p, /**< the prope
#endif /* JERRY_CPOINTER_32_BIT */
} /* ecma_set_named_accessor_property_setter */
#if JERRY_MODULE_SYSTEM
/**
* Gets the referenced property value
*
* @return pointer to the value
*/
extern inline ecma_property_value_t * JERRY_ATTR_ALWAYS_INLINE
ecma_get_property_value_from_named_reference (ecma_property_value_t *reference_p) /**< data property reference */
{
ecma_value_t value = reference_p->value;
reference_p = ECMA_GET_NON_NULL_POINTER_FROM_POINTER_TAG (ecma_property_value_t, value);
#if JERRY_CPOINTER_32_BIT
if (ECMA_GET_FIRST_BIT_FROM_POINTER_TAG (value))
{
++reference_p;
}
#else /* !JERRY_CPOINTER_32_BIT */
if (!ECMA_GET_FIRST_BIT_FROM_POINTER_TAG (value))
{
--reference_p;
}
#endif /* JERRY_CPOINTER_32_BIT */
return reference_p;
} /* ecma_get_property_value_from_named_reference */
#endif /* JERRY_MODULE_SYSTEM */
/**
* Get property's 'Writable' attribute value
*

View File

@ -358,6 +358,9 @@ const lit_utf8_byte_t *ecma_string_get_chars (const ecma_string_t *string_p,
bool ecma_compare_ecma_string_to_magic_id (const ecma_string_t *string_p, lit_magic_string_id_t id);
bool ecma_string_is_empty (const ecma_string_t *string_p);
bool ecma_string_is_length (const ecma_string_t *string_p);
#if JERRY_ESNEXT
bool ecma_compare_ecma_string_to_global_symbol (ecma_string_t *string_p, lit_magic_string_id_t property_id);
#endif /* JERRY_ESNEXT */
jmem_cpointer_t ecma_string_to_property_name (ecma_string_t *prop_name_p, ecma_property_t *name_type_p);
ecma_string_t *ecma_string_from_property_name (ecma_property_t property, jmem_cpointer_t prop_name_cp);
@ -457,11 +460,14 @@ void ecma_compact_collection_free (ecma_value_t *compact_collection_p);
/* ecma-helpers.c */
ecma_object_t *ecma_create_object (ecma_object_t *prototype_object_p, size_t ext_object_size, ecma_object_type_t type);
ecma_object_t *ecma_create_decl_lex_env (ecma_object_t *outer_lexical_environment_p);
ecma_object_t *ecma_create_object_lex_env (ecma_object_t *outer_lexical_environment_p, ecma_object_t *binding_obj_p,
ecma_lexical_environment_type_t type);
ecma_object_t *ecma_create_object_lex_env (ecma_object_t *outer_lexical_environment_p, ecma_object_t *binding_obj_p);
#if JERRY_ESNEXT
ecma_object_t *ecma_create_lex_env_class (ecma_object_t *outer_lexical_environment_p, size_t lexical_env_size);
#endif /* JERRY_ESNEXT */
bool JERRY_ATTR_PURE ecma_is_lexical_environment (const ecma_object_t *object_p);
void ecma_op_ordinary_object_set_extensible (ecma_object_t *object_p);
ecma_object_type_t JERRY_ATTR_PURE ecma_get_object_type (const ecma_object_t *object_p);
bool JERRY_ATTR_PURE ecma_object_class_is (ecma_object_t *object_p, ecma_object_class_type_t class_id);
bool JERRY_ATTR_PURE ecma_get_object_is_builtin (const ecma_object_t *object_p);
void ecma_set_object_is_builtin (ecma_object_t *object_p);
uint8_t ecma_get_object_builtin_id (ecma_object_t *object_p);
@ -475,13 +481,15 @@ ecma_create_named_data_property (ecma_object_t *object_p, ecma_string_t *name_p,
ecma_property_value_t *
ecma_create_named_accessor_property (ecma_object_t *object_p, ecma_string_t *name_p, ecma_object_t *get_p,
ecma_object_t *set_p, uint8_t prop_attributes, ecma_property_t **out_prop_p);
#if JERRY_MODULE_SYSTEM
void ecma_create_named_reference_property (ecma_object_t *object_p, ecma_string_t *name_p,
ecma_property_t *property_p);
#endif /* JERRY_MODULE_SYSTEM */
ecma_property_t *
ecma_find_named_property (ecma_object_t *obj_p, ecma_string_t *name_p);
ecma_property_value_t *
ecma_get_named_data_property (ecma_object_t *obj_p, ecma_string_t *name_p);
void ecma_free_property (ecma_object_t *object_p, jmem_cpointer_t name_cp, ecma_property_t *property_p);
void ecma_delete_property (ecma_object_t *object_p, ecma_property_value_t *prop_value_p);
void ecma_named_data_property_assign_value (ecma_object_t *obj_p, ecma_property_value_t *prop_value_p,
@ -493,6 +501,10 @@ void ecma_set_named_accessor_property_getter (ecma_object_t *object_p, ecma_prop
ecma_object_t *getter_p);
void ecma_set_named_accessor_property_setter (ecma_object_t *object_p, ecma_property_value_t *prop_value_p,
ecma_object_t *setter_p);
#if JERRY_MODULE_SYSTEM
ecma_property_value_t *
ecma_get_property_value_from_named_reference (ecma_property_value_t *reference_p);
#endif /* JERRY_MODULE_SYSTEM */
bool ecma_is_property_writable (ecma_property_t property);
void ecma_set_property_writable_attr (ecma_property_t *property_p, bool is_writable);
bool ecma_is_property_enumerable (ecma_property_t property);

View File

@ -393,15 +393,9 @@ ecma_module_evaluate (ecma_module_t *module_p) /**< module */
}
JERRY_ASSERT (module_p->header.u.cls.u1.module_state == JERRY_MODULE_STATE_LINKED);
#if JERRY_BUILTIN_REALMS
ecma_object_t *global_object_p = (ecma_object_t *) ecma_op_function_get_realm (module_p->compiled_code_p);
#else /* !JERRY_BUILTIN_REALMS */
ecma_object_t *global_object_p = ecma_builtin_get_global ();
#endif /* JERRY_BUILTIN_REALMS */
JERRY_ASSERT (module_p->scope_p != NULL);
module_p->header.u.cls.u1.module_state = JERRY_MODULE_STATE_EVALUATING;
module_p->scope_p = ecma_create_decl_lex_env (ecma_get_global_environment (global_object_p));
ecma_value_t ret_value;
ret_value = vm_run_module (module_p);
@ -457,21 +451,11 @@ ecma_module_namespace_object_add_export_if_needed (ecma_module_t *module_p, /**<
return result;
}
ecma_object_t *ref_base_lex_env_p;
ecma_value_t prop_value = ecma_op_get_value_lex_env_base (record.module_p->scope_p,
&ref_base_lex_env_p,
record.name_p);
ecma_property_t *new_property_p;
ecma_create_named_data_property (module_p->namespace_object_p,
export_name_p,
ECMA_PROPERTY_FIXED,
&new_property_p);
ecma_property_t *property_p = ecma_find_named_property (record.module_p->scope_p, record.name_p);
ecma_named_data_property_assign_value (module_p->namespace_object_p,
ECMA_PROPERTY_VALUE_PTR (new_property_p),
prop_value);
ecma_free_value (prop_value);
ecma_create_named_reference_property (module_p->namespace_object_p,
export_name_p,
property_p);
return result;
} /* ecma_module_namespace_object_add_export_if_needed */
@ -491,13 +475,23 @@ ecma_module_create_namespace_object (ecma_module_t *module_p) /**< module */
return result;
}
JERRY_ASSERT (module_p->header.u.cls.u1.module_state == JERRY_MODULE_STATE_EVALUATED);
JERRY_ASSERT (module_p->header.u.cls.u1.module_state >= JERRY_MODULE_STATE_LINKED
&& module_p->header.u.cls.u1.module_state <= JERRY_MODULE_STATE_EVALUATED);
ecma_module_resolve_set_t *resolve_set_p = NULL;
ecma_module_resolve_stack_t *stack_p = NULL;
module_p->namespace_object_p = ecma_create_object (ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE),
0,
ECMA_OBJECT_TYPE_GENERAL);
ecma_object_t *namespace_object_p = ecma_create_object (NULL,
sizeof (ecma_extended_object_t),
ECMA_OBJECT_TYPE_CLASS);
namespace_object_p->type_flags_refs &= (ecma_object_descriptor_t) ~ECMA_OBJECT_FLAG_EXTENSIBLE;
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) namespace_object_p;
ext_object_p->u.cls.type = ECMA_OBJECT_CLASS_MODULE_NAMESPACE;
ECMA_SET_INTERNAL_VALUE_POINTER (ext_object_p->u.cls.u3.value, module_p);
module_p->namespace_object_p = namespace_object_p;
ecma_deref_object (namespace_object_p);
ecma_module_resolve_stack_push (&stack_p, module_p, ecma_get_magic_string (LIT_MAGIC_STRING_ASTERIX_CHAR));
while (stack_p != NULL)
@ -516,13 +510,6 @@ ecma_module_create_namespace_object (ecma_module_t *module_p) /**< module */
continue;
}
result = ecma_module_evaluate (current_module_p);
if (ECMA_IS_VALUE_ERROR (result))
{
break;
}
ecma_module_names_t *export_names_p = current_module_p->local_exports_p;
if (export_names_p != NULL)
@ -569,6 +556,11 @@ ecma_module_create_namespace_object (ecma_module_t *module_p) /**< module */
star_export_p = star_export_p->next_p;
}
if (ECMA_IS_VALUE_ERROR (result))
{
break;
}
}
/* Clean up. */
@ -659,8 +651,6 @@ ecma_module_connect_imports (ecma_module_t *module_p)
const bool is_namespace_import = ecma_compare_ecma_string_to_magic_id (import_names_p->imex_name_p,
LIT_MAGIC_STRING_ASTERIX_CHAR);
ecma_value_t prop_value;
if (is_namespace_import)
{
result = ecma_module_create_namespace_object (imported_module_p);
@ -670,8 +660,12 @@ ecma_module_connect_imports (ecma_module_t *module_p)
return result;
}
ecma_ref_object (imported_module_p->namespace_object_p);
prop_value = ecma_make_object_value (imported_module_p->namespace_object_p);
ecma_property_value_t *value_p;
value_p = ecma_create_named_data_property (module_p->scope_p,
import_names_p->local_name_p,
ECMA_PROPERTY_FLAG_WRITABLE,
NULL);
value_p->value = ecma_make_object_value (imported_module_p->namespace_object_p);
}
else /* !is_namespace_import */
{
@ -691,46 +685,28 @@ ecma_module_connect_imports (ecma_module_t *module_p)
if (record.module_p->header.u.cls.u1.module_state == JERRY_MODULE_STATE_NATIVE)
{
ecma_object_t *object_p = record.module_p->namespace_object_p;
ecma_value_t prop_value;
prop_value = ecma_op_object_find_own (ecma_make_object_value (object_p), object_p, record.name_p);
JERRY_ASSERT (ecma_is_value_found (prop_value));
ecma_property_value_t *value_p;
value_p = ecma_create_named_data_property (module_p->scope_p,
import_names_p->local_name_p,
ECMA_PROPERTY_FLAG_WRITABLE,
NULL);
value_p->value = ecma_copy_value_if_not_object (prop_value);
}
else
{
result = ecma_module_evaluate (record.module_p);
if (ECMA_IS_VALUE_ERROR (result))
{
return result;
}
ecma_object_t *ref_base_lex_env_p;
prop_value = ecma_op_get_value_lex_env_base (record.module_p->scope_p,
&ref_base_lex_env_p,
record.name_p);
ecma_property_t *property_p = ecma_find_named_property (record.module_p->scope_p, record.name_p);
ecma_create_named_reference_property (module_p->scope_p,
import_names_p->local_name_p,
property_p);
}
}
ecma_property_t *prop_p = ecma_op_create_mutable_binding (local_env_p,
import_names_p->local_name_p,
true /* is_deletable */);
JERRY_ASSERT (prop_p != ECMA_PROPERTY_POINTER_ERROR);
if (prop_p != NULL)
{
JERRY_ASSERT (ecma_is_value_undefined (ECMA_PROPERTY_VALUE_PTR (prop_p)->value));
ECMA_PROPERTY_VALUE_PTR (prop_p)->value = prop_value;
ecma_deref_if_object (prop_value);
}
else
{
ecma_op_set_mutable_binding (local_env_p,
import_names_p->local_name_p,
prop_value,
false /* is_strict */);
ecma_free_value (prop_value);
}
import_names_p = import_names_p->next_p;
}
@ -975,6 +951,20 @@ restart:
node_p = node_p->next_p;
}
if (current_module_p->scope_p == NULL)
{
/* Initialize scope for handling circular references. */
ecma_value_t result = vm_init_module_scope (current_module_p);
if (ECMA_IS_VALUE_ERROR (result))
{
module_p->header.u.cls.u1.module_state = JERRY_MODULE_STATE_ERROR;
goto error;
}
JERRY_ASSERT (result == ECMA_VALUE_EMPTY);
}
if (current_module_p->header.u.cls.u3.dfs_ancestor_index != current_p->dfs_index)
{
current_p = current_p->parent_p;
@ -1079,15 +1069,10 @@ ecma_module_release_module (ecma_module_t *module_p) /**< module */
JERRY_ASSERT (state != JERRY_MODULE_STATE_INVALID);
if (module_p->namespace_object_p != NULL)
{
/* The module structure keeps a strong reference to the namespace object, which will require an extra GC call. */
JERRY_CONTEXT (ecma_gc_new_objects)++;
ecma_deref_object (module_p->namespace_object_p);
#ifndef JERRY_NDEBUG
module_p->namespace_object_p = NULL;
module_p->scope_p = NULL;
module_p->namespace_object_p = NULL;
#endif /* JERRY_NDEBUG */
}
if (state == JERRY_MODULE_STATE_NATIVE)
{
@ -1099,13 +1084,6 @@ ecma_module_release_module (ecma_module_t *module_p) /**< module */
ecma_module_release_module_nodes (module_p->indirect_exports_p, false);
ecma_module_release_module_nodes (module_p->star_exports_p, false);
if (state >= JERRY_MODULE_STATE_EVALUATING)
{
/* The module structure keeps a strong reference to the module scope, which will require an extra GC call. */
JERRY_CONTEXT (ecma_gc_new_objects)++;
ecma_deref_object (module_p->scope_p);
}
if (module_p->compiled_code_p != NULL)
{
ecma_bytecode_deref (module_p->compiled_code_p);

View File

@ -593,9 +593,7 @@ ecma_builtin_create_global_object (void)
global_object_p->global_scope_cp = global_object_p->global_env_cp;
#endif /* JERRY_ESNEXT */
ecma_object_t *global_lex_env_p = ecma_create_object_lex_env (NULL,
object_p,
ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
ecma_object_t *global_lex_env_p = ecma_create_object_lex_env (NULL, object_p);
ECMA_SET_NON_NULL_POINTER (global_object_p->global_env_cp, global_lex_env_p);
#if JERRY_ESNEXT
global_object_p->global_scope_cp = global_object_p->global_env_cp;

View File

@ -899,7 +899,7 @@ ecma_delete_array_properties (ecma_object_t *object_p, /**< object */
JERRY_ASSERT (ECMA_PROPERTY_IS_PROPERTY_PAIR (current_prop_p));
ecma_property_pair_t *prop_pair_p = (ecma_property_pair_t *) current_prop_p;
for (int i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
for (uint32_t i = 0; i < ECMA_PROPERTY_PAIR_ITEM_COUNT; i++)
{
if (current_prop_p->types[i] != ECMA_PROPERTY_TYPE_DELETED
&& ecma_is_property_configurable (current_prop_p->types[i]))
@ -920,7 +920,7 @@ ecma_delete_array_properties (ecma_object_t *object_p, /**< object */
}
#endif /* JERRY_PROPRETY_HASHMAP */
ecma_free_property (object_p, prop_pair_p->names_cp[i], current_prop_p->types + i);
ecma_gc_free_property (object_p, prop_pair_p, i);
current_prop_p->types[i] = ECMA_PROPERTY_TYPE_DELETED;
prop_pair_p->names_cp[i] = LIT_INTERNAL_MAGIC_STRING_DELETED;
}

View File

@ -67,8 +67,7 @@ ecma_op_get_value_lex_env_base (ecma_object_t *lex_env_p, /**< lexical environme
#if JERRY_ESNEXT
if (JERRY_UNLIKELY (property_value_p->value == ECMA_VALUE_UNINITIALIZED))
{
return ecma_raise_reference_error (ECMA_ERR_MSG ("Variables declared by let/const must be"
" initialized before reading their value"));
return ecma_raise_reference_error (ECMA_ERR_MSG (ecma_error_let_const_not_initialized));
}
#endif /* JERRY_ESNEXT */
@ -77,8 +76,32 @@ ecma_op_get_value_lex_env_base (ecma_object_t *lex_env_p, /**< lexical environme
break;
}
#if JERRY_ESNEXT
case ECMA_LEXICAL_ENVIRONMENT_HOME_OBJECT_BOUND:
case ECMA_LEXICAL_ENVIRONMENT_CLASS:
{
#if JERRY_MODULE_SYSTEM
if (lex_env_p->type_flags_refs & ECMA_OBJECT_FLAG_LEXICAL_ENV_HAS_DATA)
{
ecma_property_t *property_p = ecma_find_named_property (lex_env_p, name_p);
if (property_p != NULL)
{
*ref_base_lex_env_p = lex_env_p;
ecma_property_value_t *property_value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
if (!(*property_p & ECMA_PROPERTY_FLAG_DATA))
{
property_value_p = ecma_get_property_value_from_named_reference (property_value_p);
}
if (JERRY_UNLIKELY (property_value_p->value == ECMA_VALUE_UNINITIALIZED))
{
return ecma_raise_reference_error (ECMA_ERR_MSG (ecma_error_let_const_not_initialized));
}
return ecma_fast_copy_value (property_value_p->value);
}
}
#endif /* JERRY_MODULE_SYSTEM */
break;
}
#endif /* JERRY_ESNEXT */
@ -215,52 +238,47 @@ ecma_op_put_value_lex_env_base (ecma_object_t *lex_env_p, /**< lexical environme
{
switch (ecma_get_lex_env_type (lex_env_p))
{
#if JERRY_ESNEXT
case ECMA_LEXICAL_ENVIRONMENT_CLASS:
{
if ((lex_env_p->type_flags_refs & ECMA_OBJECT_FLAG_LEXICAL_ENV_HAS_DATA) == 0)
{
break;
}
/* FALLTHRU */
}
#endif /* JERRY_ESNEXT */
case ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE:
{
ecma_property_t *property_p = ecma_find_named_property (lex_env_p, name_p);
if (property_p != NULL)
{
#if JERRY_ESNEXT
ecma_property_value_t *property_value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
JERRY_ASSERT (!(*property_p & ECMA_PROPERTY_FLAG_WRITABLE)
|| (*property_p & ECMA_PROPERTY_FLAG_DATA));
if ((*property_p & ECMA_PROPERTY_FLAG_WRITABLE)
&& property_value_p->value != ECMA_VALUE_UNINITIALIZED)
{
ecma_named_data_property_assign_value (lex_env_p, property_value_p, value);
return ECMA_VALUE_EMPTY;
}
#else /* JERRY_ESNEXT */
if (ecma_is_property_writable (*property_p))
{
ecma_property_value_t *property_value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
#if JERRY_ESNEXT
if (JERRY_UNLIKELY (property_value_p->value == ECMA_VALUE_UNINITIALIZED))
{
return ecma_raise_reference_error (ECMA_ERR_MSG ("Variables declared by let/const must be"
" initialized before writing their value"));
}
#endif /* JERRY_ESNEXT */
ecma_named_data_property_assign_value (lex_env_p, property_value_p, value);
}
#if JERRY_ESNEXT
else if (ecma_is_property_enumerable (*property_p))
{
if (JERRY_UNLIKELY (ECMA_PROPERTY_VALUE_PTR (property_p)->value == ECMA_VALUE_UNINITIALIZED))
{
return ecma_raise_reference_error (ECMA_ERR_MSG ("Variables declared by let/const must be"
" initialized before writing their value"));
}
return ecma_raise_type_error (ECMA_ERR_MSG ("Constant bindings cannot be reassigned"));
return ECMA_VALUE_EMPTY;
}
#endif /* JERRY_ESNEXT */
else if (is_strict)
{
return ecma_raise_type_error (ECMA_ERR_MSG ("Binding cannot be set"));
}
return ECMA_VALUE_EMPTY;
return ecma_op_raise_set_binding_error (property_p, is_strict);
}
break;
}
#if JERRY_ESNEXT
case ECMA_LEXICAL_ENVIRONMENT_HOME_OBJECT_BOUND:
{
break;
}
#endif /* JERRY_ESNEXT */
default:
{
JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);

View File

@ -88,6 +88,42 @@ ecma_create_global_lexical_block (ecma_object_t *global_object_p) /**< global ob
} /* ecma_create_global_lexical_block */
#endif /* JERRY_ESNEXT */
/**
* Raise the appropriate error when setting a binding is failed
*
* @return ECMA_VALUE_EMPTY or ECMA_VALUE_ERROR
*/
ecma_value_t
ecma_op_raise_set_binding_error (ecma_property_t *property_p, /**< property */
bool is_strict) /**< flag indicating strict mode */
{
JERRY_UNUSED (property_p);
#if JERRY_ESNEXT
const ecma_property_t expected_bits = (ECMA_PROPERTY_FLAG_DATA | ECMA_PROPERTY_FLAG_ENUMERABLE);
if ((*property_p & expected_bits) == expected_bits)
{
ecma_property_value_t *property_value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
if (JERRY_UNLIKELY (property_value_p->value == ECMA_VALUE_UNINITIALIZED))
{
return ecma_raise_reference_error (ECMA_ERR_MSG (ecma_error_let_const_not_initialized));
}
JERRY_ASSERT (!ecma_is_property_writable (*property_p));
return ecma_raise_type_error (ECMA_ERR_MSG ("Constant bindings cannot be reassigned"));
}
#endif /* JERRY_ESNEXT */
if (is_strict)
{
return ecma_raise_type_error (ECMA_ERR_MSG ("Binding cannot be set"));
}
return ECMA_VALUE_EMPTY;
} /* ecma_op_raise_set_binding_error */
/**
* Get reference to Global lexical scope
* without increasing its reference count.
@ -125,18 +161,33 @@ ecma_op_has_binding (ecma_object_t *lex_env_p, /**< lexical environment */
ecma_lexical_environment_type_t lex_env_type = ecma_get_lex_env_type (lex_env_p);
if (lex_env_type == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
switch (lex_env_type)
{
ecma_property_t *property_p = ecma_find_named_property (lex_env_p, name_p);
#if JERRY_ESNEXT
case ECMA_LEXICAL_ENVIRONMENT_CLASS:
{
if ((lex_env_p->type_flags_refs & ECMA_OBJECT_FLAG_LEXICAL_ENV_HAS_DATA) == 0)
{
return ECMA_VALUE_FALSE;
}
/* FALLTHRU */
}
#endif /* JERRY_ESNEXT */
case ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE:
{
ecma_property_t *property_p = ecma_find_named_property (lex_env_p, name_p);
return ecma_make_boolean_value (property_p != NULL);
return ecma_make_boolean_value (property_p != NULL);
}
default:
{
JERRY_ASSERT (lex_env_type == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
return ecma_op_object_has_property (binding_obj_p, name_p);
}
}
JERRY_ASSERT (lex_env_type == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
return ecma_op_object_has_property (binding_obj_p, name_p);
} /* ecma_op_has_binding */
/**
@ -245,53 +296,64 @@ ecma_op_set_mutable_binding (ecma_object_t *lex_env_p, /**< lexical environment
&& ecma_is_lexical_environment (lex_env_p));
JERRY_ASSERT (name_p != NULL);
if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
switch (ecma_get_lex_env_type (lex_env_p))
{
ecma_property_t *property_p = ecma_find_named_property (lex_env_p, name_p);
if (JERRY_UNLIKELY (property_p == NULL))
{
property_p = ecma_op_create_mutable_binding (lex_env_p, name_p, is_strict);
JERRY_ASSERT (property_p != ECMA_PROPERTY_POINTER_ERROR);
}
JERRY_ASSERT (property_p != NULL && ECMA_PROPERTY_IS_RAW_DATA (*property_p));
if (ecma_is_property_writable (*property_p))
{
ecma_named_data_property_assign_value (lex_env_p, ECMA_PROPERTY_VALUE_PTR (property_p), value);
}
#if JERRY_ESNEXT
else if (ecma_is_property_enumerable (*property_p))
case ECMA_LEXICAL_ENVIRONMENT_CLASS:
{
return ecma_raise_type_error (ECMA_ERR_MSG ("Constant bindings cannot be reassigned"));
if ((lex_env_p->type_flags_refs & ECMA_OBJECT_FLAG_LEXICAL_ENV_HAS_DATA) == 0)
{
return ECMA_VALUE_EMPTY;
}
/* FALLTHRU */
}
#endif /* JERRY_ESNEXT */
else if (is_strict)
case ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE:
{
return ecma_raise_type_error (ECMA_ERR_MSG ("Binding cannot be set"));
ecma_property_t *property_p = ecma_find_named_property (lex_env_p, name_p);
if (JERRY_UNLIKELY (property_p == NULL))
{
property_p = ecma_op_create_mutable_binding (lex_env_p, name_p, is_strict);
JERRY_ASSERT (property_p != ECMA_PROPERTY_POINTER_ERROR);
}
JERRY_ASSERT (property_p != NULL && ECMA_PROPERTY_IS_RAW_DATA (*property_p));
JERRY_ASSERT (!(*property_p & ECMA_PROPERTY_FLAG_WRITABLE)
|| (*property_p & ECMA_PROPERTY_FLAG_DATA));
if ((*property_p & ECMA_PROPERTY_FLAG_WRITABLE))
{
ecma_property_value_t *property_value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
JERRY_ASSERT (property_value_p->value != ECMA_VALUE_UNINITIALIZED);
ecma_named_data_property_assign_value (lex_env_p, property_value_p, value);
return ECMA_VALUE_EMPTY;
}
return ecma_op_raise_set_binding_error (property_p, is_strict);
}
default:
{
JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
ecma_value_t completion = ecma_op_object_put (binding_obj_p,
name_p,
value,
is_strict);
if (ECMA_IS_VALUE_ERROR (completion))
{
return completion;
}
JERRY_ASSERT (ecma_is_value_boolean (completion));
return ECMA_VALUE_EMPTY;
}
}
else
{
JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
ecma_value_t completion = ecma_op_object_put (binding_obj_p,
name_p,
value,
is_strict);
if (ECMA_IS_VALUE_ERROR (completion))
{
return completion;
}
JERRY_ASSERT (ecma_is_value_boolean (completion));
}
return ECMA_VALUE_EMPTY;
} /* ecma_op_set_mutable_binding */
/**

View File

@ -37,6 +37,7 @@ ecma_object_t *ecma_get_global_scope (ecma_object_t *global_object_p);
#if JERRY_ESNEXT
void ecma_create_global_lexical_block (ecma_object_t *global_object_p);
#endif /* JERRY_ESNEXT */
ecma_value_t ecma_op_raise_set_binding_error (ecma_property_t *property_p, bool is_strict);
#if JERRY_MODULE_SYSTEM
void ecma_module_add_lex_env (ecma_object_t *lex_env_p);

View File

@ -425,12 +425,33 @@ ecma_op_general_object_define_own_property (ecma_object_t *object_p, /**< the ob
if (ECMA_PROPERTY_IS_VIRTUAL (current_prop))
{
bool writable_check_failed = (property_desc_p->flags & ECMA_PROP_IS_WRITABLE);
#if JERRY_MODULE_SYSTEM
if (ecma_object_class_is (object_p, ECMA_OBJECT_CLASS_MODULE_NAMESPACE))
{
if (JERRY_UNLIKELY (ext_property_ref.property_ref.virtual_value == ECMA_VALUE_UNINITIALIZED))
{
return ecma_raise_reference_error (ECMA_ERR_MSG (ecma_error_let_const_not_initialized));
}
if (property_desc_p->flags & ECMA_PROP_IS_WRITABLE_DEFINED)
{
writable_check_failed = ((property_desc_p->flags ^ current_prop) & ECMA_PROP_IS_WRITABLE) != 0;
}
}
else
{
JERRY_ASSERT (!is_current_configurable && !ecma_is_property_writable (current_prop));
}
#else /* !JERRY_MODULE_SYSTEM */
JERRY_ASSERT (!is_current_configurable && !ecma_is_property_writable (current_prop));
#endif /* JERRY_MODULE_SYSTEM */
ecma_value_t result = ECMA_VALUE_TRUE;
if (property_desc_type == ECMA_OP_OBJECT_DEFINE_ACCESSOR
|| (property_desc_p->flags & ECMA_PROP_IS_WRITABLE)
|| writable_check_failed
|| ((property_desc_p->flags & ECMA_PROP_IS_VALUE_DEFINED)
&& !ecma_op_same_value (property_desc_p->value,
ext_property_ref.property_ref.virtual_value)))

View File

@ -183,6 +183,59 @@ ecma_op_object_get_own_property (ecma_object_t *object_p, /**< the object */
break;
}
#endif /* JERRY_BUILTIN_TYPEDARRAY */
#if JERRY_MODULE_SYSTEM
case ECMA_OBJECT_CLASS_MODULE_NAMESPACE:
{
if (JERRY_UNLIKELY (ecma_prop_name_is_symbol (property_name_p)))
{
if (!ecma_op_compare_string_to_global_symbol (property_name_p, LIT_GLOBAL_SYMBOL_TO_STRING_TAG))
{
return ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP;
}
/* ECMA-262 v11, 26.3.1 */
if (options & ECMA_PROPERTY_GET_VALUE)
{
property_ref_p->virtual_value = ecma_make_magic_string_value (LIT_MAGIC_STRING_MODULE_UL);
}
return ECMA_PROPERTY_VIRTUAL;
}
ecma_property_t *property_p = ecma_find_named_property (object_p, property_name_p);
if (property_p == NULL)
{
return ECMA_PROPERTY_TYPE_NOT_FOUND_AND_STOP;
}
JERRY_ASSERT (ECMA_PROPERTY_IS_RAW (*property_p));
if (*property_p & ECMA_PROPERTY_FLAG_DATA)
{
if (options & ECMA_PROPERTY_GET_EXT_REFERENCE)
{
((ecma_extended_property_ref_t *) property_ref_p)->property_p = property_p;
}
if (property_ref_p != NULL)
{
property_ref_p->value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
}
return *property_p;
}
if (options & ECMA_PROPERTY_GET_VALUE)
{
ecma_property_value_t *prop_value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
prop_value_p = ecma_get_property_value_from_named_reference (prop_value_p);
property_ref_p->virtual_value = ecma_fast_copy_value (prop_value_p->value);
}
return ECMA_PROPERTY_ENUMERABLE_WRITABLE | ECMA_PROPERTY_VIRTUAL;
}
#endif /* JERRY_MODULE_SYSTEM */
}
break;
}
@ -538,6 +591,44 @@ ecma_op_object_find_own (ecma_value_t base_value, /**< base value */
break;
}
#endif /* JERRY_BUILTIN_TYPEDARRAY */
#if JERRY_MODULE_SYSTEM
case ECMA_OBJECT_CLASS_MODULE_NAMESPACE:
{
if (JERRY_UNLIKELY (ecma_prop_name_is_symbol (property_name_p)))
{
/* ECMA-262 v11, 26.3.1 */
if (ecma_op_compare_string_to_global_symbol (property_name_p, LIT_GLOBAL_SYMBOL_TO_STRING_TAG))
{
return ecma_make_magic_string_value (LIT_MAGIC_STRING_MODULE_UL);
}
return ECMA_VALUE_NOT_FOUND;
}
ecma_property_t *property_p = ecma_find_named_property (object_p, property_name_p);
if (property_p == NULL)
{
return ECMA_VALUE_NOT_FOUND;
}
JERRY_ASSERT (ECMA_PROPERTY_IS_RAW (*property_p));
ecma_property_value_t *prop_value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
if (!(*property_p & ECMA_PROPERTY_FLAG_DATA))
{
prop_value_p = ecma_get_property_value_from_named_reference (prop_value_p);
if (JERRY_UNLIKELY (prop_value_p->value == ECMA_VALUE_UNINITIALIZED))
{
return ecma_raise_reference_error (ECMA_ERR_MSG (ecma_error_let_const_not_initialized));
}
}
return ecma_fast_copy_value (prop_value_p->value);
}
#endif /* JERRY_MODULE_SYSTEM */
}
break;
}
@ -940,6 +1031,25 @@ ecma_op_get_global_symbol (lit_magic_string_id_t property_id) /**< property symb
return symbol_p;
} /* ecma_op_get_global_symbol */
/**
* Checks whether the string equals to the global symbol.
*
* @return true - if the string equals to the global symbol
* false - otherwise
*/
bool
ecma_op_compare_string_to_global_symbol (ecma_string_t *string_p, /**< string to compare */
lit_magic_string_id_t property_id) /**< property symbol id */
{
JERRY_ASSERT (LIT_IS_GLOBAL_SYMBOL (property_id));
uint32_t symbol_index = (uint32_t) property_id - (uint32_t) LIT_GLOBAL_SYMBOL__FIRST;
jmem_cpointer_t symbol_cp = JERRY_CONTEXT (global_symbols_cp)[symbol_index];
return (symbol_cp != JMEM_CP_NULL
&& string_p == ECMA_GET_NON_NULL_POINTER (ecma_string_t, symbol_cp));
} /* ecma_op_compare_string_to_global_symbol */
/**
* [[Get]] operation of ecma object where the property is a well-known symbol
*
@ -1327,6 +1437,12 @@ ecma_op_object_put_with_receiver (ecma_object_t *object_p, /**< the object */
break;
}
#endif /* JERRY_BUILTIN_TYPEDARRAY */
#if JERRY_MODULE_SYSTEM
case ECMA_OBJECT_CLASS_MODULE_NAMESPACE:
{
return ecma_raise_readonly_assignment (property_name_p, is_throw);
}
#endif /* JERRY_MODULE_SYSTEM */
}
break;
}
@ -1837,6 +1953,12 @@ ecma_op_object_get_own_property_descriptor (ecma_object_t *object_p, /**< the ob
}
else
{
#if JERRY_MODULE_SYSTEM
if (JERRY_UNLIKELY (property_ref.virtual_value == ECMA_VALUE_UNINITIALIZED))
{
return ecma_raise_reference_error (ECMA_ERR_MSG (ecma_error_let_const_not_initialized));
}
#endif /* JERRY_MODULE_SYSTEM */
prop_desc_p->value = property_ref.virtual_value;
}
@ -2685,6 +2807,9 @@ static const uint16_t ecma_class_object_magic_string_id[] =
#if JERRY_BUILTIN_TYPEDARRAY
LIT_MAGIC_STRING__EMPTY, /**< ECMA_OBJECT_CLASS_TYPEDARRAY needs special resolver */
#endif /* JERRY_BUILTIN_TYPEDARRAY */
#if JERRY_MODULE_SYSTEM
LIT_MAGIC_STRING_MODULE_UL, /**< magic string id of ECMA_OBJECT_CLASS_MODULE_NAMESPACE */
#endif
/* These objects are marked by Garbage Collector. */
#if JERRY_ESNEXT
@ -2887,29 +3012,6 @@ ecma_object_get_class_name (ecma_object_t *obj_p) /**< object */
}
} /* ecma_object_get_class_name */
/**
* Get value of an object if the class matches
*
* @return value of the object if the class matches
* ECMA_VALUE_NOT_FOUND otherwise
*/
extern inline bool JERRY_ATTR_ALWAYS_INLINE
ecma_object_class_is (ecma_object_t *object_p, /**< object */
ecma_object_class_type_t class_id) /**< class id */
{
if (ecma_get_object_type (object_p) == ECMA_OBJECT_TYPE_CLASS)
{
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
if (ext_object_p->u.cls.type == (uint8_t) class_id)
{
return true;
}
}
return false;
} /* ecma_object_class_is */
#if JERRY_BUILTIN_REGEXP
/**
* Checks if the given argument has [[RegExpMatcher]] internal slot

View File

@ -71,6 +71,7 @@ ecma_value_t ecma_op_object_get_by_index (ecma_object_t *object_p, ecma_length_t
ecma_value_t ecma_op_object_get_by_magic_id (ecma_object_t *object_p, lit_magic_string_id_t property_id);
#if JERRY_ESNEXT
ecma_string_t *ecma_op_get_global_symbol (lit_magic_string_id_t property_id);
bool ecma_op_compare_string_to_global_symbol (ecma_string_t *string_p, lit_magic_string_id_t property_id);
ecma_value_t ecma_op_object_get_by_symbol_id (ecma_object_t *object_p, lit_magic_string_id_t property_id);
ecma_value_t ecma_op_get_method_by_symbol_id (ecma_value_t value, lit_magic_string_id_t symbol_id);
ecma_value_t ecma_op_get_method_by_magic_id (ecma_value_t value, lit_magic_string_id_t magic_id);
@ -100,7 +101,6 @@ ecma_collection_t *ecma_op_object_own_property_keys (ecma_object_t *obj_p);
ecma_collection_t *ecma_op_object_enumerate (ecma_object_t *obj_p);
lit_magic_string_id_t ecma_object_get_class_name (ecma_object_t *obj_p);
bool ecma_object_class_is (ecma_object_t *object_p, ecma_object_class_type_t class_id);
#if JERRY_BUILTIN_REGEXP
bool ecma_object_is_regexp_object (ecma_value_t arg);
#endif /* JERRY_BUILTIN_REGEXP */

View File

@ -47,14 +47,6 @@ ecma_op_resolve_reference_base (ecma_object_t *lex_env_p, /**< starting lexical
while (true)
{
#if JERRY_ESNEXT
if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_HOME_OBJECT_BOUND)
{
JERRY_ASSERT (lex_env_p->u2.outer_reference_cp != JMEM_CP_NULL);
lex_env_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u2.outer_reference_cp);
}
#endif /* JERRY_ESNEXT */
ecma_value_t has_binding = ecma_op_has_binding (lex_env_p, name_p);
#if JERRY_BUILTIN_PROXY
@ -114,11 +106,12 @@ ecma_op_is_global_environment (ecma_object_t *lex_env_p) /**< lexical environmen
ecma_value_t
ecma_op_resolve_super_base (ecma_object_t *lex_env_p) /**< starting lexical environment */
{
JERRY_ASSERT (lex_env_p != NULL);
while (true)
{
if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_HOME_OBJECT_BOUND)
JERRY_ASSERT (lex_env_p != NULL);
if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_CLASS
&& (lex_env_p->type_flags_refs & ECMA_OBJECT_FLAG_LEXICAL_ENV_HAS_DATA) == 0)
{
ecma_object_t *home_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, lex_env_p->u1.home_object_cp);
@ -297,82 +290,109 @@ ecma_op_resolve_reference_value (ecma_object_t *lex_env_p, /**< starting lexical
while (true)
{
ecma_lexical_environment_type_t lex_env_type = ecma_get_lex_env_type (lex_env_p);
if (lex_env_type == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
switch (ecma_get_lex_env_type (lex_env_p))
{
ecma_property_t *property_p = ecma_find_named_property (lex_env_p, name_p);
if (property_p != NULL)
case ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE:
{
ecma_property_t *property_p = ecma_find_named_property (lex_env_p, name_p);
if (property_p == NULL)
{
break;
}
ecma_property_value_t *property_value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
#if JERRY_ESNEXT
if (JERRY_UNLIKELY (property_value_p->value == ECMA_VALUE_UNINITIALIZED))
{
return ecma_raise_reference_error (ECMA_ERR_MSG ("Variables declared by let/const must be"
" initialized before reading their value"));
return ecma_raise_reference_error (ECMA_ERR_MSG (ecma_error_let_const_not_initialized));
}
#endif /* JERRY_ESNEXT */
return ecma_fast_copy_value (property_value_p->value);
}
}
else if (lex_env_type == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND)
{
#if JERRY_ESNEXT
bool lcache_lookup_allowed = ecma_op_is_global_environment (lex_env_p);
#else /* !JERRY_ESNEXT*/
bool lcache_lookup_allowed = true;
#endif /* JERRY_ESNEXT */
if (lcache_lookup_allowed)
case ECMA_LEXICAL_ENVIRONMENT_CLASS:
{
#if JERRY_LCACHE
ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
ecma_property_t *property_p = ecma_lcache_lookup (binding_obj_p, name_p);
if (property_p != NULL)
#if JERRY_MODULE_SYSTEM
if (lex_env_p->type_flags_refs & ECMA_OBJECT_FLAG_LEXICAL_ENV_HAS_DATA)
{
JERRY_ASSERT (ECMA_PROPERTY_IS_RAW (*property_p));
ecma_property_t *property_p = ecma_find_named_property (lex_env_p, name_p);
ecma_property_value_t *prop_value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
if (*property_p & ECMA_PROPERTY_FLAG_DATA)
if (property_p == NULL)
{
return ecma_fast_copy_value (prop_value_p->value);
break;
}
ecma_getter_setter_pointers_t *get_set_pair_p = ecma_get_named_accessor_property (prop_value_p);
ecma_property_value_t *property_value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
if (get_set_pair_p->getter_cp == JMEM_CP_NULL)
if (!(*property_p & ECMA_PROPERTY_FLAG_DATA))
{
return ECMA_VALUE_UNDEFINED;
property_value_p = ecma_get_property_value_from_named_reference (property_value_p);
}
ecma_object_t *getter_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, get_set_pair_p->getter_cp);
if (JERRY_UNLIKELY (property_value_p->value == ECMA_VALUE_UNINITIALIZED))
{
return ecma_raise_reference_error (ECMA_ERR_MSG (ecma_error_let_const_not_initialized));
}
ecma_value_t base_value = ecma_make_object_value (binding_obj_p);
return ecma_op_function_call (getter_p, base_value, NULL, 0);
return ecma_fast_copy_value (property_value_p->value);
}
#endif /* JERRY_LCACHE */
#endif /* JERRY_MODULE_SYSTEM */
break;
}
ecma_value_t result = ecma_op_object_bound_environment_resolve_reference_value (lex_env_p, name_p);
if (ecma_is_value_found (result))
{
/* Note: the result may contains ECMA_VALUE_ERROR */
return result;
}
}
else
{
#if JERRY_ESNEXT
JERRY_ASSERT (lex_env_type == ECMA_LEXICAL_ENVIRONMENT_HOME_OBJECT_BOUND);
#else /* !JERRY_ESNEXT */
JERRY_UNREACHABLE ();
#endif /* JERRY_ESNEXT */
default:
{
JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
#if JERRY_ESNEXT
bool lcache_lookup_allowed = ecma_op_is_global_environment (lex_env_p);
#else /* !JERRY_ESNEXT*/
bool lcache_lookup_allowed = true;
#endif /* JERRY_ESNEXT */
if (lcache_lookup_allowed)
{
#if JERRY_LCACHE
ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
ecma_property_t *property_p = ecma_lcache_lookup (binding_obj_p, name_p);
if (property_p != NULL)
{
JERRY_ASSERT (ECMA_PROPERTY_IS_RAW (*property_p));
ecma_property_value_t *prop_value_p = ECMA_PROPERTY_VALUE_PTR (property_p);
if (*property_p & ECMA_PROPERTY_FLAG_DATA)
{
return ecma_fast_copy_value (prop_value_p->value);
}
ecma_getter_setter_pointers_t *get_set_pair_p = ecma_get_named_accessor_property (prop_value_p);
if (get_set_pair_p->getter_cp == JMEM_CP_NULL)
{
return ECMA_VALUE_UNDEFINED;
}
ecma_object_t *getter_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t, get_set_pair_p->getter_cp);
ecma_value_t base_value = ecma_make_object_value (binding_obj_p);
return ecma_op_function_call (getter_p, base_value, NULL, 0);
}
#endif /* JERRY_LCACHE */
}
ecma_value_t result = ecma_op_object_bound_environment_resolve_reference_value (lex_env_p, name_p);
if (ecma_is_value_found (result))
{
/* Note: the result may contains ECMA_VALUE_ERROR */
return result;
}
break;
}
}
if (lex_env_p->u2.outer_reference_cp == JMEM_CP_NULL)

View File

@ -1979,7 +1979,13 @@ parser_parse_source (const uint8_t *arg_list_p, /**< function argument list */
#if JERRY_MODULE_SYSTEM
else if (parse_opts & ECMA_PARSE_MODULE)
{
parser_branch_t branch;
parser_emit_cbc_forward_branch (&context, CBC_JUMP_FORWARD, &branch);
scanner_create_variables (&context, SCANNER_CREATE_VARS_NO_OPTS);
parser_emit_cbc (&context, CBC_RETURN_WITH_BLOCK);
parser_set_branch_to_current_position (&context, &branch);
}
#endif /* JERRY_MODULE_SYSTEM */
else

View File

@ -1307,9 +1307,8 @@ opfunc_init_class (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
if (ecma_get_object_type (ctor_p) == ECMA_OBJECT_TYPE_FUNCTION)
{
ecma_object_t *proto_env_p = ecma_create_object_lex_env (frame_ctx_p->lex_env_p,
proto_p,
ECMA_LEXICAL_ENVIRONMENT_HOME_OBJECT_BOUND);
ecma_object_t *proto_env_p = ecma_create_lex_env_class (frame_ctx_p->lex_env_p, 0);
ECMA_SET_NON_NULL_POINTER (proto_env_p->u1.bound_object_cp, proto_p);
ECMA_SET_NON_NULL_POINTER_TAG (((ecma_extended_object_t *) ctor_p)->u.function.scope_cp, proto_env_p, 0);
@ -1433,12 +1432,10 @@ opfunc_finalize_class (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
ecma_op_initialize_binding (class_env_p, ecma_get_string_from_value (class_name), stack_top_p[-2]);
}
ecma_object_t *ctor_env_p = ecma_create_object_lex_env (class_env_p,
ctor_p,
ECMA_LEXICAL_ENVIRONMENT_HOME_OBJECT_BOUND);
ecma_object_t *proto_env_p = ecma_create_object_lex_env (class_env_p,
proto_p,
ECMA_LEXICAL_ENVIRONMENT_HOME_OBJECT_BOUND);
ecma_object_t *ctor_env_p = ecma_create_lex_env_class (class_env_p, 0);
ECMA_SET_NON_NULL_POINTER (ctor_env_p->u1.bound_object_cp, ctor_p);
ecma_object_t *proto_env_p = ecma_create_lex_env_class (class_env_p, 0);
ECMA_SET_NON_NULL_POINTER (proto_env_p->u1.bound_object_cp, proto_p);
opfunc_set_class_attributes (ctor_p, ctor_env_p);
opfunc_set_class_attributes (proto_p, proto_env_p);

View File

@ -262,33 +262,6 @@ static const uint16_t vm_decode_table[] JERRY_ATTR_CONST_DATA =
#undef CBC_OPCODE
#if JERRY_MODULE_SYSTEM
/**
* Run module code
*
* Note:
* returned value must be freed with ecma_free_value, when it is no longer needed.
*
* @return ecma value
*/
ecma_value_t
vm_run_module (ecma_module_t *module_p) /**< module to be executed */
{
const ecma_value_t module_init_result = ecma_module_initialize (module_p);
if (ECMA_IS_VALUE_ERROR (module_init_result))
{
return module_init_result;
}
vm_frame_ctx_shared_t shared;
shared.bytecode_header_p = module_p->compiled_code_p;
shared.status_flags = 0;
return vm_run (&shared, ECMA_VALUE_UNDEFINED, module_p->scope_p);
} /* vm_run_module */
#endif /* JERRY_MODULE_SYSTEM */
/**
* Run global code
*
@ -432,6 +405,35 @@ vm_run_eval (ecma_compiled_code_t *bytecode_data_p, /**< byte-code data */
return completion_value;
} /* vm_run_eval */
#if JERRY_MODULE_SYSTEM
/**
* Run module code
*
* Note:
* returned value must be freed with ecma_free_value, when it is no longer needed.
*
* @return ecma value
*/
ecma_value_t
vm_run_module (ecma_module_t *module_p) /**< module to be executed */
{
const ecma_value_t module_init_result = ecma_module_initialize (module_p);
if (ECMA_IS_VALUE_ERROR (module_init_result))
{
return module_init_result;
}
vm_frame_ctx_shared_t shared;
shared.bytecode_header_p = module_p->compiled_code_p;
shared.status_flags = 0;
return vm_run (&shared, ECMA_VALUE_UNDEFINED, module_p->scope_p);
} /* vm_run_module */
#endif /* JERRY_MODULE_SYSTEM */
/**
* Construct object
*
@ -1578,12 +1580,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
{
uint32_t literal_index, value_index;
ecma_value_t lit_value;
bool release = false;
READ_LITERAL_INDEX (value_index);
READ_LITERAL_INDEX (literal_index);
JERRY_ASSERT (value_index != literal_index);
JERRY_ASSERT (value_index >= register_end || literal_index >= register_end);
if (value_index < register_end)
{
@ -1594,11 +1593,18 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
{
lit_value = vm_construct_literal_object (frame_ctx_p,
literal_start_p[value_index]);
release = true;
}
READ_LITERAL_INDEX (literal_index);
JERRY_ASSERT (value_index != literal_index);
JERRY_ASSERT (value_index >= register_end || literal_index >= register_end);
if (literal_index < register_end)
{
ecma_fast_free_value (VM_GET_REGISTER (frame_ctx_p, literal_index));
JERRY_ASSERT (release);
VM_GET_REGISTER (frame_ctx_p, literal_index) = lit_value;
continue;
}
@ -1617,11 +1623,10 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
JERRY_ASSERT (property_value_p->value == ECMA_VALUE_UNDEFINED);
property_value_p->value = lit_value;
if (value_index >= register_end)
if (release)
{
ecma_free_value (lit_value);
ecma_deref_object (ecma_get_object_from_value (lit_value));
}
continue;
}
#if JERRY_ESNEXT
@ -1701,12 +1706,16 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
READ_LITERAL_INDEX (literal_index);
JERRY_ASSERT (literal_index >= register_end);
JERRY_ASSERT (ecma_get_lex_env_type (frame_ctx_p->lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE);
JERRY_ASSERT (ecma_get_lex_env_type (frame_ctx_p->lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE
|| (ecma_get_lex_env_type (frame_ctx_p->lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_CLASS
&& (frame_ctx_p->lex_env_p->type_flags_refs & ECMA_OBJECT_FLAG_LEXICAL_ENV_HAS_DATA)));
ecma_string_t *name_p = ecma_get_string_from_value (literal_start_p[literal_index]);
ecma_property_t *property_p = ecma_find_named_property (frame_ctx_p->lex_env_p, name_p);
JERRY_ASSERT (property_p != NULL && ECMA_PROPERTY_IS_RAW_DATA (*property_p));
JERRY_ASSERT (property_p != NULL
&& ECMA_PROPERTY_IS_RAW_DATA (*property_p)
&& (*property_p & ECMA_PROPERTY_FLAG_DATA));
JERRY_ASSERT (ECMA_PROPERTY_VALUE_PTR (property_p)->value == ECMA_VALUE_UNINITIALIZED);
ECMA_PROPERTY_VALUE_PTR (property_p)->value = left_value;
@ -2176,10 +2185,9 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
if (opcode == CBC_EXT_PUSH_OBJECT_SUPER_ENVIRONMENT)
{
ecma_value_t obj_value = stack_top_p[-1];
ecma_object_t *obj_env_p = ecma_create_object_lex_env (frame_ctx_p->lex_env_p,
ecma_get_object_from_value (obj_value),
ECMA_LEXICAL_ENVIRONMENT_HOME_OBJECT_BOUND);
ecma_object_t *obj_env_p = ecma_create_lex_env_class (frame_ctx_p->lex_env_p, 0);
ECMA_SET_NON_NULL_POINTER (obj_env_p->u1.bound_object_cp, ecma_get_object_from_value (obj_value));
stack_top_p[-1] = ecma_make_object_value (obj_env_p);
*stack_top_p++ = obj_value;
}
@ -4029,9 +4037,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
object_p = ecma_get_object_from_value (result);
with_env_p = ecma_create_object_lex_env (frame_ctx_p->lex_env_p,
object_p,
ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
with_env_p = ecma_create_object_lex_env (frame_ctx_p->lex_env_p, object_p);
ecma_deref_object (object_p);
VM_PLUS_EQUAL_U16 (frame_ctx_p->context_depth, PARSER_WITH_CONTEXT_STACK_ALLOCATION);
@ -4914,6 +4920,172 @@ finish:
}
} /* vm_loop */
#if JERRY_MODULE_SYSTEM
/**
* Create and initialize module scope with all data properties
*
* @return ECMA_VALUE_EMPTY on success,
* ECMA_VALUE_ERROR on failure
*/
ecma_value_t
vm_init_module_scope (ecma_module_t *module_p) /**< module without scope */
{
ecma_object_t *global_object_p;
#if JERRY_BUILTIN_REALMS
global_object_p = (ecma_object_t *) ecma_op_function_get_realm (module_p->compiled_code_p);
#else /* !JERRY_BUILTIN_REALMS */
global_object_p = ecma_builtin_get_global ();
#endif /* JERRY_BUILTIN_REALMS */
ecma_object_t *scope_p = ecma_create_lex_env_class (ecma_get_global_environment (global_object_p),
sizeof (ecma_lexical_environment_class_t));
const ecma_compiled_code_t *compiled_code_p = module_p->compiled_code_p;
ecma_value_t *literal_start_p;
uint8_t *byte_code_p;
uint16_t encoding_limit;
uint16_t encoding_delta;
((ecma_lexical_environment_class_t *) scope_p)->module_p = (ecma_object_t *) module_p;
module_p->scope_p = scope_p;
ecma_deref_object (scope_p);
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
{
cbc_uint16_arguments_t *args_p = (cbc_uint16_arguments_t *) compiled_code_p;
literal_start_p = (ecma_value_t *) (args_p + 1);
literal_start_p -= args_p->register_end;
byte_code_p = (uint8_t *) (literal_start_p + args_p->literal_end);
}
else
{
cbc_uint8_arguments_t *args_p = (cbc_uint8_arguments_t *) compiled_code_p;
literal_start_p = (ecma_value_t *) (args_p + 1);
literal_start_p -= args_p->register_end;
byte_code_p = (uint8_t *) (literal_start_p + args_p->literal_end);
}
/* Prepare for byte code execution. */
if (!(compiled_code_p->status_flags & CBC_CODE_FLAGS_FULL_LITERAL_ENCODING))
{
encoding_limit = CBC_SMALL_LITERAL_ENCODING_LIMIT;
encoding_delta = CBC_SMALL_LITERAL_ENCODING_DELTA;
}
else
{
encoding_limit = CBC_FULL_LITERAL_ENCODING_LIMIT;
encoding_delta = CBC_FULL_LITERAL_ENCODING_DELTA;
}
JERRY_ASSERT (*byte_code_p >= CBC_JUMP_FORWARD && *byte_code_p <= CBC_JUMP_FORWARD_3);
byte_code_p += 1 + CBC_BRANCH_OFFSET_LENGTH (*byte_code_p);
while (true)
{
uint8_t opcode = *byte_code_p++;
switch (opcode)
{
case CBC_CREATE_VAR:
case CBC_CREATE_LET:
case CBC_CREATE_CONST:
{
uint32_t literal_index;
READ_LITERAL_INDEX (literal_index);
ecma_string_t *name_p = ecma_get_string_from_value (literal_start_p[literal_index]);
JERRY_ASSERT (ecma_find_named_property (scope_p, name_p) == NULL);
uint8_t prop_attributes = ECMA_PROPERTY_FLAG_WRITABLE;
if (opcode == CBC_CREATE_LET)
{
prop_attributes = ECMA_PROPERTY_ENUMERABLE_WRITABLE;
}
else if (opcode == CBC_CREATE_CONST)
{
prop_attributes = ECMA_PROPERTY_FLAG_ENUMERABLE;
}
ecma_property_value_t *property_value_p;
property_value_p = ecma_create_named_data_property (scope_p, name_p, prop_attributes, NULL);
if (opcode != CBC_CREATE_VAR)
{
property_value_p->value = ECMA_VALUE_UNINITIALIZED;
}
break;
}
case CBC_INIT_ARG_OR_FUNC:
{
uint32_t literal_index;
READ_LITERAL_INDEX (literal_index);
ecma_compiled_code_t *function_bytecode_p;
#if JERRY_SNAPSHOT_EXEC
if (JERRY_LIKELY (!(compiled_code_p->status_flags & CBC_CODE_FLAGS_STATIC_FUNCTION)))
{
#endif /* JERRY_SNAPSHOT_EXEC */
function_bytecode_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t,
literal_start_p[literal_index]);
#if JERRY_SNAPSHOT_EXEC
}
else
{
uint8_t *byte_p = ((uint8_t *) compiled_code_p) + literal_start_p[literal_index];
function_bytecode_p = (ecma_compiled_code_t *) byte_p;
}
#endif /* JERRY_SNAPSHOT_EXEC */
JERRY_ASSERT (CBC_IS_FUNCTION (function_bytecode_p->status_flags));
ecma_object_t *function_obj_p;
if (JERRY_UNLIKELY (CBC_FUNCTION_IS_ARROW (function_bytecode_p->status_flags)))
{
function_obj_p = ecma_op_create_arrow_function_object (scope_p,
function_bytecode_p,
ECMA_VALUE_UNDEFINED);
}
else
{
function_obj_p = ecma_op_create_any_function_object (scope_p, function_bytecode_p);
}
READ_LITERAL_INDEX (literal_index);
ecma_string_t *name_p = ecma_get_string_from_value (literal_start_p[literal_index]);
JERRY_ASSERT (ecma_find_named_property (scope_p, name_p) == NULL);
ecma_property_value_t *property_value_p;
property_value_p = ecma_create_named_data_property (scope_p,
name_p,
ECMA_PROPERTY_FLAG_WRITABLE,
NULL);
JERRY_ASSERT (property_value_p->value == ECMA_VALUE_UNDEFINED);
property_value_p->value = ecma_make_object_value (function_obj_p);
ecma_deref_object (function_obj_p);
break;
}
default:
{
JERRY_ASSERT (opcode == CBC_RETURN_WITH_BLOCK);
return ECMA_VALUE_EMPTY;
}
}
}
} /* vm_init_module_scope */
#endif /* JERRY_MODULE_SYSTEM */
#undef READ_LITERAL
#undef READ_LITERAL_INDEX

View File

@ -481,6 +481,7 @@ ecma_value_t vm_run_eval (ecma_compiled_code_t *bytecode_data_p, uint32_t parse_
#if JERRY_MODULE_SYSTEM
ecma_value_t vm_run_module (ecma_module_t *module_p);
ecma_value_t vm_init_module_scope (ecma_module_t *module_p);
#endif /* JERRY_MODULE_SYSTEM */
ecma_value_t vm_run (vm_frame_ctx_shared_t *shared_p, ecma_value_t this_binding_value, ecma_object_t *lex_env_p);

View File

@ -0,0 +1,38 @@
// 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.
export var a = 0
export let b = 1
function other() {
return 33.5
}
export function early() {
// This function is called before the module is executed
assert(other() === 33.5)
assert(a === undefined)
a = "X"
try {
b
assert(false)
} catch (e) {
assert(e instanceof ReferenceError)
}
}
early = "Loaded"
import * as o from "module-circular-02.mjs"

View File

@ -0,0 +1,85 @@
// 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.
import * as o from "module-circular-01.mjs"
if (o.early != "Loaded")
{
// The scope of module-circular-01.mjs is initialized and functions are usable
// However, the module script has not been executed
assert(o.a === undefined)
o.early()
assert(o.a === "X")
try {
o.b
assert(false)
} catch (e) {
assert(e instanceof ReferenceError)
}
try {
o.a = "X"
assert(false)
} catch (e) {
assert(e instanceof TypeError)
}
assert(o[Symbol.toStringTag] === "Module")
var result = Object.getOwnPropertyDescriptor(o, "a")
assert(result.value === "X")
assert(result.configurable === false)
assert(result.enumerable === true)
assert(result.writable === true)
try {
Object.getOwnPropertyDescriptor(o, "b")
assert(false)
} catch (e) {
assert(e instanceof ReferenceError)
}
result = Object.getOwnPropertyDescriptor(o, Symbol.toStringTag)
assert(result.value === "Module")
assert(result.configurable === false)
assert(result.enumerable === false)
assert(result.writable === false)
Object.defineProperty(o, "a", { value: "X" })
try {
Object.defineProperty(o, "a", { value: "Y" })
assert(false)
} catch (e) {
assert(e instanceof TypeError)
}
try {
Object.defineProperty(o, "b", { value:5 })
assert(false)
} catch (e) {
assert(e instanceof ReferenceError)
}
Object.defineProperty(o, Symbol.toStringTag, { value: "Module", writable:false })
try {
Object.defineProperty(o, Symbol.toStringTag, { writable:true })
assert(false)
} catch (e) {
assert(e instanceof TypeError)
}
}

View File

@ -0,0 +1,38 @@
// 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.
export var a = 0
export let b = 1
function other() {
return 33.5
}
export function early() {
// This function is called before the module is executed
assert(other() === 33.5)
assert(a === undefined)
a = "X"
try {
b
assert(false)
} catch (e) {
assert(e instanceof ReferenceError)
}
}
early = "Loaded"
import * as o from "module-circular-04.mjs"

View File

@ -0,0 +1,50 @@
// 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.
import {a as aa, b as bb, early} from "module-circular-03.mjs"
export var a = 5
if (early != "Loaded")
{
// The scope of module-circular-03.mjs is initialized and functions are usable
// However, the module script has not been executed
assert(aa === undefined)
early()
assert(aa === "X")
try {
bb
assert(false)
} catch (e) {
assert(e instanceof ReferenceError)
}
a = 7
try {
aa = "X"
assert(false)
} catch (e) {
assert(e instanceof TypeError)
}
try {
c = 4
assert(false)
} catch (e) {
assert(e instanceof ReferenceError)
}
}

View File

@ -17,4 +17,20 @@ import * as f from "./module-export-08.mjs";
assert (f.c === 5)
assert (f.x === 41)
assert (!Object.hasOwnProperty(f, "default"));
assert (Object.getPrototypeOf(f) === null)
try {
Object.hasOwnProperty(f, "default")
assert (false);
} catch (e) {
assert (e instanceof TypeError)
}
Object.setPrototypeOf(f, null)
try {
Object.setPrototypeOf(f, {})
assert (false);
} catch (e) {
assert (e instanceof TypeError)
}