diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h index 3cbbfb645e..3e1f3b5ab0 100644 --- a/jerry-core/ecma/base/ecma-globals.h +++ b/jerry-core/ecma/base/ecma-globals.h @@ -73,12 +73,12 @@ typedef enum * - immutable binding values * - special register or stack values for vm */ - ECMA_SIMPLE_VALUE_EMPTY, - ECMA_SIMPLE_VALUE_UNDEFINED, /**< undefined value */ - ECMA_SIMPLE_VALUE_NULL, /**< null value */ + ECMA_SIMPLE_VALUE_EMPTY, /**< uninitialized value */ + ECMA_SIMPLE_VALUE_ARRAY_HOLE, /**< array hole, used for initialization of an array literal */ ECMA_SIMPLE_VALUE_FALSE, /**< boolean false */ ECMA_SIMPLE_VALUE_TRUE, /**< boolean true */ - ECMA_SIMPLE_VALUE_ARRAY_HOLE, /**< array hole, used for initialization of an array literal */ + ECMA_SIMPLE_VALUE_UNDEFINED, /**< undefined value */ + ECMA_SIMPLE_VALUE_NULL, /**< null value */ ECMA_SIMPLE_VALUE_REGISTER_REF, /**< register reference, a special "base" value for vm */ ECMA_SIMPLE_VALUE__COUNT /** count of simple ecma values */ } ecma_simple_value_t; diff --git a/jerry-core/ecma/base/ecma-helpers-value.c b/jerry-core/ecma/base/ecma-helpers-value.c index b949a4c112..e9d14f1a4d 100644 --- a/jerry-core/ecma/base/ecma-helpers-value.c +++ b/jerry-core/ecma/base/ecma-helpers-value.c @@ -59,6 +59,10 @@ JERRY_STATIC_ASSERT (sizeof (uintptr_t) > sizeof (ecma_value_t), #endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */ +JERRY_STATIC_ASSERT ((ECMA_SIMPLE_VALUE_FALSE | 0x1) == ECMA_SIMPLE_VALUE_TRUE + && ECMA_SIMPLE_VALUE_FALSE != ECMA_SIMPLE_VALUE_TRUE, + only_the_lowest_bit_must_be_different_for_simple_value_true_and_false); + /** * Get type field of ecma value * @@ -109,6 +113,18 @@ ecma_get_pointer_from_ecma_value (ecma_value_t value) /**< value */ #endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */ } /* ecma_get_pointer_from_ecma_value */ +/** + * Check if the value is simple ecma-value. + * + * @return true - if the value is a simple value, + * false - otherwise. + */ +inline bool __attr_pure___ __attr_always_inline___ +ecma_is_value_simple (ecma_value_t value) /**< ecma value */ +{ + return (value & ECMA_DIRECT_TYPE_MASK) == ECMA_DIRECT_TYPE_SIMPLE_VALUE; +} /* ecma_is_value_simple */ + /** * Check whether the value is a given simple value. * @@ -167,7 +183,7 @@ ecma_is_value_null (ecma_value_t value) /**< ecma value */ inline bool __attr_pure___ __attr_always_inline___ ecma_is_value_boolean (ecma_value_t value) /**< ecma value */ { - return ecma_is_value_true (value) || ecma_is_value_false (value); + return ecma_is_value_true (value | (1 << ECMA_DIRECT_SHIFT)); } /* ecma_is_value_boolean */ /** @@ -500,6 +516,14 @@ ecma_get_integer_from_value (ecma_value_t value) /**< ecma value */ return ((ecma_integer_value_t) value) >> ECMA_DIRECT_SHIFT; } /* ecma_get_integer_from_value */ +inline ecma_number_t __attr_pure___ __attr_always_inline___ +ecma_get_float_from_value (ecma_value_t value) /**< ecma value */ +{ + JERRY_ASSERT (ecma_get_value_type_field (value) == ECMA_TYPE_FLOAT); + + return *(ecma_number_t *) ecma_get_pointer_from_ecma_value (value); +} /* ecma_get_float_from_value */ + /** * Get floating point value from an ecma value * @@ -513,9 +537,7 @@ ecma_get_number_from_value (ecma_value_t value) /**< ecma value */ return (ecma_number_t) ecma_get_integer_from_value (value); } - JERRY_ASSERT (ecma_get_value_type_field (value) == ECMA_TYPE_FLOAT); - - return *(ecma_number_t *) ecma_get_pointer_from_ecma_value (value); + return ecma_get_float_from_value (value); } /* ecma_get_number_from_value */ /** @@ -563,6 +585,19 @@ ecma_get_object_from_value (ecma_value_t value) /**< ecma value */ return (ecma_object_t *) ecma_get_pointer_from_ecma_value (value); } /* ecma_get_object_from_value */ +/** + * Invert a boolean value + * + * @return ecma value + */ +inline ecma_value_t __attr_pure___ __attr_always_inline___ +ecma_invert_boolean_value (ecma_value_t value) /**< ecma value */ +{ + JERRY_ASSERT (ecma_is_value_boolean (value)); + + return (value ^ (1 << ECMA_DIRECT_SHIFT)); +} /* ecma_invert_boolean_value */ + /** * Get the value from an error ecma value * diff --git a/jerry-core/ecma/base/ecma-helpers.h b/jerry-core/ecma/base/ecma-helpers.h index ea7c4337c2..061f7c8094 100644 --- a/jerry-core/ecma/base/ecma-helpers.h +++ b/jerry-core/ecma/base/ecma-helpers.h @@ -114,26 +114,27 @@ } /* ecma-helpers-value.c */ -extern bool ecma_is_value_empty (ecma_value_t); -extern bool ecma_is_value_undefined (ecma_value_t); -extern bool ecma_is_value_null (ecma_value_t); -extern bool ecma_is_value_boolean (ecma_value_t); -extern bool ecma_is_value_true (ecma_value_t); -extern bool ecma_is_value_false (ecma_value_t); -extern bool ecma_is_value_array_hole (ecma_value_t); - -extern bool ecma_is_value_integer_number (ecma_value_t); -extern bool ecma_are_values_integer_numbers (ecma_value_t, ecma_value_t); -extern bool ecma_is_value_float_number (ecma_value_t); -extern bool ecma_is_value_number (ecma_value_t); -extern bool ecma_is_value_string (ecma_value_t); -extern bool ecma_is_value_object (ecma_value_t); -extern bool ecma_is_value_error (ecma_value_t); +extern bool ecma_is_value_simple (ecma_value_t) __attr_pure___; +extern bool ecma_is_value_empty (ecma_value_t) __attr_pure___; +extern bool ecma_is_value_undefined (ecma_value_t) __attr_pure___; +extern bool ecma_is_value_null (ecma_value_t) __attr_pure___; +extern bool ecma_is_value_boolean (ecma_value_t) __attr_pure___; +extern bool ecma_is_value_true (ecma_value_t) __attr_pure___; +extern bool ecma_is_value_false (ecma_value_t) __attr_pure___; +extern bool ecma_is_value_array_hole (ecma_value_t) __attr_pure___; + +extern bool ecma_is_value_integer_number (ecma_value_t) __attr_pure___; +extern bool ecma_are_values_integer_numbers (ecma_value_t, ecma_value_t) __attr_pure___; +extern bool ecma_is_value_float_number (ecma_value_t) __attr_pure___; +extern bool ecma_is_value_number (ecma_value_t) __attr_pure___; +extern bool ecma_is_value_string (ecma_value_t) __attr_pure___; +extern bool ecma_is_value_object (ecma_value_t) __attr_pure___; +extern bool ecma_is_value_error (ecma_value_t) __attr_pure___; extern void ecma_check_value_type_is_spec_defined (ecma_value_t); -extern ecma_value_t ecma_make_simple_value (const ecma_simple_value_t value); -extern ecma_value_t ecma_make_integer_value (ecma_integer_value_t); +extern ecma_value_t ecma_make_simple_value (const ecma_simple_value_t value) __attr_const___; +extern ecma_value_t ecma_make_integer_value (ecma_integer_value_t) __attr_const___; extern ecma_value_t ecma_make_nan_value (void); extern ecma_value_t ecma_make_number_value (ecma_number_t); extern ecma_value_t ecma_make_int32_value (int32_t); @@ -142,12 +143,14 @@ extern ecma_value_t ecma_make_string_value (const ecma_string_t *); extern ecma_value_t ecma_make_object_value (const ecma_object_t *); extern ecma_value_t ecma_make_error_value (ecma_value_t); extern ecma_value_t ecma_make_error_obj_value (const ecma_object_t *); -extern ecma_integer_value_t ecma_get_integer_from_value (ecma_value_t); +extern ecma_integer_value_t ecma_get_integer_from_value (ecma_value_t) __attr_pure___; +extern ecma_number_t ecma_get_float_from_value (ecma_value_t value) __attr_pure___; extern ecma_number_t ecma_get_number_from_value (ecma_value_t) __attr_pure___; extern uint32_t ecma_get_uint32_from_value (ecma_value_t) __attr_pure___; extern ecma_string_t *ecma_get_string_from_value (ecma_value_t) __attr_pure___; extern ecma_object_t *ecma_get_object_from_value (ecma_value_t) __attr_pure___; extern ecma_value_t ecma_get_value_from_error_value (ecma_value_t) __attr_pure___; +extern ecma_value_t ecma_invert_boolean_value (ecma_value_t) __attr_pure___; extern ecma_value_t ecma_copy_value (ecma_value_t); extern ecma_value_t ecma_fast_copy_value (ecma_value_t); extern ecma_value_t ecma_copy_value_if_not_object (ecma_value_t); diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c index 77d6d3c16d..ce79f6f258 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c @@ -2027,8 +2027,8 @@ ecma_builtin_array_prototype_object_every (ecma_value_t this_arg, /**< this argu /* 7.c.ii */ ECMA_TRY_CATCH (call_value, ecma_op_function_call (func_object_p, arg2, call_args, 3), ret_value); - /* 7.c.iii, ecma_op_to_boolean always returns a simple value, so no need to free. */ - if (ecma_is_value_false (ecma_op_to_boolean (call_value))) + /* 7.c.iii */ + if (!ecma_op_to_boolean (call_value)) { ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE); } @@ -2125,8 +2125,8 @@ ecma_builtin_array_prototype_object_some (ecma_value_t this_arg, /**< this argum /* 7.c.ii */ ECMA_TRY_CATCH (call_value, ecma_op_function_call (func_object_p, arg2, call_args, 3), ret_value); - /* 7.c.iii, ecma_op_to_boolean always returns a simple value, so no need to free. */ - if (ecma_is_value_true (ecma_op_to_boolean (call_value))) + /* 7.c.iii */ + if (ecma_op_to_boolean (call_value)) { ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE); } @@ -2430,8 +2430,8 @@ ecma_builtin_array_prototype_object_filter (ecma_value_t this_arg, /**< this arg /* 9.c.ii */ ECMA_TRY_CATCH (call_value, ecma_op_function_call (func_object_p, arg2, call_args, 3), ret_value); - /* 9.c.iii, ecma_op_to_boolean always returns a simple value, so no need to free. */ - if (ecma_is_value_true (ecma_op_to_boolean (call_value))) + /* 9.c.iii */ + if (ecma_op_to_boolean (call_value)) { ecma_string_t *to_index_string_p = ecma_new_ecma_string_from_uint32 (new_array_index); diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-boolean.c b/jerry-core/ecma/builtin-objects/ecma-builtin-boolean.c index e6ed2668c4..4db1122609 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-boolean.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-boolean.c @@ -66,7 +66,8 @@ ecma_builtin_boolean_dispatch_call (const ecma_value_t *arguments_list_p, /**< a arg_value = arguments_list_p[0]; } - return ecma_op_to_boolean (arg_value); + return ecma_make_simple_value (ecma_op_to_boolean (arg_value) ? ECMA_SIMPLE_VALUE_TRUE + : ECMA_SIMPLE_VALUE_FALSE); } /* ecma_builtin_boolean_dispatch_call */ /** diff --git a/jerry-core/ecma/operations/ecma-boolean-object.c b/jerry-core/ecma/operations/ecma-boolean-object.c index 606141d205..e91f46d52f 100644 --- a/jerry-core/ecma/operations/ecma-boolean-object.c +++ b/jerry-core/ecma/operations/ecma-boolean-object.c @@ -41,12 +41,7 @@ ecma_value_t ecma_op_create_boolean_object (ecma_value_t arg) /**< argument passed to the Boolean constructor */ { - ecma_value_t conv_to_boolean_completion = ecma_op_to_boolean (arg); - - if (ecma_is_value_error (conv_to_boolean_completion)) - { - return conv_to_boolean_completion; - } + bool boolean_value = ecma_op_to_boolean (arg); #ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_BOOLEAN_BUILTIN ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE); @@ -64,7 +59,11 @@ ecma_op_create_boolean_object (ecma_value_t arg) /**< argument passed to the Boo ecma_property_t *prim_value_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_ECMA_VALUE); - ecma_set_internal_property_value (prim_value_prop_p, conv_to_boolean_completion); + + ecma_value_t prim_value = ecma_make_simple_value (boolean_value ? ECMA_SIMPLE_VALUE_TRUE + : ECMA_SIMPLE_VALUE_FALSE); + + ecma_set_internal_property_value (prim_value_prop_p, prim_value); return ecma_make_object_value (obj_p); } /* ecma_op_create_boolean_object */ diff --git a/jerry-core/ecma/operations/ecma-comparison.c b/jerry-core/ecma/operations/ecma-comparison.c index 6342c10374..d55877b2f4 100644 --- a/jerry-core/ecma/operations/ecma-comparison.c +++ b/jerry-core/ecma/operations/ecma-comparison.c @@ -334,15 +334,12 @@ ecma_op_abstract_relational_compare (ecma_value_t x, /**< first operand */ { ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); - ecma_value_t first_converted_value = left_first ? x : y; - ecma_value_t second_converted_value = left_first ? y : x; - // 1., 2. ECMA_TRY_CATCH (prim_first_converted_value, - ecma_op_to_primitive (first_converted_value, ECMA_PREFERRED_TYPE_NUMBER), + ecma_op_to_primitive (x, ECMA_PREFERRED_TYPE_NUMBER), ret_value); ECMA_TRY_CATCH (prim_second_converted_value, - ecma_op_to_primitive (second_converted_value, ECMA_PREFERRED_TYPE_NUMBER), + ecma_op_to_primitive (y, ECMA_PREFERRED_TYPE_NUMBER), ret_value); const ecma_value_t px = left_first ? prim_first_converted_value : prim_second_converted_value; diff --git a/jerry-core/ecma/operations/ecma-conversion.c b/jerry-core/ecma/operations/ecma-conversion.c index 1b8074dd81..b1e4fd9c6f 100644 --- a/jerry-core/ecma/operations/ecma-conversion.c +++ b/jerry-core/ecma/operations/ecma-conversion.c @@ -184,67 +184,50 @@ ecma_op_to_primitive (ecma_value_t value, /**< ecma value */ } /* ecma_op_to_primitive */ /** - * ToBoolean operation. + * ToBoolean operation. Cannot throw an exception. * * See also: * ECMA-262 v5, 9.2 * - * @return ecma value - * Returned value is simple and so need not be freed. - * However, ecma_free_value may be called for it, but it is a no-op. + * @return true if the logical value is true + * false otherwise */ -ecma_value_t +bool ecma_op_to_boolean (ecma_value_t value) /**< ecma value */ { ecma_check_value_type_is_spec_defined (value); - ecma_simple_value_t ret_value; - - if (ecma_is_value_boolean (value)) + if (ecma_is_value_simple (value)) { - ret_value = (ecma_is_value_true (value) ? - ECMA_SIMPLE_VALUE_TRUE : ECMA_SIMPLE_VALUE_FALSE); + JERRY_ASSERT (ecma_is_value_boolean (value) + || ecma_is_value_undefined (value) + || ecma_is_value_null (value)); + + return ecma_is_value_true (value); } - else if (ecma_is_value_undefined (value) - || ecma_is_value_null (value)) + + if (ecma_is_value_integer_number (value)) { - ret_value = ECMA_SIMPLE_VALUE_FALSE; + return (value != ecma_make_integer_value (0)); } - else if (ecma_is_value_number (value)) + + if (ecma_is_value_float_number (value)) { - ecma_number_t num = ecma_get_number_from_value (value); + ecma_number_t num = ecma_get_float_from_value (value); - if (ecma_number_is_nan (num) - || ecma_number_is_zero (num)) - { - ret_value = ECMA_SIMPLE_VALUE_FALSE; - } - else - { - ret_value = ECMA_SIMPLE_VALUE_TRUE; - } + return (!ecma_number_is_nan (num) && !ecma_number_is_zero (num)); } - else if (ecma_is_value_string (value)) + + if (ecma_is_value_string (value)) { ecma_string_t *str_p = ecma_get_string_from_value (value); - if (ecma_string_get_length (str_p) == 0) - { - ret_value = ECMA_SIMPLE_VALUE_FALSE; - } - else - { - ret_value = ECMA_SIMPLE_VALUE_TRUE; - } + return ecma_string_get_length (str_p) != 0; } - else - { - JERRY_ASSERT (ecma_is_value_object (value)); - ret_value = ECMA_SIMPLE_VALUE_TRUE; - } + JERRY_ASSERT (ecma_is_value_object (value)); - return ecma_make_simple_value (ret_value); + return true; } /* ecma_op_to_boolean */ /** @@ -607,23 +590,10 @@ ecma_op_to_property_descriptor (ecma_value_t obj_value, /**< object value */ ECMA_TRY_CATCH (enumerable_prop_value, ecma_op_object_get (obj_p, enumerable_magic_string_p), ret_value); - ECMA_TRY_CATCH (boolean_enumerable_prop_value, - ecma_op_to_boolean (enumerable_prop_value), - ret_value); prop_desc.is_enumerable_defined = true; - if (ecma_is_value_true (boolean_enumerable_prop_value)) - { - prop_desc.is_enumerable = true; - } - else - { - JERRY_ASSERT (ecma_is_value_boolean (boolean_enumerable_prop_value)); + prop_desc.is_enumerable = ecma_op_to_boolean (enumerable_prop_value); - prop_desc.is_enumerable = false; - } - - ECMA_FINALIZE (boolean_enumerable_prop_value); ECMA_FINALIZE (enumerable_prop_value); } @@ -641,23 +611,10 @@ ecma_op_to_property_descriptor (ecma_value_t obj_value, /**< object value */ ECMA_TRY_CATCH (configurable_prop_value, ecma_op_object_get (obj_p, configurable_magic_string_p), ret_value); - ECMA_TRY_CATCH (boolean_configurable_prop_value, - ecma_op_to_boolean (configurable_prop_value), - ret_value); prop_desc.is_configurable_defined = true; - if (ecma_is_value_true (boolean_configurable_prop_value)) - { - prop_desc.is_configurable = true; - } - else - { - JERRY_ASSERT (ecma_is_value_boolean (boolean_configurable_prop_value)); - - prop_desc.is_configurable = false; - } + prop_desc.is_configurable = ecma_op_to_boolean (configurable_prop_value); - ECMA_FINALIZE (boolean_configurable_prop_value); ECMA_FINALIZE (configurable_prop_value); } @@ -698,23 +655,10 @@ ecma_op_to_property_descriptor (ecma_value_t obj_value, /**< object value */ ECMA_TRY_CATCH (writable_prop_value, ecma_op_object_get (obj_p, writable_magic_string_p), ret_value); - ECMA_TRY_CATCH (boolean_writable_prop_value, - ecma_op_to_boolean (writable_prop_value), - ret_value); prop_desc.is_writable_defined = true; - if (ecma_is_value_true (boolean_writable_prop_value)) - { - prop_desc.is_writable = true; - } - else - { - JERRY_ASSERT (ecma_is_value_boolean (boolean_writable_prop_value)); - - prop_desc.is_writable = false; - } + prop_desc.is_writable = ecma_op_to_boolean (writable_prop_value); - ECMA_FINALIZE (boolean_writable_prop_value); ECMA_FINALIZE (writable_prop_value); } diff --git a/jerry-core/ecma/operations/ecma-conversion.h b/jerry-core/ecma/operations/ecma-conversion.h index 2dc7b6a2c7..a631076d80 100644 --- a/jerry-core/ecma/operations/ecma-conversion.h +++ b/jerry-core/ecma/operations/ecma-conversion.h @@ -40,7 +40,7 @@ typedef enum extern ecma_value_t ecma_op_check_object_coercible (ecma_value_t); extern bool ecma_op_same_value (ecma_value_t, ecma_value_t); extern ecma_value_t ecma_op_to_primitive (ecma_value_t, ecma_preferred_type_hint_t); -extern ecma_value_t ecma_op_to_boolean (ecma_value_t); +extern bool ecma_op_to_boolean (ecma_value_t); extern ecma_value_t ecma_op_to_number (ecma_value_t); extern ecma_value_t ecma_op_to_string (ecma_value_t); extern ecma_value_t ecma_op_to_object (ecma_value_t); diff --git a/jerry-core/vm/opcodes-ecma-relational.c b/jerry-core/vm/opcodes-ecma-relational.c index 5e700fbd18..da4991c963 100644 --- a/jerry-core/vm/opcodes-ecma-relational.c +++ b/jerry-core/vm/opcodes-ecma-relational.c @@ -53,25 +53,22 @@ opfunc_less_than (ecma_value_t left_value, /**< left value */ return ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE); } - ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); + ecma_value_t ret_value = ecma_op_abstract_relational_compare (left_value, right_value, true); - ECMA_TRY_CATCH (compare_result, - ecma_op_abstract_relational_compare (left_value, right_value, true), - ret_value); + if (ecma_is_value_error (ret_value)) + { + return ret_value; + } - if (ecma_is_value_undefined (compare_result)) + if (ecma_is_value_undefined (ret_value)) { ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE); } else { - JERRY_ASSERT (ecma_is_value_boolean (compare_result)); - - ret_value = compare_result; + JERRY_ASSERT (ecma_is_value_boolean (ret_value)); } - ECMA_FINALIZE (compare_result); - return ret_value; } /* opfunc_less_than */ @@ -99,25 +96,22 @@ opfunc_greater_than (ecma_value_t left_value, /**< left value */ return ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE); } - ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); + ecma_value_t ret_value = ecma_op_abstract_relational_compare (left_value, right_value, false); - ECMA_TRY_CATCH (compare_result, - ecma_op_abstract_relational_compare (right_value, left_value, false), - ret_value); + if (ecma_is_value_error (ret_value)) + { + return ret_value; + } - if (ecma_is_value_undefined (compare_result)) + if (ecma_is_value_undefined (ret_value)) { ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE); } else { - JERRY_ASSERT (ecma_is_value_boolean (compare_result)); - - ret_value = compare_result; + JERRY_ASSERT (ecma_is_value_boolean (ret_value)); } - ECMA_FINALIZE (compare_result); - return ret_value; } /* opfunc_greater_than */ @@ -145,32 +139,24 @@ opfunc_less_or_equal_than (ecma_value_t left_value, /**< left value */ return ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE); } - ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); + ecma_value_t ret_value = ecma_op_abstract_relational_compare (left_value, right_value, false); - ECMA_TRY_CATCH (compare_result, - ecma_op_abstract_relational_compare (right_value, left_value, false), - ret_value); + if (ecma_is_value_error (ret_value)) + { + return ret_value; + } - if (ecma_is_value_undefined (compare_result)) + if (ecma_is_value_undefined (ret_value)) { ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE); } else { - JERRY_ASSERT (ecma_is_value_boolean (compare_result)); + JERRY_ASSERT (ecma_is_value_boolean (ret_value)); - if (ecma_is_value_true (compare_result)) - { - ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE); - } - else - { - ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE); - } + ret_value = ecma_invert_boolean_value (ret_value); } - ECMA_FINALIZE (compare_result); - return ret_value; } /* opfunc_less_or_equal_than */ @@ -198,32 +184,24 @@ opfunc_greater_or_equal_than (ecma_value_t left_value, /**< left value */ return ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE); } - ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); + ecma_value_t ret_value = ecma_op_abstract_relational_compare (left_value, right_value, true); - ECMA_TRY_CATCH (compare_result, - ecma_op_abstract_relational_compare (left_value, right_value, true), - ret_value); + if (ecma_is_value_error (ret_value)) + { + return ret_value; + } - if (ecma_is_value_undefined (compare_result)) + if (ecma_is_value_undefined (ret_value)) { ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE); } else { - JERRY_ASSERT (ecma_is_value_boolean (compare_result)); + JERRY_ASSERT (ecma_is_value_boolean (ret_value)); - if (ecma_is_value_true (compare_result)) - { - ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE); - } - else - { - ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE); - } + ret_value = ecma_invert_boolean_value (ret_value); } - ECMA_FINALIZE (compare_result); - return ret_value; } /* opfunc_greater_or_equal_than */ diff --git a/jerry-core/vm/opcodes.c b/jerry-core/vm/opcodes.c index 66001849e2..60cfca2ddf 100644 --- a/jerry-core/vm/opcodes.c +++ b/jerry-core/vm/opcodes.c @@ -80,9 +80,8 @@ ecma_value_t opfunc_logical_not (ecma_value_t left_value) /**< left value */ { ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE); - ecma_value_t to_bool_value = ecma_op_to_boolean (left_value); - if (ecma_is_value_true (to_bool_value)) + if (ecma_op_to_boolean (left_value)) { ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE); } diff --git a/jerry-core/vm/vm.c b/jerry-core/vm/vm.c index e8e81ac10b..0af11b9acf 100644 --- a/jerry-core/vm/vm.c +++ b/jerry-core/vm/vm.c @@ -1498,26 +1498,26 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */ { uint32_t opcode_flags = VM_OC_GROUP_GET_INDEX (opcode_data) - VM_OC_BRANCH_IF_TRUE; - last_completion_value = ecma_op_to_boolean (left_value); + bool boolean_value = ecma_op_to_boolean (left_value); - if (ecma_is_value_error (last_completion_value)) + if (opcode_flags & VM_OC_BRANCH_IF_FALSE_FLAG) { - goto error; + boolean_value = !boolean_value; } - bool branch_if_false = (opcode_flags & VM_OC_BRANCH_IF_FALSE_FLAG); - - if (last_completion_value == ecma_make_simple_value (branch_if_false ? ECMA_SIMPLE_VALUE_FALSE - : ECMA_SIMPLE_VALUE_TRUE)) + if (boolean_value) { byte_code_p = byte_code_start_p + branch_offset; if (opcode_flags & VM_OC_LOGICAL_BRANCH_FLAG) { - left_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED); + /* "Push" the left_value back to the stack. */ ++stack_top_p; + continue; } } - break; + + ecma_fast_free_value (left_value); + continue; } case VM_OC_PLUS: {