diff --git a/jerry-core/parser/js/parser.cpp b/jerry-core/parser/js/parser.cpp index 08645eec5..788fb9573 100644 --- a/jerry-core/parser/js/parser.cpp +++ b/jerry-core/parser/js/parser.cpp @@ -2650,12 +2650,14 @@ preparse_scope (bool is_global) opcode_counter_t scope_code_flags_oc = dump_scope_code_flags_for_rewrite (); - opcode_scope_code_flags_t scope_flags = OPCODE_SCOPE_CODE_FLAGS__NO_FLAGS; + bool is_ref_arguments_identifier = false; + bool is_ref_eval_identifier = false; + bool is_use_strict = false; if (token_is (TOK_STRING) && literal_equal_s (lexer_get_literal_by_id (token_data ()), "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); + is_use_strict = true; } lexer_set_strict_mode (scopes_tree_strict_mode (STACK_TOP (scopes))); @@ -2687,11 +2689,43 @@ preparse_scope (bool is_global) } else { + if (token_is (TOK_NAME)) + { + if (literal_equal_type_s (lexer_get_literal_by_id (token_data ()), + "arguments")) + { + is_ref_arguments_identifier = true; + } + + if (literal_equal_type_s (lexer_get_literal_by_id (token_data ()), + "eval")) + { + is_ref_eval_identifier = true; + } + } + process_keyword_names (); } skip_newlines (); } + opcode_scope_code_flags_t scope_flags = OPCODE_SCOPE_CODE_FLAGS__EMPTY; + + if (is_use_strict) + { + 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); if (start_loc != tok.loc) diff --git a/jerry-core/vm/opcodes.h b/jerry-core/vm/opcodes.h index dab0543cb..7996ebd21 100644 --- a/jerry-core/vm/opcodes.h +++ b/jerry-core/vm/opcodes.h @@ -79,8 +79,12 @@ typedef enum */ typedef enum : idx_t { - OPCODE_SCOPE_CODE_FLAGS__NO_FLAGS = (0u), /**< initializer for empty flag set */ - OPCODE_SCOPE_CODE_FLAGS_STRICT = (1u << 0), /**< code is strict mode code */ + OPCODE_SCOPE_CODE_FLAGS__EMPTY = (0u), /**< initializer for empty flag set */ + OPCODE_SCOPE_CODE_FLAGS_STRICT = (1u << 0), /**< code is strict mode code */ + OPCODE_SCOPE_CODE_FLAGS_NOT_REF_ARGUMENTS_IDENTIFIER = (1u << 1), /**< code doesn't reference + * 'arguments' identifier */ + OPCODE_SCOPE_CODE_FLAGS_NOT_REF_EVAL_IDENTIFIER = (1u << 2) /**< code doesn't reference + * 'eval' identifier */ } opcode_scope_code_flags_t; /** diff --git a/jerry-core/vm/pretty-printer.cpp b/jerry-core/vm/pretty-printer.cpp index 6bf6eb3f4..244175993 100644 --- a/jerry-core/vm/pretty-printer.cpp +++ b/jerry-core/vm/pretty-printer.cpp @@ -627,15 +627,32 @@ pp_op_meta (opcode_counter_t oc, op_meta opm, bool rewrite) } case OPCODE_META_TYPE_SCOPE_CODE_FLAGS: { - idx_t scope_flags = opm.op.data.meta.data_1; - - if (scope_flags & OPCODE_SCOPE_CODE_FLAGS_STRICT) + if (opm.op.data.meta.data_1 != INVALID_VALUE) { - printf ("[use strict] "); - scope_flags &= (idx_t) ~(OPCODE_SCOPE_CODE_FLAGS_STRICT); - } + idx_t scope_flags = opm.op.data.meta.data_1; - JERRY_ASSERT (scope_flags == 0); + if (scope_flags & OPCODE_SCOPE_CODE_FLAGS_STRICT) + { + printf ("[use strict] "); + scope_flags &= (idx_t) ~(OPCODE_SCOPE_CODE_FLAGS_STRICT); + } + if (scope_flags & OPCODE_SCOPE_CODE_FLAGS_NOT_REF_ARGUMENTS_IDENTIFIER) + { + printf ("[no 'arguments'] "); + scope_flags &= (idx_t) ~(OPCODE_SCOPE_CODE_FLAGS_NOT_REF_ARGUMENTS_IDENTIFIER); + } + if (scope_flags & OPCODE_SCOPE_CODE_FLAGS_NOT_REF_EVAL_IDENTIFIER) + { + printf ("[no 'eval'] "); + scope_flags &= (idx_t) ~(OPCODE_SCOPE_CODE_FLAGS_NOT_REF_EVAL_IDENTIFIER); + } + + JERRY_ASSERT (scope_flags == 0); + } + else + { + printf ("[to be rewritten]"); + } break; } diff --git a/tests/unit/test_preparser.cpp b/tests/unit/test_preparser.cpp index c6e569050..d551bb8ae 100644 --- a/tests/unit/test_preparser.cpp +++ b/tests/unit/test_preparser.cpp @@ -41,7 +41,8 @@ main (int __attr_unused___ argc, opcode_t opcodes[] = { getop_meta (OPCODE_META_TYPE_SCOPE_CODE_FLAGS, // [ ] - OPCODE_SCOPE_CODE_FLAGS__NO_FLAGS, + OPCODE_SCOPE_CODE_FLAGS_NOT_REF_ARGUMENTS_IDENTIFIER + | OPCODE_SCOPE_CODE_FLAGS_NOT_REF_EVAL_IDENTIFIER, INVALID_VALUE), getop_reg_var_decl (128, 129), // var tmp128 .. tmp129; getop_var_decl (0), // var a;