ccos | 2 Dec 2004 07:07
Picon

an idea for finalization of C objects

i understand that you cannot have dtors on the sc lang side because of 
the possible resurrection of dead objects which would necessitate a 
second pass of the gc, but wouldn't it be possible to have a callback 
for deletion of C objects with the caveat that the programmer should 
not manipulate sc objects at all, it could even just pass in a void 
pointer instead of a PyrSlot, or better yet something like this 
(untested):

struct AbstractCObj {
	virtual ~AbstractCObj = 0;
};

template<typename T>
struct CObj : public AbstractCObj { // haven't thought much about the 
struct names, any suggestions
         typedef void (*DTor)( T * obj );

         CObj( T * obj, DTor dtor ) : mObj( obj ), mDtor( dtor ) {}
         virtual ~ CObj() { mDtor(mObj); }

         int initSCObj( PyrObject * scObj ) {
		check if scObj is of appropriate type and has at least one instance 
var
		then place 'this' into the first inst var as a uptr and then set 
scObj->hasCObjFinalizer to true.
		return error code for calling primitive
	}

         T * mObj;
         DTor mDtor;
};

and in PyrObject.h:

struct PyrObjectHdr {
	struct PyrObjectHdr *prev, *next;
	struct PyrClass *classptr;		
	int size;	
	bool hasCObjFinalizer;

then a function in the gc could do the following before deallocating sc 
objects:

AbstractCObj * cObj;
if( scObjectAboutToBeGCd.hasCObjFinalizer && getCObj( 
scObjectAboutToBeGCd, cObj ) ) {
	// getCObj checks if first slot is pointer and casts it to a 
AbstractCObj* (NB the short circuit)
  	delete cObj;
}

and all the user has to do is in an initialization primitive is this:

typedef CObj<MyCDataType> MyCObjType;
void myDtorCallback( MyCDataType * myObj ) { delete myObj; }

...

MyCDataType * myObj = new MyCDataType("foobar");

MyCObjType * myCObj = new MyCObjType( myObj, myDtorCallback );

err = myCObj->initSCObj(primitiveReceiver);
if( err ) {
	delete myCObj; // takes care of myObj as well
	return err;
}

this would mean that one could use third party libraries which heap 
allocate, like regex.h or parts of opengl or just about any other C 
library i can think of.

there is of course the very slight runtime cost of checking if an 
object has a finalizer but i'm wondering if there are any other reasons 
why this would be a bad idea, or if it just wouldn't be possible 
because of something i don't know about the gc?

_c

Gmane