diff --git a/jerry-core/ecma/base/ecma-globals.h b/jerry-core/ecma/base/ecma-globals.h
index a800c4ad0..64b38da59 100644
--- a/jerry-core/ecma/base/ecma-globals.h
+++ b/jerry-core/ecma/base/ecma-globals.h
@@ -2112,6 +2112,16 @@ typedef uint32_t ecma_length_t;
*/
typedef uint32_t ecma_bigint_digit_t;
+/**
+ * Special BigInt value representing zero.
+ */
+#define ECMA_BIGINT_ZERO ((ecma_value_t) ECMA_TYPE_BIGINT)
+
+/**
+ * Special BigInt value representing zero when the result is pointer.
+ */
+#define ECMA_BIGINT_POINTER_TO_ZERO ((ecma_extended_primitive_t *) 0x1)
+
/**
* Return the size of a BigInt value in ecma_bigint_data_t units.
*/
diff --git a/jerry-core/ecma/base/ecma-helpers-value.c b/jerry-core/ecma/base/ecma-helpers-value.c
index e6e955f90..deb826404 100644
--- a/jerry-core/ecma/base/ecma-helpers-value.c
+++ b/jerry-core/ecma/base/ecma-helpers-value.c
@@ -56,6 +56,13 @@ JERRY_STATIC_ASSERT ((ECMA_VALUE_FALSE | (1 << ECMA_DIRECT_SHIFT)) == ECMA_VALUE
&& ECMA_VALUE_FALSE != ECMA_VALUE_TRUE,
only_the_lowest_bit_must_be_different_for_simple_value_true_and_false);
+#if ENABLED (JERRY_BUILTIN_BIGINT)
+
+JERRY_STATIC_ASSERT (ECMA_NULL_POINTER == (ECMA_BIGINT_ZERO & ~(ecma_value_t) ECMA_VALUE_TYPE_MASK),
+ ecma_bigint_zero_must_be_encoded_as_null_pointer);
+
+#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */
+
/** \addtogroup ecma ECMA
* @{
*
@@ -707,6 +714,9 @@ ecma_make_extended_primitive_value (const ecma_extended_primitive_t *primitve_p,
uint32_t type) /**< ecma type of extended primitve value */
{
JERRY_ASSERT (primitve_p != NULL);
+#if ENABLED (JERRY_BUILTIN_BIGINT)
+ JERRY_ASSERT (primitve_p != ECMA_BIGINT_POINTER_TO_ZERO);
+#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */
JERRY_ASSERT (type == ECMA_TYPE_BIGINT || type == ECMA_TYPE_ERROR);
return ecma_pointer_to_ecma_value (primitve_p) | type;
@@ -839,6 +849,9 @@ ecma_get_object_from_value (ecma_value_t value) /**< ecma value */
inline ecma_extended_primitive_t *JERRY_ATTR_PURE JERRY_ATTR_ALWAYS_INLINE
ecma_get_extended_primitive_from_value (ecma_value_t value) /**< ecma value */
{
+#if ENABLED (JERRY_BUILTIN_BIGINT)
+ JERRY_ASSERT (value != ECMA_BIGINT_ZERO);
+#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */
JERRY_ASSERT (ecma_get_value_type_field (value) == ECMA_TYPE_BIGINT
|| ecma_get_value_type_field (value) == ECMA_TYPE_ERROR);
@@ -889,7 +902,10 @@ ecma_copy_value (ecma_value_t value) /**< value description */
#if ENABLED (JERRY_BUILTIN_BIGINT)
case ECMA_TYPE_BIGINT:
{
- ecma_ref_extended_primitive (ecma_get_extended_primitive_from_value (value));
+ if (value != ECMA_BIGINT_ZERO)
+ {
+ ecma_ref_extended_primitive (ecma_get_extended_primitive_from_value (value));
+ }
return value;
}
#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */
@@ -1123,7 +1139,10 @@ ecma_free_value (ecma_value_t value) /**< value description */
#if ENABLED (JERRY_BUILTIN_BIGINT)
case ECMA_TYPE_BIGINT:
{
- ecma_deref_bigint (ecma_get_extended_primitive_from_value (value));
+ if (value != ECMA_BIGINT_ZERO)
+ {
+ ecma_deref_bigint (ecma_get_extended_primitive_from_value (value));
+ }
break;
}
#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */
diff --git a/jerry-core/ecma/base/ecma-literal-storage.c b/jerry-core/ecma/base/ecma-literal-storage.c
index 1b0caa2c1..c47be6756 100644
--- a/jerry-core/ecma/base/ecma-literal-storage.c
+++ b/jerry-core/ecma/base/ecma-literal-storage.c
@@ -318,6 +318,11 @@ ecma_find_or_create_literal_bigint (ecma_value_t bigint) /**< bigint to be searc
{
JERRY_ASSERT (ecma_is_value_bigint (bigint));
+ if (bigint == ECMA_BIGINT_ZERO)
+ {
+ return bigint;
+ }
+
jmem_cpointer_t bigint_list_cp = JERRY_CONTEXT (bigint_list_first_cp);
jmem_cpointer_t *empty_cpointer_p = NULL;
@@ -416,7 +421,7 @@ void ecma_save_literals_append_value (ecma_value_t value, /**< value to be appen
/* Unlike direct numbers, direct strings are converted to character literals. */
if (!ecma_is_value_string (value)
#if ENABLED (JERRY_BUILTIN_BIGINT)
- && !ecma_is_value_bigint (value)
+ && (!ecma_is_value_bigint (value) || value == ECMA_BIGINT_ZERO)
#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */
&& !ecma_is_value_float_number (value))
{
diff --git a/jerry-core/ecma/operations/ecma-big-uint.c b/jerry-core/ecma/operations/ecma-big-uint.c
index e33fac983..5a18ebf28 100644
--- a/jerry-core/ecma/operations/ecma-big-uint.c
+++ b/jerry-core/ecma/operations/ecma-big-uint.c
@@ -37,6 +37,7 @@ JERRY_STATIC_ASSERT ((ECMA_BIG_UINT_BITWISE_DECREASE_LEFT << 1) == ECMA_BIG_UINT
ecma_extended_primitive_t *
ecma_bigint_create (uint32_t size) /**< size of the new BigInt value */
{
+ JERRY_ASSERT (size > 0);
JERRY_ASSERT ((size % sizeof (ecma_bigint_digit_t)) == 0);
if (JERRY_UNLIKELY (size > ECMA_BIGINT_MAX_SIZE))
@@ -46,15 +47,8 @@ ecma_bigint_create (uint32_t size) /**< size of the new BigInt value */
ecma_extended_primitive_t *value_p;
- if (size == 0)
- {
- value_p = (ecma_extended_primitive_t *) jmem_pools_alloc (sizeof (ecma_extended_primitive_t));
- }
- else
- {
- size_t mem_size = ECMA_BIGINT_GET_BYTE_SIZE (size) + sizeof (ecma_extended_primitive_t);
- value_p = (ecma_extended_primitive_t *) jmem_heap_alloc_block_null_on_error (mem_size);
- }
+ size_t mem_size = ECMA_BIGINT_GET_BYTE_SIZE (size) + sizeof (ecma_extended_primitive_t);
+ value_p = (ecma_extended_primitive_t *) jmem_heap_alloc_block_null_on_error (mem_size);
if (JERRY_UNLIKELY (value_p == NULL))
{
@@ -111,6 +105,12 @@ ecma_big_uint_shrink_value (ecma_extended_primitive_t *value_p, /**< BigUInt val
JERRY_ASSERT (value_p != NULL);
JERRY_ASSERT (ECMA_BIGINT_GET_SIZE (value_p) > new_size);
+ if (new_size == 0)
+ {
+ ecma_deref_bigint (value_p);
+ return ECMA_BIGINT_POINTER_TO_ZERO;
+ }
+
if (ECMA_BIGINT_SIZE_IS_ODD (new_size)
&& ((new_size + sizeof (ecma_bigint_digit_t)) == ECMA_BIGINT_GET_SIZE (value_p)))
{
@@ -804,7 +804,7 @@ ecma_big_uint_div_digit (ecma_extended_primitive_t *left_value_p, /**< left BigU
if (remainder == 0)
{
- return ecma_bigint_create (0);
+ return ECMA_BIGINT_POINTER_TO_ZERO;
}
result_p = ecma_bigint_create (sizeof (ecma_bigint_digit_t));
@@ -1100,33 +1100,38 @@ ecma_big_uint_div_mod (ecma_extended_primitive_t *dividend_value_p, /**< divider
}
}
- result_p = ecma_bigint_create ((uint32_t) ((uint8_t *) source_end_p - (uint8_t *) source_p));
+ result_p = ECMA_BIGINT_POINTER_TO_ZERO;
- if (result_p != NULL && source_p != source_end_p)
+ if (source_p < source_end_p)
{
- ecma_bigint_digit_t *destination_p = ECMA_BIGINT_GET_DIGITS (result_p, 0);
+ result_p = ecma_bigint_create ((uint32_t) ((uint8_t *) source_end_p - (uint8_t *) source_p));
- if (is_mod && shift_left > 0)
+ if (result_p != NULL)
{
- ecma_bigint_digit_t shift_right = shift_left;
+ ecma_bigint_digit_t *destination_p = ECMA_BIGINT_GET_DIGITS (result_p, 0);
- shift_left = (ecma_bigint_digit_t) (8 * (sizeof (ecma_bigint_digit_t)) - shift_left);
- destination_p += source_end_p - source_p;
-
- ecma_bigint_digit_t carry = *source_end_p << shift_left;
-
- do
+ if (is_mod && shift_left > 0)
{
- ecma_bigint_digit_t value = *(--source_end_p);
+ ecma_bigint_digit_t shift_right = shift_left;
- *(--destination_p) = (value >> shift_right) | carry;
- carry = value << shift_left;
+ shift_left = (ecma_bigint_digit_t) (8 * (sizeof (ecma_bigint_digit_t)) - shift_left);
+ destination_p += source_end_p - source_p;
+
+ ecma_bigint_digit_t carry = *source_end_p << shift_left;
+
+ do
+ {
+ ecma_bigint_digit_t value = *(--source_end_p);
+
+ *(--destination_p) = (value >> shift_right) | carry;
+ carry = value << shift_left;
+ }
+ while (source_end_p > source_p);
+ }
+ else
+ {
+ memcpy (destination_p, source_p, (size_t) ((uint8_t *) source_end_p - (uint8_t *) source_p));
}
- while (source_end_p > source_p);
- }
- else
- {
- memcpy (destination_p, source_p, (size_t) ((uint8_t *) source_end_p - (uint8_t *) source_p));
}
}
@@ -1243,7 +1248,7 @@ ecma_big_uint_shift_right (ecma_extended_primitive_t *left_value_p, /**< left B
if (left_size <= crop_size)
{
- return ecma_bigint_create (0);
+ return ECMA_BIGINT_POINTER_TO_ZERO;
}
uint32_t size = left_size - crop_size;
diff --git a/jerry-core/ecma/operations/ecma-bigint.c b/jerry-core/ecma/operations/ecma-bigint.c
index 8da8be0a6..b6d2d6d31 100644
--- a/jerry-core/ecma/operations/ecma-bigint.c
+++ b/jerry-core/ecma/operations/ecma-bigint.c
@@ -102,52 +102,49 @@ ecma_bigint_parse_string (const lit_utf8_byte_t *string_p, /**< string represena
if (string_p == string_end_p)
{
- sign = 0;
- result_p = ecma_bigint_create (0);
+ return ECMA_BIGINT_ZERO;
}
- else
+
+ do
{
- do
+ ecma_bigint_digit_t digit = radix;
+
+ if (*string_p >= LIT_CHAR_0 && *string_p <= LIT_CHAR_9)
{
- ecma_bigint_digit_t digit = radix;
+ digit = (ecma_bigint_digit_t) (*string_p - LIT_CHAR_0);
+ }
+ else
+ {
+ lit_utf8_byte_t character = (lit_utf8_byte_t) LEXER_TO_ASCII_LOWERCASE (*string_p);
- if (*string_p >= LIT_CHAR_0 && *string_p <= LIT_CHAR_9)
+ if (character >= LIT_CHAR_LOWERCASE_A && character <= LIT_CHAR_LOWERCASE_F)
{
- digit = (ecma_bigint_digit_t) (*string_p - LIT_CHAR_0);
- }
- else
- {
- lit_utf8_byte_t character = (lit_utf8_byte_t) LEXER_TO_ASCII_LOWERCASE (*string_p);
-
- if (character >= LIT_CHAR_LOWERCASE_A && character <= LIT_CHAR_LOWERCASE_F)
- {
- digit = (ecma_bigint_digit_t) (character - (LIT_CHAR_LOWERCASE_A - 10));
- }
- }
-
- if (digit >= radix)
- {
- if (result_p != NULL)
- {
- ecma_deref_bigint (result_p);
- }
-
- if (options & ECMA_BIGINT_PARSE_DISALLOW_SYNTAX_ERROR)
- {
- return ECMA_VALUE_FALSE;
- }
- return ecma_raise_syntax_error (ECMA_ERR_MSG ("String cannot be converted to BigInt value"));
- }
-
- result_p = ecma_big_uint_mul_digit (result_p, radix, digit);
-
- if (JERRY_UNLIKELY (result_p == NULL))
- {
- break;
+ digit = (ecma_bigint_digit_t) (character - (LIT_CHAR_LOWERCASE_A - 10));
}
}
- while (++string_p < string_end_p);
+
+ if (digit >= radix)
+ {
+ if (result_p != NULL)
+ {
+ ecma_deref_bigint (result_p);
+ }
+
+ if (options & ECMA_BIGINT_PARSE_DISALLOW_SYNTAX_ERROR)
+ {
+ return ECMA_VALUE_FALSE;
+ }
+ return ecma_raise_syntax_error (ECMA_ERR_MSG ("String cannot be converted to BigInt value"));
+ }
+
+ result_p = ecma_big_uint_mul_digit (result_p, radix, digit);
+
+ if (JERRY_UNLIKELY (result_p == NULL))
+ {
+ break;
+ }
}
+ while (++string_p < string_end_p);
if (JERRY_UNLIKELY (result_p == NULL))
{
@@ -193,14 +190,13 @@ ecma_bigint_to_string (ecma_value_t value, /**< BigInt value */
{
JERRY_ASSERT (ecma_is_value_bigint (value));
- ecma_extended_primitive_t *bigint_p = ecma_get_extended_primitive_from_value (value);
-
- if (ECMA_BIGINT_GET_SIZE (bigint_p) == 0)
+ if (value == ECMA_BIGINT_ZERO)
{
return ecma_new_ecma_string_from_code_unit (LIT_CHAR_0);
}
uint32_t char_start_p, char_size_p;
+ ecma_extended_primitive_t *bigint_p = ecma_get_extended_primitive_from_value (value);
lit_utf8_byte_t *string_buffer_p = ecma_big_uint_to_string (bigint_p, radix, &char_start_p, &char_size_p);
if (JERRY_UNLIKELY (string_buffer_p == NULL))
@@ -364,6 +360,12 @@ ecma_bigint_number_to_bigint (ecma_number_t number) /**< ecma number */
}
uint32_t digits_size = ECMA_BIGINT_NUMBER_TO_DIGITS_GET_DIGITS_SIZE (result);
+
+ if (digits_size == 0)
+ {
+ return ECMA_BIGINT_ZERO;
+ }
+
uint32_t zero_size = ECMA_BIGINT_NUMBER_TO_DIGITS_GET_ZERO_SIZE (result);
ecma_extended_primitive_t *result_p = ecma_bigint_create (digits_size + zero_size);
@@ -373,16 +375,13 @@ ecma_bigint_number_to_bigint (ecma_number_t number) /**< ecma number */
return ecma_bigint_raise_memory_error ();
}
- if (digits_size > 0)
- {
- uint8_t *data_p = (uint8_t *) ECMA_BIGINT_GET_DIGITS (result_p, 0);
- memset (data_p, 0, zero_size);
- memcpy (data_p + zero_size, digits, digits_size);
+ uint8_t *data_p = (uint8_t *) ECMA_BIGINT_GET_DIGITS (result_p, 0);
+ memset (data_p, 0, zero_size);
+ memcpy (data_p + zero_size, digits, digits_size);
- if (number < 0)
- {
- result_p->u.bigint_sign_and_size |= ECMA_BIGINT_SIGN;
- }
+ if (number < 0)
+ {
+ result_p->u.bigint_sign_and_size |= ECMA_BIGINT_SIGN;
}
return ecma_make_extended_primitive_value (result_p, ECMA_TYPE_BIGINT);
@@ -402,20 +401,19 @@ ecma_bigint_to_bigint (ecma_value_t value) /**< any value */
{
if (ecma_is_value_boolean (value))
{
- uint32_t size = ecma_is_value_true (value) ? sizeof (ecma_bigint_digit_t) : 0;
+ if (ecma_is_value_false (value))
+ {
+ return ECMA_BIGINT_ZERO;
+ }
- ecma_extended_primitive_t *result_p = ecma_bigint_create (size);
+ ecma_extended_primitive_t *result_p = ecma_bigint_create (sizeof (ecma_bigint_digit_t));
if (JERRY_UNLIKELY (result_p == NULL))
{
return ecma_bigint_raise_memory_error ();
}
- if (ecma_is_value_true (value))
- {
- *ECMA_BIGINT_GET_DIGITS (result_p, 0) = 1;
- }
-
+ *ECMA_BIGINT_GET_DIGITS (result_p, 0) = 1;
return ecma_make_extended_primitive_value (result_p, ECMA_TYPE_BIGINT);
}
@@ -438,6 +436,15 @@ ecma_bigint_is_equal_to_bigint (ecma_value_t left_value, /**< left BigInt value
{
JERRY_ASSERT (ecma_is_value_bigint (left_value) && ecma_is_value_bigint (right_value));
+ if (left_value == ECMA_BIGINT_ZERO)
+ {
+ return right_value == ECMA_BIGINT_ZERO;
+ }
+ else if (right_value == ECMA_BIGINT_ZERO)
+ {
+ return false;
+ }
+
ecma_extended_primitive_t *left_p = ecma_get_extended_primitive_from_value (left_value);
ecma_extended_primitive_t *right_p = ecma_get_extended_primitive_from_value (right_value);
@@ -466,14 +473,13 @@ ecma_bigint_is_equal_to_number (ecma_value_t left_value, /**< left BigInt value
return false;
}
- ecma_extended_primitive_t *left_value_p = ecma_get_extended_primitive_from_value (left_value);
- uint32_t left_size = ECMA_BIGINT_GET_SIZE (left_value_p);
-
- if (right_value == 0)
+ if (left_value == ECMA_BIGINT_ZERO)
{
- return left_size == 0;
+ return right_value == 0;
}
+ ecma_extended_primitive_t *left_value_p = ecma_get_extended_primitive_from_value (left_value);
+
/* Sign must be the same. */
if (left_value_p->u.bigint_sign_and_size & ECMA_BIGINT_SIGN)
{
@@ -501,7 +507,7 @@ ecma_bigint_is_equal_to_number (ecma_value_t left_value, /**< left BigInt value
uint32_t digits_size = ECMA_BIGINT_NUMBER_TO_DIGITS_GET_DIGITS_SIZE (result);
uint32_t zero_size = ECMA_BIGINT_NUMBER_TO_DIGITS_GET_ZERO_SIZE (result);
- if (left_size != digits_size + zero_size)
+ if (ECMA_BIGINT_GET_SIZE (left_value_p) != digits_size + zero_size)
{
return false;
}
@@ -568,12 +574,9 @@ ecma_bigint_compare_to_number (ecma_value_t left_value, /**< left BigInt value *
JERRY_ASSERT (ecma_is_value_bigint (left_value));
JERRY_ASSERT (!ecma_number_is_nan (right_value));
- ecma_extended_primitive_t *left_value_p = ecma_get_extended_primitive_from_value (left_value);
- uint32_t left_size = ECMA_BIGINT_GET_SIZE (left_value_p);
- int left_sign = ECMA_BIGINT_TO_SIGN (left_value_p->u.bigint_sign_and_size & ECMA_BIGINT_SIGN);
int right_invert_sign = ECMA_BIGINT_TO_SIGN (right_value > 0);
- if (left_size == 0)
+ if (left_value == ECMA_BIGINT_ZERO)
{
if (right_value == 0)
{
@@ -583,6 +586,9 @@ ecma_bigint_compare_to_number (ecma_value_t left_value, /**< left BigInt value *
return right_invert_sign;
}
+ ecma_extended_primitive_t *left_value_p = ecma_get_extended_primitive_from_value (left_value);
+ int left_sign = ECMA_BIGINT_TO_SIGN (left_value_p->u.bigint_sign_and_size & ECMA_BIGINT_SIGN);
+
if (right_value == 0 || left_sign == right_invert_sign)
{
/* Second condition: a positive BigInt is always greater than any negative number, and the opposite is true. */
@@ -610,6 +616,7 @@ ecma_bigint_compare_to_number (ecma_value_t left_value, /**< left BigInt value *
return left_sign;
}
+ uint32_t left_size = ECMA_BIGINT_GET_SIZE (left_value_p);
uint32_t right_size = digits_size + ECMA_BIGINT_NUMBER_TO_DIGITS_GET_ZERO_SIZE (result);
if (left_size != right_size)
@@ -688,18 +695,14 @@ ecma_bigint_add_sub (ecma_value_t left_value, /**< left BigInt value */
{
JERRY_ASSERT (ecma_is_value_bigint (left_value) && ecma_is_value_bigint (right_value));
- ecma_extended_primitive_t *left_p = ecma_get_extended_primitive_from_value (left_value);
- ecma_extended_primitive_t *right_p = ecma_get_extended_primitive_from_value (right_value);
- uint32_t left_size = ECMA_BIGINT_GET_SIZE (left_p);
- uint32_t right_size = ECMA_BIGINT_GET_SIZE (right_p);
-
- if (right_size == 0)
+ if (right_value == ECMA_BIGINT_ZERO)
{
- ecma_ref_extended_primitive (left_p);
- return left_value;
+ return ecma_copy_value (left_value);
}
- if (left_size == 0)
+ ecma_extended_primitive_t *right_p = ecma_get_extended_primitive_from_value (right_value);
+
+ if (left_value == ECMA_BIGINT_ZERO)
{
if (!is_add)
{
@@ -710,6 +713,7 @@ ecma_bigint_add_sub (ecma_value_t left_value, /**< left BigInt value */
return right_value;
}
+ ecma_extended_primitive_t *left_p = ecma_get_extended_primitive_from_value (left_value);
uint32_t sign = is_add ? 0 : ECMA_BIGINT_SIGN;
if (((left_p->u.bigint_sign_and_size ^ right_p->u.bigint_sign_and_size) & ECMA_BIGINT_SIGN) == sign)
@@ -730,10 +734,10 @@ ecma_bigint_add_sub (ecma_value_t left_value, /**< left BigInt value */
if (compare_result == 0)
{
- sign = 0;
- result_p = ecma_bigint_create (0);
+ return ECMA_BIGINT_ZERO;
}
- else if (compare_result > 0)
+
+ if (compare_result > 0)
{
sign = left_p->u.bigint_sign_and_size & ECMA_BIGINT_SIGN;
result_p = ecma_big_uint_sub (left_p, right_p);
@@ -771,23 +775,16 @@ ecma_bigint_mul (ecma_value_t left_value, /**< left BigInt value */
{
JERRY_ASSERT (ecma_is_value_bigint (left_value) && ecma_is_value_bigint (right_value));
+ if (left_value == ECMA_BIGINT_ZERO || right_value == ECMA_BIGINT_ZERO)
+ {
+ return ECMA_BIGINT_ZERO;
+ }
+
ecma_extended_primitive_t *left_p = ecma_get_extended_primitive_from_value (left_value);
ecma_extended_primitive_t *right_p = ecma_get_extended_primitive_from_value (right_value);
uint32_t left_size = ECMA_BIGINT_GET_SIZE (left_p);
uint32_t right_size = ECMA_BIGINT_GET_SIZE (right_p);
- if (left_size == 0)
- {
- ecma_ref_extended_primitive (left_p);
- return left_value;
- }
-
- if (right_size == 0)
- {
- ecma_ref_extended_primitive (right_p);
- return right_value;
- }
-
if (left_size == sizeof (ecma_bigint_digit_t)
&& ECMA_BIGINT_GET_LAST_DIGIT (left_p, sizeof (ecma_bigint_digit_t)) == 1)
{
@@ -837,56 +834,54 @@ ecma_bigint_div_mod (ecma_value_t left_value, /**< left BigInt value */
{
JERRY_ASSERT (ecma_is_value_bigint (left_value) && ecma_is_value_bigint (right_value));
- ecma_extended_primitive_t *left_p = ecma_get_extended_primitive_from_value (left_value);
- ecma_extended_primitive_t *right_p = ecma_get_extended_primitive_from_value (right_value);
- uint32_t left_size = ECMA_BIGINT_GET_SIZE (left_p);
- uint32_t right_size = ECMA_BIGINT_GET_SIZE (right_p);
-
- if (right_size == 0)
+ if (right_value == ECMA_BIGINT_ZERO)
{
return ecma_raise_range_error (ECMA_ERR_MSG ("BigInt division by zero"));
}
- if (left_size == 0)
+ if (left_value == ECMA_BIGINT_ZERO)
{
- ecma_ref_extended_primitive (left_p);
return left_value;
}
+ ecma_extended_primitive_t *left_p = ecma_get_extended_primitive_from_value (left_value);
+ ecma_extended_primitive_t *right_p = ecma_get_extended_primitive_from_value (right_value);
+
int compare_result = ecma_big_uint_compare (left_p, right_p);
ecma_extended_primitive_t *result_p;
if (compare_result < 0)
{
- if (is_mod)
+ if (!is_mod)
{
- ecma_ref_extended_primitive (left_p);
- return left_value;
- }
- else
- {
- result_p = ecma_bigint_create (0);
+ return ECMA_BIGINT_ZERO;
}
+
+ ecma_ref_extended_primitive (left_p);
+ return left_value;
}
else if (compare_result == 0)
{
if (is_mod)
{
- result_p = ecma_bigint_create (0);
+ return ECMA_BIGINT_ZERO;
}
- else
- {
- result_p = ecma_bigint_create (sizeof (ecma_bigint_digit_t));
- if (result_p != NULL)
- {
- *ECMA_BIGINT_GET_DIGITS (result_p, 0) = 1;
- }
+ result_p = ecma_bigint_create (sizeof (ecma_bigint_digit_t));
+
+ if (result_p != NULL)
+ {
+ *ECMA_BIGINT_GET_DIGITS (result_p, 0) = 1;
}
}
else
{
result_p = ecma_big_uint_div_mod (left_p, right_p, is_mod);
+
+ if (result_p == ECMA_BIGINT_POINTER_TO_ZERO)
+ {
+ return ECMA_BIGINT_ZERO;
+ }
}
if (JERRY_UNLIKELY (result_p == NULL))
@@ -894,11 +889,6 @@ ecma_bigint_div_mod (ecma_value_t left_value, /**< left BigInt value */
return ecma_bigint_raise_memory_error ();
}
- if (ECMA_BIGINT_GET_SIZE (result_p) == 0)
- {
- return ecma_make_extended_primitive_value (result_p, ECMA_TYPE_BIGINT);
- }
-
if (is_mod)
{
result_p->u.bigint_sign_and_size |= left_p->u.bigint_sign_and_size & ECMA_BIGINT_SIGN;
@@ -925,29 +915,34 @@ ecma_bigint_shift (ecma_value_t left_value, /**< left BigInt value */
{
JERRY_ASSERT (ecma_is_value_bigint (left_value) && ecma_is_value_bigint (right_value));
- ecma_extended_primitive_t *left_p = ecma_get_extended_primitive_from_value (left_value);
- ecma_extended_primitive_t *right_p = ecma_get_extended_primitive_from_value (right_value);
- uint32_t right_size = ECMA_BIGINT_GET_SIZE (right_p);
+ if (left_value == ECMA_BIGINT_ZERO)
+ {
+ return ECMA_BIGINT_ZERO;
+ }
- if (right_size == 0 || ECMA_BIGINT_GET_SIZE (left_p) == 0)
+ ecma_extended_primitive_t *left_p = ecma_get_extended_primitive_from_value (left_value);
+
+ if (right_value == ECMA_BIGINT_ZERO)
{
ecma_ref_extended_primitive (left_p);
return left_value;
}
+ ecma_extended_primitive_t *right_p = ecma_get_extended_primitive_from_value (right_value);
+
if (right_p->u.bigint_sign_and_size & ECMA_BIGINT_SIGN)
{
is_left = !is_left;
}
- if (right_size > sizeof (ecma_bigint_digit_t))
+ if (ECMA_BIGINT_GET_SIZE (right_p) > sizeof (ecma_bigint_digit_t))
{
if (is_left)
{
return ecma_bigint_raise_memory_error ();
}
- return ecma_make_extended_primitive_value (ecma_bigint_create (0), ECMA_TYPE_BIGINT);
+ return ECMA_BIGINT_ZERO;
}
ecma_extended_primitive_t *result_p;
@@ -960,6 +955,11 @@ ecma_bigint_shift (ecma_value_t left_value, /**< left BigInt value */
else
{
result_p = ecma_big_uint_shift_right (left_p, shift);
+
+ if (result_p == ECMA_BIGINT_POINTER_TO_ZERO)
+ {
+ return ECMA_BIGINT_ZERO;
+ }
}
if (JERRY_UNLIKELY (result_p == NULL))
@@ -990,8 +990,12 @@ ecma_bigint_bitwise_op (uint32_t operation_and_options, /**< bitwise operation t
return ecma_bigint_raise_memory_error ();
}
- if ((operation_and_options & ECMA_BIG_UINT_BITWISE_INCREASE_RESULT)
- && ECMA_BIGINT_GET_SIZE (result_p) > 0)
+ if (result_p == ECMA_BIGINT_POINTER_TO_ZERO)
+ {
+ return ECMA_BIGINT_ZERO;
+ }
+
+ if (operation_and_options & ECMA_BIG_UINT_BITWISE_INCREASE_RESULT)
{
result_p->u.bigint_sign_and_size |= ECMA_BIGINT_SIGN;
}
@@ -1009,22 +1013,13 @@ ecma_value_t
ecma_bigint_and (ecma_value_t left_value, /**< left BigInt value */
ecma_value_t right_value) /**< right BigInt value */
{
+ if (left_value == ECMA_BIGINT_ZERO || right_value == ECMA_BIGINT_ZERO)
+ {
+ return ECMA_BIGINT_ZERO;
+ }
+
ecma_extended_primitive_t *left_p = ecma_get_extended_primitive_from_value (left_value);
ecma_extended_primitive_t *right_p = ecma_get_extended_primitive_from_value (right_value);
- uint32_t left_size = ECMA_BIGINT_GET_SIZE (left_p);
- uint32_t right_size = ECMA_BIGINT_GET_SIZE (right_p);
-
- if (left_size == 0)
- {
- ecma_ref_extended_primitive (left_p);
- return left_value;
- }
-
- if (right_size == 0)
- {
- ecma_ref_extended_primitive (right_p);
- return right_value;
- }
if (!(left_p->u.bigint_sign_and_size & ECMA_BIGINT_SIGN))
{
@@ -1062,22 +1057,18 @@ ecma_value_t
ecma_bigint_or (ecma_value_t left_value, /**< left BigInt value */
ecma_value_t right_value) /**< right BigInt value */
{
+ if (left_value == ECMA_BIGINT_ZERO)
+ {
+ return ecma_copy_value (right_value);
+ }
+
+ if (right_value == ECMA_BIGINT_ZERO)
+ {
+ return ecma_copy_value (left_value);
+ }
+
ecma_extended_primitive_t *left_p = ecma_get_extended_primitive_from_value (left_value);
ecma_extended_primitive_t *right_p = ecma_get_extended_primitive_from_value (right_value);
- uint32_t left_size = ECMA_BIGINT_GET_SIZE (left_p);
- uint32_t right_size = ECMA_BIGINT_GET_SIZE (right_p);
-
- if (left_size == 0)
- {
- ecma_ref_extended_primitive (right_p);
- return right_value;
- }
-
- if (right_size == 0)
- {
- ecma_ref_extended_primitive (left_p);
- return left_value;
- }
if (!(left_p->u.bigint_sign_and_size & ECMA_BIGINT_SIGN))
{
@@ -1119,22 +1110,18 @@ ecma_value_t
ecma_bigint_xor (ecma_value_t left_value, /**< left BigInt value */
ecma_value_t right_value) /**< right BigInt value */
{
+ if (left_value == ECMA_BIGINT_ZERO)
+ {
+ return ecma_copy_value (right_value);
+ }
+
+ if (right_value == ECMA_BIGINT_ZERO)
+ {
+ return ecma_copy_value (left_value);
+ }
+
ecma_extended_primitive_t *left_p = ecma_get_extended_primitive_from_value (left_value);
ecma_extended_primitive_t *right_p = ecma_get_extended_primitive_from_value (right_value);
- uint32_t left_size = ECMA_BIGINT_GET_SIZE (left_p);
- uint32_t right_size = ECMA_BIGINT_GET_SIZE (right_p);
-
- if (left_size == 0)
- {
- ecma_ref_extended_primitive (right_p);
- return right_value;
- }
-
- if (right_size == 0)
- {
- ecma_ref_extended_primitive (left_p);
- return left_value;
- }
if (!(left_p->u.bigint_sign_and_size & ECMA_BIGINT_SIGN))
{
diff --git a/jerry-core/parser/js/common.c b/jerry-core/parser/js/common.c
index fcdff21cc..63a8f625b 100644
--- a/jerry-core/parser/js/common.c
+++ b/jerry-core/parser/js/common.c
@@ -88,14 +88,13 @@ util_print_number (ecma_number_t num_p) /**< number to print */
static void
util_print_bigint (ecma_value_t bigint) /**< bigint to print */
{
- ecma_extended_primitive_t *bigint_p = ecma_get_extended_primitive_from_value (bigint);
-
- if (ECMA_BIGINT_GET_SIZE (bigint_p) == 0)
+ if (bigint == ECMA_BIGINT_ZERO)
{
JERRY_DEBUG_MSG ("0");
return;
}
+ ecma_extended_primitive_t *bigint_p = ecma_get_extended_primitive_from_value (bigint);
uint32_t char_start_p, char_size_p;
lit_utf8_byte_t *string_buffer_p = ecma_big_uint_to_string (bigint_p, 10, &char_start_p, &char_size_p);
diff --git a/jerry-core/vm/opcodes-ecma-arithmetics.c b/jerry-core/vm/opcodes-ecma-arithmetics.c
index cb0ea169e..2248ceb2b 100644
--- a/jerry-core/vm/opcodes-ecma-arithmetics.c
+++ b/jerry-core/vm/opcodes-ecma-arithmetics.c
@@ -338,16 +338,11 @@ opfunc_unary_operation (ecma_value_t left_value, /**< left value */
}
else
{
- ecma_extended_primitive_t *left_p = ecma_get_extended_primitive_from_value (left_value);
+ ret_value = left_value;
- if (ECMA_BIGINT_GET_SIZE (left_p) == 0)
+ if (left_value != ECMA_BIGINT_ZERO)
{
- ecma_ref_extended_primitive (left_p);
- ret_value = left_value;
- }
- else
- {
- ret_value = ecma_bigint_negate (left_p);
+ ret_value = ecma_bigint_negate (ecma_get_extended_primitive_from_value (left_value));
}
}
}
diff --git a/tests/test262-esnext-excludelist.xml b/tests/test262-esnext-excludelist.xml
index 925e832b1..580038431 100644
--- a/tests/test262-esnext-excludelist.xml
+++ b/tests/test262-esnext-excludelist.xml
@@ -6183,7 +6183,6 @@
-
@@ -6597,7 +6596,6 @@
-