summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--benchmark/bmx_temp.rb9
-rw-r--r--bootstraptest/test_eval.rb19
-rw-r--r--bootstraptest/test_knownbug.rb20
-rw-r--r--compile.c37
-rw-r--r--eval.c131
-rw-r--r--eval_intern.h17
-rw-r--r--eval_method.c2
-rw-r--r--gc.c15
-rw-r--r--include/ruby/ruby.h10
-rw-r--r--insns.def20
-rw-r--r--load.c6
-rw-r--r--proc.c6
-rw-r--r--version.h8
-rw-r--r--vm.c130
-rw-r--r--vm_core.h4
-rw-r--r--vm_dump.c9
-rw-r--r--vm_insnhelper.c109
18 files changed, 228 insertions, 338 deletions
diff --git a/ChangeLog b/ChangeLog
index 58ce5fb231..085be0630b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+Mon May 19 11:32:47 2008 Koichi Sasada <ko1@atdot.net>
+
+ * vm.c, insns.def, eval.c, vm_insnhelper.c: fix CREF handling.
+ VM value stack frame of block contains cref information.
+ (dfp[-1] points CREF)
+
+ * compile.c, eval_intern.h, eval_method.c, load.c, proc.c,
+ vm_dump.h, vm_core.h: ditto.
+
+ * include/ruby/ruby.h, gc.c: remove T_VALUES because of above
+ changes.
+
+ * bootstraptest/test_eval.rb, test_knownbug.rb: move solved test.
+
Sun May 18 22:26:51 2008 GOTOU Yuuzou <gotoyuzo@notwork.org>
* lib/webrick/httpservlet/filehandler.rb: should normalize path
diff --git a/benchmark/bmx_temp.rb b/benchmark/bmx_temp.rb
index e69de29bb2..0b4b219ca2 100644
--- a/benchmark/bmx_temp.rb
+++ b/benchmark/bmx_temp.rb
@@ -0,0 +1,9 @@
+def m
+ nil
+end
+
+i=0
+while i<800000 # benchmark loop 2
+ i+=1
+ m; m; m; m; m; m; m; m;
+end
diff --git a/bootstraptest/test_eval.rb b/bootstraptest/test_eval.rb
index a0e37b9b9a..47976a304e 100644
--- a/bootstraptest/test_eval.rb
+++ b/bootstraptest/test_eval.rb
@@ -208,3 +208,22 @@ assert_normal_exit %q{
end
Foo.add_method
}, '[ruby-core:14556] reported by Frederick Cheung'
+
+assert_equal 'ok', %q{
+ class Module
+ def my_module_eval(&block)
+ module_eval(&block)
+ end
+ end
+ class String
+ Integer.my_module_eval do
+ def hoge; end
+ end
+ end
+ if Integer.instance_methods(false).map{|m|m.to_sym}.include?(:hoge) &&
+ !String.instance_methods(false).map{|m|m.to_sym}.include?(:hoge)
+ :ok
+ else
+ :ng
+ end
+}, "[ruby-dev:34236]"
diff --git a/bootstraptest/test_knownbug.rb b/bootstraptest/test_knownbug.rb
index bccb14a0e9..9041cfdbf4 100644
--- a/bootstraptest/test_knownbug.rb
+++ b/bootstraptest/test_knownbug.rb
@@ -136,26 +136,6 @@ assert_equal 'ok', %q{
end
}, '[ruby-core:16010]'
-
-assert_equal 'ok', %q{
- class Module
- def my_module_eval(&block)
- module_eval(&block)
- end
- end
- class String
- Integer.my_module_eval do
- def hoge; end
- end
- end
- if Integer.instance_methods(false).map{|m|m.to_sym}.include?(:hoge) &&
- !String.instance_methods(false).map{|m|m.to_sym}.include?(:hoge)
- :ok
- else
- :ng
- end
-}, "[ruby-dev:34236]"
-
assert_equal 'ok', %q{
def m
t = Thread.new { while true do // =~ "" end }
diff --git a/compile.c b/compile.c
index 10476081fe..5e2400a2c2 100644
--- a/compile.c
+++ b/compile.c
@@ -280,7 +280,7 @@ iseq_compile(VALUE self, NODE *node)
}
if (iseq->type == ISEQ_TYPE_RESCUE || iseq->type == ISEQ_TYPE_ENSURE) {
- ADD_INSN2(ret, 0, getdynamic, INT2FIX(1), INT2FIX(0));
+ ADD_INSN2(ret, 0, getdynamic, INT2FIX(2), INT2FIX(0));
ADD_INSN1(ret, 0, throw, INT2FIX(0) /* continue throw */ );
}
else {
@@ -771,7 +771,8 @@ iseq_set_exception_local_table(rb_iseq_t *iseq)
id_dollar_bang = rb_intern("#$!");
}
iseq->local_table = (ID *)ALLOC_N(ID *, 1);
- iseq->local_table_size = iseq->local_size = 1;
+ iseq->local_table_size = 1;
+ iseq->local_size = iseq->local_table_size + 1;
iseq->local_table[0] = id_dollar_bang;
return COMPILE_OK;
}
@@ -992,12 +993,14 @@ iseq_set_local_table(rb_iseq_t *iseq, ID *tbl)
}
iseq->local_size = iseq->local_table_size = size;
-
- if (iseq->type == ISEQ_TYPE_METHOD ||
- iseq->type == ISEQ_TYPE_CLASS ||
- iseq->type == ISEQ_TYPE_TOP) {
- iseq->local_size += 1 /* svar */;
- }
+ iseq->local_size += 1;
+ /*
+ if (lfp == dfp ) { // top, class, method
+ dfp[-1]: svar
+ else { // block
+ dfp[-1]: cref
+ }
+ */
debugs("iseq_set_local_table: %d, %d\n", iseq->local_size, iseq->local_table_size);
return COMPILE_OK;
@@ -3264,8 +3267,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
case NODE_ARRAY:
while (narg) {
COMPILE(ret, "rescue arg", narg->nd_head);
- ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(1),
- INT2FIX(0));
+ ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(2), INT2FIX(0));
ADD_SEND(ret, nd_line(node), ID2SYM(idEqq), INT2FIX(1));
ADD_INSNL(ret, nd_line(node), branchif, label_hit);
narg = narg->nd_next;
@@ -3274,8 +3276,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
case NODE_SPLAT:
case NODE_ARGSCAT:
case NODE_ARGSPUSH:
- ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(1),
- INT2FIX(0));
+ ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(2), INT2FIX(0));
COMPILE(ret, "rescue/cond splat", narg);
ADD_INSN1(ret, nd_line(node), checkincludearray, Qtrue);
ADD_INSN(ret, nd_line(node), swap);
@@ -3290,8 +3291,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
else {
ADD_INSN1(ret, nd_line(node), putobject,
rb_eStandardError);
- ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(1),
- INT2FIX(0));
+ ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(2), INT2FIX(0));
ADD_SEND(ret, nd_line(node), ID2SYM(idEqq), INT2FIX(1));
ADD_INSNL(ret, nd_line(node), branchif, label_hit);
}
@@ -4012,8 +4012,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
if (idx < 0) {
rb_bug("unknown dvar (%s)", rb_id2name(node->nd_vid));
}
- ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(ls - idx),
- INT2FIX(lv));
+ ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(ls - idx), INT2FIX(lv));
}
break;
}
@@ -4485,8 +4484,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
case NODE_ERRINFO:{
if (!poped) {
if (iseq->type == ISEQ_TYPE_RESCUE) {
- ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(1),
- INT2FIX(0));
+ ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(2), INT2FIX(0));
}
else {
rb_iseq_t *ip = iseq;
@@ -4499,8 +4497,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
level++;
}
if (ip) {
- ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(1),
- INT2FIX(level));
+ ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(2), INT2FIX(level));
}
else {
ADD_INSN(ret, nd_line(node), putnil);
diff --git a/eval.c b/eval.c
index f79854d0e9..a224744ac0 100644
--- a/eval.c
+++ b/eval.c
@@ -32,7 +32,7 @@ VALUE sysstack_error;
static VALUE exception_error;
-static VALUE eval(VALUE, VALUE, VALUE, const char *, int);
+static VALUE eval_string(VALUE, VALUE, VALUE, const char *, int);
static inline VALUE rb_yield_0(int argc, VALUE *argv);
static VALUE rb_call(VALUE, VALUE, ID, int, const VALUE *, int);
@@ -264,7 +264,7 @@ ruby_run_node(void *n)
VALUE
rb_eval_string(const char *str)
{
- return eval(rb_vm_top_self(), rb_str_new2(str), Qnil, "(eval)", 1);
+ return eval_string(rb_vm_top_self(), rb_str_new2(str), Qnil, "(eval)", 1);
}
VALUE
@@ -329,7 +329,7 @@ rb_eval_cmd(VALUE cmd, VALUE arg, int level)
PUSH_TAG();
if ((state = EXEC_TAG()) == 0) {
- val = eval(rb_vm_top_self(), cmd, Qnil, 0, 0);
+ val = eval_string(rb_vm_top_self(), cmd, Qnil, 0, 0);
}
POP_TAG();
@@ -884,11 +884,12 @@ rb_iterator_p()
VALUE
-rb_f_block_given_p()
+rb_f_block_given_p(void)
{
rb_thread_t *th = GET_THREAD();
rb_control_frame_t *cfp = th->cfp;
cfp = vm_get_ruby_level_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
+
if (GC_GUARDED_PTR_REF(cfp->lfp[0])) {
return Qtrue;
}
@@ -1681,7 +1682,7 @@ rb_frame_self(void)
}
static VALUE
-eval(VALUE self, VALUE src, VALUE scope, const char *file, int line)
+eval_string_with_cref(VALUE self, VALUE src, VALUE scope, NODE *cref, const char *file, int line)
{
int state;
VALUE result = Qundef;
@@ -1689,7 +1690,7 @@ eval(VALUE self, VALUE src, VALUE scope, const char *file, int line)
rb_binding_t *bind = 0;
rb_thread_t *th = GET_THREAD();
rb_env_t *env = NULL;
- NODE *stored_cref_stack = 0;
+ rb_block_t block;
if (file == 0) {
file = rb_sourcefile();
@@ -1705,7 +1706,6 @@ eval(VALUE self, VALUE src, VALUE scope, const char *file, int line)
if (rb_obj_is_kind_of(scope, rb_cBinding)) {
GetBindingPtr(scope, bind);
envval = bind->env;
- stored_cref_stack = bind->cref_stack;
}
else {
rb_raise(rb_eTypeError,
@@ -1717,7 +1717,9 @@ eval(VALUE self, VALUE src, VALUE scope, const char *file, int line)
}
else {
rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
- th->base_block = RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp);
+ block = *RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp);
+ th->base_block = &block;
+ th->base_block->self = self;
th->base_block->iseq = cfp->iseq; /* TODO */
}
@@ -1725,7 +1727,8 @@ eval(VALUE self, VALUE src, VALUE scope, const char *file, int line)
th->parse_in_eval++;
iseqval = rb_iseq_compile(src, rb_str_new2(file), INT2FIX(line));
th->parse_in_eval--;
- rb_vm_set_eval_stack(th, iseqval);
+
+ rb_vm_set_eval_stack(th, iseqval, cref);
th->base_block = 0;
if (0) { /* for debug */
@@ -1739,22 +1742,12 @@ eval(VALUE self, VALUE src, VALUE scope, const char *file, int line)
bind->env = vm_make_env_object(th, th->cfp);
}
- /* push tag */
- if (stored_cref_stack) {
- stored_cref_stack =
- vm_set_special_cref(th, env->block.lfp, stored_cref_stack);
- }
-
/* kick */
CHECK_STACK_OVERFLOW(th->cfp, iseq->stack_max);
result = vm_eval_body(th);
}
POP_TAG();
- if (stored_cref_stack) {
- vm_set_special_cref(th, env->block.lfp, stored_cref_stack);
- }
-
if (state) {
if (state == TAG_RAISE) {
VALUE errinfo = th->errinfo;
@@ -1779,6 +1772,12 @@ eval(VALUE self, VALUE src, VALUE scope, const char *file, int line)
return result;
}
+static VALUE
+eval_string(VALUE self, VALUE src, VALUE scope, const char *file, int line)
+{
+ return eval_string_with_cref(self, src, scope, 0, file, line);
+}
+
/*
* call-seq:
* eval(string [, binding [, filename [,lineno]]]) => obj
@@ -1825,90 +1824,36 @@ rb_f_eval(int argc, VALUE *argv, VALUE self)
if (!NIL_P(vfile))
file = RSTRING_PTR(vfile);
- return eval(self, src, scope, file, line);
+ return eval_string(self, src, scope, file, line);
}
-VALUE vm_cfp_svar_get(rb_thread_t *th, rb_control_frame_t *cfp, VALUE key);
-void vm_cfp_svar_set(rb_thread_t *th, rb_control_frame_t *cfp, VALUE key, VALUE val);
-
-/* function to call func under the specified class/module context */
+/* block eval under the class/module context */
static VALUE
-exec_under(VALUE (*func) (VALUE), VALUE under, VALUE self, VALUE args)
+yield_under(VALUE under, VALUE self, VALUE values)
{
- VALUE val = Qnil; /* OK */
rb_thread_t *th = GET_THREAD();
- rb_control_frame_t *cfp = th->cfp;
- rb_control_frame_t *pcfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
- VALUE stored_self = pcfp->self;
- NODE *stored_cref = 0;
-
- rb_block_t block;
- rb_block_t *blockptr;
- int state;
+ rb_block_t block, *blockptr;
+ NODE *cref = vm_cref_push(th, under, NOEX_PUBLIC);
- /* replace environment */
- pcfp->self = self;
- if ((blockptr = GC_GUARDED_PTR_REF(*th->cfp->lfp)) != 0) {
- /* copy block info */
- /* TODO: why? */
+ if ((blockptr = GC_GUARDED_PTR_REF(th->cfp->lfp[0])) != 0) {
block = *blockptr;
block.self = self;
- *th->cfp->lfp = GC_GUARDED_PTR(&block);
+ th->cfp->lfp[0] = GC_GUARDED_PTR(&block);
}
- while (!RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
- cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
- }
-
- stored_cref = (NODE *)vm_cfp_svar_get(th, cfp, 2);
- vm_cfp_svar_set(th, cfp, 2, (VALUE)vm_cref_push(th, under, NOEX_PUBLIC));
-
- PUSH_TAG();
- if ((state = EXEC_TAG()) == 0) {
- val = (*func) (args);
- }
- POP_TAG();
-
- /* restore environment */
- vm_cfp_svar_set(th, cfp, 2, (VALUE)stored_cref);
- pcfp->self = stored_self;
-
- if (state) {
- JUMP_TAG(state);
- }
- return val;
-}
-
-static VALUE
-yield_under_i(VALUE arg)
-{
- if (arg == Qundef) {
- return rb_yield_0(0, 0);
+ if (values == Qundef) {
+ return vm_yield_with_cref(th, 0, 0, cref);
}
else {
- return rb_yield_0(RARRAY_LEN(arg), RARRAY_PTR(arg));
+ return vm_yield_with_cref(th, RARRAY_LEN(values), RARRAY_PTR(values), cref);
}
}
-/* block eval under the class/module context */
-static VALUE
-yield_under(VALUE under, VALUE self, VALUE values)
-{
- return exec_under(yield_under_i, under, self, values);
-}
-
-static VALUE
-eval_under_i(VALUE arg)
-{
- VALUE *args = (VALUE *)arg;
- return eval(args[0], args[1], Qnil, (char *)args[2], (int)args[3]);
-}
-
/* string eval under the class/module context */
static VALUE
eval_under(VALUE under, VALUE self, VALUE src, const char *file, int line)
{
- VALUE args[4];
+ NODE *cref = vm_cref_push(GET_THREAD(), under, NOEX_PUBLIC);
if (rb_safe_level() >= 4) {
StringValue(src);
@@ -1916,11 +1861,8 @@ eval_under(VALUE under, VALUE self, VALUE src, const char *file, int line)
else {
SafeStringValue(src);
}
- args[0] = self;
- args[1] = src;
- args[2] = (VALUE)file;
- args[3] = (VALUE)line;
- return exec_under(eval_under_i, under, self, (VALUE)args);
+
+ return eval_string_with_cref(self, src, Qnil, cref, file, line);
}
static VALUE
@@ -1928,8 +1870,7 @@ specific_eval(int argc, VALUE *argv, VALUE klass, VALUE self)
{
if (rb_block_given_p()) {
if (argc > 0) {
- rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)",
- argc);
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc);
}
return yield_under(klass, self, Qundef);
}
@@ -2499,12 +2440,12 @@ errinfo_place(void)
while (RUBY_VM_VALID_CONTROL_FRAME_P(cfp, end_cfp)) {
if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
if (cfp->iseq->type == ISEQ_TYPE_RESCUE) {
- return &cfp->dfp[-1];
+ return &cfp->dfp[-2];
}
else if (cfp->iseq->type == ISEQ_TYPE_ENSURE &&
- TYPE(cfp->dfp[-1]) != T_NODE &&
- !FIXNUM_P(cfp->dfp[-1])) {
- return &cfp->dfp[-1];
+ TYPE(cfp->dfp[-2]) != T_NODE &&
+ !FIXNUM_P(cfp->dfp[-2])) {
+ return &cfp->dfp[-2];
}
}
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
diff --git a/eval_intern.h b/eval_intern.h
index c53cc32330..d4949822d7 100644
--- a/eval_intern.h
+++ b/eval_intern.h
@@ -225,11 +225,12 @@ NORETURN(void rb_print_undef(VALUE, ID, int));
NORETURN(void vm_localjump_error(const char *, VALUE, int));
NORETURN(void vm_jump_tag_but_local_jump(int, VALUE));
-NODE *vm_get_cref(rb_thread_t *th, rb_iseq_t *iseq, rb_control_frame_t *cfp);
NODE *vm_cref_push(rb_thread_t *th, VALUE, int);
NODE *vm_set_special_cref(rb_thread_t *th, VALUE *lfp, NODE * cref_stack);
VALUE vm_make_jump_tag_but_local_jump(int state, VALUE val);
+NODE *ruby_cref(void);
+
static rb_control_frame_t *
vm_get_ruby_level_cfp(rb_thread_t *th, rb_control_frame_t *cfp)
{
@@ -242,22 +243,12 @@ vm_get_ruby_level_cfp(rb_thread_t *th, rb_control_frame_t *cfp)
return 0;
}
-static inline NODE *
-ruby_cref()
-{
- rb_thread_t *th = GET_THREAD();
- rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
- return vm_get_cref(th, cfp->iseq, cfp);
-}
-
-VALUE vm_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);
-void rb_vm_set_eval_stack(rb_thread_t *, VALUE iseq);
+void rb_vm_set_eval_stack(rb_thread_t *, VALUE iseq, NODE *cref);
VALUE rb_vm_top_self();
-
-#define ruby_cbase() vm_get_cbase(GET_THREAD())
+VALUE rb_vm_cbase(void);
#endif /* RUBY_EVAL_INTERN_H */
diff --git a/eval_method.c b/eval_method.c
index 4a3f560939..de315a6682 100644
--- a/eval_method.c
+++ b/eval_method.c
@@ -463,7 +463,7 @@ rb_undef(VALUE klass, ID id)
VALUE origin;
NODE *body;
- if (ruby_cbase() == rb_cObject && klass == rb_cObject) {
+ if (rb_vm_cbase() == rb_cObject && klass == rb_cObject) {
rb_secure(4);
}
if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) {
diff --git a/gc.c b/gc.c
index 91e778f485..bcb671f700 100644
--- a/gc.c
+++ b/gc.c
@@ -1280,15 +1280,6 @@ gc_mark_children(rb_objspace_t *objspace, VALUE ptr, int lev)
}
break;
- case T_VALUES:
- {
- rb_gc_mark(RVALUES(obj)->v1);
- rb_gc_mark(RVALUES(obj)->v2);
- ptr = RVALUES(obj)->v3;
- goto again;
- }
- break;
-
default:
rb_bug("rb_gc_mark(): unknown data type 0x%lx(%p) %s",
obj->as.basic.flags & T_MASK, obj,
@@ -1531,8 +1522,6 @@ obj_free(rb_objspace_t *objspace, VALUE obj)
case T_FLOAT:
break;
- case T_VALUES:
- break;
case T_BIGNUM:
if (!(RBASIC(obj)->flags & RBIGNUM_EMBED_FLAG) && RBIGNUM_DIGITS(obj)) {
@@ -1878,7 +1867,6 @@ os_obj_of(rb_objspace_t *objspace, VALUE of)
case T_NONE:
case T_ICLASS:
case T_NODE:
- case T_VALUES:
continue;
case T_CLASS:
if (FL_TEST(p, FL_SINGLETON)) continue;
@@ -2175,7 +2163,7 @@ id2ref(VALUE obj, VALUE objid)
}
if (!is_pointer_to_heap(objspace, (void *)ptr) ||
- BUILTIN_TYPE(ptr) >= T_VALUES || BUILTIN_TYPE(ptr) == T_ICLASS) {
+ BUILTIN_TYPE(ptr) > T_FIXNUM || BUILTIN_TYPE(ptr) == T_ICLASS) {
rb_raise(rb_eRangeError, "%p is not id value", p0);
}
if (BUILTIN_TYPE(ptr) == 0 || RBASIC(ptr)->klass == 0) {
@@ -2334,7 +2322,6 @@ count_objects(int argc, VALUE *argv, VALUE os)
COUNT_TYPE(T_FALSE);
COUNT_TYPE(T_SYMBOL);
COUNT_TYPE(T_FIXNUM);
- COUNT_TYPE(T_VALUES);
COUNT_TYPE(T_UNDEF);
COUNT_TYPE(T_NODE);
COUNT_TYPE(T_ICLASS);
diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h
index 5707571cfa..0d146fbbce 100644
--- a/include/ruby/ruby.h
+++ b/include/ruby/ruby.h
@@ -262,7 +262,6 @@ enum ruby_value_type {
RUBY_T_SYMBOL = 0x14,
RUBY_T_FIXNUM = 0x15,
- RUBY_T_VALUES = 0x1a,
RUBY_T_UNDEF = 0x1b,
RUBY_T_NODE = 0x1c,
RUBY_T_ICLASS = 0x1d,
@@ -292,7 +291,6 @@ enum ruby_value_type {
#define T_SYMBOL RUBY_T_SYMBOL
#define T_RATIONAL RUBY_T_RATIONAL
#define T_COMPLEX RUBY_T_COMPLEX
-#define T_VALUES RUBY_T_VALUES
#define T_UNDEF RUBY_T_UNDEF
#define T_NODE RUBY_T_NODE
#define T_MASK RUBY_T_MASK
@@ -438,13 +436,6 @@ struct RObject {
RCLASS_IV_INDEX_TBL(rb_obj_class(o)) : \
ROBJECT(o)->as.heap.iv_index_tbl)
-struct RValues {
- struct RBasic basic;
- VALUE v1;
- VALUE v2;
- VALUE v3;
-};
-
typedef struct {
VALUE super;
struct st_table *iv_tbl;
@@ -654,7 +645,6 @@ struct RBignum {
#define RFILE(obj) (R_CAST(RFile)(obj))
#define RRATIONAL(obj) (R_CAST(RRational)(obj))
#define RCOMPLEX(obj) (R_CAST(RComplex)(obj))
-#define RVALUES(obj) (R_CAST(RValues)(obj))
#define FL_SINGLETON FL_USER0
#define FL_MARK (((VALUE)1)<<5)
diff --git a/insns.def b/insns.def
index 7723874c6c..43172efda9 100644
--- a/insns.def
+++ b/insns.def
@@ -183,7 +183,8 @@ getclassvariable
()
(VALUE val)
{
- val = rb_cvar_get(vm_get_cvar_base(th, GET_ISEQ()), id);
+ NODE *cref = vm_get_cref(GET_ISEQ(), GET_LFP(), GET_DFP());
+ val = rb_cvar_get(vm_get_cvar_base(cref), id);
}
/**
@@ -197,7 +198,8 @@ setclassvariable
(VALUE val)
()
{
- rb_cvar_set(vm_get_cvar_base(th, GET_ISEQ()), id, val);
+ NODE *cref = vm_get_cref(GET_ISEQ(), GET_LFP(), GET_DFP());
+ rb_cvar_set(vm_get_cvar_base(cref), id, val);
}
/**
@@ -317,7 +319,7 @@ putcbase
()
(VALUE val)
{
- val = vm_get_cbase(th);
+ val = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP());
}
/**
@@ -723,8 +725,8 @@ definemethod
(VALUE obj)
()
{
- vm_define_method(th, obj, id, body, is_singleton,
- get_cref(GET_ISEQ(), GET_LFP()));
+ NODE *cref = vm_get_cref(GET_ISEQ(), GET_LFP(), GET_DFP());
+ vm_define_method(th, obj, id, body, is_singleton, cref);
}
/**
@@ -744,7 +746,7 @@ alias
rb_alias_variable(SYM2ID(sym1), SYM2ID(sym2));
}
else {
- klass = get_cref(GET_ISEQ(), GET_LFP())->nd_clss;
+ klass = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP());
rb_alias(klass, SYM2ID(sym1), SYM2ID(sym2));
}
}
@@ -760,7 +762,7 @@ undef
(VALUE sym)
()
{
- VALUE klass = get_cref(GET_ISEQ(), GET_LFP())->nd_clss;
+ VALUE klass = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP());
rb_undef(klass, SYM2ID(sym));
INC_VM_STATE_VERSION();
}
@@ -787,7 +789,7 @@ defined
}
break;
case DEFINED_IVAR2:
- klass = get_cref(GET_ISEQ(), GET_LFP())->nd_clss;
+ klass = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP());
break;
case DEFINED_GVAR:
if (rb_gvar_defined((struct global_entry *)(obj & ~1))) {
@@ -795,7 +797,7 @@ defined
}
break;
case DEFINED_CVAR:
- klass = get_cref(GET_ISEQ(), GET_LFP())->nd_clss;
+ klass = vm_get_cbase(GET_ISEQ(), GET_LFP(), GET_DFP());
if (rb_cvar_defined(klass, SYM2ID(obj))) {
expr_type = "class variable";
}
diff --git a/load.c b/load.c
index 154572d80a..f91768c31a 100644
--- a/load.c
+++ b/load.c
@@ -650,7 +650,7 @@ rb_mod_autoload_p(VALUE mod, VALUE sym)
static VALUE
rb_f_autoload(VALUE obj, VALUE sym, VALUE file)
{
- VALUE klass = ruby_cbase();
+ VALUE klass = rb_vm_cbase();
if (NIL_P(klass)) {
rb_raise(rb_eTypeError, "Can not set autoload on singleton class");
}
@@ -664,8 +664,8 @@ rb_f_autoload(VALUE obj, VALUE sym, VALUE file)
static VALUE
rb_f_autoload_p(VALUE obj, VALUE sym)
{
- /* use ruby_cbase() as same as rb_f_autoload. */
- VALUE klass = ruby_cbase();
+ /* use rb_vm_cbase() as same as rb_f_autoload. */
+ VALUE klass = rb_vm_cbase();
if (NIL_P(klass)) {
return Qnil;
}
diff --git a/proc.c b/proc.c
index 57109eff73..2ac261c789 100644
--- a/proc.c
+++ b/proc.c
@@ -50,7 +50,6 @@ proc_mark(void *ptr)
proc = ptr;
RUBY_MARK_UNLESS_NULL(proc->envval);
RUBY_MARK_UNLESS_NULL(proc->blockprocval);
- RUBY_MARK_UNLESS_NULL((VALUE)proc->special_cref_stack);
RUBY_MARK_UNLESS_NULL(proc->block.proc);
RUBY_MARK_UNLESS_NULL(proc->block.self);
if (proc->block.iseq && RUBY_VM_IFUNC_P(proc->block.iseq)) {
@@ -94,7 +93,6 @@ proc_dup(VALUE self)
dst->block.proc = procval;
dst->envval = src->envval;
dst->safe_level = dst->safe_level;
- dst->special_cref_stack = src->special_cref_stack;
dst->is_lambda = src->is_lambda;
return procval;
@@ -241,7 +239,6 @@ binding_mark(void *ptr)
if (ptr) {
bind = ptr;
RUBY_MARK_UNLESS_NULL(bind->env);
- RUBY_MARK_UNLESS_NULL((VALUE)bind->cref_stack);
}
RUBY_MARK_LEAVE("binding");
}
@@ -264,7 +261,6 @@ binding_dup(VALUE self)
GetBindingPtr(self, src);
GetBindingPtr(bindval, dst);
dst->env = src->env;
- dst->cref_stack = src->cref_stack;
return bindval;
}
@@ -286,7 +282,6 @@ rb_binding_new(void)
GetBindingPtr(bindval, bind);
bind->env = vm_make_env_object(th, cfp);
- bind->cref_stack = ruby_cref();
return bindval;
}
@@ -1587,7 +1582,6 @@ proc_binding(VALUE self)
}
bind->env = proc->envval;
- bind->cref_stack = proc->special_cref_stack;
return bindval;
}
diff --git a/version.h b/version.h
index e131064ff3..7870b2492a 100644
--- a/version.h
+++ b/version.h
@@ -1,7 +1,7 @@
#define RUBY_VERSION "1.9.0"
-#define RUBY_RELEASE_DATE "2008-05-18"
+#define RUBY_RELEASE_DATE "2008-05-19"
#define RUBY_VERSION_CODE 190
-#define RUBY_RELEASE_CODE 20080518
+#define RUBY_RELEASE_CODE 20080519
#define RUBY_PATCHLEVEL 0
#define RUBY_VERSION_MAJOR 1
@@ -9,7 +9,7 @@
#define RUBY_VERSION_TEENY 0
#define RUBY_RELEASE_YEAR 2008
#define RUBY_RELEASE_MONTH 5
-#define RUBY_RELEASE_DAY 18
+#define RUBY_RELEASE_DAY 19
#ifdef RUBY_EXTERN
RUBY_EXTERN const char ruby_version[];
@@ -46,7 +46,7 @@ RUBY_EXTERN const char ruby_copyright[];
# define RUBY_DESCRIPTION \
"ruby "RUBY_VERSION \
- " ("RUBY_RELEASE_DATE" " \
+ "2008-05-19" \
RUBY_RELEASE_STR" " \
STRINGIZE(RUBY_RELEASE_NUM)") " \
"["RUBY_PLATFORM"]"
diff --git a/vm.c b/vm.c
index f29a1e221e..f5038462fb 100644
--- a/vm.c
+++ b/vm.c
@@ -79,7 +79,7 @@ rb_vm_set_top_stack(rb_thread_t *th, VALUE iseqval)
}
void
-rb_vm_set_eval_stack(rb_thread_t *th, VALUE iseqval)
+rb_vm_set_eval_stack(rb_thread_t *th, VALUE iseqval, NODE *cref)
{
rb_iseq_t *iseq;
rb_block_t *block = th->base_block;
@@ -90,6 +90,10 @@ rb_vm_set_eval_stack(rb_thread_t *th, VALUE iseqval)
vm_push_frame(th, iseq, FRAME_MAGIC_EVAL, block->self,
GC_GUARDED_PTR(block->dfp), iseq->iseq_encoded,
th->cfp->sp, block->lfp, iseq->local_size);
+
+ if (cref) {
+ th->cfp->dfp[-1] = (VALUE)cref;
+ }
}
/* Env */
@@ -263,12 +267,6 @@ vm_make_env_each(rb_thread_t *th, rb_control_frame_t *cfp,
env->block.dfp = cfp->dfp;
env->block.iseq = cfp->iseq;
- if (VMDEBUG &&
- (!(cfp->lfp[-1] == Qnil ||
- BUILTIN_TYPE(cfp->lfp[-1]) == T_VALUES))) {
- rb_bug("invalid svar");
- }
-
if (!RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
/* TODO */
env->block.iseq = 0;
@@ -389,7 +387,6 @@ vm_make_proc(rb_thread_t *th,
proc->block.proc = procval;
proc->envval = envval;
proc->safe_level = th->safe_level;
- proc->special_cref_stack = lfp_get_special_cref(block->lfp);
if (VMDEBUG) {
if (th->stack < block->dfp && block->dfp < th->stack + th->stack_size) {
@@ -540,8 +537,8 @@ rb_call_super(int argc, const VALUE *argv)
/* C -> Ruby: block */
static VALUE
-invoke_block(rb_thread_t *th, rb_block_t *block, VALUE self,
- int argc, VALUE *argv, rb_block_t *blockptr)
+invoke_block_from_c(rb_thread_t *th, rb_block_t *block, VALUE self,
+ int argc, VALUE *argv, rb_block_t *blockptr, NODE *cref)
{
VALUE val;
if (BUILTIN_TYPE(block->iseq) != T_NODE) {
@@ -566,6 +563,7 @@ invoke_block(rb_thread_t *th, rb_block_t *block, VALUE self,
self, GC_GUARDED_PTR(block->dfp),
iseq->iseq_encoded + opt_pc, cfp->sp + arg_size, block->lfp,
iseq->local_size - arg_size);
+ th->cfp->dfp[-1] = (VALUE)cref;
val = vm_eval_body(th);
}
@@ -576,7 +574,7 @@ invoke_block(rb_thread_t *th, rb_block_t *block, VALUE self,
}
VALUE
-vm_yield(rb_thread_t *th, int argc, VALUE *argv)
+vm_yield_with_cref(rb_thread_t *th, int argc, VALUE *argv, NODE *cref)
{
rb_block_t *block = GC_GUARDED_PTR_REF(th->cfp->lfp[0]);
@@ -584,7 +582,13 @@ vm_yield(rb_thread_t *th, int argc, VALUE *argv)
vm_localjump_error("no block given", Qnil, 0);
}
- return invoke_block(th, block, block->self, argc, argv, 0);
+ return invoke_block_from_c(th, block, block->self, argc, argv, 0, cref);
+}
+
+VALUE
+vm_yield(rb_thread_t *th, int argc, VALUE *argv)
+{
+ return vm_yield_with_cref(th, argc, argv, (NODE *)Qnil);
}
VALUE
@@ -594,14 +598,12 @@ vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc,
VALUE val = Qundef;
int state;
volatile int stored_safe = th->safe_level;
- volatile NODE *stored_special_cref_stack =
- lfp_set_special_cref(proc->block.lfp, proc->special_cref_stack);
rb_control_frame_t * volatile cfp = th->cfp;
TH_PUSH_TAG(th);
if ((state = EXEC_TAG()) == 0) {
th->safe_level = proc->safe_level;
- val = invoke_block(th, &proc->block, self, argc, argv, blockptr);
+ val = invoke_block_from_c(th, &proc->block, self, argc, argv, blockptr, (NODE *)Qnil);
}
TH_POP_TAG();
@@ -609,8 +611,6 @@ vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc,
th->safe_level = stored_safe;
}
- lfp_set_special_cref(proc->block.lfp, (NODE*)stored_special_cref_stack);
-
if (state) {
if (state == TAG_RETURN && proc->is_lambda) {
VALUE err = th->errinfo;
@@ -773,8 +773,6 @@ vm_backtrace(rb_thread_t *th, int lev)
return ary;
}
-/* cref */
-
static void
check_svar(void)
{
@@ -783,7 +781,7 @@ check_svar(void)
while ((void *)(cfp + 1) < (void *)(th->stack + th->stack_size)) {
/* printf("cfp: %p\n", cfp->type); */
if (cfp->lfp && cfp->lfp[-1] != Qnil &&
- TYPE(cfp->lfp[-1]) != T_VALUES) {
+ TYPE(cfp->lfp[-1]) != T_NODE) {
/* dp(cfp->lfp[-1]); */
rb_bug("!!!invalid svar!!!");
}
@@ -791,30 +789,12 @@ check_svar(void)
}
}
-static NODE *
-lfp_set_special_cref(VALUE *lfp, NODE * cref)
-{
- struct RValues *values = (void *) lfp[-1];
- NODE *old_cref;
-
- if (VMDEBUG) {
- check_svar();
- }
-
- if (cref == 0 && ((VALUE)values == Qnil || values->basic.klass == 0)) {
- old_cref = 0;
- }
- else {
- old_cref = (NODE *)lfp_svar_get(GET_THREAD(), lfp, 2);
- lfp_svar_set(GET_THREAD(), lfp, 2, (VALUE)cref);
- }
- return old_cref;
-}
-
NODE *
-vm_set_special_cref(rb_thread_t *th, VALUE *lfp, NODE * cref_stack)
+ruby_cref(void)
{
- return lfp_set_special_cref(lfp, cref_stack);
+ rb_thread_t *th = GET_THREAD();
+ rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
+ return vm_get_cref(cfp->iseq, cfp->lfp, cfp->dfp);
}
#if 0
@@ -830,28 +810,21 @@ debug_cref(NODE *cref)
#endif
NODE *
-vm_get_cref(rb_thread_t *th, rb_iseq_t *iseq, rb_control_frame_t *cfp)
-{
- return get_cref(iseq, cfp->lfp);
-}
-
-NODE *
vm_cref_push(rb_thread_t *th, VALUE klass, int noex)
{
NODE *cref = NEW_BLOCK(klass);
rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
cref->nd_file = 0;
- cref->nd_next = get_cref(cfp->iseq, cfp->lfp);
+ cref->nd_next = vm_get_cref(cfp->iseq, cfp->lfp, cfp->dfp);
cref->nd_visi = noex;
return cref;
}
-VALUE
-vm_get_cbase(rb_thread_t *th)
+static inline VALUE
+vm_get_cbase(rb_iseq_t *iseq, VALUE *lfp, VALUE *dfp)
{
- rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
- NODE *cref = get_cref(cfp->iseq, cfp->lfp);
+ NODE *cref = vm_get_cref(iseq, lfp, dfp);
VALUE klass = Qundef;
while (cref) {
@@ -860,9 +833,18 @@ vm_get_cbase(rb_thread_t *th)
}
cref = cref->nd_next;
}
+
return klass;
}
+VALUE
+rb_vm_cbase(void)
+{
+ rb_thread_t *th = GET_THREAD();
+ rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
+ return vm_get_cbase(cfp->iseq, cfp->lfp, cfp->dfp);
+}
+
/* jump */
static VALUE
@@ -1038,16 +1020,16 @@ vm_init_redefined_flag(void)
C1 : pushed by send insn (CFUNC)
struct CONTROL_FRAME {
- VALUE *pc; // cfp[0]
- VALUE *sp; // cfp[1]
- VALUE *bp; // cfp[2]
- rb_iseq_t *iseq; // cfp[3]
- VALUE flag; // cfp[4]
- VALUE self; // cfp[5]
- VALUE *lfp; // cfp[6]
- VALUE *dfp; // cfp[7]
- rb_iseq_t * block_iseq; // cfp[8]
- VALUE proc; // cfp[9] always 0
+ VALUE *pc; // cfp[0], program counter
+ VALUE *sp; // cfp[1], stack pointer
+ VALUE *bp; // cfp[2], base pointer
+ rb_iseq_t *iseq; // cfp[3], iseq
+ VALUE flag; // cfp[4], magic
+ VALUE self; // cfp[5], self
+ VALUE *lfp; // cfp[6], local frame pointer
+ VALUE *dfp; // cfp[7], dynamic frame pointer
+ rb_iseq_t * block_iseq; // cfp[8], block iseq
+ VALUE proc; // cfp[9], always 0
};
struct BLOCK {
@@ -1055,15 +1037,11 @@ vm_init_redefined_flag(void)
VALUE *lfp;
VALUE *dfp;
rb_iseq_t *block_iseq;
- };
-
- struct PROC {
- VALUE proc_sig = 0;
- struct BLOCK;
+ VALUE proc;
};
struct METHOD_CONTROL_FRAME {
- struct CONTROL_FRAME;
+ rb_control_frame_t frame;
};
struct METHOD_FRAME {
@@ -1073,12 +1051,13 @@ vm_init_redefined_flag(void)
VALUE param0;
...
VALUE paramN;
+ VALUE cref;
VALUE special; // lfp [1]
struct block_object *block_ptr | 0x01; // lfp [0]
};
struct BLOCK_CONTROL_FRAME {
- struct STACK_FRAME;
+ rb_control_frame_t frame;
};
struct BLOCK_FRAME {
@@ -1088,17 +1067,19 @@ vm_init_redefined_flag(void)
VALUE param0;
...
VALUE paramN;
+ VALUE cref;
VALUE *(prev_ptr | 0x01); // DFP[0]
};
struct CLASS_CONTROL_FRAME {
- struct STACK_FRAME;
+ rb_control_frame_t frame;
};
struct CLASS_FRAME {
VALUE param0;
...
VALUE paramN;
+ VALUE cref;
VALUE prev_dfp; // for frame jump
};
@@ -1125,11 +1106,6 @@ vm_init_redefined_flag(void)
VALUE *dfp; // lfp
rb_iseq_t * block_iseq; // 0
};
-
- struct C_METHDO_FRAME{
- VALUE block_ptr;
- VALUE special;
- };
*/
@@ -1315,7 +1291,7 @@ vm_eval_body(rb_thread_t *th)
cfp->sp[0] = err;
vm_push_frame(th, catch_iseq, FRAME_MAGIC_BLOCK,
cfp->self, (VALUE)cfp->dfp, catch_iseq->iseq_encoded,
- cfp->sp + 1, cfp->lfp, catch_iseq->local_size - 1);
+ cfp->sp + 1 /* push value */, cfp->lfp, catch_iseq->local_size - 1);
state = 0;
th->errinfo = Qnil;
diff --git a/vm_core.h b/vm_core.h
index 19a52eeeff..a6699ce1ad 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -497,8 +497,6 @@ typedef struct {
int safe_level;
int is_from_method;
int is_lambda;
-
- NODE *special_cref_stack;
} rb_proc_t;
#define GetEnvPtr(obj, ptr) \
@@ -517,7 +515,6 @@ typedef struct {
typedef struct {
VALUE env;
- NODE *cref_stack;
} rb_binding_t;
@@ -614,6 +611,7 @@ VALUE vm_make_env_object(rb_thread_t *th, rb_control_frame_t *cfp);
VALUE vm_backtrace(rb_thread_t *, int);
VALUE vm_yield(rb_thread_t *th, int argc, VALUE *argv);
+VALUE vm_yield_with_cref(rb_thread_t *th, int argc, VALUE *argv, NODE *cref);
VALUE vm_call0(rb_thread_t *th, VALUE klass, VALUE recv, VALUE id, ID oid,
int argc, const VALUE *argv, NODE *body, int nosuper);
diff --git a/vm_dump.c b/vm_dump.c
index d3e1e423a5..a0c6db5759 100644
--- a/vm_dump.c
+++ b/vm_dump.c
@@ -140,7 +140,7 @@ control_frame_dump(rb_thread_t *th, rb_control_frame_t *cfp)
void
vm_stack_dump_raw(rb_thread_t *th, rb_control_frame_t *cfp)
{
-#if 0
+#if 1
VALUE *sp = cfp->sp, *bp = cfp->bp;
VALUE *lfp = cfp->lfp;
VALUE *dfp = cfp->dfp;
@@ -175,6 +175,13 @@ vm_stack_dump_raw(rb_thread_t *th, rb_control_frame_t *cfp)
}
void
+vm_stack_dump_raw_current(void)
+{
+ rb_thread_t *th = GET_THREAD();
+ vm_stack_dump_raw(th, th->cfp);
+}
+
+void
env_dump_raw(rb_env_t *env, VALUE *lfp, VALUE *dfp)
{
int i;
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index ddd060e18b..eb7c218f6d 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -29,6 +29,8 @@ vm_push_frame(rb_thread_t *th, rb_iseq_t *iseq, VALUE type,
rb_control_frame_t *cfp;
int i;
+ /* setup vm value stack */
+
/* nil initialize */
for (i=0; i < local_size; i++) {
*sp = Qnil;
@@ -43,6 +45,8 @@ vm_push_frame(rb_thread_t *th, rb_iseq_t *iseq, VALUE type,
lfp = sp;
}
+ /* setup vm control frame stack */
+
cfp = th->cfp = th->cfp - 1;
cfp->pc = pc;
cfp->sp = sp + 1;
@@ -827,45 +831,24 @@ vm_invoke_block(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_num_t num, rb_n
}
}
-/* cref */
-
-static NODE *
-lfp_get_special_cref(VALUE *lfp)
-{
- struct RValues *values;
- if (((VALUE)(values = (void *)lfp[-1])) != Qnil && values->basic.klass) {
- return (NODE *)values->basic.klass;
- }
- else {
- return 0;
- }
-}
-
-static struct RValues *
-new_value(void)
-{
- struct RValues *val = RVALUES(rb_newobj());
- OBJSETUP(val, 0, T_VALUES);
- val->v1 = val->v2 = val->v3 = Qnil;
- return val;
-}
+/* svar */
-static struct RValues *
+static inline NODE *
lfp_svar_place(rb_thread_t *th, VALUE *lfp)
{
- struct RValues *svar;
+ NODE *svar;
if (th->local_lfp != lfp) {
- svar = (struct RValues *)lfp[-1];
+ svar = (NODE *)lfp[-1];
if ((VALUE)svar == Qnil) {
- svar = new_value();
+ svar = NEW_IF(Qnil, Qnil, Qnil);
lfp[-1] = (VALUE)svar;
}
}
else {
- svar = (struct RValues *)th->local_svar;
+ svar = (NODE *)th->local_svar;
if ((VALUE)svar == Qnil) {
- svar = new_value();
+ svar = NEW_IF(Qnil, Qnil, Qnil);
th->local_svar = (VALUE)svar;
}
}
@@ -875,17 +858,15 @@ lfp_svar_place(rb_thread_t *th, VALUE *lfp)
static VALUE
lfp_svar_get(rb_thread_t *th, VALUE *lfp, VALUE key)
{
- struct RValues *svar = lfp_svar_place(th, lfp);
+ NODE *svar = lfp_svar_place(th, lfp);
switch (key) {
case 0:
- return svar->v1;
+ return svar->u1.value;
case 1:
- return svar->v2;
- case 2:
- return svar->basic.klass;
+ return svar->u2.value;
default: {
- VALUE hash = svar->v3;
+ VALUE hash = svar->u3.value;
if (hash == Qnil) {
return Qnil;
@@ -900,45 +881,26 @@ lfp_svar_get(rb_thread_t *th, VALUE *lfp, VALUE key)
static void
lfp_svar_set(rb_thread_t *th, VALUE *lfp, VALUE key, VALUE val)
{
- struct RValues *svar = lfp_svar_place(th, lfp);
+ NODE *svar = lfp_svar_place(th, lfp);
switch (key) {
case 0:
- svar->v1 = val;
+ svar->u1.value = val;
return;
case 1:
- svar->v2 = val;
- return;
- case 2:
- svar->basic.klass = val;
+ svar->u2.value = val;
return;
default: {
- VALUE hash = svar->v3;
+ VALUE hash = svar->u3.value;
if (hash == Qnil) {
- svar->v3 = hash = rb_hash_new();
+ svar->u3.value = hash = rb_hash_new();
}
rb_hash_aset(hash, key, val);
}
}
}
-static NODE *
-get_cref(rb_iseq_t *iseq, VALUE *lfp)
-{
- NODE *cref;
- if ((cref = lfp_get_special_cref(lfp)) != 0) {
- /* */
- }
- else if ((cref = iseq->cref_stack) != 0) {
- /* */
- }
- else {
- rb_bug("get_cref: unreachable");
- }
- return cref;
-}
-
static inline VALUE
vm_getspecial(rb_thread_t *th, VALUE *lfp, VALUE key, rb_num_t type)
{
@@ -976,6 +938,30 @@ vm_getspecial(rb_thread_t *th, VALUE *lfp, VALUE key, rb_num_t type)
return val;
}
+static NODE *
+vm_get_cref(rb_iseq_t *iseq, const VALUE * const lfp, const VALUE *dfp)
+{
+ NODE *cref = 0;
+
+ while (1) {
+ if (lfp == dfp) {
+ cref = iseq->cref_stack;
+ break;
+ }
+ else if (dfp[-1] != Qnil) {
+ cref = (NODE *)dfp[-1];
+ break;
+ }
+ dfp = GET_PREV_DFP(dfp);
+ }
+
+ if (cref == 0) {
+ rb_bug("vm_get_cref: unreachable");
+ }
+ return cref;
+}
+
+
static inline void
vm_check_if_namespace(VALUE klass)
{
@@ -997,7 +983,7 @@ vm_get_ev_const(rb_thread_t *th, rb_iseq_t *iseq,
if (klass == Qnil) {
/* in current lexical scope */
- NODE *root_cref = get_cref(iseq, th->cfp->lfp);
+ NODE *root_cref = vm_get_cref(iseq, th->cfp->lfp, th->cfp->dfp);
NODE *cref = root_cref;
while (cref && cref->nd_next) {
@@ -1054,9 +1040,8 @@ vm_get_ev_const(rb_thread_t *th, rb_iseq_t *iseq,
}
static inline VALUE
-vm_get_cvar_base(rb_thread_t *th, rb_iseq_t *iseq)
+vm_get_cvar_base(NODE *cref)
{
- NODE *cref = get_cref(iseq, th->cfp->lfp);
VALUE klass = Qnil;
if (cref) {
@@ -1076,8 +1061,8 @@ vm_define_method(rb_thread_t *th, VALUE obj,
ID id, rb_iseq_t *miseq, rb_num_t is_singleton, NODE *cref)
{
NODE *newbody;
- int noex = cref->nd_visi;
VALUE klass = cref->nd_clss;
+ int noex = cref->nd_visi;
if (is_singleton) {
if (FIXNUM_P(obj) || SYMBOL_P(obj)) {