4343 * Parser statement types.
4444 *
4545 * When a new statement is added, the following
46- * functions may need to be updated as well:
47- *
48- * - parser_statement_length()
49- * - parser_parse_break_statement()
50- * - parser_parse_continue_statement()
51- * - parser_free_jumps()
52- * - 'case LEXER_RIGHT_BRACE:' in parser_parse_statements()
53- * - 'if (context_p->token.type == LEXER_RIGHT_BRACE)' in parser_parse_statements()
54- * - 'switch (context_p->stack_top_uint8)' in parser_parse_statements()
46+ * arrays must be updated as well:
47+ * - statement_lengths[]
48+ * - parser_statement_flags[]
5549 */
5650typedef enum
5751{
@@ -66,16 +60,11 @@ typedef enum
6660 PARSER_STATEMENT_LABEL ,
6761 PARSER_STATEMENT_IF ,
6862 PARSER_STATEMENT_ELSE ,
69- /* From switch -> for-in : break target statements */
7063 PARSER_STATEMENT_SWITCH ,
7164 PARSER_STATEMENT_SWITCH_NO_DEFAULT ,
72- /* From do-while -> for->in : continue target statements */
7365 PARSER_STATEMENT_DO_WHILE ,
7466 PARSER_STATEMENT_WHILE ,
7567 PARSER_STATEMENT_FOR ,
76- /* From for->in -> try : instructions with context
77- * Break and continue uses another instruction form
78- * when crosses their borders. */
7968 PARSER_STATEMENT_FOR_IN ,
8069#if ENABLED (JERRY_ES2015 )
8170 PARSER_STATEMENT_FOR_OF ,
@@ -84,6 +73,66 @@ typedef enum
8473 PARSER_STATEMENT_TRY ,
8574} parser_statement_type_t ;
8675
76+ /**
77+ * Parser statement type flags.
78+ */
79+ typedef enum
80+ {
81+ PARSER_STATM_NO_OPTS = 0 , /**< no options */
82+ PARSER_STATM_SINGLE_STATM = (1 << 0 ), /**< statment can form single statement context */
83+ PARSER_STATM_BREAK_TARGET = (1 << 1 ), /**< break target statement */
84+ PARSER_STATM_CONTINUE_TARGET = (1 << 2 ), /**< continue target statement */
85+ PARSER_STATM_CONTEXT_BREAK = (1 << 3 ), /**< uses another instruction form when crosses their borders */
86+ } parser_statement_flags_t ;
87+
88+ /**
89+ * Parser statement attributes.
90+ * Note: the order of the attributes must be keep in sync with parser_statement_type_t
91+ */
92+ static const uint8_t parser_statement_flags [] =
93+ {
94+ /* PARSER_STATEMENT_START */
95+ PARSER_STATM_NO_OPTS ,
96+ /* PARSER_STATEMENT_BLOCK, */
97+ PARSER_STATM_NO_OPTS ,
98+ #if ENABLED (JERRY_ES2015 )
99+ /* PARSER_STATEMENT_BLOCK_SCOPE, */
100+ PARSER_STATM_NO_OPTS ,
101+ /* PARSER_STATEMENT_PRIVATE_SCOPE, */
102+ PARSER_STATM_NO_OPTS ,
103+ /* PARSER_STATEMENT_BLOCK_CONTEXT, */
104+ PARSER_STATM_CONTEXT_BREAK ,
105+ /* PARSER_STATEMENT_PRIVATE_CONTEXT, */
106+ PARSER_STATM_NO_OPTS ,
107+ #endif /* ENABLED (JERRY_ES2015) */
108+ /* PARSER_STATEMENT_LABEL */
109+ PARSER_STATM_SINGLE_STATM ,
110+ /* PARSER_STATEMENT_IF */
111+ PARSER_STATM_SINGLE_STATM ,
112+ /* PARSER_STATEMENT_ELSE */
113+ PARSER_STATM_SINGLE_STATM ,
114+ /* PARSER_STATEMENT_SWITCH */
115+ PARSER_STATM_BREAK_TARGET ,
116+ /* PARSER_STATEMENT_SWITCH_NO_DEFAULT */
117+ PARSER_STATM_BREAK_TARGET ,
118+ /* PARSER_STATEMENT_DO_WHILE */
119+ PARSER_STATM_BREAK_TARGET | PARSER_STATM_CONTINUE_TARGET | PARSER_STATM_SINGLE_STATM ,
120+ /* PARSER_STATEMENT_WHILE */
121+ PARSER_STATM_BREAK_TARGET | PARSER_STATM_CONTINUE_TARGET | PARSER_STATM_SINGLE_STATM ,
122+ /* PARSER_STATEMENT_FOR */
123+ PARSER_STATM_BREAK_TARGET | PARSER_STATM_CONTINUE_TARGET | PARSER_STATM_SINGLE_STATM ,
124+ /* PARSER_STATEMENT_FOR_IN */
125+ PARSER_STATM_BREAK_TARGET | PARSER_STATM_CONTINUE_TARGET | PARSER_STATM_SINGLE_STATM | PARSER_STATM_CONTEXT_BREAK ,
126+ #if ENABLED (JERRY_ES2015 )
127+ /* PARSER_STATEMENT_FOR_OF */
128+ PARSER_STATM_BREAK_TARGET | PARSER_STATM_CONTINUE_TARGET | PARSER_STATM_SINGLE_STATM | PARSER_STATM_CONTEXT_BREAK ,
129+ #endif /* ENABLED (JERRY_ES2015) */
130+ /* PARSER_STATEMENT_WITH */
131+ PARSER_STATM_CONTEXT_BREAK | PARSER_STATM_SINGLE_STATM ,
132+ /* PARSER_STATEMENT_TRY */
133+ PARSER_STATM_CONTEXT_BREAK
134+ };
135+
87136#if !ENABLED (JERRY_ES2015 )
88137
89138/**
@@ -1886,15 +1935,7 @@ parser_parse_break_statement (parser_context_t *context_p) /**< context */
18861935 parser_raise_error (context_p , PARSER_ERR_INVALID_BREAK_LABEL );
18871936 }
18881937
1889- if (type == PARSER_STATEMENT_FOR_IN
1890- #if ENABLED (JERRY_ES2015 )
1891- || type == PARSER_STATEMENT_FOR_OF
1892- #endif /* ENABLED (JERRY_ES2015) */
1893- || type == PARSER_STATEMENT_WITH
1894- #if ENABLED (JERRY_ES2015 )
1895- || type == PARSER_STATEMENT_BLOCK_CONTEXT
1896- #endif /* ENABLED (JERRY_ES2015) */
1897- || type == PARSER_STATEMENT_TRY )
1938+ if (parser_statement_flags [type ] & PARSER_STATM_CONTEXT_BREAK )
18981939 {
18991940 opcode = CBC_JUMP_FORWARD_EXIT_CONTEXT ;
19001941 }
@@ -1933,28 +1974,12 @@ parser_parse_break_statement (parser_context_t *context_p) /**< context */
19331974 parser_raise_error (context_p , PARSER_ERR_INVALID_BREAK );
19341975 }
19351976
1936- if (type == PARSER_STATEMENT_FOR_IN
1937- #if ENABLED (JERRY_ES2015 )
1938- || type == PARSER_STATEMENT_FOR_OF
1939- #endif /* ENABLED (JERRY_ES2015) */
1940- || type == PARSER_STATEMENT_WITH
1941- #if ENABLED (JERRY_ES2015 )
1942- || type == PARSER_STATEMENT_BLOCK_CONTEXT
1943- #endif /* ENABLED (JERRY_ES2015) */
1944- || type == PARSER_STATEMENT_TRY )
1977+ if (parser_statement_flags [type ] & PARSER_STATM_CONTEXT_BREAK )
19451978 {
19461979 opcode = CBC_JUMP_FORWARD_EXIT_CONTEXT ;
19471980 }
19481981
1949- if (type == PARSER_STATEMENT_SWITCH
1950- || type == PARSER_STATEMENT_SWITCH_NO_DEFAULT
1951- || type == PARSER_STATEMENT_DO_WHILE
1952- || type == PARSER_STATEMENT_WHILE
1953- || type == PARSER_STATEMENT_FOR
1954- #if ENABLED (JERRY_ES2015 )
1955- || type == PARSER_STATEMENT_FOR_OF
1956- #endif /* ENABLED (JERRY_ES2015) */
1957- || type == PARSER_STATEMENT_FOR_IN )
1982+ if (parser_statement_flags [type ] & PARSER_STATM_BREAK_TARGET )
19581983 {
19591984 parser_loop_statement_t loop ;
19601985
@@ -1988,7 +2013,6 @@ parser_parse_continue_statement (parser_context_t *context_p) /**< context */
19882013 && context_p -> token .lit_location .type == LEXER_IDENT_LITERAL )
19892014 {
19902015 parser_stack_iterator_t loop_iterator ;
1991- bool for_in_of_was_seen = false;
19922016
19932017 loop_iterator .current_p = NULL ;
19942018
@@ -2028,33 +2052,12 @@ parser_parse_continue_statement (parser_context_t *context_p) /**< context */
20282052 continue ;
20292053 }
20302054
2031- #if ENABLED (JERRY_ES2015 )
2032- bool is_for_in_of_statement = (type == PARSER_STATEMENT_FOR_IN ) || (type == PARSER_STATEMENT_FOR_OF );
2033- #else /* !ENABLED (JERRY_ES2015) */
2034- bool is_for_in_of_statement = (type == PARSER_STATEMENT_FOR_IN );
2035- #endif /* ENABLED (JERRY_ES2015) */
2036-
2037- if (type == PARSER_STATEMENT_WITH
2038- #if ENABLED (JERRY_ES2015 )
2039- || type == PARSER_STATEMENT_BLOCK_CONTEXT
2040- #endif /* ENABLED (JERRY_ES2015) */
2041- || type == PARSER_STATEMENT_TRY
2042- || for_in_of_was_seen )
2055+ if (parser_statement_flags [type ] & PARSER_STATM_CONTEXT_BREAK )
20432056 {
20442057 opcode = CBC_JUMP_FORWARD_EXIT_CONTEXT ;
20452058 }
2046- else if (is_for_in_of_statement )
2047- {
2048- for_in_of_was_seen = true;
2049- }
20502059
2051- if (type == PARSER_STATEMENT_DO_WHILE
2052- || type == PARSER_STATEMENT_WHILE
2053- || type == PARSER_STATEMENT_FOR
2054- #if ENABLED (JERRY_ES2015 )
2055- || type == PARSER_STATEMENT_FOR_OF
2056- #endif /* ENABLED (JERRY_ES2015) */
2057- || type == PARSER_STATEMENT_FOR_IN )
2060+ if (parser_statement_flags [type ] & PARSER_STATM_CONTINUE_TARGET )
20582061 {
20592062 loop_iterator = iterator ;
20602063 }
@@ -2076,13 +2079,7 @@ parser_parse_continue_statement (parser_context_t *context_p) /**< context */
20762079 parser_raise_error (context_p , PARSER_ERR_INVALID_CONTINUE );
20772080 }
20782081
2079- if (type == PARSER_STATEMENT_DO_WHILE
2080- || type == PARSER_STATEMENT_WHILE
2081- || type == PARSER_STATEMENT_FOR
2082- #if ENABLED (JERRY_ES2015 )
2083- || type == PARSER_STATEMENT_FOR_OF
2084- #endif /* ENABLED (JERRY_ES2015) */
2085- || type == PARSER_STATEMENT_FOR_IN )
2082+ if (parser_statement_flags [type ] & PARSER_STATM_CONTINUE_TARGET )
20862083 {
20872084 parser_loop_statement_t loop ;
20882085
@@ -2096,11 +2093,7 @@ parser_parse_continue_statement (parser_context_t *context_p) /**< context */
20962093 return ;
20972094 }
20982095
2099- if (type == PARSER_STATEMENT_WITH
2100- #if ENABLED (JERRY_ES2015 )
2101- || type == PARSER_STATEMENT_BLOCK_CONTEXT
2102- #endif /* ENABLED (JERRY_ES2015) */
2103- || type == PARSER_STATEMENT_TRY )
2096+ if (parser_statement_flags [type ] & PARSER_STATM_CONTEXT_BREAK )
21042097 {
21052098 opcode = CBC_JUMP_FORWARD_EXIT_CONTEXT ;
21062099 }
@@ -2572,17 +2565,7 @@ parser_parse_statements (parser_context_t *context_p) /**< context */
25722565
25732566 case LEXER_RIGHT_BRACE :
25742567 {
2575- if (context_p -> stack_top_uint8 == PARSER_STATEMENT_LABEL
2576- || context_p -> stack_top_uint8 == PARSER_STATEMENT_IF
2577- || context_p -> stack_top_uint8 == PARSER_STATEMENT_ELSE
2578- || context_p -> stack_top_uint8 == PARSER_STATEMENT_DO_WHILE
2579- || context_p -> stack_top_uint8 == PARSER_STATEMENT_WHILE
2580- || context_p -> stack_top_uint8 == PARSER_STATEMENT_FOR
2581- || context_p -> stack_top_uint8 == PARSER_STATEMENT_FOR_IN
2582- #if ENABLED (JERRY_ES2015 )
2583- || context_p -> stack_top_uint8 == PARSER_STATEMENT_FOR_OF
2584- #endif /* ENABLED (JERRY_ES2015) */
2585- || context_p -> stack_top_uint8 == PARSER_STATEMENT_WITH )
2568+ if (parser_statement_flags [context_p -> stack_top_uint8 ] & PARSER_STATM_SINGLE_STATM )
25862569 {
25872570 parser_raise_error (context_p , PARSER_ERR_STATEMENT_EXPECTED );
25882571 }
0 commit comments