Skip to content

Commit 4ac694a

Browse files
committed
Introduce parser statement flags
These flags makes the code more readable also makes the process of introducing a new statement type easier. JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik [email protected]
1 parent 8eda9bc commit 4ac694a

File tree

1 file changed

+71
-88
lines changed

1 file changed

+71
-88
lines changed

jerry-core/parser/js/js-parser-statm.c

Lines changed: 71 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,9 @@
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
*/
5650
typedef 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

Comments
 (0)