📄 gcc_support.c
字号:
desc->has_finalizer = 1;}static void call_array_destructor( o, data ) void* o; void* data; /* call_array_destructor is the GC finalizer proc registered for gc array objects whose elements have destructors. Its client data is the destructor proc. It iterates through the elements of the array in reverse order, calling the destructor on each. */{ int num = NUM_ARRAY_ELEMENTS( o ); Descriptor* desc = DESCRIPTOR( o ); size_t size = desc->element_size; char* first_p = FIRST_ELEMENT_P( o ); char* p = first_p + (num - 1) * size; if (num > 0) { while (1) { ((destructor_proc) data)( p, 2 ); if (p == first_p) break; p -= size;}}}void* __builtin_vec_new_gc_dtor( first_elem, d, element_size ) void* first_elem; destructor_proc d; size_t element_size; /* The compiler generates a call to __builtin_vec_new_gc_dtor to register the destructor "d" of a gc array object as a GC finalizer. "first_elem" points to the first element of the array, *not* the beginning of the object (this makes the generated call to this function smaller). The elements of the array are of size "element_size". The destructor is registered as in _builtin_new_gc_dtor. */{ void* o = (char*) first_elem - sizeof( BI_header ); Descriptor* desc = DESCRIPTOR( o ); GC_REGISTER_FINALIZER_IGNORE_SELF( o, call_array_destructor, d, 0, 0 ); desc->element_size = element_size; desc->has_finalizer = 1;}void __builtin_delete( o ) void* o; /* The compiler generates calls to __builtin_delete for operator delete(). The GC currently requires that any registered finalizers be unregistered before explicitly freeing an object. If the object has any weak pointers referencing it, we can't actually free it now. */{ if (o != 0) { Descriptor* desc = DESCRIPTOR( o ); if (desc->has_finalizer) GC_REGISTER_FINALIZER( o, 0, 0, 0, 0 ); if (! desc->has_weak_pointers) GC_FREE( o );}}void __builtin_vec_delete( o ) void* o; /* The compiler generates calls to __builitn_vec_delete for operator delete[](). */{ __builtin_delete( o );}/**************************************************************************Implementations of the template class WeakPointer from WeakPointer.h***************************************************************************/typedef struct WeakPointer { void* pointer; } WeakPointer;void* _WeakPointer_New( t ) void* t;{ if (t == 0) { return 0;} else { void* base = GC_base( t ); WeakPointer* wp = (WeakPointer*) GC_MALLOC_ATOMIC( sizeof( WeakPointer ) ); Descriptor* desc = DESCRIPTOR( base ); wp->pointer = t; desc->has_weak_pointers = 1; GC_general_register_disappearing_link( &wp->pointer, base ); return wp;}}static void* PointerWithLock( wp ) WeakPointer* wp;{ if (wp == 0 || wp->pointer == 0) { return 0;} else { return (void*) wp->pointer;}}void* _WeakPointer_Pointer( wp ) WeakPointer* wp;{ return (void*) GC_call_with_alloc_lock( PointerWithLock, wp );}typedef struct EqualClosure { WeakPointer* wp1; WeakPointer* wp2;} EqualClosure;static void* EqualWithLock( ec ) EqualClosure* ec;{ if (ec->wp1 == 0 || ec->wp2 == 0) { return (void*) (ec->wp1 == ec->wp2);} else { return (void*) (ec->wp1->pointer == ec->wp2->pointer);}}int _WeakPointer_Equal( wp1, wp2 ) WeakPointer* wp1; WeakPointer* wp2;{ EqualClosure ec; ec.wp1 = wp1; ec.wp2 = wp2; return (int) GC_call_with_alloc_lock( EqualWithLock, &ec );}int _WeakPointer_Hash( wp ) WeakPointer* wp;{ return (int) _WeakPointer_Pointer( wp );}/**************************************************************************Implementations of the template class CleanUp from WeakPointer.h***************************************************************************/typedef struct Closure { void (*c) PROTO(( void* d, void* t )); ptrdiff_t t_offset; void* d;} Closure;static void _CleanUp_CallClosure( obj, data ) void* obj; void* data;{ Closure* closure = (Closure*) data; closure->c( closure->d, (char*) obj + closure->t_offset );}void _CleanUp_Set( t, c, d ) void* t; void (*c) PROTO(( void* d, void* t )); void* d;{ void* base = GC_base( t ); Descriptor* desc = DESCRIPTOR( t ); if (c == 0) { GC_REGISTER_FINALIZER_IGNORE_SELF( base, 0, 0, 0, 0 ); desc->has_finalizer = 0;} else { Closure* closure = (Closure*) GC_MALLOC( sizeof( Closure ) ); closure->c = c; closure->t_offset = (char*) t - (char*) base; closure->d = d; GC_REGISTER_FINALIZER_IGNORE_SELF( base, _CleanUp_CallClosure, closure, 0, 0 ); desc->has_finalizer = 1;}}void _CleanUp_Call( t ) void* t;{ /* ? Aren't we supposed to deactivate weak pointers to t too? Why? */ void* base = GC_base( t ); void* d; GC_finalization_proc f; GC_REGISTER_FINALIZER( base, 0, 0, &f, &d ); f( base, d );}typedef struct QueueElem { void* o; GC_finalization_proc f; void* d; struct QueueElem* next; } QueueElem;void* _CleanUp_Queue_NewHead(){ return GC_MALLOC( sizeof( QueueElem ) );} static void _CleanUp_Queue_Enqueue( obj, data ) void* obj; void* data;{ QueueElem* q = (QueueElem*) data; QueueElem* head = q->next; q->o = obj; q->next = head->next; head->next = q;} void _CleanUp_Queue_Set( h, t ) void* h; void* t;{ QueueElem* head = (QueueElem*) h; void* base = GC_base( t ); void* d; GC_finalization_proc f; QueueElem* q = (QueueElem*) GC_MALLOC( sizeof( QueueElem ) ); GC_REGISTER_FINALIZER( base, _CleanUp_Queue_Enqueue, q, &f, &d ); q->f = f; q->d = d; q->next = head;} int _CleanUp_Queue_Call( h ) void* h;{ QueueElem* head = (QueueElem*) h; QueueElem* q = head->next; if (q == 0) { return 0;} else { head->next = q->next; q->next = 0; if (q->f != 0) q->f( q->o, q->d ); return 1;}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -