From 1c03862049be55c911c1dfb2621c3be42d7c0d09 Mon Sep 17 00:00:00 2001 From: nobu Date: Mon, 18 Jun 2007 08:02:30 +0000 Subject: * eval_load.c (rb_require_safe, ruby_init_ext): load with ruby level cfp. [ruby-core:10779] * eval_intern.h, vm.c (rb_vm_call_cfunc): new function to call a function with ruby level cfp. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12570 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 8 ++++++++ eval_intern.h | 1 + eval_load.c | 25 ++++++++++++++++++------- vm.c | 15 +++++++++++++++ 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index ce78f09f48..862edb82cb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Mon Jun 18 17:04:07 2007 Nobuyoshi Nakada + + * eval_load.c (rb_require_safe, ruby_init_ext): load with ruby level + cfp. [ruby-core:10779] + + * eval_intern.h, vm.c (rb_vm_call_cfunc): new function to call a + function with ruby level cfp. + Mon Jun 18 16:57:24 2007 Nobuyoshi Nakada * parse.y (yycompile): disable trace while creating ruby_debug_lines. diff --git a/eval_intern.h b/eval_intern.h index f17f829f17..5d9195d935 100644 --- a/eval_intern.h +++ b/eval_intern.h @@ -229,6 +229,7 @@ ruby_cref() VALUE th_get_cbase(rb_thread_t *th); VALUE rb_obj_is_proc(VALUE); void rb_vm_check_redefinition_opt_method(NODE *node); +VALUE rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg, rb_block_t *blockptr, VALUE filename); void rb_thread_terminate_all(void); #define ruby_cbase() th_get_cbase(GET_THREAD()) diff --git a/eval_load.c b/eval_load.c index 871d2573ee..d95b438f63 100644 --- a/eval_load.c +++ b/eval_load.c @@ -408,6 +408,13 @@ load_failed(VALUE fname) RSTRING_PTR(fname)); } +static VALUE +load_ext(VALUE arg) +{ + SCOPE_SET(NOEX_PUBLIC); + return (VALUE)dln_load((const char *)arg); +} + VALUE rb_require_safe(VALUE fname, int safe) { @@ -448,8 +455,8 @@ rb_require_safe(VALUE fname, int safe) ruby_current_node = 0; ruby_sourcefile = rb_source_filename(RSTRING_PTR(path)); ruby_sourceline = 0; - /* SCOPE_SET(NOEX_PUBLIC); */ - handle = (long)dln_load(RSTRING_PTR(path)); + handle = (long)rb_vm_call_cfunc(ruby_top_self, load_ext, + ruby_source_filename, 0, path); rb_ary_push(ruby_dln_librefs, LONG2NUM(handle)); break; } @@ -484,18 +491,22 @@ rb_require(const char *fname) return rb_require_safe(fn, rb_safe_level()); } +static VALUE +init_ext_call(VALUE arg) +{ + SCOPE_SET(NOEX_PUBLIC); + (*(void (*)(void))arg)(); + return Qnil; +} + void ruby_init_ext(const char *name, void (*init)(void)) { - rb_control_frame_t *frame = GET_THREAD()->cfp; - ruby_current_node = 0; ruby_sourcefile = rb_source_filename(name); ruby_sourceline = 0; - frame->method_id = 0; - SCOPE_SET(NOEX_PUBLIC); if (load_lock(name)) { - (*init)(); + rb_vm_call_cfunc(ruby_top_self, init_ext_call, (VALUE)init, 0, rb_str_new2(name)); rb_provide(name); load_unlock(name); } diff --git a/vm.c b/vm.c index 40a627fdc5..6ad62d2fa9 100644 --- a/vm.c +++ b/vm.c @@ -1902,3 +1902,18 @@ rb_thread_current_status(rb_thread_t *th) return str; } + +VALUE +rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg, rb_block_t *blockptr, VALUE filename) +{ + rb_thread_t *th = GET_THREAD(); + rb_control_frame_t *reg_cfp = th->cfp; + volatile VALUE iseq = rb_iseq_new(0, filename, filename, 0, ISEQ_TYPE_TOP); + VALUE val; + + push_frame(th, DATA_PTR(iseq), FRAME_MAGIC_TOP, + recv, (VALUE)blockptr, 0, reg_cfp->sp, 0, 1); + val = (*func)(arg); + pop_frame(th); + return val; +} -- cgit v1.2.3