summaryrefslogtreecommitdiff
path: root/vm.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-08-13 04:49:37 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-08-13 04:49:37 +0000
commitcc77f676f4a386479b6457e11993b9933412022c (patch)
tree6cb438610afcd10a76d579e9d36d0a217eade120 /vm.c
parenteaa1bcab351e3d5e835a69687aff8dbee007bb1d (diff)
* vm.c: rewind cfp to show proper backtrace.
[ruby-dev:35820] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@18554 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm.c')
-rw-r--r--vm.c98
1 files changed, 56 insertions, 42 deletions
diff --git a/vm.c b/vm.c
index b14b1cdd52..7759a2426e 100644
--- a/vm.c
+++ b/vm.c
@@ -1633,35 +1633,15 @@ rb_thread_alloc(VALUE klass)
return self;
}
-static VALUE
-m_core_set_method_alias(VALUE self, VALUE cbase, VALUE sym1, VALUE sym2)
-{
- rb_alias(cbase, SYM2ID(sym1), SYM2ID(sym2));
- return Qnil;
-}
-
-static VALUE
-m_core_set_variable_alias(VALUE self, VALUE sym1, VALUE sym2)
-{
- rb_alias_variable(SYM2ID(sym1), SYM2ID(sym2));
- return Qnil;
-}
-
-static VALUE
-m_core_undef_method(VALUE self, VALUE cbase, VALUE sym)
-{
- rb_undef(cbase, SYM2ID(sym));
- INC_VM_STATE_VERSION();
- return Qnil;
-}
-
static void
-vm_define_method(rb_thread_t *th, VALUE obj, ID id, rb_iseq_t *miseq,
+vm_define_method(rb_thread_t *th, VALUE obj, ID id, VALUE iseqval,
rb_num_t is_singleton, NODE *cref)
{
NODE *newbody;
VALUE klass = cref->nd_clss;
int noex = cref->nd_visi;
+ rb_iseq_t *miseq;
+ GetISeqPtr(iseqval, miseq);
if (NIL_P(klass)) {
rb_raise(rb_eTypeError, "no class/module to add method");
@@ -1695,43 +1675,77 @@ vm_define_method(rb_thread_t *th, VALUE obj, ID id, rb_iseq_t *miseq,
INC_VM_STATE_VERSION();
}
+#define REWIND_CFP(expr) do { \
+ rb_thread_t *th__ = GET_THREAD(); \
+ th__->cfp++; (expr); th__->cfp--; \
+} while (0)
+
static VALUE
m_core_define_method(VALUE self, VALUE cbase, VALUE sym, VALUE iseqval)
{
- rb_iseq_t *iseq;
- GetISeqPtr(iseqval, iseq);
- vm_define_method(GET_THREAD(), cbase, SYM2ID(sym), iseq, 0, vm_cref());
+ REWIND_CFP({
+ vm_define_method(GET_THREAD(), cbase, SYM2ID(sym), iseqval, 0, vm_cref());
+ });
return Qnil;
}
static VALUE
m_core_define_singleton_method(VALUE self, VALUE cbase, VALUE sym, VALUE iseqval)
{
- rb_iseq_t *iseq;
- GetISeqPtr(iseqval, iseq);
- vm_define_method(GET_THREAD(), cbase, SYM2ID(sym), iseq, 1, vm_cref());
+ REWIND_CFP({
+ vm_define_method(GET_THREAD(), cbase, SYM2ID(sym), iseqval, 1, vm_cref());
+ });
return Qnil;
}
static VALUE
-m_core_set_postexe(VALUE self, VALUE iseqval)
+m_core_set_method_alias(VALUE self, VALUE cbase, VALUE sym1, VALUE sym2)
{
- rb_iseq_t *blockiseq;
- rb_block_t *blockptr;
- rb_thread_t *th = GET_THREAD();
- rb_control_frame_t *cfp = vm_get_ruby_level_next_cfp(th, th->cfp);
- VALUE proc;
- extern void rb_call_end_proc(VALUE data);
+ REWIND_CFP({
+ rb_alias(cbase, SYM2ID(sym1), SYM2ID(sym2));
+ });
+ return Qnil;
+}
- GetISeqPtr(iseqval, blockiseq);
+static VALUE
+m_core_set_variable_alias(VALUE self, VALUE sym1, VALUE sym2)
+{
+ REWIND_CFP({
+ rb_alias_variable(SYM2ID(sym1), SYM2ID(sym2));
+ });
+ return Qnil;
+}
+
+static VALUE
+m_core_undef_method(VALUE self, VALUE cbase, VALUE sym)
+{
+ REWIND_CFP({
+ rb_undef(cbase, SYM2ID(sym));
+ INC_VM_STATE_VERSION();
+ });
+ return Qnil;
+}
+
+static VALUE
+m_core_set_postexe(VALUE self, VALUE iseqval)
+{
+ REWIND_CFP({
+ rb_iseq_t *blockiseq;
+ rb_block_t *blockptr;
+ rb_thread_t *th = GET_THREAD();
+ rb_control_frame_t *cfp = vm_get_ruby_level_next_cfp(th, th->cfp);
+ VALUE proc;
+ extern void rb_call_end_proc(VALUE data);
- blockptr = RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp);
- blockptr->iseq = blockiseq;
- blockptr->proc = 0;
+ GetISeqPtr(iseqval, blockiseq);
- proc = vm_make_proc(th, cfp, blockptr);
- rb_set_end_proc(rb_call_end_proc, proc);
+ blockptr = RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp);
+ blockptr->iseq = blockiseq;
+ blockptr->proc = 0;
+ proc = vm_make_proc(th, cfp, blockptr);
+ rb_set_end_proc(rb_call_end_proc, proc);
+ });
return Qnil;
}