Revise the usage of the global error value/exception flag (#3426)

This patch also fixes #3422.

JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu
This commit is contained in:
Robert Fancsik 2019-12-10 14:42:10 +01:00 committed by Zoltan Herczeg
parent 7c0b1ca88a
commit 9b33fc8cbd
28 changed files with 238 additions and 108 deletions

View File

@ -763,7 +763,7 @@ jerry_generate_snapshot_with_args (const jerry_char_t *resource_name_p, /**< scr
if (ECMA_IS_VALUE_ERROR (parse_status))
{
return ecma_create_error_reference (JERRY_CONTEXT (error_value), true);
return ecma_create_error_reference_from_context ();
}
JERRY_ASSERT (bytecode_data_p != NULL);

View File

@ -3057,7 +3057,7 @@ jerry_foreach_object_property (const jerry_value_t obj_val, /**< object value */
return true;
}
ecma_free_value (JERRY_CONTEXT (error_value));
jcontext_release_exception ();
return false;
} /* jerry_foreach_object_property */

View File

@ -555,21 +555,15 @@ jerry_debugger_send_eval (const lit_utf8_byte_t *eval_string_p, /**< evaluated s
{
if (eval_string_p[4] != JERRY_DEBUGGER_EVAL_EVAL)
{
JERRY_ASSERT (eval_string_p[4] == JERRY_DEBUGGER_EVAL_THROW || eval_string_p[4] == JERRY_DEBUGGER_EVAL_ABORT);
JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_EXCEPTION_THROWN);
JERRY_CONTEXT (error_value) = result;
/* Stop where the error is caught. */
JERRY_DEBUGGER_SET_FLAGS (JERRY_DEBUGGER_VM_STOP);
JERRY_CONTEXT (debugger_stop_context) = NULL;
if (eval_string_p[4] == JERRY_DEBUGGER_EVAL_THROW)
{
JERRY_CONTEXT (status_flags) |= ECMA_STATUS_EXCEPTION;
}
else
{
JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_EXCEPTION;
}
jcontext_raise_exception (result);
jcontext_set_abort_flag (eval_string_p[4] == JERRY_DEBUGGER_EVAL_ABORT);
return true;
}
@ -1519,12 +1513,11 @@ jerry_debugger_exception_object_to_string (ecma_value_t exception_obj_value) /**
* false - otherwise
*/
bool
jerry_debugger_send_exception_string (void)
jerry_debugger_send_exception_string (ecma_value_t exception_value)
{
JERRY_ASSERT (jcontext_has_pending_exception ());
ecma_string_t *string_p = NULL;
ecma_value_t exception_value = JERRY_CONTEXT (error_value);
if (ecma_is_value_object (exception_value))
{
string_p = jerry_debugger_exception_object_to_string (exception_value);

View File

@ -484,7 +484,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 (void);
bool jerry_debugger_send_exception_string (ecma_value_t exception_value);
#endif /* ENABLED (JERRY_DEBUGGER) */

View File

@ -62,6 +62,7 @@ typedef enum
ECMA_STATUS_HIGH_PRESSURE_GC = (1u << 2), /**< last gc was under high pressure */
#endif /* ENABLED (JERRY_PROPRETY_HASHMAP) */
ECMA_STATUS_EXCEPTION = (1u << 3), /**< last exception is a normal exception */
ECMA_STATUS_ABORT = (1u << 4), /**< last exception is an abort */
} ecma_status_flag_t;
/**

View File

@ -1256,7 +1256,6 @@ 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));
JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_EXCEPTION;
error_ref_p->refs_and_flags = ECMA_ERROR_REF_ONE | (is_exception ? 0 : ECMA_ERROR_REF_ABORT);
error_ref_p->value = value;
return ecma_make_error_reference_value (error_ref_p);
@ -1270,8 +1269,13 @@ ecma_create_error_reference (ecma_value_t value, /**< referenced value */
ecma_value_t
ecma_create_error_reference_from_context (void)
{
return ecma_create_error_reference (JERRY_CONTEXT (error_value),
(JERRY_CONTEXT (status_flags) & ECMA_STATUS_EXCEPTION) != 0);
bool is_abort = jcontext_has_pending_abort ();
if (is_abort)
{
jcontext_set_abort_flag (false);
}
return ecma_create_error_reference (jcontext_take_exception (), !is_abort);
} /* ecma_create_error_reference_from_context */
/**
@ -1322,40 +1326,35 @@ ecma_deref_error_reference (ecma_error_reference_t *error_ref_p) /**< error refe
} /* ecma_deref_error_reference */
/**
* Clears error reference, and returns with the value.
* Raise error from the given error reference.
*
* @return value referenced by the error
* Note: the error reference's ref count is also decreased
*/
ecma_value_t
ecma_clear_error_reference (ecma_value_t value, /**< error reference */
bool set_abort_flag) /**< set abort flag */
void
ecma_raise_error_from_error_reference (ecma_value_t value) /**< error reference */
{
JERRY_ASSERT (!jcontext_has_pending_exception () && !jcontext_has_pending_abort ());
ecma_error_reference_t *error_ref_p = ecma_get_error_reference_from_value (value);
if (set_abort_flag)
{
if (error_ref_p->refs_and_flags & ECMA_ERROR_REF_ABORT)
{
JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_EXCEPTION;
}
else
{
JERRY_CONTEXT (status_flags) |= ECMA_STATUS_EXCEPTION;
}
}
JERRY_ASSERT (error_ref_p->refs_and_flags >= ECMA_ERROR_REF_ONE);
ecma_value_t referenced_value = error_ref_p->value;
jcontext_set_exception_flag (true);
jcontext_set_abort_flag (error_ref_p->refs_and_flags & ECMA_ERROR_REF_ABORT);
if (error_ref_p->refs_and_flags >= 2 * ECMA_ERROR_REF_ONE)
{
error_ref_p->refs_and_flags -= ECMA_ERROR_REF_ONE;
return ecma_copy_value (error_ref_p->value);
referenced_value = ecma_copy_value (referenced_value);
}
else
{
jmem_pools_free (error_ref_p, sizeof (ecma_error_reference_t));
}
ecma_value_t referenced_value = error_ref_p->value;
jmem_pools_free (error_ref_p, sizeof (ecma_error_reference_t));
return referenced_value;
} /* ecma_clear_error_reference */
JERRY_CONTEXT (error_value) = referenced_value;
} /* ecma_raise_error_from_error_reference */
/**
* Increase reference counter of Compact

View File

@ -421,7 +421,7 @@ ecma_value_t ecma_create_error_reference_from_context (void);
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, bool set_abort_flag);
void ecma_raise_error_from_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);

View File

@ -137,8 +137,7 @@ ecma_builtin_generator_prototype_object_do (ecma_value_t this_arg, /**< this arg
if (ECMA_IS_VALUE_ERROR (arg))
{
arg = JERRY_CONTEXT (error_value);
JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_EXCEPTION;
arg = jcontext_take_exception ();
resume_mode = ECMA_ITERATOR_THROW;
}
}
@ -176,8 +175,7 @@ ecma_builtin_generator_prototype_object_do (ecma_value_t this_arg, /**< this arg
if (ECMA_IS_VALUE_ERROR (iterator))
{
resume_mode = ECMA_ITERATOR_THROW;
arg = JERRY_CONTEXT (error_value);
JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_EXCEPTION;
arg = jcontext_take_exception ();
continue;
}

View File

@ -127,8 +127,7 @@ inline static ecma_value_t
ecma_builtin_promise_reject_abrupt (ecma_value_t capability) /**< reject description */
{
ecma_raise_type_error (ECMA_ERR_MSG ("Second argument is not an array."));
ecma_value_t reason = JERRY_CONTEXT (error_value);
JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_EXCEPTION;
ecma_value_t reason = jcontext_take_exception ();
ecma_string_t *reject_str_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_PROMISE_PROPERTY_REJECT);
ecma_value_t reject = ecma_op_object_get (ecma_get_object_from_value (capability), reject_str_p);
@ -610,7 +609,7 @@ ecma_builtin_promise_race_or_all (ecma_value_t this_arg, /**< 'this' argument */
if (ECMA_IS_VALUE_ERROR (ret))
{
ret = JERRY_CONTEXT (error_value);
ret = jcontext_take_exception ();
}
ecma_free_value (capability);

View File

@ -93,7 +93,14 @@ ecma_builtin_reflect_dispatch_routine (uint16_t builtin_routine_id, /**< built-i
ecma_value_t result = ecma_builtin_object_object_set_prototype_of (arguments_list[0], arguments_list[1]);
bool is_error = ECMA_IS_VALUE_ERROR (result);
ecma_free_value (is_error ? JERRY_CONTEXT (error_value) : result);
if (is_error)
{
jcontext_release_exception ();
}
else
{
ecma_free_value (result);
}
return ecma_make_boolean_value (!is_error);
}
@ -121,7 +128,14 @@ ecma_builtin_reflect_dispatch_routine (uint16_t builtin_routine_id, /**< built-i
ecma_deref_ecma_string (name_str_p);
bool is_error = ECMA_IS_VALUE_ERROR (result);
ecma_free_value (is_error ? JERRY_CONTEXT (error_value) : result);
if (is_error)
{
jcontext_release_exception ();
}
else
{
ecma_free_value (result);
}
return ecma_make_boolean_value (!is_error);
}

View File

@ -808,8 +808,7 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_to_string_val, /**
if (ECMA_IS_VALUE_ERROR (match_result))
{
match_result = JERRY_CONTEXT (error_value);
JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_EXCEPTION;
match_result = jcontext_take_exception ();
}
ecma_free_value (match_result);
@ -898,8 +897,7 @@ ecma_builtin_string_prototype_object_split (ecma_value_t this_to_string_val, /**
curr_pos++;
if (ECMA_IS_VALUE_ERROR (match_result))
{
ecma_free_value (JERRY_CONTEXT (error_value));
JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_EXCEPTION;
jcontext_release_exception ();
}
}
else

View File

@ -238,8 +238,7 @@ ecma_raise_standard_error (ecma_standard_error_t error_type, /**< error type */
error_obj_p = ecma_new_standard_error (error_type);
}
JERRY_CONTEXT (error_value) = ecma_make_object_value (error_obj_p);
JERRY_CONTEXT (status_flags) |= ECMA_STATUS_EXCEPTION;
jcontext_raise_exception (ecma_make_object_value (error_obj_p));
return ECMA_VALUE_ERROR;
} /* ecma_raise_standard_error */
@ -333,8 +332,7 @@ 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);
JERRY_CONTEXT (error_value) = ecma_make_object_value (error_obj_p);
JERRY_CONTEXT (status_flags) |= ECMA_STATUS_EXCEPTION;
jcontext_raise_exception (ecma_make_object_value (error_obj_p));
return ECMA_VALUE_ERROR;
} /* ecma_raise_standard_error_with_format */

View File

@ -880,7 +880,7 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
if (JERRY_UNLIKELY (ecma_is_value_error_reference (ret_value)))
{
JERRY_CONTEXT (error_value) = ecma_clear_error_reference (ret_value, true);
ecma_raise_error_from_error_reference (ret_value);
return ECMA_VALUE_ERROR;
}

View File

@ -416,10 +416,9 @@ ecma_op_iterator_close (ecma_value_t iterator) /**< iterator value */
/* 2. */
ecma_value_t completion = ECMA_VALUE_EMPTY;
if (JERRY_CONTEXT (status_flags) & ECMA_STATUS_EXCEPTION)
if (jcontext_has_pending_exception ())
{
completion = JERRY_CONTEXT (error_value);
JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_EXCEPTION;
completion = jcontext_take_exception ();
}
/* 3. */
@ -440,7 +439,7 @@ ecma_op_iterator_close (ecma_value_t iterator) /**< iterator value */
return ECMA_VALUE_UNDEFINED;
}
JERRY_CONTEXT (status_flags) |= ECMA_STATUS_EXCEPTION;
jcontext_raise_exception (completion);
return ECMA_VALUE_ERROR;
}
@ -454,12 +453,14 @@ ecma_op_iterator_close (ecma_value_t iterator) /**< iterator value */
{
if (ECMA_IS_VALUE_ERROR (inner_result))
{
ecma_free_value (JERRY_CONTEXT (error_value));
JERRY_CONTEXT (error_value) = completion;
jcontext_release_exception ();
}
else
{
ecma_free_value (inner_result);
}
ecma_free_value (inner_result);
JERRY_CONTEXT (status_flags) |= ECMA_STATUS_EXCEPTION;
jcontext_raise_exception (completion);
return ECMA_VALUE_ERROR;
}
@ -486,7 +487,7 @@ ecma_op_iterator_close (ecma_value_t iterator) /**< iterator value */
return ECMA_VALUE_UNDEFINED;
}
JERRY_CONTEXT (status_flags) |= ECMA_STATUS_EXCEPTION;
jcontext_raise_exception (completion);
return ECMA_VALUE_ERROR;
} /* ecma_op_iterator_close */

View File

@ -179,8 +179,7 @@ ecma_process_promise_reaction_job (void *obj_p) /**< the job to be operated */
{
if (ECMA_IS_VALUE_ERROR (handler_result))
{
handler_result = JERRY_CONTEXT (error_value);
JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_EXCEPTION;
handler_result = jcontext_take_exception ();
}
/* 7. */
@ -254,8 +253,7 @@ ecma_process_promise_resolve_thenable_job (void *obj_p) /**< the job to be opera
if (ECMA_IS_VALUE_ERROR (then_call_result))
{
then_call_result = JERRY_CONTEXT (error_value);
JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_EXCEPTION;
then_call_result = jcontext_take_exception ();
ret = ecma_op_function_call (ecma_get_object_from_value (funcs->reject),
ECMA_VALUE_UNDEFINED,

View File

@ -1232,7 +1232,7 @@ ecma_op_object_put (ecma_object_t *object_p, /**< the object */
if (ECMA_IS_VALUE_ERROR (error))
{
ecma_free_value (JERRY_CONTEXT (error_value));
jcontext_release_exception ();
return ecma_reject (is_throw);
}

View File

@ -330,8 +330,7 @@ ecma_promise_resolve_handler (const ecma_value_t function, /**< the function its
if (ECMA_IS_VALUE_ERROR (then))
{
/* 9. */
then = JERRY_CONTEXT (error_value);
JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_EXCEPTION;
then = jcontext_take_exception ();
ecma_reject_promise (promise, then);
}
else if (!ecma_op_is_callable (then))
@ -551,8 +550,7 @@ ecma_op_create_promise_object (ecma_value_t executor, /**< the executor function
if (ECMA_IS_VALUE_ERROR (completion))
{
/* 10.a. */
completion = JERRY_CONTEXT (error_value);
JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_EXCEPTION;
completion = jcontext_take_exception ();
status = ecma_op_function_call (ecma_get_object_from_value (funcs->reject),
ECMA_VALUE_UNDEFINED,
&completion,

View File

@ -1130,7 +1130,7 @@ ecma_op_typedarray_define_index_prop (ecma_object_t *obj_p, /**< a TypedArray ob
if (ECMA_IS_VALUE_ERROR (error))
{
ecma_free_value (JERRY_CONTEXT (error_value));
jcontext_release_exception ();
return false;
}
ecma_typedarray_info_t info = ecma_typedarray_get_info (obj_p);

View File

@ -19,6 +19,105 @@
* @{
*/
/**
* Check the existence of the ECMA_STATUS_EXCEPTION flag.
*
* @return true - if the flag is set
* false - otherwise
*/
extern inline bool JERRY_ATTR_ALWAYS_INLINE
jcontext_has_pending_exception (void)
{
return JERRY_CONTEXT (status_flags) & ECMA_STATUS_EXCEPTION;
} /* jcontext_has_pending_exception */
/**
* Check the existence of the ECMA_STATUS_ABORT flag.
*
* @return true - if the flag is set
* false - otherwise
*/
extern inline bool JERRY_ATTR_ALWAYS_INLINE
jcontext_has_pending_abort (void)
{
return JERRY_CONTEXT (status_flags) & ECMA_STATUS_ABORT;
} /* jcontext_has_pending_abort */
/**
* Set the abort flag for the context.
*/
extern inline void JERRY_ATTR_ALWAYS_INLINE
jcontext_set_abort_flag (bool is_abort) /**< true - if the abort flag should be set
* false - if the abort flag should be removed */
{
JERRY_ASSERT (jcontext_has_pending_exception ());
if (is_abort)
{
JERRY_CONTEXT (status_flags) |= ECMA_STATUS_ABORT;
}
else
{
JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_ABORT;
}
} /* jcontext_set_abort_flag */
/**
* Set the exception flag for the context.
*/
extern inline void JERRY_ATTR_ALWAYS_INLINE
jcontext_set_exception_flag (bool is_exception) /**< true - if the exception flag should be set
* false - if the exception flag should be removed */
{
if (is_exception)
{
JERRY_CONTEXT (status_flags) |= ECMA_STATUS_EXCEPTION;
}
else
{
JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_EXCEPTION;
}
} /* jcontext_set_exception_flag */
/**
* Raise exception from the given error value.
*/
extern inline void JERRY_ATTR_ALWAYS_INLINE
jcontext_raise_exception (ecma_value_t error) /**< error to raise */
{
JERRY_ASSERT (!jcontext_has_pending_exception ());
JERRY_ASSERT (!jcontext_has_pending_abort ());
JERRY_CONTEXT (error_value) = error;
jcontext_set_exception_flag (true);
} /* jcontext_raise_exception */
/**
* Release the current exception/abort of the context.
*/
void
jcontext_release_exception (void)
{
JERRY_ASSERT (jcontext_has_pending_exception ());
ecma_free_value (jcontext_take_exception ());
} /* jcontext_release_exception */
/**
* Take the current exception/abort of context.
*
* @return current exception as an ecma-value
*/
ecma_value_t
jcontext_take_exception (void)
{
JERRY_ASSERT (jcontext_has_pending_exception ());
jcontext_set_abort_flag (false);
jcontext_set_exception_flag (false);
return JERRY_CONTEXT (error_value);
} /* jcontext_take_exception */
#if !ENABLED (JERRY_EXTERNAL_CONTEXT)
/**

View File

@ -21,6 +21,7 @@
#include "debugger.h"
#include "ecma-builtins.h"
#include "ecma-helpers.h"
#include "ecma-jobqueue.h"
#include "jerryscript-port.h"
#include "jmem.h"
@ -294,6 +295,27 @@ extern jmem_heap_t jerry_global_heap;
#endif /* ENABLED (JERRY_EXTERNAL_CONTEXT) */
void
jcontext_set_exception_flag (bool is_exception);
void
jcontext_set_abort_flag (bool is_abort);
bool
jcontext_has_pending_exception (void);
bool
jcontext_has_pending_abort (void);
void
jcontext_raise_exception (ecma_value_t error);
void
jcontext_release_exception (void);
ecma_value_t
jcontext_take_exception (void);
/**
* @}
*/

View File

@ -2433,16 +2433,14 @@ lexer_construct_regexp_object (parser_context_t *context_p, /**< context */
current_flags);
ecma_deref_ecma_string (pattern_str_p);
bool is_throw = ECMA_IS_VALUE_ERROR (completion_value) != 0;
ecma_free_value (completion_value);
if (is_throw)
if (ECMA_IS_VALUE_ERROR (completion_value))
{
ecma_free_value (JERRY_CONTEXT (error_value));
jcontext_release_exception ();
parser_raise_error (context_p, PARSER_ERR_INVALID_REGEXP);
}
ecma_free_value (completion_value);
literal_p->type = LEXER_REGEXP_LITERAL;
literal_p->u.bytecode_p = (ecma_compiled_code_t *) re_bytecode_p;

View File

@ -2542,8 +2542,7 @@ 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. */
JERRY_CONTEXT (error_value) = ECMA_VALUE_NULL;
JERRY_CONTEXT (status_flags) |= ECMA_STATUS_EXCEPTION;
jcontext_raise_exception (ECMA_VALUE_NULL);
return ECMA_VALUE_ERROR;
}
#if ENABLED (JERRY_ERROR_MESSAGES)

View File

@ -656,7 +656,7 @@ re_parse_next_token (re_parser_ctx_t *parser_ctx_p, /**< RegExp parser context *
}
JERRY_ASSERT (ECMA_IS_VALUE_ERROR (ret_value));
ecma_free_value (JERRY_CONTEXT (error_value));
jcontext_release_exception ();
parser_ctx_p->input_curr_p = input_curr_p;
/* It was not an iterator, continue the parsing. */
@ -682,7 +682,7 @@ re_parse_next_token (re_parser_ctx_t *parser_ctx_p, /**< RegExp parser context *
if (!ecma_is_value_empty (ret_value))
{
ecma_free_value (JERRY_CONTEXT (error_value));
jcontext_release_exception ();
parser_ctx_p->input_curr_p = input_curr_p;
ret_value = ECMA_VALUE_EMPTY;
}

View File

@ -84,7 +84,7 @@ vm_set_var (ecma_object_t *lex_env_p, /**< target lexical environment */
if (ECMA_IS_VALUE_ERROR (put_value_result))
{
ecma_free_value (JERRY_CONTEXT (error_value));
jcontext_release_exception ();
}
ecma_free_value (lit_value);

View File

@ -169,7 +169,7 @@ vm_op_set_value (ecma_value_t object, /**< base object */
{
#if ENABLED (JERRY_ERROR_MESSAGES)
ecma_free_value (to_object);
ecma_free_value (JERRY_CONTEXT (error_value));
jcontext_release_exception ();
ecma_value_t error_value = ecma_raise_standard_error_with_format (ECMA_ERROR_TYPE,
"Cannot set property '%' of %",
@ -1273,16 +1273,17 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
{
JERRY_CONTEXT (vm_exec_stop_counter) = 1;
if (!ecma_is_value_error_reference (result))
if (ecma_is_value_error_reference (result))
{
JERRY_CONTEXT (error_value) = result;
ecma_raise_error_from_error_reference (result);
}
else
{
JERRY_CONTEXT (error_value) = ecma_clear_error_reference (result, false);
jcontext_raise_exception (result);
}
JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_EXCEPTION;
JERRY_ASSERT (jcontext_has_pending_exception ());
jcontext_set_abort_flag (true);
result = ECMA_VALUE_ERROR;
goto error;
}
@ -1628,7 +1629,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
{
if (ECMA_IS_VALUE_ERROR (result))
{
ecma_free_value (JERRY_CONTEXT (error_value));
jcontext_release_exception ();
}
ecma_free_value (result);
@ -2415,8 +2416,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
}
case VM_OC_THROW:
{
JERRY_CONTEXT (error_value) = left_value;
JERRY_CONTEXT (status_flags) |= ECMA_STATUS_EXCEPTION;
jcontext_raise_exception (left_value);
result = ECMA_VALUE_ERROR;
left_value = ECMA_VALUE_UNDEFINED;
@ -2636,8 +2636,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
if (ref_base_lex_env_p == NULL)
{
ecma_free_value (JERRY_CONTEXT (error_value));
JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_EXCEPTION;
jcontext_release_exception ();
result = ECMA_VALUE_UNDEFINED;
}
else if (ECMA_IS_VALUE_ERROR (result))
@ -3578,8 +3577,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
if (context_type == VM_CONTEXT_FINALLY_THROW)
{
JERRY_CONTEXT (error_value) = *stack_top_p;
JERRY_CONTEXT (status_flags) |= ECMA_STATUS_EXCEPTION;
jcontext_raise_exception (*stack_top_p);
result = ECMA_VALUE_ERROR;
#if ENABLED (JERRY_DEBUGGER)
@ -3841,6 +3839,7 @@ error:
if (ECMA_IS_VALUE_ERROR (result))
{
JERRY_ASSERT (jcontext_has_pending_exception ());
ecma_value_t *stack_bottom_p = VM_GET_REGISTERS (frame_ctx_p) + register_end + frame_ctx_p->context_depth;
while (stack_top_p > stack_bottom_p)
@ -3862,7 +3861,7 @@ error:
therefore an evaluation error, or user-created error throw would overwrite it. */
ecma_value_t current_error_value = JERRY_CONTEXT (error_value);
if (jerry_debugger_send_exception_string ())
if (jerry_debugger_send_exception_string (current_error_value))
{
jerry_debugger_breakpoint_hit (JERRY_DEBUGGER_EXCEPTION_HIT);
@ -3907,7 +3906,7 @@ error:
continue;
}
}
else if (JERRY_CONTEXT (status_flags) & ECMA_STATUS_EXCEPTION)
else if (jcontext_has_pending_exception () && !jcontext_has_pending_abort ())
{
if (vm_stack_find_finally (frame_ctx_p,
&stack_top_p,
@ -3921,19 +3920,19 @@ error:
JERRY_DEBUGGER_CLEAR_FLAGS (JERRY_DEBUGGER_VM_EXCEPTION_THROWN);
#endif /* ENABLED (JERRY_DEBUGGER) */
JERRY_CONTEXT (status_flags) &= (uint32_t) ~ECMA_STATUS_EXCEPTION;
result = jcontext_take_exception ();
byte_code_p = frame_ctx_p->byte_code_p;
if (VM_GET_CONTEXT_TYPE (stack_top_p[-1]) == VM_CONTEXT_FINALLY_THROW)
{
stack_top_p[-2] = JERRY_CONTEXT (error_value);
stack_top_p[-2] = result;
continue;
}
JERRY_ASSERT (VM_GET_CONTEXT_TYPE (stack_top_p[-1]) == VM_CONTEXT_CATCH);
*stack_top_p++ = JERRY_CONTEXT (error_value);
*stack_top_p++ = result;
continue;
}
}

View File

@ -0,0 +1,16 @@
// Copyright JS Foundation and other contributors, http://js.foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
assert (typeof RegExp('{}') === "object");
let {t: []} = {t: []};

View File

@ -51,7 +51,7 @@ main (void)
result = ecma_op_to_integer (error, &num);
ecma_free_value (JERRY_CONTEXT (error_value));
jcontext_release_exception ();
TEST_ASSERT (ECMA_IS_VALUE_ERROR (result));

View File

@ -51,7 +51,7 @@ main (void)
result = ecma_op_to_length (error_throw, &num);
ecma_free_value (JERRY_CONTEXT (error_value));
jcontext_release_exception ();
TEST_ASSERT (ECMA_IS_VALUE_ERROR (result));