implement right bit shift over a small integer
This commit is contained in:
parent
6fb206a265
commit
e7d00d89bf
@ -363,7 +363,10 @@ PROCESS TESTING
|
||||
(16rFFFFFFFFFF1234567890AAAAAAAAAAAAAAAAAAAAAAAAA22222222222222222F printStringRadix: 32) dump.
|
||||
(32r3VVVVVVVS938LJOI2LALALALALALALALALAL8H248H248H248HF printStringRadix: 16) dump.
|
||||
|
||||
((-2r110101010101010101010101010101111111111111111111111111111111111111111111111111111111100000000001111111 bitShift: 16r1FFFFFFFFFFFFFFFF) printStringRadix: 2) dump.
|
||||
## ((-2r110101010101010101010101010101111111111111111111111111111111111111111111111111111111100000000001111111 bitShift: 16r1FFFFFFFFFFFFFFFF) printStringRadix: 2) dump.
|
||||
|
||||
##((-2r11111111110000000000111110000 bitShift: -31) printStringRadix: 2) dump.
|
||||
((-536870911 bitShift: -536870912) printStringRadix: 2) dump.
|
||||
|
||||
"
|
||||
FFI isNil dump.
|
||||
|
@ -122,7 +122,7 @@ static STIX_INLINE int smooi_mul_overflow (stix_ooi_t a, stix_ooi_t b, stix_ooi_
|
||||
|
||||
/* though this fomula basically works for unsigned types in principle,
|
||||
* the values used here are all absolute values and they fall in
|
||||
* a safe range to apply this fomula. the safe range is guarantee because
|
||||
* a safe range to apply this fomula. the safe range is guaranteed because
|
||||
* the sources are supposed to be smoois. */
|
||||
return ub != 0 && ua > STIX_TYPE_MAX(stix_ooi_t) / ub;
|
||||
#endif
|
||||
@ -234,7 +234,7 @@ static STIX_INLINE stix_oop_t make_bigint_with_ooi (stix_t* stix, stix_ooi_t i)
|
||||
if (i >= 0)
|
||||
{
|
||||
w = i;
|
||||
hw[0] = w & STIX_LBMASK(stix_oow_t,STIX_LIW_BITS);
|
||||
hw[0] = w /*& STIX_LBMASK(stix_oow_t,STIX_LIW_BITS)*/;
|
||||
hw[1] = w >> STIX_LIW_BITS;
|
||||
return stix_instantiate (stix, stix->_large_positive_integer, &hw, (hw[1] > 0? 2: 1));
|
||||
}
|
||||
@ -242,7 +242,7 @@ static STIX_INLINE stix_oop_t make_bigint_with_ooi (stix_t* stix, stix_ooi_t i)
|
||||
{
|
||||
STIX_ASSERT (i > STIX_TYPE_MIN(stix_ooi_t));
|
||||
w = -i;
|
||||
hw[0] = w & STIX_LBMASK(stix_oow_t,STIX_LIW_BITS);
|
||||
hw[0] = w /*& STIX_LBMASK(stix_oow_t,STIX_LIW_BITS)*/;
|
||||
hw[1] = w >> STIX_LIW_BITS;
|
||||
return stix_instantiate (stix, stix->_large_negative_integer, &hw, (hw[1] > 0? 2: 1));
|
||||
}
|
||||
@ -284,7 +284,7 @@ static STIX_INLINE stix_oop_t make_bloated_bigint_with_ooi (stix_t* stix, stix_o
|
||||
if (i >= 0)
|
||||
{
|
||||
w = i;
|
||||
hw[0] = w & STIX_LBMASK(stix_oow_t,STIX_LIW_BITS);
|
||||
hw[0] = w /*& STIX_LBMASK(stix_oow_t,STIX_LIW_BITS)*/;
|
||||
hw[1] = w >> STIX_LIW_BITS;
|
||||
z = stix_instantiate (stix, stix->_large_positive_integer, STIX_NULL, (hw[1] > 0? 2: 1) + extra);
|
||||
}
|
||||
@ -292,7 +292,7 @@ static STIX_INLINE stix_oop_t make_bloated_bigint_with_ooi (stix_t* stix, stix_o
|
||||
{
|
||||
STIX_ASSERT (i > STIX_TYPE_MIN(stix_ooi_t));
|
||||
w = -i;
|
||||
hw[0] = w & STIX_LBMASK(stix_oow_t,STIX_LIW_BITS);
|
||||
hw[0] = w /*& STIX_LBMASK(stix_oow_t,STIX_LIW_BITS)*/;
|
||||
hw[1] = w >> STIX_LIW_BITS;
|
||||
z = stix_instantiate (stix, stix->_large_negative_integer, STIX_NULL, (hw[1] > 0? 2: 1) + extra);
|
||||
}
|
||||
@ -339,7 +339,7 @@ static STIX_INLINE stix_oop_t expand_bigint (stix_t* stix, stix_oop_t oop, stix_
|
||||
|
||||
if (inc > STIX_OBJ_SIZE_MAX - count)
|
||||
{
|
||||
stix->errnum = STIX_ENOMEM; /* TODO: is it a soft failure or a hard failure? is this error code proper? */
|
||||
stix->errnum = STIX_EOOMEM; /* TODO: is it a soft failure or a hard failure? is this error code proper? */
|
||||
return STIX_NULL;
|
||||
}
|
||||
|
||||
@ -857,7 +857,7 @@ static stix_oop_t add_unsigned_integers (stix_t* stix, stix_oop_t x, stix_oop_t
|
||||
|
||||
if (zs >= STIX_OBJ_SIZE_MAX)
|
||||
{
|
||||
stix->errnum = STIX_ENOMEM; /* TOOD: is it a soft failure or hard failure? */
|
||||
stix->errnum = STIX_EOOMEM; /* TOOD: is it a soft failure or hard failure? */
|
||||
return STIX_NULL;
|
||||
}
|
||||
zs++;
|
||||
@ -918,7 +918,7 @@ static stix_oop_t multiply_unsigned_integers (stix_t* stix, stix_oop_t x, stix_o
|
||||
|
||||
if (yz > STIX_OBJ_SIZE_MAX - xz)
|
||||
{
|
||||
stix->errnum = STIX_ENOMEM; /* TOOD: is it a soft failure or hard failure? */
|
||||
stix->errnum = STIX_EOOMEM; /* TOOD: is it a soft failure or hard failure? */
|
||||
return STIX_NULL;
|
||||
}
|
||||
|
||||
@ -1822,7 +1822,7 @@ stix_oop_t stix_bitorints (stix_t* stix, stix_oop_t x, stix_oop_t y)
|
||||
if (zalloc < zs)
|
||||
{
|
||||
/* overflow in zalloc calculation above */
|
||||
stix->errnum = STIX_ENOMEM; /* TODO: is it a soft failure or hard failure? */
|
||||
stix->errnum = STIX_EOOMEM; /* TODO: is it a soft failure or hard failure? */
|
||||
return STIX_NULL;
|
||||
}
|
||||
|
||||
@ -2040,7 +2040,7 @@ stix_oop_t stix_bitxorints (stix_t* stix, stix_oop_t x, stix_oop_t y)
|
||||
if (zalloc < zs)
|
||||
{
|
||||
/* overflow in zalloc calculation above */
|
||||
stix->errnum = STIX_ENOMEM; /* TODO: is it a soft failure or hard failure? */
|
||||
stix->errnum = STIX_EOOMEM; /* TODO: is it a soft failure or hard failure? */
|
||||
return STIX_NULL;
|
||||
}
|
||||
|
||||
@ -2199,7 +2199,7 @@ stix_oop_t stix_bitinvint (stix_t* stix, stix_oop_t x)
|
||||
if (zalloc < zs)
|
||||
{
|
||||
/* overflow in zalloc calculation above */
|
||||
stix->errnum = STIX_ENOMEM; /* TODO: is it a soft failure or hard failure? */
|
||||
stix->errnum = STIX_EOOMEM; /* TODO: is it a soft failure or hard failure? */
|
||||
return STIX_NULL;
|
||||
}
|
||||
|
||||
@ -2288,12 +2288,40 @@ stix_oop_t stix_bitshiftint (stix_t* stix, stix_oop_t x, stix_oop_t y)
|
||||
{
|
||||
/* right shift */
|
||||
stix_ooi_t v;
|
||||
/* TODO: ... */
|
||||
/* right shift of a negative number is complex... */
|
||||
v2 = -v2;
|
||||
if (v2 >= STIX_OOI_BITS) return STIX_SMOOI_TO_OOP(0);
|
||||
|
||||
v = v1 >> v2;
|
||||
v2 = -v2;
|
||||
if (v1 < 0)
|
||||
{
|
||||
/* guarantee arithmetic shift preserving the sign bit
|
||||
* regardless of compiler implementation.
|
||||
*
|
||||
* binary decimal shifted by
|
||||
* -------------------------------
|
||||
* 10000011 (-125) 0
|
||||
* 11000001 (-63) 1
|
||||
* 11100000 (-32) 2
|
||||
* 11110000 (-16) 3
|
||||
* 11111000 (-8) 4
|
||||
* 11111100 (-4) 5
|
||||
* 11111110 (-2) 6
|
||||
* 11111111 (-1) 7
|
||||
* 11111111 (-1) 8
|
||||
*/
|
||||
|
||||
if (v2 >= STIX_OOI_BITS - 1) v = -1;
|
||||
else
|
||||
{
|
||||
/* STIX_HBMASK_SAFE(stix_oow_t, v2 + 1) could also be
|
||||
* used as a mask. but the sign bit is shifted in.
|
||||
* so, masking up to 'v2' bits is sufficient */
|
||||
v = (stix_ooi_t)(((stix_oow_t)v1 >> v2) | STIX_HBMASK(stix_oow_t, v2));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (v2 >= STIX_OOI_BITS) v = 0;
|
||||
else v = v1 >> v2;
|
||||
}
|
||||
if (STIX_IN_SMOOI_RANGE(v)) return STIX_SMOOI_TO_OOP(v);
|
||||
return make_bigint_with_ooi (stix, v);
|
||||
}
|
||||
@ -2307,6 +2335,15 @@ stix_oop_t stix_bitshiftint (stix_t* stix, stix_oop_t x, stix_oop_t y)
|
||||
v = STIX_OOP_TO_SMOOI(x);
|
||||
if (v == 0) return STIX_SMOOI_TO_OOP(0);
|
||||
|
||||
if (STIX_OBJ_GET_CLASS(y) == stix->_large_negative_integer)
|
||||
{
|
||||
/* right shift - special case.
|
||||
* x is a small integer. it is just a few bytes long.
|
||||
* y is a large negative integer. its smallest absolute value
|
||||
* is STIX_SMOOI_MAX. i know the final answer. */
|
||||
return (v < 0)? STIX_SMOOI_TO_OOP(-1): STIX_SMOOI_TO_OOP(0);
|
||||
}
|
||||
|
||||
stix_pushtmp (stix, &y);
|
||||
x = make_bigint_with_ooi (stix, v);
|
||||
stix_poptmp (stix);
|
||||
@ -2348,10 +2385,24 @@ stix_oop_t stix_bitshiftint (stix_t* stix, stix_oop_t x, stix_oop_t y)
|
||||
/* y is too big or too small */
|
||||
if (negy)
|
||||
{
|
||||
/* TODO: right shift... */
|
||||
/* right shift */
|
||||
#if defined(STIX_LIMIT_OBJ_SIZE)
|
||||
return (negx)? STIX_SMOOI_TO_OOP(-1): STIX_SMOOI_TO_OOP(0);
|
||||
#else
|
||||
/* TODO: */
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
/* left shift */
|
||||
#if defined(STIX_LIMIT_OBJ_SIZE)
|
||||
/* the maximum number of bit shifts are guaranteed to be
|
||||
* small enough to fit into the stix_oow_t type, i can
|
||||
* simply return a failure here */
|
||||
STIX_ASSERT (STIX_TYPE_MAX(stix_oow_t) >= STIX_OBJ_SIZE_MAX * 8);
|
||||
stix->errnum = STIX_EOOMEM; /* is it a soft failure or a hard failure? is this error code proper? */
|
||||
return STIX_NULL;
|
||||
#else
|
||||
/* this loop is very inefficient as shifting is repeated
|
||||
* with lshift_unsigned_array(). however, this part of the
|
||||
* code is not likey to be useful because the amount of
|
||||
@ -2393,6 +2444,7 @@ stix_oop_t stix_bitshiftint (stix_t* stix, stix_oop_t x, stix_oop_t y)
|
||||
goto left_shift_last;
|
||||
else
|
||||
z = x;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if (sign >= 1)
|
||||
@ -2821,8 +2873,8 @@ stix_oop_t stix_inttostr (stix_t* stix, stix_oop_t num, int radix)
|
||||
b[0] = stix->bigint[radix].multiplier; /* block divisor */
|
||||
bs = 1;
|
||||
#elif (STIX_LIW_BITS == STIX_OOHW_BITS)
|
||||
b[0] = stix->bigint[radix].multiplier & STIX_LBMASK(stix_oow_t, STIX_OOHW_BITS);
|
||||
b[1] = stix->bigint[radix].multiplier >> STIX_OOHW_BITS;
|
||||
b[0] = stix->bigint[radix].multiplier /*& STIX_LBMASK(stix_oow_t, STIX_LIW_BITS)*/;
|
||||
b[1] = stix->bigint[radix].multiplier >> STIX_LIW_BITS;
|
||||
bs = (b[1] > 0)? 2: 1;
|
||||
#else
|
||||
# error UNSUPPORTED LIW BIT SIZE
|
||||
|
@ -2049,7 +2049,7 @@ static stix_ooi_t find_class_level_variable (stix_t* stix, stix_oop_class_t self
|
||||
super = ((stix_oop_class_t)super)->superclass;
|
||||
}
|
||||
|
||||
stix->errnum = STIX_ENOMEM;
|
||||
stix->errnum = STIX_ENOENT;
|
||||
return -1;
|
||||
|
||||
done:
|
||||
|
@ -54,7 +54,7 @@ static stix_oop_oop_t expand_bucket (stix_t* stix, stix_oop_oop_t oldbuc)
|
||||
if (inc_max > 0) inc = inc_max;
|
||||
else
|
||||
{
|
||||
stix->errnum = STIX_ENOMEM;
|
||||
stix->errnum = STIX_EOOMEM;
|
||||
return STIX_NULL;
|
||||
}
|
||||
}
|
||||
|
@ -1932,7 +1932,7 @@ static stix_prim_impl_t query_prim_module (stix_t* stix, const stix_ooch_t* name
|
||||
pair = stix_rbt_insert (stix->modtab, name, mod_name_len, &md, STIX_SIZEOF(md));
|
||||
if (pair == STIX_NULL)
|
||||
{
|
||||
stix->errnum = STIX_ENOMEM;
|
||||
stix->errnum = STIX_ESYSMEM;
|
||||
return STIX_NULL;
|
||||
}
|
||||
|
||||
@ -1974,7 +1974,7 @@ static stix_prim_impl_t query_prim_module (stix_t* stix, const stix_ooch_t* name
|
||||
pair = stix_rbt_insert (&stix->pmtable, (void*)name, mod_name_len, &md, STIX_SIZEOF(md));
|
||||
if (pair == STIX_NULL)
|
||||
{
|
||||
stix->errnum = STIX_ENOMEM;
|
||||
stix->errnum = STIX_ESYSMEM;
|
||||
stix->vmprim.mod_close (stix, md.handle);
|
||||
return STIX_NULL;
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ stix_heap_t* stix_makeheap (stix_t* stix, stix_oow_t size)
|
||||
heap = (stix_heap_t*)STIX_MMGR_ALLOC(stix->mmgr, STIX_SIZEOF(*heap) + size);
|
||||
if (!heap)
|
||||
{
|
||||
stix->errnum = STIX_ENOMEM;
|
||||
stix->errnum = STIX_ESYSMEM;
|
||||
return STIX_NULL;
|
||||
}
|
||||
|
||||
@ -70,7 +70,7 @@ void* stix_allocheapmem (stix_t* stix, stix_heap_t* heap, stix_oow_t size)
|
||||
if (STIX_GEPTR(stix_uint8_t, heap->ptr, heap->limit) ||
|
||||
STIX_SUBPTR(stix_uint8_t, heap->limit, heap->ptr) < size)
|
||||
{
|
||||
stix->errnum = STIX_ENOMEM;
|
||||
stix->errnum = STIX_EOOMEM;
|
||||
return STIX_NULL;
|
||||
}
|
||||
|
||||
|
@ -347,8 +347,13 @@ typedef stix_ucs_t stix_oocs_t;
|
||||
# define STIX_NULL ((void*)0)
|
||||
#endif
|
||||
|
||||
/* make a low bit mask that can mask off low n bits*/
|
||||
/* make a bit mask that can mask off low n bits */
|
||||
#define STIX_LBMASK(type,n) (~(~((type)0) << (n)))
|
||||
#define STIX_LBMASK_SAFE(type,n) (((n) < STIX_SIZEOF(type) * 8)? STIX_LBMASK(type,n): ~(type)0)
|
||||
|
||||
/* make a bit mask that can mask off hig n bits */
|
||||
#define STIX_HBMASK(type,n) (~(~((type)0) >> (n)))
|
||||
#define STIX_HBMASK_SAFE(type,n) (((n) < STIX_SIZEOF(type) * 8)? STIX_HBMASK(type,n): ~(type)0)
|
||||
|
||||
/* get 'length' bits starting from the bit at the 'offset' */
|
||||
#define STIX_GETBITS(type,value,offset,length) \
|
||||
@ -538,11 +543,11 @@ struct stix_cmgr_t
|
||||
#define STIX_TYPE_IS_UNSIGNED(type) (((type)0) < ((type)-1))
|
||||
|
||||
#define STIX_TYPE_SIGNED_MAX(type) \
|
||||
((type)~((type)1 << (STIX_SIZEOF(type) * 8 - 1)))
|
||||
((type)~((type)1 << ((type)STIX_SIZEOF(type) * 8 - 1)))
|
||||
#define STIX_TYPE_UNSIGNED_MAX(type) ((type)(~(type)0))
|
||||
|
||||
#define STIX_TYPE_SIGNED_MIN(type) \
|
||||
((type)((type)1 << (STIX_SIZEOF(type) * 8 - 1)))
|
||||
((type)((type)1 << ((type)STIX_SIZEOF(type) * 8 - 1)))
|
||||
#define STIX_TYPE_UNSIGNED_MIN(type) ((type)0)
|
||||
|
||||
#define STIX_TYPE_MAX(type) \
|
||||
|
@ -55,6 +55,13 @@
|
||||
/*#define STIX_DEBUG_EXEC*/
|
||||
#define STIX_PROFILE_EXEC
|
||||
|
||||
/* limit the maximum object size such that:
|
||||
* 1. an index to an object field can be represented in a small integer.
|
||||
* 2. the maximum number of bit shifts can be represented in the stix_oow_t type.
|
||||
*/
|
||||
#define STIX_LIMIT_OBJ_SIZE
|
||||
|
||||
|
||||
#include <stdio.h> /* TODO: delete these header inclusion lines */
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
@ -207,6 +214,18 @@
|
||||
#define STIX_MAX_CLASSVARS STIX_BITS_MAX(stix_oow_t, STIX_SMOOI_ABS_BITS / 2)
|
||||
#define STIX_MAX_CLASSINSTVARS STIX_BITS_MAX(stix_oow_t, STIX_SMOOI_ABS_BITS / 2)
|
||||
|
||||
|
||||
#if defined(STIX_LIMIT_OBJ_SIZE)
|
||||
/* limit the maximum object size such that:
|
||||
* 1. an index to an object field can be represented in a small integer.
|
||||
* 2. the maximum number of bit shifts can be represented in the stix_oow_t type.
|
||||
*/
|
||||
# define STIX_OBJ_SIZE_MAX ((stix_oow_t)STIX_SMOOI_MAX)
|
||||
#else
|
||||
# define STIX_OBJ_SIZE_MAX ((stix_oow_t)STIX_TYPE_MAX(stix_oow_t))
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(STIX_INCLUDE_COMPILER)
|
||||
|
||||
/* ========================================================================= */
|
||||
|
@ -45,7 +45,7 @@ stix_t* stix_open (stix_mmgr_t* mmgr, stix_oow_t xtnsize, stix_oow_t heapsize, c
|
||||
}
|
||||
else STIX_MEMSET (stix + 1, 0, xtnsize);
|
||||
}
|
||||
else if (errnum) *errnum = STIX_ENOMEM;
|
||||
else if (errnum) *errnum = STIX_ESYSMEM;
|
||||
|
||||
return stix;
|
||||
}
|
||||
@ -249,7 +249,7 @@ void* stix_allocmem (stix_t* stix, stix_oow_t size)
|
||||
void* ptr;
|
||||
|
||||
ptr = STIX_MMGR_ALLOC (stix->mmgr, size);
|
||||
if (!ptr) stix->errnum = STIX_ENOMEM;
|
||||
if (!ptr) stix->errnum = STIX_ESYSMEM;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@ -258,7 +258,7 @@ void* stix_callocmem (stix_t* stix, stix_oow_t size)
|
||||
void* ptr;
|
||||
|
||||
ptr = STIX_MMGR_ALLOC (stix->mmgr, size);
|
||||
if (!ptr) stix->errnum = STIX_ENOMEM;
|
||||
if (!ptr) stix->errnum = STIX_ESYSMEM;
|
||||
else STIX_MEMSET (ptr, 0, size);
|
||||
return ptr;
|
||||
}
|
||||
@ -266,7 +266,7 @@ void* stix_callocmem (stix_t* stix, stix_oow_t size)
|
||||
void* stix_reallocmem (stix_t* stix, void* ptr, stix_oow_t size)
|
||||
{
|
||||
ptr = STIX_MMGR_REALLOC (stix->mmgr, ptr, size);
|
||||
if (!ptr) stix->errnum = STIX_ENOMEM;
|
||||
if (!ptr) stix->errnum = STIX_ESYSMEM;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,8 @@ enum stix_errnum_t
|
||||
STIX_ENOIMPL, /**< not implemented */
|
||||
STIX_ESYSERR, /**< subsystem error */
|
||||
STIX_EINTERN, /**< internal error */
|
||||
STIX_ENOMEM, /**< insufficient memory */
|
||||
STIX_ESYSMEM, /**< insufficient system memory */
|
||||
STIX_EOOMEM, /**< insufficient object memory */
|
||||
STIX_EINVAL, /**< invalid parameter or data */
|
||||
STIX_ERANGE, /**< range error. overflow and underflow */
|
||||
STIX_ENOENT, /**< no matching entry */
|
||||
@ -296,9 +297,6 @@ typedef enum stix_obj_type_t stix_obj_type_t;
|
||||
(((stix_oow_t)(r)) << 0) \
|
||||
)
|
||||
|
||||
#define STIX_OBJ_SIZE_MAX ((stix_oow_t)STIX_SMOOI_MAX)
|
||||
/*#define STIX_OBJ_SIZE_MAX ((stix_oow_t)STIX_TYPE_MAX(stix_oow_t))*/
|
||||
|
||||
#define STIX_OBJ_HEADER \
|
||||
stix_oow_t _flags; \
|
||||
stix_oow_t _size; \
|
||||
|
@ -53,7 +53,7 @@ static stix_oop_oop_t expand_bucket (stix_t* stix, stix_oop_oop_t oldbuc)
|
||||
if (inc_max > 0) inc = inc_max;
|
||||
else
|
||||
{
|
||||
stix->errnum = STIX_ENOMEM;
|
||||
stix->errnum = STIX_EOOMEM;
|
||||
return STIX_NULL;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user