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:
@@ -99,11 +99,26 @@ typedef enum
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ECMA_COMPLETION_TYPE_NORMAL, /**< default block completion */
|
||||
ECMA_COMPLETION_TYPE_RETURN, /**< block completed with return */
|
||||
ECMA_COMPLETION_TYPE_BREAK, /**< block completed with break */
|
||||
ECMA_COMPLETION_TYPE_CONTINUE, /**< block completed with continue */
|
||||
ECMA_COMPLETION_TYPE_THROW, /**< block completed with throw */
|
||||
ECMA_COMPLETION_TYPE_NORMAL, /**< default completion */
|
||||
ECMA_COMPLETION_TYPE_RETURN, /**< completion with return */
|
||||
ECMA_COMPLETION_TYPE_JUMP, /**< implementation-defined completion type
|
||||
* for jump statements (break, continue)
|
||||
* that require completion of one or several
|
||||
* statements, before performing related jump.
|
||||
*
|
||||
* For example, 'break' in the following code
|
||||
* requires to return from opfunc_with handler
|
||||
* before performing jump to the loop end:
|
||||
*
|
||||
* for (var i = 0; i < 10; i++)
|
||||
* {
|
||||
* with (obj)
|
||||
* {
|
||||
* break;
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
ECMA_COMPLETION_TYPE_THROW, /**< completion with throw */
|
||||
ECMA_COMPLETION_TYPE_EXIT, /**< implementation-defined completion type
|
||||
for finishing script execution */
|
||||
ECMA_COMPLETION_TYPE_META /**< implementation-defined completion type
|
||||
@@ -142,7 +157,7 @@ typedef uint32_t ecma_value_t;
|
||||
*
|
||||
* value (16)
|
||||
* Bit-field structure: type (8) | padding (8) <
|
||||
* label_desc_cp (16)
|
||||
* break / continue target
|
||||
*/
|
||||
typedef uint32_t ecma_completion_value_t;
|
||||
|
||||
@@ -155,12 +170,10 @@ typedef uint32_t ecma_completion_value_t;
|
||||
#define ECMA_COMPLETION_VALUE_VALUE_WIDTH (ECMA_VALUE_SIZE)
|
||||
|
||||
/**
|
||||
* Label
|
||||
*
|
||||
* Used for break and continue completion types.
|
||||
* Break / continue jump target
|
||||
*/
|
||||
#define ECMA_COMPLETION_VALUE_LABEL_DESC_CP_POS (0)
|
||||
#define ECMA_COMPLETION_VALUE_LABEL_DESC_CP_WIDTH (ECMA_POINTER_FIELD_WIDTH)
|
||||
#define ECMA_COMPLETION_VALUE_TARGET_POS (0)
|
||||
#define ECMA_COMPLETION_VALUE_TARGET_WIDTH ((uint32_t) sizeof (opcode_counter_t) * JERRY_BITSINBYTE)
|
||||
|
||||
/**
|
||||
* Type (ecma_completion_type_t)
|
||||
@@ -168,8 +181,8 @@ typedef uint32_t ecma_completion_value_t;
|
||||
#define ECMA_COMPLETION_VALUE_TYPE_POS (JERRY_MAX (JERRY_ALIGNUP (ECMA_COMPLETION_VALUE_VALUE_POS + \
|
||||
ECMA_COMPLETION_VALUE_VALUE_WIDTH, \
|
||||
JERRY_BITSINBYTE), \
|
||||
JERRY_ALIGNUP (ECMA_COMPLETION_VALUE_LABEL_DESC_CP_POS + \
|
||||
ECMA_COMPLETION_VALUE_LABEL_DESC_CP_WIDTH, \
|
||||
JERRY_ALIGNUP (ECMA_COMPLETION_VALUE_TARGET_POS + \
|
||||
ECMA_COMPLETION_VALUE_TARGET_WIDTH, \
|
||||
JERRY_BITSINBYTE)))
|
||||
#define ECMA_COMPLETION_VALUE_TYPE_WIDTH (8)
|
||||
|
||||
|
||||
@@ -462,18 +462,17 @@ ecma_get_completion_value_value_field (ecma_completion_value_t completion_value)
|
||||
} /* ecma_get_completion_value_value_field */
|
||||
|
||||
/**
|
||||
* Get pointer to label descriptor from completion value
|
||||
* Get target of break / continue completion value
|
||||
*
|
||||
* @return pointer to label descriptor
|
||||
* @return opcode counter
|
||||
*/
|
||||
static ecma_label_descriptor_t* __attr_const___
|
||||
ecma_get_completion_value_label_descriptor (ecma_completion_value_t completion_value) /**< completion value */
|
||||
static opcode_counter_t
|
||||
ecma_get_completion_value_target (ecma_completion_value_t completion_value) /**< completion value */
|
||||
{
|
||||
return ECMA_GET_NON_NULL_POINTER (ecma_label_descriptor_t,
|
||||
(uintptr_t) jrt_extract_bit_field (completion_value,
|
||||
ECMA_COMPLETION_VALUE_LABEL_DESC_CP_POS,
|
||||
ECMA_COMPLETION_VALUE_LABEL_DESC_CP_WIDTH));
|
||||
} /* ecma_get_completion_value_label_descriptor */
|
||||
return (opcode_counter_t) jrt_extract_bit_field (completion_value,
|
||||
ECMA_COMPLETION_VALUE_TARGET_POS,
|
||||
ECMA_COMPLETION_VALUE_TARGET_WIDTH);
|
||||
} /* ecma_get_completion_value_target */
|
||||
|
||||
/**
|
||||
* Set type field of completion value
|
||||
@@ -508,24 +507,20 @@ ecma_set_completion_value_value_field (ecma_completion_value_t completion_value,
|
||||
} /* ecma_set_completion_value_value_field */
|
||||
|
||||
/**
|
||||
* Set label descriptor of completion value
|
||||
* Set target of break / continue completion value
|
||||
*
|
||||
* @return completion value with updated field
|
||||
*/
|
||||
static ecma_completion_value_t __attr_const___
|
||||
ecma_set_completion_value_label_descriptor (ecma_completion_value_t completion_value, /**< completion value
|
||||
* to set field in */
|
||||
ecma_label_descriptor_t* label_desc_p) /**< pointer to the
|
||||
* label descriptor */
|
||||
ecma_set_completion_value_target (ecma_completion_value_t completion_value, /**< completion value
|
||||
* to set field in */
|
||||
opcode_counter_t target) /**< break / continue target */
|
||||
{
|
||||
uintptr_t label_desc_cp;
|
||||
ECMA_SET_NON_NULL_POINTER (label_desc_cp, label_desc_p);
|
||||
|
||||
return (ecma_completion_value_t) jrt_set_bit_field_value (completion_value,
|
||||
label_desc_cp,
|
||||
ECMA_COMPLETION_VALUE_LABEL_DESC_CP_POS,
|
||||
ECMA_COMPLETION_VALUE_LABEL_DESC_CP_WIDTH);
|
||||
} /* ecma_set_completion_value_label_descriptor */
|
||||
target,
|
||||
ECMA_COMPLETION_VALUE_TARGET_POS,
|
||||
ECMA_COMPLETION_VALUE_TARGET_WIDTH);
|
||||
} /* ecma_set_completion_value_target */
|
||||
|
||||
/**
|
||||
* Normal, throw, return, exit and meta completion values constructor
|
||||
@@ -555,34 +550,6 @@ ecma_make_completion_value (ecma_completion_type_t type, /**< type */
|
||||
return completion_value;
|
||||
} /* ecma_make_completion_value */
|
||||
|
||||
/**
|
||||
* Break and continue completion values constructor
|
||||
*
|
||||
* @return completion value
|
||||
*/
|
||||
ecma_completion_value_t __attr_const___
|
||||
ecma_make_label_completion_value (ecma_completion_type_t type, /**< type */
|
||||
uint8_t depth_level, /**< depth level (in try constructions,
|
||||
with blocks, etc.) */
|
||||
uint16_t offset) /**< offset to label from end of last block */
|
||||
{
|
||||
JERRY_ASSERT (type == ECMA_COMPLETION_TYPE_BREAK
|
||||
|| type == ECMA_COMPLETION_TYPE_CONTINUE);
|
||||
|
||||
ecma_label_descriptor_t *label_desc_p = ecma_alloc_label_descriptor ();
|
||||
label_desc_p->offset = offset;
|
||||
label_desc_p->depth = depth_level;
|
||||
|
||||
ecma_completion_value_t completion_value = 0;
|
||||
|
||||
completion_value = ecma_set_completion_value_type_field (completion_value,
|
||||
type);
|
||||
completion_value = ecma_set_completion_value_label_descriptor (completion_value,
|
||||
label_desc_p);
|
||||
|
||||
return completion_value;
|
||||
} /* ecma_make_label_completion_value */
|
||||
|
||||
/**
|
||||
* Simple normal completion value constructor
|
||||
*
|
||||
@@ -688,6 +655,24 @@ ecma_make_meta_completion_value (void)
|
||||
ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY));
|
||||
} /* ecma_make_meta_completion_value */
|
||||
|
||||
/**
|
||||
* Break / continue completion values constructor
|
||||
*
|
||||
* @return completion value
|
||||
*/
|
||||
ecma_completion_value_t __attr_const___
|
||||
ecma_make_jump_completion_value (opcode_counter_t target) /**< target break / continue */
|
||||
{
|
||||
ecma_completion_value_t completion_value = 0;
|
||||
|
||||
completion_value = ecma_set_completion_value_type_field (completion_value,
|
||||
ECMA_COMPLETION_TYPE_JUMP);
|
||||
completion_value = ecma_set_completion_value_target (completion_value,
|
||||
target);
|
||||
|
||||
return completion_value;
|
||||
} /* ecma_make_jump_completion_value */
|
||||
|
||||
/**
|
||||
* Get ecma-value from specified completion value
|
||||
*
|
||||
@@ -741,6 +726,20 @@ ecma_get_object_from_completion_value (ecma_completion_value_t completion_value)
|
||||
return ecma_get_object_from_value (ecma_get_completion_value_value (completion_value));
|
||||
} /* ecma_get_object_from_completion_value */
|
||||
|
||||
/**
|
||||
* Get break / continue target from completion value
|
||||
*
|
||||
* @return opcode counter
|
||||
*/
|
||||
opcode_counter_t
|
||||
ecma_get_jump_target_from_completion_value (ecma_completion_value_t completion_value) /**< completion
|
||||
* value */
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_completion_value_type_field (completion_value) == ECMA_COMPLETION_TYPE_JUMP);
|
||||
|
||||
return ecma_get_completion_value_target (completion_value);
|
||||
} /* ecma_get_jump_target_from_completion_value */
|
||||
|
||||
/**
|
||||
* Copy ecma-completion value.
|
||||
*
|
||||
@@ -753,6 +752,7 @@ ecma_copy_completion_value (ecma_completion_value_t value) /**< completion value
|
||||
const bool is_type_ok = (type == ECMA_COMPLETION_TYPE_NORMAL
|
||||
|| type == ECMA_COMPLETION_TYPE_THROW
|
||||
|| type == ECMA_COMPLETION_TYPE_RETURN
|
||||
|| type == ECMA_COMPLETION_TYPE_JUMP
|
||||
|| type == ECMA_COMPLETION_TYPE_EXIT);
|
||||
|
||||
JERRY_ASSERT (is_type_ok);
|
||||
@@ -784,10 +784,8 @@ ecma_free_completion_value (ecma_completion_value_t completion_value) /**< compl
|
||||
JERRY_ASSERT (ecma_get_value_type_field (v) == ECMA_TYPE_SIMPLE);
|
||||
break;
|
||||
}
|
||||
case ECMA_COMPLETION_TYPE_CONTINUE:
|
||||
case ECMA_COMPLETION_TYPE_BREAK:
|
||||
case ECMA_COMPLETION_TYPE_JUMP:
|
||||
{
|
||||
ecma_dealloc_label_descriptor (ecma_get_completion_value_label_descriptor (completion_value));
|
||||
break;
|
||||
}
|
||||
case ECMA_COMPLETION_TYPE_META:
|
||||
@@ -876,28 +874,16 @@ ecma_is_completion_value_meta (ecma_completion_value_t value) /**< completion va
|
||||
} /* ecma_is_completion_value_meta */
|
||||
|
||||
/**
|
||||
* Check if the completion value is break value.
|
||||
* Check if the completion value is break / continue value.
|
||||
*
|
||||
* @return true - if the completion type is break,
|
||||
* @return true - if the completion type is break / continue,
|
||||
* false - otherwise.
|
||||
*/
|
||||
bool __attr_const___ __attr_always_inline___
|
||||
ecma_is_completion_value_break (ecma_completion_value_t value) /**< completion value */
|
||||
ecma_is_completion_value_jump (ecma_completion_value_t value) /**< completion value */
|
||||
{
|
||||
return (ecma_get_completion_value_type_field (value) == ECMA_COMPLETION_TYPE_BREAK);
|
||||
} /* ecma_is_completion_value_break */
|
||||
|
||||
/**
|
||||
* Check if the completion value is continue value.
|
||||
*
|
||||
* @return true - if the completion type is continue,
|
||||
* false - otherwise.
|
||||
*/
|
||||
bool __attr_const___ __attr_always_inline___
|
||||
ecma_is_completion_value_continue (ecma_completion_value_t value) /**< completion value */
|
||||
{
|
||||
return (ecma_get_completion_value_type_field (value) == ECMA_COMPLETION_TYPE_CONTINUE);
|
||||
} /* ecma_is_completion_value_continue */
|
||||
return (ecma_get_completion_value_type_field (value) == ECMA_COMPLETION_TYPE_JUMP);
|
||||
} /* ecma_is_completion_value_jump */
|
||||
|
||||
/**
|
||||
* Check if the completion value is specified normal simple value.
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "ecma-globals.h"
|
||||
#include "mem-allocator.h"
|
||||
#include "opcodes.h"
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
extern ecma_completion_value_t ecma_make_completion_value (ecma_completion_type_t type,
|
||||
ecma_value_t value);
|
||||
extern ecma_completion_value_t ecma_make_label_completion_value (ecma_completion_type_t type,
|
||||
uint8_t depth_level,
|
||||
uint16_t offset);
|
||||
extern ecma_completion_value_t ecma_make_simple_completion_value (ecma_simple_value_t simple_value);
|
||||
extern ecma_completion_value_t ecma_make_normal_completion_value (ecma_value_t value);
|
||||
extern ecma_completion_value_t ecma_make_throw_completion_value (ecma_value_t value);
|
||||
@@ -85,6 +83,7 @@ extern ecma_completion_value_t ecma_make_empty_completion_value (void);
|
||||
extern ecma_completion_value_t ecma_make_return_completion_value (ecma_value_t value);
|
||||
extern ecma_completion_value_t ecma_make_exit_completion_value (bool is_successful);
|
||||
extern ecma_completion_value_t ecma_make_meta_completion_value (void);
|
||||
extern ecma_completion_value_t ecma_make_jump_completion_value (opcode_counter_t target);
|
||||
extern ecma_value_t ecma_get_completion_value_value (ecma_completion_value_t completion_value);
|
||||
extern ecma_number_t* __attr_const___
|
||||
ecma_get_number_from_completion_value (ecma_completion_value_t completion_value);
|
||||
@@ -92,6 +91,8 @@ extern ecma_string_t* __attr_const___
|
||||
ecma_get_string_from_completion_value (ecma_completion_value_t completion_value);
|
||||
extern ecma_object_t* __attr_const___
|
||||
ecma_get_object_from_completion_value (ecma_completion_value_t completion_value);
|
||||
extern opcode_counter_t
|
||||
ecma_get_jump_target_from_completion_value (ecma_completion_value_t completion_value);
|
||||
extern ecma_completion_value_t ecma_copy_completion_value (ecma_completion_value_t value);
|
||||
extern void ecma_free_completion_value (ecma_completion_value_t completion_value);
|
||||
|
||||
@@ -100,8 +101,7 @@ extern bool ecma_is_completion_value_throw (ecma_completion_value_t value);
|
||||
extern bool ecma_is_completion_value_return (ecma_completion_value_t value);
|
||||
extern bool ecma_is_completion_value_exit (ecma_completion_value_t value);
|
||||
extern bool ecma_is_completion_value_meta (ecma_completion_value_t value);
|
||||
extern bool ecma_is_completion_value_break (ecma_completion_value_t value);
|
||||
extern bool ecma_is_completion_value_continue (ecma_completion_value_t value);
|
||||
extern bool ecma_is_completion_value_jump (ecma_completion_value_t value);
|
||||
extern bool ecma_is_completion_value_normal_simple_value (ecma_completion_value_t value,
|
||||
ecma_simple_value_t simple_value);
|
||||
extern bool ecma_is_completion_value_normal_true (ecma_completion_value_t value);
|
||||
|
||||
Reference in New Issue
Block a user