check smptr check in pf_call() in ffi.c

changed FFI>>call:signature:arguments: to throw an FFIException exception upon failure
added FFIException
This commit is contained in:
hyunghwan.chung 2018-12-22 08:37:18 +00:00
parent f69b4c0881
commit 981882de7e
4 changed files with 29 additions and 25 deletions

View File

@ -1023,7 +1023,10 @@ class AssociativeCollection(Collection)
method associationAt: assoc 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 method associationAt: assoc ifAbsent: error_block

View File

@ -8,6 +8,10 @@ class _FFI(Object) from 'ffi'
method(#primitive) call(func, sig, args). method(#primitive) call(func, sig, args).
} }
class FFIException(Exception)
{
}
class FFI(Object) class FFI(Object)
{ {
var name, ffi, funcs. var name, ffi, funcs.
@ -42,11 +46,11 @@ class FFI(Object)
method call: name signature: sig arguments: args method call: name signature: sig arguments: args
{ {
| f | | f rc |
(* f := self.funcs at: name ifAbsent: [ (* f := self.funcs at: name ifAbsent: [
f := self.ffi getsym(name). 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.funcs at: name put: f.
f. ## need this as at:put: returns an association f. ## need this as at:put: returns an association
]. *) ]. *)
@ -55,10 +59,11 @@ class FFI(Object)
if (f isNil) if (f isNil)
{ {
f := self.ffi getsym(name). 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.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)) }.
} }
} }

View File

@ -68,7 +68,8 @@ static moo_oop_oop_t expand_bucket (moo_t* moo, moo_oop_oop_t oldbuc)
while (oldsz > 0) 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) if ((moo_oop_t)ass != moo->_nil)
{ {
MOO_ASSERT (moo, MOO_CLASSOF(moo,ass) == moo->_association); 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); 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_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); index = hv % MOO_OBJ_GET_SIZE(dic->bucket);
/* find */ /* 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) == moo->_association);
/*MOO_ASSERT (moo, MOO_CLASSOF(moo,ass->key) == moo->_symbol);*/ /*MOO_ASSERT (moo, MOO_CLASSOF(moo,ass->key) == moo->_symbol);*/
MOO_ASSERT (moo, MOO_OBJ_IS_CHAR_POINTER(ass->key)); 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 */ /* recalculate the index for the expanded bucket */
index = hv % MOO_OBJ_GET_SIZE(dic->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); 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 */ * it overflows after increment below */
MOO_ASSERT (moo, tally < MOO_SMOOI_MAX); 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 */ 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); moo_poptmps (moo, tmp_count);
return ass; 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); 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) == moo->_association);
/*MOO_ASSERT (moo, MOO_CLASSOF(moo,ass->key) == moo->_symbol);*/ /*MOO_ASSERT (moo, MOO_CLASSOF(moo,ass->key) == moo->_symbol);*/
MOO_ASSERT (moo, MOO_OBJ_IS_CHAR_POINTER(ass->key)); 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; index = hv % bs;
/* find */ /* 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) == moo->_association);
/*MOO_ASSERT (moo, MOO_CLASSOF(moo,ass->key) == moo->_symbol);*/ /*MOO_ASSERT (moo, MOO_CLASSOF(moo,ass->key) == moo->_symbol);*/
MOO_ASSERT (moo, MOO_OBJ_IS_CHAR_POINTER(ass->key)); MOO_ASSERT (moo, MOO_OBJ_IS_CHAR_POINTER(ass->key));
@ -323,23 +318,22 @@ found:
y = (y + 1) % bs; y = (y + 1) % bs;
/* done if the slot at the current index is empty */ /* 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 */ * 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; z = moo_hashoochars(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)) || if ((y > x && (z <= x || z > y)) ||
(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; 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--; tally--;
dic->tally = MOO_SMOOI_TO_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); count = MOO_OBJ_GET_SIZE(dic->bucket);
for (index = 0; index < count; index++) 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) if ((moo_oop_t)ass != moo->_nil)
{ {

View File

@ -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); sig = MOO_STACK_GETARG(moo, nargs, 1);
args = MOO_STACK_GETARG(moo, nargs, 2); 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 /* the signature must not be empty. at least the return type must be
* specified */ * specified */
if (!MOO_OBJ_IS_CHAR_POINTER(sig) || MOO_OBJ_GET_SIZE(sig) <= 0) goto inval; if (!MOO_OBJ_IS_CHAR_POINTER(sig) || MOO_OBJ_GET_SIZE(sig) <= 0) goto inval;