mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
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:
parent
7c0b1ca88a
commit
9b33fc8cbd
@ -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);
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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) */
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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)
|
||||
|
||||
/**
|
||||
|
||||
@ -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);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
16
tests/jerry/es2015/regression-test-issue-3422.js
Normal file
16
tests/jerry/es2015/regression-test-issue-3422.js
Normal 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: []};
|
||||
@ -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));
|
||||
|
||||
|
||||
@ -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));
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user