diff --git a/stix/lib/bigint.c b/stix/lib/bigint.c index 114c253..2e3e537 100644 --- a/stix/lib/bigint.c +++ b/stix/lib/bigint.c @@ -257,7 +257,7 @@ static STIX_INLINE stix_oop_t make_bloated_bigint_with_ooi (stix_t* stix, stix_o stix_oow_t w; stix_oop_t z; - STIX_ASSERT (extra <= STIX_TYPE_MAX(stix_oow_t) - 1); + STIX_ASSERT (extra <= STIX_OBJ_SIZE_MAX - 1); STIX_ASSERT (STIX_SIZEOF(stix_oow_t) == STIX_SIZEOF(stix_liw_t)); if (i >= 0) { @@ -280,7 +280,7 @@ static STIX_INLINE stix_oop_t make_bloated_bigint_with_ooi (stix_t* stix, stix_o stix_oow_t w; stix_oop_t z; - STIX_ASSERT (extra <= STIX_TYPE_MAX(stix_oow_t) - 2); + STIX_ASSERT (extra <= STIX_OBJ_SIZE_MAX - 2); if (i >= 0) { w = i; @@ -337,7 +337,7 @@ static STIX_INLINE stix_oop_t expand_bigint (stix_t* stix, stix_oop_t oop, stix_ STIX_ASSERT (STIX_OOP_IS_POINTER(oop)); count = STIX_OBJ_GET_SIZE(oop); - if (inc > STIX_TYPE_MAX(stix_oow_t) - count) + 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? */ return STIX_NULL; @@ -855,7 +855,7 @@ static stix_oop_t add_unsigned_integers (stix_t* stix, stix_oop_t x, stix_oop_t bs = STIX_OBJ_GET_SIZE(y); zs = (as >= bs? as: bs); - if (zs >= STIX_TYPE_MAX(stix_oow_t)) + if (zs >= STIX_OBJ_SIZE_MAX) { stix->errnum = STIX_ENOMEM; /* TOOD: is it a soft failure or hard failure? */ return STIX_NULL; @@ -916,7 +916,7 @@ static stix_oop_t multiply_unsigned_integers (stix_t* stix, stix_oop_t x, stix_o xz = STIX_OBJ_GET_SIZE(x); yz = STIX_OBJ_GET_SIZE(y); - if (yz > STIX_TYPE_MAX(stix_oow_t) - xz) + if (yz > STIX_OBJ_SIZE_MAX - xz) { stix->errnum = STIX_ENOMEM; /* TOOD: is it a soft failure or hard failure? */ return STIX_NULL; diff --git a/stix/lib/dic.c b/stix/lib/dic.c index bc5c73d..9044f87 100644 --- a/stix/lib/dic.c +++ b/stix/lib/dic.c @@ -33,15 +33,39 @@ static stix_oop_oop_t expand_bucket (stix_t* stix, stix_oop_oop_t oldbuc) stix_oop_association_t ass; stix_oop_char_t key; -/* TODO: derive a better growth size */ + oldsz = STIX_OBJ_GET_SIZE(oldbuc); + + /* TODO: better growth policy? */ + if (oldsz < 5000) newsz = oldsz + oldsz; + else if (oldsz < 50000) newsz = oldsz + (oldsz / 2); + else if (oldsz < 100000) newsz = oldsz + (oldsz / 4); + else if (oldsz < 200000) newsz = oldsz + (oldsz / 8); + else if (oldsz < 400000) newsz = oldsz + (oldsz / 16); + else if (oldsz < 800000) newsz = oldsz + (oldsz / 32); + else if (oldsz < 1600000) newsz = oldsz + (oldsz / 64); + else + { + stix_oow_t inc, inc_max; + + inc = oldsz / 128; + inc_max = STIX_OBJ_SIZE_MAX - oldsz; + if (inc > inc_max) + { + if (inc_max > 0) inc = inc_max; + else + { + stix->errnum = STIX_ENOMEM; + return STIX_NULL; + } + } + newsz = oldsz + inc; + } + stix_pushtmp (stix, (stix_oop_t*)&oldbuc); - newbuc = (stix_oop_oop_t)stix_instantiate (stix, stix->_array, STIX_NULL, STIX_OBJ_GET_SIZE(oldbuc) * 2); + newbuc = (stix_oop_oop_t)stix_instantiate (stix, stix->_array, STIX_NULL, newsz); stix_poptmp (stix); if (!newbuc) return STIX_NULL; - oldsz = STIX_OBJ_GET_SIZE(oldbuc); - newsz = STIX_OBJ_GET_SIZE(newbuc); - while (oldsz > 0) { ass = (stix_oop_association_t)oldbuc->slot[--oldsz]; diff --git a/stix/lib/main.c b/stix/lib/main.c index 02ba8c3..f224140 100644 --- a/stix/lib/main.c +++ b/stix/lib/main.c @@ -384,7 +384,7 @@ int main (int argc, char* argv[]) stix_vmprim_t vmprim; int i; - printf ("Stix 1.0.0 - max named %lu max indexed %lu max class %lu max classinst %lu oowmax %lu, ooimax %ld ooimin %ld smintmax %ld smintmax %ld\n", + printf ("Stix 1.0.0 - max named %lu max indexed %lu max class %lu max classinst %lu oowmax %lu, ooimax %ld ooimin %ld smooimax %ld smooimax %ld\n", (unsigned long int)STIX_MAX_NAMED_INSTVARS, (unsigned long int)STIX_MAX_INDEXED_INSTVARS(STIX_MAX_NAMED_INSTVARS), (unsigned long int)STIX_MAX_CLASSVARS, diff --git a/stix/lib/obj.c b/stix/lib/obj.c index a2496c7..af72630 100644 --- a/stix/lib/obj.c +++ b/stix/lib/obj.c @@ -199,11 +199,14 @@ stix_oop_t stix_instantiate (stix_t* stix, stix_oop_t _class, const void* vptr, { goto einval; } + + STIX_ASSERT (named_instvar + vlen <= STIX_OBJ_SIZE_MAX); } 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; } } else @@ -211,9 +214,10 @@ stix_oop_t stix_instantiate (stix_t* stix, stix_oop_t _class, const void* vptr, /* 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; + vlen = 0; /* vlen is not used */ if (named_instvar > STIX_MAX_NAMED_INSTVARS) goto einval; + STIX_ASSERT (named_instvar <= STIX_OBJ_SIZE_MAX); } stix_pushtmp (stix, &_class); tmp_count++; diff --git a/stix/lib/stix-prv.h b/stix/lib/stix-prv.h index f6efdc6..41d7127 100644 --- a/stix/lib/stix-prv.h +++ b/stix/lib/stix-prv.h @@ -55,7 +55,6 @@ /*#define STIX_DEBUG_EXEC*/ #define STIX_PROFILE_EXEC - #include /* TODO: delete these header inclusion lines */ #include #include @@ -118,8 +117,9 @@ * |number of named instance variables|indexed-type|indexability|oop-tag| * * the number of named instance variables is stored in high 23 bits. - * the indexed type takes up bit 3 to bit 8. And the indexability is - * stored in bit 2. + * the indexed type takes up bit 3 to bit 8 (assuming STIX_OBJ_TYPE_BITS is 6. + * STIX_OBJ_TYPE_XXX enumerators are used to represent actual values). + * and the indexability is stored in bit 2. * * The maximum number of named(fixed) instance variables for a class is: * 2 ^ ((BITS-IN-OOW - STIX_OOP_TAG_BITS) - STIX_OBJ_TYPE_BITS - 1) - 1 @@ -163,11 +163,15 @@ * This limit is set so because the number must be encoded into the spec field * of the class with limited number of bits assigned to the number of * named instance variables. the trailing -1 in the calculation of number of - * bits is to consider the signness of a small-integer which is a typical + * bits is to consider the sign bit of a small-integer which is a typical * type of the spec field in the class object. */ +/* #define STIX_MAX_NAMED_INSTVARS \ STIX_BITS_MAX(stix_oow_t, STIX_OOW_BITS - STIX_OOP_TAG_BITS - (STIX_OBJ_FLAGS_TYPE_BITS + 1) - 1) +*/ +#define STIX_MAX_NAMED_INSTVARS \ + STIX_BITS_MAX(stix_oow_t, STIX_SMOOI_ABS_BITS - (STIX_OBJ_FLAGS_TYPE_BITS + 1)) /* Given the number of named instance variables, what is the maximum number * of indexed instance variables? The number of indexed instance variables @@ -176,21 +180,32 @@ * named instance variables. So it's the maximum value of obj->_size minus * the number of named instance variables. */ -#define STIX_MAX_INDEXED_INSTVARS(named_instvar) ((~(stix_oow_t)0) - named_instvar) - +#define STIX_MAX_INDEXED_INSTVARS(named_instvar) (STIX_OBJ_SIZE_MAX - named_instvar) +/* #define STIX_CLASS_SELFSPEC_MAKE(class_var,classinst_var) \ (((stix_oow_t)class_var) << ((STIX_OOW_BITS - STIX_OOP_TAG_BITS) / 2)) | ((stix_oow_t)classinst_var) +*/ +#define STIX_CLASS_SELFSPEC_MAKE(class_var,classinst_var) \ + (((stix_oow_t)class_var) << (STIX_SMOOI_BITS / 2)) | ((stix_oow_t)classinst_var) +/* #define STIX_CLASS_SELFSPEC_CLASSVAR(spec) ((stix_oow_t)spec >> ((STIX_OOW_BITS - STIX_OOP_TAG_BITS) / 2)) #define STIX_CLASS_SELFSPEC_CLASSINSTVAR(spec) (((stix_oow_t)spec) & STIX_LBMASK(stix_oow_t, (STIX_OOW_BITS - STIX_OOP_TAG_BITS) / 2)) +*/ +#define STIX_CLASS_SELFSPEC_CLASSVAR(spec) ((stix_oow_t)spec >> (STIX_SMOOI_BITS / 2)) +#define STIX_CLASS_SELFSPEC_CLASSINSTVAR(spec) (((stix_oow_t)spec) & STIX_LBMASK(stix_oow_t, (STIX_SMOOI_BITS / 2))) /* * yet another -1 in the calculation of the bit numbers for signed nature of * a small-integer */ +/* #define STIX_MAX_CLASSVARS STIX_BITS_MAX(stix_oow_t, (STIX_OOW_BITS - STIX_OOP_TAG_BITS - 1) / 2) #define STIX_MAX_CLASSINSTVARS STIX_BITS_MAX(stix_oow_t, (STIX_OOW_BITS - STIX_OOP_TAG_BITS - 1) / 2) +*/ +#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_INCLUDE_COMPILER) @@ -855,7 +870,7 @@ extern "C" { */ stix_heap_t* stix_makeheap ( stix_t* stix, - stix_oow_t size + stix_oow_t size ); /** @@ -875,7 +890,7 @@ void stix_killheap ( void* stix_allocheapmem ( stix_t* stix, stix_heap_t* heap, - stix_oow_t size + stix_oow_t size ); @@ -892,7 +907,7 @@ stix_oop_t stix_moveoop ( /* ========================================================================= */ void* stix_allocbytes ( stix_t* stix, - stix_oow_t size + stix_oow_t size ); /** @@ -984,7 +999,7 @@ stix_oop_association_t stix_getatsysdic ( ); stix_oop_association_t stix_lookupsysdic ( - stix_t* stix, + stix_t* stix, const stix_oocs_t* name ); @@ -1002,8 +1017,8 @@ stix_oop_association_t stix_getatdic ( ); stix_oop_association_t stix_lookupdic ( - stix_t* stix, - stix_oop_set_t dic, + stix_t* stix, + stix_oop_set_t dic, const stix_oocs_t* name ); @@ -1026,20 +1041,20 @@ stix_oop_process_t stix_makeproc ( stix_oow_t stix_uctoutf8 ( stix_uch_t uc, stix_bch_t* utf8, - stix_oow_t size + stix_oow_t size ); stix_oow_t stix_utf8touc ( const stix_bch_t* utf8, - stix_oow_t size, + stix_oow_t size, stix_uch_t* uc ); int stix_ucstoutf8 ( const stix_uch_t* ucs, - stix_oow_t* ucslen, + stix_oow_t* ucslen, stix_bch_t* bcs, - stix_oow_t* bcslen + stix_oow_t* bcslen ); /** @@ -1072,9 +1087,9 @@ int stix_ucstoutf8 ( */ int stix_utf8toucs ( const stix_bch_t* bcs, - stix_oow_t* bcslen, + stix_oow_t* bcslen, stix_uch_t* ucs, - stix_oow_t* ucslen + stix_oow_t* ucslen ); /* ========================================================================= */ @@ -1152,7 +1167,7 @@ stix_oop_t stix_inttostr ( /* comp.c */ /* ========================================================================= */ STIX_EXPORT int stix_compile ( - stix_t* stix, + stix_t* stix, stix_io_impl_t io ); @@ -1165,7 +1180,7 @@ STIX_EXPORT void stix_getsynerr ( /* exec.c */ /* ========================================================================= */ int stix_getprimno ( - stix_t* stix, + stix_t* stix, const stix_oocs_t* name ); diff --git a/stix/lib/stix.h b/stix/lib/stix.h index 23a7dbf..d31aab8 100644 --- a/stix/lib/stix.h +++ b/stix/lib/stix.h @@ -163,10 +163,14 @@ typedef struct stix_obj_word_t* stix_oop_word_t; #define STIX_CHAR_TO_OOP(num) ((stix_oop_t)((((stix_oow_t)(num)) << STIX_OOP_TAG_BITS) | STIX_OOP_TAG_CHAR)) #define STIX_OOP_TO_CHAR(oop) (((stix_oow_t)oop) >> STIX_OOP_TAG_BITS) -#define STIX_SMINT_BITS (STIX_SIZEOF(stix_ooi_t) * 8 - STIX_OOP_TAG_BITS) +/* SMOOI takes up 62 bit on a 64-bit architecture and 30 bits + * on a 32-bit architecture. The absolute value takes up 61 bits and 29 bits + * respectively for the 1 sign bit. */ +#define STIX_SMOOI_BITS (STIX_OOI_BITS - STIX_OOP_TAG_BITS) +#define STIX_SMOOI_ABS_BITS (STIX_SMOOI_BITS - 1) #define STIX_SMOOI_MAX ((stix_ooi_t)(~((stix_oow_t)0) >> (STIX_OOP_TAG_BITS + 1))) -/* Sacrificing 1 bit pattern for a negative SMOOI makes implementation - * a lot eaisier in many parts */ +/* Sacrificing 1 bit pattern for a negative SMOOI makes + * implementation a lot eaisier in many respect. */ /*#define STIX_SMOOI_MIN (-STIX_SMOOI_MAX - 1)*/ #define STIX_SMOOI_MIN (-STIX_SMOOI_MAX) #define STIX_IN_SMOOI_RANGE(ooi) ((ooi) >= STIX_SMOOI_MIN && (ooi) <= STIX_SMOOI_MAX) @@ -187,7 +191,6 @@ enum stix_obj_type_t STIX_OBJ_TYPE_BYTE, STIX_OBJ_TYPE_HALFWORD, STIX_OBJ_TYPE_WORD, - /* STIX_OBJ_TYPE_UINT8, @@ -293,6 +296,9 @@ 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; \ diff --git a/stix/lib/sym.c b/stix/lib/sym.c index b24c9f8..0a201ef 100644 --- a/stix/lib/sym.c +++ b/stix/lib/sym.c @@ -32,15 +32,39 @@ static stix_oop_oop_t expand_bucket (stix_t* stix, stix_oop_oop_t oldbuc) stix_oow_t oldsz, newsz, index; stix_oop_char_t symbol; -/* TODO: derive a better growth size */ + oldsz = STIX_OBJ_GET_SIZE(oldbuc); + +/* TODO: better growth policy? */ + if (oldsz < 5000) newsz = oldsz + oldsz; + else if (oldsz < 50000) newsz = oldsz + (oldsz / 2); + else if (oldsz < 100000) newsz = oldsz + (oldsz / 4); + else if (oldsz < 200000) newsz = oldsz + (oldsz / 8); + else if (oldsz < 400000) newsz = oldsz + (oldsz / 16); + else if (oldsz < 800000) newsz = oldsz + (oldsz / 32); + else if (oldsz < 1600000) newsz = oldsz + (oldsz / 64); + else + { + stix_oow_t inc, inc_max; + + inc = oldsz / 128; + inc_max = STIX_OBJ_SIZE_MAX - oldsz; + if (inc > inc_max) + { + if (inc_max > 0) inc = inc_max; + else + { + stix->errnum = STIX_ENOMEM; + return STIX_NULL; + } + } + newsz = oldsz + inc; + } + stix_pushtmp (stix, (stix_oop_t*)&oldbuc); - newbuc = (stix_oop_oop_t)stix_instantiate (stix, stix->_array, STIX_NULL, STIX_OBJ_GET_SIZE(oldbuc) * 2); + newbuc = (stix_oop_oop_t)stix_instantiate (stix, stix->_array, STIX_NULL, newsz); stix_poptmp (stix); if (!newbuc) return STIX_NULL; - oldsz = STIX_OBJ_GET_SIZE(oldbuc); - newsz = STIX_OBJ_GET_SIZE(newbuc); - while (oldsz > 0) { symbol = (stix_oop_char_t)oldbuc->slot[--oldsz];