Implement BigInt primitve type and some of its operations (#4062)
Supported operations: - parse BigInt (decimal, hexadecimal, binary) - toString with any radix between 2 and 36 - arithmetic operations: negate, add, subtract, multiply, divide, modulo - left and right shift JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
@@ -14,8 +14,11 @@
|
||||
*/
|
||||
|
||||
#include "ecma-alloc.h"
|
||||
#include "ecma-bigint.h"
|
||||
#include "ecma-conversion.h"
|
||||
#include "ecma-exceptions.h"
|
||||
#include "ecma-helpers.h"
|
||||
#include "ecma-objects.h"
|
||||
#include "ecma-try-catch-macro.h"
|
||||
#include "opcodes.h"
|
||||
|
||||
@@ -45,61 +48,131 @@ do_number_bitwise_logic (number_bitwise_logic_op op, /**< number bitwise logic o
|
||||
JERRY_ASSERT (!ECMA_IS_VALUE_ERROR (left_value)
|
||||
&& !ECMA_IS_VALUE_ERROR (right_value));
|
||||
|
||||
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
|
||||
bool free_left_value = false;
|
||||
bool free_right_value = false;
|
||||
|
||||
ECMA_OP_TO_NUMBER_TRY_CATCH (num_left, left_value, ret_value);
|
||||
ECMA_OP_TO_NUMBER_TRY_CATCH (num_right, right_value, ret_value);
|
||||
|
||||
ecma_number_t result = ECMA_NUMBER_ZERO;
|
||||
uint32_t right_uint32 = ecma_number_to_uint32 (num_right);
|
||||
|
||||
switch (op)
|
||||
if (ecma_is_value_object (left_value))
|
||||
{
|
||||
case NUMBER_BITWISE_LOGIC_AND:
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (left_value);
|
||||
left_value = ecma_op_object_default_value (obj_p, ECMA_PREFERRED_TYPE_NUMBER);
|
||||
free_left_value = true;
|
||||
|
||||
if (ECMA_IS_VALUE_ERROR (left_value))
|
||||
{
|
||||
uint32_t left_uint32 = ecma_number_to_uint32 (num_left);
|
||||
result = (ecma_number_t) ((int32_t) (left_uint32 & right_uint32));
|
||||
break;
|
||||
}
|
||||
case NUMBER_BITWISE_LOGIC_OR:
|
||||
{
|
||||
uint32_t left_uint32 = ecma_number_to_uint32 (num_left);
|
||||
result = (ecma_number_t) ((int32_t) (left_uint32 | right_uint32));
|
||||
break;
|
||||
}
|
||||
case NUMBER_BITWISE_LOGIC_XOR:
|
||||
{
|
||||
uint32_t left_uint32 = ecma_number_to_uint32 (num_left);
|
||||
result = (ecma_number_t) ((int32_t) (left_uint32 ^ right_uint32));
|
||||
break;
|
||||
}
|
||||
case NUMBER_BITWISE_SHIFT_LEFT:
|
||||
{
|
||||
result = (ecma_number_t) (ecma_number_to_int32 (num_left) << (right_uint32 & 0x1F));
|
||||
break;
|
||||
}
|
||||
case NUMBER_BITWISE_SHIFT_RIGHT:
|
||||
{
|
||||
result = (ecma_number_t) (ecma_number_to_int32 (num_left) >> (right_uint32 & 0x1F));
|
||||
break;
|
||||
}
|
||||
case NUMBER_BITWISE_SHIFT_URIGHT:
|
||||
{
|
||||
uint32_t left_uint32 = ecma_number_to_uint32 (num_left);
|
||||
result = (ecma_number_t) (left_uint32 >> (right_uint32 & 0x1F));
|
||||
break;
|
||||
}
|
||||
case NUMBER_BITWISE_NOT:
|
||||
{
|
||||
result = (ecma_number_t) ((int32_t) ~right_uint32);
|
||||
break;
|
||||
return left_value;
|
||||
}
|
||||
}
|
||||
|
||||
ret_value = ecma_make_number_value (result);
|
||||
if (ecma_is_value_object (right_value))
|
||||
{
|
||||
ecma_object_t *obj_p = ecma_get_object_from_value (right_value);
|
||||
right_value = ecma_op_object_default_value (obj_p, ECMA_PREFERRED_TYPE_NUMBER);
|
||||
free_right_value = true;
|
||||
|
||||
ECMA_OP_TO_NUMBER_FINALIZE (num_right);
|
||||
ECMA_OP_TO_NUMBER_FINALIZE (num_left);
|
||||
if (ECMA_IS_VALUE_ERROR (right_value))
|
||||
{
|
||||
if (free_left_value)
|
||||
{
|
||||
ecma_free_value (left_value);
|
||||
}
|
||||
return right_value;
|
||||
}
|
||||
}
|
||||
|
||||
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
|
||||
|
||||
#if ENABLED (JERRY_BUILTIN_BIGINT)
|
||||
if (JERRY_LIKELY (!ecma_is_value_bigint (left_value))
|
||||
|| JERRY_LIKELY (!ecma_is_value_bigint (right_value)))
|
||||
{
|
||||
#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */
|
||||
ECMA_OP_TO_NUMBER_TRY_CATCH (num_left, left_value, ret_value);
|
||||
ECMA_OP_TO_NUMBER_TRY_CATCH (num_right, right_value, ret_value);
|
||||
|
||||
ecma_number_t result = ECMA_NUMBER_ZERO;
|
||||
uint32_t right_uint32 = ecma_number_to_uint32 (num_right);
|
||||
|
||||
switch (op)
|
||||
{
|
||||
case NUMBER_BITWISE_LOGIC_AND:
|
||||
{
|
||||
uint32_t left_uint32 = ecma_number_to_uint32 (num_left);
|
||||
result = (ecma_number_t) ((int32_t) (left_uint32 & right_uint32));
|
||||
break;
|
||||
}
|
||||
case NUMBER_BITWISE_LOGIC_OR:
|
||||
{
|
||||
uint32_t left_uint32 = ecma_number_to_uint32 (num_left);
|
||||
result = (ecma_number_t) ((int32_t) (left_uint32 | right_uint32));
|
||||
break;
|
||||
}
|
||||
case NUMBER_BITWISE_LOGIC_XOR:
|
||||
{
|
||||
uint32_t left_uint32 = ecma_number_to_uint32 (num_left);
|
||||
result = (ecma_number_t) ((int32_t) (left_uint32 ^ right_uint32));
|
||||
break;
|
||||
}
|
||||
case NUMBER_BITWISE_SHIFT_LEFT:
|
||||
{
|
||||
result = (ecma_number_t) (ecma_number_to_int32 (num_left) << (right_uint32 & 0x1F));
|
||||
break;
|
||||
}
|
||||
case NUMBER_BITWISE_SHIFT_RIGHT:
|
||||
{
|
||||
result = (ecma_number_t) (ecma_number_to_int32 (num_left) >> (right_uint32 & 0x1F));
|
||||
break;
|
||||
}
|
||||
case NUMBER_BITWISE_SHIFT_URIGHT:
|
||||
{
|
||||
uint32_t left_uint32 = ecma_number_to_uint32 (num_left);
|
||||
result = (ecma_number_t) (left_uint32 >> (right_uint32 & 0x1F));
|
||||
break;
|
||||
}
|
||||
case NUMBER_BITWISE_NOT:
|
||||
{
|
||||
result = (ecma_number_t) ((int32_t) ~right_uint32);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ret_value = ecma_make_number_value (result);
|
||||
|
||||
ECMA_OP_TO_NUMBER_FINALIZE (num_right);
|
||||
ECMA_OP_TO_NUMBER_FINALIZE (num_left);
|
||||
#if ENABLED (JERRY_BUILTIN_BIGINT)
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case NUMBER_BITWISE_SHIFT_LEFT:
|
||||
{
|
||||
ret_value = ecma_bigint_shift (left_value, right_value, true);
|
||||
break;
|
||||
}
|
||||
case NUMBER_BITWISE_SHIFT_RIGHT:
|
||||
{
|
||||
ret_value = ecma_bigint_shift (left_value, right_value, false);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
ret_value = ecma_raise_common_error (ECMA_ERR_MSG ("Not supported BigInt operation"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* ENABLED (JERRY_BUILTIN_BIGINT) */
|
||||
|
||||
if (free_left_value)
|
||||
{
|
||||
ecma_free_value (left_value);
|
||||
}
|
||||
|
||||
if (free_right_value)
|
||||
{
|
||||
ecma_free_value (right_value);
|
||||
}
|
||||
|
||||
return ret_value;
|
||||
} /* do_number_bitwise_logic */
|
||||
|
||||
Reference in New Issue
Block a user