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:
Andrey Shitov
2015-08-12 15:50:16 +03:00
parent cc4283b945
commit a870a07972
7 changed files with 352 additions and 344 deletions
+62 -232
View File
@@ -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 */