Improve equal operations.
The implementation is simplified and optimized resulting the removal a large amount of code. JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
@@ -113,6 +113,18 @@ ecma_get_pointer_from_ecma_value (ecma_value_t value) /**< value */
|
|||||||
#endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
|
#endif /* ECMA_VALUE_CAN_STORE_UINTPTR_VALUE_DIRECTLY */
|
||||||
} /* ecma_get_pointer_from_ecma_value */
|
} /* ecma_get_pointer_from_ecma_value */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the value is direct ecma-value.
|
||||||
|
*
|
||||||
|
* @return true - if the value is a direct value,
|
||||||
|
* false - otherwise.
|
||||||
|
*/
|
||||||
|
inline bool __attr_pure___ __attr_always_inline___
|
||||||
|
ecma_is_value_direct (ecma_value_t value) /**< ecma value */
|
||||||
|
{
|
||||||
|
return (ecma_get_value_type_field (value) == ECMA_TYPE_DIRECT);
|
||||||
|
} /* ecma_is_value_direct */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the value is simple ecma-value.
|
* Check if the value is simple ecma-value.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -114,6 +114,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ecma-helpers-value.c */
|
/* ecma-helpers-value.c */
|
||||||
|
extern bool ecma_is_value_direct (ecma_value_t) __attr_pure___;
|
||||||
extern bool ecma_is_value_simple (ecma_value_t) __attr_pure___;
|
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_empty (ecma_value_t) __attr_pure___;
|
||||||
extern bool ecma_is_value_undefined (ecma_value_t) __attr_pure___;
|
extern bool ecma_is_value_undefined (ecma_value_t) __attr_pure___;
|
||||||
|
|||||||
@@ -38,41 +38,22 @@ ecma_value_t
|
|||||||
ecma_op_abstract_equality_compare (ecma_value_t x, /**< first operand */
|
ecma_op_abstract_equality_compare (ecma_value_t x, /**< first operand */
|
||||||
ecma_value_t y) /**< second operand */
|
ecma_value_t y) /**< second operand */
|
||||||
{
|
{
|
||||||
const bool is_x_undefined = ecma_is_value_undefined (x);
|
if (x == y)
|
||||||
const bool is_x_null = ecma_is_value_null (x);
|
|
||||||
const bool is_x_boolean = ecma_is_value_boolean (x);
|
|
||||||
const bool is_x_number = ecma_is_value_number (x);
|
|
||||||
const bool is_x_string = ecma_is_value_string (x);
|
|
||||||
const bool is_x_object = ecma_is_value_object (x);
|
|
||||||
|
|
||||||
const bool is_y_undefined = ecma_is_value_undefined (y);
|
|
||||||
const bool is_y_null = ecma_is_value_null (y);
|
|
||||||
const bool is_y_boolean = ecma_is_value_boolean (y);
|
|
||||||
const bool is_y_number = ecma_is_value_number (y);
|
|
||||||
const bool is_y_string = ecma_is_value_string (y);
|
|
||||||
const bool is_y_object = ecma_is_value_object (y);
|
|
||||||
|
|
||||||
const bool is_types_equal = ((is_x_undefined && is_y_undefined)
|
|
||||||
|| (is_x_null && is_y_null)
|
|
||||||
|| (is_x_boolean && is_y_boolean)
|
|
||||||
|| (is_x_number && is_y_number)
|
|
||||||
|| (is_x_string && is_y_string)
|
|
||||||
|| (is_x_object && is_y_object));
|
|
||||||
|
|
||||||
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
|
||||||
|
|
||||||
if (is_types_equal)
|
|
||||||
{
|
{
|
||||||
// 1.
|
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
if (is_x_undefined
|
if (ecma_are_values_integer_numbers (x, y))
|
||||||
|| is_x_null)
|
{
|
||||||
|
/* Note: the (x == y) comparison captures the true case. */
|
||||||
|
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ecma_is_value_number (x))
|
||||||
|
{
|
||||||
|
if (ecma_is_value_number (y))
|
||||||
{
|
{
|
||||||
// a., b.
|
// 1.c
|
||||||
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
|
|
||||||
}
|
|
||||||
else if (is_x_number)
|
|
||||||
{ // c.
|
|
||||||
ecma_number_t x_num = ecma_get_number_from_value (x);
|
ecma_number_t x_num = ecma_get_number_from_value (x);
|
||||||
ecma_number_t y_num = ecma_get_number_from_value (y);
|
ecma_number_t y_num = ecma_get_number_from_value (y);
|
||||||
|
|
||||||
@@ -100,111 +81,104 @@ ecma_op_abstract_equality_compare (ecma_value_t x, /**< first operand */
|
|||||||
JERRY_ASSERT (is_x_equal_to_y == is_x_equal_to_y_check);
|
JERRY_ASSERT (is_x_equal_to_y == is_x_equal_to_y_check);
|
||||||
#endif /* !JERRY_NDEBUG */
|
#endif /* !JERRY_NDEBUG */
|
||||||
|
|
||||||
ret_value = ecma_make_simple_value (is_x_equal_to_y ? ECMA_SIMPLE_VALUE_TRUE : ECMA_SIMPLE_VALUE_FALSE);
|
return ecma_make_simple_value (is_x_equal_to_y ? ECMA_SIMPLE_VALUE_TRUE : ECMA_SIMPLE_VALUE_FALSE);
|
||||||
}
|
}
|
||||||
else if (is_x_string)
|
|
||||||
{ // d.
|
/* Swap values. */
|
||||||
|
ecma_value_t tmp = x;
|
||||||
|
x = y;
|
||||||
|
y = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ecma_is_value_string (x))
|
||||||
|
{
|
||||||
|
if (ecma_is_value_string (y))
|
||||||
|
{
|
||||||
|
// 1., d.
|
||||||
ecma_string_t *x_str_p = ecma_get_string_from_value (x);
|
ecma_string_t *x_str_p = ecma_get_string_from_value (x);
|
||||||
ecma_string_t *y_str_p = ecma_get_string_from_value (y);
|
ecma_string_t *y_str_p = ecma_get_string_from_value (y);
|
||||||
|
|
||||||
bool is_equal = ecma_compare_ecma_strings (x_str_p, y_str_p);
|
bool is_equal = ecma_compare_ecma_strings (x_str_p, y_str_p);
|
||||||
|
|
||||||
ret_value = ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_TRUE : ECMA_SIMPLE_VALUE_FALSE);
|
return ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_TRUE : ECMA_SIMPLE_VALUE_FALSE);
|
||||||
}
|
}
|
||||||
else if (is_x_boolean)
|
|
||||||
{ // e.
|
|
||||||
bool is_equal = (ecma_is_value_true (x) == ecma_is_value_true (y));
|
|
||||||
|
|
||||||
ret_value = ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_TRUE : ECMA_SIMPLE_VALUE_FALSE);
|
if (ecma_is_value_number (y))
|
||||||
|
{
|
||||||
|
// 4.
|
||||||
|
ecma_value_t x_num_value = ecma_op_to_number (x);
|
||||||
|
|
||||||
|
if (ecma_is_value_error (x_num_value))
|
||||||
|
{
|
||||||
|
return x_num_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
ecma_value_t compare_result = ecma_op_abstract_equality_compare (x_num_value, y);
|
||||||
|
|
||||||
|
ecma_free_value (x_num_value);
|
||||||
|
return compare_result;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{ // f.
|
|
||||||
JERRY_ASSERT (is_x_object);
|
|
||||||
|
|
||||||
bool is_equal = (ecma_get_object_from_value (x) == ecma_get_object_from_value (y));
|
/* Swap values. */
|
||||||
|
ecma_value_t tmp = x;
|
||||||
ret_value = ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_TRUE : ECMA_SIMPLE_VALUE_FALSE);
|
x = y;
|
||||||
}
|
y = tmp;
|
||||||
}
|
}
|
||||||
else if ((is_x_null && is_y_undefined)
|
|
||||||
|| (is_x_undefined && is_y_null))
|
if (ecma_is_value_boolean (y))
|
||||||
{ // 2., 3.
|
|
||||||
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
|
|
||||||
}
|
|
||||||
else if (is_x_number && is_y_string)
|
|
||||||
{
|
{
|
||||||
// 4.
|
if (ecma_is_value_boolean (x))
|
||||||
ECMA_TRY_CATCH (y_num_value,
|
{
|
||||||
ecma_op_to_number (y),
|
// 1., e.
|
||||||
ret_value);
|
/* Note: the (x == y) comparison captures the true case. */
|
||||||
|
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
ret_value = ecma_op_abstract_equality_compare (x, y_num_value);
|
// 7.
|
||||||
|
return ecma_op_abstract_equality_compare (x, ecma_make_integer_value (ecma_is_value_true (y) ? 1 : 0));
|
||||||
ECMA_FINALIZE (y_num_value);
|
|
||||||
}
|
}
|
||||||
else if (is_x_string && is_y_number)
|
|
||||||
|
if (ecma_is_value_object (x))
|
||||||
{
|
{
|
||||||
// 5.
|
if (ecma_is_value_string (y)
|
||||||
ECMA_TRY_CATCH (x_num_value,
|
|| ecma_is_value_number (y))
|
||||||
ecma_op_to_number (x),
|
{
|
||||||
ret_value);
|
// 9.
|
||||||
|
ecma_value_t x_prim_value = ecma_op_to_primitive (x, ECMA_PREFERRED_TYPE_NO);
|
||||||
|
|
||||||
ret_value = ecma_op_abstract_equality_compare (x_num_value, y);
|
if (ecma_is_value_error (x_prim_value))
|
||||||
|
{
|
||||||
|
return x_prim_value;
|
||||||
|
}
|
||||||
|
|
||||||
ECMA_FINALIZE (x_num_value);
|
ecma_value_t compare_result = ecma_op_abstract_equality_compare (x_prim_value, y);
|
||||||
|
|
||||||
|
ecma_free_value (x_prim_value);
|
||||||
|
return compare_result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1., f.
|
||||||
|
/* Note: the (x == y) comparison captures the true case. */
|
||||||
|
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
|
||||||
}
|
}
|
||||||
else if (is_x_boolean)
|
|
||||||
|
if (ecma_is_value_boolean (x))
|
||||||
{
|
{
|
||||||
// 6.
|
// 6.
|
||||||
ECMA_TRY_CATCH (x_num_value,
|
return ecma_op_abstract_equality_compare (ecma_make_integer_value (ecma_is_value_true (x) ? 1 : 0), y);
|
||||||
ecma_op_to_number (x),
|
|
||||||
ret_value);
|
|
||||||
|
|
||||||
ret_value = ecma_op_abstract_equality_compare (x_num_value, y);
|
|
||||||
|
|
||||||
ECMA_FINALIZE (x_num_value);
|
|
||||||
}
|
}
|
||||||
else if (is_y_boolean)
|
|
||||||
|
if (ecma_is_value_undefined (x)
|
||||||
|
|| ecma_is_value_null (x))
|
||||||
{
|
{
|
||||||
// 7.
|
// 1. a., b.
|
||||||
ECMA_TRY_CATCH (y_num_value,
|
// 2., 3.
|
||||||
ecma_op_to_number (y),
|
bool is_equal = ecma_is_value_undefined (y) || ecma_is_value_null (y);
|
||||||
ret_value);
|
|
||||||
|
|
||||||
ret_value = ecma_op_abstract_equality_compare (x, y_num_value);
|
return ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_TRUE : ECMA_SIMPLE_VALUE_FALSE);
|
||||||
|
|
||||||
ECMA_FINALIZE (y_num_value);
|
|
||||||
}
|
|
||||||
else if (is_y_object
|
|
||||||
&& (is_x_number || is_x_string))
|
|
||||||
{
|
|
||||||
// 8.
|
|
||||||
ECMA_TRY_CATCH (y_prim_value,
|
|
||||||
ecma_op_to_primitive (y, ECMA_PREFERRED_TYPE_NO),
|
|
||||||
ret_value);
|
|
||||||
|
|
||||||
ret_value = ecma_op_abstract_equality_compare (x, y_prim_value);
|
|
||||||
|
|
||||||
ECMA_FINALIZE (y_prim_value);
|
|
||||||
}
|
|
||||||
else if (is_x_object
|
|
||||||
&& (is_y_number || is_y_string))
|
|
||||||
{
|
|
||||||
// 9.
|
|
||||||
ECMA_TRY_CATCH (x_prim_value,
|
|
||||||
ecma_op_to_primitive (x, ECMA_PREFERRED_TYPE_NO),
|
|
||||||
ret_value);
|
|
||||||
|
|
||||||
ret_value = ecma_op_abstract_equality_compare (x_prim_value, y);
|
|
||||||
|
|
||||||
ECMA_FINALIZE (x_prim_value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret_value;
|
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
|
||||||
} /* ecma_op_abstract_equality_compare */
|
} /* ecma_op_abstract_equality_compare */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -219,104 +193,81 @@ bool
|
|||||||
ecma_op_strict_equality_compare (ecma_value_t x, /**< first operand */
|
ecma_op_strict_equality_compare (ecma_value_t x, /**< first operand */
|
||||||
ecma_value_t y) /**< second operand */
|
ecma_value_t y) /**< second operand */
|
||||||
{
|
{
|
||||||
const bool is_x_undefined = ecma_is_value_undefined (x);
|
if (ecma_is_value_direct (x)
|
||||||
const bool is_x_null = ecma_is_value_null (x);
|
|| ecma_is_value_direct (y)
|
||||||
const bool is_x_boolean = ecma_is_value_boolean (x);
|
|| ecma_is_value_object (x)
|
||||||
const bool is_x_number = ecma_is_value_number (x);
|
|| ecma_is_value_object (y))
|
||||||
const bool is_x_string = ecma_is_value_string (x);
|
|
||||||
const bool is_x_object = ecma_is_value_object (x);
|
|
||||||
|
|
||||||
const bool is_y_undefined = ecma_is_value_undefined (y);
|
|
||||||
const bool is_y_null = ecma_is_value_null (y);
|
|
||||||
const bool is_y_boolean = ecma_is_value_boolean (y);
|
|
||||||
const bool is_y_number = ecma_is_value_number (y);
|
|
||||||
const bool is_y_string = ecma_is_value_string (y);
|
|
||||||
const bool is_y_object = ecma_is_value_object (y);
|
|
||||||
|
|
||||||
const bool is_types_equal = ((is_x_undefined && is_y_undefined)
|
|
||||||
|| (is_x_null && is_y_null)
|
|
||||||
|| (is_x_boolean && is_y_boolean)
|
|
||||||
|| (is_x_number && is_y_number)
|
|
||||||
|| (is_x_string && is_y_string)
|
|
||||||
|| (is_x_object && is_y_object));
|
|
||||||
|
|
||||||
// 1. If Type (x) is different from Type (y), return false.
|
|
||||||
if (!is_types_equal)
|
|
||||||
{
|
{
|
||||||
return false;
|
JERRY_ASSERT (!ecma_is_value_direct (x)
|
||||||
}
|
|| ecma_is_value_undefined (x)
|
||||||
|
|| ecma_is_value_null (x)
|
||||||
|
|| ecma_is_value_boolean (x)
|
||||||
|
|| ecma_is_value_integer_number (x));
|
||||||
|
|
||||||
// 2. If Type (x) is Undefined, return true.
|
JERRY_ASSERT (!ecma_is_value_direct (y)
|
||||||
if (is_x_undefined)
|
|| ecma_is_value_undefined (y)
|
||||||
{
|
|| ecma_is_value_null (y)
|
||||||
return true;
|
|| ecma_is_value_boolean (y)
|
||||||
}
|
|| ecma_is_value_integer_number (y));
|
||||||
|
|
||||||
// 3. If Type (x) is Null, return true.
|
if ((x != ecma_make_integer_value (0) || !ecma_is_value_float_number (y))
|
||||||
if (is_x_null)
|
&& (y != ecma_make_integer_value (0) || !ecma_is_value_float_number (x)))
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. If Type (x) is Number, then
|
|
||||||
if (is_x_number)
|
|
||||||
{
|
|
||||||
// a. If x is NaN, return false.
|
|
||||||
// b. If y is NaN, return false.
|
|
||||||
// c. If x is the same Number value as y, return true.
|
|
||||||
// d. If x is +0 and y is -0, return true.
|
|
||||||
// e. If x is -0 and y is +0, return true.
|
|
||||||
|
|
||||||
ecma_number_t x_num = ecma_get_number_from_value (x);
|
|
||||||
ecma_number_t y_num = ecma_get_number_from_value (y);
|
|
||||||
|
|
||||||
bool is_x_equal_to_y = (x_num == y_num);
|
|
||||||
|
|
||||||
#ifndef JERRY_NDEBUG
|
|
||||||
bool is_x_equal_to_y_check;
|
|
||||||
|
|
||||||
if (ecma_number_is_nan (x_num)
|
|
||||||
|| ecma_number_is_nan (y_num))
|
|
||||||
{
|
{
|
||||||
is_x_equal_to_y_check = false;
|
return (x == y);
|
||||||
}
|
|
||||||
else if (x_num == y_num
|
|
||||||
|| (ecma_number_is_zero (x_num)
|
|
||||||
&& ecma_number_is_zero (y_num)))
|
|
||||||
{
|
|
||||||
is_x_equal_to_y_check = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
is_x_equal_to_y_check = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JERRY_ASSERT (is_x_equal_to_y == is_x_equal_to_y_check);
|
/* The +0 === -0 case handled below. */
|
||||||
#endif /* !JERRY_NDEBUG */
|
|
||||||
|
|
||||||
return is_x_equal_to_y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5. If Type (x) is String, then return true if x and y are exactly the same sequence of characters
|
JERRY_ASSERT (ecma_is_value_number (x) || ecma_is_value_string (x));
|
||||||
// (same length and same characters in corresponding positions); otherwise, return false.
|
JERRY_ASSERT (ecma_is_value_number (y) || ecma_is_value_string (y));
|
||||||
if (is_x_string)
|
|
||||||
|
if (ecma_is_value_string (x))
|
||||||
{
|
{
|
||||||
|
if (!ecma_is_value_string (y))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ecma_string_t *x_str_p = ecma_get_string_from_value (x);
|
ecma_string_t *x_str_p = ecma_get_string_from_value (x);
|
||||||
ecma_string_t *y_str_p = ecma_get_string_from_value (y);
|
ecma_string_t *y_str_p = ecma_get_string_from_value (y);
|
||||||
|
|
||||||
return ecma_compare_ecma_strings (x_str_p, y_str_p);
|
return ecma_compare_ecma_strings (x_str_p, y_str_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6. If Type (x) is Boolean, return true if x and y are both true or both false; otherwise, return false.
|
if (!ecma_is_value_number (y))
|
||||||
if (is_x_boolean)
|
|
||||||
{
|
{
|
||||||
return (ecma_is_value_true (x) == ecma_is_value_true (y));
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 7. Return true if x and y refer to the same object. Otherwise, return false.
|
ecma_number_t x_num = ecma_get_number_from_value (x);
|
||||||
JERRY_ASSERT (is_x_object);
|
ecma_number_t y_num = ecma_get_number_from_value (y);
|
||||||
|
|
||||||
return (ecma_get_object_from_value (x) == ecma_get_object_from_value (y));
|
bool is_x_equal_to_y = (x_num == y_num);
|
||||||
|
|
||||||
|
#ifndef JERRY_NDEBUG
|
||||||
|
bool is_x_equal_to_y_check;
|
||||||
|
|
||||||
|
if (ecma_number_is_nan (x_num)
|
||||||
|
|| ecma_number_is_nan (y_num))
|
||||||
|
{
|
||||||
|
is_x_equal_to_y_check = false;
|
||||||
|
}
|
||||||
|
else if (x_num == y_num
|
||||||
|
|| (ecma_number_is_zero (x_num)
|
||||||
|
&& ecma_number_is_zero (y_num)))
|
||||||
|
{
|
||||||
|
is_x_equal_to_y_check = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
is_x_equal_to_y_check = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
JERRY_ASSERT (is_x_equal_to_y == is_x_equal_to_y_check);
|
||||||
|
#endif /* !JERRY_NDEBUG */
|
||||||
|
|
||||||
|
return is_x_equal_to_y;
|
||||||
} /* ecma_op_strict_equality_compare */
|
} /* ecma_op_strict_equality_compare */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -47,29 +47,13 @@ opfunc_equal_value (ecma_value_t left_value, /**< left value */
|
|||||||
JERRY_ASSERT (!ecma_is_value_error (left_value)
|
JERRY_ASSERT (!ecma_is_value_error (left_value)
|
||||||
&& !ecma_is_value_error (right_value));
|
&& !ecma_is_value_error (right_value));
|
||||||
|
|
||||||
if (ecma_are_values_integer_numbers (left_value, right_value))
|
ecma_value_t compare_result = ecma_op_abstract_equality_compare (left_value,
|
||||||
{
|
right_value);
|
||||||
if (left_value == right_value)
|
|
||||||
{
|
|
||||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
|
|
||||||
}
|
|
||||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
JERRY_ASSERT (ecma_is_value_boolean (compare_result)
|
||||||
|
|| ecma_is_value_error (compare_result));
|
||||||
|
|
||||||
ECMA_TRY_CATCH (compare_result,
|
return compare_result;
|
||||||
ecma_op_abstract_equality_compare (left_value,
|
|
||||||
right_value),
|
|
||||||
ret_value);
|
|
||||||
|
|
||||||
JERRY_ASSERT (ecma_is_value_boolean (compare_result));
|
|
||||||
|
|
||||||
ret_value = compare_result;
|
|
||||||
|
|
||||||
ECMA_FINALIZE (compare_result);
|
|
||||||
|
|
||||||
return ret_value;
|
|
||||||
} /* opfunc_equal_value */
|
} /* opfunc_equal_value */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -87,93 +71,20 @@ opfunc_not_equal_value (ecma_value_t left_value, /**< left value */
|
|||||||
JERRY_ASSERT (!ecma_is_value_error (left_value)
|
JERRY_ASSERT (!ecma_is_value_error (left_value)
|
||||||
&& !ecma_is_value_error (right_value));
|
&& !ecma_is_value_error (right_value));
|
||||||
|
|
||||||
if (ecma_are_values_integer_numbers (left_value, right_value))
|
ecma_value_t compare_result = ecma_op_abstract_equality_compare (left_value,
|
||||||
|
right_value);
|
||||||
|
|
||||||
|
JERRY_ASSERT (ecma_is_value_boolean (compare_result)
|
||||||
|
|| ecma_is_value_error (compare_result));
|
||||||
|
|
||||||
|
if (!ecma_is_value_error (compare_result))
|
||||||
{
|
{
|
||||||
if (left_value == right_value)
|
compare_result = ecma_invert_boolean_value (compare_result);
|
||||||
{
|
|
||||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
|
|
||||||
}
|
|
||||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
return compare_result;
|
||||||
|
|
||||||
ECMA_TRY_CATCH (compare_result,
|
|
||||||
ecma_op_abstract_equality_compare (left_value, right_value),
|
|
||||||
ret_value);
|
|
||||||
|
|
||||||
JERRY_ASSERT (ecma_is_value_boolean (compare_result));
|
|
||||||
|
|
||||||
bool is_equal = ecma_is_value_true (compare_result);
|
|
||||||
|
|
||||||
ret_value = ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_FALSE
|
|
||||||
: ECMA_SIMPLE_VALUE_TRUE);
|
|
||||||
|
|
||||||
ECMA_FINALIZE (compare_result);
|
|
||||||
|
|
||||||
return ret_value;
|
|
||||||
} /* opfunc_not_equal_value */
|
} /* opfunc_not_equal_value */
|
||||||
|
|
||||||
/**
|
|
||||||
* 'Strict Equals' opcode handler.
|
|
||||||
*
|
|
||||||
* See also: ECMA-262 v5, 11.9.4
|
|
||||||
*
|
|
||||||
* @return ecma value
|
|
||||||
* Returned value must be freed with ecma_free_value
|
|
||||||
*/
|
|
||||||
ecma_value_t
|
|
||||||
opfunc_equal_value_type (ecma_value_t left_value, /**< left value */
|
|
||||||
ecma_value_t right_value) /**< right value */
|
|
||||||
{
|
|
||||||
JERRY_ASSERT (!ecma_is_value_error (left_value)
|
|
||||||
&& !ecma_is_value_error (right_value));
|
|
||||||
|
|
||||||
if (ecma_are_values_integer_numbers (left_value, right_value))
|
|
||||||
{
|
|
||||||
if (left_value == right_value)
|
|
||||||
{
|
|
||||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
|
|
||||||
}
|
|
||||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_equal = ecma_op_strict_equality_compare (left_value, right_value);
|
|
||||||
|
|
||||||
return ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_TRUE
|
|
||||||
: ECMA_SIMPLE_VALUE_FALSE);
|
|
||||||
} /* opfunc_equal_value_type */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 'Strict Does-not-equals' opcode handler.
|
|
||||||
*
|
|
||||||
* See also: ECMA-262 v5, 11.9.5
|
|
||||||
*
|
|
||||||
* @return ecma value
|
|
||||||
* Returned value must be freed with ecma_free_value
|
|
||||||
*/
|
|
||||||
ecma_value_t
|
|
||||||
opfunc_not_equal_value_type (ecma_value_t left_value, /**< left value */
|
|
||||||
ecma_value_t right_value) /**< right value */
|
|
||||||
{
|
|
||||||
JERRY_ASSERT (!ecma_is_value_error (left_value)
|
|
||||||
&& !ecma_is_value_error (right_value));
|
|
||||||
|
|
||||||
if (ecma_are_values_integer_numbers (left_value, right_value))
|
|
||||||
{
|
|
||||||
if (left_value == right_value)
|
|
||||||
{
|
|
||||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
|
|
||||||
}
|
|
||||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_equal = ecma_op_strict_equality_compare (left_value, right_value);
|
|
||||||
|
|
||||||
return ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_FALSE
|
|
||||||
: ECMA_SIMPLE_VALUE_TRUE);
|
|
||||||
} /* opfunc_not_equal_value_type */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
* @}
|
* @}
|
||||||
|
|||||||
@@ -62,12 +62,6 @@ opfunc_equal_value (ecma_value_t, ecma_value_t);
|
|||||||
ecma_value_t
|
ecma_value_t
|
||||||
opfunc_not_equal_value (ecma_value_t, ecma_value_t);
|
opfunc_not_equal_value (ecma_value_t, ecma_value_t);
|
||||||
|
|
||||||
ecma_value_t
|
|
||||||
opfunc_equal_value_type (ecma_value_t, ecma_value_t);
|
|
||||||
|
|
||||||
ecma_value_t
|
|
||||||
opfunc_not_equal_value_type (ecma_value_t, ecma_value_t);
|
|
||||||
|
|
||||||
ecma_value_t
|
ecma_value_t
|
||||||
do_number_arithmetic (number_arithmetic_op, ecma_value_t, ecma_value_t);
|
do_number_arithmetic (number_arithmetic_op, ecma_value_t, ecma_value_t);
|
||||||
|
|
||||||
|
|||||||
+8
-25
@@ -19,6 +19,7 @@
|
|||||||
#include "ecma-alloc.h"
|
#include "ecma-alloc.h"
|
||||||
#include "ecma-array-object.h"
|
#include "ecma-array-object.h"
|
||||||
#include "ecma-builtins.h"
|
#include "ecma-builtins.h"
|
||||||
|
#include "ecma-comparison.h"
|
||||||
#include "ecma-conversion.h"
|
#include "ecma-conversion.h"
|
||||||
#include "ecma-exceptions.h"
|
#include "ecma-exceptions.h"
|
||||||
#include "ecma-function-object.h"
|
#include "ecma-function-object.h"
|
||||||
@@ -1483,17 +1484,7 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
|||||||
{
|
{
|
||||||
JERRY_ASSERT (stack_top_p > frame_ctx_p->registers_p + register_end);
|
JERRY_ASSERT (stack_top_p > frame_ctx_p->registers_p + register_end);
|
||||||
|
|
||||||
last_completion_value = opfunc_equal_value_type (left_value,
|
if (ecma_op_strict_equality_compare (left_value, stack_top_p[-1]))
|
||||||
stack_top_p[-1]);
|
|
||||||
|
|
||||||
if (ecma_is_value_error (last_completion_value))
|
|
||||||
{
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = last_completion_value;
|
|
||||||
|
|
||||||
if (result == ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE))
|
|
||||||
{
|
{
|
||||||
byte_code_p = byte_code_start_p + branch_offset;
|
byte_code_p = byte_code_start_p + branch_offset;
|
||||||
ecma_free_value (*--stack_top_p);
|
ecma_free_value (*--stack_top_p);
|
||||||
@@ -1726,26 +1717,18 @@ vm_loop (vm_frame_ctx_t *frame_ctx_p) /**< frame context */
|
|||||||
}
|
}
|
||||||
case VM_OC_STRICT_EQUAL:
|
case VM_OC_STRICT_EQUAL:
|
||||||
{
|
{
|
||||||
last_completion_value = opfunc_equal_value_type (left_value, right_value);
|
bool is_equal = ecma_op_strict_equality_compare (left_value, right_value);
|
||||||
|
|
||||||
if (ecma_is_value_error (last_completion_value))
|
result = ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_TRUE
|
||||||
{
|
: ECMA_SIMPLE_VALUE_FALSE);
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = last_completion_value;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VM_OC_STRICT_NOT_EQUAL:
|
case VM_OC_STRICT_NOT_EQUAL:
|
||||||
{
|
{
|
||||||
last_completion_value = opfunc_not_equal_value_type (left_value, right_value);
|
bool is_equal = ecma_op_strict_equality_compare (left_value, right_value);
|
||||||
|
|
||||||
if (ecma_is_value_error (last_completion_value))
|
result = ecma_make_simple_value (is_equal ? ECMA_SIMPLE_VALUE_FALSE
|
||||||
{
|
: ECMA_SIMPLE_VALUE_TRUE);
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = last_completion_value;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VM_OC_BIT_OR:
|
case VM_OC_BIT_OR:
|
||||||
|
|||||||
Reference in New Issue
Block a user