Remove preparser lexer pass and pass for searching of "eval" and "arguments" literals.
JerryScript-DCO-1.0-Signed-off-by: Andrey Shitov a.shitov@samsung.com
This commit is contained in:
+62
-232
@@ -829,7 +829,18 @@ parse_primary_expression (void)
|
||||
case TOK_NUMBER:
|
||||
case TOK_REGEXP:
|
||||
case TOK_STRING: return parse_literal ();
|
||||
case TOK_NAME: return literal_operand (token_data_as_lit_cp ());
|
||||
case TOK_NAME:
|
||||
{
|
||||
if (lit_literal_equal_type_cstr (lit_get_literal_by_cp (token_data_as_lit_cp ()), "arguments"))
|
||||
{
|
||||
scopes_tree_set_arguments_used (STACK_TOP (scopes));
|
||||
}
|
||||
if (lit_literal_equal_type_cstr (lit_get_literal_by_cp (token_data_as_lit_cp ()), "eval"))
|
||||
{
|
||||
scopes_tree_set_eval_used (STACK_TOP (scopes));
|
||||
}
|
||||
return literal_operand (token_data_as_lit_cp ());
|
||||
}
|
||||
case TOK_OPEN_SQUARE: return parse_array_literal ();
|
||||
case TOK_OPEN_BRACE: return parse_object_literal ();
|
||||
case TOK_OPEN_PAREN:
|
||||
@@ -1812,6 +1823,15 @@ parse_variable_declaration (void)
|
||||
current_token_must_be (TOK_NAME);
|
||||
const operand name = literal_operand (token_data_as_lit_cp ());
|
||||
|
||||
if (!dumper_variable_declaration_exists (token_data_as_lit_cp ()))
|
||||
{
|
||||
jsp_early_error_check_for_eval_and_arguments_in_strict_mode (literal_operand (token_data_as_lit_cp ()),
|
||||
is_strict_mode (),
|
||||
tok.loc);
|
||||
|
||||
dump_variable_declaration (token_data_as_lit_cp ());
|
||||
}
|
||||
|
||||
skip_newlines ();
|
||||
if (token_is (TOK_EQ))
|
||||
{
|
||||
@@ -1825,7 +1845,7 @@ parse_variable_declaration (void)
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
} /* parse_variable_declaration */
|
||||
|
||||
/* variable_declaration_list
|
||||
: variable_declaration
|
||||
@@ -2886,65 +2906,12 @@ parse_source_element (void)
|
||||
}
|
||||
|
||||
/**
|
||||
* Skip function's optional name and parentheses
|
||||
*
|
||||
* @return: true, if skipped successfully
|
||||
* false, if open parentheses wasn't found (this means that keyword 'function' is used as
|
||||
* a property name)
|
||||
* Check for "use strict" in directive prologue
|
||||
*/
|
||||
static bool
|
||||
skip_optional_name_and_parens (void)
|
||||
{
|
||||
if (token_is (TOK_NAME))
|
||||
{
|
||||
token_after_newlines_must_be (TOK_OPEN_PAREN);
|
||||
}
|
||||
|
||||
if (token_is (TOK_OPEN_PAREN))
|
||||
{
|
||||
skip_newlines ();
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
while (!token_is (TOK_CLOSE_PAREN))
|
||||
{
|
||||
skip_newlines ();
|
||||
}
|
||||
|
||||
return true;
|
||||
} /* skip_optional_name_and_parens */
|
||||
|
||||
static void
|
||||
skip_function (void)
|
||||
{
|
||||
skip_newlines ();
|
||||
if (skip_optional_name_and_parens ())
|
||||
{
|
||||
skip_newlines ();
|
||||
jsp_skip_braces (TOK_OPEN_BRACE);
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
var_declared (lit_cpointer_t var_cp)
|
||||
{
|
||||
return dumper_variable_declaration_exists (var_cp);
|
||||
}
|
||||
|
||||
static void
|
||||
preparse_scope (bool is_global)
|
||||
check_directive_prologue_for_use_strict ()
|
||||
{
|
||||
const locus start_loc = tok.loc;
|
||||
const token_type end_tt = is_global ? TOK_EOF : TOK_CLOSE_BRACE;
|
||||
|
||||
vm_instr_counter_t scope_code_flags_oc = dump_scope_code_flags_for_rewrite ();
|
||||
|
||||
bool is_use_strict = false;
|
||||
bool is_ref_arguments_identifier = false;
|
||||
bool is_ref_eval_identifier = false;
|
||||
|
||||
/*
|
||||
* Check Directive Prologue for Use Strict directive (see ECMA-262 5.1 section 14.1)
|
||||
@@ -2954,7 +2921,8 @@ preparse_scope (bool is_global)
|
||||
if (lit_literal_equal_type_cstr (lit_get_literal_by_cp (token_data_as_lit_cp ()), "use strict")
|
||||
&& lexer_is_no_escape_sequences_in_token_string (tok))
|
||||
{
|
||||
is_use_strict = true;
|
||||
scopes_tree_set_strict_mode (STACK_TOP (scopes), true);
|
||||
lexer_set_strict_mode (scopes_tree_strict_mode (STACK_TOP (scopes)));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -2966,186 +2934,15 @@ preparse_scope (bool is_global)
|
||||
}
|
||||
}
|
||||
|
||||
size_t nesting_level = 0;
|
||||
while (nesting_level > 0 || !token_is (end_tt))
|
||||
{
|
||||
if (token_is (TOK_OPEN_BRACE))
|
||||
{
|
||||
nesting_level++;
|
||||
}
|
||||
else if (token_is (TOK_CLOSE_BRACE))
|
||||
{
|
||||
nesting_level--;
|
||||
}
|
||||
else if (token_is (TOK_NAME))
|
||||
{
|
||||
if (lit_literal_equal_type_cstr (lit_get_literal_by_cp (token_data_as_lit_cp ()), "arguments"))
|
||||
{
|
||||
is_ref_arguments_identifier = true;
|
||||
}
|
||||
else if (lit_literal_equal_type_cstr (lit_get_literal_by_cp (token_data_as_lit_cp ()), "eval"))
|
||||
{
|
||||
is_ref_eval_identifier = true;
|
||||
}
|
||||
}
|
||||
|
||||
skip_newlines ();
|
||||
}
|
||||
|
||||
opcode_scope_code_flags_t scope_flags = OPCODE_SCOPE_CODE_FLAGS__EMPTY;
|
||||
|
||||
if (is_use_strict)
|
||||
{
|
||||
scopes_tree_set_strict_mode (STACK_TOP (scopes), true);
|
||||
|
||||
scope_flags = (opcode_scope_code_flags_t) (scope_flags | OPCODE_SCOPE_CODE_FLAGS_STRICT);
|
||||
}
|
||||
|
||||
if (!is_ref_arguments_identifier)
|
||||
{
|
||||
scope_flags = (opcode_scope_code_flags_t) (scope_flags | OPCODE_SCOPE_CODE_FLAGS_NOT_REF_ARGUMENTS_IDENTIFIER);
|
||||
}
|
||||
|
||||
if (!is_ref_eval_identifier)
|
||||
{
|
||||
scope_flags = (opcode_scope_code_flags_t) (scope_flags | OPCODE_SCOPE_CODE_FLAGS_NOT_REF_EVAL_IDENTIFIER);
|
||||
}
|
||||
|
||||
rewrite_scope_code_flags (scope_code_flags_oc, scope_flags);
|
||||
|
||||
lexer_set_strict_mode (scopes_tree_strict_mode (STACK_TOP (scopes)));
|
||||
|
||||
dump_reg_var_decl_for_rewrite ();
|
||||
|
||||
if (lit_utf8_iterator_pos_cmp (start_loc, tok.loc) != 0)
|
||||
{
|
||||
lexer_seek (start_loc);
|
||||
skip_newlines ();
|
||||
|
||||
bool is_in_var_declaration_list = false;
|
||||
|
||||
size_t nesting_level = 0;
|
||||
while (nesting_level > 0 || !token_is (end_tt))
|
||||
{
|
||||
/*
|
||||
* FIXME:
|
||||
* Remove preparse_scope; move variable declaration search to main pass of parser.
|
||||
* When byte-code and scope storages would be introduced, move variable declarations
|
||||
* from byte-code to scope descriptor.
|
||||
*/
|
||||
if (token_is (TOK_NAME))
|
||||
{
|
||||
if (is_in_var_declaration_list)
|
||||
{
|
||||
if (!var_declared (token_data_as_lit_cp ()))
|
||||
{
|
||||
jsp_early_error_check_for_eval_and_arguments_in_strict_mode (literal_operand (token_data_as_lit_cp ()),
|
||||
is_strict_mode (),
|
||||
tok.loc);
|
||||
dump_variable_declaration (token_data_as_lit_cp ());
|
||||
}
|
||||
}
|
||||
|
||||
skip_newlines ();
|
||||
|
||||
if (!token_is (TOK_COMMA)
|
||||
&& !token_is (TOK_EQ))
|
||||
{
|
||||
is_in_var_declaration_list = false;
|
||||
}
|
||||
}
|
||||
else if (is_in_var_declaration_list)
|
||||
{
|
||||
if (token_is (TOK_EQ))
|
||||
{
|
||||
skip_newlines ();
|
||||
|
||||
while (!token_is (end_tt)
|
||||
&& !token_is (TOK_COMMA)
|
||||
&& !token_is (TOK_SEMICOLON))
|
||||
{
|
||||
if (is_keyword (KW_FUNCTION))
|
||||
{
|
||||
skip_function ();
|
||||
}
|
||||
else if (token_is (TOK_OPEN_BRACE))
|
||||
{
|
||||
jsp_skip_braces (TOK_OPEN_BRACE);
|
||||
}
|
||||
else if (token_is (TOK_OPEN_SQUARE))
|
||||
{
|
||||
jsp_skip_braces (TOK_OPEN_SQUARE);
|
||||
}
|
||||
else if (token_is (TOK_OPEN_PAREN))
|
||||
{
|
||||
jsp_skip_braces (TOK_OPEN_PAREN);
|
||||
}
|
||||
else if (token_is (TOK_KEYWORD))
|
||||
{
|
||||
if (is_keyword (KW_VAR))
|
||||
{
|
||||
is_in_var_declaration_list = false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
else if (token_is (TOK_CLOSE_BRACE))
|
||||
{
|
||||
/* the '}' would be handled during next iteration, reducing nesting level counter */
|
||||
is_in_var_declaration_list = false;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
skip_token ();
|
||||
}
|
||||
}
|
||||
else if (token_is (TOK_COMMA))
|
||||
{
|
||||
skip_newlines ();
|
||||
}
|
||||
else
|
||||
{
|
||||
is_in_var_declaration_list = false;
|
||||
|
||||
skip_newlines ();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (token_is (TOK_OPEN_BRACE))
|
||||
{
|
||||
nesting_level++;
|
||||
}
|
||||
else if (token_is (TOK_CLOSE_BRACE))
|
||||
{
|
||||
nesting_level--;
|
||||
}
|
||||
else if (token_is (TOK_OPEN_SQUARE))
|
||||
{
|
||||
jsp_skip_braces (TOK_OPEN_SQUARE);
|
||||
}
|
||||
else if (is_keyword (KW_VAR))
|
||||
{
|
||||
is_in_var_declaration_list = true;
|
||||
}
|
||||
else if (is_keyword (KW_FUNCTION))
|
||||
{
|
||||
skip_function ();
|
||||
}
|
||||
|
||||
skip_newlines ();
|
||||
}
|
||||
}
|
||||
|
||||
lexer_seek (start_loc);
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (token_is (end_tt));
|
||||
|
||||
lexer_save_token (tok);
|
||||
}
|
||||
}
|
||||
} /* check_directive_prologue_for_use_strict */
|
||||
|
||||
/**
|
||||
* Parse source element list
|
||||
@@ -3155,10 +2952,17 @@ preparse_scope (bool is_global)
|
||||
* ;
|
||||
*/
|
||||
static void
|
||||
parse_source_element_list (bool is_global) /**< flag indicating if we are parsing the global scope */
|
||||
parse_source_element_list (bool is_global) /**< flag, indicating that we parsing global context */
|
||||
{
|
||||
const token_type end_tt = is_global ? TOK_EOF : TOK_CLOSE_BRACE;
|
||||
|
||||
dumper_new_scope ();
|
||||
preparse_scope (is_global);
|
||||
|
||||
vm_instr_counter_t scope_code_flags_oc = dump_scope_code_flags_for_rewrite ();
|
||||
|
||||
check_directive_prologue_for_use_strict ();
|
||||
|
||||
dump_reg_var_decl_for_rewrite ();
|
||||
|
||||
if (inside_eval
|
||||
&& !inside_function)
|
||||
@@ -3172,7 +2976,33 @@ parse_source_element_list (bool is_global) /**< flag indicating if we are parsin
|
||||
parse_source_element ();
|
||||
skip_newlines ();
|
||||
}
|
||||
|
||||
if (!token_is (end_tt))
|
||||
{
|
||||
PARSE_ERROR (JSP_EARLY_ERROR_SYNTAX, "Unexpected token", tok.loc);
|
||||
}
|
||||
|
||||
lexer_save_token (tok);
|
||||
|
||||
opcode_scope_code_flags_t scope_flags = OPCODE_SCOPE_CODE_FLAGS__EMPTY;
|
||||
|
||||
scopes_tree fe_scope_tree = STACK_TOP (scopes);
|
||||
if (fe_scope_tree->strict_mode)
|
||||
{
|
||||
scope_flags = (opcode_scope_code_flags_t) (scope_flags | OPCODE_SCOPE_CODE_FLAGS_STRICT);
|
||||
}
|
||||
|
||||
if (!fe_scope_tree->ref_arguments)
|
||||
{
|
||||
scope_flags = (opcode_scope_code_flags_t) (scope_flags | OPCODE_SCOPE_CODE_FLAGS_NOT_REF_ARGUMENTS_IDENTIFIER);
|
||||
}
|
||||
|
||||
if (!fe_scope_tree->ref_eval)
|
||||
{
|
||||
scope_flags = (opcode_scope_code_flags_t) (scope_flags | OPCODE_SCOPE_CODE_FLAGS_NOT_REF_EVAL_IDENTIFIER);
|
||||
}
|
||||
rewrite_scope_code_flags (scope_code_flags_oc, scope_flags);
|
||||
|
||||
rewrite_reg_var_decl ();
|
||||
dumper_finish_scope ();
|
||||
} /* parse_source_element_list */
|
||||
|
||||
Reference in New Issue
Block a user