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
+1
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;
/**
+24 -25
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
+1 -1
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);
@@ -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
+2 -4
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 */
@@ -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 */
+2 -4
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,
+1 -1
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);
}
@@ -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);