Remove ECMA_TRY_CATCH macro (#3829)

also refactored the touched methods a little bit

JerryScript-DCO-1.0-Signed-off-by: Adam Szilagyi aszilagy@inf.u-szeged.hu
This commit is contained in:
Szilagyi Adam 2020-07-03 15:06:49 +02:00 committed by GitHub
parent 19ecd8717f
commit 392ee71712
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 510 additions and 520 deletions

View File

@ -22,7 +22,6 @@
#include "ecma-helpers.h"
#include "ecma-objects.h"
#include "ecma-string-object.h"
#include "ecma-try-catch-macro.h"
#include "jrt.h"
#if ENABLED (JERRY_BUILTIN_BOOLEAN)
@ -56,26 +55,21 @@
static ecma_value_t
ecma_builtin_boolean_prototype_object_to_string (ecma_value_t this_arg) /**< this argument */
{
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
ecma_value_t value_of_ret = ecma_builtin_boolean_prototype_object_value_of (this_arg);
ECMA_TRY_CATCH (value_of_ret,
ecma_builtin_boolean_prototype_object_value_of (this_arg),
ret_value);
if (ECMA_IS_VALUE_ERROR (value_of_ret))
{
return value_of_ret;
}
if (ecma_is_value_true (value_of_ret))
{
ret_value = ecma_make_magic_string_value (LIT_MAGIC_STRING_TRUE);
}
else
{
JERRY_ASSERT (ecma_is_value_boolean (value_of_ret));
ret_value = ecma_make_magic_string_value (LIT_MAGIC_STRING_FALSE);
return ecma_make_magic_string_value (LIT_MAGIC_STRING_TRUE);
}
ECMA_FINALIZE (value_of_ret);
JERRY_ASSERT (ecma_is_value_boolean (value_of_ret));
return ret_value;
return ecma_make_magic_string_value (LIT_MAGIC_STRING_FALSE);
} /* ecma_builtin_boolean_prototype_object_to_string */
/**

View File

@ -19,6 +19,7 @@
#include "ecma-builtin-helpers.h"
#include "ecma-exceptions.h"
#include "ecma-function-object.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-objects.h"
@ -131,38 +132,46 @@ enum
static ecma_value_t
ecma_builtin_date_prototype_to_json (ecma_value_t this_arg) /**< this argument */
{
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
/* 1. */
ECMA_TRY_CATCH (obj,
ecma_op_to_object (this_arg),
ret_value);
ecma_value_t obj = ecma_op_to_object (this_arg);
if (ECMA_IS_VALUE_ERROR (obj))
{
return obj;
}
/* 2. */
ECMA_TRY_CATCH (tv,
ecma_op_to_primitive (obj, ECMA_PREFERRED_TYPE_NUMBER),
ret_value);
ecma_value_t tv = ecma_op_to_primitive (obj, ECMA_PREFERRED_TYPE_NUMBER);
if (ECMA_IS_VALUE_ERROR (tv))
{
ecma_free_value (obj);
return tv;
}
/* 3. */
if (ecma_is_value_number (tv))
{
ecma_number_t num_value = ecma_get_number_from_value (tv);
ecma_free_value (tv);
if (ecma_number_is_nan (num_value) || ecma_number_is_infinity (num_value))
{
ret_value = ECMA_VALUE_NULL;
ecma_free_value (obj);
return ECMA_VALUE_NULL;
}
}
if (ecma_is_value_empty (ret_value))
ecma_value_t ret_value = ECMA_VALUE_ERROR;
ecma_object_t *value_obj_p = ecma_get_object_from_value (obj);
/* 4. */
ecma_value_t to_iso = ecma_op_object_get_by_magic_id (value_obj_p, LIT_MAGIC_STRING_TO_ISO_STRING_UL);
if (!ECMA_IS_VALUE_ERROR (to_iso))
{
ecma_object_t *value_obj_p = ecma_get_object_from_value (obj);
/* 4. */
ECMA_TRY_CATCH (to_iso,
ecma_op_object_get_by_magic_id (value_obj_p, LIT_MAGIC_STRING_TO_ISO_STRING_UL),
ret_value);
/* 5. */
if (!ecma_op_is_callable (to_iso))
{
@ -175,11 +184,10 @@ ecma_builtin_date_prototype_to_json (ecma_value_t this_arg) /**< this argument *
ret_value = ecma_op_function_call (to_iso_obj_p, this_arg, NULL, 0);
}
ECMA_FINALIZE (to_iso);
ecma_free_value (to_iso);
}
ECMA_FINALIZE (tv);
ECMA_FINALIZE (obj);
ecma_deref_object (value_obj_p);
return ret_value;
} /* ecma_builtin_date_prototype_to_json */

View File

@ -24,7 +24,6 @@
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-try-catch-macro.h"
#include "lit-char-helpers.h"
#if ENABLED (JERRY_BUILTIN_DATE)
@ -198,91 +197,52 @@ static ecma_value_t
ecma_date_construct_helper (const ecma_value_t *args, /**< arguments passed to the Date constructor */
ecma_length_t args_len) /**< number of arguments */
{
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
ecma_number_t date_nums[7] =
{
ECMA_NUMBER_ZERO, /* year */
ECMA_NUMBER_ZERO, /* month */
ECMA_NUMBER_ONE, /* date */
ECMA_NUMBER_ZERO, /* hours */
ECMA_NUMBER_ZERO, /* minutes */
ECMA_NUMBER_ZERO, /* seconds */
ECMA_NUMBER_ZERO /* miliseconds */
};
args_len = JERRY_MIN (args_len, sizeof (date_nums) / sizeof (date_nums[0]));
/* 1-7. */
for (uint32_t i = 0; i < args_len; i++)
{
ecma_value_t status = ecma_get_number (args[i], date_nums + i);
if (ECMA_IS_VALUE_ERROR (status))
{
return status;
}
}
ecma_number_t prim_value = ecma_number_make_nan ();
ECMA_TRY_CATCH (year_value, ecma_op_to_number (args[0]), ret_value);
ECMA_TRY_CATCH (month_value, ecma_op_to_number (args[1]), ret_value);
ecma_number_t year = ecma_get_number_from_value (year_value);
ecma_number_t month = ecma_get_number_from_value (month_value);
ecma_number_t date = ECMA_NUMBER_ONE;
ecma_number_t hours = ECMA_NUMBER_ZERO;
ecma_number_t minutes = ECMA_NUMBER_ZERO;
ecma_number_t seconds = ECMA_NUMBER_ZERO;
ecma_number_t milliseconds = ECMA_NUMBER_ZERO;
/* 3. */
if (args_len >= 3 && ecma_is_value_empty (ret_value))
if (!ecma_number_is_nan (date_nums[0]))
{
ECMA_TRY_CATCH (date_value, ecma_op_to_number (args[2]), ret_value);
date = ecma_get_number_from_value (date_value);
ECMA_FINALIZE (date_value);
}
/* 8. */
ecma_number_t y = ecma_number_trunc (date_nums[0]);
/* 4. */
if (args_len >= 4 && ecma_is_value_empty (ret_value))
{
ECMA_TRY_CATCH (hours_value, ecma_op_to_number (args[3]), ret_value);
hours = ecma_get_number_from_value (hours_value);
ECMA_FINALIZE (hours_value);
}
/* 5. */
if (args_len >= 5 && ecma_is_value_empty (ret_value))
{
ECMA_TRY_CATCH (minutes_value, ecma_op_to_number (args[4]), ret_value);
minutes = ecma_get_number_from_value (minutes_value);
ECMA_FINALIZE (minutes_value);
}
/* 6. */
if (args_len >= 6 && ecma_is_value_empty (ret_value))
{
ECMA_TRY_CATCH (seconds_value, ecma_op_to_number (args[5]), ret_value);
seconds = ecma_get_number_from_value (seconds_value);
ECMA_FINALIZE (seconds_value);
}
/* 7. */
if (args_len >= 7 && ecma_is_value_empty (ret_value))
{
ECMA_TRY_CATCH (milliseconds_value, ecma_op_to_number (args[6]), ret_value);
milliseconds = ecma_get_number_from_value (milliseconds_value);
ECMA_FINALIZE (milliseconds_value);
}
if (ecma_is_value_empty (ret_value))
{
if (!ecma_number_is_nan (year))
if (y >= 0 && y <= 99)
{
/* 8. */
ecma_number_t y = ecma_number_trunc (year);
if (y >= 0 && y <= 99)
{
year = 1900 + y;
}
date_nums[0] = 1900 + y;
}
prim_value = ecma_date_make_date (ecma_date_make_day (year,
month,
date),
ecma_date_make_time (hours,
minutes,
seconds,
milliseconds));
}
ECMA_FINALIZE (month_value);
ECMA_FINALIZE (year_value);
prim_value = ecma_date_make_date (ecma_date_make_day (date_nums[0],
date_nums[1],
date_nums[2]),
ecma_date_make_time (date_nums[3],
date_nums[4],
date_nums[5],
date_nums[6]));
if (ecma_is_value_empty (ret_value))
{
ret_value = ecma_make_number_value (prim_value);
}
return ret_value;
return ecma_make_number_value (prim_value);
} /* ecma_date_construct_helper */
/**
@ -656,7 +616,6 @@ ecma_builtin_date_utc (ecma_value_t this_arg, /**< this argument */
ecma_length_t args_number) /**< number of arguments */
{
JERRY_UNUSED (this_arg);
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
if (args_number < 2)
{
@ -667,16 +626,31 @@ ecma_builtin_date_utc (ecma_value_t this_arg, /**< this argument */
return ecma_make_number_value (ecma_number_make_nan ());
}
ECMA_TRY_CATCH (time_value, ecma_date_construct_helper (args, args_number), ret_value);
ecma_value_t time_value = ecma_date_construct_helper (args, args_number);
if (ECMA_IS_VALUE_ERROR (time_value))
{
return time_value;
}
ecma_number_t time = ecma_get_number_from_value (time_value);
ret_value = ecma_make_number_value (ecma_date_time_clip (time));
ECMA_FINALIZE (time_value);
ecma_free_value (time_value);
return ret_value;
return ecma_make_number_value (ecma_date_time_clip (time));
} /* ecma_builtin_date_utc */
/**
* Helper method to get the current time
*
* @return ecma_number_t
*/
static ecma_number_t
ecma_builtin_date_now_helper (void)
{
return floor (DOUBLE_TO_ECMA_NUMBER_T (jerry_port_get_current_time ()));
} /* ecma_builtin_date_now_helper */
/**
* The Date object's 'now' routine
*
@ -690,7 +664,7 @@ static ecma_value_t
ecma_builtin_date_now (ecma_value_t this_arg) /**< this argument */
{
JERRY_UNUSED (this_arg);
return ecma_make_number_value (floor (DOUBLE_TO_ECMA_NUMBER_T (jerry_port_get_current_time ())));
return ecma_make_number_value (ecma_builtin_date_now_helper ());
} /* ecma_builtin_date_now */
/**
@ -707,17 +681,10 @@ ecma_builtin_date_dispatch_call (const ecma_value_t *arguments_list_p, /**< argu
{
JERRY_UNUSED (arguments_list_p);
JERRY_UNUSED (arguments_list_len);
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
ECMA_TRY_CATCH (now_val,
ecma_builtin_date_now (ECMA_VALUE_UNDEFINED),
ret_value);
ecma_number_t now_val_num = ecma_builtin_date_now_helper ();
ret_value = ecma_date_value_to_string (ecma_get_number_from_value (now_val));
ECMA_FINALIZE (now_val);
return ret_value;
return ecma_date_value_to_string (now_val_num);
} /* ecma_builtin_date_dispatch_call */
/**
@ -732,104 +699,107 @@ ecma_value_t
ecma_builtin_date_dispatch_construct (const ecma_value_t *arguments_list_p, /**< arguments list */
ecma_length_t arguments_list_len) /**< number of arguments */
{
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
ecma_number_t prim_value_num = ECMA_NUMBER_ZERO;
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_DATE_PROTOTYPE);
#if ENABLED (JERRY_ESNEXT)
if (JERRY_CONTEXT (current_new_target))
JERRY_ASSERT (JERRY_CONTEXT (current_new_target));
ecma_object_t *prototype_obj_p = ecma_op_get_prototype_from_constructor (JERRY_CONTEXT (current_new_target),
ECMA_BUILTIN_ID_DATE_PROTOTYPE);
if (JERRY_UNLIKELY (prototype_obj_p == NULL))
{
prototype_obj_p = ecma_op_get_prototype_from_constructor (JERRY_CONTEXT (current_new_target),
ECMA_BUILTIN_ID_DATE_PROTOTYPE);
if (JERRY_UNLIKELY (prototype_obj_p == NULL))
{
return ECMA_VALUE_ERROR;
}
return ECMA_VALUE_ERROR;
}
#endif /* !(ENABLED (JERRY_ESNEXT) */
#else /* !ENABLED (JERRY_ESNEXT) */
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_DATE_PROTOTYPE);
#endif /* (ENABLED (JERRY_ESNEXT) */
ecma_object_t *obj_p = ecma_create_object (prototype_obj_p,
sizeof (ecma_extended_object_t),
ECMA_OBJECT_TYPE_CLASS);
#if ENABLED (JERRY_ESNEXT)
ecma_deref_object (prototype_obj_p);
#endif /* ENABLED (JERRY_ESNEXT) */
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p;
ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_UNDEFINED;
ecma_number_t prim_value_num = ECMA_NUMBER_ZERO;
if (arguments_list_len == 0)
{
ECMA_TRY_CATCH (parse_res_value,
ecma_builtin_date_now (ecma_make_object_value (obj_p)),
ret_value);
prim_value_num = ecma_get_number_from_value (parse_res_value);
ECMA_FINALIZE (parse_res_value)
prim_value_num = ecma_builtin_date_now_helper ();
}
else if (arguments_list_len == 1)
{
ECMA_TRY_CATCH (prim_comp_value,
ecma_op_to_primitive (arguments_list_p[0], ECMA_PREFERRED_TYPE_NUMBER),
ret_value);
ecma_value_t prim_comp_value = ecma_op_to_primitive (arguments_list_p[0], ECMA_PREFERRED_TYPE_NUMBER);
if (ECMA_IS_VALUE_ERROR (prim_comp_value))
{
ecma_deref_object (obj_p);
return prim_comp_value;
}
if (ecma_is_value_string (prim_comp_value))
{
ECMA_TRY_CATCH (parse_res_value,
ecma_builtin_date_parse (ecma_make_object_value (obj_p), prim_comp_value),
ret_value);
ecma_value_t parse_res_value = ecma_builtin_date_parse (ecma_make_object_value (obj_p), prim_comp_value);
if (ECMA_IS_VALUE_ERROR (parse_res_value))
{
ecma_deref_object (obj_p);
ecma_free_value (prim_comp_value);
return parse_res_value;
}
prim_value_num = ecma_get_number_from_value (parse_res_value);
ECMA_FINALIZE (parse_res_value);
ecma_free_value (parse_res_value);
}
else
{
ECMA_TRY_CATCH (prim_value, ecma_op_to_number (arguments_list_p[0]), ret_value);
ecma_value_t prim_value = ecma_op_to_number (arguments_list_p[0]);
if (ECMA_IS_VALUE_ERROR (prim_value))
{
ecma_deref_object (obj_p);
ecma_free_value (prim_comp_value);
return prim_value;
}
prim_value_num = ecma_date_time_clip (ecma_get_number_from_value (prim_value));
ECMA_FINALIZE (prim_value);
ecma_free_value (prim_value);
}
ECMA_FINALIZE (prim_comp_value);
ecma_free_value (prim_comp_value);
}
else
{
ECMA_TRY_CATCH (time_value,
ecma_date_construct_helper (arguments_list_p, arguments_list_len),
ret_value);
ecma_value_t time_value = ecma_date_construct_helper (arguments_list_p, arguments_list_len);
if (ECMA_IS_VALUE_ERROR (time_value))
{
ecma_deref_object (obj_p);
return time_value;
}
ecma_number_t time = ecma_get_number_from_value (time_value);
prim_value_num = ecma_date_time_clip (ecma_date_utc (time));
ECMA_FINALIZE (time_value);
ecma_free_value (time_value);
}
if (ecma_is_value_empty (ret_value))
if (!ecma_number_is_nan (prim_value_num) && ecma_number_is_infinity (prim_value_num))
{
if (!ecma_number_is_nan (prim_value_num) && ecma_number_is_infinity (prim_value_num))
{
prim_value_num = ecma_number_make_nan ();
}
ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_DATE_UL;
ecma_number_t *date_num_p = ecma_alloc_number ();
*date_num_p = prim_value_num;
ECMA_SET_INTERNAL_VALUE_POINTER (ext_object_p->u.class_prop.u.value, date_num_p);
ret_value = ecma_make_object_value (obj_p);
prim_value_num = ecma_number_make_nan ();
}
else
{
JERRY_ASSERT (ECMA_IS_VALUE_ERROR (ret_value));
ecma_deref_object (obj_p);
}
#if ENABLED (JERRY_ESNEXT)
if (JERRY_CONTEXT (current_new_target))
{
ecma_deref_object (prototype_obj_p);
}
#endif /* !(ENABLED (JERRY_ESNEXT) */
return ret_value;
ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_DATE_UL;
ecma_number_t *date_num_p = ecma_alloc_number ();
*date_num_p = prim_value_num;
ECMA_SET_INTERNAL_VALUE_POINTER (ext_object_p->u.class_prop.u.value, date_num_p);
return ecma_make_object_value (obj_p);
} /* ecma_builtin_date_dispatch_construct */
/**

View File

@ -15,7 +15,6 @@
#include "ecma-builtin-helpers.h"
#include "ecma-globals.h"
#include "ecma-try-catch-macro.h"
/**
* Function used to reconstruct the ordered binary tree.
@ -31,20 +30,24 @@ ecma_builtin_helper_array_to_heap (ecma_value_t *array_p, /**< heap data array *
ecma_value_t compare_func, /**< compare function */
const ecma_builtin_helper_sort_compare_fn_t sort_cb) /**< sorting cb */
{
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
/* Left child of the current index. */
uint32_t child = index * 2 + 1;
ecma_value_t swap = array_p[index];
bool should_break = false;
while (child <= right && ecma_is_value_empty (ret_value) && !should_break)
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
while (child <= right)
{
if (child < right)
{
/* Compare the two child nodes. */
ECMA_TRY_CATCH (child_compare_value, sort_cb (array_p[child], array_p[child + 1], compare_func),
ret_value);
ecma_value_t child_compare_value = sort_cb (array_p[child], array_p[child + 1], compare_func);
if (ECMA_IS_VALUE_ERROR (child_compare_value))
{
ret_value = ECMA_VALUE_ERROR;
break;
}
JERRY_ASSERT (ecma_is_value_number (child_compare_value));
@ -54,35 +57,38 @@ ecma_builtin_helper_array_to_heap (ecma_value_t *array_p, /**< heap data array *
child++;
}
ECMA_FINALIZE (child_compare_value);
ecma_free_value (child_compare_value);
}
if (ecma_is_value_empty (ret_value))
JERRY_ASSERT (child <= right);
/* Compare current child node with the swap (tree top). */
ecma_value_t swap_compare_value = sort_cb (array_p[child], swap, compare_func);
if (ECMA_IS_VALUE_ERROR (swap_compare_value))
{
JERRY_ASSERT (child <= right);
/* Compare current child node with the swap (tree top). */
ECMA_TRY_CATCH (swap_compare_value, sort_cb (array_p[child], swap, compare_func), ret_value);
JERRY_ASSERT (ecma_is_value_number (swap_compare_value));
if (ecma_get_number_from_value (swap_compare_value) <= ECMA_NUMBER_ZERO)
{
/* Break from loop if current child is less than swap (tree top) */
should_break = true;
}
else
{
/* We have to move 'swap' lower in the tree, so shift current child up in the hierarchy. */
uint32_t parent = (child - 1) / 2;
JERRY_ASSERT (parent <= right);
array_p[parent] = array_p[child];
/* Update child to be the left child of the current node. */
child = child * 2 + 1;
}
ECMA_FINALIZE (swap_compare_value);
ret_value = ECMA_VALUE_ERROR;
break;
}
JERRY_ASSERT (ecma_is_value_number (swap_compare_value));
if (ecma_get_number_from_value (swap_compare_value) <= ECMA_NUMBER_ZERO)
{
/* Break from loop if current child is less than swap (tree top) */
ecma_free_value (swap_compare_value);
break;
}
/* We have to move 'swap' lower in the tree, so shift current child up in the hierarchy. */
uint32_t parent = (child - 1) / 2;
JERRY_ASSERT (parent <= right);
array_p[parent] = array_p[child];
/* Update child to be the left child of the current node. */
child = child * 2 + 1;
ecma_free_value (swap_compare_value);
}
/*
@ -93,11 +99,6 @@ ecma_builtin_helper_array_to_heap (ecma_value_t *array_p, /**< heap data array *
JERRY_ASSERT (parent <= right);
array_p[parent] = swap;
if (ecma_is_value_empty (ret_value))
{
ret_value = ECMA_VALUE_UNDEFINED;
}
return ret_value;
} /* ecma_builtin_helper_array_to_heap */
@ -113,19 +114,19 @@ ecma_builtin_helper_array_heap_sort_helper (ecma_value_t *array_p, /**< array to
ecma_value_t compare_func, /**< compare function */
const ecma_builtin_helper_sort_compare_fn_t sort_cb) /**< sorting cb */
{
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
/* First, construct the ordered binary tree from the array. */
for (uint32_t i = (right / 2) + 1; i > 0 && ecma_is_value_empty (ret_value); i--)
for (uint32_t i = (right / 2) + 1; i > 0; i--)
{
ECMA_TRY_CATCH (value,
ecma_builtin_helper_array_to_heap (array_p, i - 1, right, compare_func, sort_cb),
ret_value);
ECMA_FINALIZE (value);
ecma_value_t value = ecma_builtin_helper_array_to_heap (array_p, i - 1, right, compare_func, sort_cb);
if (ECMA_IS_VALUE_ERROR (value))
{
return value;
}
}
/* Sorting elements. */
for (uint32_t i = right; i > 0 && ecma_is_value_empty (ret_value); i--)
for (uint32_t i = right; i > 0; i--)
{
/*
* The top element will always contain the largest value.
@ -136,11 +137,13 @@ ecma_builtin_helper_array_heap_sort_helper (ecma_value_t *array_p, /**< array to
array_p[i] = swap;
/* Rebuild binary tree from the remaining elements. */
ECMA_TRY_CATCH (value,
ecma_builtin_helper_array_to_heap (array_p, 0, i - 1, compare_func, sort_cb),
ret_value);
ECMA_FINALIZE (value);
ecma_value_t value = ecma_builtin_helper_array_to_heap (array_p, 0, i - 1, compare_func, sort_cb);
if (ECMA_IS_VALUE_ERROR (value))
{
return value;
}
}
return ret_value;
return ECMA_VALUE_EMPTY;
} /* ecma_builtin_helper_array_heap_sort_helper */

View File

@ -29,7 +29,6 @@
#include "ecma-iterator-object.h"
#include "ecma-number-object.h"
#include "ecma-objects.h"
#include "ecma-try-catch-macro.h"
#include "ecma-typedarray-object.h"
#include "jcontext.h"
#include "jmem.h"
@ -931,11 +930,10 @@ ecma_builtin_typedarray_prototype_set (ecma_value_t this_arg, /**< this argument
/* 6.~ 8. targetOffset */
ecma_number_t target_offset_num;
ecma_value_t ret_val = ecma_op_to_integer (offset_val, &target_offset_num);
if (ECMA_IS_VALUE_ERROR (ret_val))
if (ECMA_IS_VALUE_ERROR (ecma_op_to_integer (offset_val, &target_offset_num)))
{
return ret_val;
return ECMA_VALUE_ERROR;
}
if (target_offset_num <= -1.0 || target_offset_num >= (ecma_number_t) UINT32_MAX + 0.5)
@ -955,25 +953,29 @@ ecma_builtin_typedarray_prototype_set (ecma_value_t this_arg, /**< this argument
ecma_typedarray_info_t target_info = ecma_typedarray_get_info (typedarray_p);
/* 16.~ 17. */
ECMA_TRY_CATCH (source_obj, ecma_op_to_object (arr_val), ret_val);
ecma_value_t source_obj = ecma_op_to_object (arr_val);
if (ECMA_IS_VALUE_ERROR (source_obj))
{
return source_obj;
}
/* 18.~ 19. */
ecma_object_t *source_obj_p = ecma_get_object_from_value (source_obj);
ECMA_TRY_CATCH (source_length,
ecma_op_object_get_by_magic_id (source_obj_p, LIT_MAGIC_STRING_LENGTH),
ret_val);
uint32_t source_length_uint32;
if (ECMA_IS_VALUE_ERROR (ecma_op_to_length (source_length, &source_length_uint32)))
if (ECMA_IS_VALUE_ERROR (ecma_op_object_get_length (source_obj_p, &source_length_uint32)))
{
ecma_deref_object (source_obj_p);
return ECMA_VALUE_ERROR;
}
/* 20. if srcLength + targetOffset > targetLength, throw a RangeError */
if ((int64_t) source_length_uint32 + target_offset_uint32 > target_info.length)
{
ret_val = ecma_raise_range_error (ECMA_ERR_MSG ("Invalid range of index"));
ecma_deref_object (source_obj_p);
return ecma_raise_range_error (ECMA_ERR_MSG ("Invalid range of index"));
}
/* 21.~ 25. */
@ -982,31 +984,36 @@ ecma_builtin_typedarray_prototype_set (ecma_value_t this_arg, /**< this argument
ecma_typedarray_setter_fn_t target_typedarray_setter_cb = ecma_get_typedarray_setter_fn (target_info.id);
while (k < source_length_uint32 && ecma_is_value_empty (ret_val))
while (k < source_length_uint32)
{
ECMA_TRY_CATCH (elem,
ecma_op_object_get_by_uint32_index (source_obj_p, k),
ret_val);
ecma_value_t elem = ecma_op_object_get_by_uint32_index (source_obj_p, k);
ECMA_OP_TO_NUMBER_TRY_CATCH (elem_num, elem, ret_val);
if (ECMA_IS_VALUE_ERROR (elem))
{
ecma_deref_object (source_obj_p);
return elem;
}
ecma_number_t elem_num;
if (ECMA_IS_VALUE_ERROR (ecma_get_number (elem, &elem_num)))
{
ecma_free_value (elem);
ecma_deref_object (source_obj_p);
return ECMA_VALUE_ERROR;
}
target_typedarray_setter_cb (target_info.buffer_p + target_byte_index, elem_num);
ECMA_OP_TO_NUMBER_FINALIZE (elem_num);
ECMA_FINALIZE (elem);
ecma_free_value (elem);
k++;
target_byte_index += target_info.element_size;
}
ECMA_FINALIZE (source_length);
ECMA_FINALIZE (source_obj);
ecma_deref_object (source_obj_p);
if (ecma_is_value_empty (ret_val))
{
ret_val = ECMA_VALUE_UNDEFINED;
}
return ret_val;
return ECMA_VALUE_UNDEFINED;
} /* ecma_builtin_typedarray_prototype_set */
/**
@ -1391,11 +1398,10 @@ ecma_builtin_typedarray_prototype_sort_compare_helper (ecma_value_t lhs, /**< le
ecma_value_t rhs, /**< right value */
ecma_value_t compare_func) /**< compare function */
{
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
ecma_number_t result = ECMA_NUMBER_ZERO;
if (ecma_is_value_undefined (compare_func))
{
ecma_number_t result = ECMA_NUMBER_ZERO;
/* Default comparison when no comparefn is passed. */
double lhs_value = (double) ecma_get_number_from_value (lhs);
double rhs_value = (double) ecma_get_number_from_value (rhs);
@ -1435,38 +1441,33 @@ ecma_builtin_typedarray_prototype_sort_compare_helper (ecma_value_t lhs, /**< le
ecma_value_t compare_args[] = { lhs, rhs };
ECMA_TRY_CATCH (call_value,
ecma_op_function_call (comparefn_obj_p,
ECMA_VALUE_UNDEFINED,
compare_args,
2),
ret_value);
ecma_value_t call_value = ecma_op_function_call (comparefn_obj_p,
ECMA_VALUE_UNDEFINED,
compare_args,
2);
if (!ecma_is_value_number (call_value))
if (ECMA_IS_VALUE_ERROR (call_value) || ecma_is_value_number (call_value))
{
ECMA_OP_TO_NUMBER_TRY_CATCH (ret_num, call_value, ret_value);
result = ret_num;
ECMA_OP_TO_NUMBER_FINALIZE (ret_num);
// If the coerced value can't be represented as a Number, compare them as equals.
if (ecma_number_is_nan (result))
{
result = ECMA_NUMBER_ZERO;
}
}
else
{
result = ecma_get_number_from_value (call_value);
return call_value;
}
ECMA_FINALIZE (call_value);
ecma_number_t ret_num;
ecma_value_t number_result = ecma_get_number (call_value, &ret_num);
if (ecma_is_value_empty (ret_value))
ecma_free_value (call_value);
if (ECMA_IS_VALUE_ERROR (number_result))
{
ret_value = ecma_make_number_value (result);
return number_result;
}
return ret_value;
// If the coerced value can't be represented as a Number, compare them as equals.
if (ecma_number_is_nan (ret_num))
{
return ecma_make_number_value (ECMA_NUMBER_ZERO);
}
return ecma_make_number_value (ret_num);
} /* ecma_builtin_typedarray_prototype_sort_compare_helper */
/**
@ -1505,8 +1506,6 @@ ecma_builtin_typedarray_prototype_sort (ecma_value_t this_arg, /**< this argumen
return ecma_copy_value (this_arg);
}
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
JMEM_DEFINE_LOCAL_ARRAY (values_buffer, info.length, ecma_value_t);
uint32_t byte_index = 0, buffer_index = 0;
@ -1526,34 +1525,36 @@ ecma_builtin_typedarray_prototype_sort (ecma_value_t this_arg, /**< this argumen
JERRY_ASSERT (buffer_index == info.length);
const ecma_builtin_helper_sort_compare_fn_t sort_cb = &ecma_builtin_typedarray_prototype_sort_compare_helper;
ECMA_TRY_CATCH (sort_value,
ecma_builtin_helper_array_heap_sort_helper (values_buffer,
(uint32_t) (info.length - 1),
compare_func,
sort_cb),
ret_value);
ECMA_FINALIZE (sort_value);
ecma_value_t sort_value = ecma_builtin_helper_array_heap_sort_helper (values_buffer,
(uint32_t) (info.length - 1),
compare_func,
sort_cb);
if (ECMA_IS_VALUE_ERROR (sort_value))
{
return sort_value;
}
JERRY_ASSERT (sort_value == ECMA_VALUE_EMPTY);
ecma_typedarray_setter_fn_t typedarray_setter_cb = ecma_get_typedarray_setter_fn (info.id);
if (ecma_is_value_empty (ret_value))
byte_index = 0;
buffer_index = 0;
limit = info.length * info.element_size;
/* Put sorted values from the native array back into the typedarray buffer. */
while (byte_index < limit)
{
byte_index = 0;
buffer_index = 0;
limit = info.length * info.element_size;
/* Put sorted values from the native array back into the typedarray buffer. */
while (byte_index < limit)
{
JERRY_ASSERT (buffer_index < info.length);
ecma_value_t element_value = values_buffer[buffer_index++];
ecma_number_t element_num = ecma_get_number_from_value (element_value);
typedarray_setter_cb (info.buffer_p + byte_index, element_num);
byte_index += info.element_size;
}
JERRY_ASSERT (buffer_index == info.length);
JERRY_ASSERT (buffer_index < info.length);
ecma_value_t element_value = values_buffer[buffer_index++];
ecma_number_t element_num = ecma_get_number_from_value (element_value);
typedarray_setter_cb (info.buffer_p + byte_index, element_num);
byte_index += info.element_size;
}
JERRY_ASSERT (buffer_index == info.length);
/* Free values that were copied to the local array. */
for (uint32_t index = 0; index < info.length; index++)
{
@ -1562,12 +1563,7 @@ ecma_builtin_typedarray_prototype_sort (ecma_value_t this_arg, /**< this argumen
JMEM_FINALIZE_LOCAL_ARRAY (values_buffer);
if (ecma_is_value_empty (ret_value))
{
ret_value = ecma_copy_value (this_arg);
}
return ret_value;
return ecma_copy_value (this_arg);
} /* ecma_builtin_typedarray_prototype_sort */
/**

View File

@ -32,7 +32,6 @@
#include "ecma-objects-general.h"
#include "ecma-string-object.h"
#include "ecma-symbol-object.h"
#include "ecma-try-catch-macro.h"
#include "jrt-libc-includes.h"
/** \addtogroup ecma ECMA
@ -680,193 +679,183 @@ ecma_op_to_property_descriptor (ecma_value_t obj_value, /**< object value */
if return value is normal
empty completion value */
{
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
/* 1. */
if (!ecma_is_value_object (obj_value))
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Expected an object."));
return ecma_raise_type_error (ECMA_ERR_MSG ("Expected an object."));
}
else
ecma_object_t *obj_p = ecma_get_object_from_value (obj_value);
ecma_value_t ret_value = ECMA_VALUE_ERROR;
/* 3. */
ecma_value_t enumerable_prop_value = ecma_op_object_find (obj_p,
ecma_get_magic_string (LIT_MAGIC_STRING_ENUMERABLE));
if (ECMA_IS_VALUE_ERROR (enumerable_prop_value))
{
ecma_object_t *obj_p = ecma_get_object_from_value (obj_value);
return enumerable_prop_value;
}
/* 2. */
ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor ();
/* 2. */
ecma_property_descriptor_t prop_desc = ecma_make_empty_property_descriptor ();
/* 3. */
ECMA_TRY_CATCH (enumerable_prop_value,
ecma_op_object_find (obj_p, ecma_get_magic_string (LIT_MAGIC_STRING_ENUMERABLE)),
ret_value);
if (ecma_is_value_found (enumerable_prop_value))
{
uint32_t is_enumerable = (ecma_op_to_boolean (enumerable_prop_value) ? ECMA_PROP_IS_ENUMERABLE
: ECMA_PROP_NO_OPTS);
prop_desc.flags |= (uint16_t) (ECMA_PROP_IS_ENUMERABLE_DEFINED | is_enumerable);
}
ECMA_FINALIZE (enumerable_prop_value);
if (!ECMA_IS_VALUE_ERROR (ret_value))
{
JERRY_ASSERT (ecma_is_value_empty (ret_value));
/* 4. */
ECMA_TRY_CATCH (configurable_prop_value,
ecma_op_object_find (obj_p, ecma_get_magic_string (LIT_MAGIC_STRING_CONFIGURABLE)),
ret_value);
if (ecma_is_value_found (configurable_prop_value))
{
uint32_t is_configurable = (ecma_op_to_boolean (configurable_prop_value) ? ECMA_PROP_IS_CONFIGURABLE
: ECMA_PROP_NO_OPTS);
prop_desc.flags |= (uint16_t) (ECMA_PROP_IS_CONFIGURABLE_DEFINED | is_configurable);
}
ECMA_FINALIZE (configurable_prop_value);
}
if (!ECMA_IS_VALUE_ERROR (ret_value))
{
JERRY_ASSERT (ecma_is_value_empty (ret_value));
/* 5. */
ECMA_TRY_CATCH (value_prop_value,
ecma_op_object_find (obj_p, ecma_get_magic_string (LIT_MAGIC_STRING_VALUE)),
ret_value);
if (ecma_is_value_found (value_prop_value))
{
prop_desc.flags |= ECMA_PROP_IS_VALUE_DEFINED;
prop_desc.value = ecma_copy_value (value_prop_value);
}
ECMA_FINALIZE (value_prop_value);
}
if (!ECMA_IS_VALUE_ERROR (ret_value))
{
JERRY_ASSERT (ecma_is_value_empty (ret_value));
/* 6. */
ECMA_TRY_CATCH (writable_prop_value,
ecma_op_object_find (obj_p, ecma_get_magic_string (LIT_MAGIC_STRING_WRITABLE)),
ret_value);
if (ecma_is_value_found (writable_prop_value))
{
uint32_t is_writable = (ecma_op_to_boolean (writable_prop_value) ? ECMA_PROP_IS_WRITABLE
if (ecma_is_value_found (enumerable_prop_value))
{
uint32_t is_enumerable = (ecma_op_to_boolean (enumerable_prop_value) ? ECMA_PROP_IS_ENUMERABLE
: ECMA_PROP_NO_OPTS);
prop_desc.flags |= (uint16_t) (ECMA_PROP_IS_WRITABLE_DEFINED | is_writable);
}
prop_desc.flags |= (uint16_t) (ECMA_PROP_IS_ENUMERABLE_DEFINED | is_enumerable);
ECMA_FINALIZE (writable_prop_value);
ecma_free_value (enumerable_prop_value);
}
/* 4. */
ecma_value_t configurable_prop_value = ecma_op_object_find (obj_p,
ecma_get_magic_string (LIT_MAGIC_STRING_CONFIGURABLE));
if (ECMA_IS_VALUE_ERROR (configurable_prop_value))
{
goto free_desc;
}
if (ecma_is_value_found (configurable_prop_value))
{
uint32_t is_configurable = (ecma_op_to_boolean (configurable_prop_value) ? ECMA_PROP_IS_CONFIGURABLE
: ECMA_PROP_NO_OPTS);
prop_desc.flags |= (uint16_t) (ECMA_PROP_IS_CONFIGURABLE_DEFINED | is_configurable);
ecma_free_value (configurable_prop_value);
}
/* 5. */
ecma_value_t value_prop_value = ecma_op_object_find (obj_p,
ecma_get_magic_string (LIT_MAGIC_STRING_VALUE));
if (ECMA_IS_VALUE_ERROR (value_prop_value))
{
goto free_desc;
}
if (ecma_is_value_found (value_prop_value))
{
prop_desc.flags |= ECMA_PROP_IS_VALUE_DEFINED;
prop_desc.value = ecma_copy_value (value_prop_value);
ecma_free_value (value_prop_value);
}
/* 6. */
ecma_value_t writable_prop_value = ecma_op_object_find (obj_p,
ecma_get_magic_string (LIT_MAGIC_STRING_WRITABLE));
if (ECMA_IS_VALUE_ERROR (writable_prop_value))
{
goto free_desc;
}
if (ecma_is_value_found (writable_prop_value))
{
uint32_t is_writable = (ecma_op_to_boolean (writable_prop_value) ? ECMA_PROP_IS_WRITABLE
: ECMA_PROP_NO_OPTS);
prop_desc.flags |= (uint16_t) (ECMA_PROP_IS_WRITABLE_DEFINED | is_writable);
ecma_free_value (writable_prop_value);
}
/* 7. */
ecma_value_t get_prop_value = ecma_op_object_find (obj_p,
ecma_get_magic_string (LIT_MAGIC_STRING_GET));
if (ECMA_IS_VALUE_ERROR (get_prop_value))
{
goto free_desc;
}
if (ecma_is_value_found (get_prop_value))
{
if (!ecma_op_is_callable (get_prop_value)
&& !ecma_is_value_undefined (get_prop_value))
{
ecma_free_value (get_prop_value);
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Expected a function."));
goto free_desc;
}
if (!ECMA_IS_VALUE_ERROR (ret_value))
prop_desc.flags |= ECMA_PROP_IS_GET_DEFINED;
if (ecma_is_value_undefined (get_prop_value))
{
JERRY_ASSERT (ecma_is_value_empty (ret_value));
/* 7. */
ECMA_TRY_CATCH (get_prop_value,
ecma_op_object_find (obj_p, ecma_get_magic_string (LIT_MAGIC_STRING_GET)),
ret_value);
if (ecma_is_value_found (get_prop_value))
{
if (!ecma_op_is_callable (get_prop_value)
&& !ecma_is_value_undefined (get_prop_value))
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Expected a function."));
}
else
{
prop_desc.flags |= ECMA_PROP_IS_GET_DEFINED;
if (ecma_is_value_undefined (get_prop_value))
{
prop_desc.get_p = NULL;
}
else
{
JERRY_ASSERT (ecma_is_value_object (get_prop_value));
ecma_object_t *get_p = ecma_get_object_from_value (get_prop_value);
ecma_ref_object (get_p);
prop_desc.get_p = get_p;
}
}
}
ECMA_FINALIZE (get_prop_value);
}
if (!ECMA_IS_VALUE_ERROR (ret_value))
{
JERRY_ASSERT (ecma_is_value_empty (ret_value));
/* 8. */
ECMA_TRY_CATCH (set_prop_value,
ecma_op_object_find (obj_p, ecma_get_magic_string (LIT_MAGIC_STRING_SET)),
ret_value);
if (ecma_is_value_found (set_prop_value))
{
if (!ecma_op_is_callable (set_prop_value)
&& !ecma_is_value_undefined (set_prop_value))
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Expected a function."));
}
else
{
prop_desc.flags |= ECMA_PROP_IS_SET_DEFINED;
if (ecma_is_value_undefined (set_prop_value))
{
prop_desc.set_p = NULL;
}
else
{
JERRY_ASSERT (ecma_is_value_object (set_prop_value));
ecma_object_t *set_p = ecma_get_object_from_value (set_prop_value);
ecma_ref_object (set_p);
prop_desc.set_p = set_p;
}
}
}
ECMA_FINALIZE (set_prop_value);
}
if (!ECMA_IS_VALUE_ERROR (ret_value))
{
JERRY_ASSERT (ecma_is_value_empty (ret_value));
/* 9. */
if ((prop_desc.flags & (ECMA_PROP_IS_VALUE_DEFINED | ECMA_PROP_IS_WRITABLE_DEFINED))
&& (prop_desc.flags & (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED)))
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Accessors cannot be writable."));
}
}
if (!ECMA_IS_VALUE_ERROR (ret_value))
{
JERRY_ASSERT (ecma_is_value_empty (ret_value));
prop_desc.get_p = NULL;
}
else
{
ecma_free_property_descriptor (&prop_desc);
JERRY_ASSERT (ecma_is_value_object (get_prop_value));
ecma_object_t *get_p = ecma_get_object_from_value (get_prop_value);
ecma_ref_object (get_p);
prop_desc.get_p = get_p;
}
ecma_free_value (get_prop_value);
}
/* 8. */
ecma_value_t set_prop_value = ecma_op_object_find (obj_p,
ecma_get_magic_string (LIT_MAGIC_STRING_SET));
if (ECMA_IS_VALUE_ERROR (set_prop_value))
{
goto free_desc;
}
if (ecma_is_value_found (set_prop_value))
{
if (!ecma_op_is_callable (set_prop_value)
&& !ecma_is_value_undefined (set_prop_value))
{
ecma_free_value (set_prop_value);
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Expected a function."));
goto free_desc;
}
prop_desc.flags |= ECMA_PROP_IS_SET_DEFINED;
if (ecma_is_value_undefined (set_prop_value))
{
prop_desc.set_p = NULL;
}
else
{
JERRY_ASSERT (ecma_is_value_object (set_prop_value));
ecma_object_t *set_p = ecma_get_object_from_value (set_prop_value);
ecma_ref_object (set_p);
prop_desc.set_p = set_p;
}
ecma_free_value (set_prop_value);
}
/* 9. */
if ((prop_desc.flags & (ECMA_PROP_IS_VALUE_DEFINED | ECMA_PROP_IS_WRITABLE_DEFINED))
&& (prop_desc.flags & (ECMA_PROP_IS_GET_DEFINED | ECMA_PROP_IS_SET_DEFINED)))
{
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Accessors cannot be writable."));
}
else
{
*out_prop_desc_p = prop_desc;
ret_value = ECMA_VALUE_EMPTY;
}
free_desc:
if (ECMA_IS_VALUE_ERROR (ret_value))
{
ecma_free_property_descriptor (&prop_desc);
}
return ret_value;

View File

@ -18,41 +18,6 @@
#include "ecma-helpers.h"
/**
* The macro defines try-block that initializes variable 'var' with 'op'
* and checks for exceptions that might be thrown during initialization.
*
* If no exception was thrown, then code after the try-block is executed.
* Otherwise, throw-completion value is just copied to return_value.
*
* Note:
* Each ECMA_TRY_CATCH should have it's own corresponding ECMA_FINALIZE
* statement with same argument as corresponding ECMA_TRY_CATCH's first argument.
*/
#define ECMA_TRY_CATCH(var, op, return_value) \
JERRY_ASSERT (return_value == ECMA_VALUE_EMPTY); \
ecma_value_t var ## _completion = op; \
if (ECMA_IS_VALUE_ERROR (var ## _completion)) \
{ \
return_value = var ## _completion; \
} \
else \
{ \
ecma_value_t var = var ## _completion; \
JERRY_UNUSED (var);
/**
* The macro marks end of code block that is defined by corresponding
* ECMA_TRY_CATCH and frees variable, initialized by the ECMA_TRY_CATCH.
*
* Note:
* Each ECMA_TRY_CATCH should be followed by ECMA_FINALIZE with same argument
* as corresponding ECMA_TRY_CATCH's first argument.
*/
#define ECMA_FINALIZE(var) \
ecma_free_value (var ## _completion); \
}
/**
* The macro defines try-block that tries to perform ToNumber operation on given value
* and checks for exceptions that might be thrown during the operation.

View File

@ -0,0 +1,65 @@
// 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.
var sym = Symbol();
var date;
try {
date = new Date(sym, 11, 17, 3, 24, 0);
assert(false);
} catch (e) {
assert(e instanceof TypeError);
}
try {
date = new Date(1997, sym, 17, 3, 24, 0);
assert(false);
} catch (e) {
assert(e instanceof TypeError);
}
try {
date = new Date(1997, 11, sym, 3, 24, 0);
assert(false);
} catch (e) {
assert(e instanceof TypeError);
}
try {
date = new Date(1997, 11, 17, sym, 24, 0);
assert(false);
} catch (e) {
assert(e instanceof TypeError);
}
try {
date = new Date(1997, 11, 17, 3, sym, 0);
assert(false);
} catch (e) {
assert(e instanceof TypeError);
}
try {
date = new Date(1997, 11, 17, 3, 24, sym);
assert(false);
} catch (e) {
assert(e instanceof TypeError);
}
try {
date = new Date(1997, 11, 17, 3, 24, 0, sym);
assert(false);
} catch (e) {
assert(e instanceof TypeError);
}