Fix break and continue generation
This commit is contained in:
@@ -296,8 +296,8 @@ do { STACK_SET_ELEMENT (NAME, I, (NAME##_stack_value_type) (STACK_ELEMENT(NAME,
|
||||
#define STACK_DECR_ELEMENT(NAME, I) \
|
||||
do { STACK_SET_ELEMENT (NAME, I, (NAME##_stack_value_type) (STACK_ELEMENT(NAME, I) - 1)); } while (0)
|
||||
|
||||
#define STACK_ITERATE_VARG(NAME, FUNC, ...) \
|
||||
do { for (NAME##_stack_data_type i = 0; i < NAME.current; i++) { \
|
||||
#define STACK_ITERATE_VARG(NAME, FUNC, FROM, ...) \
|
||||
do { for (NAME##_stack_data_type i = FROM; i < NAME.current; i++) { \
|
||||
FUNC (STACK_ELEMENT (NAME, i), __VA_ARGS__); \
|
||||
} } while (0)
|
||||
|
||||
|
||||
+43
-14
@@ -533,11 +533,19 @@ rewrite_breaks (opcode_counter_t break_oc, opcode_counter_t dest_oc)
|
||||
static void
|
||||
rewrite_continues (opcode_counter_t cont_oc, opcode_counter_t dest_oc)
|
||||
{
|
||||
REWRITE_JMP (cont_oc, jmp_up, cont_oc - dest_oc);
|
||||
if (cont_oc > dest_oc)
|
||||
{
|
||||
REWRITE_JMP (cont_oc, jmp_up, cont_oc - dest_oc);
|
||||
}
|
||||
else
|
||||
{
|
||||
// in case of do-while loop we must jump to condition
|
||||
REWRITE_JMP (cont_oc, jmp_up, dest_oc - cont_oc);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
rewrite_rewritable_opcodes (rewritable_opcode_type type, opcode_counter_t oc)
|
||||
rewrite_rewritable_opcodes (rewritable_opcode_type type, uint8_t from, opcode_counter_t oc)
|
||||
{
|
||||
STACK_DECLARE_USAGE (U8)
|
||||
|
||||
@@ -547,13 +555,13 @@ rewrite_rewritable_opcodes (rewritable_opcode_type type, opcode_counter_t oc)
|
||||
{
|
||||
case REWRITABLE_BREAK:
|
||||
{
|
||||
STACK_ITERATE_VARG (rewritable_break, rewrite_breaks, oc);
|
||||
STACK_ITERATE_VARG (rewritable_break, rewrite_breaks, from, oc);
|
||||
STACK_CLEAN (rewritable_break);
|
||||
break;
|
||||
}
|
||||
case REWRITABLE_CONTINUE:
|
||||
{
|
||||
STACK_ITERATE_VARG (rewritable_continue, rewrite_continues, oc);
|
||||
STACK_ITERATE_VARG (rewritable_continue, rewrite_continues, from, oc);
|
||||
STACK_CLEAN (rewritable_continue);
|
||||
break;
|
||||
}
|
||||
@@ -2461,6 +2469,7 @@ parse_for_or_for_in_statement (void)
|
||||
STACK_DECLARE_USAGE (IDX)
|
||||
STACK_DECLARE_USAGE (U16)
|
||||
STACK_DECLARE_USAGE (nestings)
|
||||
STACK_DECLARE_USAGE (U8)
|
||||
|
||||
assert_keyword (KW_FOR);
|
||||
token_after_newlines_must_be (TOK_OPEN_PAREN);
|
||||
@@ -2548,6 +2557,9 @@ plain_for:
|
||||
21 jmp_up 5; // step_oc;
|
||||
22 ...
|
||||
*/
|
||||
STACK_PUSH (U8, STACK_SIZE (rewritable_continue));
|
||||
STACK_PUSH (U8, STACK_SIZE (rewritable_break));
|
||||
|
||||
STACK_PUSH (U16, OPCODE_COUNTER ()); // cond_oc;
|
||||
skip_newlines ();
|
||||
if (!token_is (TOK_SEMICOLON))
|
||||
@@ -2585,9 +2597,10 @@ plain_for:
|
||||
DUMP_OPCODE_2 (jmp_up, 0, OPCODE_COUNTER () - STACK_TOP (U16));
|
||||
REWRITE_COND_JMP (STACK_HEAD (U16, 3), is_false_jmp_down, OPCODE_COUNTER () - STACK_HEAD (U16, 3));
|
||||
|
||||
rewrite_rewritable_opcodes (REWRITABLE_CONTINUE, STACK_TOP (U16));
|
||||
rewrite_rewritable_opcodes (REWRITABLE_BREAK, OPCODE_COUNTER ());
|
||||
rewrite_rewritable_opcodes (REWRITABLE_CONTINUE, STACK_HEAD (U8, 2), STACK_TOP (U16));
|
||||
rewrite_rewritable_opcodes (REWRITABLE_BREAK, STACK_TOP (U8), OPCODE_COUNTER ());
|
||||
|
||||
STACK_DROP (U8, 2);
|
||||
STACK_DROP (IDX, 1);
|
||||
STACK_DROP (U16, 4);
|
||||
|
||||
@@ -2599,6 +2612,7 @@ for_in:
|
||||
cleanup:
|
||||
STACK_CHECK_USAGE (IDX);
|
||||
STACK_CHECK_USAGE (U16);
|
||||
STACK_CHECK_USAGE (U8);
|
||||
STACK_CHECK_USAGE (nestings);
|
||||
}
|
||||
|
||||
@@ -2705,29 +2719,33 @@ parse_do_while_statement (void)
|
||||
// U16 loop_oc;
|
||||
STACK_DECLARE_USAGE (IDX)
|
||||
STACK_DECLARE_USAGE (U16)
|
||||
STACK_DECLARE_USAGE (U8)
|
||||
STACK_DECLARE_USAGE (nestings)
|
||||
|
||||
assert_keyword (KW_DO);
|
||||
|
||||
STACK_PUSH (U16, OPCODE_COUNTER ());
|
||||
STACK_PUSH (U8, STACK_SIZE (rewritable_continue));
|
||||
STACK_PUSH (U8, STACK_SIZE (rewritable_break));
|
||||
|
||||
skip_newlines ();
|
||||
push_nesting (NESTING_ITERATIONAL);
|
||||
parse_statement ();
|
||||
pop_nesting (NESTING_ITERATIONAL);
|
||||
|
||||
rewrite_rewritable_opcodes (REWRITABLE_CONTINUE, STACK_HEAD (U8, 2), OPCODE_COUNTER ());
|
||||
token_after_newlines_must_be_keyword (KW_WHILE);
|
||||
parse_expression_inside_parens ();
|
||||
STACK_PUSH (U16, OPCODE_COUNTER ());
|
||||
DUMP_OPCODE_3 (is_true_jmp_up, INVALID_VALUE, INVALID_VALUE, INVALID_VALUE);
|
||||
REWRITE_COND_JMP (STACK_HEAD(U16, 1), is_true_jmp_up, OPCODE_COUNTER () - STACK_HEAD (U16, 2));
|
||||
|
||||
rewrite_rewritable_opcodes (REWRITABLE_CONTINUE, STACK_HEAD (U16, 2));
|
||||
rewrite_rewritable_opcodes (REWRITABLE_BREAK, OPCODE_COUNTER ());
|
||||
rewrite_rewritable_opcodes (REWRITABLE_BREAK, STACK_TOP (U8), OPCODE_COUNTER ());
|
||||
|
||||
STACK_DROP (IDX, 1);
|
||||
STACK_DROP (U16, 2);
|
||||
STACK_DROP (U16, 1);
|
||||
STACK_DROP (U8, 2);
|
||||
|
||||
STACK_CHECK_USAGE (U8);
|
||||
STACK_CHECK_USAGE (U16);
|
||||
STACK_CHECK_USAGE (IDX);
|
||||
STACK_CHECK_USAGE (nestings);
|
||||
@@ -2743,10 +2761,14 @@ parse_while_statement (void)
|
||||
// U16 cond_oc, jmp_oc;
|
||||
STACK_DECLARE_USAGE (IDX)
|
||||
STACK_DECLARE_USAGE (U16)
|
||||
STACK_DECLARE_USAGE (U8)
|
||||
STACK_DECLARE_USAGE (nestings)
|
||||
|
||||
assert_keyword (KW_WHILE);
|
||||
|
||||
STACK_PUSH (U8, STACK_SIZE (rewritable_continue));
|
||||
STACK_PUSH (U8, STACK_SIZE (rewritable_break));
|
||||
|
||||
STACK_PUSH (U16, OPCODE_COUNTER ()); // cond_oc;
|
||||
parse_expression_inside_parens ();
|
||||
STACK_PUSH (U16, OPCODE_COUNTER ()); // jmp_oc;
|
||||
@@ -2762,12 +2784,14 @@ parse_while_statement (void)
|
||||
REWRITE_JMP (STACK_TOP (U16), jmp_up, OPCODE_COUNTER () - STACK_HEAD (U16, 3));
|
||||
REWRITE_COND_JMP (STACK_HEAD (U16, 2), is_false_jmp_down, OPCODE_COUNTER () - STACK_HEAD (U16, 2));
|
||||
|
||||
rewrite_rewritable_opcodes (REWRITABLE_CONTINUE, STACK_HEAD (U16, 3));
|
||||
rewrite_rewritable_opcodes (REWRITABLE_BREAK, OPCODE_COUNTER ());
|
||||
rewrite_rewritable_opcodes (REWRITABLE_CONTINUE, STACK_HEAD (U8, 2), STACK_HEAD (U16, 3));
|
||||
rewrite_rewritable_opcodes (REWRITABLE_BREAK, STACK_TOP (U8), OPCODE_COUNTER ());
|
||||
|
||||
STACK_DROP (IDX, 1);
|
||||
STACK_DROP (U16, 3);
|
||||
STACK_DROP (U8, 2);
|
||||
|
||||
STACK_CHECK_USAGE (U8);
|
||||
STACK_CHECK_USAGE (U16);
|
||||
STACK_CHECK_USAGE (IDX);
|
||||
STACK_CHECK_USAGE (nestings);
|
||||
@@ -2849,9 +2873,12 @@ parse_switch_statement (void)
|
||||
STACK_DECLARE_USAGE (rewritable_break)
|
||||
STACK_DECLARE_USAGE (IDX)
|
||||
STACK_DECLARE_USAGE (U16)
|
||||
STACK_DECLARE_USAGE (U8)
|
||||
|
||||
assert_keyword (KW_SWITCH);
|
||||
|
||||
STACK_PUSH (U8, STACK_SIZE (rewritable_break));
|
||||
|
||||
parse_expression_inside_parens ();
|
||||
token_after_newlines_must_be (TOK_OPEN_BRACE);
|
||||
push_nesting (NESTING_SWITCH);
|
||||
@@ -2881,12 +2908,14 @@ parse_switch_statement (void)
|
||||
EMIT_ERROR ("Expected '}' token");
|
||||
}
|
||||
pop_nesting (NESTING_SWITCH);
|
||||
STACK_DROP (IDX, 1);
|
||||
rewrite_rewritable_opcodes (REWRITABLE_BREAK, STACK_TOP (U8), OPCODE_COUNTER ());
|
||||
|
||||
rewrite_rewritable_opcodes (REWRITABLE_BREAK, OPCODE_COUNTER ());
|
||||
STACK_DROP (IDX, 1);
|
||||
STACK_DROP (U8, 1);
|
||||
|
||||
STACK_CHECK_USAGE (IDX);
|
||||
STACK_CHECK_USAGE (U16);
|
||||
STACK_CHECK_USAGE (U8);
|
||||
STACK_CHECK_USAGE (rewritable_break);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user