diff --git a/moo/kernel/Collect.moo b/moo/kernel/Collect.moo index c25476c..0080497 100644 --- a/moo/kernel/Collect.moo +++ b/moo/kernel/Collect.moo @@ -1023,7 +1023,10 @@ class AssociativeCollection(Collection) method associationAt: assoc { - ^self __find: (assoc key) or_upsert: false with: nil. + | ass | + ass := self __find: (assoc key) or_upsert: false with: nil. + if (ass isError) { ^KeyNotFoundException signal: ('Unable to find ' & (assoc key asString)) }. + ^ass. } method associationAt: assoc ifAbsent: error_block diff --git a/moo/kernel/FFI.moo b/moo/kernel/FFI.moo index fc24d77..214cd2b 100644 --- a/moo/kernel/FFI.moo +++ b/moo/kernel/FFI.moo @@ -8,6 +8,10 @@ class _FFI(Object) from 'ffi' method(#primitive) call(func, sig, args). } +class FFIException(Exception) +{ +} + class FFI(Object) { var name, ffi, funcs. @@ -42,11 +46,11 @@ class FFI(Object) method call: name signature: sig arguments: args { - | f | + | f rc | (* f := self.funcs at: name ifAbsent: [ f := self.ffi getsym(name). - if (f isError) { ^f }. + if (f isError) { FFIException signal: ('Unable to find %s' strfmt(name)) }. self.funcs at: name put: f. f. ## need this as at:put: returns an association ]. *) @@ -55,10 +59,11 @@ class FFI(Object) if (f isNil) { f := self.ffi getsym(name). - if (f isError) { ^f }. + if (f isError) { FFIException signal: ('Unable to find %s' strfmt(name)) }. self.funcs at: name put: f. }. - ^self.ffi call(f, sig, args) + rc := self.ffi call(f, sig, args). + if (rc isError) { FFIException signal: ('Unable to call %s' strfmt(name)) }. } } diff --git a/moo/lib/dic.c b/moo/lib/dic.c index a6410f7..107d4e4 100644 --- a/moo/lib/dic.c +++ b/moo/lib/dic.c @@ -68,7 +68,8 @@ static moo_oop_oop_t expand_bucket (moo_t* moo, moo_oop_oop_t oldbuc) while (oldsz > 0) { - ass = (moo_oop_association_t)oldbuc->slot[--oldsz]; + oldsz = oldsz - 1; + ass = (moo_oop_association_t)MOO_OBJ_GET_OOP_VAL(oldbuc, oldsz); if ((moo_oop_t)ass != moo->_nil) { MOO_ASSERT (moo, MOO_CLASSOF(moo,ass) == moo->_association); @@ -77,9 +78,9 @@ static moo_oop_oop_t expand_bucket (moo_t* moo, moo_oop_oop_t oldbuc) MOO_ASSERT (moo, MOO_CLASSOF(moo,key) == moo->_symbol); index = moo_hashoochars(MOO_OBJ_GET_CHAR_SLOT(key), MOO_OBJ_GET_SIZE(key)) % newsz; - while (newbuc->slot[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, &newbuc->slot[index], (moo_oop_t)ass); /* newbuc->slot[index] = (moo_oop_t)ass; */ + MOO_STORE_OOP (moo, MOO_OBJ_GET_OOP_PTR(newbuc, index), (moo_oop_t)ass); } } @@ -104,10 +105,8 @@ static moo_oop_association_t find_or_upsert (moo_t* moo, moo_oop_dic_t dic, moo_ index = hv % MOO_OBJ_GET_SIZE(dic->bucket); /* find */ - while (dic->bucket->slot[index] != moo->_nil) + while ((moo_oop_t)(ass = (moo_oop_association_t)MOO_OBJ_GET_OOP_VAL(dic->bucket, index)) != moo->_nil) { - ass = (moo_oop_association_t)dic->bucket->slot[index]; - MOO_ASSERT (moo, MOO_CLASSOF(moo,ass) == moo->_association); /*MOO_ASSERT (moo, MOO_CLASSOF(moo,ass->key) == moo->_symbol);*/ MOO_ASSERT (moo, MOO_OBJ_IS_CHAR_POINTER(ass->key)); @@ -171,7 +170,7 @@ static moo_oop_association_t find_or_upsert (moo_t* moo, moo_oop_dic_t dic, moo_ /* recalculate the index for the expanded bucket */ index = hv % MOO_OBJ_GET_SIZE(dic->bucket); - while (dic->bucket->slot[index] != moo->_nil) + while (MOO_OBJ_GET_OOP_VAL(dic->bucket, index) != moo->_nil) index = (index + 1) % MOO_OBJ_GET_SIZE(dic->bucket); } @@ -187,7 +186,7 @@ static moo_oop_association_t find_or_upsert (moo_t* moo, moo_oop_dic_t dic, moo_ * it overflows after increment below */ MOO_ASSERT (moo, tally < MOO_SMOOI_MAX); dic->tally = MOO_SMOOI_TO_OOP(tally + 1); /* no need to use MOO_STORE_OOP as the value is not a pointer object */ - MOO_STORE_OOP (moo, &dic->bucket->slot[index], (moo_oop_t)ass); /*dic->bucket->slot[index] = (moo_oop_t)ass;*/ + MOO_STORE_OOP (moo, MOO_OBJ_GET_OOP_PTR(dic->bucket, index), (moo_oop_t)ass); moo_poptmps (moo, tmp_count); return ass; @@ -210,10 +209,8 @@ moo_oop_association_t moo_lookupdic_noseterr (moo_t* moo, moo_oop_dic_t dic, con index = moo_hashoochars(name->ptr, name->len) % MOO_OBJ_GET_SIZE(dic->bucket); - while (dic->bucket->slot[index] != moo->_nil) + while ((moo_oop_t)(ass = (moo_oop_association_t)MOO_OBJ_GET_OOP_VAL(dic->bucket, index)) != moo->_nil) { - ass = (moo_oop_association_t)dic->bucket->slot[index]; - MOO_ASSERT (moo, MOO_CLASSOF(moo,ass) == moo->_association); /*MOO_ASSERT (moo, MOO_CLASSOF(moo,ass->key) == moo->_symbol);*/ MOO_ASSERT (moo, MOO_OBJ_IS_CHAR_POINTER(ass->key)); @@ -296,10 +293,8 @@ int moo_deletedic (moo_t* moo, moo_oop_dic_t dic, const moo_oocs_t* name) index = hv % bs; /* find */ - while (dic->bucket->slot[index] != moo->_nil) + while ((moo_oop_t)(ass = (moo_oop_association_t)MOO_OBJ_GET_OOP_VAL(dic->bucket, index)) != moo->_nil) { - ass = (moo_oop_association_t)dic->bucket->slot[index]; - MOO_ASSERT (moo, MOO_CLASSOF(moo,ass) == moo->_association); /*MOO_ASSERT (moo, MOO_CLASSOF(moo,ass->key) == moo->_symbol);*/ MOO_ASSERT (moo, MOO_OBJ_IS_CHAR_POINTER(ass->key)); @@ -323,23 +318,22 @@ found: y = (y + 1) % bs; /* done if the slot at the current index is empty */ - if (dic->bucket->slot[y] == moo->_nil) break; + if ((moo_oop_t)(ass = (moo_oop_association_t)MOO_OBJ_GET_OOP_VAL(dic->bucket, y)) == moo->_nil) break; - /* 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 */ - ass = (moo_oop_association_t)dic->bucket->slot[y]; z = moo_hashoochars(MOO_OBJ_GET_CHAR_SLOT(ass->key), MOO_OBJ_GET_SIZE(ass->key)) % bs; /* move an element if necesary */ if ((y > x && (z <= x || z > y)) || (y < x && (z <= x && z > y))) { - MOO_STORE_OOP (moo, &dic->bucket->slot[x], dic->bucket->slot[y]); /*dic->bucket->slot[x] = dic->bucket->slot[y];*/ + MOO_STORE_OOP (moo, MOO_OBJ_GET_OOP_PTR(dic->bucket, x), MOO_OBJ_GET_OOP_VAL(dic->bucket, y)); x = y; } } - MOO_STORE_OOP (moo, &dic->bucket->slot[x], moo->_nil); /*dic->bucket->slot[x] = moo->_nil;*/ + dic->bucket->slot[x] = moo->_nil; /* the value is nil. no MOO_STORE_OOP */ tally--; dic->tally = MOO_SMOOI_TO_OOP(tally); @@ -355,7 +349,7 @@ int moo_walkdic (moo_t* moo, moo_oop_dic_t dic, moo_dic_walker_t walker, void* c count = MOO_OBJ_GET_SIZE(dic->bucket); for (index = 0; index < count; index++) { - ass = (moo_oop_association_t)dic->bucket->slot[index]; + ass = (moo_oop_association_t)MOO_OBJ_GET_OOP_VAL(dic->bucket, index); if ((moo_oop_t)ass != moo->_nil) { diff --git a/moo/mod/ffi.c b/moo/mod/ffi.c index 64b705f..96c3d42 100644 --- a/moo/mod/ffi.c +++ b/moo/mod/ffi.c @@ -185,6 +185,8 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) sig = MOO_STACK_GETARG(moo, nargs, 1); args = MOO_STACK_GETARG(moo, nargs, 2); + if (!MOO_OOP_IS_SMPTR(fun)) goto inval; + /* the signature must not be empty. at least the return type must be * specified */ if (!MOO_OBJ_IS_CHAR_POINTER(sig) || MOO_OBJ_GET_SIZE(sig) <= 0) goto inval;