Rework error to use a global slot to store the error value.
This change frees up the error bit in ecma_value_t, which allows to define 4 more value types (e.g. symbols). To keep API compatibility we introduce a box for values with error flag. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
@@ -534,7 +534,7 @@ jerry_parse_and_save_snapshot_with_args (const jerry_char_t *source_p, /**< scri
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (parse_status))
|
||||
{
|
||||
ecma_free_value (parse_status);
|
||||
ecma_free_value (JERRY_CONTEXT (error_value));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -728,6 +728,11 @@ jerry_snapshot_result_at (const uint32_t *snapshot_p, /**< snapshot */
|
||||
ecma_bytecode_deref (bytecode_p);
|
||||
}
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (ret_val))
|
||||
{
|
||||
return ecma_create_error_reference (JERRY_CONTEXT (error_value));
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
} /* jerry_snapshot_result_at */
|
||||
#endif /* JERRY_ENABLE_SNAPSHOT_EXEC */
|
||||
@@ -1312,14 +1317,14 @@ jerry_parse_and_save_literals (const jerry_char_t *source_p, /**< script source
|
||||
is_strict,
|
||||
&bytecode_data_p);
|
||||
|
||||
const bool error = ECMA_IS_VALUE_ERROR (parse_status);
|
||||
ecma_free_value (parse_status);
|
||||
|
||||
if (error)
|
||||
if (ECMA_IS_VALUE_ERROR (parse_status))
|
||||
{
|
||||
ecma_free_value (JERRY_CONTEXT (error_value));
|
||||
return 0;
|
||||
}
|
||||
|
||||
ecma_free_value (parse_status);
|
||||
|
||||
ecma_bytecode_deref (bytecode_data_p);
|
||||
|
||||
ecma_lit_storage_item_t *string_list_p = JERRY_CONTEXT (string_list_first_p);
|
||||
|
||||
+320
-189
File diff suppressed because it is too large
Load Diff
@@ -164,6 +164,7 @@ jerry_debugger_send_eval (const lit_utf8_byte_t *eval_string_p, /**< evaluated s
|
||||
if (ECMA_IS_VALUE_ERROR (result))
|
||||
{
|
||||
type = JERRY_DEBUGGER_EVAL_ERROR;
|
||||
result = JERRY_CONTEXT (error_value);
|
||||
|
||||
if (ecma_is_value_object (result))
|
||||
{
|
||||
@@ -980,18 +981,19 @@ jerry_debugger_exception_object_to_string (ecma_value_t exception_obj_value) /**
|
||||
* false - otherwise
|
||||
*/
|
||||
bool
|
||||
jerry_debugger_send_exception_string (ecma_value_t exception_value) /**< error value */
|
||||
jerry_debugger_send_exception_string (void)
|
||||
{
|
||||
ecma_string_t *string_p = NULL;
|
||||
|
||||
ecma_value_t exception_value = JERRY_CONTEXT (error_value);
|
||||
|
||||
if (ecma_is_value_object (exception_value))
|
||||
{
|
||||
ecma_value_t object_value = ecma_get_value_from_error_value (exception_value);
|
||||
string_p = jerry_debugger_exception_object_to_string (exception_value);
|
||||
|
||||
string_p = jerry_debugger_exception_object_to_string (object_value);
|
||||
if (string_p == NULL)
|
||||
{
|
||||
string_p = ecma_get_string_from_value (ecma_builtin_helper_object_to_string (object_value));
|
||||
string_p = ecma_get_string_from_value (ecma_builtin_helper_object_to_string (exception_value));
|
||||
}
|
||||
}
|
||||
else if (ecma_is_value_string (exception_value))
|
||||
|
||||
@@ -352,7 +352,7 @@ bool jerry_debugger_send_string (uint8_t message_type, uint8_t sub_type, const u
|
||||
bool jerry_debugger_send_function_cp (jerry_debugger_header_type_t type, ecma_compiled_code_t *compiled_code_p);
|
||||
bool jerry_debugger_send_parse_function (uint32_t line, uint32_t column);
|
||||
void jerry_debugger_send_memstats (void);
|
||||
bool jerry_debugger_send_exception_string (ecma_value_t exception_value);
|
||||
bool jerry_debugger_send_exception_string (void);
|
||||
|
||||
#endif /* JERRY_DEBUGGER */
|
||||
|
||||
|
||||
@@ -69,11 +69,12 @@ typedef enum
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
ECMA_TYPE_DIRECT, /**< directly encoded value, a 28 bit signed integer or a simple value */
|
||||
ECMA_TYPE_FLOAT, /**< pointer to a 64 or 32 bit floating point number */
|
||||
ECMA_TYPE_STRING, /**< pointer to description of a string */
|
||||
ECMA_TYPE_OBJECT, /**< pointer to description of an object */
|
||||
ECMA_TYPE___MAX = ECMA_TYPE_OBJECT /** highest value for ecma types */
|
||||
ECMA_TYPE_DIRECT = 0, /**< directly encoded value, a 28 bit signed integer or a simple value */
|
||||
ECMA_TYPE_FLOAT = 1, /**< pointer to a 64 or 32 bit floating point number */
|
||||
ECMA_TYPE_STRING = 2, /**< pointer to description of a string */
|
||||
ECMA_TYPE_OBJECT = 3, /**< pointer to description of an object */
|
||||
ECMA_TYPE_ERROR = 7, /**< pointer to description of an error reference */
|
||||
ECMA_TYPE___MAX = ECMA_TYPE_ERROR /** highest value for ecma types */
|
||||
} ecma_type_t;
|
||||
|
||||
/**
|
||||
@@ -88,11 +89,12 @@ typedef enum
|
||||
* - special register or stack values for vm
|
||||
*/
|
||||
ECMA_SIMPLE_VALUE_EMPTY, /**< uninitialized value */
|
||||
ECMA_SIMPLE_VALUE_ARRAY_HOLE, /**< array hole, used for initialization of an array literal */
|
||||
ECMA_SIMPLE_VALUE_ERROR, /**< an error is currently thrown */
|
||||
ECMA_SIMPLE_VALUE_FALSE, /**< boolean false */
|
||||
ECMA_SIMPLE_VALUE_TRUE, /**< boolean true */
|
||||
ECMA_SIMPLE_VALUE_UNDEFINED, /**< undefined value */
|
||||
ECMA_SIMPLE_VALUE_NULL, /**< null value */
|
||||
ECMA_SIMPLE_VALUE_ARRAY_HOLE, /**< array hole, used for initialization of an array literal */
|
||||
ECMA_SIMPLE_VALUE_NOT_FOUND, /**< a special value returned by ecma_op_object_find */
|
||||
ECMA_SIMPLE_VALUE_REGISTER_REF, /**< register reference, a special "base" value for vm */
|
||||
ECMA_SIMPLE_VALUE__COUNT /** count of simple ecma values */
|
||||
@@ -122,12 +124,7 @@ typedef int32_t ecma_integer_value_t;
|
||||
/**
|
||||
* Mask for ecma types in ecma_type_t
|
||||
*/
|
||||
#define ECMA_VALUE_TYPE_MASK 0x3u
|
||||
|
||||
/**
|
||||
* Error flag in ecma_type_t
|
||||
*/
|
||||
#define ECMA_VALUE_ERROR_FLAG 0x4u
|
||||
#define ECMA_VALUE_TYPE_MASK 0x7u
|
||||
|
||||
/**
|
||||
* Shift for value part in ecma_type_t
|
||||
@@ -199,7 +196,7 @@ typedef int32_t ecma_integer_value_t;
|
||||
* Checks whether the error flag is set.
|
||||
*/
|
||||
#define ECMA_IS_VALUE_ERROR(value) \
|
||||
(unlikely ((value & ECMA_VALUE_ERROR_FLAG) != 0))
|
||||
(unlikely ((value) == ecma_make_simple_value (ECMA_SIMPLE_VALUE_ERROR)))
|
||||
|
||||
/**
|
||||
* Representation for native external pointer
|
||||
@@ -1139,6 +1136,15 @@ typedef struct
|
||||
lit_utf8_size_t long_utf8_string_length; /**< length of this long utf-8 string in bytes */
|
||||
} ecma_long_string_t;
|
||||
|
||||
/**
|
||||
* Representation of a thrown value on API level.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t refs; /**< reference counter */
|
||||
ecma_value_t value; /**< referenced value */
|
||||
} ecma_error_reference_t;
|
||||
|
||||
/**
|
||||
* Compiled byte code data.
|
||||
*/
|
||||
|
||||
@@ -28,15 +28,10 @@
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Masking the type and flags
|
||||
*/
|
||||
#define ECMA_VALUE_FULL_MASK (ECMA_VALUE_TYPE_MASK | ECMA_VALUE_ERROR_FLAG)
|
||||
|
||||
JERRY_STATIC_ASSERT (ECMA_TYPE___MAX <= ECMA_VALUE_TYPE_MASK,
|
||||
ecma_types_must_be_less_than_mask);
|
||||
|
||||
JERRY_STATIC_ASSERT ((ECMA_VALUE_FULL_MASK + 1) == (1 << ECMA_VALUE_SHIFT),
|
||||
JERRY_STATIC_ASSERT ((ECMA_VALUE_TYPE_MASK + 1) == (1 << ECMA_VALUE_SHIFT),
|
||||
ecma_value_part_must_start_after_flags);
|
||||
|
||||
JERRY_STATIC_ASSERT (ECMA_VALUE_SHIFT <= JMEM_ALIGNMENT_LOG,
|
||||
@@ -83,7 +78,7 @@ ecma_pointer_to_ecma_value (const void *ptr) /**< pointer */
|
||||
#ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
|
||||
|
||||
uintptr_t uint_ptr = (uintptr_t) ptr;
|
||||
JERRY_ASSERT ((uint_ptr & ECMA_VALUE_FULL_MASK) == 0);
|
||||
JERRY_ASSERT ((uint_ptr & ECMA_VALUE_TYPE_MASK) == 0);
|
||||
return (ecma_value_t) uint_ptr;
|
||||
|
||||
#else /* !ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
|
||||
@@ -104,7 +99,7 @@ static inline void * __attr_pure___ __attr_always_inline___
|
||||
ecma_get_pointer_from_ecma_value (ecma_value_t value) /**< value */
|
||||
{
|
||||
#ifdef ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY
|
||||
return (void *) (uintptr_t) ((value) & ~ECMA_VALUE_FULL_MASK);
|
||||
return (void *) (uintptr_t) ((value) & ~ECMA_VALUE_TYPE_MASK);
|
||||
#else /* !ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
|
||||
return ECMA_GET_NON_NULL_POINTER (ecma_number_t,
|
||||
value >> ECMA_VALUE_SHIFT);
|
||||
@@ -145,7 +140,7 @@ static inline bool __attr_const___ __attr_always_inline___
|
||||
ecma_is_value_equal_to_simple_value (ecma_value_t value, /**< ecma value */
|
||||
ecma_simple_value_t simple_value) /**< simple value */
|
||||
{
|
||||
return (value | ECMA_VALUE_ERROR_FLAG) == (ecma_make_simple_value (simple_value) | ECMA_VALUE_ERROR_FLAG);
|
||||
return value == ecma_make_simple_value (simple_value);
|
||||
} /* ecma_is_value_equal_to_simple_value */
|
||||
|
||||
/**
|
||||
@@ -321,6 +316,18 @@ ecma_is_value_object (ecma_value_t value) /**< ecma value */
|
||||
return (ecma_get_value_type_field (value) == ECMA_TYPE_OBJECT);
|
||||
} /* ecma_is_value_object */
|
||||
|
||||
/**
|
||||
* Check if the value is error reference.
|
||||
*
|
||||
* @return true - if the value contains object value,
|
||||
* false - otherwise
|
||||
*/
|
||||
inline bool __attr_const___ __attr_always_inline___
|
||||
ecma_is_value_error_reference (ecma_value_t value) /**< ecma value */
|
||||
{
|
||||
return (ecma_get_value_type_field (value) == ECMA_TYPE_ERROR);
|
||||
} /* ecma_is_value_error_reference */
|
||||
|
||||
/**
|
||||
* Debug assertion that specified value's type is one of ECMA-defined
|
||||
* script-visible types, i.e.: undefined, null, boolean, number, string, object.
|
||||
@@ -485,7 +492,7 @@ ecma_make_uint32_value (uint32_t uint32_number) /**< uint32 number to be encoded
|
||||
/**
|
||||
* String value constructor
|
||||
*/
|
||||
ecma_value_t __attr_pure___
|
||||
inline ecma_value_t __attr_pure___ __attr_always_inline___
|
||||
ecma_make_string_value (const ecma_string_t *ecma_string_p) /**< string to reference in value */
|
||||
{
|
||||
JERRY_ASSERT (ecma_string_p != NULL);
|
||||
@@ -496,7 +503,7 @@ ecma_make_string_value (const ecma_string_t *ecma_string_p) /**< string to refer
|
||||
/**
|
||||
* Object value constructor
|
||||
*/
|
||||
ecma_value_t __attr_pure___
|
||||
inline ecma_value_t __attr_pure___ __attr_always_inline___
|
||||
ecma_make_object_value (const ecma_object_t *object_p) /**< object to reference in value */
|
||||
{
|
||||
JERRY_ASSERT (object_p != NULL);
|
||||
@@ -505,25 +512,15 @@ ecma_make_object_value (const ecma_object_t *object_p) /**< object to reference
|
||||
} /* ecma_make_object_value */
|
||||
|
||||
/**
|
||||
* Error value constructor
|
||||
* Error reference constructor
|
||||
*/
|
||||
ecma_value_t __attr_const___
|
||||
ecma_make_error_value (ecma_value_t value) /**< original ecma value */
|
||||
inline ecma_value_t __attr_pure___ __attr_always_inline___
|
||||
ecma_make_error_reference_value (const ecma_error_reference_t *error_ref_p) /**< error reference */
|
||||
{
|
||||
/* Error values cannot be converted. */
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (value));
|
||||
JERRY_ASSERT (error_ref_p != NULL);
|
||||
|
||||
return value | ECMA_VALUE_ERROR_FLAG;
|
||||
} /* ecma_make_error_value */
|
||||
|
||||
/**
|
||||
* Error value constructor
|
||||
*/
|
||||
ecma_value_t __attr_pure___
|
||||
ecma_make_error_obj_value (const ecma_object_t *object_p) /**< object to reference in value */
|
||||
{
|
||||
return ecma_make_error_value (ecma_make_object_value (object_p));
|
||||
} /* ecma_make_error_obj_value */
|
||||
return ecma_pointer_to_ecma_value (error_ref_p) | ECMA_TYPE_ERROR;
|
||||
} /* ecma_make_error_reference_value */
|
||||
|
||||
/**
|
||||
* Get integer value from an integer ecma value
|
||||
@@ -588,6 +585,19 @@ ecma_get_object_from_value (ecma_value_t value) /**< ecma value */
|
||||
return (ecma_object_t *) ecma_get_pointer_from_ecma_value (value);
|
||||
} /* ecma_get_object_from_value */
|
||||
|
||||
/**
|
||||
* Get pointer to error reference from ecma value
|
||||
*
|
||||
* @return the pointer
|
||||
*/
|
||||
inline ecma_error_reference_t *__attr_pure___ __attr_always_inline___
|
||||
ecma_get_error_reference_from_value (ecma_value_t value) /**< ecma value */
|
||||
{
|
||||
JERRY_ASSERT (ecma_get_value_type_field (value) == ECMA_TYPE_ERROR);
|
||||
|
||||
return (ecma_error_reference_t *) ecma_get_pointer_from_ecma_value (value);
|
||||
} /* ecma_get_error_reference_from_value */
|
||||
|
||||
/**
|
||||
* Invert a boolean value
|
||||
*
|
||||
@@ -601,23 +611,6 @@ ecma_invert_boolean_value (ecma_value_t value) /**< ecma value */
|
||||
return (value ^ (1 << ECMA_DIRECT_SHIFT));
|
||||
} /* ecma_invert_boolean_value */
|
||||
|
||||
/**
|
||||
* Get the value from an error ecma value
|
||||
*
|
||||
* @return ecma value
|
||||
*/
|
||||
ecma_value_t __attr_const___
|
||||
ecma_get_value_from_error_value (ecma_value_t value) /**< ecma value */
|
||||
{
|
||||
JERRY_ASSERT (ECMA_IS_VALUE_ERROR (value));
|
||||
|
||||
value = (ecma_value_t) (value & ~ECMA_VALUE_ERROR_FLAG);
|
||||
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (value));
|
||||
|
||||
return value;
|
||||
} /* ecma_get_value_from_error_value */
|
||||
|
||||
/**
|
||||
* Copy ecma value.
|
||||
*
|
||||
@@ -648,9 +641,12 @@ ecma_copy_value (ecma_value_t value) /**< value description */
|
||||
ecma_ref_object (ecma_get_object_from_value (value));
|
||||
return value;
|
||||
}
|
||||
default:
|
||||
{
|
||||
JERRY_UNREACHABLE ();
|
||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||
}
|
||||
}
|
||||
|
||||
JERRY_UNREACHABLE ();
|
||||
} /* ecma_copy_value */
|
||||
|
||||
/**
|
||||
@@ -840,6 +836,12 @@ ecma_free_value (ecma_value_t value) /**< value description */
|
||||
ecma_deref_object (ecma_get_object_from_value (value));
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
JERRY_UNREACHABLE ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} /* ecma_free_value */
|
||||
|
||||
|
||||
@@ -1320,6 +1320,103 @@ ecma_free_property_descriptor (ecma_property_descriptor_t *prop_desc_p) /**< pro
|
||||
*prop_desc_p = ecma_make_empty_property_descriptor ();
|
||||
} /* ecma_free_property_descriptor */
|
||||
|
||||
/**
|
||||
* The size of error reference must be 8 bytes to use jmem_pools_alloc().
|
||||
*/
|
||||
JERRY_STATIC_ASSERT (sizeof (ecma_error_reference_t) == 8,
|
||||
ecma_error_reference_size_must_be_8_bytes);
|
||||
|
||||
/**
|
||||
* Create an error reference from a given value.
|
||||
*
|
||||
* Note:
|
||||
* Reference of the value is taken.
|
||||
*
|
||||
* @return error reference value
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_create_error_reference (ecma_value_t value) /**< referenced value */
|
||||
{
|
||||
ecma_error_reference_t *error_ref_p = (ecma_error_reference_t *) jmem_pools_alloc (sizeof (ecma_error_reference_t));
|
||||
|
||||
error_ref_p->refs = 1;
|
||||
error_ref_p->value = value;
|
||||
return ecma_make_error_reference_value (error_ref_p);
|
||||
} /* ecma_create_error_reference */
|
||||
|
||||
/**
|
||||
* Create an error reference from a given object.
|
||||
*
|
||||
* Note:
|
||||
* Reference of the value is taken.
|
||||
*
|
||||
* @return error reference value
|
||||
*/
|
||||
inline ecma_value_t __attr_always_inline___
|
||||
ecma_create_error_object_reference (ecma_object_t *object_p) /**< referenced object */
|
||||
{
|
||||
return ecma_create_error_reference (ecma_make_object_value (object_p));
|
||||
} /* ecma_create_error_object_reference */
|
||||
|
||||
/**
|
||||
* Increase ref count of an error reference.
|
||||
*/
|
||||
void
|
||||
ecma_ref_error_reference (ecma_error_reference_t *error_ref_p) /**< error reference */
|
||||
{
|
||||
if (likely (error_ref_p->refs < UINT32_MAX))
|
||||
{
|
||||
error_ref_p->refs++;
|
||||
}
|
||||
else
|
||||
{
|
||||
jerry_fatal (ERR_REF_COUNT_LIMIT);
|
||||
}
|
||||
} /* ecma_ref_error_reference */
|
||||
|
||||
/**
|
||||
* Decrease ref count of an error reference.
|
||||
*/
|
||||
void
|
||||
ecma_deref_error_reference (ecma_error_reference_t *error_ref_p) /**< error reference */
|
||||
{
|
||||
JERRY_ASSERT (error_ref_p->refs > 0);
|
||||
|
||||
error_ref_p->refs--;
|
||||
|
||||
if (error_ref_p->refs == 0)
|
||||
{
|
||||
ecma_free_value (error_ref_p->value);
|
||||
jmem_pools_free (error_ref_p, sizeof (ecma_error_reference_t));
|
||||
}
|
||||
} /* ecma_deref_error_reference */
|
||||
|
||||
/**
|
||||
* Clears error reference, and returns with the value.
|
||||
*
|
||||
* @return value referenced by the error
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_clear_error_reference (ecma_value_t value)
|
||||
{
|
||||
ecma_error_reference_t *error_ref_p = ecma_get_error_reference_from_value (value);
|
||||
|
||||
JERRY_ASSERT (error_ref_p->refs > 0);
|
||||
|
||||
ecma_value_t referenced_value = error_ref_p->value;
|
||||
|
||||
if (error_ref_p->refs > 1)
|
||||
{
|
||||
error_ref_p->refs--;
|
||||
}
|
||||
else
|
||||
{
|
||||
jmem_pools_free (error_ref_p, sizeof (ecma_error_reference_t));
|
||||
}
|
||||
|
||||
return referenced_value;
|
||||
} /* ecma_clear_error_reference */
|
||||
|
||||
/**
|
||||
* Increase reference counter of Compact
|
||||
* Byte Code or regexp byte code.
|
||||
|
||||
@@ -128,6 +128,7 @@ bool ecma_is_value_float_number (ecma_value_t value) __attr_const___;
|
||||
bool ecma_is_value_number (ecma_value_t value) __attr_const___;
|
||||
bool ecma_is_value_string (ecma_value_t value) __attr_const___;
|
||||
bool ecma_is_value_object (ecma_value_t value) __attr_const___;
|
||||
bool ecma_is_value_error_reference (ecma_value_t value) __attr_const___;
|
||||
|
||||
void ecma_check_value_type_is_spec_defined (ecma_value_t value);
|
||||
|
||||
@@ -140,14 +141,13 @@ ecma_value_t ecma_make_int32_value (int32_t int32_number);
|
||||
ecma_value_t ecma_make_uint32_value (uint32_t uint32_number);
|
||||
ecma_value_t ecma_make_string_value (const ecma_string_t *ecma_string_p) __attr_pure___;
|
||||
ecma_value_t ecma_make_object_value (const ecma_object_t *object_p) __attr_pure___;
|
||||
ecma_value_t ecma_make_error_value (ecma_value_t value) __attr_const___;
|
||||
ecma_value_t ecma_make_error_obj_value (const ecma_object_t *object_p) __attr_pure___;
|
||||
ecma_value_t ecma_make_error_reference_value (const ecma_error_reference_t *error_ref_p) __attr_pure___;
|
||||
ecma_integer_value_t ecma_get_integer_from_value (ecma_value_t value) __attr_const___;
|
||||
ecma_number_t ecma_get_float_from_value (ecma_value_t value) __attr_pure___;
|
||||
ecma_number_t ecma_get_number_from_value (ecma_value_t value) __attr_pure___;
|
||||
ecma_string_t *ecma_get_string_from_value (ecma_value_t value) __attr_pure___;
|
||||
ecma_object_t *ecma_get_object_from_value (ecma_value_t value) __attr_pure___;
|
||||
ecma_value_t ecma_get_value_from_error_value (ecma_value_t value) __attr_const___;
|
||||
ecma_error_reference_t *ecma_get_error_reference_from_value (ecma_value_t value) __attr_pure___;
|
||||
ecma_value_t ecma_invert_boolean_value (ecma_value_t value) __attr_const___;
|
||||
ecma_value_t ecma_copy_value (ecma_value_t value);
|
||||
ecma_value_t ecma_fast_copy_value (ecma_value_t value);
|
||||
@@ -339,7 +339,11 @@ void ecma_set_property_lcached (ecma_property_t *property_p, bool is_lcached);
|
||||
ecma_property_descriptor_t ecma_make_empty_property_descriptor (void);
|
||||
void ecma_free_property_descriptor (ecma_property_descriptor_t *prop_desc_p);
|
||||
|
||||
ecma_property_t *ecma_get_next_property_pair (ecma_property_pair_t *);
|
||||
ecma_value_t ecma_create_error_reference (ecma_value_t value);
|
||||
ecma_value_t ecma_create_error_object_reference (ecma_object_t *object_p);
|
||||
void ecma_ref_error_reference (ecma_error_reference_t *error_ref_p);
|
||||
void ecma_deref_error_reference (ecma_error_reference_t *error_ref_p);
|
||||
ecma_value_t ecma_clear_error_reference (ecma_value_t value);
|
||||
|
||||
void ecma_bytecode_ref (ecma_compiled_code_t *bytecode_p);
|
||||
void ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-number-object.h"
|
||||
#include "ecma-promise-object.h"
|
||||
#include "jcontext.h"
|
||||
|
||||
#ifndef CONFIG_DISABLE_ES2015_PROMISE_BUILTIN
|
||||
|
||||
@@ -124,10 +125,9 @@ ecma_builtin_promise_reject_or_resolve (ecma_value_t this_arg, /**< "this" argum
|
||||
* Returned value must be freed with ecma_free_value.
|
||||
*/
|
||||
inline static ecma_value_t
|
||||
ecma_builtin_promise_reject_abrupt (ecma_value_t abrupt_value,
|
||||
ecma_value_t capability)
|
||||
ecma_builtin_promise_reject_abrupt (ecma_value_t capability) /**< reject description */
|
||||
{
|
||||
ecma_value_t reason = ecma_get_value_from_error_value (abrupt_value);
|
||||
ecma_value_t reason = JERRY_CONTEXT (error_value);
|
||||
ecma_string_t *str_reject = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_REJECT);
|
||||
ecma_value_t reject = ecma_op_object_get (ecma_get_object_from_value (capability), str_reject);
|
||||
ecma_deref_ecma_string (str_reject);
|
||||
@@ -590,9 +590,9 @@ ecma_builtin_promise_race_or_all (ecma_value_t this_arg, /**< 'this' argument */
|
||||
if (!ecma_is_value_object (array)
|
||||
|| ecma_get_object_type (ecma_get_object_from_value (array)) != ECMA_OBJECT_TYPE_ARRAY)
|
||||
{
|
||||
ecma_value_t error = ecma_raise_type_error (ECMA_ERR_MSG ("Second argument is not an array."));
|
||||
ret = ecma_builtin_promise_reject_abrupt (error, capability);
|
||||
ecma_free_value (error);
|
||||
ecma_raise_type_error (ECMA_ERR_MSG ("Second argument is not an array."));
|
||||
ret = ecma_builtin_promise_reject_abrupt (capability);
|
||||
ecma_free_value (JERRY_CONTEXT (error_value));
|
||||
ecma_free_value (capability);
|
||||
|
||||
return ret;
|
||||
@@ -609,7 +609,7 @@ ecma_builtin_promise_race_or_all (ecma_value_t this_arg, /**< 'this' argument */
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (ret))
|
||||
{
|
||||
ret = ecma_get_value_from_error_value (ret);
|
||||
ret = JERRY_CONTEXT (error_value);
|
||||
}
|
||||
|
||||
ecma_free_value (capability);
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "ecma-objects.h"
|
||||
#include "ecma-string-object.h"
|
||||
#include "ecma-try-catch-macro.h"
|
||||
#include "jcontext.h"
|
||||
#include "jrt.h"
|
||||
#include "jrt-libc-includes.h"
|
||||
#include "lit-char-helpers.h"
|
||||
@@ -1593,6 +1594,11 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_arg, /**< this arg
|
||||
match_result = ecma_regexp_exec_helper (regexp_value, ecma_make_string_value (substr_str_p), true);
|
||||
should_return = !ecma_is_value_null (match_result);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (match_result))
|
||||
{
|
||||
match_result = JERRY_CONTEXT (error_value);
|
||||
}
|
||||
|
||||
ecma_deref_ecma_string (substr_str_p);
|
||||
ecma_free_value (match_result);
|
||||
#else
|
||||
@@ -1684,6 +1690,10 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_arg, /**< this arg
|
||||
if (ecma_is_value_null (match_result) || ECMA_IS_VALUE_ERROR (match_result))
|
||||
{
|
||||
curr_pos++;
|
||||
if (ECMA_IS_VALUE_ERROR (match_result))
|
||||
{
|
||||
ecma_free_value (JERRY_CONTEXT (error_value));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "ecma-globals.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "ecma-objects.h"
|
||||
#include "jcontext.h"
|
||||
#include "jrt.h"
|
||||
|
||||
/** \addtogroup ecma ECMA
|
||||
@@ -155,7 +156,8 @@ ecma_raise_standard_error (ecma_standard_error_t error_type, /**< error type */
|
||||
error_obj_p = ecma_new_standard_error (error_type);
|
||||
}
|
||||
|
||||
return ecma_make_error_obj_value (error_obj_p);
|
||||
JERRY_CONTEXT (error_value) = ecma_make_object_value (error_obj_p);
|
||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_ERROR);
|
||||
} /* ecma_raise_standard_error */
|
||||
|
||||
#ifdef JERRY_ENABLE_ERROR_MESSAGES
|
||||
@@ -242,7 +244,9 @@ ecma_raise_standard_error_with_format (ecma_standard_error_t error_type, /**< er
|
||||
|
||||
ecma_object_t *error_obj_p = ecma_new_standard_error_with_message (error_type, error_msg_p);
|
||||
ecma_deref_ecma_string (error_msg_p);
|
||||
return ecma_make_error_obj_value (error_obj_p);
|
||||
|
||||
JERRY_CONTEXT (error_value) = ecma_make_object_value (error_obj_p);
|
||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_ERROR);
|
||||
} /* ecma_raise_standard_error_with_format */
|
||||
|
||||
#endif /* JERRY_ENABLE_ERROR_MESSAGES */
|
||||
|
||||
@@ -468,6 +468,12 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
|
||||
this_arg_value,
|
||||
arguments_list_p,
|
||||
arguments_list_len);
|
||||
|
||||
if (unlikely (ecma_is_value_error_reference (ret_value)))
|
||||
{
|
||||
JERRY_CONTEXT (error_value) = ecma_clear_error_reference (ret_value);
|
||||
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_ERROR);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -179,7 +179,7 @@ ecma_process_promise_reaction_job (void *obj_p) /**< the job to be operated */
|
||||
{
|
||||
if (ECMA_IS_VALUE_ERROR (handler_result))
|
||||
{
|
||||
handler_result = ecma_get_value_from_error_value (handler_result);
|
||||
handler_result = JERRY_CONTEXT (error_value);
|
||||
}
|
||||
|
||||
/* 7. */
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "ecma-objects.h"
|
||||
#include "ecma-objects-general.h"
|
||||
#include "ecma-promise-object.h"
|
||||
#include "jcontext.h"
|
||||
|
||||
#ifndef CONFIG_DISABLE_ES2015_PROMISE_BUILTIN
|
||||
|
||||
@@ -547,7 +548,7 @@ ecma_op_create_promise_object (ecma_value_t executor, /**< the executor function
|
||||
if (ECMA_IS_VALUE_ERROR (completion))
|
||||
{
|
||||
/* 10.a. */
|
||||
completion = ecma_get_value_from_error_value (completion);
|
||||
completion = JERRY_CONTEXT (error_value);
|
||||
status = ecma_op_function_call (ecma_get_object_from_value (funcs->reject),
|
||||
ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED),
|
||||
&completion,
|
||||
|
||||
@@ -81,6 +81,7 @@ typedef struct
|
||||
size_t jmem_heap_allocated_size; /**< size of allocated regions */
|
||||
size_t jmem_heap_limit; /**< current limit of heap usage, that is upon being reached,
|
||||
* causes call of "try give memory back" callbacks */
|
||||
ecma_value_t error_value; /**< currently thrown error value */
|
||||
uint32_t lit_magic_string_ex_count; /**< external magic strings count */
|
||||
uint32_t jerry_init_flags; /**< run-time configuration flags */
|
||||
uint8_t is_direct_eval_form_call; /**< direct call from eval */
|
||||
|
||||
@@ -2721,7 +2721,8 @@ parser_parse_script (const uint8_t *arg_list_p, /**< function argument list */
|
||||
{
|
||||
/* It is unlikely that memory can be allocated in an out-of-memory
|
||||
* situation. However, a simple value can still be thrown. */
|
||||
return ecma_make_error_value (ecma_make_simple_value (ECMA_SIMPLE_VALUE_NULL));
|
||||
JERRY_CONTEXT (error_value) = ecma_make_simple_value (ECMA_SIMPLE_VALUE_NULL);
|
||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_ERROR);
|
||||
}
|
||||
#ifdef JERRY_ENABLE_ERROR_MESSAGES
|
||||
const lit_utf8_byte_t *err_bytes_p = (const lit_utf8_byte_t *) parser_error_to_string (parser_error.error);
|
||||
|
||||
@@ -44,8 +44,8 @@ do_number_bitwise_logic (number_bitwise_logic_op op, /**< number bitwise logic o
|
||||
{
|
||||
JERRY_STATIC_ASSERT (ECMA_DIRECT_TYPE_INTEGER_VALUE == 0,
|
||||
ecma_direct_type_integer_value_must_be_zero_for_bitwise_logic);
|
||||
JERRY_STATIC_ASSERT ((ECMA_DIRECT_TYPE_MASK | ECMA_VALUE_ERROR_FLAG) == ((1 << ECMA_DIRECT_SHIFT) - 1),
|
||||
direct_type_mask_and_error_flag_must_fill_all_bits_before_the_value_starts);
|
||||
JERRY_STATIC_ASSERT (ECMA_DIRECT_TYPE_MASK == ((1 << ECMA_DIRECT_SHIFT) - 1),
|
||||
direct_type_mask_must_fill_all_bits_before_the_value_starts);
|
||||
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (left_value)
|
||||
&& !ECMA_IS_VALUE_ERROR (right_value));
|
||||
|
||||
+30
-10
@@ -679,7 +679,15 @@ vm_init_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
name_p,
|
||||
is_strict,
|
||||
lit_value);
|
||||
ecma_free_value (put_value_result);
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_boolean (put_value_result)
|
||||
|| ecma_is_value_empty (put_value_result)
|
||||
|| ECMA_IS_VALUE_ERROR (put_value_result));
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (put_value_result))
|
||||
{
|
||||
ecma_free_value (JERRY_CONTEXT (error_value));
|
||||
}
|
||||
}
|
||||
|
||||
if (value_index >= register_end)
|
||||
@@ -882,10 +890,15 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
{
|
||||
JERRY_CONTEXT (vm_exec_stop_counter) = 1;
|
||||
|
||||
if (!ECMA_IS_VALUE_ERROR (result))
|
||||
if (!ecma_is_value_error_reference (result))
|
||||
{
|
||||
result = ecma_make_error_value (result);
|
||||
JERRY_CONTEXT (error_value) = result;
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_CONTEXT (error_value) = ecma_clear_error_reference (result);
|
||||
}
|
||||
result = ecma_make_simple_value (ECMA_SIMPLE_VALUE_ERROR);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
@@ -1399,7 +1412,8 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
}
|
||||
case VM_OC_THROW:
|
||||
{
|
||||
result = ecma_make_error_value (left_value);
|
||||
JERRY_CONTEXT (error_value) = left_value;
|
||||
result = ecma_make_simple_value (ECMA_SIMPLE_VALUE_ERROR);
|
||||
left_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||
goto error;
|
||||
}
|
||||
@@ -2322,11 +2336,12 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
||||
}
|
||||
case VM_CONTEXT_FINALLY_THROW:
|
||||
{
|
||||
result = stack_top_p[-2];
|
||||
JERRY_CONTEXT (error_value) = stack_top_p[-2];
|
||||
|
||||
VM_MINUS_EQUAL_U16 (frame_ctx_p->context_depth,
|
||||
PARSER_TRY_CONTEXT_STACK_ALLOCATION);
|
||||
stack_top_p -= PARSER_TRY_CONTEXT_STACK_ALLOCATION;
|
||||
result = ecma_make_simple_value (ECMA_SIMPLE_VALUE_ERROR);
|
||||
goto error;
|
||||
}
|
||||
case VM_CONTEXT_FINALLY_RETURN:
|
||||
@@ -2567,7 +2582,7 @@ error:
|
||||
&& !(frame_ctx_p->bytecode_header_p->status_flags & CBC_CODE_FLAGS_DEBUGGER_IGNORE)
|
||||
&& !(JERRY_CONTEXT (debugger_flags) & (JERRY_DEBUGGER_VM_IGNORE_EXCEPTION | JERRY_DEBUGGER_VM_IGNORE)))
|
||||
{
|
||||
if (jerry_debugger_send_exception_string (result))
|
||||
if (jerry_debugger_send_exception_string ())
|
||||
{
|
||||
jerry_debugger_breakpoint_hit (JERRY_DEBUGGER_EXCEPTION_HIT);
|
||||
}
|
||||
@@ -2621,7 +2636,7 @@ error:
|
||||
ecma_object_t *catch_env_p;
|
||||
ecma_string_t *catch_name_p;
|
||||
|
||||
*stack_top_p++ = ecma_get_value_from_error_value (result);
|
||||
*stack_top_p++ = JERRY_CONTEXT (error_value);
|
||||
|
||||
JERRY_ASSERT (byte_code_p[0] == CBC_ASSIGN_SET_IDENT);
|
||||
|
||||
@@ -2644,7 +2659,7 @@ error:
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (VM_GET_CONTEXT_TYPE (stack_top_p[-1]) == VM_CONTEXT_FINALLY_THROW);
|
||||
stack_top_p[-2] = result;
|
||||
stack_top_p[-2] = JERRY_CONTEXT (error_value);
|
||||
}
|
||||
|
||||
#ifdef JERRY_VM_EXEC_STOP
|
||||
@@ -2664,10 +2679,15 @@ error:
|
||||
left_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||
right_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
|
||||
|
||||
if (!ECMA_IS_VALUE_ERROR (result))
|
||||
if (!ecma_is_value_error_reference (result))
|
||||
{
|
||||
result = ecma_make_error_value (result);
|
||||
JERRY_CONTEXT (error_value) = result;
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_CONTEXT (error_value) = ecma_clear_error_reference (result);
|
||||
}
|
||||
result = ecma_make_simple_value (ECMA_SIMPLE_VALUE_ERROR);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,9 +133,8 @@ jerry_value_is_syntax_error (jerry_value_t error_value) /**< error value */
|
||||
static void
|
||||
print_unhandled_exception (jerry_value_t error_value) /**< error value */
|
||||
{
|
||||
assert (jerry_value_has_error_flag (error_value));
|
||||
assert (!jerry_value_has_error_flag (error_value));
|
||||
|
||||
jerry_value_clear_error_flag (&error_value);
|
||||
jerry_value_t err_str_val = jerry_value_to_string (error_value);
|
||||
jerry_size_t err_str_size = jerry_get_string_size (err_str_val);
|
||||
jerry_char_t err_str_buf[256];
|
||||
@@ -262,6 +261,7 @@ register_js_function (const char *name_p, /**< name of the function */
|
||||
if (jerry_value_has_error_flag (result_val))
|
||||
{
|
||||
jerry_port_log (JERRY_LOG_LEVEL_WARNING, "Warning: failed to register '%s' method.", name_p);
|
||||
jerry_value_clear_error_flag (&result_val);
|
||||
print_unhandled_exception (result_val);
|
||||
}
|
||||
|
||||
@@ -870,11 +870,13 @@ main (int argc,
|
||||
|
||||
if (jerry_value_has_error_flag (ret_val_eval))
|
||||
{
|
||||
jerry_value_clear_error_flag (&ret_val_eval);
|
||||
print_unhandled_exception (ret_val_eval);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
jerry_value_clear_error_flag (&ret_val_eval);
|
||||
print_unhandled_exception (ret_val_eval);
|
||||
}
|
||||
|
||||
@@ -887,6 +889,7 @@ main (int argc,
|
||||
|
||||
if (jerry_value_has_error_flag (ret_value))
|
||||
{
|
||||
jerry_value_clear_error_flag (&ret_value);
|
||||
print_unhandled_exception (ret_value);
|
||||
|
||||
ret_code = JERRY_STANDALONE_EXIT_CODE_FAIL;
|
||||
@@ -898,6 +901,7 @@ main (int argc,
|
||||
|
||||
if (jerry_value_has_error_flag (ret_value))
|
||||
{
|
||||
jerry_value_clear_error_flag (&ret_value);
|
||||
print_unhandled_exception (ret_value);
|
||||
ret_code = JERRY_STANDALONE_EXIT_CODE_FAIL;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user