moved the inttostr conversion buffer into moo_t

This commit is contained in:
hyunghwan.chung 2018-02-17 13:32:30 +00:00
parent f0cd3472e7
commit 9531c6a7e8
3 changed files with 89 additions and 27 deletions

View File

@ -4005,8 +4005,7 @@ moo_oop_t moo_inttostr (moo_t* moo, moo_oop_t num, int radix)
moo_liw_t* a, * q, * r; moo_liw_t* a, * q, * r;
moo_liw_t* t = MOO_NULL; moo_liw_t* t = MOO_NULL;
moo_ooch_t* xbuf = MOO_NULL; moo_ooch_t* xbuf = MOO_NULL;
moo_oow_t xlen = 0, seglen; moo_oow_t xlen = 0, seglen, reqcapa;
moo_oop_t s;
MOO_ASSERT (moo, radix >= 2 && radix <= 36); MOO_ASSERT (moo, radix >= 2 && radix <= 36);
@ -4015,19 +4014,29 @@ moo_oop_t moo_inttostr (moo_t* moo, moo_oop_t num, int radix)
if (v) if (v)
{ {
/* Use a static buffer for simple conversion as the largest /* The largest buffer is required for radix 2.
* size is known. The largest buffer is required for radix 2.
* For a binary conversion(radix 2), the number of bits is * For a binary conversion(radix 2), the number of bits is
* the maximum number of digits that can be produced. +1 is * the maximum number of digits that can be produced. +1 is
* needed for the sign. */ * needed for the sign. */
moo_ooch_t buf[MOO_OOW_BITS + 1];
moo_oow_t len;
len = oow_to_text (moo, w, radix, buf); reqcapa = MOO_OOW_BITS + 1;
if (v < 0) buf[len++] = '-'; if (moo->inttostr.xbuf.capa < reqcapa)
{
xbuf = (moo_ooch_t*)moo_reallocmem(moo, moo->inttostr.xbuf.ptr, reqcapa);
if (!xbuf) return MOO_NULL;
moo->inttostr.xbuf.capa = reqcapa;
moo->inttostr.xbuf.ptr = xbuf;
}
else
{
xbuf = moo->inttostr.xbuf.ptr;
}
reverse_string (buf, len); xlen = oow_to_text(moo, w, radix, xbuf);
return moo_makestring (moo, buf, len); if (v < 0) xbuf[xlen++] = '-';
reverse_string (xbuf, xlen);
return moo_makestring(moo, xbuf, xlen);
} }
as = MOO_OBJ_GET_SIZE(num); as = MOO_OBJ_GET_SIZE(num);
@ -4042,8 +4051,18 @@ moo_oop_t moo_inttostr (moo_t* moo, moo_oop_t num, int radix)
xlen = as * ((MOO_LIW_BITS + exp) / exp) + 1; xlen = as * ((MOO_LIW_BITS + exp) / exp) + 1;
xpos = xlen; xpos = xlen;
xbuf = (moo_ooch_t*)moo_allocmem (moo, MOO_SIZEOF(*xbuf) * xlen); reqcapa = MOO_SIZEOF(*xbuf) * xlen;
if (!xbuf) return MOO_NULL; if (moo->inttostr.xbuf.capa < reqcapa)
{
xbuf = (moo_ooch_t*)moo_reallocmem(moo, moo->inttostr.xbuf.ptr, reqcapa);
if (!xbuf) return MOO_NULL;
moo->inttostr.xbuf.capa = reqcapa;
moo->inttostr.xbuf.ptr = xbuf;
}
else
{
xbuf = moo->inttostr.xbuf.ptr;
}
acc = 0; acc = 0;
accbits = 0; accbits = 0;
@ -4075,23 +4094,39 @@ moo_oop_t moo_inttostr (moo_t* moo, moo_oop_t num, int radix)
MOO_ASSERT (moo, xpos >= 1); MOO_ASSERT (moo, xpos >= 1);
if (MOO_OBJ_GET_CLASS(num) == moo->_large_negative_integer) xbuf[--xpos] = '-'; if (MOO_OBJ_GET_CLASS(num) == moo->_large_negative_integer) xbuf[--xpos] = '-';
s = moo_makestring (moo, &xbuf[xpos], xlen - xpos); return moo_makestring(moo, &xbuf[xpos], xlen - xpos);
moo_freemem (moo, xbuf);
return s;
} }
/* Do it in a hard way for other cases */ /* Do it in a hard way for other cases */
/* TODO: migrate these buffers into moo_t? */
/* TODO: find an optimial buffer size */
xbuf = (moo_ooch_t*)moo_allocmem (moo, MOO_SIZEOF(*xbuf) * (as * MOO_LIW_BITS + 1));
if (!xbuf) return MOO_NULL;
t = (moo_liw_t*)moo_callocmem (moo, MOO_SIZEOF(*t) * as * 3); /* TODO: find an optimial buffer size */
if (!t) /* TODO: find an optimial buffer size */
reqcapa = MOO_SIZEOF(*xbuf) * (as * MOO_LIW_BITS + 1);
if (moo->inttostr.xbuf.capa < reqcapa)
{ {
moo_freemem (moo, xbuf); xbuf = (moo_ooch_t*)moo_reallocmem(moo, moo->inttostr.xbuf.ptr, reqcapa);
return MOO_NULL; if (!xbuf) return MOO_NULL;
moo->inttostr.xbuf.capa = reqcapa;
moo->inttostr.xbuf.ptr = xbuf;
} }
else
{
xbuf = moo->inttostr.xbuf.ptr;
}
reqcapa = MOO_SIZEOF(*t) * as * 3;
if (moo->inttostr.t.capa < reqcapa)
{
t = (moo_liw_t*)moo_reallocmem(moo, moo->inttostr.t.ptr, reqcapa);
if (!t) return MOO_NULL;
moo->inttostr.t.capa = reqcapa;
moo->inttostr.t.ptr = t;
}
else
{
t = moo->inttostr.t.ptr;
}
#if (MOO_LIW_BITS == MOO_OOW_BITS) #if (MOO_LIW_BITS == MOO_OOW_BITS)
b[0] = moo->bigint[radix].multiplier; /* block divisor */ b[0] = moo->bigint[radix].multiplier; /* block divisor */
@ -4164,11 +4199,8 @@ moo_oop_t moo_inttostr (moo_t* moo, moo_oop_t num, int radix)
if (MOO_OBJ_GET_CLASS(num) == moo->_large_negative_integer) xbuf[xlen++] = '-'; if (MOO_OBJ_GET_CLASS(num) == moo->_large_negative_integer) xbuf[xlen++] = '-';
reverse_string (xbuf, xlen); reverse_string (xbuf, xlen);
s = moo_makestring (moo, xbuf, xlen);
moo_freemem (moo, t); return moo_makestring(moo, xbuf, xlen);
moo_freemem (moo, xbuf);
return s;
oops_einval: oops_einval:
moo_seterrnum (moo, MOO_EINVAL); moo_seterrnum (moo, MOO_EINVAL);

View File

@ -257,6 +257,21 @@ void moo_fini (moo_t* moo)
moo->log.capa = 0; moo->log.capa = 0;
moo->log.len = 0; moo->log.len = 0;
} }
if (moo->inttostr.xbuf.ptr)
{
moo_freemem (moo, moo->inttostr.xbuf.ptr);
moo->inttostr.xbuf.ptr = MOO_NULL;
moo->inttostr.xbuf.capa = 0;
moo->inttostr.xbuf.len = 0;
}
if (moo->inttostr.t.ptr)
{
moo_freemem (moo, moo->inttostr.t.ptr);
moo->inttostr.t.ptr = MOO_NULL;
moo->inttostr.t.capa = 0;
}
} }
int moo_setoption (moo_t* moo, moo_option_t id, const void* value) int moo_setoption (moo_t* moo, moo_option_t id, const void* value)

View File

@ -1338,6 +1338,21 @@ struct moo_t
int safe_ndigits; int safe_ndigits;
moo_oow_t multiplier; moo_oow_t multiplier;
} bigint[37]; } bigint[37];
struct
{
struct
{
moo_uch_t* ptr;
moo_oow_t capa;
moo_oow_t len;
} xbuf;
struct
{
moo_liw_t* ptr;
moo_oow_t capa;
} t;
} inttostr;
/* == END BIGINT CONVERSION == */ /* == END BIGINT CONVERSION == */
moo_sbuf_t sbuf[64]; moo_sbuf_t sbuf[64];