diff --git a/stix/kernel/Apex.st b/stix/kernel/Apex.st index 1c3a744..fccb956 100644 --- a/stix/kernel/Apex.st +++ b/stix/kernel/Apex.st @@ -43,6 +43,18 @@ self primitiveFailed. } + #method(#class) ngcNew + { + + self primitiveFailed. + } + + #method(#class) ngcNew: anInteger + { + + self primitiveFailed. + } + #method(#class) new { | x | @@ -66,6 +78,11 @@ ^self. } + #method ngcDispose + { + + self primitiveFailed. + } ## ------------------------------------------------------- ## ------------------------------------------------------- #method shallowCopy diff --git a/stix/kernel/Stix.st b/stix/kernel/Stix.st index 7d51a1b..00a9e85 100644 --- a/stix/kernel/Stix.st +++ b/stix/kernel/Stix.st @@ -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) diff --git a/stix/kernel/test-005.st b/stix/kernel/test-005.st index 4bffea4..329ca7c 100644 --- a/stix/kernel/test-005.st +++ b/stix/kernel/test-005.st @@ -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. diff --git a/stix/lib/bigint.c b/stix/lib/bigint.c index d706cc6..8777779 100644 --- a/stix/lib/bigint.c +++ b/stix/lib/bigint.c @@ -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) diff --git a/stix/lib/exec.c b/stix/lib/exec.c index 9d8007c..cf04396 100644 --- a/stix/lib/exec.c +++ b/stix/lib/exec.c @@ -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" }, diff --git a/stix/lib/ignite.c b/stix/lib/ignite.c index 6bf789e..445ddf8 100644 --- a/stix/lib/ignite.c +++ b/stix/lib/ignite.c @@ -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; diff --git a/stix/lib/obj.c b/stix/lib/obj.c index af72630..3aaec0a 100644 --- a/stix/lib/obj.c +++ b/stix/lib/obj.c @@ -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 diff --git a/stix/lib/stix-prv.h b/stix/lib/stix-prv.h index 180b4f0..2bcefb2 100644 --- a/stix/lib/stix-prv.h +++ b/stix/lib/stix-prv.h @@ -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, diff --git a/stix/lib/stix.h b/stix/lib/stix.h index f5e7535..777c0a8 100644 --- a/stix/lib/stix.h +++ b/stix/lib/stix.h @@ -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) \ )