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:
Zoltan Herczeg
2017-10-18 03:44:48 -07:00
committed by yichoi
parent 742654a3f1
commit 53cd324179
19 changed files with 582 additions and 288 deletions
+10 -5
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+6 -4
View File
@@ -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))
+1 -1
View File
@@ -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 */
+19 -13
View File
@@ -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.
*/
+48 -46
View File
@@ -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 */
+97
View File
@@ -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.
+8 -4
View File
@@ -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
{
+6 -2
View File
@@ -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
{
+1 -1
View File
@@ -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,
+1
View File
@@ -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 */
+2 -1
View File
@@ -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);
+2 -2
View File
@@ -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
View File
@@ -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;
}
}
+6 -2
View File
@@ -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;
}