Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

fix for <rdar://problem/7281043> Adding frameworks after requiring a …

…library that uses at_exit causes a bus error

git-svn-id: http://svn.macosforge.org/repository/ruby/MacRuby/trunk@2744 23306eb0-4c56-4727-a40e-e92c0eb68959
  • Loading branch information...
commit ac3a5b45f0421fedf08f2e289dd17ff0a4b0fce5 1 parent 7c39c53
Laurent Sansonetti authored
Showing with 22 additions and 48 deletions.
  1. +15 −47 eval_jump.c
  2. +1 −1  include/ruby/intern.h
  3. +6 −0 proc.c
View
62 eval_jump.c
@@ -5,11 +5,8 @@
/* exit */
-void
-rb_call_end_proc(VALUE data)
-{
- rb_proc_call(data, rb_ary_new());
-}
+// TODO: move & lock me into RoxorCore
+static VALUE at_exit_procs = Qnil;
/*
* call-seq:
@@ -35,63 +32,34 @@ rb_call_end_proc(VALUE data)
static VALUE
rb_f_at_exit(VALUE self, SEL sel)
{
- VALUE proc;
-
if (!rb_block_given_p()) {
rb_raise(rb_eArgError, "called without a block");
}
- proc = rb_block_proc();
- rb_set_end_proc(rb_call_end_proc, proc);
+ VALUE proc = rb_block_proc();
+ rb_ary_push(at_exit_procs, proc);
return proc;
}
-struct end_proc_data {
- void (*func) ();
- VALUE data;
- int safe;
- struct end_proc_data *next;
-};
-
-static struct end_proc_data *end_procs = NULL;
-static struct end_proc_data *tmp_end_procs = NULL;
-
-void
-rb_set_end_proc(void (*func)(VALUE), VALUE data)
-{
- struct end_proc_data *link = ALLOC(struct end_proc_data);
- struct end_proc_data **list;
-
- list = &end_procs;
- GC_WB(&link->next, *list);
- link->func = func;
- link->data = data;
- link->safe = rb_safe_level();
- *list = link;
-}
-
void
rb_exec_end_proc(void)
{
- struct end_proc_data *link, *tmp;
- int safe = rb_safe_level();
-
- if (end_procs != NULL) {
- tmp_end_procs = link = end_procs;
- end_procs = 0;
- while (link != NULL) {
- rb_set_safe_level_force(link->safe);
- (*link->func) (link->data);
- tmp = link;
- tmp_end_procs = link = link->next;
- xfree(tmp);
+ while (true) {
+ const int count = RARRAY_LEN(at_exit_procs);
+ if (count > 0) {
+ VALUE proc = RARRAY_AT(at_exit_procs, count - 1);
+ rb_ary_delete_at(at_exit_procs, count - 1);
+ rb_proc_call2(proc, 0, NULL);
+ continue;
}
+ break;
}
- rb_set_safe_level_force(safe);
}
void
Init_jump(void)
{
rb_objc_define_module_function(rb_mKernel, "at_exit", rb_f_at_exit, 0);
- GC_ROOT(&end_procs);
+
+ at_exit_procs = rb_ary_new();
+ GC_RETAIN(at_exit_procs);
}
View
2  include/ruby/intern.h
@@ -278,13 +278,13 @@ VALUE rb_class_new_instance(int, VALUE*, VALUE);
VALUE rb_block_proc(void);
VALUE rb_f_lambda(void);
VALUE rb_proc_call(VALUE, VALUE);
+VALUE rb_proc_call2(VALUE self, int argc, VALUE *argv);
int rb_proc_arity(VALUE);
VALUE rb_binding_new(void);
VALUE rb_method_call(VALUE, SEL, int, VALUE*);
int rb_mod_method_arity(VALUE, ID);
int rb_obj_method_arity(VALUE, ID);
VALUE rb_protect(VALUE (*)(VALUE), VALUE, int*);
-void rb_set_end_proc(void (*)(VALUE), VALUE);
void rb_mark_end_proc(void);
void rb_exec_end_proc(void);
void Init_jump(void);
View
6 proc.c
@@ -450,6 +450,12 @@ rb_proc_call(VALUE self, VALUE args)
return proc_call(self, 0, RARRAY_LEN(args), RARRAY_PTR(args));
}
+VALUE
+rb_proc_call2(VALUE self, int argc, VALUE *argv)
+{
+ return proc_call(self, 0, argc, argv);
+}
+
/*
* call-seq:
* prc.arity -> fixnum
Please sign in to comment.
Something went wrong with that request. Please try again.