[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[sc-dev] 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?