Introducing ECMA_OP_TO_NUMBER_TRY_CATCH and ECMA_OP_TO_NUMBER_FINALIZE macroses.

- the ECMA_OP_TO_NUMBER_TRY_CATCH macro gets number from given value,
    converting the value to number if it's type is different,
    and catching possible conversion exceptions;

  - using the macroses instead of ecma_op_to_number to reduce allocator invocations
    in several routines with arguments that are likely to be numbers.
This commit is contained in:
Ruben Ayrapetyan
2014-12-15 22:52:07 +03:00
parent 386a530d4d
commit d836dc32af
8 changed files with 187 additions and 188 deletions
+28 -29
View File
@@ -48,42 +48,38 @@ do_number_arithmetic (int_data_t *int_data, /**< interpreter context */
ecma_value_t left_value, /**< left value */
ecma_value_t right_value) /** right value */
{
ecma_completion_value_t ret_value;
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
ECMA_TRY_CATCH (num_left_value, ecma_op_to_number (left_value), ret_value);
ECMA_TRY_CATCH (num_right_value, ecma_op_to_number (right_value), ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (num_left, left_value, ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (num_right, right_value, ret_value);
ecma_number_t *left_p, *right_p, *res_p;
left_p = ecma_get_number_from_completion_value (num_left_value);
right_p = ecma_get_number_from_completion_value (num_right_value);
res_p = int_data->tmp_num_p;
ecma_number_t *res_p = int_data->tmp_num_p;
switch (op)
{
case number_arithmetic_addition:
{
*res_p = ecma_number_add (*left_p, *right_p);
*res_p = ecma_number_add (num_left, num_right);
break;
}
case number_arithmetic_substraction:
{
*res_p = ecma_number_substract (*left_p, *right_p);
*res_p = ecma_number_substract (num_left, num_right);
break;
}
case number_arithmetic_multiplication:
{
*res_p = ecma_number_multiply (*left_p, *right_p);
*res_p = ecma_number_multiply (num_left, num_right);
break;
}
case number_arithmetic_division:
{
*res_p = ecma_number_divide (*left_p, *right_p);
*res_p = ecma_number_divide (num_left, num_right);
break;
}
case number_arithmetic_remainder:
{
*res_p = ecma_op_number_remainder (*left_p, *right_p);
*res_p = ecma_op_number_remainder (num_left, num_right);
break;
}
}
@@ -92,8 +88,8 @@ do_number_arithmetic (int_data_t *int_data, /**< interpreter context */
dst_var_idx,
ecma_make_number_value (res_p));
ECMA_FINALIZE (num_right_value);
ECMA_FINALIZE (num_left_value);
ECMA_OP_TO_NUMBER_FINALIZE (num_right);
ECMA_OP_TO_NUMBER_FINALIZE (num_left);
return ret_value;
} /* do_number_arithmetic */
@@ -319,17 +315,21 @@ opfunc_unary_plus (opcode_t opdata, /**< operation data */
const idx_t dst_var_idx = opdata.data.remainder.dst;
const idx_t var_idx = opdata.data.remainder.var_left;
ecma_completion_value_t ret_value;
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
ECMA_TRY_CATCH (var_value, get_variable_value (int_data, var_idx, false), ret_value);
ECMA_TRY_CATCH (num_value, ecma_op_to_number (ecma_get_completion_value_value (var_value)), ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (num_var_value,
ecma_get_completion_value_value (var_value),
ret_value);
ecma_number_t *var_p = ecma_get_number_from_completion_value (num_value);
ecma_number_t *tmp_p = int_data->tmp_num_p;
*tmp_p = num_var_value;
ret_value = set_variable_value (int_data, int_data->pos,
dst_var_idx,
ecma_make_number_value (var_p));
ecma_make_number_value (tmp_p));
ECMA_FINALIZE (num_value);
ECMA_OP_TO_NUMBER_FINALIZE (num_var_value);
ECMA_FINALIZE (var_value);
int_data->pos++;
@@ -352,22 +352,21 @@ opfunc_unary_minus (opcode_t opdata, /**< operation data */
const idx_t dst_var_idx = opdata.data.remainder.dst;
const idx_t var_idx = opdata.data.remainder.var_left;
ecma_completion_value_t ret_value;
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
ECMA_TRY_CATCH (var_value, get_variable_value (int_data, var_idx, false), ret_value);
ECMA_TRY_CATCH (num_value, ecma_op_to_number (ecma_get_completion_value_value (var_value)), ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (num_var_value,
ecma_get_completion_value_value (var_value),
ret_value);
ecma_number_t *var_p, *res_p;
var_p = ecma_get_number_from_completion_value (num_value);
ecma_number_t *tmp_p = int_data->tmp_num_p;
res_p = int_data->tmp_num_p;
*res_p = ecma_number_negate (*var_p);
*tmp_p = ecma_number_negate (num_var_value);
ret_value = set_variable_value (int_data, int_data->pos,
dst_var_idx,
ecma_make_number_value (res_p));
ecma_make_number_value (tmp_p));
ECMA_FINALIZE (num_value);
ECMA_OP_TO_NUMBER_FINALIZE (num_var_value);
ECMA_FINALIZE (var_value);
int_data->pos++;
+9 -13
View File
@@ -48,22 +48,18 @@ do_number_bitwise_logic (int_data_t *int_data, /**< interpreter context */
ecma_value_t left_value, /**< left value */
ecma_value_t right_value) /** right value */
{
ecma_completion_value_t ret_value;
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
ECMA_TRY_CATCH (num_left_value, ecma_op_to_number (left_value), ret_value);
ECMA_TRY_CATCH (num_right_value, ecma_op_to_number (right_value), ret_value);
ecma_number_t *left_p, *right_p;
left_p = ecma_get_number_from_completion_value (num_left_value);
right_p = ecma_get_number_from_completion_value (num_right_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (num_left, left_value, ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (num_right, right_value, ret_value);
ecma_number_t* res_p = int_data->tmp_num_p;
int32_t left_int32 = ecma_number_to_int32 (*left_p);
// int32_t right_int32 = ecma_number_to_int32 (*right_p);
int32_t left_int32 = ecma_number_to_int32 (num_left);
// int32_t right_int32 = ecma_number_to_int32 (num_right);
uint32_t left_uint32 = ecma_number_to_uint32 (*left_p);
uint32_t right_uint32 = ecma_number_to_uint32 (*right_p);
uint32_t left_uint32 = ecma_number_to_uint32 (num_left);
uint32_t right_uint32 = ecma_number_to_uint32 (num_right);
switch (op)
{
@@ -108,8 +104,8 @@ do_number_bitwise_logic (int_data_t *int_data, /**< interpreter context */
dst_var_idx,
ecma_make_number_value (res_p));
ECMA_FINALIZE (num_right_value);
ECMA_FINALIZE (num_left_value);
ECMA_OP_TO_NUMBER_FINALIZE (num_right);
ECMA_OP_TO_NUMBER_FINALIZE (num_left);
return ret_value;
} /* do_number_bitwise_logic */
+32 -22
View File
@@ -197,17 +197,18 @@ opfunc_pre_incr (opcode_t opdata, /**< operation data */
const idx_t dst_var_idx = opdata.data.pre_incr.dst;
const idx_t incr_var_idx = opdata.data.pre_incr.var_right;
ecma_completion_value_t ret_value;
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
// 1., 2., 3.
ECMA_TRY_CATCH (old_value, get_variable_value (int_data, incr_var_idx, true), ret_value);
ECMA_TRY_CATCH (old_num_value, ecma_op_to_number (ecma_get_completion_value_value (old_value)), ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (old_num,
ecma_get_completion_value_value (old_value),
ret_value);
// 4.
ecma_number_t* new_num_p = int_data->tmp_num_p;
ecma_number_t* old_num_p = ecma_get_number_from_completion_value (old_num_value);
*new_num_p = ecma_number_add (*old_num_p, ECMA_NUMBER_ONE);
*new_num_p = ecma_number_add (old_num, ECMA_NUMBER_ONE);
ecma_value_t new_num_value = ecma_make_number_value (new_num_p);
@@ -222,7 +223,7 @@ opfunc_pre_incr (opcode_t opdata, /**< operation data */
new_num_value);
JERRY_ASSERT (ecma_is_completion_value_empty (reg_assignment_res));
ECMA_FINALIZE (old_num_value);
ECMA_OP_TO_NUMBER_FINALIZE (old_num);
ECMA_FINALIZE (old_value);
int_data->pos++;
@@ -245,17 +246,18 @@ opfunc_pre_decr (opcode_t opdata, /**< operation data */
const idx_t dst_var_idx = opdata.data.pre_decr.dst;
const idx_t decr_var_idx = opdata.data.pre_decr.var_right;
ecma_completion_value_t ret_value;
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
// 1., 2., 3.
ECMA_TRY_CATCH (old_value, get_variable_value (int_data, decr_var_idx, true), ret_value);
ECMA_TRY_CATCH (old_num_value, ecma_op_to_number (ecma_get_completion_value_value (old_value)), ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (old_num,
ecma_get_completion_value_value (old_value),
ret_value);
// 4.
ecma_number_t* new_num_p = int_data->tmp_num_p;
ecma_number_t* old_num_p = ecma_get_number_from_completion_value (old_num_value);
*new_num_p = ecma_number_substract (*old_num_p, ECMA_NUMBER_ONE);
*new_num_p = ecma_number_substract (old_num, ECMA_NUMBER_ONE);
ecma_value_t new_num_value = ecma_make_number_value (new_num_p);
@@ -270,7 +272,7 @@ opfunc_pre_decr (opcode_t opdata, /**< operation data */
new_num_value);
JERRY_ASSERT (ecma_is_completion_value_empty (reg_assignment_res));
ECMA_FINALIZE (old_num_value);
ECMA_OP_TO_NUMBER_FINALIZE (old_num);
ECMA_FINALIZE (old_value);
int_data->pos++;
@@ -293,30 +295,34 @@ opfunc_post_incr (opcode_t opdata, /**< operation data */
const idx_t dst_var_idx = opdata.data.post_incr.dst;
const idx_t incr_var_idx = opdata.data.post_incr.var_right;
ecma_completion_value_t ret_value;
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
// 1., 2., 3.
ECMA_TRY_CATCH (old_value, get_variable_value (int_data, incr_var_idx, true), ret_value);
ECMA_TRY_CATCH (old_num_value, ecma_op_to_number (ecma_get_completion_value_value (old_value)), ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (old_num,
ecma_get_completion_value_value (old_value),
ret_value);
// 4.
ecma_number_t* new_num_p = int_data->tmp_num_p;
ecma_number_t* old_num_p = ecma_get_number_from_completion_value (old_num_value);
*new_num_p = ecma_number_add (*old_num_p, ECMA_NUMBER_ONE);
*new_num_p = ecma_number_add (old_num, ECMA_NUMBER_ONE);
// 5.
ret_value = set_variable_value (int_data, int_data->pos,
incr_var_idx,
ecma_make_number_value (new_num_p));
ecma_number_t *tmp_p = int_data->tmp_num_p;
*tmp_p = old_num;
// assignment of operator result to register variable
ecma_completion_value_t reg_assignment_res = set_variable_value (int_data, int_data->pos,
dst_var_idx,
ecma_get_completion_value_value (old_num_value));
ecma_make_number_value (tmp_p));
JERRY_ASSERT (ecma_is_completion_value_empty (reg_assignment_res));
ECMA_FINALIZE (old_num_value);
ECMA_OP_TO_NUMBER_FINALIZE (old_num);
ECMA_FINALIZE (old_value);
int_data->pos++;
@@ -339,30 +345,34 @@ opfunc_post_decr (opcode_t opdata, /**< operation data */
const idx_t dst_var_idx = opdata.data.post_decr.dst;
const idx_t decr_var_idx = opdata.data.post_decr.var_right;
ecma_completion_value_t ret_value;
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
// 1., 2., 3.
ECMA_TRY_CATCH (old_value, get_variable_value (int_data, decr_var_idx, true), ret_value);
ECMA_TRY_CATCH (old_num_value, ecma_op_to_number (ecma_get_completion_value_value (old_value)), ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (old_num,
ecma_get_completion_value_value (old_value),
ret_value);
// 4.
ecma_number_t* new_num_p = int_data->tmp_num_p;
ecma_number_t* old_num_p = ecma_get_number_from_completion_value (old_num_value);
*new_num_p = ecma_number_substract (*old_num_p, ECMA_NUMBER_ONE);
*new_num_p = ecma_number_substract (old_num, ECMA_NUMBER_ONE);
// 5.
ret_value = set_variable_value (int_data, int_data->pos,
decr_var_idx,
ecma_make_number_value (new_num_p));
ecma_number_t *tmp_p = int_data->tmp_num_p;
*tmp_p = old_num;
// assignment of operator result to register variable
ecma_completion_value_t reg_assignment_res = set_variable_value (int_data, int_data->pos,
dst_var_idx,
ecma_get_completion_value_value (old_num_value));
ecma_make_number_value (tmp_p));
JERRY_ASSERT (ecma_is_completion_value_empty (reg_assignment_res));
ECMA_FINALIZE (old_num_value);
ECMA_OP_TO_NUMBER_FINALIZE (old_num);
ECMA_FINALIZE (old_value);
int_data->pos++;
+9 -13
View File
@@ -101,18 +101,16 @@ static ecma_completion_value_t
ecma_builtin_global_object_is_nan (ecma_value_t this_arg __unused, /**< this argument */
ecma_value_t arg) /**< routine's first argument */
{
ecma_completion_value_t ret_value;
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
ECMA_TRY_CATCH (num_value, ecma_op_to_number (arg), ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, arg, ret_value);
ecma_number_t *num_p = ecma_get_number_from_completion_value (num_value);
bool is_nan = ecma_number_is_nan (*num_p);
bool is_nan = ecma_number_is_nan (arg_num);
ret_value = ecma_make_simple_completion_value (is_nan ? ECMA_SIMPLE_VALUE_TRUE
: ECMA_SIMPLE_VALUE_FALSE);
ECMA_FINALIZE (num_value);
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
return ret_value;
} /* ecma_builtin_global_object_is_nan */
@@ -130,19 +128,17 @@ static ecma_completion_value_t
ecma_builtin_global_object_is_finite (ecma_value_t this_arg __unused, /**< this argument */
ecma_value_t arg) /**< routine's first argument */
{
ecma_completion_value_t ret_value;
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
ECMA_TRY_CATCH (num_value, ecma_op_to_number (arg), ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, arg, ret_value);
ecma_number_t *num_p = ecma_get_number_from_completion_value (num_value);
bool is_finite = !(ecma_number_is_nan (*num_p)
|| ecma_number_is_infinity (*num_p));
bool is_finite = !(ecma_number_is_nan (arg_num)
|| ecma_number_is_infinity (arg_num));
ret_value = ecma_make_simple_completion_value (is_finite ? ECMA_SIMPLE_VALUE_TRUE
: ECMA_SIMPLE_VALUE_FALSE);
ECMA_FINALIZE (num_value);
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
return ret_value;
} /* ecma_builtin_global_object_is_finite */
+30 -72
View File
@@ -58,16 +58,12 @@ static ecma_completion_value_t
ecma_builtin_math_object_abs (ecma_value_t this_arg __unused, /**< 'this' argument */
ecma_value_t arg) /**< routine's argument */
{
ecma_completion_value_t ret_value;
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
ECMA_TRY_CATCH (arg_num_value,
ecma_op_to_number (arg),
ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, arg, ret_value);
ecma_number_t *num_p = ecma_alloc_number ();
const ecma_number_t arg_num = *ecma_get_number_from_completion_value (arg_num_value);
if (ecma_number_is_nan (arg_num))
{
*num_p = arg_num;
@@ -79,7 +75,7 @@ ecma_builtin_math_object_abs (ecma_value_t this_arg __unused, /**< 'this' argume
ret_value = ecma_make_normal_completion_value (ecma_make_number_value (num_p));
ECMA_FINALIZE (arg_num_value);
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
return ret_value;
} /* ecma_builtin_math_object_abs */
@@ -178,16 +174,12 @@ static ecma_completion_value_t
ecma_builtin_math_object_cos (ecma_value_t this_arg __unused, /**< 'this' argument */
ecma_value_t arg) /**< routine's argument */
{
ecma_completion_value_t ret_value;
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
ECMA_TRY_CATCH (arg_num_value,
ecma_op_to_number (arg),
ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, arg, ret_value);
ecma_number_t *num_p = ecma_alloc_number ();
const ecma_number_t arg_num = *ecma_get_number_from_completion_value (arg_num_value);
if (ecma_number_is_nan (arg_num)
|| ecma_number_is_infinity (arg_num))
{
@@ -232,7 +224,7 @@ ecma_builtin_math_object_cos (ecma_value_t this_arg __unused, /**< 'this' argume
ret_value = ecma_make_normal_completion_value (ecma_make_number_value (num_p));
ECMA_FINALIZE (arg_num_value);
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
return ret_value;
} /* ecma_builtin_math_object_cos */
@@ -250,16 +242,12 @@ static ecma_completion_value_t
ecma_builtin_math_object_exp (ecma_value_t this_arg __unused, /**< 'this' argument */
ecma_value_t arg) /**< routine's argument */
{
ecma_completion_value_t ret_value;
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
ECMA_TRY_CATCH (arg_num_value,
ecma_op_to_number (arg),
ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, arg, ret_value);
ecma_number_t *num_p = ecma_alloc_number ();
const ecma_number_t arg_num = *ecma_get_number_from_completion_value (arg_num_value);
if (ecma_number_is_nan (arg_num))
{
*num_p = arg_num;
@@ -286,7 +274,7 @@ ecma_builtin_math_object_exp (ecma_value_t this_arg __unused, /**< 'this' argume
ret_value = ecma_make_normal_completion_value (ecma_make_number_value (num_p));
ECMA_FINALIZE (arg_num_value);
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
return ret_value;
} /* ecma_builtin_math_object_exp */
@@ -320,16 +308,12 @@ static ecma_completion_value_t
ecma_builtin_math_object_log (ecma_value_t this_arg __unused, /**< 'this' argument */
ecma_value_t arg) /**< routine's argument */
{
ecma_completion_value_t ret_value;
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
ECMA_TRY_CATCH (arg_num_value,
ecma_op_to_number (arg),
ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, arg, ret_value);
ecma_number_t *num_p = ecma_alloc_number ();
const ecma_number_t arg_num = *ecma_get_number_from_completion_value (arg_num_value);
if (ecma_number_is_nan (arg_num))
{
*num_p = arg_num;
@@ -353,7 +337,7 @@ ecma_builtin_math_object_log (ecma_value_t this_arg __unused, /**< 'this' argume
ret_value = ecma_make_normal_completion_value (ecma_make_number_value (num_p));
ECMA_FINALIZE (arg_num_value);
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
return ret_value;
} /* ecma_builtin_math_object_log */
@@ -382,14 +366,10 @@ ecma_builtin_math_object_max (ecma_value_t this_arg __unused, /**< 'this' argume
arg_index < args_number;
arg_index++)
{
ECMA_TRY_CATCH (arg_num_value,
ecma_op_to_number (args[arg_index]),
ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, args[arg_index], ret_value);
if (!is_just_convert)
{
ecma_number_t arg_num = *ecma_get_number_from_completion_value (arg_num_value);
if (unlikely (ecma_number_is_nan (arg_num)))
{
ret_num = arg_num;
@@ -431,7 +411,7 @@ ecma_builtin_math_object_max (ecma_value_t this_arg __unused, /**< 'this' argume
}
}
ECMA_FINALIZE (arg_num_value);
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
if (ecma_is_completion_value_throw (ret_value))
{
@@ -473,14 +453,10 @@ ecma_builtin_math_object_min (ecma_value_t this_arg __unused, /**< 'this' argume
arg_index < args_number;
arg_index++)
{
ECMA_TRY_CATCH (arg_num_value,
ecma_op_to_number (args[arg_index]),
ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, args[arg_index], ret_value);
if (!is_just_convert)
{
ecma_number_t arg_num = *ecma_get_number_from_completion_value (arg_num_value);
if (unlikely (ecma_number_is_nan (arg_num)))
{
ret_num = arg_num;
@@ -522,7 +498,7 @@ ecma_builtin_math_object_min (ecma_value_t this_arg __unused, /**< 'this' argume
}
}
ECMA_FINALIZE (arg_num_value);
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
if (ecma_is_completion_value_throw (ret_value))
{
@@ -554,20 +530,13 @@ ecma_builtin_math_object_pow (ecma_value_t this_arg __unused, /**< 'this' argume
ecma_value_t arg1, /**< first routine's argument */
ecma_value_t arg2) /**< second routine's argument */
{
ecma_completion_value_t ret_value;
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
ECMA_TRY_CATCH (arg1_num_value,
ecma_op_to_number (arg1),
ret_value);
ECMA_TRY_CATCH (arg2_num_value,
ecma_op_to_number (arg2),
ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (x, arg1, ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (y, arg2, ret_value);
ecma_number_t *num_p = ecma_alloc_number ();
const ecma_number_t x = *ecma_get_number_from_completion_value (arg1_num_value);
const ecma_number_t y = *ecma_get_number_from_completion_value (arg2_num_value);
if (ecma_number_is_nan (y)
|| (ecma_number_is_nan (x)
&& !ecma_number_is_zero (y)))
@@ -775,8 +744,8 @@ ecma_builtin_math_object_pow (ecma_value_t this_arg __unused, /**< 'this' argume
ret_value = ecma_make_normal_completion_value (ecma_make_number_value (num_p));
ECMA_FINALIZE (arg2_num_value);
ECMA_FINALIZE (arg1_num_value);
ECMA_OP_TO_NUMBER_FINALIZE (y);
ECMA_OP_TO_NUMBER_FINALIZE (x);
return ret_value;
} /* ecma_builtin_math_object_pow */
@@ -835,16 +804,12 @@ static ecma_completion_value_t
ecma_builtin_math_object_round (ecma_value_t this_arg __unused, /**< 'this' argument */
ecma_value_t arg) /**< routine's argument */
{
ecma_completion_value_t ret_value;
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
ECMA_TRY_CATCH (arg_num_value,
ecma_op_to_number (arg),
ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, arg, ret_value);
ecma_number_t *num_p = ecma_alloc_number ();
const ecma_number_t arg_num = *ecma_get_number_from_completion_value (arg_num_value);
if (ecma_number_is_nan (arg_num)
|| ecma_number_is_zero (arg_num)
|| ecma_number_is_infinity (arg_num))
@@ -875,7 +840,7 @@ ecma_builtin_math_object_round (ecma_value_t this_arg __unused, /**< 'this' argu
ret_value = ecma_make_normal_completion_value (ecma_make_number_value (num_p));
ECMA_FINALIZE (arg_num_value);
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
return ret_value;
} /* ecma_builtin_math_object_round */
@@ -893,16 +858,12 @@ static ecma_completion_value_t
ecma_builtin_math_object_sin (ecma_value_t this_arg __unused, /**< 'this' argument */
ecma_value_t arg) /**< routine's argument */
{
ecma_completion_value_t ret_value;
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
ECMA_TRY_CATCH (arg_num_value,
ecma_op_to_number (arg),
ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, arg, ret_value);
ecma_number_t *num_p = ecma_alloc_number ();
const ecma_number_t arg_num = *ecma_get_number_from_completion_value (arg_num_value);
if (ecma_number_is_nan (arg_num)
|| ecma_number_is_infinity (arg_num))
{
@@ -947,7 +908,7 @@ ecma_builtin_math_object_sin (ecma_value_t this_arg __unused, /**< 'this' argume
ret_value = ecma_make_normal_completion_value (ecma_make_number_value (num_p));
ECMA_FINALIZE (arg_num_value);
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
return ret_value;
} /* ecma_builtin_math_object_sin */
@@ -965,13 +926,10 @@ static ecma_completion_value_t
ecma_builtin_math_object_sqrt (ecma_value_t this_arg __unused, /**< 'this' argument */
ecma_value_t arg) /**< routine's argument */
{
ecma_completion_value_t ret_value;
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
ECMA_TRY_CATCH (arg_num_value,
ecma_op_to_number (arg),
ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, arg, ret_value);
const ecma_number_t arg_num = *ecma_get_number_from_completion_value (arg_num_value);
ecma_number_t ret_num;
if (ecma_number_is_nan (arg_num)
@@ -1000,7 +958,7 @@ ecma_builtin_math_object_sqrt (ecma_value_t this_arg __unused, /**< 'this' argum
ret_value = ecma_make_normal_completion_value (ecma_make_number_value (num_p));
ECMA_FINALIZE (arg_num_value);
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
return ret_value;
} /* ecma_builtin_math_object_sqrt */
+3 -8
View File
@@ -70,14 +70,9 @@ ecma_builtin_string_object_from_char_code (ecma_value_t this_arg __unused, /**<
arg_index < args_number;
arg_index++)
{
ECMA_TRY_CATCH (arg_num_value,
ecma_op_to_number (args[arg_index]),
ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, args[arg_index], ret_value);
JERRY_ASSERT (ecma_is_value_number (ecma_get_completion_value_value (arg_num_value)));
ecma_number_t *arg_num_p = ecma_get_number_from_completion_value (arg_num_value);
uint32_t uint32_char_code = ecma_number_to_uint32 (*arg_num_p);
uint32_t uint32_char_code = ecma_number_to_uint32 (arg_num);
uint16_t uint16_char_code = (uint16_t) uint32_char_code;
#if CONFIG_ECMA_CHAR_ENCODING == CONFIG_ECMA_CHAR_ASCII
@@ -93,7 +88,7 @@ ecma_builtin_string_object_from_char_code (ecma_value_t this_arg __unused, /**<
ret_zt_str_p [arg_index] = (ecma_char_t) uint16_char_code;
#endif /* CONFIG_ECMA_CHAR_ENCODING == CONFIG_ECMA_CHAR_UTF16 */
ECMA_FINALIZE (arg_num_value);
ECMA_OP_TO_NUMBER_FINALIZE (arg_num);
if (ecma_is_completion_value_throw (ret_value))
{
+31 -31
View File
@@ -59,7 +59,7 @@ ecma_op_abstract_equality_compare (ecma_value_t x, /**< first operand */
|| (is_x_string && is_y_string)
|| (is_x_object && is_y_object));
ecma_completion_value_t ret_value;
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
if (is_types_equal)
{
@@ -339,7 +339,7 @@ ecma_op_abstract_relational_compare (ecma_value_t x, /**< first operand */
ecma_value_t y, /**< second operand */
bool left_first) /**< 'LeftFirst' flag */
{
ecma_completion_value_t ret_value;
ecma_completion_value_t ret_value = ecma_make_empty_completion_value ();
ecma_value_t first_converted_value = left_first ? x : y;
ecma_value_t second_converted_value = left_first ? y : x;
@@ -365,54 +365,54 @@ ecma_op_abstract_relational_compare (ecma_value_t x, /**< first operand */
// 3.
// a.
ECMA_TRY_CATCH(nx, ecma_op_to_number (ecma_get_completion_value_value (px)), ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (nx,
ecma_get_completion_value_value (px),
ret_value);
ECMA_OP_TO_NUMBER_TRY_CATCH (ny,
ecma_get_completion_value_value (py),
ret_value);
// b.
ECMA_TRY_CATCH(ny, ecma_op_to_number (ecma_get_completion_value_value (py)), ret_value);
ecma_number_t* num_x_p = ecma_get_number_from_completion_value (nx);
ecma_number_t* num_y_p = ecma_get_number_from_completion_value (ny);
if (ecma_number_is_nan (*num_x_p)
|| ecma_number_is_nan (*num_y_p))
if (ecma_number_is_nan (nx)
|| ecma_number_is_nan (ny))
{
// c., d.
ret_value = ecma_make_simple_completion_value (ECMA_SIMPLE_VALUE_UNDEFINED);
}
else
{
bool is_x_less_than_y = (*num_x_p < *num_y_p);
bool is_x_less_than_y = (nx < ny);
#ifndef JERRY_NDEBUG
bool is_x_less_than_y_check;
if (*num_x_p == *num_y_p
|| (ecma_number_is_zero (*num_x_p)
&& ecma_number_is_zero (*num_y_p)))
if (nx == ny
|| (ecma_number_is_zero (nx)
&& ecma_number_is_zero (ny)))
{
// e., f., g.
is_x_less_than_y_check = false;
}
else if (ecma_number_is_infinity (*num_x_p)
&& !ecma_number_is_negative (*num_x_p))
else if (ecma_number_is_infinity (nx)
&& !ecma_number_is_negative (nx))
{
// h.
is_x_less_than_y_check = false;
}
else if (ecma_number_is_infinity (*num_y_p)
&& !ecma_number_is_negative (*num_y_p))
else if (ecma_number_is_infinity (ny)
&& !ecma_number_is_negative (ny))
{
// i.
is_x_less_than_y_check = true;
}
else if (ecma_number_is_infinity (*num_y_p)
&& ecma_number_is_negative (*num_y_p))
else if (ecma_number_is_infinity (ny)
&& ecma_number_is_negative (ny))
{
// j.
is_x_less_than_y_check = false;
}
else if (ecma_number_is_infinity (*num_x_p)
&& ecma_number_is_negative (*num_x_p))
else if (ecma_number_is_infinity (nx)
&& ecma_number_is_negative (nx))
{
// k.
is_x_less_than_y_check = true;
@@ -420,14 +420,14 @@ ecma_op_abstract_relational_compare (ecma_value_t x, /**< first operand */
else
{
// l.
JERRY_ASSERT (!ecma_number_is_nan (*num_x_p)
&& !ecma_number_is_infinity (*num_x_p));
JERRY_ASSERT (!ecma_number_is_nan (*num_y_p)
&& !ecma_number_is_infinity (*num_y_p));
JERRY_ASSERT (!(ecma_number_is_zero (*num_x_p)
&& ecma_number_is_zero (*num_y_p)));
JERRY_ASSERT (!ecma_number_is_nan (nx)
&& !ecma_number_is_infinity (nx));
JERRY_ASSERT (!ecma_number_is_nan (ny)
&& !ecma_number_is_infinity (ny));
JERRY_ASSERT (!(ecma_number_is_zero (nx)
&& ecma_number_is_zero (ny)));
if (*num_x_p < *num_y_p)
if (nx < ny)
{
is_x_less_than_y_check = true;
}
@@ -444,8 +444,8 @@ ecma_op_abstract_relational_compare (ecma_value_t x, /**< first operand */
ECMA_SIMPLE_VALUE_TRUE : ECMA_SIMPLE_VALUE_FALSE);
}
ECMA_FINALIZE(ny);
ECMA_FINALIZE(nx);
ECMA_OP_TO_NUMBER_FINALIZE (ny);
ECMA_OP_TO_NUMBER_FINALIZE (nx);
}
else
{ // 4.
@@ -50,4 +50,49 @@
#define ECMA_FINALIZE(var) } \
ecma_free_completion_value (var)
/**
* 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.
*
* 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_OP_TO_NUMBER_TRY_CATCH should have it's own corresponding ECMA_OP_TO_NUMBER_FINALIZE
* statement with same argument as corresponding ECMA_OP_TO_NUMBER_TRY_CATCH's first argument.
*/
#define ECMA_OP_TO_NUMBER_TRY_CATCH(num_var, value, return_value) \
JERRY_ASSERT (ecma_is_completion_value_empty (return_value)); \
ecma_number_t num_var = ecma_number_make_nan (); \
if (ecma_is_value_number (value)) \
{ \
num_var = *ecma_get_number_from_value (value); \
} \
else \
{ \
ECMA_TRY_CATCH (to_number_completion_value, \
ecma_op_to_number (value), \
return_value); \
\
num_var = *ecma_get_number_from_completion_value (to_number_completion_value); \
\
ECMA_FINALIZE (to_number_completion_value); \
} \
\
if (ecma_is_completion_value_empty (return_value)) \
{
/**
* The macro marks end of code block that is defined by corresponding ECMA_OP_TO_NUMBER_TRY_CATCH.
*
* Note:
* Each ECMA_OP_TO_NUMBER_TRY_CATCH should be followed by ECMA_OP_TO_NUMBER_FINALIZE
* with same argument as corresponding ECMA_OP_TO_NUMBER_TRY_CATCH's first argument.
*/
#define ECMA_OP_TO_NUMBER_FINALIZE(num_var) } \
else \
{ \
JERRY_ASSERT (ecma_number_is_nan (num_var)); \
}
#endif /* !ECMA_TRY_CATCH_MACRO_H */