29
29
#include " opcodes-dumper.h"
30
30
#include " serializer.h"
31
31
32
- #define NESTING_ITERATIONAL 1
33
- #define NESTING_SWITCH 2
34
- #define NESTING_FUNCTION 3
32
+ /* *
33
+ * Nesting types
34
+ *
35
+ * Note:
36
+ * Nesting is an element, describing classes of syntax blocks, handled by parser.
37
+ *
38
+ * Nestings are pushed to the nestings stack upon entering them, and popped upon leaving.
39
+ *
40
+ * The top-most nesting, if any, describes the inner-most syntax block of specified type,
41
+ * currently reached by parser.
42
+ */
43
+ typedef enum
44
+ {
45
+ NESTING_ITERATIONAL, /* *< an iterational (for, for-in, while, do-while) statement */
46
+ NESTING_SWITCH, /* *< switch-case block */
47
+ NESTING_FUNCTION, /* *< function */
48
+ NESTING_TRY, /* *< try-catch-finally block */
49
+ NESTING_WITH /* *< with block */
50
+ } nesting_t ;
35
51
36
52
static token tok;
37
53
38
54
enum
39
55
{
40
56
nestings_global_size
41
57
};
42
- STATIC_STACK (nestings, uint8_t )
58
+ STATIC_STACK (nestings, nesting_t )
43
59
44
60
enum
45
61
{
@@ -56,7 +72,12 @@ STATIC_STACK (scopes, scopes_tree)
56
72
: I == NESTING_ITERATIONAL \
57
73
? " iterational" \
58
74
: I == NESTING_SWITCH \
59
- ? " switch" : " unknown" )
75
+ ? " switch" \
76
+ : I == NESTING_TRY \
77
+ ? " try" \
78
+ : I == NESTING_WITH \
79
+ ? " with" \
80
+ : " unknown" )
60
81
61
82
#define OPCODE_IS (OP, ID ) (OP.op_idx == __op__idx_##ID)
62
83
@@ -69,18 +90,24 @@ static void process_keyword_names (void);
69
90
static void skip_braces (void );
70
91
static void skip_parens (void );
71
92
93
+ /* *
94
+ * Push a nesting to the nesting stack, so setting new current nesting
95
+ */
72
96
static void
73
- push_nesting (uint8_t nesting_type)
97
+ push_nesting (nesting_t nesting_type) /* *< type of new nesting */
74
98
{
75
99
STACK_PUSH (nestings, nesting_type);
76
- }
100
+ } /* push_nesting */
77
101
102
+ /* *
103
+ * Restore nesting from nestings stack
104
+ */
78
105
static void
79
- pop_nesting (uint8_t nesting_type)
106
+ pop_nesting (nesting_t nesting_type) /* *< type of current nesting */
80
107
{
81
108
JERRY_ASSERT (STACK_HEAD (nestings, 1 ) == nesting_type);
82
109
STACK_DROP (nestings, 1 );
83
- }
110
+ } /* pop_nesting */
84
111
85
112
static void
86
113
must_be_inside_but_not_in (uint8_t not_in, uint8_t insides_count, ...)
@@ -1992,10 +2019,15 @@ parse_with_statement (void)
1992
2019
EMIT_ERROR (" 'with' expression is not allowed in strict mode." );
1993
2020
}
1994
2021
const operand expr = parse_expression_inside_parens ();
2022
+
2023
+ push_nesting (NESTING_WITH);
2024
+
1995
2025
dump_with (expr);
1996
2026
skip_newlines ();
1997
2027
parse_statement ();
1998
2028
dump_with_end ();
2029
+
2030
+ pop_nesting (NESTING_WITH);
1999
2031
}
2000
2032
2001
2033
static void
@@ -2165,6 +2197,8 @@ parse_try_statement (void)
2165
2197
{
2166
2198
assert_keyword (KW_TRY);
2167
2199
2200
+ push_nesting (NESTING_TRY);
2201
+
2168
2202
dump_try_for_rewrite ();
2169
2203
2170
2204
token_after_newlines_must_be (TOK_OPEN_BRACE);
@@ -2199,6 +2233,8 @@ parse_try_statement (void)
2199
2233
}
2200
2234
2201
2235
dump_end_try_catch_finally ();
2236
+
2237
+ pop_nesting (NESTING_TRY);
2202
2238
}
2203
2239
2204
2240
static void
@@ -2346,13 +2382,24 @@ parse_statement (void)
2346
2382
}
2347
2383
if (is_keyword (KW_CONTINUE))
2348
2384
{
2385
+ must_be_inside_but_not_in (NESTING_FUNCTION,
2386
+ 4 ,
2387
+ NESTING_ITERATIONAL,
2388
+ NESTING_TRY,
2389
+ NESTING_WITH);
2390
+
2349
2391
must_be_inside_but_not_in (NESTING_FUNCTION, 1 , NESTING_ITERATIONAL);
2350
2392
dump_continue_for_rewrite ();
2351
2393
return ;
2352
2394
}
2353
2395
if (is_keyword (KW_BREAK))
2354
2396
{
2355
- must_be_inside_but_not_in (NESTING_FUNCTION, 2 , NESTING_ITERATIONAL, NESTING_SWITCH);
2397
+ must_be_inside_but_not_in (NESTING_FUNCTION,
2398
+ 4 ,
2399
+ NESTING_ITERATIONAL,
2400
+ NESTING_SWITCH,
2401
+ NESTING_TRY,
2402
+ NESTING_WITH);
2356
2403
dump_break_for_rewrite ();
2357
2404
return ;
2358
2405
}
0 commit comments