Fix lexical scoping between scripts (#3558)
This change fixes the handling of lexical blocks when executing multiple scripts, and also fixes a few issues with module environments. After this change, all script files will run in the same context and will have access to lexically scoped global variables of previous scripts, and module environments will no longer have a bound global 'this' value. The REPL implementation in main-unix is also fixed to correctly handle lexically scoped variables. Fixes #3561. JerryScript-DCO-1.0-Signed-off-by: Dániel Bátyai dbatyai@inf.u-szeged.hu
This commit is contained in:
@@ -37,25 +37,35 @@
|
||||
* Initialize Global environment
|
||||
*/
|
||||
void
|
||||
ecma_init_global_lex_env (void)
|
||||
ecma_init_global_environment (void)
|
||||
{
|
||||
ecma_object_t *glob_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_GLOBAL);
|
||||
|
||||
ecma_object_t *global_lex_env_p = ecma_create_object_lex_env (NULL,
|
||||
glob_obj_p,
|
||||
ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
|
||||
ECMA_SET_NON_NULL_POINTER (JERRY_CONTEXT (ecma_global_lex_env_cp), global_lex_env_p);
|
||||
} /* ecma_init_global_lex_env */
|
||||
ECMA_SET_NON_NULL_POINTER (JERRY_CONTEXT (ecma_global_env_cp), global_lex_env_p);
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
ECMA_SET_NON_NULL_POINTER (JERRY_CONTEXT (ecma_global_scope_cp), global_lex_env_p);
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
} /* ecma_init_global_environment */
|
||||
|
||||
/**
|
||||
* Finalize Global environment
|
||||
*/
|
||||
void
|
||||
ecma_finalize_global_lex_env (void)
|
||||
ecma_finalize_global_environment (void)
|
||||
{
|
||||
ecma_deref_object (ECMA_GET_NON_NULL_POINTER (ecma_object_t, JERRY_CONTEXT (ecma_global_lex_env_cp)));
|
||||
JERRY_CONTEXT (ecma_global_lex_env_cp) = JMEM_CP_NULL;
|
||||
} /* ecma_finalize_global_lex_env */
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
if (JERRY_CONTEXT (ecma_global_scope_cp) != JERRY_CONTEXT (ecma_global_env_cp))
|
||||
{
|
||||
ecma_deref_object (ECMA_GET_NON_NULL_POINTER (ecma_object_t, JERRY_CONTEXT (ecma_global_scope_cp)));
|
||||
}
|
||||
JERRY_CONTEXT (ecma_global_scope_cp) = JMEM_CP_NULL;
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
ecma_deref_object (ECMA_GET_NON_NULL_POINTER (ecma_object_t, JERRY_CONTEXT (ecma_global_env_cp)));
|
||||
JERRY_CONTEXT (ecma_global_env_cp) = JMEM_CP_NULL;
|
||||
} /* ecma_finalize_global_environment */
|
||||
|
||||
/**
|
||||
* Get reference to Global lexical environment
|
||||
@@ -66,10 +76,43 @@ ecma_finalize_global_lex_env (void)
|
||||
ecma_object_t *
|
||||
ecma_get_global_environment (void)
|
||||
{
|
||||
JERRY_ASSERT (JERRY_CONTEXT (ecma_global_lex_env_cp) != JMEM_CP_NULL);
|
||||
return ECMA_GET_NON_NULL_POINTER (ecma_object_t, JERRY_CONTEXT (ecma_global_lex_env_cp));
|
||||
JERRY_ASSERT (JERRY_CONTEXT (ecma_global_env_cp) != JMEM_CP_NULL);
|
||||
return ECMA_GET_NON_NULL_POINTER (ecma_object_t, JERRY_CONTEXT (ecma_global_env_cp));
|
||||
} /* ecma_get_global_environment */
|
||||
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
/**
|
||||
* Create the global lexical block on top of the global environment.
|
||||
*/
|
||||
void
|
||||
ecma_create_global_lexical_block (void)
|
||||
{
|
||||
if (JERRY_CONTEXT (ecma_global_scope_cp) == JERRY_CONTEXT (ecma_global_env_cp))
|
||||
{
|
||||
ecma_object_t *global_scope_p = ecma_create_decl_lex_env (ecma_get_global_environment ());
|
||||
global_scope_p->type_flags_refs |= (uint16_t) ECMA_OBJECT_FLAG_BLOCK;
|
||||
ECMA_SET_NON_NULL_POINTER (JERRY_CONTEXT (ecma_global_scope_cp), global_scope_p);
|
||||
}
|
||||
} /* ecma_create_global_lexical_block */
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
/**
|
||||
* Get reference to Global lexical scope
|
||||
* without increasing its reference count.
|
||||
*
|
||||
* @return pointer to the object's instance
|
||||
*/
|
||||
ecma_object_t *
|
||||
ecma_get_global_scope (void)
|
||||
{
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
JERRY_ASSERT (JERRY_CONTEXT (ecma_global_scope_cp) != JMEM_CP_NULL);
|
||||
return ECMA_GET_NON_NULL_POINTER (ecma_object_t, JERRY_CONTEXT (ecma_global_scope_cp));
|
||||
#else /* !ENABLED (JERRY_ES2015) */
|
||||
return ecma_get_global_environment ();
|
||||
#endif /* !ENABLED (JERRY_ES2015) */
|
||||
} /* ecma_get_global_scope */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@@ -30,9 +30,13 @@
|
||||
* @{
|
||||
*/
|
||||
|
||||
void ecma_init_global_lex_env (void);
|
||||
void ecma_finalize_global_lex_env (void);
|
||||
void ecma_init_global_environment (void);
|
||||
void ecma_finalize_global_environment (void);
|
||||
ecma_object_t *ecma_get_global_environment (void);
|
||||
ecma_object_t *ecma_get_global_scope (void);
|
||||
#if ENABLED (JERRY_ES2015)
|
||||
void ecma_create_global_lexical_block (void);
|
||||
#endif /* ENABLED (JERRY_ES2015) */
|
||||
|
||||
#if ENABLED (JERRY_ES2015_MODULE_SYSTEM)
|
||||
void ecma_module_add_lex_env (ecma_object_t *lex_env_p);
|
||||
|
||||
@@ -106,7 +106,7 @@ ecma_value_t
|
||||
ecma_op_is_prop_unscopable (ecma_object_t *lex_env_p, /**< lexical environment */
|
||||
ecma_string_t *prop_name_p) /**< property's name */
|
||||
{
|
||||
if (lex_env_p == ecma_get_global_environment ())
|
||||
if (lex_env_p == ecma_get_global_scope ())
|
||||
{
|
||||
return ECMA_VALUE_FALSE;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user