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 @@ -