Skip to content

Commit 28d0d69

Browse files
Fixing break / continue, nested into 'try', 'with' blocks.
Related issue: #128 JerryScript-DCO-1.0-Signed-off-by: Ruben Ayrapetyan r.ayrapetyan@samsung.com
1 parent 98e8737 commit 28d0d69

12 files changed

+430
-140
lines changed

jerry-core/ecma/base/ecma-globals.h

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,26 @@ typedef enum
9999
*/
100100
typedef enum
101101
{
102-
ECMA_COMPLETION_TYPE_NORMAL, /**< default block completion */
103-
ECMA_COMPLETION_TYPE_RETURN, /**< block completed with return */
104-
ECMA_COMPLETION_TYPE_BREAK, /**< block completed with break */
105-
ECMA_COMPLETION_TYPE_CONTINUE, /**< block completed with continue */
106-
ECMA_COMPLETION_TYPE_THROW, /**< block completed with throw */
102+
ECMA_COMPLETION_TYPE_NORMAL, /**< default completion */
103+
ECMA_COMPLETION_TYPE_RETURN, /**< completion with return */
104+
ECMA_COMPLETION_TYPE_JUMP, /**< implementation-defined completion type
105+
* for jump statements (break, continue)
106+
* that require completion of one or several
107+
* statements, before performing related jump.
108+
*
109+
* For example, 'break' in the following code
110+
* requires to return from opfunc_with handler
111+
* before performing jump to the loop end:
112+
*
113+
* for (var i = 0; i < 10; i++)
114+
* {
115+
* with (obj)
116+
* {
117+
* break;
118+
* }
119+
* }
120+
*/
121+
ECMA_COMPLETION_TYPE_THROW, /**< completion with throw */
107122
ECMA_COMPLETION_TYPE_EXIT, /**< implementation-defined completion type
108123
for finishing script execution */
109124
ECMA_COMPLETION_TYPE_META /**< implementation-defined completion type
@@ -142,7 +157,7 @@ typedef uint32_t ecma_value_t;
142157
*
143158
* value (16)
144159
* Bit-field structure: type (8) | padding (8) <
145-
* label_desc_cp (16)
160+
* break / continue target
146161
*/
147162
typedef uint32_t ecma_completion_value_t;
148163

@@ -155,21 +170,19 @@ typedef uint32_t ecma_completion_value_t;
155170
#define ECMA_COMPLETION_VALUE_VALUE_WIDTH (ECMA_VALUE_SIZE)
156171

157172
/**
158-
* Label
159-
*
160-
* Used for break and continue completion types.
173+
* Break / continue jump target
161174
*/
162-
#define ECMA_COMPLETION_VALUE_LABEL_DESC_CP_POS (0)
163-
#define ECMA_COMPLETION_VALUE_LABEL_DESC_CP_WIDTH (ECMA_POINTER_FIELD_WIDTH)
175+
#define ECMA_COMPLETION_VALUE_TARGET_POS (0)
176+
#define ECMA_COMPLETION_VALUE_TARGET_WIDTH ((uint32_t) sizeof (opcode_counter_t) * JERRY_BITSINBYTE)
164177

165178
/**
166179
* Type (ecma_completion_type_t)
167180
*/
168181
#define ECMA_COMPLETION_VALUE_TYPE_POS (JERRY_MAX (JERRY_ALIGNUP (ECMA_COMPLETION_VALUE_VALUE_POS + \
169182
ECMA_COMPLETION_VALUE_VALUE_WIDTH, \
170183
JERRY_BITSINBYTE), \
171-
JERRY_ALIGNUP (ECMA_COMPLETION_VALUE_LABEL_DESC_CP_POS + \
172-
ECMA_COMPLETION_VALUE_LABEL_DESC_CP_WIDTH, \
184+
JERRY_ALIGNUP (ECMA_COMPLETION_VALUE_TARGET_POS + \
185+
ECMA_COMPLETION_VALUE_TARGET_WIDTH, \
173186
JERRY_BITSINBYTE)))
174187
#define ECMA_COMPLETION_VALUE_TYPE_WIDTH (8)
175188

jerry-core/ecma/base/ecma-helpers-value.cpp

Lines changed: 55 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -462,18 +462,17 @@ ecma_get_completion_value_value_field (ecma_completion_value_t completion_value)
462462
} /* ecma_get_completion_value_value_field */
463463

464464
/**
465-
* Get pointer to label descriptor from completion value
465+
* Get target of break / continue completion value
466466
*
467-
* @return pointer to label descriptor
467+
* @return opcode counter
468468
*/
469-
static ecma_label_descriptor_t* __attr_const___
470-
ecma_get_completion_value_label_descriptor (ecma_completion_value_t completion_value) /**< completion value */
469+
static opcode_counter_t
470+
ecma_get_completion_value_target (ecma_completion_value_t completion_value) /**< completion value */
471471
{
472-
return ECMA_GET_NON_NULL_POINTER (ecma_label_descriptor_t,
473-
(uintptr_t) jrt_extract_bit_field (completion_value,
474-
ECMA_COMPLETION_VALUE_LABEL_DESC_CP_POS,
475-
ECMA_COMPLETION_VALUE_LABEL_DESC_CP_WIDTH));
476-
} /* ecma_get_completion_value_label_descriptor */
472+
return (opcode_counter_t) jrt_extract_bit_field (completion_value,
473+
ECMA_COMPLETION_VALUE_TARGET_POS,
474+
ECMA_COMPLETION_VALUE_TARGET_WIDTH);
475+
} /* ecma_get_completion_value_target */
477476

478477
/**
479478
* Set type field of completion value
@@ -508,24 +507,20 @@ ecma_set_completion_value_value_field (ecma_completion_value_t completion_value,
508507
} /* ecma_set_completion_value_value_field */
509508

510509
/**
511-
* Set label descriptor of completion value
510+
* Set target of break / continue completion value
512511
*
513512
* @return completion value with updated field
514513
*/
515514
static ecma_completion_value_t __attr_const___
516-
ecma_set_completion_value_label_descriptor (ecma_completion_value_t completion_value, /**< completion value
517-
* to set field in */
518-
ecma_label_descriptor_t* label_desc_p) /**< pointer to the
519-
* label descriptor */
515+
ecma_set_completion_value_target (ecma_completion_value_t completion_value, /**< completion value
516+
* to set field in */
517+
opcode_counter_t target) /**< break / continue target */
520518
{
521-
uintptr_t label_desc_cp;
522-
ECMA_SET_NON_NULL_POINTER (label_desc_cp, label_desc_p);
523-
524519
return (ecma_completion_value_t) jrt_set_bit_field_value (completion_value,
525-
label_desc_cp,
526-
ECMA_COMPLETION_VALUE_LABEL_DESC_CP_POS,
527-
ECMA_COMPLETION_VALUE_LABEL_DESC_CP_WIDTH);
528-
} /* ecma_set_completion_value_label_descriptor */
520+
target,
521+
ECMA_COMPLETION_VALUE_TARGET_POS,
522+
ECMA_COMPLETION_VALUE_TARGET_WIDTH);
523+
} /* ecma_set_completion_value_target */
529524

530525
/**
531526
* Normal, throw, return, exit and meta completion values constructor
@@ -555,34 +550,6 @@ ecma_make_completion_value (ecma_completion_type_t type, /**< type */
555550
return completion_value;
556551
} /* ecma_make_completion_value */
557552

558-
/**
559-
* Break and continue completion values constructor
560-
*
561-
* @return completion value
562-
*/
563-
ecma_completion_value_t __attr_const___
564-
ecma_make_label_completion_value (ecma_completion_type_t type, /**< type */
565-
uint8_t depth_level, /**< depth level (in try constructions,
566-
with blocks, etc.) */
567-
uint16_t offset) /**< offset to label from end of last block */
568-
{
569-
JERRY_ASSERT (type == ECMA_COMPLETION_TYPE_BREAK
570-
|| type == ECMA_COMPLETION_TYPE_CONTINUE);
571-
572-
ecma_label_descriptor_t *label_desc_p = ecma_alloc_label_descriptor ();
573-
label_desc_p->offset = offset;
574-
label_desc_p->depth = depth_level;
575-
576-
ecma_completion_value_t completion_value = 0;
577-
578-
completion_value = ecma_set_completion_value_type_field (completion_value,
579-
type);
580-
completion_value = ecma_set_completion_value_label_descriptor (completion_value,
581-
label_desc_p);
582-
583-
return completion_value;
584-
} /* ecma_make_label_completion_value */
585-
586553
/**
587554
* Simple normal completion value constructor
588555
*
@@ -688,6 +655,24 @@ ecma_make_meta_completion_value (void)
688655
ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY));
689656
} /* ecma_make_meta_completion_value */
690657

658+
/**
659+
* Break / continue completion values constructor
660+
*
661+
* @return completion value
662+
*/
663+
ecma_completion_value_t __attr_const___
664+
ecma_make_jump_completion_value (opcode_counter_t target) /**< target break / continue */
665+
{
666+
ecma_completion_value_t completion_value = 0;
667+
668+
completion_value = ecma_set_completion_value_type_field (completion_value,
669+
ECMA_COMPLETION_TYPE_BREAK_CONTINUE);
670+
completion_value = ecma_set_completion_value_target (completion_value,
671+
target);
672+
673+
return completion_value;
674+
} /* ecma_make_jump_completion_value */
675+
691676
/**
692677
* Get ecma-value from specified completion value
693678
*
@@ -741,6 +726,20 @@ ecma_get_object_from_completion_value (ecma_completion_value_t completion_value)
741726
return ecma_get_object_from_value (ecma_get_completion_value_value (completion_value));
742727
} /* ecma_get_object_from_completion_value */
743728

729+
/**
730+
* Get break / continue target from completion value
731+
*
732+
* @return opcode counter
733+
*/
734+
opcode_counter_t
735+
ecma_get_jump_target_from_completion_value (ecma_completion_value_t completion_value) /**< completion
736+
* value */
737+
{
738+
JERRY_ASSERT (ecma_get_completion_value_type_field (completion_value) == ECMA_COMPLETION_TYPE_BREAK_CONTINUE);
739+
740+
return ecma_get_completion_value_target (completion_value);
741+
} /* ecma_get_jump_target_from_completion_value */
742+
744743
/**
745744
* Copy ecma-completion value.
746745
*
@@ -753,6 +752,7 @@ ecma_copy_completion_value (ecma_completion_value_t value) /**< completion value
753752
const bool is_type_ok = (type == ECMA_COMPLETION_TYPE_NORMAL
754753
|| type == ECMA_COMPLETION_TYPE_THROW
755754
|| type == ECMA_COMPLETION_TYPE_RETURN
755+
|| type == ECMA_COMPLETION_TYPE_BREAK_CONTINUE
756756
|| type == ECMA_COMPLETION_TYPE_EXIT);
757757

758758
JERRY_ASSERT (is_type_ok);
@@ -784,10 +784,8 @@ ecma_free_completion_value (ecma_completion_value_t completion_value) /**< compl
784784
JERRY_ASSERT (ecma_get_value_type_field (v) == ECMA_TYPE_SIMPLE);
785785
break;
786786
}
787-
case ECMA_COMPLETION_TYPE_CONTINUE:
788-
case ECMA_COMPLETION_TYPE_BREAK:
787+
case ECMA_COMPLETION_TYPE_BREAK_CONTINUE:
789788
{
790-
ecma_dealloc_label_descriptor (ecma_get_completion_value_label_descriptor (completion_value));
791789
break;
792790
}
793791
case ECMA_COMPLETION_TYPE_META:
@@ -876,28 +874,16 @@ ecma_is_completion_value_meta (ecma_completion_value_t value) /**< completion va
876874
} /* ecma_is_completion_value_meta */
877875

878876
/**
879-
* Check if the completion value is break value.
880-
*
881-
* @return true - if the completion type is break,
882-
* false - otherwise.
883-
*/
884-
bool __attr_const___ __attr_always_inline___
885-
ecma_is_completion_value_break (ecma_completion_value_t value) /**< completion value */
886-
{
887-
return (ecma_get_completion_value_type_field (value) == ECMA_COMPLETION_TYPE_BREAK);
888-
} /* ecma_is_completion_value_break */
889-
890-
/**
891-
* Check if the completion value is continue value.
877+
* Check if the completion value is break / continue value.
892878
*
893-
* @return true - if the completion type is continue,
879+
* @return true - if the completion type is break / continue,
894880
* false - otherwise.
895881
*/
896882
bool __attr_const___ __attr_always_inline___
897-
ecma_is_completion_value_continue (ecma_completion_value_t value) /**< completion value */
883+
ecma_is_completion_value_jump (ecma_completion_value_t value) /**< completion value */
898884
{
899-
return (ecma_get_completion_value_type_field (value) == ECMA_COMPLETION_TYPE_CONTINUE);
900-
} /* ecma_is_completion_value_continue */
885+
return (ecma_get_completion_value_type_field (value) == ECMA_COMPLETION_TYPE_BREAK_CONTINUE);
886+
} /* ecma_is_completion_value_jump */
901887

902888
/**
903889
* Check if the completion value is specified normal simple value.

jerry-core/ecma/base/ecma-helpers.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
#include "ecma-globals.h"
2727
#include "mem-allocator.h"
28+
#include "opcodes.h"
2829

2930
/**
3031
* Get value of pointer from specified non-null compressed pointer.
@@ -74,9 +75,6 @@ extern void ecma_free_value (ecma_value_t value, bool do_deref_if_object);
7475

7576
extern ecma_completion_value_t ecma_make_completion_value (ecma_completion_type_t type,
7677
ecma_value_t value);
77-
extern ecma_completion_value_t ecma_make_label_completion_value (ecma_completion_type_t type,
78-
uint8_t depth_level,
79-
uint16_t offset);
8078
extern ecma_completion_value_t ecma_make_simple_completion_value (ecma_simple_value_t simple_value);
8179
extern ecma_completion_value_t ecma_make_normal_completion_value (ecma_value_t value);
8280
extern ecma_completion_value_t ecma_make_throw_completion_value (ecma_value_t value);
@@ -85,13 +83,16 @@ extern ecma_completion_value_t ecma_make_empty_completion_value (void);
8583
extern ecma_completion_value_t ecma_make_return_completion_value (ecma_value_t value);
8684
extern ecma_completion_value_t ecma_make_exit_completion_value (bool is_successful);
8785
extern ecma_completion_value_t ecma_make_meta_completion_value (void);
86+
extern ecma_completion_value_t ecma_make_break_continue_completion_value (opcode_counter_t target);
8887
extern ecma_value_t ecma_get_completion_value_value (ecma_completion_value_t completion_value);
8988
extern ecma_number_t* __attr_const___
9089
ecma_get_number_from_completion_value (ecma_completion_value_t completion_value);
9190
extern ecma_string_t* __attr_const___
9291
ecma_get_string_from_completion_value (ecma_completion_value_t completion_value);
9392
extern ecma_object_t* __attr_const___
9493
ecma_get_object_from_completion_value (ecma_completion_value_t completion_value);
94+
extern opcode_counter_t
95+
ecma_get_break_continue_target_from_completion_value (ecma_completion_value_t completion_value);
9596
extern ecma_completion_value_t ecma_copy_completion_value (ecma_completion_value_t value);
9697
extern void ecma_free_completion_value (ecma_completion_value_t completion_value);
9798

@@ -100,8 +101,7 @@ extern bool ecma_is_completion_value_throw (ecma_completion_value_t value);
100101
extern bool ecma_is_completion_value_return (ecma_completion_value_t value);
101102
extern bool ecma_is_completion_value_exit (ecma_completion_value_t value);
102103
extern bool ecma_is_completion_value_meta (ecma_completion_value_t value);
103-
extern bool ecma_is_completion_value_break (ecma_completion_value_t value);
104-
extern bool ecma_is_completion_value_continue (ecma_completion_value_t value);
104+
extern bool ecma_is_completion_value_break_continue (ecma_completion_value_t value);
105105
extern bool ecma_is_completion_value_normal_simple_value (ecma_completion_value_t value,
106106
ecma_simple_value_t simple_value);
107107
extern bool ecma_is_completion_value_normal_true (ecma_completion_value_t value);

0 commit comments

Comments
 (0)