Managing bigint memory

This commit is contained in:
Krzosa Karol
2022-06-06 16:49:41 +02:00
parent 06d6ec7525
commit dc56bd54f3
6 changed files with 165 additions and 62 deletions

View File

@@ -3,9 +3,17 @@
// a copy of which can be found in the LICENSE file.
struct Token;
Allocator *bigint_allocator;
global S64 bigint_allocation_count;
function void parsing_error(Token *token, const char *str, ...);
#define malloc_arena(x) (bigint_allocation_count++, exp_alloc(&pernament_arena, x))
#define Set_BigInt_Allocator(x) BigInt_Allocator bigint_allocator(x)
struct BigInt_Allocator{
BigInt_Allocator(Allocator *allocator){bigint_allocator = allocator;}
~BigInt_Allocator(){bigint_allocator = 0;}
};
#define malloc_arena(x) (bigint_allocation_count++, exp_alloc(bigint_allocator, x, AF_ZeroMemory))
#define ALLOC_DIGITS(_digits) (uint64_t *)((_digits) ? malloc_arena(sizeof(uint64_t) * (_digits)) : NULL)
#define FATAL_ERROR(x) parsing_error(0, x)
@@ -95,6 +103,33 @@ bigint_mul(const BigInt *a, const BigInt *b){
return result;
}
function BigInt
bigint_add(const BigInt *a, const BigInt *b){
BigInt result;
bigint_add(&result, a, b);
return result;
}
function BigInt
bigint_copy(Allocator *allocator, BigInt *src){
BigInt dest = {};
if (src->digit_count == 0){
bigint_init_unsigned(&dest, 0);
return dest;
}
if(src->digit_count == 1){
dest.digit_count = 1;
dest.digit = src->digit;
dest.is_negative = src->is_negative;
return dest;
}
dest.is_negative = src->is_negative;
dest.digit_count = src->digit_count;
dest.digits = exp_alloc_array(allocator, uint64_t, dest.digit_count, AF_ZeroMemory);
memcpy(dest.digits, src->digits, sizeof(uint64_t) * dest.digit_count);
return dest;
}
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
@@ -671,6 +706,8 @@ bool mul_u64_overflow(uint64_t op1, uint64_t op2, uint64_t *result)
void bigint_add(BigInt *dest, const BigInt *op1, const BigInt *op2)
{
assert(dest != op1);
assert(dest != op2);
if (op1->digit_count == 0)
{
return bigint_init_bigint(dest, op2);
@@ -893,6 +930,8 @@ static void mul_scalar(BigInt *dest, const BigInt *op, uint64_t scalar)
void bigint_mul(BigInt *dest, const BigInt *op1, const BigInt *op2)
{
assert(dest != op1);
assert(dest != op2);
if (op1->digit_count == 0 || op2->digit_count == 0)
{
return bigint_init_unsigned(dest, 0);
@@ -1958,6 +1997,7 @@ void bigint_print(BigInt *bigint, uint64_t base)
const char *bigint_to_error_string(Allocator *allocator, const BigInt *bigint, uint64_t base)
{
Set_BigInt_Allocator(allocator);
if (bigint->digit_count == 0)
{
return "0";
@@ -2021,6 +2061,7 @@ const char *bigint_to_error_string(Allocator *allocator, const BigInt *bigint, u
*(current++) = *ptr;
}
*(current++) = '\0';
return out;
}