added stix_isint(), stix_inttooow(), stix_oowtoint().

added stix_eqints(), stix_neints(), stix_gtints(), stix_geints(), stix_ltints(), stix_leints().
enhanced some primitive handlers to support large integers
This commit is contained in:
hyunghwan.chung 2015-12-27 18:02:59 +00:00
parent fff2af4762
commit c427f39a12
9 changed files with 627 additions and 284 deletions

View File

@ -43,6 +43,18 @@
self primitiveFailed.
}
#method(#class) ngcNew
{
<primitive: #_ngc_new>
self primitiveFailed.
}
#method(#class) ngcNew: anInteger
{
<primitive: #_ngc_new_with_size>
self primitiveFailed.
}
#method(#class) new
{
| x |
@ -66,6 +78,11 @@
^self.
}
#method ngcDispose
{
<primitive: #_ngc_dispose>
self primitiveFailed.
}
## -------------------------------------------------------
## -------------------------------------------------------
#method shallowCopy

View File

@ -186,6 +186,19 @@
{
^self to: end by: 1 do: aBlock.
}
#method abs
{
self < 0 ifTrue: [^self negated].
^self.
}
#method sign
{
self < 0 ifTrue: [^-1].
self > 0 ifTrue: [^1].
^0.
}
}
#class SmallInteger(Number)

View File

@ -407,6 +407,7 @@ PROCESS TESTING
##self a: 1 b: 2 c: 3 d: 4 e: 5 f: 6 g: 7.
##self a: 1 b: 2 c: 3.
"
FFI isNil dump.
FFI notNil dump.

View File

@ -192,47 +192,34 @@ static int is_normalized_integer (stix_t* stix, stix_oop_t oop)
return 0;
}
static STIX_INLINE int is_integer (stix_t* stix, stix_oop_t oop)
STIX_INLINE int is_bigint (stix_t* stix, stix_oop_t x)
{
if (STIX_OOP_IS_SMOOI(oop)) return 1;
if (STIX_OOP_IS_POINTER(oop))
{
stix_oop_t c;
stix_oop_t c;
STIX_ASSERT (STIX_OOP_IS_POINTER(x));
/* TODO: is it better to introduce a special integer mark into the class itself */
/* TODO: or should it check if it's a subclass, subsubclass, subsubsubclass, etc of a large_integer as well? */
c = STIX_OBJ_GET_CLASS(oop);
c = STIX_OBJ_GET_CLASS(x);
if (c == stix->_large_positive_integer ||
c == stix->_large_negative_integer) return 1;
}
if (c == stix->_large_positive_integer ||
c == stix->_large_negative_integer) return 1;
return 0;
}
static STIX_INLINE int integer_to_oow (stix_t* stix, stix_oop_t num, stix_oow_t* w)
STIX_INLINE int stix_isint (stix_t* stix, stix_oop_t x)
{
/* return value
* 1 - a positive number including 0 that can fit into stix_oow_t
* -1 - a negative number whose absolute value can fit into stix_oow_t
* 0 - number too large or too small
*/
if (STIX_OOP_IS_SMOOI(x)) return 1;
if (STIX_OOP_IS_POINTER(x)) return is_bigint(stix, x);
return 0;
}
if (STIX_OOP_IS_SMOOI(num))
{
stix_ooi_t v;
v = STIX_OOP_TO_SMOOI(num);
if (v < 0)
{
*w = -v;
return -1;
}
else
{
*w = v;
return 1;
}
}
static STIX_INLINE int bigint_to_oow (stix_t* stix, stix_oop_t num, stix_oow_t* w)
{
STIX_ASSERT (STIX_OOP_IS_POINTER(num));
STIX_ASSERT (STIX_OBJ_GET_CLASS(num) == stix->_large_positive_integer ||
STIX_OBJ_GET_CLASS(num) == stix->_large_negative_integer);
#if (STIX_LIW_BITS == STIX_OOW_BITS)
STIX_ASSERT (STIX_OBJ_GET_SIZE(num) >= 1);
@ -261,6 +248,74 @@ static STIX_INLINE int integer_to_oow (stix_t* stix, stix_oop_t num, stix_oow_t*
return 0; /* not convertable */
}
static STIX_INLINE int integer_to_oow (stix_t* stix, stix_oop_t x, stix_oow_t* w)
{
/* return value
* 1 - a positive number including 0 that can fit into stix_oow_t
* -1 - a negative number whose absolute value can fit into stix_oow_t
* 0 - number too large or too small
*/
if (STIX_OOP_IS_SMOOI(x))
{
stix_ooi_t v;
v = STIX_OOP_TO_SMOOI(x);
if (v < 0)
{
*w = -v;
return -1;
}
else
{
*w = v;
return 1;
}
}
STIX_ASSERT (is_bigint(stix, x));
return bigint_to_oow (stix, x, w);
}
int stix_inttooow (stix_t* stix, stix_oop_t x, stix_oow_t* w)
{
if (STIX_OOP_IS_SMOOI(x))
{
stix_ooi_t v;
v = STIX_OOP_TO_SMOOI(x);
if (v < 0)
{
*w = -v;
return -1;
}
else
{
*w = v;
return 1;
}
}
if (is_bigint(stix, x)) return bigint_to_oow (stix, x, w);
return 0; /* not convertable - too big, too small, or not an integer */
}
static STIX_INLINE stix_oop_t make_bigint_with_oow (stix_t* stix, stix_oow_t w)
{
#if (STIX_LIW_BITS == STIX_OOW_BITS)
STIX_ASSERT (STIX_SIZEOF(stix_oow_t) == STIX_SIZEOF(stix_liw_t));
return stix_instantiate (stix, stix->_large_positive_integer, &w, 1);
#elif (STIX_LIW_BITS == STIX_OOHW_BITS)
stix_liw_t hw[2];
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));
#else
# error UNSUPPORTED LIW BIT SIZE
#endif
}
static STIX_INLINE stix_oop_t make_bigint_with_ooi (stix_t* stix, stix_ooi_t i)
{
#if (STIX_LIW_BITS == STIX_OOW_BITS)
@ -382,6 +437,18 @@ static STIX_INLINE stix_oop_t make_bigint_with_intmax (stix_t* stix, stix_intmax
return stix_instantiate (stix, ((v >= 0)? stix->_large_positive_integer: stix->_large_negative_integer), buf, len);
}
stix_oop_t stix_oowtoint (stix_t* stix, stix_oow_t w)
{
if (STIX_IN_SMOOI_RANGE(w))
{
return STIX_SMOOI_TO_OOP(w);
}
else
{
return make_bigint_with_oow(stix, w);
}
}
static STIX_INLINE stix_oop_t expand_bigint (stix_t* stix, stix_oop_t oop, stix_oow_t inc)
{
stix_oop_t z;
@ -579,7 +646,52 @@ static STIX_INLINE int is_less (stix_t* stix, stix_oop_t x, stix_oop_t y)
return STIX_OBJ_GET_CLASS(x) == stix->_large_negative_integer;
}
return is_less_unsigned (x, y);
if (STIX_OBJ_GET_CLASS(x) == stix->_large_positive_integer)
{
return is_less_unsigned (x, y);
}
else
{
return is_less_unsigned (y, x);
}
}
static STIX_INLINE int is_greater_unsigned_array (const stix_liw_t* x, stix_oow_t xs, const stix_liw_t* y, stix_oow_t ys)
{
stix_oow_t i;
if (xs != ys) return xs > ys;
for (i = xs; i > 0; )
{
--i;
if (x[i] != y[i]) return x[i] > y[i];
}
return 0;
}
static STIX_INLINE int is_greater_unsigned (stix_oop_t x, stix_oop_t y)
{
return is_greater_unsigned_array (
((stix_oop_liword_t)x)->slot, STIX_OBJ_GET_SIZE(x),
((stix_oop_liword_t)y)->slot, STIX_OBJ_GET_SIZE(y));
}
static STIX_INLINE int is_greater (stix_t* stix, stix_oop_t x, stix_oop_t y)
{
if (STIX_OBJ_GET_CLASS(x) != STIX_OBJ_GET_CLASS(y))
{
return STIX_OBJ_GET_CLASS(y) == stix->_large_negative_integer;
}
if (STIX_OBJ_GET_CLASS(x) == stix->_large_positive_integer)
{
return is_greater_unsigned (x, y);
}
else
{
return is_greater_unsigned (y, x);
}
}
static STIX_INLINE int is_equal (stix_t* stix, stix_oop_t x, stix_oop_t y)
@ -1042,7 +1154,7 @@ stix_oop_t stix_addints (stix_t* stix, stix_oop_t x, stix_oop_t y)
if (STIX_OOP_IS_SMOOI(x))
{
if (!is_integer(stix,y)) goto oops_einval;
if (!is_bigint(stix,y)) goto oops_einval;
v = STIX_OOP_TO_SMOOI(x);
if (v == 0) return clone_bigint (stix, y, STIX_OBJ_GET_SIZE(y));
@ -1054,7 +1166,7 @@ stix_oop_t stix_addints (stix_t* stix, stix_oop_t x, stix_oop_t y)
}
else if (STIX_OOP_IS_SMOOI(y))
{
if (!is_integer(stix,x)) goto oops_einval;
if (!is_bigint(stix,x)) goto oops_einval;
v = STIX_OOP_TO_SMOOI(y);
if (v == 0) return clone_bigint (stix, x, STIX_OBJ_GET_SIZE(x));
@ -1066,8 +1178,8 @@ stix_oop_t stix_addints (stix_t* stix, stix_oop_t x, stix_oop_t y)
}
else
{
if (!is_integer(stix,x)) goto oops_einval;
if (!is_integer(stix,y)) goto oops_einval;
if (!is_bigint(stix,x)) goto oops_einval;
if (!is_bigint(stix,y)) goto oops_einval;
}
if (STIX_OBJ_GET_CLASS(x) != STIX_OBJ_GET_CLASS(y))
@ -1146,7 +1258,7 @@ stix_oop_t stix_subints (stix_t* stix, stix_oop_t x, stix_oop_t y)
if (STIX_OOP_IS_SMOOI(x))
{
if (!is_integer(stix,y)) goto oops_einval;
if (!is_bigint(stix,y)) goto oops_einval;
v = STIX_OOP_TO_SMOOI(x);
if (v == 0)
@ -1162,7 +1274,7 @@ stix_oop_t stix_subints (stix_t* stix, stix_oop_t x, stix_oop_t y)
}
else if (STIX_OOP_IS_SMOOI(y))
{
if (!is_integer(stix,x)) goto oops_einval;
if (!is_bigint(stix,x)) goto oops_einval;
v = STIX_OOP_TO_SMOOI(y);
if (v == 0) return clone_bigint (stix, x, STIX_OBJ_GET_SIZE(x));
@ -1174,8 +1286,8 @@ stix_oop_t stix_subints (stix_t* stix, stix_oop_t x, stix_oop_t y)
}
else
{
if (!is_integer(stix,x)) goto oops_einval;
if (!is_integer(stix,y)) goto oops_einval;
if (!is_bigint(stix,x)) goto oops_einval;
if (!is_bigint(stix,y)) goto oops_einval;
}
if (STIX_OBJ_GET_CLASS(x) != STIX_OBJ_GET_CLASS(y))
@ -1258,7 +1370,7 @@ stix_oop_t stix_mulints (stix_t* stix, stix_oop_t x, stix_oop_t y)
if (STIX_OOP_IS_SMOOI(x))
{
if (!is_integer(stix,y)) goto oops_einval;
if (!is_bigint(stix,y)) goto oops_einval;
v = STIX_OOP_TO_SMOOI(x);
switch (v)
@ -1278,7 +1390,7 @@ stix_oop_t stix_mulints (stix_t* stix, stix_oop_t x, stix_oop_t y)
}
else if (STIX_OOP_IS_SMOOI(y))
{
if (!is_integer(stix,x)) goto oops_einval;
if (!is_bigint(stix,x)) goto oops_einval;
v = STIX_OOP_TO_SMOOI(y);
switch (v)
@ -1298,8 +1410,8 @@ stix_oop_t stix_mulints (stix_t* stix, stix_oop_t x, stix_oop_t y)
}
else
{
if (!is_integer(stix,x)) goto oops_einval;
if (!is_integer(stix,y)) goto oops_einval;
if (!is_bigint(stix,x)) goto oops_einval;
if (!is_bigint(stix,y)) goto oops_einval;
}
normal:
@ -1427,7 +1539,7 @@ stix_oop_t stix_divints (stix_t* stix, stix_oop_t x, stix_oop_t y, int modulo, s
{
stix_ooi_t v;
if (!is_integer(stix,y)) goto oops_einval;
if (!is_bigint(stix,y)) goto oops_einval;
v = STIX_OOP_TO_SMOOI(x);
if (v == 0)
@ -1445,7 +1557,7 @@ stix_oop_t stix_divints (stix_t* stix, stix_oop_t x, stix_oop_t y, int modulo, s
{
stix_ooi_t v;
if (!is_integer(stix,x)) goto oops_einval;
if (!is_bigint(stix,x)) goto oops_einval;
v = STIX_OOP_TO_SMOOI(y);
switch (v)
@ -1488,8 +1600,8 @@ stix_oop_t stix_divints (stix_t* stix, stix_oop_t x, stix_oop_t y, int modulo, s
}
else
{
if (!is_integer(stix,x)) goto oops_einval;
if (!is_integer(stix,y)) goto oops_einval;
if (!is_bigint(stix,x)) goto oops_einval;
if (!is_bigint(stix,y)) goto oops_einval;
}
}
@ -1579,7 +1691,7 @@ stix_oop_t stix_negateint (stix_t* stix, stix_oop_t x)
}
else
{
if (!is_integer(stix, x)) goto oops_einval;
if (!is_bigint(stix, x)) goto oops_einval;
return clone_bigint_negated (stix, x, STIX_OBJ_GET_SIZE(x));
}
@ -1614,7 +1726,7 @@ stix_oop_t stix_bitatint (stix_t* stix, stix_oop_t x, stix_oop_t y)
}
else if (STIX_OOP_IS_SMOOI(x))
{
if (!is_integer(stix, y)) goto oops_einval;
if (!is_bigint(stix, y)) goto oops_einval;
if (STIX_OBJ_GET_CLASS(y) == stix->_large_negative_integer) return STIX_SMOOI_TO_OOP(0);
/* y is definitely >= STIX_SMOOI_BITS */
@ -1628,7 +1740,7 @@ stix_oop_t stix_bitatint (stix_t* stix, stix_oop_t x, stix_oop_t y)
stix_ooi_t v;
stix_oow_t wp, bp, xs;
if (!is_integer(stix, x)) goto oops_einval;
if (!is_bigint(stix, x)) goto oops_einval;
v = STIX_OOP_TO_SMOOI(y);
if (v <= 0) return STIX_SMOOI_TO_OOP(0);
@ -1669,7 +1781,7 @@ stix_oop_t stix_bitatint (stix_t* stix, stix_oop_t x, stix_oop_t y)
int sign;
#endif
if (!is_integer(stix, x) || !is_integer(stix, y)) goto oops_einval;
if (!is_bigint(stix, x) || !is_bigint(stix, y)) goto oops_einval;
#if defined(STIX_LIMIT_OBJ_SIZE)
if (STIX_OBJ_GET_CLASS(y) == stix->_large_negative_integer) return STIX_SMOOI_TO_OOP(0);
@ -1688,7 +1800,7 @@ stix_oop_t stix_bitatint (stix_t* stix, stix_oop_t x, stix_oop_t y)
if (STIX_OBJ_GET_CLASS(y) == stix->_large_negative_integer) return STIX_SMOOI_TO_OOP(0);
sign = integer_to_oow (stix, y, &w);
sign = bigint_to_oow (stix, y, &w);
STIX_ASSERT (sign >= 0);
if (sign >= 1)
{
@ -1772,7 +1884,7 @@ stix_oop_t stix_bitandints (stix_t* stix, stix_oop_t x, stix_oop_t y)
{
stix_ooi_t v;
if (!is_integer(stix, y)) goto oops_einval;
if (!is_bigint(stix, y)) goto oops_einval;
v = STIX_OOP_TO_SMOOI(x);
if (v == 0) return STIX_SMOOI_TO_OOP(0);
@ -1788,7 +1900,7 @@ stix_oop_t stix_bitandints (stix_t* stix, stix_oop_t x, stix_oop_t y)
{
stix_ooi_t v;
if (!is_integer(stix, x)) goto oops_einval;
if (!is_bigint(stix, x)) goto oops_einval;
v = STIX_OOP_TO_SMOOI(y);
if (v == 0) return STIX_SMOOI_TO_OOP(0);
@ -1806,7 +1918,7 @@ stix_oop_t stix_bitandints (stix_t* stix, stix_oop_t x, stix_oop_t y)
stix_oow_t i, xs, ys, zs, zalloc;
int negx, negy;
if (!is_integer(stix,x) || !is_integer(stix, y)) goto oops_einval;
if (!is_bigint(stix,x) || !is_bigint(stix, y)) goto oops_einval;
bigint_and_bigint:
xs = STIX_OBJ_GET_SIZE(x);
@ -1985,7 +2097,7 @@ stix_oop_t stix_bitorints (stix_t* stix, stix_oop_t x, stix_oop_t y)
{
stix_ooi_t v;
if (!is_integer(stix, y)) goto oops_einval;
if (!is_bigint(stix, y)) goto oops_einval;
v = STIX_OOP_TO_SMOOI(x);
if (v == 0) return clone_bigint(stix, y, STIX_OBJ_GET_SIZE(y));
@ -2001,7 +2113,7 @@ stix_oop_t stix_bitorints (stix_t* stix, stix_oop_t x, stix_oop_t y)
{
stix_ooi_t v;
if (!is_integer(stix, x)) goto oops_einval;
if (!is_bigint(stix, x)) goto oops_einval;
v = STIX_OOP_TO_SMOOI(y);
if (v == 0) return clone_bigint(stix, x, STIX_OBJ_GET_SIZE(x));
@ -2019,7 +2131,7 @@ stix_oop_t stix_bitorints (stix_t* stix, stix_oop_t x, stix_oop_t y)
stix_oow_t i, xs, ys, zs, zalloc;
int negx, negy;
if (!is_integer(stix,x) || !is_integer(stix, y)) goto oops_einval;
if (!is_bigint(stix,x) || !is_bigint(stix, y)) goto oops_einval;
bigint_and_bigint:
xs = STIX_OBJ_GET_SIZE(x);
@ -2203,7 +2315,7 @@ stix_oop_t stix_bitxorints (stix_t* stix, stix_oop_t x, stix_oop_t y)
{
stix_ooi_t v;
if (!is_integer(stix, y)) goto oops_einval;
if (!is_bigint(stix, y)) goto oops_einval;
v = STIX_OOP_TO_SMOOI(x);
if (v == 0) return clone_bigint(stix, y, STIX_OBJ_GET_SIZE(y));
@ -2219,7 +2331,7 @@ stix_oop_t stix_bitxorints (stix_t* stix, stix_oop_t x, stix_oop_t y)
{
stix_ooi_t v;
if (!is_integer(stix, x)) goto oops_einval;
if (!is_bigint(stix, x)) goto oops_einval;
v = STIX_OOP_TO_SMOOI(y);
if (v == 0) return clone_bigint(stix, x, STIX_OBJ_GET_SIZE(x));
@ -2237,7 +2349,7 @@ stix_oop_t stix_bitxorints (stix_t* stix, stix_oop_t x, stix_oop_t y)
stix_oow_t i, xs, ys, zs, zalloc;
int negx, negy;
if (!is_integer(stix,x) || !is_integer(stix, y)) goto oops_einval;
if (!is_bigint(stix,x) || !is_bigint(stix, y)) goto oops_einval;
bigint_and_bigint:
xs = STIX_OBJ_GET_SIZE(x);
@ -2421,7 +2533,7 @@ stix_oop_t stix_bitinvint (stix_t* stix, stix_oop_t x)
stix_oow_t i, xs, zs, zalloc;
int negx;
if (!is_integer(stix,x)) goto oops_einval;
if (!is_bigint(stix,x)) goto oops_einval;
xs = STIX_OBJ_GET_SIZE(x);
negx = (STIX_OBJ_GET_CLASS(x) == stix->_large_negative_integer)? 1: 0;
@ -2842,7 +2954,7 @@ stix_oop_t stix_bitshiftint (stix_t* stix, stix_oop_t x, stix_oop_t y)
{
stix_ooi_t v;
if (!is_integer(stix,y)) goto oops_einval;
if (!is_bigint(stix,y)) goto oops_einval;
v = STIX_OOP_TO_SMOOI(x);
if (v == 0) return STIX_SMOOI_TO_OOP(0);
@ -2867,7 +2979,7 @@ stix_oop_t stix_bitshiftint (stix_t* stix, stix_oop_t x, stix_oop_t y)
{
stix_ooi_t v;
if (!is_integer(stix,x)) goto oops_einval;
if (!is_bigint(stix,x)) goto oops_einval;
v = STIX_OOP_TO_SMOOI(y);
if (v == 0) return clone_bigint (stix, x, STIX_OBJ_GET_SIZE(x));
@ -2892,13 +3004,13 @@ stix_oop_t stix_bitshiftint (stix_t* stix, stix_oop_t x, stix_oop_t y)
{
stix_oop_t z;
if (!is_integer(stix,x) || !is_integer(stix, y)) goto oops_einval;
if (!is_bigint(stix,x) || !is_bigint(stix, y)) goto oops_einval;
bigint_and_bigint:
negx = (STIX_OBJ_GET_CLASS(x) == stix->_large_negative_integer)? 1: 0;
negy = (STIX_OBJ_GET_CLASS(y) == stix->_large_negative_integer)? 1: 0;
sign = integer_to_oow (stix, y, &shift);
sign = bigint_to_oow (stix, y, &shift);
if (sign == 0)
{
/* y is too big or too small */
@ -3249,6 +3361,156 @@ static void reverse_string (stix_ooch_t* str, stix_oow_t len)
}
}
stix_oop_t stix_eqints (stix_t* stix, stix_oop_t x, stix_oop_t y)
{
if (STIX_OOP_IS_SMOOI(x) && STIX_OOP_IS_SMOOI(y))
{
return (STIX_OOP_TO_SMOOI(x) == STIX_OOP_TO_SMOOI(y))? stix->_true: stix->_false;
}
else if (STIX_OOP_IS_SMOOI(x) || STIX_OOP_IS_SMOOI(y))
{
return stix->_false;
}
else
{
if (!is_bigint(stix, x) || !is_bigint(stix, y)) goto oops_einval;
return is_equal(stix, x, y)? stix->_true: stix->_false;
}
oops_einval:
stix->errnum = STIX_EINVAL;
return STIX_NULL;
}
stix_oop_t stix_neints (stix_t* stix, stix_oop_t x, stix_oop_t y)
{
if (STIX_OOP_IS_SMOOI(x) && STIX_OOP_IS_SMOOI(y))
{
return (STIX_OOP_TO_SMOOI(x) != STIX_OOP_TO_SMOOI(y))? stix->_true: stix->_false;
}
else if (STIX_OOP_IS_SMOOI(x) || STIX_OOP_IS_SMOOI(y))
{
return stix->_true;
}
else
{
if (!is_bigint(stix, x) || !is_bigint(stix, y)) goto oops_einval;
return !is_equal(stix, x, y)? stix->_true: stix->_false;
}
oops_einval:
stix->errnum = STIX_EINVAL;
return STIX_NULL;
}
stix_oop_t stix_gtints (stix_t* stix, stix_oop_t x, stix_oop_t y)
{
if (STIX_OOP_IS_SMOOI(x) && STIX_OOP_IS_SMOOI(y))
{
return (STIX_OOP_TO_SMOOI(x) > STIX_OOP_TO_SMOOI(y))? stix->_true: stix->_false;
}
else if (STIX_OOP_IS_SMOOI(x))
{
if (!is_bigint(stix, y)) goto oops_einval;
return (STIX_OBJ_GET_CLASS(y) == stix->_large_negative_integer)? stix->_true: stix->_false;
}
else if (STIX_OOP_IS_SMOOI(y))
{
if (!is_bigint(stix, x)) goto oops_einval;
return (STIX_OBJ_GET_CLASS(x) == stix->_large_positive_integer)? stix->_true: stix->_false;
}
else
{
if (!is_bigint(stix, x) || !is_bigint(stix, y)) goto oops_einval;
return is_greater(stix, x, y)? stix->_true: stix->_false;
}
oops_einval:
stix->errnum = STIX_EINVAL;
return STIX_NULL;
}
stix_oop_t stix_geints (stix_t* stix, stix_oop_t x, stix_oop_t y)
{
if (STIX_OOP_IS_SMOOI(x) && STIX_OOP_IS_SMOOI(y))
{
return (STIX_OOP_TO_SMOOI(x) >= STIX_OOP_TO_SMOOI(y))? stix->_true: stix->_false;
}
else if (STIX_OOP_IS_SMOOI(x))
{
if (!is_bigint(stix, y)) goto oops_einval;
return (STIX_OBJ_GET_CLASS(y) == stix->_large_negative_integer)? stix->_true: stix->_false;
}
else if (STIX_OOP_IS_SMOOI(y))
{
if (!is_bigint(stix, x)) goto oops_einval;
return (STIX_OBJ_GET_CLASS(x) == stix->_large_positive_integer)? stix->_true: stix->_false;
}
else
{
if (!is_bigint(stix, x) || !is_bigint(stix, y)) goto oops_einval;
return (is_greater(stix, x, y) || is_equal(stix, x, y))? stix->_true: stix->_false;
}
oops_einval:
stix->errnum = STIX_EINVAL;
return STIX_NULL;
}
stix_oop_t stix_ltints (stix_t* stix, stix_oop_t x, stix_oop_t y)
{
if (STIX_OOP_IS_SMOOI(x) && STIX_OOP_IS_SMOOI(y))
{
return (STIX_OOP_TO_SMOOI(x) < STIX_OOP_TO_SMOOI(y))? stix->_true: stix->_false;
}
else if (STIX_OOP_IS_SMOOI(x))
{
if (!is_bigint(stix, y)) goto oops_einval;
return (STIX_OBJ_GET_CLASS(y) == stix->_large_positive_integer)? stix->_true: stix->_false;
}
else if (STIX_OOP_IS_SMOOI(y))
{
if (!is_bigint(stix, x)) goto oops_einval;
return (STIX_OBJ_GET_CLASS(x) == stix->_large_negative_integer)? stix->_true: stix->_false;
}
else
{
if (!is_bigint(stix, x) || !is_bigint(stix, y)) goto oops_einval;
return is_less(stix, x, y)? stix->_true: stix->_false;
}
oops_einval:
stix->errnum = STIX_EINVAL;
return STIX_NULL;
}
stix_oop_t stix_leints (stix_t* stix, stix_oop_t x, stix_oop_t y)
{
if (STIX_OOP_IS_SMOOI(x) && STIX_OOP_IS_SMOOI(y))
{
return (STIX_OOP_TO_SMOOI(x) <= STIX_OOP_TO_SMOOI(y))? stix->_true: stix->_false;
}
else if (STIX_OOP_IS_SMOOI(x))
{
if (!is_bigint(stix, y)) goto oops_einval;
return (STIX_OBJ_GET_CLASS(y) == stix->_large_positive_integer)? stix->_true: stix->_false;
}
else if (STIX_OOP_IS_SMOOI(y))
{
if (!is_bigint(stix, x)) goto oops_einval;
return (STIX_OBJ_GET_CLASS(x) == stix->_large_negative_integer)? stix->_true: stix->_false;
}
else
{
if (!is_bigint(stix, x) || !is_bigint(stix, y)) goto oops_einval;
return (is_less(stix, x, y) || is_equal(stix, x, y))? stix->_true: stix->_false;
}
oops_einval:
stix->errnum = STIX_EINVAL;
return STIX_NULL;
}
stix_oop_t stix_inttostr (stix_t* stix, stix_oop_t num, int radix)
{
stix_ooi_t v = 0;
@ -3269,7 +3531,7 @@ stix_oop_t stix_inttostr (stix_t* stix, stix_oop_t num, int radix)
STIX_ASSERT (radix >= 2 && radix <= 36);
if (!is_integer(stix,num)) goto oops_einval;
if (!stix_isint(stix,num)) goto oops_einval;
v = integer_to_oow (stix, num, &w);
if (v)

View File

@ -650,14 +650,9 @@ static int prim_basic_new_with_size (stix_t* stix, stix_ooi_t nargs)
}
szoop = ACTIVE_STACK_GET(stix, stix->sp);
if (STIX_OOP_IS_SMOOI(szoop))
if (stix_inttooow (stix, szoop, &size) <= 0)
{
size = STIX_OOP_TO_SMOOI(szoop);
}
/* TODO: support LargeInteger */
else
{
/* size is not a proper numeric object */
/* integer out of range or not integer */
return 0;
}
@ -679,6 +674,40 @@ static int prim_basic_new_with_size (stix_t* stix, stix_ooi_t nargs)
return 1; /* success */
}
static int prim_ngc_new (stix_t* stix, stix_ooi_t nargs)
{
int n;
n = prim_basic_new (stix, nargs);
if (n <= 0) return n;
return 1;
}
static int prim_ngc_new_with_size (stix_t* stix, stix_ooi_t nargs)
{
int n;
n = prim_basic_new_with_size (stix, nargs);
if (n <= 0) return n;
return 1;
}
static int prim_ngc_dispose (stix_t* stix, stix_ooi_t nargs)
{
stix_oop_t rcv;
STIX_ASSERT (nargs == 0);
rcv = ACTIVE_STACK_GETTOP (stix);
stix_freemem (stix, rcv);
ACTIVE_STACK_SETTOP (stix, stix->_nil);
return 1; /* success */
}
static int prim_shallow_copy (stix_t* stix, stix_ooi_t nargs)
{
stix_oop_t rcv, obj;
@ -697,19 +726,23 @@ static int prim_shallow_copy (stix_t* stix, stix_ooi_t nargs)
static int prim_basic_size (stix_t* stix, stix_ooi_t nargs)
{
stix_oop_t rcv;
stix_oop_t rcv, sz;
STIX_ASSERT (nargs == 0);
rcv = ACTIVE_STACK_GETTOP(stix);
ACTIVE_STACK_SETTOP(stix, STIX_SMOOI_TO_OOP(STIX_OBJ_GET_SIZE(rcv)));
/* TODO: use LargeInteger if the size is very big */
sz = stix_oowtoint (stix, STIX_OBJ_GET_SIZE(rcv));
if (!sz) return -1; /* hard failure */
ACTIVE_STACK_SETTOP(stix, sz);
return 1;
}
static int prim_basic_at (stix_t* stix, stix_ooi_t nargs)
{
stix_oop_t rcv, pos, v;
stix_ooi_t idx;
stix_oow_t idx;
STIX_ASSERT (nargs == 1);
@ -721,21 +754,18 @@ static int prim_basic_at (stix_t* stix, stix_ooi_t nargs)
}
pos = ACTIVE_STACK_GET(stix, stix->sp);
if (!STIX_OOP_IS_SMOOI(pos))
if (stix_inttooow (stix, pos, &idx) <= 0)
{
/* TODO: handle LargeInteger */
/* the position must be an integer */
/* integer out of range or not integer */
return 0;
}
idx = STIX_OOP_TO_SMOOI(pos);
if (idx < 1 || idx > STIX_OBJ_GET_SIZE(rcv))
{
/* index out of range */
return 0;
}
/* [NOTE] basicAt: and basicAt:put: used a 1-based index. */
/* [NOTE] basicAt: and basicAt:put: uses a 1-based index. */
idx = idx - 1;
switch (STIX_OBJ_GET_FLAGS_TYPE(rcv))
@ -775,7 +805,7 @@ static int prim_basic_at (stix_t* stix, stix_ooi_t nargs)
static int prim_basic_at_put (stix_t* stix, stix_ooi_t nargs)
{
stix_oop_t rcv, pos, val;
stix_ooi_t idx;
stix_oow_t idx;
STIX_ASSERT (nargs == 2);
@ -785,18 +815,14 @@ static int prim_basic_at_put (stix_t* stix, stix_ooi_t nargs)
/* the receiver is a special numeric object, not a normal pointer */
return 0;
}
pos = ACTIVE_STACK_GET(stix, stix->sp - 1);
if (!STIX_OOP_IS_SMOOI(pos))
{
/* TODO: handle LargeInteger */
/* the position must be an integer */
return 0;
}
val = ACTIVE_STACK_GET(stix, stix->sp);
idx = STIX_OOP_TO_SMOOI(pos);
if (stix_inttooow (stix, pos, &idx) <= 0)
{
/* integer out of range or not integer */
return 0;
}
if (idx < 1 || idx > STIX_OBJ_GET_SIZE(rcv))
{
/* index out of range */
@ -811,7 +837,7 @@ static int prim_basic_at_put (stix_t* stix, stix_ooi_t nargs)
return 0;
}
/* [NOTE] basicAt: and basicAt:put: used a 1-based index. */
/* [NOTE] basicAt: and basicAt:put: uses a 1-based index. */
idx = idx - 1;
switch (STIX_OBJ_GET_FLAGS_TYPE(rcv))
@ -847,7 +873,7 @@ static int prim_basic_at_put (stix_t* stix, stix_ooi_t nargs)
break;
case STIX_OBJ_TYPE_WORD:
/* TODO: handle largeINteger */
/* TODO: handle LargeInteger */
if (!STIX_OOP_IS_SMOOI(val))
{
/* the value is not a number */
@ -1306,168 +1332,104 @@ static int prim_integer_bitshift (stix_t* stix, stix_ooi_t nargs)
static int prim_integer_eq (stix_t* stix, stix_ooi_t nargs)
{
stix_oop_t rcv, arg;
stix_oop_t rcv, arg, res;
STIX_ASSERT (nargs == 1);
rcv = ACTIVE_STACK_GET(stix, stix->sp - 1);
arg = ACTIVE_STACK_GET(stix, stix->sp);
if (STIX_OOP_IS_SMOOI(rcv) && STIX_OOP_IS_SMOOI(arg))
{
ACTIVE_STACK_POP (stix);
if (STIX_OOP_TO_SMOOI(rcv) == STIX_OOP_TO_SMOOI(arg))
{
ACTIVE_STACK_SETTOP (stix, stix->_true);
}
else
{
ACTIVE_STACK_SETTOP (stix, stix->_false);
}
return 1;
}
res = stix_eqints (stix, rcv, arg);
if (!res) return (stix->errnum == STIX_EINVAL? 0: -1); /* soft or hard failure */
/* TODO: handle LargeInteger */
return 0;
ACTIVE_STACK_POP (stix);
ACTIVE_STACK_SETTOP (stix, res);
return 1;
}
static int prim_integer_ne (stix_t* stix, stix_ooi_t nargs)
{
stix_oop_t rcv, arg;
stix_oop_t rcv, arg, res;
STIX_ASSERT (nargs == 1);
rcv = ACTIVE_STACK_GET(stix, stix->sp - 1);
arg = ACTIVE_STACK_GET(stix, stix->sp);
if (STIX_OOP_IS_SMOOI(rcv) && STIX_OOP_IS_SMOOI(arg))
{
ACTIVE_STACK_POP (stix);
if (STIX_OOP_TO_SMOOI(rcv) != STIX_OOP_TO_SMOOI(arg))
{
ACTIVE_STACK_SETTOP (stix, stix->_true);
}
else
{
ACTIVE_STACK_SETTOP (stix, stix->_false);
}
return 1;
}
res = stix_neints (stix, rcv, arg);
if (!res) return (stix->errnum == STIX_EINVAL? 0: -1); /* soft or hard failure */
/* TODO: handle LargeInteger */
return 0;
ACTIVE_STACK_POP (stix);
ACTIVE_STACK_SETTOP (stix, res);
return 1;
}
static int prim_integer_lt (stix_t* stix, stix_ooi_t nargs)
{
stix_oop_t rcv, arg;
stix_oop_t rcv, arg, res;
STIX_ASSERT (nargs == 1);
rcv = ACTIVE_STACK_GET(stix, stix->sp - 1);
arg = ACTIVE_STACK_GET(stix, stix->sp);
if (STIX_OOP_IS_SMOOI(rcv) && STIX_OOP_IS_SMOOI(arg))
{
ACTIVE_STACK_POP (stix);
if (STIX_OOP_TO_SMOOI(rcv) < STIX_OOP_TO_SMOOI(arg))
{
ACTIVE_STACK_SETTOP (stix, stix->_true);
}
else
{
ACTIVE_STACK_SETTOP (stix, stix->_false);
}
return 1;
}
res = stix_ltints (stix, rcv, arg);
if (!res) return (stix->errnum == STIX_EINVAL? 0: -1); /* soft or hard failure */
/* TODO: handle LargeInteger */
return 0;
ACTIVE_STACK_POP (stix);
ACTIVE_STACK_SETTOP (stix, res);
return 1;
}
static int prim_integer_gt (stix_t* stix, stix_ooi_t nargs)
{
stix_oop_t rcv, arg;
stix_oop_t rcv, arg, res;
STIX_ASSERT (nargs == 1);
rcv = ACTIVE_STACK_GET(stix, stix->sp - 1);
arg = ACTIVE_STACK_GET(stix, stix->sp);
if (STIX_OOP_IS_SMOOI(rcv) && STIX_OOP_IS_SMOOI(arg))
{
ACTIVE_STACK_POP (stix);
if (STIX_OOP_TO_SMOOI(rcv) > STIX_OOP_TO_SMOOI(arg))
{
ACTIVE_STACK_SETTOP (stix, stix->_true);
}
else
{
ACTIVE_STACK_SETTOP (stix, stix->_false);
}
return 1;
}
res = stix_gtints (stix, rcv, arg);
if (!res) return (stix->errnum == STIX_EINVAL? 0: -1); /* soft or hard failure */
/* TODO: handle LargeInteger */
return 0;
ACTIVE_STACK_POP (stix);
ACTIVE_STACK_SETTOP (stix, res);
return 1;
}
static int prim_integer_le (stix_t* stix, stix_ooi_t nargs)
{
stix_oop_t rcv, arg;
stix_oop_t rcv, arg, res;
STIX_ASSERT (nargs == 1);
rcv = ACTIVE_STACK_GET(stix, stix->sp - 1);
arg = ACTIVE_STACK_GET(stix, stix->sp);
if (STIX_OOP_IS_SMOOI(rcv) && STIX_OOP_IS_SMOOI(arg))
{
ACTIVE_STACK_POP (stix);
if (STIX_OOP_TO_SMOOI(rcv) <= STIX_OOP_TO_SMOOI(arg))
{
ACTIVE_STACK_SETTOP (stix, stix->_true);
}
else
{
ACTIVE_STACK_SETTOP (stix, stix->_false);
}
return 1;
}
res = stix_leints (stix, rcv, arg);
if (!res) return (stix->errnum == STIX_EINVAL? 0: -1); /* soft or hard failure */
/* TODO: handle LargeInteger */
return 0;
ACTIVE_STACK_POP (stix);
ACTIVE_STACK_SETTOP (stix, res);
return 1;
}
static int prim_integer_ge (stix_t* stix, stix_ooi_t nargs)
{
stix_oop_t rcv, arg;
stix_oop_t rcv, arg, res;
STIX_ASSERT (nargs == 1);
rcv = ACTIVE_STACK_GET(stix, stix->sp - 1);
arg = ACTIVE_STACK_GET(stix, stix->sp);
if (STIX_OOP_IS_SMOOI(rcv) && STIX_OOP_IS_SMOOI(arg))
{
ACTIVE_STACK_POP (stix);
if (STIX_OOP_TO_SMOOI(rcv) >= STIX_OOP_TO_SMOOI(arg))
{
ACTIVE_STACK_SETTOP (stix, stix->_true);
}
else
{
ACTIVE_STACK_SETTOP (stix, stix->_false);
}
return 1;
}
res = stix_geints (stix, rcv, arg);
if (!res) return (stix->errnum == STIX_EINVAL? 0: -1); /* soft or hard failure */
return 0;
ACTIVE_STACK_POP (stix);
ACTIVE_STACK_SETTOP (stix, res);
return 1;
}
static int prim_integer_inttostr (stix_t* stix, stix_ooi_t nargs)
@ -1829,6 +1791,9 @@ static prim_t primitives[] =
{ 0, prim_basic_new, "_basic_new" },
{ 1, prim_basic_new_with_size, "_basic_new_with_size" },
{ 0, prim_ngc_new, "_ngc_new" },
{ 1, prim_ngc_new_with_size, "_ngc_new_with_size" },
{ 0, prim_ngc_dispose, "_ngc_dispose" },
{ 0, prim_shallow_copy, "_shallow_copy" },
{ 0, prim_basic_size, "_basic_size" },

View File

@ -290,7 +290,7 @@ int stix_ignite (stix_t* stix)
stix->_nil = stix_allocbytes (stix, STIX_SIZEOF(stix_obj_t));
if (!stix->_nil) return -1;
stix->_nil->_flags = STIX_OBJ_MAKE_FLAGS (STIX_OBJ_TYPE_OOP, STIX_SIZEOF(stix_oop_t), 0, 1, 0, 0);
stix->_nil->_flags = STIX_OBJ_MAKE_FLAGS (STIX_OBJ_TYPE_OOP, STIX_SIZEOF(stix_oop_t), 0, 1, 0, 0, 0);
stix->_nil->_size = 0;
if (ignite_1(stix) <= -1 || ignite_2(stix) <= -1 || ignite_3(stix)) return -1;

View File

@ -64,7 +64,7 @@ stix_oop_t stix_allocoopobj (stix_t* stix, stix_oow_t size)
hdr = stix_allocbytes (stix, STIX_SIZEOF(stix_obj_t) + nbytes_aligned);
if (!hdr) return STIX_NULL;
hdr->_flags = STIX_OBJ_MAKE_FLAGS(STIX_OBJ_TYPE_OOP, STIX_SIZEOF(stix_oop_t), 0, 0, 0, 0);
hdr->_flags = STIX_OBJ_MAKE_FLAGS(STIX_OBJ_TYPE_OOP, STIX_SIZEOF(stix_oop_t), 0, 0, 0, 0, 0);
STIX_OBJ_SET_SIZE (hdr, size);
STIX_OBJ_SET_CLASS (hdr, stix->_nil);
@ -87,7 +87,7 @@ stix_oop_t stix_allocoopobjwithtrailer (stix_t* stix, stix_oow_t size, const sti
hdr = stix_allocbytes (stix, STIX_SIZEOF(stix_obj_t) + nbytes_aligned);
if (!hdr) return STIX_NULL;
hdr->_flags = STIX_OBJ_MAKE_FLAGS(STIX_OBJ_TYPE_OOP, STIX_SIZEOF(stix_oop_t), 0, 0, 0, 1);
hdr->_flags = STIX_OBJ_MAKE_FLAGS(STIX_OBJ_TYPE_OOP, STIX_SIZEOF(stix_oop_t), 0, 0, 0, 0, 1);
STIX_OBJ_SET_SIZE (hdr, size);
STIX_OBJ_SET_CLASS (hdr, stix->_nil);
@ -130,7 +130,7 @@ static STIX_INLINE stix_oop_t alloc_numeric_array (stix_t* stix, const void* ptr
hdr = stix_allocbytes (stix, STIX_SIZEOF(stix_obj_t) + nbytes_aligned);
if (!hdr) return STIX_NULL;
hdr->_flags = STIX_OBJ_MAKE_FLAGS(type, unit, extra, 0, 0, 0);
hdr->_flags = STIX_OBJ_MAKE_FLAGS(type, unit, extra, 0, 0, 0, 0);
hdr->_size = len;
STIX_OBJ_SET_SIZE (hdr, len);
STIX_OBJ_SET_CLASS (hdr, stix->_nil);
@ -170,15 +170,11 @@ stix_oop_t stix_allocwordobj (stix_t* stix, const stix_oow_t* ptr, stix_oow_t le
return alloc_numeric_array (stix, ptr, len, STIX_OBJ_TYPE_WORD, STIX_SIZEOF(stix_oow_t), 0);
}
stix_oop_t stix_instantiate (stix_t* stix, stix_oop_t _class, const void* vptr, stix_oow_t vlen)
static STIX_INLINE int decode_spec (stix_t* stix, stix_oop_t _class, stix_oow_t vlen, stix_obj_type_t* type, stix_oow_t* outlen)
{
stix_oop_t oop;
stix_oow_t spec;
stix_oow_t named_instvar;
stix_obj_type_t indexed_type;
stix_oow_t tmp_count = 0;
STIX_ASSERT (stix->_nil != STIX_NULL);
STIX_ASSERT (STIX_OOP_IS_POINTER(_class));
STIX_ASSERT (STIX_CLASSOF(stix, _class) == stix->_class);
@ -197,7 +193,7 @@ stix_oop_t stix_instantiate (stix_t* stix, stix_oop_t _class, const void* vptr,
if (named_instvar > STIX_MAX_NAMED_INSTVARS ||
vlen > STIX_MAX_INDEXED_INSTVARS(named_instvar))
{
goto einval;
return -1;
}
STIX_ASSERT (named_instvar + vlen <= STIX_OBJ_SIZE_MAX);
@ -205,8 +201,8 @@ stix_oop_t stix_instantiate (stix_t* stix, stix_oop_t _class, const void* vptr,
else
{
/* a non-pointer indexed class can't have named instance variables */
if (named_instvar > 0) goto einval;
if (vlen > STIX_OBJ_SIZE_MAX) goto einval;
if (named_instvar > 0) return -1;
if (vlen > STIX_OBJ_SIZE_MAX) return -1;
}
}
else
@ -216,18 +212,38 @@ stix_oop_t stix_instantiate (stix_t* stix, stix_oop_t _class, const void* vptr,
indexed_type = STIX_OBJ_TYPE_OOP;
vlen = 0; /* vlen is not used */
if (named_instvar > STIX_MAX_NAMED_INSTVARS) goto einval;
if (named_instvar > STIX_MAX_NAMED_INSTVARS) return -1;
STIX_ASSERT (named_instvar <= STIX_OBJ_SIZE_MAX);
}
*type = indexed_type;
*outlen = named_instvar + vlen;
return 0;
}
stix_oop_t stix_instantiate (stix_t* stix, stix_oop_t _class, const void* vptr, stix_oow_t vlen)
{
stix_oop_t oop;
stix_obj_type_t type;
stix_oow_t alloclen;
stix_oow_t tmp_count = 0;
STIX_ASSERT (stix->_nil != STIX_NULL);
if (decode_spec (stix, _class, vlen, &type, &alloclen) <= -1)
{
stix->errnum = STIX_EINVAL;
return STIX_NULL;
}
stix_pushtmp (stix, &_class); tmp_count++;
switch (indexed_type)
switch (type)
{
case STIX_OBJ_TYPE_OOP:
/* both the fixed part(named instance variables) and
* the variable part(indexed instance variables) are allowed. */
oop = stix_allocoopobj (stix, named_instvar + vlen);
oop = stix_allocoopobj (stix, alloclen);
STIX_ASSERT (vptr == STIX_NULL);
/*
@ -248,19 +264,19 @@ stix_oop_t stix_instantiate (stix_t* stix, stix_oop_t _class, const void* vptr,
break;
case STIX_OBJ_TYPE_CHAR:
oop = stix_alloccharobj (stix, vptr, vlen);
oop = stix_alloccharobj (stix, vptr, alloclen);
break;
case STIX_OBJ_TYPE_BYTE:
oop = stix_allocbyteobj (stix, vptr, vlen);
oop = stix_allocbyteobj (stix, vptr, alloclen);
break;
case STIX_OBJ_TYPE_HALFWORD:
oop = stix_allochalfwordobj (stix, vptr, vlen);
oop = stix_allochalfwordobj (stix, vptr, alloclen);
break;
case STIX_OBJ_TYPE_WORD:
oop = stix_allocwordobj (stix, vptr, vlen);
oop = stix_allocwordobj (stix, vptr, alloclen);
break;
default:
@ -272,67 +288,85 @@ stix_oop_t stix_instantiate (stix_t* stix, stix_oop_t _class, const void* vptr,
if (oop) STIX_OBJ_SET_CLASS (oop, _class);
stix_poptmps (stix, tmp_count);
return oop;
einval:
STIX_ASSERT (tmp_count <= 0);
stix->errnum = STIX_EINVAL;
return STIX_NULL;
}
stix_oop_t stix_instantiate2 (stix_t* stix, stix_oop_t _class, const void* vptr, stix_oow_t vlen, int ngc)
{
stix_oop_t oop;
stix_obj_type_t type;
stix_oow_t alloclen;
stix_oow_t tmp_count = 0;
STIX_ASSERT (stix->_nil != STIX_NULL);
if (decode_spec (stix, _class, vlen, &type, &alloclen) <= -1)
{
stix->errnum = STIX_EINVAL;
return STIX_NULL;
}
stix_pushtmp (stix, &_class); tmp_count++;
/* TODO: support NGC */
switch (type)
{
case STIX_OBJ_TYPE_OOP:
/* NOTE: vptr is not used for GC unsafety */
oop = stix_allocoopobj (stix, alloclen);
break;
case STIX_OBJ_TYPE_CHAR:
oop = stix_alloccharobj (stix, vptr, alloclen);
break;
case STIX_OBJ_TYPE_BYTE:
oop = stix_allocbyteobj (stix, vptr, alloclen);
break;
case STIX_OBJ_TYPE_HALFWORD:
oop = stix_allochalfwordobj (stix, vptr, alloclen);
break;
case STIX_OBJ_TYPE_WORD:
oop = stix_allocwordobj (stix, vptr, alloclen);
break;
default:
stix->errnum = STIX_EINTERN;
oop = STIX_NULL;
break;
}
if (oop) STIX_OBJ_SET_CLASS (oop, _class);
stix_poptmps (stix, tmp_count);
return oop;
}
#if defined(STIX_USE_OBJECT_TRAILER)
stix_oop_t stix_instantiatewithtrailer (stix_t* stix, stix_oop_t _class, stix_oow_t vlen, const stix_oob_t* tptr, stix_oow_t tlen)
{
stix_oop_t oop;
stix_oow_t spec;
stix_oow_t named_instvar;
stix_obj_type_t indexed_type;
stix_obj_type_t type;
stix_oow_t alloclen;
stix_oow_t tmp_count = 0;
STIX_ASSERT (stix->_nil != STIX_NULL);
STIX_ASSERT (STIX_OOP_IS_POINTER(_class));
STIX_ASSERT (STIX_CLASSOF(stix, _class) == stix->_class);
STIX_ASSERT (STIX_OOP_IS_SMOOI(((stix_oop_class_t)_class)->spec));
spec = STIX_OOP_TO_SMOOI(((stix_oop_class_t)_class)->spec);
named_instvar = STIX_CLASS_SPEC_NAMED_INSTVAR(spec); /* size of the named_instvar part */
if (STIX_CLASS_SPEC_IS_INDEXED(spec))
if (decode_spec (stix, _class, vlen, &type, &alloclen) <= -1)
{
indexed_type = STIX_CLASS_SPEC_INDEXED_TYPE(spec);
if (indexed_type == STIX_OBJ_TYPE_OOP)
{
if (named_instvar > STIX_MAX_NAMED_INSTVARS ||
vlen > STIX_MAX_INDEXED_INSTVARS(named_instvar))
{
goto einval;
}
}
else
{
/* not a class for an OOP object */
goto einval;
}
}
else
{
/* named instance variables only. treat it as if it is an
* indexable class with no variable data */
indexed_type = STIX_OBJ_TYPE_OOP;
vlen = 0;
if (named_instvar > STIX_MAX_NAMED_INSTVARS) goto einval;
stix->errnum = STIX_EINVAL;
return STIX_NULL;
}
stix_pushtmp (stix, &_class); tmp_count++;
switch (indexed_type)
switch (type)
{
case STIX_OBJ_TYPE_OOP:
oop = stix_allocoopobjwithtrailer(stix, named_instvar + vlen, tptr, tlen);
/* NOTE: vptr is not used for GC unsafety */
oop = stix_allocoopobjwithtrailer(stix, alloclen, tptr, tlen);
break;
default:
@ -344,12 +378,6 @@ stix_oop_t stix_instantiatewithtrailer (stix_t* stix, stix_oop_t _class, stix_oo
if (oop) STIX_OBJ_SET_CLASS (oop, _class);
stix_poptmps (stix, tmp_count);
return oop;
einval:
STIX_ASSERT (tmp_count <= 0);
stix->errnum = STIX_EINVAL;
return STIX_NULL;
}
#endif

View File

@ -1117,6 +1117,22 @@ int stix_utf8toucs (
/* ========================================================================= */
/* bigint.c */
/* ========================================================================= */
int stix_isint (
stix_t* stix,
stix_oop_t x
);
int stix_inttooow (
stix_t* stix,
stix_oop_t x,
stix_oow_t* w
);
stix_oop_t stix_oowtoint (
stix_t* stix,
stix_oow_t w
);
stix_oop_t stix_addints (
stix_t* stix,
stix_oop_t x,
@ -1183,6 +1199,42 @@ stix_oop_t stix_bitshiftint (
stix_oop_t y
);
stix_oop_t stix_eqints (
stix_t* stix,
stix_oop_t x,
stix_oop_t y
);
stix_oop_t stix_neints (
stix_t* stix,
stix_oop_t x,
stix_oop_t y
);
stix_oop_t stix_gtints (
stix_t* stix,
stix_oop_t x,
stix_oop_t y
);
stix_oop_t stix_geints (
stix_t* stix,
stix_oop_t x,
stix_oop_t y
);
stix_oop_t stix_ltints (
stix_t* stix,
stix_oop_t x,
stix_oop_t y
);
stix_oop_t stix_leints (
stix_t* stix,
stix_oop_t x,
stix_oop_t y
);
stix_oop_t stix_strtoint (
stix_t* stix,
const stix_ooch_t* str,

View File

@ -227,6 +227,7 @@ typedef enum stix_obj_type_t stix_obj_type_t;
* VM disallows layout changes of a kernel object.
* internal use only.
* moved: 0 or 1. used by GC. internal use only.
* ngc: 0 or 1, used by GC. internal use only.
* trailer: 0 or 1. indicates that there are trailing bytes
* after the object payload. internal use only.
*
@ -260,21 +261,24 @@ typedef enum stix_obj_type_t stix_obj_type_t;
#define STIX_OBJ_FLAGS_EXTRA_BITS 1
#define STIX_OBJ_FLAGS_KERNEL_BITS 2
#define STIX_OBJ_FLAGS_MOVED_BITS 1
#define STIX_OBJ_FLAGS_NGC_BITS 1
#define STIX_OBJ_FLAGS_TRAILER_BITS 1
#define STIX_OBJ_GET_FLAGS_TYPE(oop) STIX_GETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_UNIT_BITS + STIX_OBJ_FLAGS_EXTRA_BITS + STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS + STIX_OBJ_FLAGS_TRAILER_BITS), STIX_OBJ_FLAGS_TYPE_BITS)
#define STIX_OBJ_GET_FLAGS_UNIT(oop) STIX_GETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_EXTRA_BITS + STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS + STIX_OBJ_FLAGS_TRAILER_BITS), STIX_OBJ_FLAGS_UNIT_BITS)
#define STIX_OBJ_GET_FLAGS_EXTRA(oop) STIX_GETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS + STIX_OBJ_FLAGS_TRAILER_BITS), STIX_OBJ_FLAGS_EXTRA_BITS)
#define STIX_OBJ_GET_FLAGS_KERNEL(oop) STIX_GETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_MOVED_BITS + STIX_OBJ_FLAGS_TRAILER_BITS), STIX_OBJ_FLAGS_KERNEL_BITS)
#define STIX_OBJ_GET_FLAGS_MOVED(oop) STIX_GETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_TRAILER_BITS), STIX_OBJ_FLAGS_MOVED_BITS)
#define STIX_OBJ_GET_FLAGS_TRAILER(oop) STIX_GETBITS(stix_oow_t, (oop)->_flags, 0, STIX_OBJ_FLAGS_TRAILER_BITS)
#define STIX_OBJ_GET_FLAGS_TYPE(oop) STIX_GETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_UNIT_BITS + STIX_OBJ_FLAGS_EXTRA_BITS + STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS + STIX_OBJ_FLAGS_TRAILER_BITS + STIX_OBJ_FLAGS_NGC_BITS), STIX_OBJ_FLAGS_TYPE_BITS)
#define STIX_OBJ_GET_FLAGS_UNIT(oop) STIX_GETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_EXTRA_BITS + STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS + STIX_OBJ_FLAGS_TRAILER_BITS + STIX_OBJ_FLAGS_NGC_BITS), STIX_OBJ_FLAGS_UNIT_BITS)
#define STIX_OBJ_GET_FLAGS_EXTRA(oop) STIX_GETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS + STIX_OBJ_FLAGS_TRAILER_BITS + STIX_OBJ_FLAGS_NGC_BITS), STIX_OBJ_FLAGS_EXTRA_BITS)
#define STIX_OBJ_GET_FLAGS_KERNEL(oop) STIX_GETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_MOVED_BITS + STIX_OBJ_FLAGS_TRAILER_BITS + STIX_OBJ_FLAGS_NGC_BITS), STIX_OBJ_FLAGS_KERNEL_BITS)
#define STIX_OBJ_GET_FLAGS_MOVED(oop) STIX_GETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_TRAILER_BITS + STIX_OBJ_FLAGS_NGC_BITS), STIX_OBJ_FLAGS_MOVED_BITS)
#define STIX_OBJ_GET_FLAGS_NGC(oop) STIX_GETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_TRAILER_BITS), STIX_OBJ_FLAGS_MOVED_BITS)
#define STIX_OBJ_GET_FLAGS_TRAILER(oop) STIX_GETBITS(stix_oow_t, (oop)->_flags, 0, STIX_OBJ_FLAGS_TRAILER_BITS)
#define STIX_OBJ_SET_FLAGS_TYPE(oop,v) STIX_SETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_UNIT_BITS + STIX_OBJ_FLAGS_EXTRA_BITS + STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS + STIX_OBJ_FLAGS_TRAILER_BITS), STIX_OBJ_FLAGS_TYPE_BITS, v)
#define STIX_OBJ_SET_FLAGS_UNIT(oop,v) STIX_SETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_EXTRA_BITS + STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS + STIX_OBJ_FLAGS_TRAILER_BITS), STIX_OBJ_FLAGS_UNIT_BITS, v)
#define STIX_OBJ_SET_FLAGS_EXTRA(oop,v) STIX_SETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS + STIX_OBJ_FLAGS_TRAILER_BITS), STIX_OBJ_FLAGS_EXTRA_BITS, v)
#define STIX_OBJ_SET_FLAGS_KERNEL(oop,v) STIX_SETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_MOVED_BITS + STIX_OBJ_FLAGS_TRAILER_BITS), STIX_OBJ_FLAGS_KERNEL_BITS, v)
#define STIX_OBJ_SET_FLAGS_MOVED(oop,v) STIX_SETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_TRAILER_BITS), STIX_OBJ_FLAGS_MOVED_BITS, v)
#define STIX_OBJ_SET_FLAGS_TRAILER(oop,v) STIX_SETBITS(stix_oow_t, (oop)->_flags, 0, STIX_OBJ_FLAGS_TRAILER_BITS, v)
#define STIX_OBJ_SET_FLAGS_TYPE(oop,v) STIX_SETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_UNIT_BITS + STIX_OBJ_FLAGS_EXTRA_BITS + STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS + STIX_OBJ_FLAGS_TRAILER_BITS + STIX_OBJ_FLAGS_NGC_BITS), STIX_OBJ_FLAGS_TYPE_BITS, v)
#define STIX_OBJ_SET_FLAGS_UNIT(oop,v) STIX_SETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_EXTRA_BITS + STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS + STIX_OBJ_FLAGS_TRAILER_BITS + STIX_OBJ_FLAGS_NGC_BITS), STIX_OBJ_FLAGS_UNIT_BITS, v)
#define STIX_OBJ_SET_FLAGS_EXTRA(oop,v) STIX_SETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS + STIX_OBJ_FLAGS_TRAILER_BITS + STIX_OBJ_FLAGS_NGC_BITS), STIX_OBJ_FLAGS_EXTRA_BITS, v)
#define STIX_OBJ_SET_FLAGS_KERNEL(oop,v) STIX_SETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_MOVED_BITS + STIX_OBJ_FLAGS_TRAILER_BITS + STIX_OBJ_FLAGS_NGC_BITS), STIX_OBJ_FLAGS_KERNEL_BITS, v)
#define STIX_OBJ_SET_FLAGS_MOVED(oop,v) STIX_SETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_TRAILER_BITS + STIX_OBJ_FLAGS_NGC_BITS), STIX_OBJ_FLAGS_MOVED_BITS, v)
#define STIX_OBJ_SET_FLAGS_NGC(oop,v) STIX_SETBITS(stix_oow_t, (oop)->_flags, (STIX_OBJ_FLAGS_TRAILER_BITS), STIX_OBJ_FLAGS_MOVED_BITS, v)
#define STIX_OBJ_SET_FLAGS_TRAILER(oop,v) STIX_SETBITS(stix_oow_t, (oop)->_flags, 0, STIX_OBJ_FLAGS_TRAILER_BITS, v)
#define STIX_OBJ_GET_SIZE(oop) ((oop)->_size)
#define STIX_OBJ_GET_CLASS(oop) ((oop)->_class)
@ -288,12 +292,13 @@ typedef enum stix_obj_type_t stix_obj_type_t;
/* [NOTE] this macro doesn't check the range of the actual value.
* make sure that the value of each bit fields given falls within the
* possible range of the defined bits */
#define STIX_OBJ_MAKE_FLAGS(t,u,e,k,m,r) ( \
(((stix_oow_t)(t)) << (STIX_OBJ_FLAGS_UNIT_BITS + STIX_OBJ_FLAGS_EXTRA_BITS + STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS + STIX_OBJ_FLAGS_TRAILER_BITS)) | \
(((stix_oow_t)(u)) << (STIX_OBJ_FLAGS_EXTRA_BITS + STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS + STIX_OBJ_FLAGS_TRAILER_BITS)) | \
(((stix_oow_t)(e)) << (STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS + STIX_OBJ_FLAGS_TRAILER_BITS)) | \
(((stix_oow_t)(k)) << (STIX_OBJ_FLAGS_MOVED_BITS + STIX_OBJ_FLAGS_TRAILER_BITS)) | \
(((stix_oow_t)(m)) << (STIX_OBJ_FLAGS_TRAILER_BITS)) | \
#define STIX_OBJ_MAKE_FLAGS(t,u,e,k,m,g,r) ( \
(((stix_oow_t)(t)) << (STIX_OBJ_FLAGS_UNIT_BITS + STIX_OBJ_FLAGS_EXTRA_BITS + STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS + STIX_OBJ_FLAGS_TRAILER_BITS + STIX_OBJ_FLAGS_NGC_BITS)) | \
(((stix_oow_t)(u)) << (STIX_OBJ_FLAGS_EXTRA_BITS + STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS + STIX_OBJ_FLAGS_TRAILER_BITS + STIX_OBJ_FLAGS_NGC_BITS)) | \
(((stix_oow_t)(e)) << (STIX_OBJ_FLAGS_KERNEL_BITS + STIX_OBJ_FLAGS_MOVED_BITS + STIX_OBJ_FLAGS_TRAILER_BITS + STIX_OBJ_FLAGS_NGC_BITS)) | \
(((stix_oow_t)(k)) << (STIX_OBJ_FLAGS_MOVED_BITS + STIX_OBJ_FLAGS_TRAILER_BITS + STIX_OBJ_FLAGS_NGC_BITS)) | \
(((stix_oow_t)(m)) << (STIX_OBJ_FLAGS_TRAILER_BITS + STIX_OBJ_FLAGS_NGC_BITS)) | \
(((stix_oow_t)(g)) << (STIX_OBJ_FLAGS_TRAILER_BITS)) | \
(((stix_oow_t)(r)) << 0) \
)