diff --git a/src/libcoreint/opcodes-ecma-arithmetics.c b/src/libcoreint/opcodes-ecma-arithmetics.c index f52e10d77..7566f5961 100644 --- a/src/libcoreint/opcodes-ecma-arithmetics.c +++ b/src/libcoreint/opcodes-ecma-arithmetics.c @@ -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++; diff --git a/src/libcoreint/opcodes-ecma-bitwise.c b/src/libcoreint/opcodes-ecma-bitwise.c index e15dab15b..6cfa9105e 100644 --- a/src/libcoreint/opcodes-ecma-bitwise.c +++ b/src/libcoreint/opcodes-ecma-bitwise.c @@ -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 */ diff --git a/src/libcoreint/opcodes.c b/src/libcoreint/opcodes.c index 50253e65a..dcff5d0c7 100644 --- a/src/libcoreint/opcodes.c +++ b/src/libcoreint/opcodes.c @@ -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++; diff --git a/src/libecmabuiltins/ecma-builtin-global.c b/src/libecmabuiltins/ecma-builtin-global.c index bc13c14da..2b7968406 100644 --- a/src/libecmabuiltins/ecma-builtin-global.c +++ b/src/libecmabuiltins/ecma-builtin-global.c @@ -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 */ diff --git a/src/libecmabuiltins/ecma-builtin-math.c b/src/libecmabuiltins/ecma-builtin-math.c index a322eda30..b86a8e368 100644 --- a/src/libecmabuiltins/ecma-builtin-math.c +++ b/src/libecmabuiltins/ecma-builtin-math.c @@ -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 */ diff --git a/src/libecmabuiltins/ecma-builtin-string.c b/src/libecmabuiltins/ecma-builtin-string.c index c315ea959..12bb65577 100644 --- a/src/libecmabuiltins/ecma-builtin-string.c +++ b/src/libecmabuiltins/ecma-builtin-string.c @@ -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)) { diff --git a/src/libecmaoperations/ecma-comparison.c b/src/libecmaoperations/ecma-comparison.c index 663c5fe61..45bb9095a 100644 --- a/src/libecmaoperations/ecma-comparison.c +++ b/src/libecmaoperations/ecma-comparison.c @@ -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. diff --git a/src/libecmaoperations/ecma-try-catch-macro.h b/src/libecmaoperations/ecma-try-catch-macro.h index 0625359a5..07b6d6511 100644 --- a/src/libecmaoperations/ecma-try-catch-macro.h +++ b/src/libecmaoperations/ecma-try-catch-macro.h @@ -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 */