From 9987d53e519cf84fe47ffbbd4f48be0bc40938c7 Mon Sep 17 00:00:00 2001 From: ko1 Date: Sun, 25 Feb 2007 16:29:26 +0000 Subject: [PATCH] * yarvcore.h: add rb_thread_t#top_wrapper, top_self. * eval_load.c (rb_load): support eval in wrapper module (load(file, true)). * eval.c: ditto. * eval_jump.h: ditto. * iseq.c: ditto. * vm.c: ditto. * yarvcore.c: ditto. * insns.def: add a empty line. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@11884 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 19 +++++++++++++++++++ eval.c | 23 +++++++++++++---------- eval_jump.h | 3 ++- eval_load.c | 20 ++++++++++++++------ insns.def | 1 + iseq.c | 14 ++++++++------ vm.c | 6 ++---- yarvcore.c | 7 +++++++ yarvcore.h | 4 ++++ 9 files changed, 70 insertions(+), 27 deletions(-) diff --git a/ChangeLog b/ChangeLog index f6eb54ea90..2554384ab8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +Mon Feb 26 00:58:39 2007 Koichi Sasada + + * yarvcore.h: add rb_thread_t#top_wrapper, top_self. + + * eval_load.c (rb_load): support eval in wrapper module + (load(file, true)). + + * eval.c: ditto. + + * eval_jump.h: ditto. + + * iseq.c: ditto. + + * vm.c: ditto. + + * yarvcore.c: ditto. + + * insns.def: add a empty line. + Mon Feb 26 00:54:36 2007 Koichi Sasada * common.mk: change "gdb" rule. You can debug miniruby with diff --git a/eval.c b/eval.c index eea1098c05..582450941f 100644 --- a/eval.c +++ b/eval.c @@ -35,8 +35,6 @@ VALUE rb_eSysStackError; extern int ruby_nerrs; extern VALUE ruby_top_self; -static VALUE ruby_wrapper; /* security wrapper */ - static VALUE eval _((VALUE, VALUE, VALUE, char *, int)); static VALUE rb_yield_0 _((VALUE, VALUE, VALUE, int, int)); @@ -289,17 +287,20 @@ VALUE rb_eval_string_wrap(const char *str, int *state) { int status; - VALUE self = ruby_top_self; - VALUE wrapper = ruby_wrapper; + rb_thread_t *th = GET_THREAD(); + VALUE self = th->top_self; + VALUE wrapper = th->top_wrapper; VALUE val; - ruby_top_self = rb_obj_clone(ruby_top_self); - rb_extend_object(ruby_top_self, ruby_wrapper); + th->top_wrapper = rb_module_new(); + th->top_self = rb_obj_clone(ruby_top_self); + rb_extend_object(th->top_self, th->top_wrapper); val = rb_eval_string_protect(str, &status); - ruby_top_self = self; - ruby_wrapper = wrapper; + th->top_self = self; + th->top_wrapper = wrapper; + if (state) { *state = status; } @@ -2687,11 +2688,13 @@ rb_obj_extend(int argc, VALUE *argv, VALUE obj) static VALUE top_include(int argc, VALUE *argv, VALUE self) { + rb_thread_t *th = GET_THREAD(); + rb_secure(4); - if (ruby_wrapper) { + if (th->top_wrapper) { rb_warning ("main#include in the wrapped load is effective only in wrapper module"); - return rb_mod_include(argc, argv, ruby_wrapper); + return rb_mod_include(argc, argv, th->top_wrapper); } return rb_mod_include(argc, argv, rb_cObject); } diff --git a/eval_jump.h b/eval_jump.h index 8bc47a0cc0..a48a5357fd 100644 --- a/eval_jump.h +++ b/eval_jump.h @@ -318,8 +318,9 @@ rb_set_end_proc(void (*func)(VALUE), VALUE data) { struct end_proc_data *link = ALLOC(struct end_proc_data); struct end_proc_data **list; + rb_thread_t *th = GET_THREAD(); - if (ruby_wrapper) { + if (th->top_wrapper) { list = &ephemeral_end_procs; } else { diff --git a/eval_load.c b/eval_load.c index 321fc31093..debc2412e3 100644 --- a/eval_load.c +++ b/eval_load.c @@ -136,7 +136,7 @@ rb_load_internal(char *file) } iseq = rb_iseq_new(node, rb_str_new2(""), - rb_str_new2(file), Qfalse, ISEQ_TYPE_TOP); + rb_str_new2(file), Qfalse, ISEQ_TYPE_TOP); rb_thread_eval(GET_THREAD(), iseq); return 0; @@ -147,7 +147,9 @@ rb_load(VALUE fname, int wrap) { VALUE tmp; int state; - volatile VALUE self = ruby_top_self; + rb_thread_t *th = GET_THREAD(); + VALUE wrapper = th->top_wrapper; + VALUE self = th->top_self; FilePathValue(fname); fname = rb_str_new4(fname); @@ -157,14 +159,17 @@ rb_load(VALUE fname, int wrap) } fname = tmp; - GET_THREAD()->errinfo = Qnil; /* ensure */ - + th->errinfo = Qnil; /* ensure */ + if (!wrap) { rb_secure(4); /* should alter global state */ + th->top_wrapper = 0; } else { /* load in anonymous module as toplevel */ - self = rb_obj_clone(ruby_top_self); + th->top_self = rb_obj_clone(ruby_top_self); + th->top_wrapper = rb_module_new(); + rb_extend_object(th->top_self, th->top_wrapper); } PUSH_TAG(PROT_NONE); @@ -174,6 +179,9 @@ rb_load(VALUE fname, int wrap) } POP_TAG(); + th->top_self = self; + th->top_wrapper = wrapper; + if (ruby_nerrs > 0) { ruby_nerrs = 0; rb_exc_raise(GET_THREAD()->errinfo); @@ -184,7 +192,7 @@ rb_load(VALUE fname, int wrap) if (!NIL_P(GET_THREAD()->errinfo)) { /* exception during load */ - rb_exc_raise(GET_THREAD()->errinfo); + rb_exc_raise(th->errinfo); } } diff --git a/insns.def b/insns.def index 022a6018e5..13c468cfc4 100644 --- a/insns.def +++ b/insns.def @@ -1058,6 +1058,7 @@ defineclass if (super == Qnil) { super = rb_cObject; } + if (cbase == Qnil) { cbase = th_get_cbase(th); } diff --git a/iseq.c b/iseq.c index 050ad03936..106c4dae8f 100644 --- a/iseq.c +++ b/iseq.c @@ -107,12 +107,14 @@ prepare_iseq_build(rb_iseq_t *iseq, VALUE parent, VALUE type, VALUE block_opt, const rb_compile_option_t *option) { + rb_thread_t *th = GET_THREAD(); + iseq->name = name; iseq->defined_method_id = 0; iseq->filename = filename; iseq->iseq_mark_ary = rb_ary_new(); RBASIC(iseq->iseq_mark_ary)->klass = 0; - + iseq->type = type; iseq->arg_rest = 0; iseq->arg_block = 0; @@ -124,7 +126,7 @@ prepare_iseq_build(rb_iseq_t *iseq, /* set class nest stack */ if (type == ISEQ_TYPE_TOP) { /* toplevel is private */ - iseq->cref_stack = NEW_BLOCK(rb_cObject); + iseq->cref_stack = NEW_BLOCK(th->top_wrapper ? th->top_wrapper : rb_cObject); iseq->cref_stack->nd_file = 0; iseq->cref_stack->nd_visi = NOEX_PRIVATE; } @@ -144,17 +146,17 @@ prepare_iseq_build(rb_iseq_t *iseq, RBASIC(iseq->compile_data->mark_ary)->klass = 0; iseq->compile_data->storage_head = iseq->compile_data->storage_current = - (struct iseq_compile_data_storage *) - ALLOC_N(char, INITIAL_ISEQ_COMPILE_DATA_STORAGE_BUFF_SIZE + + (struct iseq_compile_data_storage *) + ALLOC_N(char, INITIAL_ISEQ_COMPILE_DATA_STORAGE_BUFF_SIZE + sizeof(struct iseq_compile_data_storage)); iseq->compile_data->catch_table_ary = rb_ary_new(); iseq->compile_data->storage_head->pos = 0; iseq->compile_data->storage_head->next = 0; iseq->compile_data->storage_head->size = - INITIAL_ISEQ_COMPILE_DATA_STORAGE_BUFF_SIZE; + INITIAL_ISEQ_COMPILE_DATA_STORAGE_BUFF_SIZE; iseq->compile_data->storage_head->buff = - (char *)(&iseq->compile_data->storage_head->buff + 1); + (char *)(&iseq->compile_data->storage_head->buff + 1); iseq->compile_data->option = option; if (type == ISEQ_TYPE_TOP || diff --git a/vm.c b/vm.c index 6a7fa42824..e28b10f64d 100644 --- a/vm.c +++ b/vm.c @@ -139,8 +139,6 @@ pop_frame(rb_thread_t *th) th->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp); } -EXTERN VALUE ruby_top_self; - VALUE th_set_finish_env(rb_thread_t *th) { @@ -165,7 +163,7 @@ th_set_top_stack(rb_thread_t *th, VALUE iseqval) th_set_finish_env(th); push_frame(th, iseq, FRAME_MAGIC_TOP, - ruby_top_self, 0, iseq->iseq_encoded, + th->top_self, 0, iseq->iseq_encoded, th->cfp->sp, 0, iseq->local_size); } @@ -1150,7 +1148,7 @@ th_get_cbase(rb_thread_t *th) rb_control_frame_t *cfp = th_get_ruby_level_cfp(th, th->cfp); NODE *cref = get_cref(cfp->iseq, cfp->lfp); VALUE klass = Qundef; - + while (cref) { if ((klass = cref->nd_clss) != 0) { break; diff --git a/yarvcore.c b/yarvcore.c index be8922d811..bfc53fc6b3 100644 --- a/yarvcore.c +++ b/yarvcore.c @@ -277,6 +277,8 @@ thread_mark(void *ptr) MARK_UNLESS_NULL(th->value); MARK_UNLESS_NULL(th->errinfo); MARK_UNLESS_NULL(th->local_svar); + MARK_UNLESS_NULL(th->top_self); + MARK_UNLESS_NULL(th->top_wrapper); rb_mark_tbl(th->local_storage); @@ -340,6 +342,8 @@ th_init(rb_thread_t *th) th_init2(th); } +extern VALUE ruby_top_self; + static VALUE thread_init(VALUE self) { @@ -350,6 +354,9 @@ thread_init(VALUE self) th_init(th); th->self = self; th->vm = vm; + + th->top_wrapper = 0; + th->top_self = ruby_top_self; return self; } diff --git a/yarvcore.h b/yarvcore.h index dc1963ab62..e2885711cc 100644 --- a/yarvcore.h +++ b/yarvcore.h @@ -404,6 +404,10 @@ struct rb_thread_struct /* passed via parse.y, eval.c (rb_scope_setup_local_tbl) */ ID *top_local_tbl; + /* for load(true) */ + VALUE top_self; + VALUE top_wrapper; + /* eval env */ rb_block_t *base_block;