diff --git a/vm.c b/vm.c index 58ed56b..671f618 100644 --- a/vm.c +++ b/vm.c @@ -468,20 +468,28 @@ rb_frame_pop(void) void ruby_vm_at_exit(void (*func)(rb_vm_t *)) { - rb_ary_push((VALUE)&GET_VM()->at_exit, (VALUE)func); + rb_at_exit_list *nl = (rb_at_exit_list*)xmalloc(sizeof(rb_at_exit_list)); + nl->func = func; + nl->next = 0; + + GET_VM()->at_exit_end->next = nl; + GET_VM()->at_exit_end = nl; } static void ruby_vm_run_at_exit_hooks(rb_vm_t *vm) { - VALUE hook = (VALUE)&vm->at_exit; + for(rb_at_exit_list *l = &vm->at_exit; l; l = l->next) { + if(l->func) { + (*l->func)(vm); + } + } - while (RARRAY_LEN(hook) > 0) { - typedef void rb_vm_at_exit_func(rb_vm_t*); - rb_vm_at_exit_func *func = (rb_vm_at_exit_func*)rb_ary_pop(hook); - (*func)(vm); + for(rb_at_exit_list *l = vm->at_exit.next; l;) { + rb_at_exit_list* t = l->next; + free(l); + l = t; } - rb_ary_free(hook); } /* Env */ @@ -2170,8 +2178,7 @@ vm_init2(rb_vm_t *vm) MEMZERO(vm, rb_vm_t, 1); rb_vm_living_threads_init(vm); vm->src_encoding_index = -1; - vm->at_exit.basic.flags = (T_ARRAY | RARRAY_EMBED_FLAG) & ~RARRAY_EMBED_LEN_MASK; /* len set 0 */ - rb_obj_hide((VALUE)&vm->at_exit); + vm->at_exit_end = &vm->at_exit; vm_default_params_setup(vm); } diff --git a/vm_core.h b/vm_core.h index 38fcc0c..2165643 100644 --- a/vm_core.h +++ b/vm_core.h @@ -459,6 +459,14 @@ enum ruby_basic_operators { #define GetVMPtr(obj, ptr) \ GetCoreDataFromValue((obj), rb_vm_t, (ptr)) +struct rb_vm_struct; +typedef void rb_vm_at_exit_func(struct rb_vm_struct*); + +typedef struct rb_at_exit_list { + rb_vm_at_exit_func *func; + struct rb_at_exit_list *next; +} rb_at_exit_list; + struct rb_objspace; struct rb_objspace *rb_objspace_alloc(void); void rb_objspace_free(struct rb_objspace *); @@ -527,11 +535,8 @@ typedef struct rb_vm_struct { struct rb_objspace *objspace; - /* - * @shyouhei notes that this is not for storing normal Ruby - * objects so do *NOT* mark this when you GC. - */ - struct RArray at_exit; + rb_at_exit_list at_exit; + rb_at_exit_list *at_exit_end; VALUE *defined_strings; st_table *frozen_strings;