[Bug #1150] calling instance_eval in extended library cause exception

Bug #1150: calling instance_eval in extended library cause exception
http://redmine.ruby-lang.org/issues/show/1150

e$B5/I<<Te(B: Akio T.
e$B%9%F!<%?%9e(B: Open, e$BM%@hEYe(B: Normal
Target version: 1.9.1
ruby -v: ruby 1.9.1p0 (2009-01-30 revision 21907) [i386-mswin32]

e$B3HD%%i%$%V%i%jFb$N%a%=%C%I$Ge(Binstance_evale$B$r8F$S=P$9$H!"e(BCan’t
eval on top of Fiber or Thread (RuntimeError)e$B$K$J$j$^$9!#e(B
e$B:F8=%3!<%I$r0J2<$K<($7$^$9!#e(B
// cmodev.c
#include “ruby.h”
#include “extconf.h”
static VALUE cmodev;
static VALUE xtest_func(VALUE self, VALUE s)
{
return rb_funcall2(self, rb_intern(“instance_eval”), 1, &s);
}
void Init_cmodev()
{
cmodev = rb_define_class(“XTest”, rb_cObject);
rb_define_method(cmodev, “xtest”, xtest_func, 1);
}

#t.rb
require ‘cmodev’
x = XTest.new
x.xtest(“puts ‘hello’”)

e$B<B9TNce(B
c:\test\modev\test>ruby t.rb
t.rb:3:in instance_eval': Can't eval on top of Fiber or Thread (RuntimeError) from t.rb:3:in xtest’
from t.rb:3:in `’

e$B!!$5$5$@$G$9!%e(B

Akio T. wrote::

e$B3HD%%i%$%V%i%jFb$N%a%=%C%I$Ge(Binstance_evale$B$r8F$S=P$9$H!"e(BCan’t eval on top of Fiber or Thread (RuntimeError)e$B$K$J$j$^$9!#e(B

e$B!!$4;XE&$"$j$,$H$&$4$6$$$^$9!%%P%0$G$7$?!%e(B

Index: vm_core.h

— vm_core.h (e$B%j%S%8%g%se(B 22272)
+++ vm_core.h (e$B:n6H%3%T!<e(B)
@@ -593,10 +593,14 @@ int ruby_thread_has_gvl_p(void);
VALUE rb_make_backtrace(void);
typedef int rb_backtrace_iter_func(void *, const char *, int, const
char *);
VALUE rb_backtrace_each(rb_backtrace_iter_func *iter, void *arg);
+rb_control_frame_t *rb_vm_get_ruby_level_next_cfp(rb_thread_t *th,
rb_control_frame_t *cfp);

NOINLINE(void rb_gc_save_machine_context(rb_thread_t *));

Index: vm_eval.c

— vm_eval.c (e$B%j%S%8%g%se(B 22272)
+++ vm_eval.c (e$B:n6H%3%T!<e(B)
@@ -706,7 +706,7 @@ eval_string_with_cref(VALUE self, VALUE
th->base_block = &env->block;
}
else {

  •  rb_control_frame_t *cfp = vm_get_ruby_level_caller_cfp(th, 
    

th->cfp);

  •  rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, 
    

th->cfp);

   if (cfp != 0) {
 block = *RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp);

Index: proc.c

— proc.c (e$B%j%S%8%g%se(B 22272)
+++ proc.c (e$B:n6H%3%T!<e(B)
@@ -274,8 +274,6 @@ binding_clone(VALUE self)
return bindval;
}

-rb_control_frame_t *rb_vm_get_ruby_level_next_cfp(rb_thread_t *th,
rb_control_frame_t *cfp);

VALUE
rb_binding_new(void)
{

e$B!!$A$J$_$K!$K\Ev$Ke(B eval e$B$,$d$j$?$$$s$G$9$+$M!%e(Bbinding
e$B$r9M$($J$1$l$P!$e(B

rb_iseq_eval(rb_iseq_compile(VALUE src, VALUE file, VALUE line))

e$B$J$s$F<j$,$"$j$^$9!%$,!$$^$@$3$l$ON"5;!Je(Bintern.h
e$B$K$J$$$H$$$&0UL#!K$@e(B
e$B$J!%e(B1.9.2 e$B$^$G$K@0M}$7$h$&!%$3$l$r$$$C$Z$s$K$d$ke(B API
e$B$b$[$7$$$s$G$9$,!$e(B
e$BL>A0$,7h$a$i$l$J$/$F!%e(B