/* object - handle runtime objects. Do reference * counting and automatic cleanup. */ #include "common.h" #include "../compiler/pfPreamble.h" #include "runType.h" void _pf_var_link(_pf_Var var) /* Increment _pf_refCount if variable needs cleanup. */ { struct _pf_type *type = _pf_type_table[var.typeId]; if (type->base->needsCleanup && var.val.Obj != NULL) var.val.Obj->_pf_refCount += 1; } void _pf_var_cleanup(_pf_Var var) /* If variable needs cleanup decrement _pf_refCount and if necessary * call _pf_cleanup */ { struct _pf_type *type = _pf_type_table[var.typeId]; if (type->base->needsCleanup && var.val.Obj != NULL) if ((var.val.Obj->_pf_refCount -= 1) <= 0) var.val.Obj->_pf_cleanup(var.val.Obj, var.typeId); } struct interfaceHeader /* All interfaces begin with these three fields. (The rest of * the fields are function pointers to the methods. */ { int _pf_refCount; void (*_pf_cleanup)(void *obj, int typeId); struct _pf_object *_pf_obj; int _pf_objTypeId; }; void _pf_cleanup_interface(void *v, int typeId) /* Clean up interface of some sort. */ { struct interfaceHeader *face = v; struct _pf_object *obj = face->_pf_obj; if ((obj->_pf_refCount -= 1) <= 0) obj->_pf_cleanup(obj, face->_pf_objTypeId); freeMem(face); } void _pf_nil_use() /* Complain about use of undefined object and punt. */ { errAbort("using uninitialized object"); } void _pf_nil_check(void *v) /* Punt if v is nil. */ { if (v == NULL) _pf_nil_use(); }