touched up hash macros and functions
This commit is contained in:
parent
ec5f881951
commit
e93da317e3
@ -77,7 +77,7 @@ static moo_oop_oop_t expand_bucket (moo_t* moo, moo_oop_oop_t oldbuc)
|
|||||||
key = (moo_oop_char_t)ass->key;
|
key = (moo_oop_char_t)ass->key;
|
||||||
MOO_ASSERT (moo, MOO_CLASSOF(moo,key) == moo->_symbol);
|
MOO_ASSERT (moo, MOO_CLASSOF(moo,key) == moo->_symbol);
|
||||||
|
|
||||||
index = moo_hashoochars(MOO_OBJ_GET_CHAR_SLOT(key), MOO_OBJ_GET_SIZE(key)) % newsz;
|
index = moo_hash_oochars(MOO_OBJ_GET_CHAR_SLOT(key), MOO_OBJ_GET_SIZE(key)) % newsz;
|
||||||
while (MOO_OBJ_GET_OOP_VAL(newbuc, index) != moo->_nil) index = (index + 1) % newsz;
|
while (MOO_OBJ_GET_OOP_VAL(newbuc, index) != moo->_nil) index = (index + 1) % newsz;
|
||||||
|
|
||||||
MOO_STORE_OOP (moo, MOO_OBJ_GET_OOP_PTR(newbuc, index), (moo_oop_t)ass);
|
MOO_STORE_OOP (moo, MOO_OBJ_GET_OOP_PTR(newbuc, index), (moo_oop_t)ass);
|
||||||
@ -101,7 +101,7 @@ static moo_oop_association_t find_or_upsert (moo_t* moo, moo_oop_dic_t dic, moo_
|
|||||||
MOO_ASSERT (moo, MOO_CLASSOF(moo,dic->tally) == moo->_small_integer);
|
MOO_ASSERT (moo, MOO_CLASSOF(moo,dic->tally) == moo->_small_integer);
|
||||||
MOO_ASSERT (moo, MOO_CLASSOF(moo,dic->bucket) == moo->_array);
|
MOO_ASSERT (moo, MOO_CLASSOF(moo,dic->bucket) == moo->_array);
|
||||||
|
|
||||||
hv = moo_hashoochars(MOO_OBJ_GET_CHAR_SLOT(key), MOO_OBJ_GET_SIZE(key));
|
hv = moo_hash_oochars(MOO_OBJ_GET_CHAR_SLOT(key), MOO_OBJ_GET_SIZE(key));
|
||||||
index = hv % MOO_OBJ_GET_SIZE(dic->bucket);
|
index = hv % MOO_OBJ_GET_SIZE(dic->bucket);
|
||||||
|
|
||||||
/* find */
|
/* find */
|
||||||
@ -207,7 +207,7 @@ moo_oop_association_t moo_lookupdic_noseterr (moo_t* moo, moo_oop_dic_t dic, con
|
|||||||
MOO_ASSERT (moo, MOO_CLASSOF(moo,dic->tally) == moo->_small_integer);
|
MOO_ASSERT (moo, MOO_CLASSOF(moo,dic->tally) == moo->_small_integer);
|
||||||
MOO_ASSERT (moo, MOO_CLASSOF(moo,dic->bucket) == moo->_array);
|
MOO_ASSERT (moo, MOO_CLASSOF(moo,dic->bucket) == moo->_array);
|
||||||
|
|
||||||
index = moo_hashoochars(name->ptr, name->len) % MOO_OBJ_GET_SIZE(dic->bucket);
|
index = moo_hash_oochars(name->ptr, name->len) % MOO_OBJ_GET_SIZE(dic->bucket);
|
||||||
|
|
||||||
while ((moo_oop_t)(ass = (moo_oop_association_t)MOO_OBJ_GET_OOP_VAL(dic->bucket, index)) != moo->_nil)
|
while ((moo_oop_t)(ass = (moo_oop_association_t)MOO_OBJ_GET_OOP_VAL(dic->bucket, index)) != moo->_nil)
|
||||||
{
|
{
|
||||||
@ -289,7 +289,7 @@ int moo_deletedic (moo_t* moo, moo_oop_dic_t dic, const moo_oocs_t* name)
|
|||||||
tally = MOO_OOP_TO_SMOOI(dic->tally);
|
tally = MOO_OOP_TO_SMOOI(dic->tally);
|
||||||
|
|
||||||
bs = MOO_OBJ_GET_SIZE(dic->bucket);
|
bs = MOO_OBJ_GET_SIZE(dic->bucket);
|
||||||
hv = moo_hashoochars(name->ptr, name->len) % bs;
|
hv = moo_hash_oochars(name->ptr, name->len) % bs;
|
||||||
index = hv % bs;
|
index = hv % bs;
|
||||||
|
|
||||||
/* find */
|
/* find */
|
||||||
@ -322,7 +322,7 @@ found:
|
|||||||
|
|
||||||
/* otherwise get the natural hash index for the data in the slot at
|
/* otherwise get the natural hash index for the data in the slot at
|
||||||
* the current hash index */
|
* the current hash index */
|
||||||
z = moo_hashoochars(MOO_OBJ_GET_CHAR_SLOT(ass->key), MOO_OBJ_GET_SIZE(ass->key)) % bs;
|
z = moo_hash_oochars(MOO_OBJ_GET_CHAR_SLOT(ass->key), MOO_OBJ_GET_SIZE(ass->key)) % bs;
|
||||||
|
|
||||||
/* move an element if necesary */
|
/* move an element if necesary */
|
||||||
if ((y > x && (z <= x || z > y)) || (y < x && (z <= x && z > y)))
|
if ((y > x && (z <= x || z > y)) || (y < x && (z <= x && z > y)))
|
||||||
|
@ -2003,15 +2003,15 @@ static moo_pfrc_t pf_hash (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case MOO_OBJ_TYPE_CHAR:
|
case MOO_OBJ_TYPE_CHAR:
|
||||||
hv = moo_hashoochars (MOO_OBJ_GET_CHAR_SLOT(rcv), MOO_OBJ_GET_SIZE(rcv));
|
hv = moo_hash_oochars (MOO_OBJ_GET_CHAR_SLOT(rcv), MOO_OBJ_GET_SIZE(rcv));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MOO_OBJ_TYPE_HALFWORD:
|
case MOO_OBJ_TYPE_HALFWORD:
|
||||||
hv = moo_hashhalfwords(MOO_OBJ_GET_HALFWORD_SLOT(rcv), MOO_OBJ_GET_SIZE(rcv));
|
hv = moo_hash_halfwords(MOO_OBJ_GET_HALFWORD_SLOT(rcv), MOO_OBJ_GET_SIZE(rcv));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MOO_OBJ_TYPE_WORD:
|
case MOO_OBJ_TYPE_WORD:
|
||||||
hv = moo_hashwords(MOO_OBJ_GET_WORD_SLOT(rcv), MOO_OBJ_GET_SIZE(rcv));
|
hv = moo_hash_words(MOO_OBJ_GET_WORD_SLOT(rcv), MOO_OBJ_GET_SIZE(rcv));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -460,8 +460,8 @@ static int fmtoutv (moo_t* moo, const fmtchar_t* fmt, moo_fmtout_data_t* data, v
|
|||||||
#endif
|
#endif
|
||||||
lowercase_s:
|
lowercase_s:
|
||||||
|
|
||||||
bsp = va_arg (ap, moo_bch_t*);
|
bsp = va_arg(ap, moo_bch_t*);
|
||||||
if (bsp == MOO_NULL) bsp = bch_nullstr;
|
if (!bsp) bsp = bch_nullstr;
|
||||||
|
|
||||||
#if defined(MOO_OOCH_IS_UCH)
|
#if defined(MOO_OOCH_IS_UCH)
|
||||||
/* get the length */
|
/* get the length */
|
||||||
@ -536,8 +536,8 @@ static int fmtoutv (moo_t* moo, const fmtchar_t* fmt, moo_fmtout_data_t* data, v
|
|||||||
if (lm_flag & LF_J) goto lowercase_s;
|
if (lm_flag & LF_J) goto lowercase_s;
|
||||||
#endif
|
#endif
|
||||||
uppercase_s:
|
uppercase_s:
|
||||||
usp = va_arg (ap, moo_uch_t*);
|
usp = va_arg(ap, moo_uch_t*);
|
||||||
if (usp == MOO_NULL) usp = uch_nullstr;
|
if (!usp) usp = uch_nullstr;
|
||||||
|
|
||||||
#if defined(MOO_OOCH_IS_BCH)
|
#if defined(MOO_OOCH_IS_BCH)
|
||||||
/* get the length */
|
/* get the length */
|
||||||
@ -682,15 +682,15 @@ static int fmtoutv (moo_t* moo, const fmtchar_t* fmt, moo_fmtout_data_t* data, v
|
|||||||
{
|
{
|
||||||
if (fltfmt->ptr == fltfmt->buf)
|
if (fltfmt->ptr == fltfmt->buf)
|
||||||
{
|
{
|
||||||
fltfmt->ptr = MOO_MMGR_ALLOC (MOO_MMGR_GETDFL(), MOO_SIZEOF(*fltfmt->ptr) * (fmtlen + 1));
|
fltfmt->ptr = MOO_MMGR_ALLOC(MOO_MMGR_GETDFL(), MOO_SIZEOF(*fltfmt->ptr) * (fmtlen + 1));
|
||||||
if (fltfmt->ptr == MOO_NULL) goto oops;
|
if (!fltfmt->ptr) goto oops;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
moo_mchar_t* tmpptr;
|
moo_bch_t* tmpptr;
|
||||||
|
|
||||||
tmpptr = MOO_MMGR_REALLOC (MOO_MMGR_GETDFL(), fltfmt->ptr, MOO_SIZEOF(*fltfmt->ptr) * (fmtlen + 1));
|
tmpptr = MOO_MMGR_REALLOC(MOO_MMGR_GETDFL(), fltfmt->ptr, MOO_SIZEOF(*fltfmt->ptr) * (fmtlen + 1));
|
||||||
if (tmpptr == MOO_NULL) goto oops;
|
if (!tmpptr) goto oops;
|
||||||
fltfmt->ptr = tmpptr;
|
fltfmt->ptr = tmpptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -742,8 +742,8 @@ static int fmtoutv (moo_t* moo, const fmtchar_t* fmt, moo_fmtout_data_t* data, v
|
|||||||
{
|
{
|
||||||
MOO_ASSERT (moo, fltout->ptr == fltout->buf);
|
MOO_ASSERT (moo, fltout->ptr == fltout->buf);
|
||||||
|
|
||||||
fltout->ptr = MOO_MMGR_ALLOC (MOO_MMGR_GETDFL(), MOO_SIZEOF(char_t) * (newcapa + 1));
|
fltout->ptr = MOO_MMGR_ALLOC(MOO_MMGR_GETDFL(), MOO_SIZEOF(char_t) * (newcapa + 1));
|
||||||
if (fltout->ptr == MOO_NULL) goto oops;
|
if (!fltout->ptr) goto oops;
|
||||||
fltout->capa = newcapa;
|
fltout->capa = newcapa;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -754,23 +754,23 @@ static int fmtoutv (moo_t* moo, const fmtchar_t* fmt, moo_fmtout_data_t* data, v
|
|||||||
if (dtype == LF_LD)
|
if (dtype == LF_LD)
|
||||||
{
|
{
|
||||||
#if defined(HAVE_SNPRINTF)
|
#if defined(HAVE_SNPRINTF)
|
||||||
q = snprintf ((moo_mchar_t*)fltout->ptr, fltout->capa + 1, fltfmt->ptr, v_ld);
|
q = snprintf ((moo_bch_t*)fltout->ptr, fltout->capa + 1, fltfmt->ptr, v_ld);
|
||||||
#else
|
#else
|
||||||
q = sprintf ((moo_mchar_t*)fltout->ptr, fltfmt->ptr, v_ld);
|
q = sprintf ((moo_bch_t*)fltout->ptr, fltfmt->ptr, v_ld);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#if (MOO_SIZEOF___FLOAT128 > 0) && defined(HAVE_QUADMATH_SNPRINTF)
|
#if (MOO_SIZEOF___FLOAT128 > 0) && defined(HAVE_QUADMATH_SNPRINTF)
|
||||||
else if (dtype == LF_QD)
|
else if (dtype == LF_QD)
|
||||||
{
|
{
|
||||||
q = quadmath_snprintf ((moo_mchar_t*)fltout->ptr, fltout->capa + 1, fltfmt->ptr, v_qd);
|
q = quadmath_snprintf((moo_bch_t*)fltout->ptr, fltout->capa + 1, fltfmt->ptr, v_qd);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#if defined(HAVE_SNPRINTF)
|
#if defined(HAVE_SNPRINTF)
|
||||||
q = snprintf ((moo_mchar_t*)fltout->ptr, fltout->capa + 1, fltfmt->ptr, v_d);
|
q = snprintf ((moo_bch_t*)fltout->ptr, fltout->capa + 1, fltfmt->ptr, v_d);
|
||||||
#else
|
#else
|
||||||
q = sprintf ((moo_mchar_t*)fltout->ptr, fltfmt->ptr, v_d);
|
q = sprintf ((moo_bch_t*)fltout->ptr, fltfmt->ptr, v_d);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (q <= -1) goto oops;
|
if (q <= -1) goto oops;
|
||||||
@ -781,27 +781,27 @@ static int fmtoutv (moo_t* moo, const fmtchar_t* fmt, moo_fmtout_data_t* data, v
|
|||||||
|
|
||||||
if (fltout->ptr == fltout->sbuf)
|
if (fltout->ptr == fltout->sbuf)
|
||||||
{
|
{
|
||||||
fltout->ptr = MOO_MMGR_ALLOC (MOO_MMGR_GETDFL(), MOO_SIZEOF(char_t) * (newcapa + 1));
|
fltout->ptr = MOO_MMGR_ALLOC(MOO_MMGR_GETDFL(), MOO_SIZEOF(char_t) * (newcapa + 1));
|
||||||
if (fltout->ptr == MOO_NULL) goto oops;
|
if (!fltout->ptr) goto oops;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char_t* tmpptr;
|
char_t* tmpptr;
|
||||||
|
|
||||||
tmpptr = MOO_MMGR_REALLOC (MOO_MMGR_GETDFL(), fltout->ptr, MOO_SIZEOF(char_t) * (newcapa + 1));
|
tmpptr = MOO_MMGR_REALLOC(MOO_MMGR_GETDFL(), fltout->ptr, MOO_SIZEOF(char_t) * (newcapa + 1));
|
||||||
if (tmpptr == MOO_NULL) goto oops;
|
if (!tmpptr) goto oops;
|
||||||
fltout->ptr = tmpptr;
|
fltout->ptr = tmpptr;
|
||||||
}
|
}
|
||||||
fltout->capa = newcapa;
|
fltout->capa = newcapa;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MOO_SIZEOF(char_t) != MOO_SIZEOF(moo_mchar_t))
|
if (MOO_SIZEOF(char_t) != MOO_SIZEOF(moo_bch_t))
|
||||||
{
|
{
|
||||||
fltout->ptr[q] = '\0';
|
fltout->ptr[q] = '\0';
|
||||||
while (q > 0)
|
while (q > 0)
|
||||||
{
|
{
|
||||||
q--;
|
q--;
|
||||||
fltout->ptr[q] = ((moo_mchar_t*)fltout->ptr)[q];
|
fltout->ptr[q] = ((moo_bch_t*)fltout->ptr)[q];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -682,7 +682,7 @@ static void compact_symbol_table (moo_t* moo, moo_oop_t _nil)
|
|||||||
/* get the natural hash index for the data in the slot
|
/* get the natural hash index for the data in the slot
|
||||||
* at the current hash index */
|
* at the current hash index */
|
||||||
MOO_ASSERT (moo, MOO_CLASSOF(moo,tmp) == moo->_symbol);
|
MOO_ASSERT (moo, MOO_CLASSOF(moo,tmp) == moo->_symbol);
|
||||||
z = moo_hashoochars(MOO_OBJ_GET_CHAR_SLOT(tmp), MOO_OBJ_GET_SIZE(tmp)) % bucket_size;
|
z = moo_hash_oochars(MOO_OBJ_GET_CHAR_SLOT(tmp), MOO_OBJ_GET_SIZE(tmp)) % bucket_size;
|
||||||
|
|
||||||
/* move an element if necessary */
|
/* move an element if necessary */
|
||||||
if ((y > x && (z <= x || z > y)) || (y < x && (z <= x && z > y)))
|
if ((y > x && (z <= x || z > y)) || (y < x && (z <= x && z > y)))
|
||||||
|
@ -271,7 +271,7 @@
|
|||||||
|
|
||||||
/* =========================================================================
|
/* =========================================================================
|
||||||
* BASIC MOO TYPES
|
* BASIC MOO TYPES
|
||||||
* =========================================================================*/
|
* ========================================================================= */
|
||||||
|
|
||||||
typedef char moo_bch_t;
|
typedef char moo_bch_t;
|
||||||
typedef int moo_bci_t;
|
typedef int moo_bci_t;
|
||||||
@ -347,6 +347,108 @@ typedef struct moo_bcs_t moo_bcs_t;
|
|||||||
/* the maximum number of bch charaters to represent a single uch character */
|
/* the maximum number of bch charaters to represent a single uch character */
|
||||||
#define MOO_BCSIZE_MAX 6
|
#define MOO_BCSIZE_MAX 6
|
||||||
|
|
||||||
|
|
||||||
|
/* =========================================================================
|
||||||
|
* BASIC OOP ENCODING
|
||||||
|
* ========================================================================= */
|
||||||
|
|
||||||
|
/* actual structure defined in moo.h */
|
||||||
|
typedef struct moo_obj_t moo_obj_t;
|
||||||
|
typedef struct moo_obj_t* moo_oop_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* An object pointer(OOP) is an ordinary pointer value to an object.
|
||||||
|
* but some simple numeric values are also encoded into OOP using a simple
|
||||||
|
* bit-shifting and masking.
|
||||||
|
*
|
||||||
|
* A real OOP is stored without any bit-shifting while a non-pointer value encoded
|
||||||
|
* in an OOP is bit-shifted to the left by 2 and the 2 least-significant bits
|
||||||
|
* are set to 1 or 2.
|
||||||
|
*
|
||||||
|
* This scheme works because the object allocators aligns the object size to
|
||||||
|
* a multiple of sizeof(moo_oop_t). This way, the 2 least-significant bits
|
||||||
|
* of a real OOP are always 0s.
|
||||||
|
*
|
||||||
|
* With 2 bits, i can encode only 3 special types except object pointers.
|
||||||
|
* Since I need more than 3 special types, I extend the tag bits up to 4 bits
|
||||||
|
* to represent a special data type that doesn't require a range as wide
|
||||||
|
* as a small integer. A unicode character, for instance, only requires 21
|
||||||
|
* bits at most. An error doesn't need to be as diverse as a small integer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define MOO_OOP_TAG_BITS_LO 2
|
||||||
|
#define MOO_OOP_TAG_BITS_HI 2
|
||||||
|
|
||||||
|
#define MOO_OOP_TAG_SMOOI 1 /* 01 */
|
||||||
|
#define MOO_OOP_TAG_SMPTR 2 /* 10 */
|
||||||
|
#define MOO_OOP_TAG_EXTENDED 3 /* 11 - internal use only */
|
||||||
|
#define MOO_OOP_TAG_CHAR 3 /* 0011 */
|
||||||
|
#define MOO_OOP_TAG_ERROR 7 /* 0111 */
|
||||||
|
#define MOO_OOP_TAG_RESERVED0 11 /* 1011 */
|
||||||
|
#define MOO_OOP_TAG_RESERVED1 15 /* 1111 */
|
||||||
|
|
||||||
|
#define MOO_OOP_GET_TAG_LO(oop) (((moo_oow_t)oop) & MOO_LBMASK(moo_oow_t, MOO_OOP_TAG_BITS_LO))
|
||||||
|
#define MOO_OOP_GET_TAG_LOHI(oop) (((moo_oow_t)oop) & MOO_LBMASK(moo_oow_t, MOO_OOP_TAG_BITS_LO + MOO_OOP_TAG_BITS_HI))
|
||||||
|
#define MOO_OOP_GET_TAG(oop) (MOO_OOP_GET_TAG_LO(oop) == MOO_OOP_TAG_EXTENDED? MOO_OOP_GET_TAG_LOHI(oop): MOO_OOP_GET_TAG_LO(oop))
|
||||||
|
|
||||||
|
#define MOO_OOP_IS_NUMERIC(oop) (MOO_OOP_GET_TAG_LO(oop) != 0)
|
||||||
|
#define MOO_OOP_IS_POINTER(oop) (MOO_OOP_GET_TAG_LO(oop) == 0)
|
||||||
|
|
||||||
|
#define MOO_OOP_IS_SMOOI(oop) (MOO_OOP_GET_TAG_LO(oop) == MOO_OOP_TAG_SMOOI)
|
||||||
|
#define MOO_OOP_IS_SMPTR(oop) (MOO_OOP_GET_TAG_LO(oop) == MOO_OOP_TAG_SMPTR)
|
||||||
|
|
||||||
|
#define MOO_SMOOI_TO_OOP(num) ((moo_oop_t)((((moo_oow_t)(moo_ooi_t)(num)) << MOO_OOP_TAG_BITS_LO) | MOO_OOP_TAG_SMOOI))
|
||||||
|
#define MOO_OOP_TO_SMOOI(oop) (((moo_ooi_t)oop) >> MOO_OOP_TAG_BITS_LO)
|
||||||
|
/*
|
||||||
|
#define MOO_SMPTR_TO_OOP(ptr) ((moo_oop_t)((((moo_oow_t)(ptr)) << MOO_OOP_TAG_BITS_LO) | MOO_OOP_TAG_SMPTR))
|
||||||
|
#define MOO_OOP_TO_SMPTR(oop) (((moo_ooi_t)oop) >> MOO_OOP_TAG_BITS_LO)
|
||||||
|
*/
|
||||||
|
#define MOO_SMPTR_TO_OOP(ptr) ((moo_oop_t)(((moo_oow_t)ptr) | MOO_OOP_TAG_SMPTR))
|
||||||
|
#define MOO_OOP_TO_SMPTR(oop) ((void*)(((moo_oow_t)oop) & ~MOO_LBMASK(moo_oow_t, MOO_OOP_TAG_BITS_LO)))
|
||||||
|
|
||||||
|
#define MOO_OOP_IS_CHAR(oop) (MOO_OOP_GET_TAG(oop) == MOO_OOP_TAG_CHAR)
|
||||||
|
#define MOO_OOP_IS_ERROR(oop) (MOO_OOP_GET_TAG(oop) == MOO_OOP_TAG_ERROR)
|
||||||
|
|
||||||
|
#define MOO_OOP_TO_CHAR(oop) (((moo_oow_t)oop) >> (MOO_OOP_TAG_BITS_LO + MOO_OOP_TAG_BITS_LO))
|
||||||
|
#define MOO_CHAR_TO_OOP(num) ((moo_oop_t)((((moo_oow_t)(num)) << (MOO_OOP_TAG_BITS_LO + MOO_OOP_TAG_BITS_LO)) | MOO_OOP_TAG_CHAR))
|
||||||
|
#define MOO_OOP_TO_ERROR(oop) (((moo_oow_t)oop) >> (MOO_OOP_TAG_BITS_LO + MOO_OOP_TAG_BITS_LO))
|
||||||
|
#define MOO_ERROR_TO_OOP(num) ((moo_oop_t)((((moo_oow_t)(num)) << (MOO_OOP_TAG_BITS_LO + MOO_OOP_TAG_BITS_LO)) | MOO_OOP_TAG_ERROR))
|
||||||
|
|
||||||
|
/* -------------------------------- */
|
||||||
|
|
||||||
|
/* SMOOI takes up 62 bits 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 sign bit. */
|
||||||
|
#define MOO_SMOOI_BITS (MOO_OOI_BITS - MOO_OOP_TAG_BITS_LO)
|
||||||
|
#define MOO_SMOOI_ABS_BITS (MOO_SMOOI_BITS - 1)
|
||||||
|
#define MOO_SMOOI_MAX ((moo_ooi_t)(~((moo_oow_t)0) >> (MOO_OOP_TAG_BITS_LO + 1)))
|
||||||
|
/* Sacrificing 1 bit pattern for a negative SMOOI makes
|
||||||
|
* implementation a lot eaisier in many aspects. */
|
||||||
|
/*#define MOO_SMOOI_MIN (-MOO_SMOOI_MAX - 1)*/
|
||||||
|
#define MOO_SMOOI_MIN (-MOO_SMOOI_MAX)
|
||||||
|
#define MOO_IN_SMOOI_RANGE(ooi) ((ooi) >= MOO_SMOOI_MIN && (ooi) <= MOO_SMOOI_MAX)
|
||||||
|
|
||||||
|
/* SMPTR is a special value which has been devised to encode an address value
|
||||||
|
* whose low MOO_OOP_TAG_BITS_LO bits are 0. its class is SmallPointer. A pointer
|
||||||
|
* returned by most of system functions would be aligned to the pointer size.
|
||||||
|
* you can use the followings macros when converting such a pointer without loss. */
|
||||||
|
#define MOO_IN_SMPTR_RANGE(ptr) ((((moo_oow_t)ptr) & MOO_LBMASK(moo_oow_t, MOO_OOP_TAG_BITS_LO)) == 0)
|
||||||
|
|
||||||
|
#define MOO_CHAR_BITS (MOO_OOI_BITS - MOO_OOP_TAG_BITS_LO - MOO_OOP_TAG_BITS_HI)
|
||||||
|
#define MOO_CHAR_MIN 0
|
||||||
|
#define MOO_CHAR_MAX (~((moo_oow_t)0) >> (MOO_OOP_TAG_BITS_LO + MOO_OOP_TAG_BITS_HI))
|
||||||
|
|
||||||
|
#define MOO_ERROR_BITS (MOO_OOI_BITS - MOO_OOP_TAG_BITS_LO - MOO_OOP_TAG_BITS_HI)
|
||||||
|
#define MOO_ERROR_MIN 0
|
||||||
|
#define MOO_ERROR_MAX (~((moo_oow_t)0) >> (MOO_OOP_TAG_BITS_LO + MOO_OOP_TAG_BITS_HI))
|
||||||
|
|
||||||
|
/* TODO: There are untested code where a small integer is converted to moo_oow_t.
|
||||||
|
* for example, the spec making macro treats the number as moo_oow_t instead of moo_ooi_t.
|
||||||
|
* as of this writing, i skip testing that part with the spec value exceeding MOO_SMOOI_MAX.
|
||||||
|
* later, please verify it works, probably by limiting the value ranges in such macros
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* =========================================================================
|
/* =========================================================================
|
||||||
* TIME-RELATED TYPES
|
* TIME-RELATED TYPES
|
||||||
* =========================================================================*/
|
* =========================================================================*/
|
||||||
|
@ -29,10 +29,9 @@
|
|||||||
|
|
||||||
#include "moo-cmn.h"
|
#include "moo-cmn.h"
|
||||||
|
|
||||||
|
/* =========================================================================
|
||||||
/* -----------------------------------------------------------------------
|
* DOUBLY LINKED LIST
|
||||||
* DOUBLY LINKED LIST MACROS
|
* ========================================================================= */
|
||||||
* ----------------------------------------------------------------------- */
|
|
||||||
#define MOO_APPEND_TO_LIST(list, node) do { \
|
#define MOO_APPEND_TO_LIST(list, node) do { \
|
||||||
(node)->next = MOO_NULL; \
|
(node)->next = MOO_NULL; \
|
||||||
(node)->prev = (list)->last; \
|
(node)->prev = (list)->last; \
|
||||||
@ -57,7 +56,6 @@
|
|||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define MOO_APPEND_TO_OOP_LIST(moo, list, node_type, node, _link) do { \
|
#define MOO_APPEND_TO_OOP_LIST(moo, list, node_type, node, _link) do { \
|
||||||
(node)->_link.next = (node_type)(moo)->_nil; \
|
(node)->_link.next = (node_type)(moo)->_nil; \
|
||||||
(node)->_link.prev = (list)->last; \
|
(node)->_link.prev = (list)->last; \
|
||||||
@ -89,8 +87,9 @@
|
|||||||
} while(0);
|
} while(0);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* =========================================================================
|
||||||
|
* ENDIAN CHANGE
|
||||||
|
* ========================================================================= */
|
||||||
#define MOO_CONST_SWAP16(x) \
|
#define MOO_CONST_SWAP16(x) \
|
||||||
((qse_uint16_t)((((qse_uint16_t)(x) & (qse_uint16_t)0x00ffU) << 8) | \
|
((qse_uint16_t)((((qse_uint16_t)(x) & (qse_uint16_t)0x00ffU) << 8) | \
|
||||||
(((qse_uint16_t)(x) & (qse_uint16_t)0xff00U) >> 8) ))
|
(((qse_uint16_t)(x) & (qse_uint16_t)0xff00U) >> 8) ))
|
||||||
@ -116,46 +115,129 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* =========================================================================
|
||||||
|
* HASH
|
||||||
|
* ========================================================================= */
|
||||||
|
|
||||||
|
#if (MOO_SIZEOF_SIZE_T == 4)
|
||||||
|
# define MOO_HASH_FNV_MAGIC_INIT (0x811c9dc5)
|
||||||
|
# define MOO_HASH_FNV_MAGIC_PRIME (0x01000193)
|
||||||
|
#elif (MOO_SIZEOF_SIZE_T == 8)
|
||||||
|
|
||||||
|
# define MOO_HASH_FNV_MAGIC_INIT (0xCBF29CE484222325)
|
||||||
|
# define MOO_HASH_FNV_MAGIC_PRIME (0x100000001B3l)
|
||||||
|
|
||||||
|
#elif (MOO_SIZEOF_SIZE_T == 16)
|
||||||
|
# define MOO_HASH_FNV_MAGIC_INIT (0x6C62272E07BB014262B821756295C58D)
|
||||||
|
# define MOO_HASH_FNV_MAGIC_PRIME (0x1000000000000000000013B)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(MOO_HASH_FNV_MAGIC_INIT)
|
||||||
|
/* FNV-1 hash */
|
||||||
|
# define MOO_HASH_INIT MOO_HASH_FNV_MAGIC_INIT
|
||||||
|
# define MOO_HASH_VALUE(hv,v) (((hv) ^ (v)) * MOO_HASH_FNV_MAGIC_PRIME)
|
||||||
|
|
||||||
|
#else
|
||||||
|
/* SDBM hash */
|
||||||
|
# define MOO_HASH_INIT 0
|
||||||
|
# define MOO_HASH_VALUE(hv,v) (((hv) << 6) + ((hv) << 16) - (hv) + (v))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MOO_HASH_VPTL(hv, ptr, len, type) do { \
|
||||||
|
hv = MOO_HASH_INIT; \
|
||||||
|
MOO_HASH_MORE_VPTL (hv, ptr, len, type); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define MOO_HASH_MORE_VPTL(hv, ptr, len, type) do { \
|
||||||
|
type* __moo_hash_more_vptl_p = (type*)(ptr); \
|
||||||
|
type* __moo_hash_more_vptl_q = (type*)__moo_hash_more_vptl_p + (len); \
|
||||||
|
while (__moo_hash_more_vptl_p < __moo_hash_more_vptl_q) \
|
||||||
|
{ \
|
||||||
|
hv = MOO_HASH_VALUE(hv, *__moo_hash_more_vptl_p); \
|
||||||
|
__moo_hash_more_vptl_p++; \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define MOO_HASH_VPTR(hv, ptr, type) do { \
|
||||||
|
hv = MOO_HASH_INIT; \
|
||||||
|
MOO_HASH_MORE_VPTR (hv, ptr, type); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define MOO_HASH_MORE_VPTR(hv, ptr, type) do { \
|
||||||
|
type* __moo_hash_more_vptr_p = (type*)(ptr); \
|
||||||
|
while (*__moo_hash_more_vptr_p) \
|
||||||
|
{ \
|
||||||
|
hv = MOO_HASH_VALUE(hv, *__moo_hash_more_vptr_p); \
|
||||||
|
__moo_hash_more_vptr_p++; \
|
||||||
|
} \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
#define MOO_HASH_BYTES(hv, ptr, len) MOO_HASH_VPTL(hv, ptr, len, const moo_uint8_t)
|
||||||
|
#define MOO_HASH_MORE_BYTES(hv, ptr, len) MOO_HASH_MORE_VPTL(hv, ptr, len, const moo_uint8_t)
|
||||||
|
|
||||||
|
#define MOO_HASH_BCHARS(hv, ptr, len) MOO_HASH_VPTL(hv, ptr, len, const moo_bch_t)
|
||||||
|
#define MOO_HASH_MORE_BCHARS(hv, ptr, len) MOO_HASH_MORE_VPTL(hv, ptr, len, const moo_bch_t)
|
||||||
|
|
||||||
|
#define MOO_HASH_UCHARS(hv, ptr, len) MOO_HASH_VPTL(hv, ptr, len, const moo_uch_t)
|
||||||
|
#define MOO_HASH_MORE_UCHARS(hv, ptr, len) MOO_HASH_MORE_VPTL(hv, ptr, len, const moo_uch_t)
|
||||||
|
|
||||||
|
#define MOO_HASH_BCSTR(hv, ptr) MOO_HASH_VPTR(hv, ptr, const moo_bch_t)
|
||||||
|
#define MOO_HASH_MORE_BCSTR(hv, ptr) MOO_HASH_MORE_VPTR(hv, ptr, const moo_bch_t)
|
||||||
|
|
||||||
|
#define MOO_HASH_UCSTR(hv, ptr) MOO_HASH_VPTR(hv, ptr, const moo_uch_t)
|
||||||
|
#define MOO_HASH_MORE_UCSTR(hv, ptr) MOO_HASH_MORE_VPTR(hv, ptr, const moo_uch_t)
|
||||||
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MOO_EXPORT moo_oow_t moo_hash_bytes (
|
MOO_EXPORT moo_oow_t moo_hash_bytes_ (
|
||||||
const moo_oob_t* ptr,
|
const moo_oob_t* ptr,
|
||||||
moo_oow_t len
|
moo_oow_t len
|
||||||
);
|
);
|
||||||
|
|
||||||
#if defined(MOO_HAVE_INLINE)
|
#if defined(MOO_HAVE_INLINE)
|
||||||
static MOO_INLINE moo_oow_t moo_hashbchars (const moo_bch_t* ptr, moo_oow_t len)
|
static MOO_INLINE moo_oow_t moo_hash_bytes (const moo_oob_t* ptr, moo_oow_t len)
|
||||||
|
{
|
||||||
|
moo_oow_t hv;
|
||||||
|
MOO_HASH_BYTES (hv, ptr, len);
|
||||||
|
/* constrain the hash value to be representable in a small integer
|
||||||
|
* for convenience sake */
|
||||||
|
return hv % ((moo_oow_t)MOO_SMOOI_MAX + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static MOO_INLINE moo_oow_t moo_hash_bchars (const moo_bch_t* ptr, moo_oow_t len)
|
||||||
{
|
{
|
||||||
return moo_hash_bytes((const moo_oob_t*)ptr, len * MOO_SIZEOF(moo_bch_t));
|
return moo_hash_bytes((const moo_oob_t*)ptr, len * MOO_SIZEOF(moo_bch_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
static MOO_INLINE moo_oow_t moo_hashuchars (const moo_uch_t* ptr, moo_oow_t len)
|
static MOO_INLINE moo_oow_t moo_hash_uchars (const moo_uch_t* ptr, moo_oow_t len)
|
||||||
{
|
{
|
||||||
return moo_hash_bytes((const moo_oob_t*)ptr, len * MOO_SIZEOF(moo_uch_t));
|
return moo_hash_bytes((const moo_oob_t*)ptr, len * MOO_SIZEOF(moo_uch_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
static MOO_INLINE moo_oow_t moo_hashwords (const moo_oow_t* ptr, moo_oow_t len)
|
static MOO_INLINE moo_oow_t moo_hash_words (const moo_oow_t* ptr, moo_oow_t len)
|
||||||
{
|
{
|
||||||
return moo_hash_bytes((const moo_oob_t*)ptr, len * MOO_SIZEOF(moo_oow_t));
|
return moo_hash_bytes((const moo_oob_t*)ptr, len * MOO_SIZEOF(moo_oow_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
static MOO_INLINE moo_oow_t moo_hashhalfwords (const moo_oohw_t* ptr, moo_oow_t len)
|
static MOO_INLINE moo_oow_t moo_hash_halfwords (const moo_oohw_t* ptr, moo_oow_t len)
|
||||||
{
|
{
|
||||||
return moo_hash_bytes((const moo_oob_t*)ptr, len * MOO_SIZEOF(moo_oohw_t));
|
return moo_hash_bytes((const moo_oob_t*)ptr, len * MOO_SIZEOF(moo_oohw_t));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
# define moo_hashbchars(ptr,len) moo_hash_bytes((const moo_oob_t*)ptr, len * MOO_SIZEOF(moo_bch_t))
|
# define moo_hash_bytes(ptr,len) moo_hash_bytes_(ptr, len)
|
||||||
# define moo_hashuchars(ptr,len) moo_hash_bytes((const moo_oob_t*)ptr, len * MOO_SIZEOF(moo_uch_t))
|
# define moo_hash_bchars(ptr,len) moo_hash_bytes((const moo_oob_t*)(ptr), (len) * MOO_SIZEOF(moo_bch_t))
|
||||||
# define moo_hashwords(ptr,len) moo_hash_bytes((const moo_oob_t*)ptr, len * MOO_SIZEOF(moo_oow_t))
|
# define moo_hash_uchars(ptr,len) moo_hash_bytes((const moo_oob_t*)(ptr), (len) * MOO_SIZEOF(moo_uch_t))
|
||||||
# define moo_hashhalfwords(ptr,len) moo_hash_bytes((const moo_oob_t*)ptr, len * MOO_SIZEOF(moo_oohw_t))
|
# define moo_hash_words(ptr,len) moo_hash_bytes((const moo_oob_t*)(ptr), (len) * MOO_SIZEOF(moo_oow_t))
|
||||||
|
# define moo_hash_halfwords(ptr,len) moo_hash_bytes((const moo_oob_t*)(ptr), (len) * MOO_SIZEOF(moo_oohw_t))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(MOO_OOCH_IS_UCH)
|
#if defined(MOO_OOCH_IS_UCH)
|
||||||
# define moo_hashoochars(ptr,len) moo_hashuchars(ptr,len)
|
# define moo_hash_oochars(ptr,len) moo_hash_uchars(ptr,len)
|
||||||
#else
|
#else
|
||||||
# define moo_hashoochars(ptr,len) moo_hashbchars(ptr,len)
|
# define moo_hash_oochars(ptr,len) moo_hash_bchars(ptr,len)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
122
moo/lib/moo.h
122
moo/lib/moo.h
@ -131,8 +131,13 @@ enum moo_trait_t
|
|||||||
};
|
};
|
||||||
typedef enum moo_trait_t moo_trait_t;
|
typedef enum moo_trait_t moo_trait_t;
|
||||||
|
|
||||||
typedef struct moo_obj_t moo_obj_t;
|
|
||||||
typedef struct moo_obj_t* moo_oop_t;
|
/* =========================================================================
|
||||||
|
* SPECIALIZED OOP TYPES
|
||||||
|
* ========================================================================= */
|
||||||
|
|
||||||
|
/* moo_oop_t defined in moo-cmn.h
|
||||||
|
* moo_obj_t defined further down */
|
||||||
|
|
||||||
/* these are more specialized types for moo_obj_t */
|
/* these are more specialized types for moo_obj_t */
|
||||||
typedef struct moo_obj_oop_t moo_obj_oop_t;
|
typedef struct moo_obj_oop_t moo_obj_oop_t;
|
||||||
@ -154,9 +159,9 @@ typedef struct moo_obj_word_t* moo_oop_word_t;
|
|||||||
#define MOO_OOHW_BITS (MOO_SIZEOF_OOHW_T * 8)
|
#define MOO_OOHW_BITS (MOO_SIZEOF_OOHW_T * 8)
|
||||||
|
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* =========================================================================
|
||||||
/* BIGINT TYPES AND MACROS */
|
* BIGINT TYPES AND MACROS
|
||||||
/* ========================================================================= */
|
* ========================================================================= */
|
||||||
#if (MOO_SIZEOF_UINTMAX_T > MOO_SIZEOF_OOW_T)
|
#if (MOO_SIZEOF_UINTMAX_T > MOO_SIZEOF_OOW_T)
|
||||||
# define MOO_USE_FULL_WORD
|
# define MOO_USE_FULL_WORD
|
||||||
#endif
|
#endif
|
||||||
@ -197,102 +202,9 @@ enum moo_method_type_t
|
|||||||
};
|
};
|
||||||
typedef enum moo_method_type_t moo_method_type_t;
|
typedef enum moo_method_type_t moo_method_type_t;
|
||||||
|
|
||||||
/*
|
/* =========================================================================
|
||||||
* OOP encoding
|
* OBJECT STRUCTURE
|
||||||
* An object pointer(OOP) is an ordinary pointer value to an object.
|
* ========================================================================= */
|
||||||
* but some simple numeric values are also encoded into OOP using a simple
|
|
||||||
* bit-shifting and masking.
|
|
||||||
*
|
|
||||||
* A real OOP is stored without any bit-shifting while a non-pointer value encoded
|
|
||||||
* in an OOP is bit-shifted to the left by 2 and the 2 least-significant bits
|
|
||||||
* are set to 1 or 2.
|
|
||||||
*
|
|
||||||
* This scheme works because the object allocators aligns the object size to
|
|
||||||
* a multiple of sizeof(moo_oop_t). This way, the 2 least-significant bits
|
|
||||||
* of a real OOP are always 0s.
|
|
||||||
*
|
|
||||||
* With 2 bits, i can encode only 3 special types except object pointers.
|
|
||||||
* Since I need more than 3 special types, I extend the tag bits up to 4 bits
|
|
||||||
* to represent a special data type that doesn't require a range as wide
|
|
||||||
* as a small integer. A unicode character, for instance, only requires 21
|
|
||||||
* bits at most. An error doesn't need to be as diverse as a small integer.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define MOO_OOP_TAG_BITS_LO 2
|
|
||||||
#define MOO_OOP_TAG_BITS_HI 2
|
|
||||||
|
|
||||||
#define MOO_OOP_TAG_SMOOI 1 /* 01 */
|
|
||||||
#define MOO_OOP_TAG_SMPTR 2 /* 10 */
|
|
||||||
#define MOO_OOP_TAG_EXTENDED 3 /* 11 - internal use only */
|
|
||||||
#define MOO_OOP_TAG_CHAR 3 /* 0011 */
|
|
||||||
#define MOO_OOP_TAG_ERROR 7 /* 0111 */
|
|
||||||
#define MOO_OOP_TAG_RESERVED0 11 /* 1011 */
|
|
||||||
#define MOO_OOP_TAG_RESERVED1 15 /* 1111 */
|
|
||||||
|
|
||||||
#define MOO_OOP_GET_TAG_LO(oop) (((moo_oow_t)oop) & MOO_LBMASK(moo_oow_t, MOO_OOP_TAG_BITS_LO))
|
|
||||||
#define MOO_OOP_GET_TAG_LOHI(oop) (((moo_oow_t)oop) & MOO_LBMASK(moo_oow_t, MOO_OOP_TAG_BITS_LO + MOO_OOP_TAG_BITS_HI))
|
|
||||||
#define MOO_OOP_GET_TAG(oop) (MOO_OOP_GET_TAG_LO(oop) == MOO_OOP_TAG_EXTENDED? MOO_OOP_GET_TAG_LOHI(oop): MOO_OOP_GET_TAG_LO(oop))
|
|
||||||
|
|
||||||
#define MOO_OOP_IS_NUMERIC(oop) (MOO_OOP_GET_TAG_LO(oop) != 0)
|
|
||||||
#define MOO_OOP_IS_POINTER(oop) (MOO_OOP_GET_TAG_LO(oop) == 0)
|
|
||||||
|
|
||||||
#define MOO_OOP_IS_SMOOI(oop) (MOO_OOP_GET_TAG_LO(oop) == MOO_OOP_TAG_SMOOI)
|
|
||||||
#define MOO_OOP_IS_SMPTR(oop) (MOO_OOP_GET_TAG_LO(oop) == MOO_OOP_TAG_SMPTR)
|
|
||||||
|
|
||||||
#define MOO_SMOOI_TO_OOP(num) ((moo_oop_t)((((moo_oow_t)(moo_ooi_t)(num)) << MOO_OOP_TAG_BITS_LO) | MOO_OOP_TAG_SMOOI))
|
|
||||||
#define MOO_OOP_TO_SMOOI(oop) (((moo_ooi_t)oop) >> MOO_OOP_TAG_BITS_LO)
|
|
||||||
/*
|
|
||||||
#define MOO_SMPTR_TO_OOP(ptr) ((moo_oop_t)((((moo_oow_t)(ptr)) << MOO_OOP_TAG_BITS_LO) | MOO_OOP_TAG_SMPTR))
|
|
||||||
#define MOO_OOP_TO_SMPTR(oop) (((moo_ooi_t)oop) >> MOO_OOP_TAG_BITS_LO)
|
|
||||||
*/
|
|
||||||
#define MOO_SMPTR_TO_OOP(ptr) ((moo_oop_t)(((moo_oow_t)ptr) | MOO_OOP_TAG_SMPTR))
|
|
||||||
#define MOO_OOP_TO_SMPTR(oop) ((void*)(((moo_oow_t)oop) & ~MOO_LBMASK(moo_oow_t, MOO_OOP_TAG_BITS_LO)))
|
|
||||||
|
|
||||||
#define MOO_OOP_IS_CHAR(oop) (MOO_OOP_GET_TAG(oop) == MOO_OOP_TAG_CHAR)
|
|
||||||
#define MOO_OOP_IS_ERROR(oop) (MOO_OOP_GET_TAG(oop) == MOO_OOP_TAG_ERROR)
|
|
||||||
|
|
||||||
#define MOO_OOP_TO_CHAR(oop) (((moo_oow_t)oop) >> (MOO_OOP_TAG_BITS_LO + MOO_OOP_TAG_BITS_LO))
|
|
||||||
#define MOO_CHAR_TO_OOP(num) ((moo_oop_t)((((moo_oow_t)(num)) << (MOO_OOP_TAG_BITS_LO + MOO_OOP_TAG_BITS_LO)) | MOO_OOP_TAG_CHAR))
|
|
||||||
#define MOO_OOP_TO_ERROR(oop) (((moo_oow_t)oop) >> (MOO_OOP_TAG_BITS_LO + MOO_OOP_TAG_BITS_LO))
|
|
||||||
#define MOO_ERROR_TO_OOP(num) ((moo_oop_t)((((moo_oow_t)(num)) << (MOO_OOP_TAG_BITS_LO + MOO_OOP_TAG_BITS_LO)) | MOO_OOP_TAG_ERROR))
|
|
||||||
|
|
||||||
/* -------------------------------- */
|
|
||||||
|
|
||||||
/* SMOOI takes up 62 bits 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 sign bit. */
|
|
||||||
#define MOO_SMOOI_BITS (MOO_OOI_BITS - MOO_OOP_TAG_BITS_LO)
|
|
||||||
#define MOO_SMOOI_ABS_BITS (MOO_SMOOI_BITS - 1)
|
|
||||||
#define MOO_SMOOI_MAX ((moo_ooi_t)(~((moo_oow_t)0) >> (MOO_OOP_TAG_BITS_LO + 1)))
|
|
||||||
/* Sacrificing 1 bit pattern for a negative SMOOI makes
|
|
||||||
* implementation a lot eaisier in many aspects. */
|
|
||||||
/*#define MOO_SMOOI_MIN (-MOO_SMOOI_MAX - 1)*/
|
|
||||||
#define MOO_SMOOI_MIN (-MOO_SMOOI_MAX)
|
|
||||||
#define MOO_IN_SMOOI_RANGE(ooi) ((ooi) >= MOO_SMOOI_MIN && (ooi) <= MOO_SMOOI_MAX)
|
|
||||||
|
|
||||||
/* SMPTR is a special value which has been devised to encode an address value
|
|
||||||
* whose low MOO_OOP_TAG_BITS_LO bits are 0. its class is SmallPointer. A pointer
|
|
||||||
* returned by most of system functions would be aligned to the pointer size.
|
|
||||||
* you can use the followings macros when converting such a pointer without loss. */
|
|
||||||
#define MOO_IN_SMPTR_RANGE(ptr) ((((moo_oow_t)ptr) & MOO_LBMASK(moo_oow_t, MOO_OOP_TAG_BITS_LO)) == 0)
|
|
||||||
|
|
||||||
#define MOO_CHAR_BITS (MOO_OOI_BITS - MOO_OOP_TAG_BITS_LO - MOO_OOP_TAG_BITS_HI)
|
|
||||||
#define MOO_CHAR_MIN 0
|
|
||||||
#define MOO_CHAR_MAX (~((moo_oow_t)0) >> (MOO_OOP_TAG_BITS_LO + MOO_OOP_TAG_BITS_HI))
|
|
||||||
|
|
||||||
#define MOO_ERROR_BITS (MOO_OOI_BITS - MOO_OOP_TAG_BITS_LO - MOO_OOP_TAG_BITS_HI)
|
|
||||||
#define MOO_ERROR_MIN 0
|
|
||||||
#define MOO_ERROR_MAX (~((moo_oow_t)0) >> (MOO_OOP_TAG_BITS_LO + MOO_OOP_TAG_BITS_HI))
|
|
||||||
|
|
||||||
/* TODO: There are untested code where a small integer is converted to moo_oow_t.
|
|
||||||
* for example, the spec making macro treats the number as moo_oow_t instead of moo_ooi_t.
|
|
||||||
* as of this writing, i skip testing that part with the spec value exceeding MOO_SMOOI_MAX.
|
|
||||||
* later, please verify it works, probably by limiting the value ranges in such macros
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Object structure
|
|
||||||
*/
|
|
||||||
enum moo_obj_type_t
|
enum moo_obj_type_t
|
||||||
{
|
{
|
||||||
MOO_OBJ_TYPE_OOP,
|
MOO_OBJ_TYPE_OOP,
|
||||||
@ -1002,6 +914,11 @@ struct moo_fpdec_t
|
|||||||
#define MOO_BYTESOF(moo,oop) \
|
#define MOO_BYTESOF(moo,oop) \
|
||||||
(MOO_OOP_IS_NUMERIC(oop)? MOO_SIZEOF(moo_oow_t): MOO_OBJ_BYTESOF(oop))
|
(MOO_OOP_IS_NUMERIC(oop)? MOO_SIZEOF(moo_oow_t): MOO_OBJ_BYTESOF(oop))
|
||||||
|
|
||||||
|
|
||||||
|
/* =========================================================================
|
||||||
|
* HEAP
|
||||||
|
* ========================================================================= */
|
||||||
|
|
||||||
typedef struct moo_space_t moo_space_t;
|
typedef struct moo_space_t moo_space_t;
|
||||||
|
|
||||||
struct moo_space_t
|
struct moo_space_t
|
||||||
@ -1023,9 +940,8 @@ struct moo_heap_t
|
|||||||
moo_space_t newspace;
|
moo_space_t newspace;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* =========================================================================
|
/* =========================================================================
|
||||||
* MOO VM LOGGING
|
* VM LOGGING
|
||||||
* ========================================================================= */
|
* ========================================================================= */
|
||||||
|
|
||||||
enum moo_log_mask_t
|
enum moo_log_mask_t
|
||||||
|
@ -75,7 +75,7 @@ static moo_oop_oop_t expand_bucket (moo_t* moo, moo_oop_oop_t oldbuc)
|
|||||||
MOO_ASSERT (moo, MOO_CLASSOF(moo,symbol) == moo->_symbol);
|
MOO_ASSERT (moo, MOO_CLASSOF(moo,symbol) == moo->_symbol);
|
||||||
/*MOO_ASSERT (moo, sym->size > 0);*/
|
/*MOO_ASSERT (moo, sym->size > 0);*/
|
||||||
|
|
||||||
index = moo_hashoochars(MOO_OBJ_GET_CHAR_SLOT(symbol), MOO_OBJ_GET_SIZE(symbol)) % newsz;
|
index = moo_hash_oochars(MOO_OBJ_GET_CHAR_SLOT(symbol), MOO_OBJ_GET_SIZE(symbol)) % newsz;
|
||||||
while (MOO_OBJ_GET_OOP_VAL(newbuc, index) != moo->_nil) index = (index + 1) % newsz;
|
while (MOO_OBJ_GET_OOP_VAL(newbuc, index) != moo->_nil) index = (index + 1) % newsz;
|
||||||
MOO_STORE_OOP (moo, MOO_OBJ_GET_OOP_PTR(newbuc, index), (moo_oop_t)symbol);
|
MOO_STORE_OOP (moo, MOO_OBJ_GET_OOP_PTR(newbuc, index), (moo_oop_t)symbol);
|
||||||
}
|
}
|
||||||
@ -91,7 +91,7 @@ static moo_oop_t find_or_make_symbol (moo_t* moo, const moo_ooch_t* ptr, moo_oow
|
|||||||
moo_oop_char_t symbol;
|
moo_oop_char_t symbol;
|
||||||
|
|
||||||
MOO_ASSERT (moo, MOO_CLASSOF(moo,moo->symtab->bucket) == moo->_array);
|
MOO_ASSERT (moo, MOO_CLASSOF(moo,moo->symtab->bucket) == moo->_array);
|
||||||
index = moo_hashoochars(ptr, len) % MOO_OBJ_GET_SIZE(moo->symtab->bucket);
|
index = moo_hash_oochars(ptr, len) % MOO_OBJ_GET_SIZE(moo->symtab->bucket);
|
||||||
|
|
||||||
/* find a matching symbol in the open-addressed symbol table */
|
/* find a matching symbol in the open-addressed symbol table */
|
||||||
while ((moo_oop_t)(symbol = (moo_oop_char_t)MOO_OBJ_GET_OOP_VAL(moo->symtab->bucket, index)) != moo->_nil)
|
while ((moo_oop_t)(symbol = (moo_oop_char_t)MOO_OBJ_GET_OOP_VAL(moo->symtab->bucket, index)) != moo->_nil)
|
||||||
@ -146,7 +146,7 @@ static moo_oop_t find_or_make_symbol (moo_t* moo, const moo_ooch_t* ptr, moo_oow
|
|||||||
MOO_STORE_OOP (moo, (moo_oop_t*)&moo->symtab->bucket, (moo_oop_t)tmp);
|
MOO_STORE_OOP (moo, (moo_oop_t*)&moo->symtab->bucket, (moo_oop_t)tmp);
|
||||||
|
|
||||||
/* recalculate the index for the expanded bucket */
|
/* recalculate the index for the expanded bucket */
|
||||||
index = moo_hashoochars(ptr, len) % MOO_OBJ_GET_SIZE(moo->symtab->bucket);
|
index = moo_hash_oochars(ptr, len) % MOO_OBJ_GET_SIZE(moo->symtab->bucket);
|
||||||
|
|
||||||
while (MOO_OBJ_GET_OOP_VAL(moo->symtab->bucket, index) != moo->_nil)
|
while (MOO_OBJ_GET_OOP_VAL(moo->symtab->bucket, index) != moo->_nil)
|
||||||
index = (index + 1) % MOO_OBJ_GET_SIZE(moo->symtab->bucket);
|
index = (index + 1) % MOO_OBJ_GET_SIZE(moo->symtab->bucket);
|
||||||
|
@ -206,6 +206,16 @@ moo_uint128_t moo_hton128 (moo_uint128_t x)
|
|||||||
|
|
||||||
/* ----------------------------------------------------------------------- */
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
moo_oow_t moo_hash_bytes_ (const moo_oob_t* ptr, moo_oow_t len)
|
||||||
|
{
|
||||||
|
moo_oow_t hv;
|
||||||
|
MOO_HASH_BYTES (hv, ptr, len);
|
||||||
|
/* constrain the hash value to be representable in a small integer
|
||||||
|
* for convenience sake */
|
||||||
|
return hv % ((moo_oow_t)MOO_SMOOI_MAX + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------- */
|
||||||
|
|
||||||
/* some naming conventions
|
/* some naming conventions
|
||||||
* bchars, uchars -> pointer and length
|
* bchars, uchars -> pointer and length
|
||||||
@ -216,51 +226,6 @@ moo_uint128_t moo_hton128 (moo_uint128_t x)
|
|||||||
* utobcstr -> ucstr to bcstr
|
* utobcstr -> ucstr to bcstr
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#if MOO_SIZEOF_OOW_T == 4
|
|
||||||
# define FNV_MAGIC_INIT (0x811c9dc5)
|
|
||||||
# define FNV_MAGIC_PRIME (0x01000193)
|
|
||||||
#elif MOO_SIZEOF_OOW_T == 8
|
|
||||||
# define FNV_MAGIC_INIT (0xCBF29CE484222325)
|
|
||||||
# define FNV_MAGIC_PRIME (0x100000001B3)
|
|
||||||
#elif MOO_SIZEOF_OOW_T == 16
|
|
||||||
# define FNV_MAGIC_INIT (0x6C62272E07BB014262B821756295C58D)
|
|
||||||
# define FNV_MAGIC_PRIME (0x1000000000000000000013B)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
moo_oow_t moo_hash_bytes (const moo_oob_t* ptr, moo_oow_t len)
|
|
||||||
{
|
|
||||||
moo_oow_t h;
|
|
||||||
const moo_uint8_t* bp, * be;
|
|
||||||
|
|
||||||
bp = ptr; be = bp + len;
|
|
||||||
|
|
||||||
/* this hash doesn't produce good distribution */
|
|
||||||
/*
|
|
||||||
h = 0
|
|
||||||
while (bp < be) h = h * 31 + *bp++;
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(FNV_MAGIC_INIT)
|
|
||||||
/* FNV-1 hash */
|
|
||||||
h = FNV_MAGIC_INIT;
|
|
||||||
while (bp < be)
|
|
||||||
{
|
|
||||||
h ^= (moo_oow_t)(*bp++);
|
|
||||||
h *= FNV_MAGIC_PRIME;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
/* SDBM hash is known to produce good overall distribution
|
|
||||||
* for many different data sets */
|
|
||||||
h = 0;
|
|
||||||
while (bp < be) h = (h << 6) + (h << 16) - h + *bp++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* constrain the hash value to be representable in a small integer
|
|
||||||
* for convenience sake */
|
|
||||||
return h % ((moo_oow_t)MOO_SMOOI_MAX + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int moo_equal_uchars (const moo_uch_t* str1, const moo_uch_t* str2, moo_oow_t len)
|
int moo_equal_uchars (const moo_uch_t* str1, const moo_uch_t* str2, moo_oow_t len)
|
||||||
{
|
{
|
||||||
moo_oow_t i;
|
moo_oow_t i;
|
||||||
|
Loading…
Reference in New Issue
Block a user