Rework module parsing and execution (#4462)
This patch disables automatic detection of module code, and instead requires the user to explicitly specify whether to parse a source as a module or as a script. To achieve this the jerry_parse API function now takes a new option which signals that the source should be parsed as a module. JerryScript-DCO-1.0-Signed-off-by: Dániel Bátyai daniel.batyai@h-lab.eu
This commit is contained in:
+71
-8
@@ -246,10 +246,6 @@ jerry_cleanup (void)
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLED (JERRY_MODULE_SYSTEM)
|
||||
ecma_module_cleanup ();
|
||||
#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
|
||||
|
||||
#if ENABLED (JERRY_BUILTIN_PROMISE)
|
||||
ecma_free_all_enqueued_jobs ();
|
||||
#endif /* ENABLED (JERRY_BUILTIN_PROMISE) */
|
||||
@@ -456,6 +452,15 @@ jerry_parse (const jerry_char_t *resource_name_p, /**< resource name (usually a
|
||||
}
|
||||
#endif /* ENABLED (JERRY_RESOURCE_NAME) */
|
||||
|
||||
if ((parse_opts & JERRY_PARSE_MODULE) != 0)
|
||||
{
|
||||
#if ENABLED (JERRY_MODULE_SYSTEM)
|
||||
ecma_module_initialize_context (ecma_get_string_from_value (resource_name));
|
||||
#else /* !ENABLED (JERRY_MODULE_SYSTEM) */
|
||||
return jerry_throw (ecma_raise_syntax_error (ECMA_ERR_MSG ("Module system has been disabled.")));
|
||||
#endif /* !ENABLED (JERRY_MODULE_SYSTEM) */
|
||||
}
|
||||
|
||||
ecma_compiled_code_t *bytecode_data_p = parser_parse_script (NULL,
|
||||
0,
|
||||
source_p,
|
||||
@@ -465,9 +470,44 @@ jerry_parse (const jerry_char_t *resource_name_p, /**< resource name (usually a
|
||||
|
||||
if (JERRY_UNLIKELY (bytecode_data_p == NULL))
|
||||
{
|
||||
#if ENABLED (JERRY_MODULE_SYSTEM)
|
||||
if ((parse_opts & JERRY_PARSE_MODULE) != 0)
|
||||
{
|
||||
ecma_module_cleanup_context ();
|
||||
}
|
||||
#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
|
||||
|
||||
return ecma_create_error_reference_from_context ();
|
||||
}
|
||||
|
||||
#if ENABLED (JERRY_MODULE_SYSTEM)
|
||||
if ((parse_opts & JERRY_PARSE_MODULE) != 0)
|
||||
{
|
||||
if (ECMA_IS_VALUE_ERROR (ecma_module_parse_referenced_modules ()))
|
||||
{
|
||||
ecma_bytecode_deref (bytecode_data_p);
|
||||
ecma_module_cleanup_context ();
|
||||
|
||||
return ecma_create_error_reference_from_context ();
|
||||
}
|
||||
|
||||
ecma_object_t *obj_p = ecma_create_object (NULL, sizeof (ecma_extended_object_t), ECMA_OBJECT_TYPE_CLASS);
|
||||
|
||||
ecma_extended_object_t *wrapper_p = (ecma_extended_object_t *) obj_p;
|
||||
wrapper_p->u.class_prop.class_id = LIT_MAGIC_STRING_RUNNABLE_UL;
|
||||
wrapper_p->u.class_prop.extra_info = ECMA_RUNNABLE_FLAGS_MODULE;
|
||||
|
||||
ecma_module_t *root_module_p = JERRY_CONTEXT (module_current_p);
|
||||
root_module_p->compiled_code_p = bytecode_data_p;
|
||||
|
||||
ECMA_SET_INTERNAL_VALUE_POINTER (wrapper_p->u.class_prop.u.value, root_module_p);
|
||||
JERRY_CONTEXT (module_current_p) = NULL;
|
||||
JERRY_CONTEXT (module_list_p) = NULL;
|
||||
|
||||
return ecma_make_object_value (obj_p);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
|
||||
|
||||
ecma_object_t *global_object_p = ecma_builtin_get_global ();
|
||||
|
||||
#if ENABLED (JERRY_BUILTIN_REALMS)
|
||||
@@ -475,6 +515,9 @@ jerry_parse (const jerry_char_t *resource_name_p, /**< resource name (usually a
|
||||
#endif /* ENABLED (JERRY_BUILTIN_REALMS) */
|
||||
|
||||
ecma_object_t *lex_env_p = ecma_get_global_environment (global_object_p);
|
||||
|
||||
/* TODO(dbatyai): For now Scripts continue to return Function objects due to backwards compatibility. This should be
|
||||
* changed to also return a Runnable object eventually. */
|
||||
ecma_object_t *func_obj_p = ecma_op_create_simple_function_object (lex_env_p, bytecode_data_p);
|
||||
ecma_bytecode_deref (bytecode_data_p);
|
||||
|
||||
@@ -588,15 +631,35 @@ jerry_run (const jerry_value_t func_val) /**< function to run */
|
||||
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
|
||||
}
|
||||
|
||||
ecma_object_t *func_obj_p = ecma_get_object_from_value (func_val);
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (func_val);
|
||||
|
||||
if (ecma_get_object_type (func_obj_p) != ECMA_OBJECT_TYPE_FUNCTION
|
||||
|| ecma_get_object_is_builtin (func_obj_p))
|
||||
#if ENABLED (JERRY_MODULE_SYSTEM)
|
||||
if (ecma_object_class_is (obj_p, LIT_MAGIC_STRING_RUNNABLE_UL))
|
||||
{
|
||||
ecma_extended_object_t *wrapper_p = (ecma_extended_object_t *) obj_p;
|
||||
JERRY_ASSERT (wrapper_p->u.class_prop.extra_info == ECMA_RUNNABLE_FLAGS_MODULE);
|
||||
ecma_module_t *root_module_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_module_t, wrapper_p->u.class_prop.u.value);
|
||||
|
||||
#if ENABLED (JERRY_BUILTIN_REALMS)
|
||||
ecma_object_t *global_object_p = (ecma_object_t *) ecma_op_function_get_realm (root_module_p->compiled_code_p);
|
||||
#else /* !ENABLED (JERRY_BUILTIN_REALMS) */
|
||||
ecma_object_t *global_object_p = ecma_builtin_get_global ();
|
||||
#endif /* ENABLED (JERRY_BUILTIN_REALMS) */
|
||||
|
||||
ecma_create_global_lexical_block (global_object_p);
|
||||
root_module_p->scope_p = ecma_get_global_scope (global_object_p);
|
||||
|
||||
return jerry_return (vm_run_module (root_module_p));
|
||||
}
|
||||
#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
|
||||
|
||||
if (ecma_get_object_type (obj_p) != ECMA_OBJECT_TYPE_FUNCTION
|
||||
|| ecma_get_object_is_builtin (obj_p))
|
||||
{
|
||||
return jerry_throw (ecma_raise_type_error (ECMA_ERR_MSG (wrong_args_msg_p)));
|
||||
}
|
||||
|
||||
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) func_obj_p;
|
||||
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) obj_p;
|
||||
|
||||
const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p);
|
||||
|
||||
|
||||
@@ -1630,6 +1630,20 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
|
||||
break;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
#if ENABLED (JERRY_MODULE_SYSTEM)
|
||||
case LIT_MAGIC_STRING_RUNNABLE_UL:
|
||||
{
|
||||
ecma_extended_object_t *wrapper_p = (ecma_extended_object_t *) object_p;
|
||||
|
||||
JERRY_ASSERT (wrapper_p->u.class_prop.extra_info == ECMA_RUNNABLE_FLAGS_MODULE);
|
||||
ecma_module_t *root_module_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_module_t,
|
||||
wrapper_p->u.class_prop.u.value);
|
||||
|
||||
ecma_bytecode_deref (root_module_p->compiled_code_p);
|
||||
ecma_module_cleanup (root_module_p);
|
||||
break;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
|
||||
default:
|
||||
{
|
||||
/* The undefined id represents an uninitialized class. */
|
||||
|
||||
@@ -1059,6 +1059,14 @@ typedef struct
|
||||
#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) */
|
||||
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
/**
|
||||
* Flags for runnable objects.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ECMA_RUNNABLE_FLAGS_EMPTY = (0), /**< empty flags */
|
||||
ECMA_RUNNABLE_FLAGS_MODULE = (1 << 0) /**< runnable is a module */
|
||||
} ecma_runnable_flags_t;
|
||||
|
||||
/**
|
||||
* Description of arrow function objects.
|
||||
|
||||
+243
-175
@@ -37,8 +37,9 @@
|
||||
* @return pointer to ecma_string_t containing the normalized and zero terminated path
|
||||
*/
|
||||
ecma_string_t *
|
||||
ecma_module_create_normalized_path (const uint8_t *char_p, /**< module specifier */
|
||||
prop_length_t size) /**< size of module specifier */
|
||||
ecma_module_create_normalized_path (const lit_utf8_byte_t *char_p, /**< module path specifier */
|
||||
lit_utf8_size_t size, /**< size of module specifier */
|
||||
ecma_string_t *const base_path_p) /**< base path for the module specifier */
|
||||
{
|
||||
JERRY_ASSERT (size > 0);
|
||||
ecma_string_t *ret_p = NULL;
|
||||
@@ -57,16 +58,13 @@ ecma_module_create_normalized_path (const uint8_t *char_p, /**< module specifier
|
||||
lit_utf8_byte_t *module_path_p = NULL;
|
||||
lit_utf8_size_t module_path_size = 0;
|
||||
|
||||
/* Check if we have a current module, and use its path as the base path. */
|
||||
JERRY_ASSERT (JERRY_CONTEXT (module_top_context_p) != NULL);
|
||||
if (JERRY_CONTEXT (module_top_context_p)->module_p != NULL)
|
||||
if (base_path_p != NULL)
|
||||
{
|
||||
JERRY_ASSERT (JERRY_CONTEXT (module_top_context_p)->module_p->path_p != NULL);
|
||||
module_path_size = ecma_string_get_size (JERRY_CONTEXT (module_top_context_p)->module_p->path_p);
|
||||
module_path_size = ecma_string_get_size (base_path_p);
|
||||
module_path_p = (lit_utf8_byte_t *) jmem_heap_alloc_block (module_path_size + 1);
|
||||
|
||||
lit_utf8_size_t module_utf8_size;
|
||||
module_utf8_size = ecma_string_copy_to_utf8_buffer (JERRY_CONTEXT (module_top_context_p)->module_p->path_p,
|
||||
module_utf8_size = ecma_string_copy_to_utf8_buffer (base_path_p,
|
||||
module_path_p,
|
||||
module_path_size);
|
||||
|
||||
@@ -96,26 +94,39 @@ ecma_module_create_normalized_path (const uint8_t *char_p, /**< module specifier
|
||||
} /* ecma_module_create_normalized_path */
|
||||
|
||||
/**
|
||||
* Find a module with a specific identifier
|
||||
* Push a new module into the module list. New modules are inserted after the head module, this way in the end the
|
||||
* root module remains the first in the list.
|
||||
*/
|
||||
static void
|
||||
ecma_module_list_push (ecma_module_t *module_p)
|
||||
{
|
||||
ecma_module_t *head_p = JERRY_CONTEXT (module_list_p);
|
||||
module_p->next_p = head_p->next_p;
|
||||
head_p->next_p = module_p;
|
||||
} /* ecma_module_list_push */
|
||||
|
||||
/**
|
||||
* Lookup a module with a specific identifier.
|
||||
*
|
||||
* @return pointer to ecma_module_t, if found
|
||||
* NULL, otherwise
|
||||
*/
|
||||
ecma_module_t *
|
||||
ecma_module_find_module (ecma_string_t *const path_p) /**< module identifier */
|
||||
static ecma_module_t *
|
||||
ecma_module_list_lookup (ecma_string_t *const path_p) /**< module identifier */
|
||||
{
|
||||
ecma_module_t *current_p = JERRY_CONTEXT (ecma_modules_p);
|
||||
ecma_module_t *current_p = JERRY_CONTEXT (module_list_p);
|
||||
while (current_p != NULL)
|
||||
{
|
||||
if (ecma_compare_ecma_strings (path_p, current_p->path_p))
|
||||
{
|
||||
return current_p;
|
||||
}
|
||||
|
||||
current_p = current_p->next_p;
|
||||
}
|
||||
|
||||
return current_p;
|
||||
} /* ecma_module_find_module */
|
||||
return NULL;
|
||||
} /* ecma_module_list_lookup */
|
||||
|
||||
/**
|
||||
* Create a new module
|
||||
@@ -129,8 +140,7 @@ ecma_module_create_module (ecma_string_t *const path_p) /**< module identifier *
|
||||
memset (module_p, 0, sizeof (ecma_module_t));
|
||||
|
||||
module_p->path_p = path_p;
|
||||
module_p->next_p = JERRY_CONTEXT (ecma_modules_p);
|
||||
JERRY_CONTEXT (ecma_modules_p) = module_p;
|
||||
ecma_module_list_push (module_p);
|
||||
return module_p;
|
||||
} /* ecma_module_create_module */
|
||||
|
||||
@@ -140,9 +150,10 @@ ecma_module_create_module (ecma_string_t *const path_p) /**< module identifier *
|
||||
* @return pointer to found or newly created module structure
|
||||
*/
|
||||
ecma_module_t *
|
||||
ecma_module_find_or_create_module (ecma_string_t *const path_p) /**< module path */
|
||||
ecma_module_find_module (ecma_string_t *const path_p) /**< module path */
|
||||
{
|
||||
ecma_module_t *module_p = ecma_module_find_module (path_p);
|
||||
ecma_module_t *module_p = ecma_module_list_lookup (path_p);
|
||||
|
||||
if (module_p)
|
||||
{
|
||||
ecma_deref_ecma_string (path_p);
|
||||
@@ -150,7 +161,7 @@ ecma_module_find_or_create_module (ecma_string_t *const path_p) /**< module path
|
||||
}
|
||||
|
||||
return ecma_module_create_module (path_p);
|
||||
} /* ecma_module_find_or_create_module */
|
||||
} /* ecma_module_find_module */
|
||||
|
||||
/**
|
||||
* Create a new native module
|
||||
@@ -158,28 +169,83 @@ ecma_module_find_or_create_module (ecma_string_t *const path_p) /**< module path
|
||||
* @return pointer to created module
|
||||
*/
|
||||
ecma_module_t *
|
||||
ecma_module_create_native_module (ecma_string_t *const path_p, /**< module identifier */
|
||||
ecma_object_t *const namespace_p) /**< module namespace */
|
||||
ecma_module_find_native_module (ecma_string_t *const path_p)
|
||||
{
|
||||
ecma_module_t *module_p = ecma_module_create_module (path_p);
|
||||
module_p->state = ECMA_MODULE_STATE_NATIVE;
|
||||
module_p->namespace_object_p = namespace_p;
|
||||
return module_p;
|
||||
} /* ecma_module_create_native_module */
|
||||
ecma_module_t *module_p = ecma_module_list_lookup (path_p);
|
||||
|
||||
if (module_p != NULL)
|
||||
{
|
||||
return module_p;
|
||||
}
|
||||
|
||||
ecma_value_t native = jerry_port_get_native_module (ecma_make_string_value (path_p));
|
||||
|
||||
if (!ecma_is_value_undefined (native))
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_object (native));
|
||||
|
||||
module_p = ecma_module_create_module (path_p);
|
||||
module_p->state = ECMA_MODULE_STATE_NATIVE;
|
||||
module_p->namespace_object_p = ecma_get_object_from_value (native);
|
||||
|
||||
return module_p;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
} /* ecma_module_find_native_module */
|
||||
|
||||
/**
|
||||
* Creates a module context.
|
||||
*
|
||||
* @return pointer to created module context
|
||||
* Initialize context variables for the root module.
|
||||
*/
|
||||
static ecma_module_context_t *
|
||||
ecma_module_create_module_context (void)
|
||||
void
|
||||
ecma_module_initialize_context (ecma_string_t *root_path_p) /**< root module */
|
||||
{
|
||||
ecma_module_context_t *context_p = (ecma_module_context_t *) jmem_heap_alloc_block (sizeof (ecma_module_context_t));
|
||||
memset (context_p, 0, sizeof (ecma_module_context_t));
|
||||
JERRY_ASSERT (JERRY_CONTEXT (module_current_p) == NULL);
|
||||
JERRY_ASSERT (JERRY_CONTEXT (module_list_p) == NULL);
|
||||
|
||||
return context_p;
|
||||
} /* ecma_module_create_module_context */
|
||||
lit_utf8_size_t path_str_size;
|
||||
uint8_t flags = ECMA_STRING_FLAG_EMPTY;
|
||||
|
||||
const lit_utf8_byte_t *path_str_chars_p = ecma_string_get_chars (root_path_p,
|
||||
&path_str_size,
|
||||
NULL,
|
||||
NULL,
|
||||
&flags);
|
||||
|
||||
ecma_string_t *path_p = ecma_module_create_normalized_path (path_str_chars_p,
|
||||
path_str_size,
|
||||
NULL);
|
||||
|
||||
if (path_p == NULL)
|
||||
{
|
||||
ecma_ref_ecma_string (root_path_p);
|
||||
path_p = root_path_p;
|
||||
}
|
||||
|
||||
ecma_module_t *module_p = (ecma_module_t *) jmem_heap_alloc_block (sizeof (ecma_module_t));
|
||||
memset (module_p, 0, sizeof (ecma_module_t));
|
||||
|
||||
module_p->path_p = path_p;
|
||||
/* Root modules are handled differently then the rest of the referenced modules, as the scope and compiled code
|
||||
* are handled separately. */
|
||||
module_p->state = ECMA_MODULE_STATE_ROOT;
|
||||
|
||||
JERRY_CONTEXT (module_current_p) = module_p;
|
||||
JERRY_CONTEXT (module_list_p) = module_p;
|
||||
} /* ecma_module_initialize_context */
|
||||
|
||||
/**
|
||||
* cleanup context variables for the root module.
|
||||
*/
|
||||
void
|
||||
ecma_module_cleanup_context (void)
|
||||
{
|
||||
ecma_module_cleanup (JERRY_CONTEXT (module_current_p));
|
||||
#ifndef JERRY_NDEBUG
|
||||
JERRY_CONTEXT (module_current_p) = NULL;
|
||||
JERRY_CONTEXT (module_list_p) = NULL;
|
||||
#endif /* JERRY_NDEBUG */
|
||||
} /* ecma_module_cleanup_context */
|
||||
|
||||
/**
|
||||
* Inserts a {module, export_name} record into a resolve set.
|
||||
@@ -190,8 +256,8 @@ ecma_module_create_module_context (void)
|
||||
*/
|
||||
bool
|
||||
ecma_module_resolve_set_insert (ecma_module_resolve_set_t **set_p, /**< [in, out] resolve set */
|
||||
ecma_module_t * const module_p, /**< module */
|
||||
ecma_string_t * const export_name_p) /**< export name */
|
||||
ecma_module_t *const module_p, /**< module */
|
||||
ecma_string_t *const export_name_p) /**< export name */
|
||||
{
|
||||
JERRY_ASSERT (set_p != NULL);
|
||||
ecma_module_resolve_set_t *current_p = *set_p;
|
||||
@@ -283,8 +349,8 @@ ecma_module_resolve_stack_pop (ecma_module_resolve_stack_t **stack_p) /**< [in,
|
||||
* ECMA_VALUE_EMPTY - otherwise
|
||||
*/
|
||||
static ecma_value_t
|
||||
ecma_module_resolve_export (ecma_module_t * const module_p, /**< base module */
|
||||
ecma_string_t * const export_name_p, /**< export name */
|
||||
ecma_module_resolve_export (ecma_module_t *const module_p, /**< base module */
|
||||
ecma_string_t *const export_name_p, /**< export name */
|
||||
ecma_module_record_t *out_record_p) /**< [out] found module record */
|
||||
{
|
||||
ecma_module_resolve_set_t *resolve_set_p = NULL;
|
||||
@@ -302,7 +368,6 @@ ecma_module_resolve_export (ecma_module_t * const module_p, /**< base module */
|
||||
|
||||
ecma_module_t *current_module_p = current_frame_p->module_p;
|
||||
JERRY_ASSERT (current_module_p->state >= ECMA_MODULE_STATE_PARSED);
|
||||
ecma_module_context_t *context_p = current_module_p->context_p;
|
||||
ecma_string_t *current_export_name_p = current_frame_p->export_name_p;
|
||||
|
||||
if (!current_frame_p->resolving)
|
||||
@@ -341,11 +406,11 @@ ecma_module_resolve_export (ecma_module_t * const module_p, /**< base module */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (context_p->local_exports_p != NULL)
|
||||
if (current_module_p->local_exports_p != NULL)
|
||||
{
|
||||
/* 15.2.1.16.3 / 4 */
|
||||
JERRY_ASSERT (context_p->local_exports_p->next_p == NULL);
|
||||
ecma_module_names_t *export_names_p = context_p->local_exports_p->module_names_p;
|
||||
JERRY_ASSERT (current_module_p->local_exports_p->next_p == NULL);
|
||||
ecma_module_names_t *export_names_p = current_module_p->local_exports_p->module_names_p;
|
||||
while (export_names_p != NULL)
|
||||
{
|
||||
if (ecma_compare_ecma_strings (current_export_name_p, export_names_p->imex_name_p))
|
||||
@@ -377,7 +442,7 @@ ecma_module_resolve_export (ecma_module_t * const module_p, /**< base module */
|
||||
}
|
||||
|
||||
/* 15.2.1.16.3 / 5 */
|
||||
ecma_module_node_t *indirect_export_p = context_p->indirect_exports_p;
|
||||
ecma_module_node_t *indirect_export_p = current_module_p->indirect_exports_p;
|
||||
while (indirect_export_p != NULL)
|
||||
{
|
||||
ecma_module_names_t *export_names_p = indirect_export_p->module_names_p;
|
||||
@@ -389,6 +454,7 @@ ecma_module_resolve_export (ecma_module_t * const module_p, /**< base module */
|
||||
ecma_module_resolve_stack_push (&stack_p,
|
||||
indirect_export_p->module_request_p,
|
||||
export_names_p->local_name_p);
|
||||
break;
|
||||
}
|
||||
|
||||
export_names_p = export_names_p->next_p;
|
||||
@@ -432,7 +498,7 @@ ecma_module_resolve_export (ecma_module_t * const module_p, /**< base module */
|
||||
ecma_module_resolve_stack_pop (&stack_p);
|
||||
|
||||
/* 15.2.1.16.3 / 10 */
|
||||
ecma_module_node_t *star_export_p = context_p->star_exports_p;
|
||||
ecma_module_node_t *star_export_p = current_module_p->star_exports_p;
|
||||
while (star_export_p != NULL)
|
||||
{
|
||||
JERRY_ASSERT (star_export_p->module_names_p == NULL);
|
||||
@@ -493,12 +559,9 @@ ecma_module_evaluate (ecma_module_t *module_p) /**< module */
|
||||
|
||||
module_p->state = ECMA_MODULE_STATE_EVALUATING;
|
||||
module_p->scope_p = ecma_create_decl_lex_env (ecma_get_global_environment (global_object_p));
|
||||
module_p->context_p->parent_p = JERRY_CONTEXT (module_top_context_p);
|
||||
JERRY_CONTEXT (module_top_context_p) = module_p->context_p;
|
||||
|
||||
ecma_value_t ret_value;
|
||||
ret_value = vm_run_module (module_p->compiled_code_p,
|
||||
module_p->scope_p);
|
||||
ret_value = vm_run_module (module_p);
|
||||
|
||||
if (!ECMA_IS_VALUE_ERROR (ret_value))
|
||||
{
|
||||
@@ -506,10 +569,11 @@ ecma_module_evaluate (ecma_module_t *module_p) /**< module */
|
||||
ret_value = ECMA_VALUE_EMPTY;
|
||||
}
|
||||
|
||||
JERRY_CONTEXT (module_top_context_p) = module_p->context_p->parent_p;
|
||||
|
||||
ecma_bytecode_deref (module_p->compiled_code_p);
|
||||
module_p->state = ECMA_MODULE_STATE_EVALUATED;
|
||||
ecma_bytecode_deref (module_p->compiled_code_p);
|
||||
#ifndef JERRY_NDEBUG
|
||||
module_p->compiled_code_p = NULL;
|
||||
#endif /* JERRY_NDEBUG */
|
||||
|
||||
return ret_value;
|
||||
} /* ecma_module_evaluate */
|
||||
@@ -597,7 +661,6 @@ ecma_module_create_namespace_object (ecma_module_t *module_p) /**< module */
|
||||
{
|
||||
ecma_module_resolve_stack_t *current_frame_p = stack_p;
|
||||
ecma_module_t *current_module_p = current_frame_p->module_p;
|
||||
ecma_module_context_t *context_p = current_module_p->context_p;
|
||||
|
||||
ecma_module_resolve_stack_pop (&stack_p);
|
||||
|
||||
@@ -617,11 +680,11 @@ ecma_module_create_namespace_object (ecma_module_t *module_p) /**< module */
|
||||
break;
|
||||
}
|
||||
|
||||
if (context_p->local_exports_p != NULL)
|
||||
if (current_module_p->local_exports_p != NULL)
|
||||
{
|
||||
/* 15.2.1.16.2 / 5 */
|
||||
JERRY_ASSERT (context_p->local_exports_p->next_p == NULL);
|
||||
ecma_module_names_t *export_names_p = context_p->local_exports_p->module_names_p;
|
||||
JERRY_ASSERT (current_module_p->local_exports_p->next_p == NULL);
|
||||
ecma_module_names_t *export_names_p = current_module_p->local_exports_p->module_names_p;
|
||||
while (export_names_p != NULL && ecma_is_value_empty (result))
|
||||
{
|
||||
result = ecma_module_namespace_object_add_export_if_needed (module_p,
|
||||
@@ -631,7 +694,7 @@ ecma_module_create_namespace_object (ecma_module_t *module_p) /**< module */
|
||||
}
|
||||
|
||||
/* 15.2.1.16.2 / 6 */
|
||||
ecma_module_node_t *indirect_export_p = context_p->indirect_exports_p;
|
||||
ecma_module_node_t *indirect_export_p = current_module_p->indirect_exports_p;
|
||||
while (indirect_export_p != NULL && ecma_is_value_empty (result))
|
||||
{
|
||||
ecma_module_names_t *export_names_p = indirect_export_p->module_names_p;
|
||||
@@ -645,7 +708,7 @@ ecma_module_create_namespace_object (ecma_module_t *module_p) /**< module */
|
||||
}
|
||||
|
||||
/* 15.2.1.16.2 / 7 */
|
||||
ecma_module_node_t *star_export_p = context_p->star_exports_p;
|
||||
ecma_module_node_t *star_export_p = current_module_p->star_exports_p;
|
||||
while (star_export_p != NULL && ecma_is_value_empty (result))
|
||||
{
|
||||
JERRY_ASSERT (star_export_p->module_names_p == NULL);
|
||||
@@ -670,20 +733,18 @@ ecma_module_create_namespace_object (ecma_module_t *module_p) /**< module */
|
||||
} /* ecma_module_create_namespace_object */
|
||||
|
||||
/**
|
||||
* Connects imported values to the current context.
|
||||
* Connects imported values to the current module scope.
|
||||
*
|
||||
* @return ECMA_VALUE_ERROR - if an error occured
|
||||
* ECMA_VALUE_EMPTY - otherwise
|
||||
*/
|
||||
static ecma_value_t
|
||||
ecma_module_connect_imports (void)
|
||||
ecma_module_connect_imports (ecma_module_t *module_p)
|
||||
{
|
||||
ecma_module_context_t *current_context_p = JERRY_CONTEXT (module_top_context_p);
|
||||
|
||||
ecma_object_t *local_env_p = current_context_p->module_p->scope_p;
|
||||
ecma_object_t *local_env_p = module_p->scope_p;
|
||||
JERRY_ASSERT (ecma_is_lexical_environment (local_env_p));
|
||||
|
||||
ecma_module_node_t *import_node_p = current_context_p->imports_p;
|
||||
ecma_module_node_t *import_node_p = module_p->imports_p;
|
||||
|
||||
/* Check that the imported bindings don't exist yet. */
|
||||
while (import_node_p != NULL)
|
||||
@@ -728,7 +789,7 @@ ecma_module_connect_imports (void)
|
||||
import_node_p = import_node_p->next_p;
|
||||
}
|
||||
|
||||
import_node_p = current_context_p->imports_p;
|
||||
import_node_p = module_p->imports_p;
|
||||
|
||||
/* Resolve imports and create local bindings. */
|
||||
while (import_node_p != NULL)
|
||||
@@ -823,6 +884,48 @@ ecma_module_connect_imports (void)
|
||||
return ECMA_VALUE_EMPTY;
|
||||
} /* ecma_module_connect_imports */
|
||||
|
||||
/**
|
||||
* Checks if indirect exports in the current context are resolvable.
|
||||
* Note: See 15.2.1.16.4 / 9.
|
||||
*
|
||||
* @return ECMA_VALUE_ERROR - if an error occured
|
||||
* ECMA_VALUE_EMPTY - otherwise
|
||||
*/
|
||||
static ecma_value_t
|
||||
ecma_module_check_indirect_exports (ecma_module_t *module_p)
|
||||
{
|
||||
ecma_module_node_t *indirect_export_p = module_p->indirect_exports_p;
|
||||
while (indirect_export_p != NULL)
|
||||
{
|
||||
ecma_module_names_t *name_p = indirect_export_p->module_names_p;
|
||||
while (name_p != NULL)
|
||||
{
|
||||
ecma_module_record_t record;
|
||||
ecma_value_t result = ecma_module_resolve_export (indirect_export_p->module_request_p,
|
||||
name_p->local_name_p,
|
||||
&record);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_empty (result));
|
||||
|
||||
if (record.module_p == NULL)
|
||||
{
|
||||
return ecma_raise_syntax_error (ECMA_ERR_MSG ("Ambiguous indirect export request."));
|
||||
}
|
||||
|
||||
name_p = name_p->next_p;
|
||||
}
|
||||
|
||||
indirect_export_p = indirect_export_p->next_p;
|
||||
}
|
||||
|
||||
return ECMA_VALUE_EMPTY;
|
||||
} /* ecma_module_check_indirect_exports */
|
||||
|
||||
/**
|
||||
* Initialize the current module by creating the local binding for the imported variables
|
||||
* and verifying indirect exports.
|
||||
@@ -831,17 +934,42 @@ ecma_module_connect_imports (void)
|
||||
* ECMA_VALUE_EMPTY - otherwise
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_module_initialize_current (void)
|
||||
ecma_module_initialize (ecma_module_t *module_p) /**< module */
|
||||
{
|
||||
ecma_value_t ret_value = ecma_module_connect_imports ();
|
||||
ecma_value_t ret_value = ecma_module_connect_imports (module_p);
|
||||
|
||||
if (ecma_is_value_empty (ret_value))
|
||||
{
|
||||
ret_value = ecma_module_check_indirect_exports ();
|
||||
ret_value = ecma_module_check_indirect_exports (module_p);
|
||||
}
|
||||
|
||||
return ret_value;
|
||||
} /* ecma_module_initialize_current */
|
||||
} /* ecma_module_initialize */
|
||||
|
||||
static ecma_value_t ecma_module_parse (ecma_module_t *module_p);
|
||||
|
||||
/**
|
||||
* Parses all referenced modules.
|
||||
*
|
||||
* @return ECMA_VALUE_ERROR - if an error occured
|
||||
* ECMA_VALUE_EMPTY - otherwise
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_module_parse_referenced_modules (void)
|
||||
{
|
||||
ecma_module_t *current_p = JERRY_CONTEXT (module_list_p);
|
||||
while (current_p != NULL)
|
||||
{
|
||||
if (ECMA_IS_VALUE_ERROR (ecma_module_parse (current_p)))
|
||||
{
|
||||
return ECMA_VALUE_ERROR;
|
||||
}
|
||||
|
||||
current_p = current_p->next_p;
|
||||
}
|
||||
|
||||
return ECMA_VALUE_EMPTY;
|
||||
} /* ecma_module_parse_referenced_modules */
|
||||
|
||||
/**
|
||||
* Parses an EcmaScript module.
|
||||
@@ -849,7 +977,7 @@ ecma_module_initialize_current (void)
|
||||
* @return ECMA_VALUE_ERROR - if an error occured
|
||||
* ECMA_VALUE_EMPTY - otherwise
|
||||
*/
|
||||
static jerry_value_t
|
||||
static ecma_value_t
|
||||
ecma_module_parse (ecma_module_t *module_p) /**< module */
|
||||
{
|
||||
if (module_p->state >= ECMA_MODULE_STATE_PARSING)
|
||||
@@ -858,7 +986,6 @@ ecma_module_parse (ecma_module_t *module_p) /**< module */
|
||||
}
|
||||
|
||||
module_p->state = ECMA_MODULE_STATE_PARSING;
|
||||
module_p->context_p = ecma_module_create_module_context ();
|
||||
|
||||
lit_utf8_size_t module_path_size = ecma_string_get_size (module_p->path_p);
|
||||
lit_utf8_byte_t *module_path_p = (lit_utf8_byte_t *) jmem_heap_alloc_block (module_path_size + 1);
|
||||
@@ -878,9 +1005,8 @@ ecma_module_parse (ecma_module_t *module_p) /**< module */
|
||||
return ecma_raise_syntax_error (ECMA_ERR_MSG ("File not found."));
|
||||
}
|
||||
|
||||
module_p->context_p->module_p = module_p;
|
||||
module_p->context_p->parent_p = JERRY_CONTEXT (module_top_context_p);
|
||||
JERRY_CONTEXT (module_top_context_p) = module_p->context_p;
|
||||
ecma_module_t *prev_module_p = JERRY_CONTEXT (module_current_p);
|
||||
JERRY_CONTEXT (module_current_p) = module_p;
|
||||
|
||||
#if ENABLED (JERRY_DEBUGGER) && ENABLED (JERRY_PARSER)
|
||||
if (JERRY_CONTEXT (debugger_flags) & JERRY_DEBUGGER_CONNECTED)
|
||||
@@ -899,8 +1025,7 @@ ecma_module_parse (ecma_module_t *module_p) /**< module */
|
||||
ecma_make_string_value (module_p->path_p),
|
||||
ECMA_PARSE_STRICT_MODE | ECMA_PARSE_MODULE);
|
||||
|
||||
JERRY_CONTEXT (module_top_context_p) = module_p->context_p->parent_p;
|
||||
|
||||
JERRY_CONTEXT (module_current_p) = prev_module_p;
|
||||
jerry_port_release_source (source_p);
|
||||
|
||||
if (JERRY_UNLIKELY (bytecode_p == NULL))
|
||||
@@ -908,78 +1033,18 @@ ecma_module_parse (ecma_module_t *module_p) /**< module */
|
||||
return ECMA_VALUE_ERROR;
|
||||
}
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (ecma_module_parse_referenced_modules ()))
|
||||
{
|
||||
ecma_bytecode_deref (bytecode_p);
|
||||
return ECMA_VALUE_ERROR;
|
||||
}
|
||||
|
||||
module_p->compiled_code_p = bytecode_p;
|
||||
module_p->state = ECMA_MODULE_STATE_PARSED;
|
||||
|
||||
return ECMA_VALUE_EMPTY;
|
||||
} /* ecma_module_parse */
|
||||
|
||||
/**
|
||||
* Parses all referenced modules.
|
||||
*
|
||||
* @return ECMA_VALUE_ERROR - if an error occured
|
||||
* ECMA_VALUE_EMPTY - otherwise
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_module_parse_modules (void)
|
||||
{
|
||||
ecma_module_t *current_p = JERRY_CONTEXT (ecma_modules_p);
|
||||
|
||||
while (current_p != NULL)
|
||||
{
|
||||
ecma_value_t ret_value = ecma_module_parse (current_p);
|
||||
if (ECMA_IS_VALUE_ERROR (ret_value))
|
||||
{
|
||||
return ret_value;
|
||||
}
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_empty (ret_value));
|
||||
current_p = current_p->next_p;
|
||||
}
|
||||
|
||||
return ECMA_VALUE_EMPTY;
|
||||
} /* ecma_module_parse_modules */
|
||||
|
||||
/**
|
||||
* Checks if indirect exports in the current context are resolvable.
|
||||
* Note: See 15.2.1.16.4 / 9.
|
||||
*
|
||||
* @return ECMA_VALUE_ERROR - if an error occured
|
||||
* ECMA_VALUE_EMPTY - otherwise
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_module_check_indirect_exports (void)
|
||||
{
|
||||
ecma_module_node_t *indirect_export_p = JERRY_CONTEXT (module_top_context_p)->indirect_exports_p;
|
||||
while (indirect_export_p != NULL)
|
||||
{
|
||||
ecma_module_names_t *name_p = indirect_export_p->module_names_p;
|
||||
while (name_p != NULL)
|
||||
{
|
||||
ecma_module_record_t record;
|
||||
ecma_value_t result = ecma_module_resolve_export (indirect_export_p->module_request_p,
|
||||
name_p->local_name_p,
|
||||
&record);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (record.module_p == NULL)
|
||||
{
|
||||
return ecma_raise_syntax_error (ECMA_ERR_MSG ("Ambiguous indirect export request."));
|
||||
}
|
||||
|
||||
name_p = name_p->next_p;
|
||||
}
|
||||
|
||||
indirect_export_p = indirect_export_p->next_p;
|
||||
}
|
||||
|
||||
return ECMA_VALUE_EMPTY;
|
||||
} /* ecma_module_check_indirect_exports */
|
||||
|
||||
/**
|
||||
* Cleans up a list of module names.
|
||||
*/
|
||||
@@ -1016,52 +1081,60 @@ ecma_module_release_module_nodes (ecma_module_node_t *module_node_p) /**< first
|
||||
} /* ecma_module_release_module_nodes */
|
||||
|
||||
/**
|
||||
* Cleans up a module context.
|
||||
*/
|
||||
static void
|
||||
ecma_module_release_module_context (ecma_module_context_t *module_context_p) /**< modle context */
|
||||
{
|
||||
ecma_module_release_module_nodes (module_context_p->imports_p);
|
||||
ecma_module_release_module_nodes (module_context_p->local_exports_p);
|
||||
ecma_module_release_module_nodes (module_context_p->indirect_exports_p);
|
||||
ecma_module_release_module_nodes (module_context_p->star_exports_p);
|
||||
|
||||
jmem_heap_free_block (module_context_p, sizeof (ecma_module_context_t));
|
||||
} /* ecma_module_release_module_context */
|
||||
|
||||
/**
|
||||
* Cleans up a module structure.
|
||||
* Cleans up and releases a module structure including all referenced modules.
|
||||
*/
|
||||
static void
|
||||
ecma_module_release_module (ecma_module_t *module_p) /**< module */
|
||||
{
|
||||
ecma_module_state_t state = module_p->state;
|
||||
|
||||
ecma_deref_ecma_string (module_p->path_p);
|
||||
#ifndef JERRY_NDEBUG
|
||||
module_p->path_p = NULL;
|
||||
#endif /* JERRY_NDEBUG */
|
||||
|
||||
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;
|
||||
#endif /* JERRY_NDEBUG */
|
||||
}
|
||||
|
||||
if (module_p->state == ECMA_MODULE_STATE_NATIVE)
|
||||
if (state == ECMA_MODULE_STATE_NATIVE)
|
||||
{
|
||||
goto finished;
|
||||
}
|
||||
|
||||
if (module_p->state >= ECMA_MODULE_STATE_PARSING)
|
||||
if (state >= ECMA_MODULE_STATE_PARSING)
|
||||
{
|
||||
ecma_module_release_module_context (module_p->context_p);
|
||||
ecma_module_release_module_nodes (module_p->imports_p);
|
||||
ecma_module_release_module_nodes (module_p->local_exports_p);
|
||||
ecma_module_release_module_nodes (module_p->indirect_exports_p);
|
||||
ecma_module_release_module_nodes (module_p->star_exports_p);
|
||||
}
|
||||
|
||||
if (module_p->state >= ECMA_MODULE_STATE_EVALUATING
|
||||
&& module_p->scope_p != NULL)
|
||||
if (state == ECMA_MODULE_STATE_ROOT)
|
||||
{
|
||||
goto finished;
|
||||
}
|
||||
|
||||
if (state >= ECMA_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->state >= ECMA_MODULE_STATE_PARSED
|
||||
&& module_p->state < ECMA_MODULE_STATE_EVALUATED)
|
||||
if (state >= ECMA_MODULE_STATE_PARSED
|
||||
&& state < ECMA_MODULE_STATE_EVALUATED)
|
||||
{
|
||||
ecma_bytecode_deref (module_p->compiled_code_p);
|
||||
#ifndef JERRY_NDEBUG
|
||||
module_p->compiled_code_p = NULL;
|
||||
#endif /* JERRY_NDEBUG */
|
||||
}
|
||||
|
||||
finished:
|
||||
@@ -1069,21 +1142,16 @@ finished:
|
||||
} /* ecma_module_release_module */
|
||||
|
||||
/**
|
||||
* Cleans up all modules if the current context is the root context.
|
||||
* Cleans up and releases a module list.
|
||||
*/
|
||||
void
|
||||
ecma_module_cleanup (void)
|
||||
ecma_module_cleanup (ecma_module_t *head_p) /**< module */
|
||||
{
|
||||
ecma_module_t *current_p = JERRY_CONTEXT (ecma_modules_p);
|
||||
while (current_p != NULL)
|
||||
while (head_p != NULL)
|
||||
{
|
||||
ecma_module_t *next_p = current_p->next_p;
|
||||
ecma_module_release_module (current_p);
|
||||
current_p = next_p;
|
||||
ecma_module_t *next_p = head_p->next_p;
|
||||
ecma_module_release_module (head_p);
|
||||
head_p = next_p;
|
||||
}
|
||||
|
||||
JERRY_CONTEXT (ecma_modules_p) = NULL;
|
||||
JERRY_CONTEXT (module_top_context_p) = NULL;
|
||||
} /* ecma_module_cleanup */
|
||||
|
||||
#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
|
||||
|
||||
@@ -16,11 +16,11 @@
|
||||
#ifndef ECMA_MODULE_H
|
||||
#define ECMA_MODULE_H
|
||||
|
||||
#if ENABLED (JERRY_MODULE_SYSTEM)
|
||||
|
||||
#include "common.h"
|
||||
#include "ecma-globals.h"
|
||||
|
||||
#if ENABLED (JERRY_MODULE_SYSTEM)
|
||||
|
||||
#define ECMA_MODULE_MAX_PATH 255u
|
||||
|
||||
/**
|
||||
@@ -35,31 +35,6 @@ typedef struct ecma_module_names
|
||||
ecma_string_t *local_name_p; /**< Local name of the item */
|
||||
} ecma_module_names_t;
|
||||
|
||||
typedef struct ecma_module ecma_module_t;
|
||||
|
||||
/**
|
||||
* Module node to store imports / exports.
|
||||
*/
|
||||
typedef struct ecma_module_node
|
||||
{
|
||||
struct ecma_module_node *next_p; /**< next linked list node */
|
||||
ecma_module_names_t *module_names_p; /**< names of the requested import/export node */
|
||||
ecma_module_t *module_request_p; /**< module structure of the requested module */
|
||||
} ecma_module_node_t;
|
||||
|
||||
/**
|
||||
* Module context containing all import and export nodes.
|
||||
*/
|
||||
typedef struct ecma_module_context
|
||||
{
|
||||
struct ecma_module_context *parent_p; /**< parent context */
|
||||
ecma_module_node_t *imports_p; /**< import item of the current context */
|
||||
ecma_module_node_t *local_exports_p; /**< export item of the current context */
|
||||
ecma_module_node_t *indirect_exports_p; /**< export item of the current context */
|
||||
ecma_module_node_t *star_exports_p; /**< export item of the current context */
|
||||
ecma_module_t *module_p; /**< module request */
|
||||
} ecma_module_context_t;
|
||||
|
||||
/**
|
||||
* An enum identifing the current state of the module
|
||||
*/
|
||||
@@ -71,21 +46,36 @@ typedef enum
|
||||
ECMA_MODULE_STATE_EVALUATING = 3, /**< module is currently being evaluated */
|
||||
ECMA_MODULE_STATE_EVALUATED = 4, /**< module has been evaluated */
|
||||
ECMA_MODULE_STATE_NATIVE = 5, /**< module is native */
|
||||
ECMA_MODULE_STATE_ROOT = 6, /**< module is a root module */
|
||||
} ecma_module_state_t;
|
||||
|
||||
/**
|
||||
* Module structure storing an instance of a module
|
||||
*/
|
||||
struct ecma_module
|
||||
typedef struct ecma_module
|
||||
{
|
||||
struct ecma_module *next_p; /**< next linked list node */
|
||||
ecma_module_state_t state; /**< state of the mode */
|
||||
ecma_string_t *path_p; /**< path of the module */
|
||||
ecma_module_context_t *context_p; /**< module context of the module */
|
||||
ecma_compiled_code_t *compiled_code_p; /**< compiled code of the module */
|
||||
ecma_object_t *scope_p; /**< lexica lenvironment of the module */
|
||||
ecma_object_t *namespace_object_p; /**< namespace import object of the module */
|
||||
};
|
||||
/* TODO(dbatyai): These could be compressed pointers */
|
||||
struct ecma_module *next_p; /**< next module in the list */
|
||||
struct ecma_module_node *imports_p; /**< import requests of the module */
|
||||
struct ecma_module_node *local_exports_p; /**< local exports of the module */
|
||||
struct ecma_module_node *indirect_exports_p; /**< indirect exports of the module */
|
||||
struct ecma_module_node *star_exports_p; /**< star exports of the module*/
|
||||
ecma_string_t *path_p; /**< path of the module */
|
||||
ecma_compiled_code_t *compiled_code_p; /**< compiled code for the module */
|
||||
ecma_object_t *scope_p; /**< lexical lenvironment of the module */
|
||||
ecma_object_t *namespace_object_p; /**< namespace object of the module */
|
||||
ecma_module_state_t state; /**< evaluation state of the module */
|
||||
} ecma_module_t;
|
||||
|
||||
/**
|
||||
* Module node to store imports / exports.
|
||||
*/
|
||||
typedef struct ecma_module_node
|
||||
{
|
||||
struct ecma_module_node *next_p; /**< next linked list node */
|
||||
ecma_module_names_t *module_names_p; /**< names of the requested import/export node */
|
||||
ecma_module_t *module_request_p; /**< module structure of the requested module */
|
||||
} ecma_module_node_t;
|
||||
|
||||
/**
|
||||
* A record that can be used to store {module, identifier} pairs
|
||||
@@ -126,19 +116,21 @@ void ecma_module_resolve_stack_push (ecma_module_resolve_stack_t **stack_p,
|
||||
ecma_string_t *const export_name_p);
|
||||
void ecma_module_resolve_stack_pop (ecma_module_resolve_stack_t **stack_p);
|
||||
|
||||
ecma_string_t *ecma_module_create_normalized_path (const uint8_t *char_p,
|
||||
prop_length_t size);
|
||||
ecma_module_t *ecma_module_find_module (ecma_string_t *const path_p);
|
||||
ecma_module_t *ecma_module_create_native_module (ecma_string_t *const path_p,
|
||||
ecma_object_t *const namespace_p);
|
||||
ecma_module_t *ecma_module_find_or_create_module (ecma_string_t *const path_p);
|
||||
ecma_string_t *ecma_module_create_normalized_path (const lit_utf8_byte_t *char_p,
|
||||
lit_utf8_size_t size,
|
||||
ecma_string_t *const base_path_p);
|
||||
|
||||
ecma_value_t ecma_module_initialize_current (void);
|
||||
ecma_value_t ecma_module_parse_modules (void);
|
||||
ecma_value_t ecma_module_check_indirect_exports (void);
|
||||
ecma_module_t *ecma_module_find_module (ecma_string_t *const path_p);
|
||||
ecma_module_t *ecma_module_find_native_module (ecma_string_t *const path_p);
|
||||
|
||||
ecma_value_t ecma_module_parse_referenced_modules (void);
|
||||
ecma_value_t ecma_module_initialize (ecma_module_t *module_p);
|
||||
|
||||
void ecma_module_initialize_context (ecma_string_t *root_path_p);
|
||||
void ecma_module_cleanup_context (void);
|
||||
|
||||
void ecma_module_release_module_nodes (ecma_module_node_t *module_node_p);
|
||||
void ecma_module_cleanup (void);
|
||||
void ecma_module_cleanup (ecma_module_t *head_p);
|
||||
#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
|
||||
|
||||
#endif /* !ECMA_MODULE_H */
|
||||
|
||||
@@ -115,7 +115,8 @@ typedef enum
|
||||
typedef enum
|
||||
{
|
||||
JERRY_PARSE_NO_OPTS = 0, /**< no options passed */
|
||||
JERRY_PARSE_STRICT_MODE = (1 << 0) /**< enable strict mode */
|
||||
JERRY_PARSE_STRICT_MODE = (1 << 0), /**< enable strict mode */
|
||||
JERRY_PARSE_MODULE = (1 << 1) /**< parse source as an ECMAScript module */
|
||||
} jerry_parse_opts_t;
|
||||
|
||||
/**
|
||||
|
||||
@@ -150,8 +150,8 @@ struct jerry_context_t
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
|
||||
#if ENABLED (JERRY_MODULE_SYSTEM)
|
||||
ecma_module_t *ecma_modules_p; /**< list of referenced modules */
|
||||
ecma_module_context_t *module_top_context_p; /**< top (current) module parser context */
|
||||
ecma_module_t *module_list_p; /**< current module context */
|
||||
ecma_module_t *module_current_p; /**< current module context */
|
||||
#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
|
||||
|
||||
vm_frame_ctx_t *vm_top_context_p; /**< top (current) interpreter context */
|
||||
|
||||
@@ -16,14 +16,16 @@
|
||||
#include "config.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "lit-char-helpers.h"
|
||||
#include "lit-unicode-ranges.inc.h"
|
||||
#include "lit-unicode-ranges-sup.inc.h"
|
||||
#include "lit-strings.h"
|
||||
#include "lit-unicode-ranges.inc.h"
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
#include "lit-unicode-ranges-sup.inc.h"
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
|
||||
#if ENABLED (JERRY_UNICODE_CASE_CONVERSION)
|
||||
#include "lit-unicode-conversions.inc.h"
|
||||
#include "lit-unicode-conversions-sup.inc.h"
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
#include "lit-unicode-conversions-sup.inc.h"
|
||||
#include "lit-unicode-folding.inc.h"
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
#endif /* ENABLED (JERRY_UNICODE_CASE_CONVERSION) */
|
||||
|
||||
@@ -549,6 +549,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_DATAVIEW_UL, "DataView")
|
||||
#endif
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_FUNCTION_UL, "Function")
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_INFINITY_UL, "Infinity")
|
||||
#if ENABLED (JERRY_MODULE_SYSTEM)
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_RUNNABLE_UL, "Runnable")
|
||||
#endif
|
||||
#if ENABLED (JERRY_BUILTIN_ERRORS)
|
||||
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_URI_ERROR_UL, "URIError")
|
||||
#endif
|
||||
|
||||
@@ -214,6 +214,7 @@ LIT_MAGIC_STRING_VALUE_OF_UL = "valueOf"
|
||||
LIT_MAGIC_STRING_WEAKMAP_UL = "WeakMap"
|
||||
LIT_MAGIC_STRING_WEAKSET_UL = "WeakSet"
|
||||
LIT_MAGIC_STRING_EPSILON_U = "EPSILON"
|
||||
LIT_MAGIC_STRING_RUNNABLE_UL = "Runnable"
|
||||
LIT_MAGIC_STRING_DATAVIEW_UL = "DataView"
|
||||
LIT_MAGIC_STRING_FUNCTION_UL = "Function"
|
||||
LIT_MAGIC_STRING_INFINITY_UL = "Infinity"
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#ifndef JS_LEXER_H
|
||||
#define JS_LEXER_H
|
||||
|
||||
#include "ecma-globals.h"
|
||||
|
||||
/** \addtogroup parser Parser
|
||||
* @{
|
||||
*
|
||||
|
||||
@@ -860,8 +860,8 @@ void parser_free_jumps (parser_stack_iterator_t iterator);
|
||||
*/
|
||||
|
||||
extern const lexer_lit_location_t lexer_default_literal;
|
||||
void parser_module_add_export_node_to_context (parser_context_t *context_p);
|
||||
void parser_module_add_import_node_to_context (parser_context_t *context_p);
|
||||
void parser_module_finalize_export_node (parser_context_t *context_p);
|
||||
void parser_module_finalize_import_node (parser_context_t *context_p);
|
||||
void parser_module_check_request_place (parser_context_t *context_p);
|
||||
void parser_module_context_init (parser_context_t *context_p);
|
||||
void parser_module_handle_module_specifier (parser_context_t *context_p);
|
||||
|
||||
@@ -55,7 +55,7 @@ parser_module_check_duplicate_import (parser_context_t *context_p, /**< parser c
|
||||
module_names_p = module_names_p->next_p;
|
||||
}
|
||||
|
||||
ecma_module_node_t *module_node_p = JERRY_CONTEXT (module_top_context_p)->imports_p;
|
||||
ecma_module_node_t *module_node_p = JERRY_CONTEXT (module_current_p)->imports_p;
|
||||
while (module_node_p != NULL)
|
||||
{
|
||||
module_names_p = module_node_p->module_names_p;
|
||||
@@ -124,7 +124,7 @@ parser_module_check_duplicate_export (parser_context_t *context_p, /**< parser c
|
||||
current_names_p = current_names_p->next_p;
|
||||
}
|
||||
|
||||
ecma_module_node_t *export_node_p = JERRY_CONTEXT (module_top_context_p)->local_exports_p;
|
||||
ecma_module_node_t *export_node_p = JERRY_CONTEXT (module_current_p)->local_exports_p;
|
||||
if (export_node_p != NULL)
|
||||
{
|
||||
JERRY_ASSERT (export_node_p->next_p == NULL);
|
||||
@@ -141,7 +141,7 @@ parser_module_check_duplicate_export (parser_context_t *context_p, /**< parser c
|
||||
}
|
||||
}
|
||||
|
||||
export_node_p = JERRY_CONTEXT (module_top_context_p)->indirect_exports_p;
|
||||
export_node_p = JERRY_CONTEXT (module_current_p)->indirect_exports_p;
|
||||
while (export_node_p != NULL)
|
||||
{
|
||||
ecma_module_names_t *name_p = export_node_p->module_names_p;
|
||||
@@ -167,7 +167,7 @@ parser_module_check_duplicate_export (parser_context_t *context_p, /**< parser c
|
||||
* Add export node to parser context.
|
||||
*/
|
||||
void
|
||||
parser_module_add_export_node_to_context (parser_context_t *context_p) /**< parser context */
|
||||
parser_module_finalize_export_node (parser_context_t *context_p) /**< parser context */
|
||||
{
|
||||
ecma_module_node_t *module_node_p = context_p->module_current_node_p;
|
||||
context_p->module_current_node_p = NULL;
|
||||
@@ -180,17 +180,17 @@ parser_module_add_export_node_to_context (parser_context_t *context_p) /**< pars
|
||||
if (!module_node_p->module_names_p)
|
||||
{
|
||||
/* If there are no names in the node, then it's a star export. */
|
||||
export_list_p = &(JERRY_CONTEXT (module_top_context_p)->star_exports_p);
|
||||
export_list_p = &(JERRY_CONTEXT (module_current_p)->star_exports_p);
|
||||
}
|
||||
else
|
||||
{
|
||||
export_list_p = &(JERRY_CONTEXT (module_top_context_p)->indirect_exports_p);
|
||||
export_list_p = &(JERRY_CONTEXT (module_current_p)->indirect_exports_p);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If there is no module request, then it's a local export. */
|
||||
export_list_p = &(JERRY_CONTEXT (module_top_context_p)->local_exports_p);
|
||||
export_list_p = &(JERRY_CONTEXT (module_current_p)->local_exports_p);
|
||||
}
|
||||
|
||||
/* Check if we have a node with the same module request, append to it if we do. */
|
||||
@@ -213,7 +213,7 @@ parser_module_add_export_node_to_context (parser_context_t *context_p) /**< pars
|
||||
module_node_p->module_names_p = NULL;
|
||||
}
|
||||
|
||||
ecma_module_release_module_nodes (module_node_p);
|
||||
jmem_heap_free_block (module_node_p, sizeof (ecma_module_node_t));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -222,22 +222,22 @@ parser_module_add_export_node_to_context (parser_context_t *context_p) /**< pars
|
||||
|
||||
module_node_p->next_p = *export_list_p;
|
||||
*export_list_p = module_node_p;
|
||||
} /* parser_module_add_export_node_to_context */
|
||||
} /* parser_module_finalize_export_node */
|
||||
|
||||
/**
|
||||
* Add import node to parser context.
|
||||
*/
|
||||
void
|
||||
parser_module_add_import_node_to_context (parser_context_t *context_p) /**< parser context */
|
||||
parser_module_finalize_import_node (parser_context_t *context_p) /**< parser context */
|
||||
{
|
||||
ecma_module_node_t *module_node_p = context_p->module_current_node_p;
|
||||
context_p->module_current_node_p = NULL;
|
||||
ecma_module_node_t *stored_imports = JERRY_CONTEXT (module_top_context_p)->imports_p;
|
||||
ecma_module_node_t *stored_imports_p = JERRY_CONTEXT (module_current_p)->imports_p;
|
||||
|
||||
/* Check if we have a node with the same module request, append to it if we do. */
|
||||
while (stored_imports != NULL)
|
||||
while (stored_imports_p != NULL)
|
||||
{
|
||||
if (stored_imports->module_request_p == module_node_p->module_request_p)
|
||||
if (stored_imports_p->module_request_p == module_node_p->module_request_p)
|
||||
{
|
||||
ecma_module_names_t *module_names_p = module_node_p->module_names_p;
|
||||
|
||||
@@ -248,21 +248,21 @@ parser_module_add_import_node_to_context (parser_context_t *context_p) /**< pars
|
||||
module_names_p = module_names_p->next_p;
|
||||
}
|
||||
|
||||
module_names_p->next_p = stored_imports->module_names_p;
|
||||
stored_imports->module_names_p = module_node_p->module_names_p;
|
||||
module_names_p->next_p = stored_imports_p->module_names_p;
|
||||
stored_imports_p->module_names_p = module_node_p->module_names_p;
|
||||
module_node_p->module_names_p = NULL;
|
||||
}
|
||||
|
||||
ecma_module_release_module_nodes (module_node_p);
|
||||
jmem_heap_free_block (module_node_p, sizeof (ecma_module_node_t));
|
||||
return;
|
||||
}
|
||||
|
||||
stored_imports = stored_imports->next_p;
|
||||
stored_imports_p = stored_imports_p->next_p;
|
||||
}
|
||||
|
||||
module_node_p->next_p = JERRY_CONTEXT (module_top_context_p)->imports_p;
|
||||
JERRY_CONTEXT (module_top_context_p)->imports_p = module_node_p;
|
||||
} /* parser_module_add_import_node_to_context */
|
||||
module_node_p->next_p = JERRY_CONTEXT (module_current_p)->imports_p;
|
||||
JERRY_CONTEXT (module_current_p)->imports_p = module_node_p;
|
||||
} /* parser_module_finalize_import_node */
|
||||
|
||||
/**
|
||||
* Add module names to current module node.
|
||||
@@ -289,50 +289,6 @@ parser_module_add_names_to_node (parser_context_t *context_p, /**< parser contex
|
||||
new_names_p->local_name_p = local_name_p;
|
||||
} /* parser_module_add_names_to_node */
|
||||
|
||||
/**
|
||||
* Create module context if needed.
|
||||
*/
|
||||
void
|
||||
parser_module_context_init (parser_context_t *context_p)
|
||||
{
|
||||
if (JERRY_CONTEXT (module_top_context_p) == NULL)
|
||||
{
|
||||
ecma_module_context_t *module_context_p;
|
||||
module_context_p = (ecma_module_context_t *) jmem_heap_alloc_block (sizeof (ecma_module_context_t));
|
||||
memset (module_context_p, 0, sizeof (ecma_module_context_t));
|
||||
JERRY_CONTEXT (module_top_context_p) = module_context_p;
|
||||
|
||||
ecma_string_t *path_str_p = ecma_get_string_from_value (context_p->resource_name);
|
||||
|
||||
lit_utf8_size_t path_str_size;
|
||||
uint8_t flags = ECMA_STRING_FLAG_EMPTY;
|
||||
|
||||
const lit_utf8_byte_t *path_str_chars_p = ecma_string_get_chars (path_str_p,
|
||||
&path_str_size,
|
||||
NULL,
|
||||
NULL,
|
||||
&flags);
|
||||
|
||||
ecma_string_t *path_p = ecma_module_create_normalized_path (path_str_chars_p,
|
||||
(prop_length_t) path_str_size);
|
||||
|
||||
if (path_p == NULL)
|
||||
{
|
||||
ecma_ref_ecma_string (path_str_p);
|
||||
path_p = path_str_p;
|
||||
}
|
||||
|
||||
ecma_module_t *module_p = ecma_module_find_or_create_module (path_p);
|
||||
|
||||
module_p->state = ECMA_MODULE_STATE_EVALUATED;
|
||||
/* The lexical scope of the root module does not exist yet. */
|
||||
module_p->scope_p = NULL;
|
||||
|
||||
module_p->context_p = module_context_p;
|
||||
module_context_p->module_p = module_p;
|
||||
}
|
||||
} /* parser_module_context_init */
|
||||
|
||||
/**
|
||||
* Create a permanent import/export node from a template node.
|
||||
* @return - the copy of the template if the second parameter is not NULL.
|
||||
@@ -567,7 +523,8 @@ parser_module_check_request_place (parser_context_t *context_p) /**< parser cont
|
||||
if (context_p->last_context_p != NULL
|
||||
|| context_p->stack_top_uint8 != 0
|
||||
|| (context_p->status_flags & PARSER_IS_FUNCTION)
|
||||
|| (context_p->global_status_flags & ECMA_PARSE_EVAL))
|
||||
|| (context_p->global_status_flags & ECMA_PARSE_EVAL)
|
||||
|| (context_p->global_status_flags & ECMA_PARSE_MODULE) == 0)
|
||||
{
|
||||
parser_raise_error (context_p, PARSER_ERR_MODULE_UNEXPECTED);
|
||||
}
|
||||
@@ -592,34 +549,25 @@ parser_module_handle_module_specifier (parser_context_t *context_p) /**< parser
|
||||
ecma_string_t *name_p = ecma_new_ecma_string_from_utf8 (context_p->lit_object.literal_p->u.char_p,
|
||||
context_p->lit_object.literal_p->prop.length);
|
||||
|
||||
ecma_module_t *module_p = ecma_module_find_module (name_p);
|
||||
ecma_module_t *module_p = ecma_module_find_native_module (name_p);
|
||||
|
||||
if (module_p)
|
||||
{
|
||||
ecma_deref_ecma_string (name_p);
|
||||
goto module_found;
|
||||
}
|
||||
|
||||
ecma_value_t native = jerry_port_get_native_module (ecma_make_string_value (name_p));
|
||||
|
||||
if (!ecma_is_value_undefined (native))
|
||||
{
|
||||
JERRY_ASSERT (ecma_is_value_object (native));
|
||||
ecma_object_t *module_object_p = ecma_get_object_from_value (native);
|
||||
|
||||
module_p = ecma_module_create_native_module (name_p, module_object_p);
|
||||
goto module_found;
|
||||
}
|
||||
|
||||
ecma_deref_ecma_string (name_p);
|
||||
ecma_string_t *path_p = ecma_module_create_normalized_path (context_p->lit_object.literal_p->u.char_p,
|
||||
context_p->lit_object.literal_p->prop.length);
|
||||
context_p->lit_object.literal_p->prop.length,
|
||||
JERRY_CONTEXT (module_current_p)->path_p);
|
||||
|
||||
if (path_p == NULL)
|
||||
{
|
||||
parser_raise_error (context_p, PARSER_ERR_FILE_NOT_FOUND);
|
||||
}
|
||||
|
||||
module_p = ecma_module_find_or_create_module (path_p);
|
||||
module_p = ecma_module_find_module (path_p);
|
||||
|
||||
module_found:
|
||||
module_node_p->module_request_p = module_p;
|
||||
|
||||
@@ -2427,7 +2427,6 @@ parser_parse_import_statement (parser_context_t *context_p) /**< parser context
|
||||
JERRY_ASSERT (context_p->token.type == LEXER_KEYW_IMPORT);
|
||||
|
||||
parser_module_check_request_place (context_p);
|
||||
parser_module_context_init (context_p);
|
||||
|
||||
context_p->module_current_node_p = parser_module_create_module_node (context_p);
|
||||
|
||||
@@ -2529,7 +2528,7 @@ parser_parse_import_statement (parser_context_t *context_p) /**< parser context
|
||||
}
|
||||
|
||||
parser_module_handle_module_specifier (context_p);
|
||||
parser_module_add_import_node_to_context (context_p);
|
||||
parser_module_finalize_import_node (context_p);
|
||||
|
||||
context_p->module_current_node_p = NULL;
|
||||
} /* parser_parse_import_statement */
|
||||
@@ -2543,7 +2542,6 @@ parser_parse_export_statement (parser_context_t *context_p) /**< context */
|
||||
JERRY_ASSERT (context_p->token.type == LEXER_KEYW_EXPORT);
|
||||
|
||||
parser_module_check_request_place (context_p);
|
||||
parser_module_context_init (context_p);
|
||||
|
||||
context_p->module_current_node_p = parser_module_create_module_node (context_p);
|
||||
|
||||
@@ -2656,7 +2654,7 @@ parser_parse_export_statement (parser_context_t *context_p) /**< context */
|
||||
}
|
||||
|
||||
context_p->status_flags &= (uint32_t) ~(PARSER_MODULE_DEFAULT_CLASS_OR_FUNC | PARSER_MODULE_STORE_IDENT);
|
||||
parser_module_add_export_node_to_context (context_p);
|
||||
parser_module_finalize_export_node (context_p);
|
||||
context_p->module_current_node_p = NULL;
|
||||
} /* parser_parse_export_statement */
|
||||
#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
|
||||
|
||||
@@ -1396,7 +1396,7 @@ parser_error_to_string (parser_error_t error) /**< error code */
|
||||
}
|
||||
case PARSER_ERR_MODULE_UNEXPECTED:
|
||||
{
|
||||
return "Import and export statements must be in the global context.";
|
||||
return "Unexpected import or export statement.";
|
||||
}
|
||||
case PARSER_ERR_LEFT_BRACE_MULTIPLY_EXPECTED:
|
||||
{
|
||||
|
||||
@@ -1811,6 +1811,15 @@ parser_parse_source (const uint8_t *arg_list_p, /**< function argument list */
|
||||
context.status_flags = parse_opts & PARSER_STRICT_MODE_MASK;
|
||||
context.global_status_flags = parse_opts;
|
||||
|
||||
#if ENABLED (JERRY_MODULE_SYSTEM)
|
||||
if (context.global_status_flags & ECMA_PARSE_MODULE)
|
||||
{
|
||||
context.status_flags |= PARSER_IS_STRICT;
|
||||
}
|
||||
|
||||
context.module_current_node_p = NULL;
|
||||
#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
|
||||
|
||||
if (arg_list_p != NULL)
|
||||
{
|
||||
context.status_flags |= PARSER_IS_FUNCTION;
|
||||
@@ -1934,15 +1943,6 @@ parser_parse_source (const uint8_t *arg_list_p, /**< function argument list */
|
||||
context.breakpoint_info_count = 0;
|
||||
#endif /* ENABLED (JERRY_DEBUGGER) */
|
||||
|
||||
#if ENABLED (JERRY_MODULE_SYSTEM)
|
||||
if (context.global_status_flags & ECMA_PARSE_MODULE)
|
||||
{
|
||||
context.status_flags |= PARSER_IS_STRICT;
|
||||
}
|
||||
|
||||
context.module_current_node_p = NULL;
|
||||
#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
|
||||
|
||||
JERRY_ASSERT (context.next_scanner_info_p->source_p == context.source_p);
|
||||
JERRY_ASSERT (context.next_scanner_info_p->type == SCANNER_TYPE_FUNCTION);
|
||||
|
||||
@@ -2859,12 +2859,6 @@ parser_parse_script (const uint8_t *arg_list_p, /**< function argument list */
|
||||
resource_name,
|
||||
line_str_val,
|
||||
col_str_val);
|
||||
#if ENABLED (JERRY_MODULE_SYSTEM)
|
||||
if (JERRY_CONTEXT (module_top_context_p) != NULL)
|
||||
{
|
||||
ecma_module_cleanup ();
|
||||
}
|
||||
#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
|
||||
|
||||
ecma_free_value (col_str_val);
|
||||
ecma_free_value (line_str_val);
|
||||
@@ -2881,16 +2875,6 @@ parser_parse_script (const uint8_t *arg_list_p, /**< function argument list */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if ENABLED (JERRY_MODULE_SYSTEM)
|
||||
if (JERRY_CONTEXT (module_top_context_p) != NULL && ECMA_IS_VALUE_ERROR (ecma_module_parse_modules ()))
|
||||
{
|
||||
ecma_bytecode_deref (bytecode_p);
|
||||
ecma_module_cleanup ();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
|
||||
|
||||
#if ENABLED (JERRY_DEBUGGER)
|
||||
if ((JERRY_CONTEXT (debugger_flags) & (JERRY_DEBUGGER_CONNECTED | JERRY_DEBUGGER_PARSER_WAIT))
|
||||
== (JERRY_DEBUGGER_CONNECTED | JERRY_DEBUGGER_PARSER_WAIT))
|
||||
|
||||
@@ -1649,8 +1649,6 @@ scanner_scan_statement (parser_context_t *context_p, /**< context */
|
||||
scanner_raise_error (context_p);
|
||||
}
|
||||
|
||||
context_p->global_status_flags |= ECMA_PARSE_MODULE;
|
||||
|
||||
scanner_context_p->mode = SCAN_MODE_STATEMENT_END;
|
||||
lexer_next_token (context_p);
|
||||
|
||||
@@ -1801,8 +1799,6 @@ scanner_scan_statement (parser_context_t *context_p, /**< context */
|
||||
scanner_raise_error (context_p);
|
||||
}
|
||||
|
||||
context_p->global_status_flags |= ECMA_PARSE_MODULE;
|
||||
|
||||
lexer_next_token (context_p);
|
||||
|
||||
if (context_p->token.type == LEXER_KEYW_DEFAULT)
|
||||
|
||||
+4
-26
@@ -272,10 +272,9 @@ static const uint16_t vm_decode_table[] JERRY_ATTR_CONST_DATA =
|
||||
* @return ecma value
|
||||
*/
|
||||
ecma_value_t
|
||||
vm_run_module (const ecma_compiled_code_t *bytecode_p, /**< pointer to bytecode to run */
|
||||
ecma_object_t *lex_env_p) /**< pointer to the specified lexenv to run in */
|
||||
vm_run_module (ecma_module_t *module_p) /**< module to be executed */
|
||||
{
|
||||
const ecma_value_t module_init_result = ecma_module_initialize_current ();
|
||||
const ecma_value_t module_init_result = ecma_module_initialize (module_p);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (module_init_result))
|
||||
{
|
||||
@@ -283,10 +282,10 @@ vm_run_module (const ecma_compiled_code_t *bytecode_p, /**< pointer to bytecode
|
||||
}
|
||||
|
||||
vm_frame_ctx_shared_t shared;
|
||||
shared.bytecode_header_p = bytecode_p;
|
||||
shared.bytecode_header_p = module_p->compiled_code_p;
|
||||
shared.status_flags = 0;
|
||||
|
||||
return vm_run (&shared, ECMA_VALUE_UNDEFINED, lex_env_p);
|
||||
return vm_run (&shared, ECMA_VALUE_UNDEFINED, module_p->scope_p);
|
||||
} /* vm_run_module */
|
||||
#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
|
||||
|
||||
@@ -316,27 +315,6 @@ vm_run_global (const ecma_compiled_code_t *bytecode_p) /**< pointer to bytecode
|
||||
|
||||
ecma_object_t *const global_scope_p = ecma_get_global_scope (global_obj_p);
|
||||
|
||||
#if ENABLED (JERRY_MODULE_SYSTEM)
|
||||
if (JERRY_CONTEXT (module_top_context_p) != NULL)
|
||||
{
|
||||
JERRY_ASSERT (JERRY_CONTEXT (module_top_context_p)->parent_p == NULL);
|
||||
ecma_module_t *module_p = JERRY_CONTEXT (module_top_context_p)->module_p;
|
||||
|
||||
JERRY_ASSERT (module_p->scope_p == NULL);
|
||||
ecma_ref_object (global_scope_p);
|
||||
module_p->scope_p = global_scope_p;
|
||||
|
||||
const ecma_value_t module_init_result = ecma_module_initialize_current ();
|
||||
JERRY_CONTEXT (module_top_context_p) = NULL;
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (module_init_result))
|
||||
{
|
||||
ecma_module_cleanup ();
|
||||
return module_init_result;
|
||||
}
|
||||
}
|
||||
#endif /* ENABLED (JERRY_MODULE_SYSTEM) */
|
||||
|
||||
vm_frame_ctx_shared_t shared;
|
||||
shared.bytecode_header_p = bytecode_p;
|
||||
shared.status_flags = 0;
|
||||
|
||||
+2
-1
@@ -17,6 +17,7 @@
|
||||
#define VM_H
|
||||
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-module.h"
|
||||
#include "jrt.h"
|
||||
#include "vm-defines.h"
|
||||
|
||||
@@ -481,7 +482,7 @@ ecma_value_t vm_run_global (const ecma_compiled_code_t *bytecode_p);
|
||||
ecma_value_t vm_run_eval (ecma_compiled_code_t *bytecode_data_p, uint32_t parse_opts);
|
||||
|
||||
#if ENABLED (JERRY_MODULE_SYSTEM)
|
||||
ecma_value_t vm_run_module (const ecma_compiled_code_t *bytecode_p, ecma_object_t *lex_env_p);
|
||||
ecma_value_t vm_run_module (ecma_module_t *module_p);
|
||||
#endif /* ENABLED (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);
|
||||
|
||||
Reference in New Issue
Block a user