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:
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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
@@ -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))
|
||||
|
||||
Reference in New Issue
Block a user