Implement relational operators for BigInts (#4087)
Improve BigInt constructor as well JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "ecma-bigint.h"
|
||||
#include "ecma-comparison.h"
|
||||
#include "ecma-conversion.h"
|
||||
#include "ecma-globals.h"
|
||||
@@ -131,13 +132,6 @@ ecma_op_abstract_equality_compare (ecma_value_t x, /**< first operand */
|
||||
y = tmp;
|
||||
}
|
||||
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
if (ecma_is_value_symbol (x))
|
||||
{
|
||||
return ECMA_VALUE_FALSE;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
|
||||
if (ecma_is_value_boolean (y))
|
||||
{
|
||||
if (ecma_is_value_boolean (x))
|
||||
@@ -167,12 +161,57 @@ ecma_op_abstract_equality_compare (ecma_value_t x, /**< first operand */
|
||||
return ecma_make_boolean_value (is_equal);
|
||||
}
|
||||
|
||||
#if ENABLED (JERRY_BUILTIN_BIGINT)
|
||||
if (JERRY_UNLIKELY (ecma_is_value_bigint (x)))
|
||||
{
|
||||
if (ecma_is_value_bigint (y))
|
||||
{
|
||||
return ecma_make_boolean_value (ecma_bigint_is_equal_to_bigint (x, y));
|
||||
}
|
||||
|
||||
if (ecma_is_value_string (y))
|
||||
{
|
||||
ecma_value_t bigint = ecma_bigint_parse_string_value (y, false);
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (bigint)
|
||||
|| bigint == ECMA_VALUE_FALSE)
|
||||
{
|
||||
return bigint;
|
||||
}
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_bigint (bigint));
|
||||
|
||||
ecma_value_t result = ecma_make_boolean_value (ecma_bigint_is_equal_to_bigint (x, bigint));
|
||||
|
||||
ecma_free_value (bigint);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (ecma_is_value_number (y))
|
||||
{
|
||||
return ecma_make_boolean_value (ecma_bigint_is_equal_to_number (x, ecma_get_number_from_value (y)));
|
||||
}
|
||||
|
||||
return ECMA_VALUE_FALSE;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */
|
||||
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
if (JERRY_UNLIKELY (ecma_is_value_symbol (x)))
|
||||
{
|
||||
return ECMA_VALUE_FALSE;
|
||||
}
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_object (x));
|
||||
|
||||
if (ecma_is_value_string (y)
|
||||
#if ENABLED (JERRY_ESNEXT)
|
||||
|| ecma_is_value_symbol (y)
|
||||
#endif /* ENABLED (JERRY_ESNEXT) */
|
||||
#if ENABLED (JERRY_BUILTIN_BIGINT)
|
||||
|| ecma_is_value_bigint (y)
|
||||
#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */
|
||||
|| ecma_is_value_number (y))
|
||||
{
|
||||
/* 9. */
|
||||
@@ -237,8 +276,8 @@ ecma_op_strict_equality_compare (ecma_value_t x, /**< first operand */
|
||||
/* The +0 === -0 case handled below. */
|
||||
}
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_number (x) || ecma_is_value_string (x));
|
||||
JERRY_ASSERT (ecma_is_value_number (y) || ecma_is_value_string (y));
|
||||
JERRY_ASSERT (ecma_is_value_number (x) || ecma_is_value_string (x) || ECMA_CHECK_BIGINT_IN_ASSERT (x));
|
||||
JERRY_ASSERT (ecma_is_value_number (y) || ecma_is_value_string (y) || ECMA_CHECK_BIGINT_IN_ASSERT (y));
|
||||
|
||||
if (ecma_is_value_string (x))
|
||||
{
|
||||
@@ -253,6 +292,18 @@ ecma_op_strict_equality_compare (ecma_value_t x, /**< first operand */
|
||||
return ecma_compare_ecma_strings (x_str_p, y_str_p);
|
||||
}
|
||||
|
||||
#if ENABLED (JERRY_BUILTIN_BIGINT)
|
||||
if (JERRY_UNLIKELY (ecma_is_value_bigint (x)))
|
||||
{
|
||||
if (!ecma_is_value_bigint (y))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return ecma_bigint_is_equal_to_bigint (x, y);
|
||||
}
|
||||
#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */
|
||||
|
||||
if (!ecma_is_value_number (y))
|
||||
{
|
||||
return false;
|
||||
@@ -317,93 +368,164 @@ ecma_op_abstract_relational_compare (ecma_value_t x, /**< first operand */
|
||||
return prim_second_converted_value;
|
||||
}
|
||||
|
||||
const ecma_value_t px = left_first ? prim_first_converted_value : prim_second_converted_value;
|
||||
const ecma_value_t py = left_first ? prim_second_converted_value : prim_first_converted_value;
|
||||
ecma_value_t px = left_first ? prim_first_converted_value : prim_second_converted_value;
|
||||
ecma_value_t py = left_first ? prim_second_converted_value : prim_first_converted_value;
|
||||
|
||||
const bool is_px_string = ecma_is_value_string (px);
|
||||
const bool is_py_string = ecma_is_value_string (py);
|
||||
|
||||
if (!(is_px_string && is_py_string))
|
||||
{
|
||||
/* 3. */
|
||||
|
||||
/* a. */
|
||||
ECMA_OP_TO_NUMBER_TRY_CATCH (nx, px, ret_value);
|
||||
ECMA_OP_TO_NUMBER_TRY_CATCH (ny, py, ret_value);
|
||||
|
||||
/* b. */
|
||||
if (ecma_number_is_nan (nx)
|
||||
|| ecma_number_is_nan (ny))
|
||||
#if ENABLED (JERRY_BUILTIN_BIGINT)
|
||||
if (JERRY_LIKELY (!ecma_is_value_bigint (px))
|
||||
&& JERRY_LIKELY (!ecma_is_value_bigint (py)))
|
||||
{
|
||||
/* c., d. */
|
||||
ret_value = ECMA_VALUE_UNDEFINED;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool is_x_less_than_y = (nx < ny);
|
||||
#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */
|
||||
/* 3. */
|
||||
|
||||
#ifndef JERRY_NDEBUG
|
||||
bool is_x_less_than_y_check;
|
||||
/* a. */
|
||||
ECMA_OP_TO_NUMBER_TRY_CATCH (nx, px, ret_value);
|
||||
ECMA_OP_TO_NUMBER_TRY_CATCH (ny, py, ret_value);
|
||||
|
||||
if (nx == ny
|
||||
|| (ecma_number_is_zero (nx)
|
||||
&& ecma_number_is_zero (ny)))
|
||||
/* b. */
|
||||
if (ecma_number_is_nan (nx)
|
||||
|| ecma_number_is_nan (ny))
|
||||
{
|
||||
/* e., f., g. */
|
||||
is_x_less_than_y_check = false;
|
||||
}
|
||||
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 (ny)
|
||||
&& !ecma_number_is_negative (ny))
|
||||
{
|
||||
/* i. */
|
||||
is_x_less_than_y_check = true;
|
||||
}
|
||||
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 (nx)
|
||||
&& ecma_number_is_negative (nx))
|
||||
{
|
||||
/* k. */
|
||||
is_x_less_than_y_check = true;
|
||||
/* c., d. */
|
||||
ret_value = ECMA_VALUE_UNDEFINED;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* l. */
|
||||
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)));
|
||||
bool is_x_less_than_y = (nx < ny);
|
||||
|
||||
if (nx < ny)
|
||||
#ifndef JERRY_NDEBUG
|
||||
bool is_x_less_than_y_check;
|
||||
|
||||
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 (nx)
|
||||
&& !ecma_number_is_negative (nx))
|
||||
{
|
||||
/* h. */
|
||||
is_x_less_than_y_check = false;
|
||||
}
|
||||
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 (ny)
|
||||
&& ecma_number_is_negative (ny))
|
||||
{
|
||||
/* j. */
|
||||
is_x_less_than_y_check = false;
|
||||
}
|
||||
else if (ecma_number_is_infinity (nx)
|
||||
&& ecma_number_is_negative (nx))
|
||||
{
|
||||
/* k. */
|
||||
is_x_less_than_y_check = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
is_x_less_than_y_check = false;
|
||||
}
|
||||
}
|
||||
/* l. */
|
||||
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)));
|
||||
|
||||
JERRY_ASSERT (is_x_less_than_y_check == is_x_less_than_y);
|
||||
if (nx < ny)
|
||||
{
|
||||
is_x_less_than_y_check = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
is_x_less_than_y_check = false;
|
||||
}
|
||||
}
|
||||
|
||||
JERRY_ASSERT (is_x_less_than_y_check == is_x_less_than_y);
|
||||
#endif /* !JERRY_NDEBUG */
|
||||
|
||||
ret_value = ecma_make_boolean_value (is_x_less_than_y);
|
||||
}
|
||||
ret_value = ecma_make_boolean_value (is_x_less_than_y);
|
||||
}
|
||||
|
||||
ECMA_OP_TO_NUMBER_FINALIZE (ny);
|
||||
ECMA_OP_TO_NUMBER_FINALIZE (nx);
|
||||
ECMA_OP_TO_NUMBER_FINALIZE (ny);
|
||||
ECMA_OP_TO_NUMBER_FINALIZE (nx);
|
||||
#if ENABLED (JERRY_BUILTIN_BIGINT)
|
||||
}
|
||||
else
|
||||
{
|
||||
bool invert_result = false;
|
||||
int compare_result = 0;
|
||||
|
||||
if (!ecma_is_value_bigint (px))
|
||||
{
|
||||
ecma_value_t tmp = px;
|
||||
px = py;
|
||||
py = tmp;
|
||||
invert_result = true;
|
||||
}
|
||||
|
||||
JERRY_ASSERT (ecma_is_value_bigint (px));
|
||||
|
||||
if (ecma_is_value_bigint (py))
|
||||
{
|
||||
compare_result = ecma_bigint_compare_to_bigint (px, py);
|
||||
}
|
||||
else if (ecma_is_value_string (py))
|
||||
{
|
||||
ret_value = ecma_bigint_parse_string_value (py, false);
|
||||
|
||||
if (!ECMA_IS_VALUE_ERROR (ret_value))
|
||||
{
|
||||
if (ret_value == ECMA_VALUE_FALSE)
|
||||
{
|
||||
ret_value = ECMA_VALUE_UNDEFINED;
|
||||
}
|
||||
else
|
||||
{
|
||||
compare_result = ecma_bigint_compare_to_bigint (px, ret_value);
|
||||
ecma_free_value (ret_value);
|
||||
ret_value = ECMA_VALUE_EMPTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ECMA_OP_TO_NUMBER_TRY_CATCH (ny, py, ret_value);
|
||||
|
||||
if (ecma_number_is_nan (ny))
|
||||
{
|
||||
ret_value = ECMA_VALUE_UNDEFINED;
|
||||
}
|
||||
else
|
||||
{
|
||||
compare_result = ecma_bigint_compare_to_number (px, ny);
|
||||
}
|
||||
|
||||
ECMA_OP_TO_NUMBER_FINALIZE (ny);
|
||||
}
|
||||
|
||||
if (ret_value == ECMA_VALUE_EMPTY)
|
||||
{
|
||||
if (invert_result)
|
||||
{
|
||||
compare_result = -compare_result;
|
||||
}
|
||||
|
||||
ret_value = ecma_make_boolean_value (compare_result < 0);
|
||||
}
|
||||
}
|
||||
#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */
|
||||
}
|
||||
else
|
||||
{ /* 4. */
|
||||
|
||||
Reference in New Issue
Block a user