Fixing break / continue, nested into 'try', 'with' blocks.

Related issue: #128

JerryScript-DCO-1.0-Signed-off-by: Ruben Ayrapetyan r.ayrapetyan@samsung.com
This commit is contained in:
Ruben Ayrapetyan
2015-06-02 17:06:43 +03:00
parent 8433df3097
commit ac87616f05
13 changed files with 440 additions and 146 deletions
+17
View File
@@ -198,3 +198,20 @@ opfunc_jmp_up (opcode_t opdata, /**< operation data */
return ecma_make_empty_completion_value ();
}
/**
* 'Break or continue jump' opcode handler.
*
* Note:
* the opcode returns break-continue completion value with jump target
*/
ecma_completion_value_t
opfunc_jmp_break_continue (opcode_t opdata, /**< operation data */
int_data_t *int_data) /**< interpreter context */
{
opcode_counter_t target = int_data->pos;
target = (opcode_counter_t) (target + calc_opcode_counter_from_idx_idx (opdata.data.jmp_down.opcode_1,
opdata.data.jmp_down.opcode_2));
return ecma_make_jump_completion_value (target);
} /* opfunc_jmp_break_continue */
+4 -6
View File
@@ -1334,22 +1334,20 @@ opfunc_with (opcode_t opdata, /**< operation data */
vm_run_scope_t run_scope_with = { int_data->pos, with_end_oc };
ecma_completion_value_t with_completion = vm_loop (int_data, &run_scope_with);
if (ecma_is_completion_value_normal (with_completion))
if (ecma_is_completion_value_empty (with_completion))
{
JERRY_ASSERT (ecma_is_completion_value_empty (with_completion));
JERRY_ASSERT (int_data->pos == with_end_oc);
int_data->pos++;
ret_value = ecma_make_empty_completion_value ();
}
else
{
JERRY_ASSERT (!ecma_is_completion_value_normal (with_completion));
JERRY_ASSERT (int_data->pos <= with_end_oc);
ret_value = with_completion;
}
ret_value = with_completion;
int_data->lex_env_p = old_env_p;
ecma_deref_object (new_env_p);
+2 -1
View File
@@ -206,7 +206,8 @@ opcode_counter_t read_meta_opcode_counter (opcode_meta_type expected_type, int_d
p##_3 (a, is_true_jmp_up, value, opcode_1, opcode_2) \
p##_3 (a, is_true_jmp_down, value, opcode_1, opcode_2) \
p##_3 (a, is_false_jmp_up, value, opcode_1, opcode_2) \
p##_3 (a, is_false_jmp_down, value, opcode_1, opcode_2)
p##_3 (a, is_false_jmp_down, value, opcode_1, opcode_2) \
p##_2 (a, jmp_break_continue, opcode_1, opcode_2)
#define OP_LIST_FULL(p, a) \
OP_CALLS_AND_ARGS (p, a) \
+1
View File
@@ -288,6 +288,7 @@ pp_op_meta (opcode_counter_t oc, op_meta opm, bool rewrite)
case NAME_TO_ID (is_false_jmp_down): printf ("if (%s == false) goto %d;", VAR (1), oc + OC (2, 3)); break;
case NAME_TO_ID (jmp_up): printf ("goto %d;", oc - OC (1, 2)); break;
case NAME_TO_ID (jmp_down): printf ("goto %d;", oc + OC (1, 2)); break;
case NAME_TO_ID (jmp_break_continue): printf ("goto_nested %d;", oc + OC (1, 2)); break;
case NAME_TO_ID (try_block): printf ("try (end: %d);", oc + OC (1, 2)); break;
case NAME_TO_ID (assignment):
{
+15 -4
View File
@@ -473,12 +473,23 @@ vm_loop (int_data_t *int_data_p, /**< interpreter context */
}
while (ecma_is_completion_value_normal (completion));
if (ecma_is_completion_value_break (completion)
|| ecma_is_completion_value_continue (completion))
if (ecma_is_completion_value_jump (completion))
{
JERRY_UNIMPLEMENTED ("break and continue on labels are not supported.");
opcode_counter_t target = ecma_get_jump_target_from_completion_value (completion);
continue;
/*
* TODO:
* Implement instantiation of run scopes for global scope, functions and eval scope.
* Currently, correctness of jumps without run scope set is guaranteed through byte-code semantics.
*/
if (run_scope_p == NULL /* if no run scope set */
|| (target >= run_scope_p->start_oc /* or target is within the current run scope */
&& target < run_scope_p->end_oc))
{
int_data_p->pos = target;
continue;
}
}
if (ecma_is_completion_value_meta (completion))