ruby-changes:5579
From: ko1 <ko1@a...>
Date: Wed, 11 Jun 2008 06:47:07 +0900 (JST)
Subject: [ruby-changes:5579] Ruby:r17084 (trunk): * vm.c, eval_intern.h (PASS_PASSED_BLOCK):
ko1 2008-06-11 06:46:43 +0900 (Wed, 11 Jun 2008)
New Revision: 17084
Modified files:
trunk/ChangeLog
trunk/KNOWNBUGS.rb
trunk/bootstraptest/test_eval.rb
trunk/bootstraptest/test_proc.rb
trunk/bootstraptest/test_syntax.rb
trunk/bootstraptest/test_thread.rb
trunk/eval.c
trunk/eval_intern.h
trunk/insns.def
trunk/proc.c
trunk/vm.c
trunk/vm.h
trunk/vm_core.h
trunk/vm_dump.c
trunk/vm_eval.c
trunk/vm_evalbody.c
trunk/vm_insnhelper.c
Log:
* vm.c, eval_intern.h (PASS_PASSED_BLOCK):
set a VM_FRAME_FLAG_PASSED flag to skip this frame when
searching ruby-level-cfp.
* eval.c, eval_intern.h, proc.c: fix to check cfp. if there is
no valid ruby-level-cfp, cause RuntimeError exception.
[ruby-dev:34128]
* vm_core.h, vm_evalbody.c, vm.c, vm_dump.c, vm_insnhelper.c,
insns.def: rename FRAME_MAGIC_* to VM_FRAME_MAGIC_*.
* KNOWNBUGS.rb, bootstraptest/test*.rb: move solved bugs.
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/vm_dump.c?r1=17084&r2=17083&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/vm.h?r1=17084&r2=17083&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=17084&r2=17083&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/vm_evalbody.c?r1=17084&r2=17083&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/eval.c?r1=17084&r2=17083&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/bootstraptest/test_proc.rb?r1=17084&r2=17083&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/KNOWNBUGS.rb?r1=17084&r2=17083&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/vm_core.h?r1=17084&r2=17083&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/proc.c?r1=17084&r2=17083&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/bootstraptest/test_thread.rb?r1=17084&r2=17083&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/bootstraptest/test_syntax.rb?r1=17084&r2=17083&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/vm.c?r1=17084&r2=17083&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/vm_eval.c?r1=17084&r2=17083&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/insns.def?r1=17084&r2=17083&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/vm_insnhelper.c?r1=17084&r2=17083&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/eval_intern.h?r1=17084&r2=17083&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/bootstraptest/test_eval.rb?r1=17084&r2=17083&diff_format=u
Index: eval_intern.h
===================================================================
--- eval_intern.h (revision 17083)
+++ eval_intern.h (revision 17084)
@@ -2,10 +2,16 @@
#ifndef RUBY_EVAL_INTERN_H
#define RUBY_EVAL_INTERN_H
-#define PASS_PASSED_BLOCK() \
- (GET_THREAD()->passed_block = \
- GC_GUARDED_PTR_REF((rb_block_t *)GET_THREAD()->cfp->lfp[0]))
+#define PASS_PASSED_BLOCK_TH(th) do { \
+ (th)->passed_block = GC_GUARDED_PTR_REF((rb_block_t *)(th)->cfp->lfp[0]); \
+ (th)->cfp->flag |= VM_FRAME_FLAG_PASSED; \
+} while (0)
+#define PASS_PASSED_BLOCK() do { \
+ rb_thread_t * const __th__ = GET_THREAD(); \
+ PASS_PASSED_BLOCK_TH(__th__); \
+} while (0)
+
#include "ruby/ruby.h"
#include "ruby/node.h"
#include "ruby/util.h"
@@ -219,7 +225,7 @@
VALUE vm_make_jump_tag_but_local_jump(int state, VALUE val);
NODE *vm_cref(void);
-rb_control_frame_t *vm_get_ruby_level_cfp(rb_thread_t *th, rb_control_frame_t *cfp);
+rb_control_frame_t *vm_get_ruby_level_caller_cfp(rb_thread_t *th, rb_control_frame_t *cfp);
VALUE rb_obj_is_proc(VALUE);
VALUE rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg, const rb_block_t *blockptr, VALUE filename);
void rb_thread_terminate_all(void);
Index: insns.def
===================================================================
--- insns.def (revision 17083)
+++ insns.def (revision 17084)
@@ -996,7 +996,7 @@
/* enter scope */
vm_push_frame(th, class_iseq,
- FRAME_MAGIC_CLASS, klass, (VALUE) GET_DFP() | 0x02,
+ VM_FRAME_MAGIC_CLASS, klass, (VALUE) GET_DFP() | 0x02,
class_iseq->iseq_encoded, GET_SP(), 0,
class_iseq->local_size);
RESTORE_REGS();
Index: ChangeLog
===================================================================
--- ChangeLog (revision 17083)
+++ ChangeLog (revision 17084)
@@ -1,3 +1,18 @@
+Wed Jun 11 05:53:20 2008 Koichi Sasada <ko1@a...>
+
+ * vm.c, eval_intern.h (PASS_PASSED_BLOCK):
+ set a VM_FRAME_FLAG_PASSED flag to skip this frame when
+ searching ruby-level-cfp.
+
+ * eval.c, eval_intern.h, proc.c: fix to check cfp. if there is
+ no valid ruby-level-cfp, cause RuntimeError exception.
+ [ruby-dev:34128]
+
+ * vm_core.h, vm_evalbody.c, vm.c, vm_dump.c, vm_insnhelper.c,
+ insns.def: rename FRAME_MAGIC_* to VM_FRAME_MAGIC_*.
+
+ * KNOWNBUGS.rb, bootstraptest/test*.rb: move solved bugs.
+
Wed Jun 11 05:55:31 2008 Hidetoshi NAGAI <nagai@a...>
* ext/tk/tcltklib.c: SEGV when tcltk-stubs is enabled.
Index: bootstraptest/test_syntax.rb
===================================================================
--- bootstraptest/test_syntax.rb (revision 17083)
+++ bootstraptest/test_syntax.rb (revision 17084)
@@ -817,3 +817,14 @@
end
}, '[ruby-core:14537]'
+assert_equal 'ok', %q{
+ a = [false]
+ (a[0] &&= true) == false ? :ok : :ng
+}, '[ruby-dev:34679]'
+
+assert_normal_exit %q{
+ a = []
+ 100.times {|i| a << i << nil << nil }
+ p a.compact!
+}
+
Index: bootstraptest/test_eval.rb
===================================================================
--- bootstraptest/test_eval.rb (revision 17083)
+++ bootstraptest/test_eval.rb (revision 17084)
@@ -282,3 +282,7 @@
:ok
end
}, '[ruby-core:16796]'
+
+assert_normal_exit %q{
+ eval("", method(:proc).call {}.binding)
+}
Index: bootstraptest/test_proc.rb
===================================================================
--- bootstraptest/test_proc.rb (revision 17083)
+++ bootstraptest/test_proc.rb (revision 17084)
@@ -259,3 +259,20 @@
GC.start
block.call
}, '[ruby-core:14885]'
+
+assert_equal 'ok', %q{
+ a = lambda {|x, y, &b| b }
+ b = a.curry[1]
+ if b.call(2){} == nil
+ :ng
+ else
+ :ok
+ end
+}, '[ruby-core:15551]'
+
+assert_equal 'ok', %q{
+ lambda {
+ break :ok
+ :ng
+ }.call
+}, '[ruby-dev:34646]'
Index: bootstraptest/test_thread.rb
===================================================================
--- bootstraptest/test_thread.rb (revision 17083)
+++ bootstraptest/test_thread.rb (revision 17084)
@@ -1,3 +1,5 @@
+# Thread and Fiber
+
assert_equal %q{ok}, %q{
Thread.new{
}.join
@@ -268,3 +270,35 @@
at_exit { Fiber.new{}.resume }
}
+assert_normal_exit %q{
+ g = enum_for(:local_variables)
+ loop { g.next }
+}, '[ruby-dev:34128]'
+
+assert_normal_exit %q{
+ g = enum_for(:block_given?)
+ loop { g.next }
+}, '[ruby-dev:34128]'
+
+assert_normal_exit %q{
+ g = enum_for(:binding)
+ loop { g.next }
+}, '[ruby-dev:34128]'
+
+assert_normal_exit %q{
+ g = "abc".enum_for(:scan, /./)
+ loop { g.next }
+}, '[ruby-dev:34128]'
+
+assert_normal_exit %q{
+ g = Module.enum_for(:new)
+ loop { g.next }
+}, '[ruby-dev:34128]'
+
+assert_normal_exit %q{
+ Fiber.new(&Object.method(:class_eval)).resume("foo")
+}, '[ruby-dev:34128]'
+
+assert_normal_exit %q{
+ Thread.new("foo", &Object.method(:class_eval)).join
+}, '[ruby-dev:34128]'
Index: vm_core.h
===================================================================
--- vm_core.h (revision 17083)
+++ vm_core.h (revision 17084)
@@ -539,6 +539,29 @@
#define VM_CALL_SUPER_BIT (0x01 << 7)
#define VM_CALL_SEND_BIT (0x01 << 8)
+#define VM_FRAME_MAGIC_METHOD 0x11
+#define VM_FRAME_MAGIC_BLOCK 0x21
+#define VM_FRAME_MAGIC_CLASS 0x31
+#define VM_FRAME_MAGIC_TOP 0x41
+#define VM_FRAME_MAGIC_FINISH 0x51
+#define VM_FRAME_MAGIC_CFUNC 0x61
+#define VM_FRAME_MAGIC_PROC 0x71
+#define VM_FRAME_MAGIC_IFUNC 0x81
+#define VM_FRAME_MAGIC_EVAL 0x91
+#define VM_FRAME_MAGIC_LAMBDA 0xa1
+#define VM_FRAME_MAGIC_MASK_BITS 8
+#define VM_FRAME_MAGIC_MASK (~(~0<<VM_FRAME_MAGIC_MASK_BITS))
+
+#define VM_FRAME_TYPE(cfp) ((cfp)->flag & VM_FRAME_MAGIC_MASK)
+
+/* other frame flag */
+#define VM_FRAME_FLAG_PASSED 0x0100
+
+
+#define RUBYVM_CFUNC_FRAME_P(cfp) \
+ (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_CFUNC)
+
+
/* inline (method|const) cache */
#define NEW_INLINE_CACHE_ENTRY() NEW_WHILE(Qundef, 0, 0)
#define ic_class u1.value
Index: vm_eval.c
===================================================================
--- vm_eval.c (revision 17083)
+++ vm_eval.c (revision 17084)
@@ -66,7 +66,7 @@
{
rb_control_frame_t *reg_cfp = th->cfp;
rb_control_frame_t *cfp =
- vm_push_frame(th, 0, FRAME_MAGIC_CFUNC,
+ vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC,
recv, (VALUE)blockptr, 0, reg_cfp->sp, 0, 1);
cfp->method_id = id;
@@ -412,13 +412,15 @@
{
VALUE vid;
VALUE self = RUBY_VM_PREVIOUS_CONTROL_FRAME(GET_THREAD()->cfp)->self;
+ rb_thread_t *th = GET_THREAD();
if (argc == 0) {
rb_raise(rb_eArgError, "no method name given");
}
vid = *argv++; argc--;
- PASS_PASSED_BLOCK();
+ PASS_PASSED_BLOCK_TH(th);
+
return rb_call0(CLASS_OF(recv), recv, rb_to_id(vid), argc, argv, scope, self);
}
@@ -687,11 +689,17 @@
th->base_block = &env->block;
}
else {
- rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
- block = *RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp);
- th->base_block = █
- th->base_block->self = self;
- th->base_block->iseq = cfp->iseq; /* TODO */
+ rb_control_frame_t *cfp = vm_get_ruby_level_caller_cfp(th, th->cfp);
+
+ if (cfp != 0) {
+ block = *RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp);
+ th->base_block = █
+ th->base_block->self = self;
+ th->base_block->iseq = cfp->iseq; /* TODO */
+ }
+ else {
+ rb_raise(rb_eRuntimeError, "Can't eval on top of Fiber or Thread");
+ }
}
/* make eval iseq */
Index: proc.c
===================================================================
--- proc.c (revision 17083)
+++ proc.c (revision 17084)
@@ -275,10 +275,14 @@
rb_binding_new(void)
{
rb_thread_t *th = GET_THREAD();
- rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
+ rb_control_frame_t *cfp = vm_get_ruby_level_caller_cfp(th, th->cfp);
VALUE bindval = binding_alloc(rb_cBinding);
rb_binding_t *bind;
+ if (cfp == 0) {
+ rb_raise(rb_eRuntimeError, "Can't create Binding Object on top of Fiber.");
+ }
+
GetBindingPtr(bindval, bind);
bind->env = vm_make_env_object(th, cfp);
return bindval;
@@ -1187,11 +1191,12 @@
}
}
if ((state = EXEC_TAG()) == 0) {
+ rb_thread_t *th = GET_THREAD();
VALUE rb_vm_call(rb_thread_t * th, VALUE klass, VALUE recv, VALUE id, ID oid,
int argc, const VALUE *argv, const NODE *body, int nosuper);
- PASS_PASSED_BLOCK();
- result = rb_vm_call(GET_THREAD(), data->oclass, data->recv, data->id, data->oid,
+ PASS_PASSED_BLOCK_TH(th);
+ result = rb_vm_call(th, data->oclass, data->recv, data->id, data->oid,
argc, argv, data->body, 0);
}
POP_TAG();
Index: eval.c
===================================================================
--- eval.c (revision 17083)
+++ eval.c (revision 17084)
@@ -17,8 +17,6 @@
VALUE rb_binding_new(void);
NORETURN(void rb_raise_jump(VALUE));
-VALUE rb_f_block_given_p(void);
-
ID rb_frame_callee(void);
VALUE rb_eLocalJumpError;
VALUE rb_eSysStackError;
@@ -586,9 +584,9 @@
{
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));
+ cfp = vm_get_ruby_level_caller_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
- if (GC_GUARDED_PTR_REF(cfp->lfp[0])) {
+ if (cfp != 0 && GC_GUARDED_PTR_REF(cfp->lfp[0])) {
return Qtrue;
}
else {
@@ -1089,10 +1087,10 @@
VALUE ary = rb_ary_new();
rb_thread_t *th = GET_THREAD();
rb_control_frame_t *cfp =
- vm_get_ruby_level_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp));
+ vm_get_ruby_level_caller_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp));
int i;
- while (1) {
+ while (cfp) {
if (cfp->iseq) {
for (i = 0; i < cfp->iseq->local_table_size; i++) {
ID lid = cfp->iseq->local_table[i];
Index: KNOWNBUGS.rb
===================================================================
--- KNOWNBUGS.rb (revision 17083)
+++ KNOWNBUGS.rb (revision 17084)
@@ -29,49 +29,6 @@
C.new.foo
}, '[ruby-core:14813]'
-assert_equal 'ok', %q{
- a = lambda {|x, y, &b| b }
- b = a.curry[1]
- if b.call(2){} == nil
- :ng
- else
- :ok
- end
-}, '[ruby-core:15551]'
-
-assert_normal_exit %q{
- g = Module.enum_for(:new)
- loop { g.next }
-}, '[ruby-dev:34128]'
-
-assert_normal_exit %q{
- Fiber.new(&Object.method(:class_eval)).resume("foo")
-}, '[ruby-dev:34128]'
-
-assert_normal_exit %q{
- Thread.new("foo", &Object.method(:class_eval)).join
-}, '[ruby-dev:34128]'
-
-assert_normal_exit %q{
- g = enum_for(:local_variables)
- loop { g.next }
-}, '[ruby-dev:34128]'
-
-assert_normal_exit %q{
- g = enum_for(:block_given?)
- loop { g.next }
-}, '[ruby-dev:34128]'
-
-assert_normal_exit %q{
- g = enum_for(:binding)
- loop { g.next }
-}, '[ruby-dev:34128]'
-
-assert_normal_exit %q{
- g = "abc".enum_for(:scan, /./)
- loop { g.next }
-}, '[ruby-dev:34128]'
-
assert_equal %q{[:bar, :foo]}, %q{
def foo
klass = Class.new do
@@ -84,24 +41,3 @@
foo
}, "[ ruby-Bugs-19304 ]"
-assert_equal 'ok', %q{
- lambda {
- break :ok
- :ng
- }.call
-}, '[ruby-dev:34646]'
-
-assert_normal_exit %q{
- eval("", method(:proc).call {}.binding)
-}
-
-assert_normal_exit %q{
- a = []
- 100.times {|i| a << i << nil << nil }
- p a.compact!
-}
-
-assert_equal 'ok', %q{
- a = [false]
- (a[0] &&= true) == false ? :ok : :ng
-}, '[ruby-dev:34679]'
Index: vm_evalbody.c
===================================================================
--- vm_evalbody.c (revision 17083)
+++ vm_evalbody.c (revision 17084)
@@ -131,7 +131,7 @@
}
}
- if (VM_FRAME_TYPE(th->cfp) != FRAME_MAGIC_FINISH) {
+ if (VM_FRAME_TYPE(th->cfp) != VM_FRAME_MAGIC_FINISH) {
rb_bug("cfp consistency error");
}
Index: vm.c
===================================================================
--- vm.c (revision 17083)
+++ vm.c (revision 17084)
@@ -52,7 +52,7 @@
static inline VALUE
rb_vm_set_finish_env(rb_thread_t * th)
{
- vm_push_frame(th, 0, FRAME_MAGIC_FINISH,
+ vm_push_frame(th, 0, VM_FRAME_MAGIC_FINISH,
Qnil, th->cfp->lfp[0], 0,
th->cfp->sp, 0, 1);
th->cfp->pc = (VALUE *)&finish_insn_seq[0];
@@ -72,7 +72,7 @@
/* for return */
rb_vm_set_finish_env(th);
- vm_push_frame(th, iseq, FRAME_MAGIC_TOP,
+ vm_push_frame(th, iseq, VM_FRAME_MAGIC_TOP,
th->top_self, 0, iseq->iseq_encoded,
th->cfp->sp, 0, iseq->local_size);
}
@@ -86,7 +86,7 @@
/* for return */
rb_vm_set_finish_env(th);
- vm_push_frame(th, iseq, FRAME_MAGIC_EVAL, block->self,
+ vm_push_frame(th, iseq, VM_FRAME_MAGIC_EVAL, block->self,
GC_GUARDED_PTR(block->dfp), iseq->iseq_encoded,
th->cfp->sp, block->lfp, iseq->local_size);
@@ -95,13 +95,35 @@
}
}
+static rb_control_frame_t *
+vm_get_ruby_level_next_cfp(rb_thread_t *th, rb_control_frame_t *cfp)
+{
+ while (!RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp)) {
+ if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
+ return cfp;
+ }
+ cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
+ }
+ return 0;
+}
+
rb_control_frame_t *
-vm_get_ruby_level_cfp(rb_thread_t *th, rb_control_frame_t *cfp)
+vm_get_ruby_level_caller_cfp(rb_thread_t *th, rb_control_frame_t *cfp)
{
+ if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
+ return cfp;
+ }
+
+ cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
+
while (!RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp)) {
if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
return cfp;
}
+
+ if ((cfp->flag & VM_FRAME_FLAG_PASSED) == 0) {
+ break;
+ }
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
}
return 0;
@@ -322,7 +344,7 @@
{
VALUE envval;
- if (VM_FRAME_FLAG(cfp->flag) == FRAME_MAGIC_FINISH) {
+ if (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_FINISH) {
/* for method_missing */
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
}
@@ -340,7 +362,7 @@
vm_stack_to_heap(rb_thread_t * const th)
{
rb_control_frame_t *cfp = th->cfp;
- while ((cfp = vm_get_ruby_level_cfp(th, cfp)) != 0) {
+ while ((cfp = vm_get_ruby_level_next_cfp(th, cfp)) != 0) {
vm_make_env_object(th, cfp);
cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
}
@@ -423,7 +445,8 @@
const rb_iseq_t *iseq = block->iseq;
const rb_control_frame_t *cfp = th->cfp;
int i, opt_pc, arg_size = iseq->arg_size;
- int type = block_proc_is_lambda(block->proc) ? FRAME_MAGIC_LAMBDA : FRAME_MAGIC_BLOCK;
+ int type = block_proc_is_lambda(block->proc) ?
+ VM_FRAME_MAGIC_LAMBDA : VM_FRAME_MAGIC_BLOCK;
rb_vm_set_finish_env(th);
@@ -434,7 +457,7 @@
}
opt_pc = vm_yield_setup_args(th, iseq, argc, cfp->sp, blockptr,
- type == FRAME_MAGIC_LAMBDA);
+ type == VM_FRAME_MAGIC_LAMBDA);
vm_push_frame(th, iseq, type,
self, GC_GUARDED_PTR(block->dfp),
@@ -521,22 +544,30 @@
/* special variable */
-static VALUE
-vm_cfp_svar_get(rb_thread_t *th, rb_control_frame_t *cfp, VALUE key)
+static rb_control_frame_t *
+vm_normal_frame(rb_thread_t *th, rb_control_frame_t *cfp)
{
while (cfp->pc == 0) {
- cfp++;
+ cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
+ if (RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp)) {
+ return 0;
+ }
}
- return lfp_svar_get(th, cfp->lfp, key);
+ return cfp;
}
+static VALUE
+vm_cfp_svar_get(rb_thread_t *th, rb_control_frame_t *cfp, VALUE key)
+{
+ cfp = vm_normal_frame(th, cfp);
+ return lfp_svar_get(th, cfp ? cfp->lfp : 0, key);
+}
+
static void
vm_cfp_svar_set(rb_thread_t *th, rb_control_frame_t *cfp, VALUE key, const VALUE val)
{
- while (cfp->pc == 0) {
- cfp++;
- }
- lfp_svar_set(th, cfp->lfp, key, val);
+ cfp = vm_normal_frame(th, cfp);
+ lfp_svar_set(th, cfp ? cfp->lfp : 0, key, val);
}
static VALUE
@@ -663,7 +694,7 @@
rb_sourcefile(void)
{
rb_thread_t *th = GET_THREAD();
- rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
+ rb_control_frame_t *cfp = vm_get_ruby_level_next_cfp(th, th->cfp);
if (cfp) {
return RSTRING_PTR(cfp->iseq->filename);
@@ -677,7 +708,7 @@
rb_sourceline(void)
{
rb_thread_t *th = GET_THREAD();
- rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
+ rb_control_frame_t *cfp = vm_get_ruby_level_next_cfp(th, th->cfp);
if (cfp) {
return vm_get_sourceline(cfp);
@@ -691,7 +722,7 @@
vm_cref(void)
{
rb_thread_t *th = GET_THREAD();
- rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
+ rb_control_frame_t *cfp = vm_get_ruby_level_next_cfp(th, th->cfp);
return vm_get_cref(cfp->iseq, cfp->lfp, cfp->dfp);
}
@@ -710,12 +741,15 @@
static NODE *
vm_cref_push(rb_thread_t *th, VALUE klass, int noex)
{
+ rb_control_frame_t *cfp = vm_get_ruby_level_caller_cfp(th, th->cfp);
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 = vm_get_cref(cfp->iseq, cfp->lfp, cfp->dfp);
cref->nd_visi = noex;
+
+ if (cfp) {
+ cref->nd_next = vm_get_cref(cfp->iseq, cfp->lfp, cfp->dfp);
+ }
+
return cref;
}
@@ -739,7 +773,8 @@
rb_vm_cbase(void)
{
rb_thread_t *th = GET_THREAD();
- rb_control_frame_t *cfp = vm_get_ruby_level_cfp(th, th->cfp);
+ rb_control_frame_t *cfp = vm_get_ruby_level_next_cfp(th, th->cfp);
+
return vm_get_cbase(cfp->iseq, cfp->lfp, cfp->dfp);
}
@@ -1183,7 +1218,7 @@
/* push block frame */
cfp->sp[0] = err;
- vm_push_frame(th, catch_iseq, FRAME_MAGIC_BLOCK,
+ vm_push_frame(th, catch_iseq, VM_FRAME_MAGIC_BLOCK,
cfp->self, (VALUE)cfp->dfp, catch_iseq->iseq_encoded,
cfp->sp + 1 /* push value */, cfp->lfp, catch_iseq->local_size - 1);
@@ -1297,7 +1332,7 @@
volatile VALUE iseqval = rb_iseq_new(0, filename, filename, 0, ISEQ_TYPE_TOP);
VALUE val;
- vm_push_frame(th, DATA_PTR(iseqval), FRAME_MAGIC_TOP,
+ vm_push_frame(th, DATA_PTR(iseqval), VM_FRAME_MAGIC_TOP,
recv, (VALUE)blockptr, 0, reg_cfp->sp, 0, 1);
val = (*func)(arg);
@@ -1306,14 +1341,6 @@
return val;
}
-int
-rb_vm_cfunc_funcall_p(const rb_control_frame_t *cfp)
-{
- if (vm_cfunc_flags(cfp) & (VM_CALL_FCALL_BIT | VM_CALL_VCALL_BIT))
- return Qtrue;
- return Qfalse;
-}
-
/* vm */
static void
@@ -1548,7 +1575,7 @@
th->cfp = (void *)(th->stack + th->stack_size);
- vm_push_frame(th, 0, FRAME_MAGIC_TOP, Qnil, 0, 0,
+ vm_push_frame(th, 0, VM_FRAME_MAGIC_TOP, Qnil, 0, 0,
th->stack, 0, 1);
th->status = THREAD_RUNNABLE;
Index: vm.h
===================================================================
--- vm.h (revision 17083)
+++ vm.h (revision 17084)
@@ -219,27 +219,6 @@
(!((th)->stack < (env) && (env) < ((th)->stack + (th)->stack_size)))
#define ENV_VAL(env) ((env)[1])
-#define FRAME_MAGIC_METHOD 0x11
-#define FRAME_MAGIC_BLOCK 0x21
-#define FRAME_MAGIC_CLASS 0x31
-#define FRAME_MAGIC_TOP 0x41
-#define FRAME_MAGIC_FINISH 0x51
-#define FRAME_MAGIC_CFUNC 0x61
-#define FRAME_MAGIC_PROC 0x71
-#define FRAME_MAGIC_IFUNC 0x81
-#define FRAME_MAGIC_EVAL 0x91
-#define FRAME_MAGIC_LAMBDA 0xa1
-#define FRAME_MAGIC_MASK_BITS 8
-#define FRAME_MAGIC_MASK (~(~0<<FRAME_MAGIC_MASK_BITS))
-
-#define VM_FRAME_FLAG(type) ((VALUE)((type) & FRAME_MAGIC_MASK))
-
-#define VM_FRAME_TYPE(cfp) \
- ((cfp)->flag & FRAME_MAGIC_MASK)
-
-#define RUBYVM_CFUNC_FRAME_P(cfp) \
- (VM_FRAME_TYPE(cfp) == FRAME_MAGIC_CFUNC)
-
#if OPT_CALL_THREADED_CODE
#define THROW_EXCEPTION(exc) do { \
th->errinfo = (VALUE)(exc); \
Index: vm_dump.c
===================================================================
--- vm_dump.c (revision 17083)
+++ vm_dump.c (revision 17084)
@@ -46,34 +46,34 @@
}
switch (VM_FRAME_TYPE(cfp)) {
- case FRAME_MAGIC_TOP:
+ case VM_FRAME_MAGIC_TOP:
magic = "TOP";
break;
- case FRAME_MAGIC_METHOD:
+ case VM_FRAME_MAGIC_METHOD:
magic = "METHOD";
break;
- case FRAME_MAGIC_CLASS:
+ case VM_FRAME_MAGIC_CLASS:
magic = "CLASS";
break;
- case FRAME_MAGIC_BLOCK:
+ case VM_FRAME_MAGIC_BLOCK:
magic = "BLOCK";
break;
- case FRAME_MAGIC_FINISH:
+ case VM_FRAME_MAGIC_FINISH:
magic = "FINISH";
break;
- case FRAME_MAGIC_CFUNC:
+ case VM_FRAME_MAGIC_CFUNC:
magic = "CFUNC";
break;
- case FRAME_MAGIC_PROC:
+ case VM_FRAME_MAGIC_PROC:
magic = "PROC";
break;
- case FRAME_MAGIC_LAMBDA:
+ case VM_FRAME_MAGIC_LAMBDA:
magic = "LAMBDA";
break;
- case FRAME_MAGIC_IFUNC:
+ case VM_FRAME_MAGIC_IFUNC:
magic = "IFUNC";
break;
- case FRAME_MAGIC_EVAL:
+ case VM_FRAME_MAGIC_EVAL:
magic = "EVAL";
break;
case 0:
@@ -271,15 +271,15 @@
/* stack trace header */
- if (VM_FRAME_TYPE(cfp) == FRAME_MAGIC_METHOD ||
- VM_FRAME_TYPE(cfp) == FRAME_MAGIC_TOP ||
- VM_FRAME_TYPE(cfp) == FRAME_MAGIC_BLOCK ||
- VM_FRAME_TYPE(cfp) == FRAME_MAGIC_CLASS ||
- VM_FRAME_TYPE(cfp) == FRAME_MAGIC_PROC ||
- VM_FRAME_TYPE(cfp) == FRAME_MAGIC_LAMBDA ||
- VM_FRAME_TYPE(cfp) == FRAME_MAGIC_CFUNC ||
- VM_FRAME_TYPE(cfp) == FRAME_MAGIC_IFUNC ||
- VM_FRAME_TYPE(cfp) == FRAME_MAGIC_EVAL) {
+ if (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_METHOD ||
+ VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_TOP ||
+ VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_BLOCK ||
+ VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_CLASS ||
+ VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_PROC ||
+ VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_LAMBDA ||
+ VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_CFUNC ||
+ VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_IFUNC ||
+ VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_EVAL) {
VALUE *ptr = dfp - local_size;
@@ -312,7 +312,7 @@
ptr - th->stack);
}
}
- else if (VM_FRAME_TYPE(cfp) == FRAME_MAGIC_FINISH) {
+ else if (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_FINISH) {
if ((th)->stack + (th)->stack_size > (VALUE *)(cfp + 2)) {
stack_dump_each(th, cfp + 1);
}
@@ -362,7 +362,7 @@
{
rb_iseq_t *iseq = cfp->iseq;
- if (iseq != 0 && VM_FRAME_TYPE(cfp) != FRAME_MAGIC_FINISH) {
+ if (iseq != 0 && VM_FRAME_TYPE(cfp) != VM_FRAME_MAGIC_FINISH) {
VALUE *seq = iseq->iseq;
int pc = cfp->pc - iseq->iseq_encoded;
Index: vm_insnhelper.c
===================================================================
--- vm_insnhelper.c (revision 17083)
+++ vm_insnhelper.c (revision 17084)
@@ -367,7 +367,7 @@
EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, recv, id, klass);
{
rb_control_frame_t *cfp =
- vm_push_frame(th, 0, FRAME_MAGIC_CFUNC | (flag << FRAME_MAGIC_MASK_BITS),
+ vm_push_frame(th, 0, VM_FRAME_MAGIC_CFUNC,
recv, (VALUE) blockptr, 0, reg_cfp->sp, 0, 1);
cfp->method_id = id;
@@ -380,6 +380,7 @@
if (reg_cfp != th->cfp + 1) {
rb_bug("cfp consistency error - send");
}
+
vm_pop_frame(th);
}
EXEC_EVENT_HOOK(th, RUBY_EVENT_C_RETURN, recv, id, klass);
@@ -387,14 +388,6 @@
return val;
}
-static inline int
-vm_cfunc_flags(const rb_control_frame_t *cfp)
-{
- if (RUBYVM_CFUNC_FRAME_P(cfp))
- return cfp->flag >> FRAME_MAGIC_MASK_BITS;
- return 0;
-}
-
static inline VALUE
vm_call_bmethod(rb_thread_t *th, ID id, VALUE procval, VALUE recv,
VALUE klass, int argc, VALUE *argv, rb_block_t *blockptr)
@@ -455,7 +448,7 @@
}
vm_push_frame(th, iseq,
- FRAME_MAGIC_METHOD, recv, (VALUE) blockptr,
+ VM_FRAME_MAGIC_METHOD, recv, (VALUE) blockptr,
iseq->iseq_encoded + opt_pc, sp, 0, 0);
cfp->sp = rsp - 1 /* recv */;
@@ -478,7 +471,7 @@
}
vm_push_frame(th, iseq,
- FRAME_MAGIC_METHOD, recv, (VALUE) blockptr,
+ VM_FRAME_MAGIC_METHOD, recv, (VALUE) blockptr,
iseq->iseq_encoded + opt_pc, sp, 0, 0);
}
}
@@ -675,7 +668,7 @@
blockarg = Qnil;
}
- vm_push_frame(th, 0, FRAME_MAGIC_IFUNC,
+ vm_push_frame(th, 0, VM_FRAME_MAGIC_IFUNC,
self, (VALUE)block->dfp,
0, th->cfp->sp, block->lfp, 1);
@@ -831,7 +824,7 @@
block_proc_is_lambda(block->proc));
vm_push_frame(th, iseq,
- FRAME_MAGIC_BLOCK, block->self, (VALUE) block->dfp,
+ VM_FRAME_MAGIC_BLOCK, block->self, (VALUE) block->dfp,
iseq->iseq_encoded + opt_pc, rsp + arg_size, block->lfp,
iseq->local_size - arg_size);
@@ -849,23 +842,18 @@
static inline NODE *
lfp_svar_place(rb_thread_t *th, VALUE *lfp)
{
- NODE *svar;
+ VALUE *svar;
- if (th->local_lfp != lfp) {
- svar = (NODE *)lfp[-1];
- if ((VALUE)svar == Qnil) {
- svar = NEW_IF(Qnil, Qnil, Qnil);
- lfp[-1] = (VALUE)svar;
- }
+ if (lfp && th->local_lfp != lfp) {
+ svar = &lfp[-1];
}
else {
- svar = (NODE *)th->local_svar;
- if ((VALUE)svar == Qnil) {
- svar = NEW_IF(Qnil, Qnil, Qnil);
- th->local_svar = (VALUE)svar;
- }
+ svar = &th->local_svar;
}
- return svar;
+ if (NIL_P(*svar)) {
+ *svar = (VALUE)NEW_IF(Qnil, Qnil, Qnil);
+ }
+ return (NODE *)*svar;
}
static VALUE
@@ -1238,7 +1226,7 @@
rb_bug("VM (throw): can't find break base.");
}
- if (VM_FRAME_TYPE(cfp) == FRAME_MAGIC_LAMBDA) {
+ if (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_LAMBDA) {
/* lambda{... break ...} */
is_orphan = 0;
pt = GET_LFP();
@@ -1297,7 +1285,7 @@
*/
while ((VALUE *) cfp < th->stack + th->stack_size) {
if (GET_DFP() == dfp) {
- if (VM_FRAME_TYPE(cfp) == FRAME_MAGIC_LAMBDA) {
+ if (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_LAMBDA) {
/* in lambda */
is_orphan = 0;
break;
--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/