Implement unary operators: bitwise not, pre/post increment/decrement (#4116)

JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
Zoltan Herczeg
2020-08-10 22:38:34 +02:00
committed by GitHub
parent 43a82cddb9
commit 39fe04814e
11 changed files with 519 additions and 110 deletions
+132
View File
@@ -373,6 +373,138 @@ ecma_big_uint_to_string (ecma_extended_primitive_t *value_p, /**< BigUInt value
return result_p;
} /* ecma_big_uint_to_string */
/**
* Increase the value of a BigUInt value by 1
*
* return new BigInt value, NULL on error
*/
ecma_extended_primitive_t *
ecma_big_uint_increase (ecma_extended_primitive_t *value_p) /**< BigUInt value */
{
uint32_t size = ECMA_BIGINT_GET_SIZE (value_p);
JERRY_ASSERT (size > 0 && ECMA_BIGINT_GET_LAST_DIGIT (value_p, size) != 0);
ecma_bigint_digit_t *digits_p = ECMA_BIGINT_GET_DIGITS (value_p, 0);
ecma_bigint_digit_t *digits_end_p = ECMA_BIGINT_GET_DIGITS (value_p, size);
if (JERRY_UNLIKELY (digits_p[0] == ~((ecma_bigint_digit_t) 0) && digits_end_p[-1] == ~((ecma_bigint_digit_t) 0)))
{
do
{
digits_p++;
}
while (digits_p < digits_end_p && digits_p[0] == ~((ecma_bigint_digit_t) 0));
if (digits_p == digits_end_p)
{
ecma_extended_primitive_t *result_value_p;
result_value_p = ecma_bigint_create ((uint32_t) (size + sizeof (ecma_bigint_digit_t)));
if (JERRY_UNLIKELY (result_value_p == NULL))
{
return NULL;
}
memset (ECMA_BIGINT_GET_DIGITS (result_value_p, 0), 0, size);
*ECMA_BIGINT_GET_DIGITS (result_value_p, size) = 1;
return result_value_p;
}
digits_p = ECMA_BIGINT_GET_DIGITS (value_p, 0);
}
ecma_extended_primitive_t *result_value_p = ecma_bigint_create (size);
if (JERRY_UNLIKELY (result_value_p == NULL))
{
return NULL;
}
ecma_bigint_digit_t *result_p = ECMA_BIGINT_GET_DIGITS (result_value_p, 0);
while (digits_p[0] == ~((ecma_bigint_digit_t) 0))
{
digits_p++;
*result_p++ = 0;
}
*result_p++ = (*digits_p++) + 1;
if (digits_p < digits_end_p)
{
memcpy (result_p, digits_p, (size_t) ((uint8_t *) digits_end_p - (uint8_t *) digits_p));
}
return result_value_p;
} /* ecma_big_uint_increase */
/**
* Decrease the value of a BigUInt value by 1
*
* return new BigInt value, NULL on error
*/
ecma_extended_primitive_t *
ecma_big_uint_decrease (ecma_extended_primitive_t *value_p) /**< BigUInt value */
{
uint32_t size = ECMA_BIGINT_GET_SIZE (value_p);
JERRY_ASSERT (size > 0 && ECMA_BIGINT_GET_LAST_DIGIT (value_p, size) != 0);
ecma_bigint_digit_t *digits_p = ECMA_BIGINT_GET_DIGITS (value_p, 0);
ecma_bigint_digit_t *digits_end_p = ECMA_BIGINT_GET_DIGITS (value_p, size);
JERRY_ASSERT (size > sizeof (ecma_bigint_digit_t) || *digits_p > 1);
if (JERRY_UNLIKELY (digits_p[0] == 0 && digits_end_p[-1] == 1))
{
do
{
digits_p++;
JERRY_ASSERT (digits_p < digits_end_p);
}
while (digits_p[0] == 0);
if (digits_p + 1 == digits_end_p)
{
size -= (uint32_t) sizeof (ecma_bigint_digit_t);
ecma_extended_primitive_t *result_value_p = ecma_bigint_create (size);
if (JERRY_UNLIKELY (result_value_p == NULL))
{
return NULL;
}
memset (ECMA_BIGINT_GET_DIGITS (result_value_p, 0), 0xff, size);
return result_value_p;
}
digits_p = ECMA_BIGINT_GET_DIGITS (value_p, 0);
}
ecma_extended_primitive_t *result_value_p = ecma_bigint_create (size);
if (JERRY_UNLIKELY (result_value_p == NULL))
{
return NULL;
}
ecma_bigint_digit_t *result_p = ECMA_BIGINT_GET_DIGITS (result_value_p, 0);
while (digits_p[0] == 0)
{
digits_p++;
*result_p++ = ~((ecma_bigint_digit_t) 0);
}
*result_p++ = (*digits_p++) - 1;
if (digits_p < digits_end_p)
{
memcpy (result_p, digits_p, (size_t) ((uint8_t *) digits_end_p - (uint8_t *) digits_p));
}
return result_value_p;
} /* ecma_big_uint_decrease */
/**
* Add right BigUInt value to the left BigUInt value
*