summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--eval_intern.h1
-rw-r--r--eval_load.c25
-rw-r--r--vm.c15
4 files changed, 42 insertions, 7 deletions
diff --git a/ChangeLog b/ChangeLog
index ce78f09..862edb8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Mon Jun 18 17:04:07 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * 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 <nobu@ruby-lang.org>
* parse.y (yycompile): disable trace while creating ruby_debug_lines.
diff --git a/eval_intern.h b/eval_intern.h
index f17f829..5d9195d 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 871d257..d95b438 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 40a627f..6ad62d2 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;
+}