Patch for ruby-dev:34236

e$B%o%J%Y$H?=$7$^$9!#e(B

[ruby-dev:34236]e$B$KBP$9$k%Q%C%A$r=q$-$^$7$?!#e(B
Proc e$B%*%V%8%’%/%H$N:n@.$5$l$?0LCV$HL54X78$Ke(B
module_eval e$BCf$G$N%a%=%C%IDj5A$,$G$-$k$h$&$K$J$j$^$9!#e(B

Index: eval.c

— eval.c (revision 16056)
+++ eval.c (working copy)
@@ -1832,6 +1832,7 @@
rb_control_frame_t *pcfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
VALUE stored_self = pcfp->self;
NODE *stored_cref = 0;

  • VALUE stored_cref_stack = INT2FIX(0);

    rb_block_t block;
    rb_block_t blockptr;
    @@ -1844,6 +1845,10 @@
    /
    TODO: why? */
    block = *blockptr;
    block.self = self;

  • if (BUILTIN_TYPE(block.iseq) != T_NODE) {

  •  stored_cref_stack = (VALUE)block.iseq->cref_stack;
    
  •  block.iseq->cref_stack = vm_cref_push(th, under, NOEX_PUBLIC);
    
  • }
    *th->cfp->lfp = GC_GUARDED_PTR(&block);
    }

@@ -1863,6 +1868,9 @@
/* restore environment */
vm_cfp_svar_set(th, cfp, 2, (VALUE)stored_cref);
pcfp->self = stored_self;

  • if (stored_cref_stack != INT2FIX(0)) {

  • block.iseq->cref_stack = (NODE*)stored_cref_stack;

  • }

    if (state) {
    JUMP_TAG(state);

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

wanabe wrote:

[ruby-dev:34236]e$B$KBP$9$k%Q%C%A$r=q$-$^$7$?!#e(B
Proc e$B%*%V%8%’%/%H$N:n@.$5$l$?0LCV$HL54X78$Ke(B
module_eval e$BCf$G$N%a%=%C%IDj5A$,$G$-$k$h$&$K$J$j$^$9!#e(B

e$B!!$3$l!$$Q$C$HNc$,=P$J$$$s$G$9$,!$K\Ev$KBg>fIW$G$7$g$&$+!%e(Biseq
e$B$KBPe(B
e$B$9$k%"%/%;%9$J$N$G!$I{:nMQ$,!%e(B

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:34466] Re: patch for ruby-dev:34236”
on Mon, 21 Apr 2008 09:57:26 +0900, SASADA Koichi [email protected]
writes:

|wanabe wrote:
|> [ruby-dev:34236]e$B$KBP$9$k%Q%C%A$r=q$-$^$7$?!#e(B
|> Proc e$B%*%V%8%'%/%H$N:n@.$5$l$?0LCV$HL54X78$Ke(B
|> module_eval e$BCf$G$N%a%=%C%IDj5A$,$G$-$k$h$&$K$J$j$^$9!#e(B
|
|e$B!!$3$l!$$Q$C$HNc$,=P$J$$$s$G$9$,!$K\Ev$KBg>fIW$G$7$g$&$+!%e(Biseq e$B$KBPe(B
|e$B$9$k%"%/%;%9$J$N$G!$I{:nMQ$,!%e(B

(e$B$$$k$H$9$k$J$i$Pe(B)e$B$5$5$@$/$s0J30$K!VK\Ev$KBg>fIW$+!WJ,$+$k?Me(B
e$B$O$$$J$$$H$*$b$$$^$9$h!#$H$j$"$($:<h$j9~$s$G$$$m$$$m;n$9$7$+e(B
e$B$J$$$s$8$c$J$$$G$9$+$M!#e(B

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

Yukihiro M. wrote:

(e$B$$$k$H$9$k$J$i$Pe(B)e$B$5$5$@$/$s0J30$K!VK\Ev$KBg>fIW$+!WJ,$+$k?Me(B
e$B$O$$$J$$$H$*$b$$$^$9$h!#$H$j$"$($:<h$j9~$s$G$$$m$$$m;n$9$7$+e(B
e$B$J$$$s$8$c$J$$$G$9$+$M!#e(B

e$B!!$3$NLdBj$O0JA0$+$i9M$($F$$$k$N$G$9$,!$!J;d$K$O!KFq$7$$$N$G!$!VK\Eve(B
e$B$KBg>fIW$+!W$b4^$a$F>/$79M$($5$;$F2<$5$$!%e(B

e$B!!:,K\E*$K!$e(Biseq e$B$,e(B mutable
e$B$H$$$&E@$,%,%s$J$N$G!$$=$NE@$r2r>C$7$h$&e(B
e$B$H;W$&$s$G$9$,!$$^$@<j$,DI$$$D$$$F$$$J$$$H$3$m$G$9!%?’!9$HCY$/$F$9$_e(B
e$B$^$;$s!%e(B

e$B!!e(B[ruby-core:14726]
e$B$H$+$=$NJU$J$s$G$9$,!$$C$F$b$&e(B1e$B7n$+e(B orz

e$B1sF#$H?=$7$^$9!#e(B

2008/04/21 9:57 SASADA Koichi [email protected]:

wanabe wrote:

[ruby-dev:34236]e$B$KBP$9$k%Q%C%A$r=q$-$^$7$?!#e(B
Proc e$B%*%V%8%'%/%H$N:n@.$5$l$?0LCV$HL54X78$Ke(B
module_eval e$BCf$G$N%a%=%C%IDj5A$,$G$-$k$h$&$K$J$j$^$9!#e(B

e$B!!$3$l!$$Q$C$HNc$,=P$J$$$s$G$9$,!$K\Ev$KBg>fIW$G$7$g$&$+!%e(Biseq e$B$KBPe(B
e$B$9$k%"%/%;%9$J$N$G!$I{:nMQ$,!%e(B

e$B$3$s$J46$8$N%3!<%I$G5sF0$,JQ$o$j$^$9$M!#e(B

$ cat test.rb
class Module
def my_module_eval(&block)
module_eval(&block)
end
end

$b = proc do |f|
if f
$b.call(nil)
else
def foo
p :foo
end
end
end

class A
end
class B
A.my_module_eval(&$b)
end

foo

1.8

$ ruby test.rb
:foo

[ruby-dev:34460] e$B$N%Q%C%AA0e(B

$ ./ruby.org test.rb
:foo

[ruby-dev:34460] e$B$N%Q%C%A8ee(B

$ ./ruby.new test.rb
test.rb:23:in <main>': undefined local variable or method foo’ for
main:Object (NameError)

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

wanabe wrote:

iseq e$B$K?($i$:!"e(Brb_block_t e$B$Ke(B cref e$B$r;}$?$;$k$h$&$K=q$-D>$7$^$7$?!#e(B
e$B1sF#$5$s$N=q$+$l$?Nc$,F0:n$9$k$h$&$K$9$k$?$a!“e(B1.8e$B$HF1$8$h$&$Ke(B
instance_eval/module_eval e$B$N%V%m%C%/$K0z?te(B self e$B$rM?$($k$h$&$K$7$F$$$^$9!#e(B
e$B!Je(Byield_under(klass, self, rb_ary_new3(1, self))e$B$NItJ,!Ke(B
e$BLdBj$,$”$j$^$7$?$i$3$NItJ,$OL5;k$7$F$/$@$5$$!#e(B

e$B!!$$$D$b$"$j$,$H$&$4$6$$$^$9!%:#$^$5$K$3$NLdBj$K4X$7$F%G%P%C%0Cf$G$9!%e(B

e$B!!e(Bcref
e$B$r%U%l!<%`$4$H$K;}$?$J$$$N$O!$%l%"%1!<%9$N$?$a$KB>$rCY$/$9$ke(B
e$B$N$,7y$@$C$?$N$G!$:#$N$h$&$J$b$N$K$J$C$F$$$^$9!%=PMh$l$P!$$3$N$^$^$Ge(B
e$B:Q$^$;$k$3$H$,=PMh$J$$$+!$G:$s$G$$$^$9!%e(B

e$B!!$=$l$O$H$b$+$/!$<B$OLdBj$O$3$l0J30$K$b$$$/$D$+$"$k$H$$$&$3$H$,$oe(B
e$B$+$C$F$-$F$$$F!$8=:_$=$l$r4^$a$FD>$7J}$r9M$(Cf$G$9!%6qBNE*$K$O!$e(B1.8
e$B$Ne(B ruby_class e$B$He(B ruby_cref
e$B$rF10l;k$7$F$$$?$s$G$9$,!$<B$OF10l;k$7$Fe(B
e$B$O$$$1$J$+$C$?$H$+!$$=$s$JOC$G$9!%:#F|Cf$K$O!$$J$s$H$+$7$?$$$s$G$9$,!%e(B

e$B%o%J%Y$G$9!#e(B

08/04/21 e$B$Ke(B Yusuke ENDOH[email protected] e$B$5$s$O=q$-$^$7$?e(B:

2008/04/21 9:57 SASADA Koichi [email protected]:

e$B$3$l!$$Q$C$HNc$,=P$J$$$s$G$9$,!$K\Ev$KBg>fIW$G$7$g$&$+!%e(Biseq e$B$KBPe(B
e$B$9$k%"%/%;%9$J$N$G!$I{:nMQ$,!%e(B

e$B$3$s$J46$8$N%3!<%I$G5sF0$,JQ$o$j$^$9$M!#e(B

iseq e$B$K?($i$:!"e(Brb_block_t e$B$Ke(B cref
e$B$r;}$?$;$k$h$&$K=q$-D>$7$^$7$?!#e(B
e$B1sF#$5$s$N=q$+$l$?Nc$,F0:n$9$k$h$&$K$9$k$?$a!“e(B1.8e$B$HF1$8$h$&$Ke(B
instance_eval/module_eval e$B$N%V%m%C%/$K0z?te(B self
e$B$rM?$($k$h$&$K$7$F$$$^$9!#e(B
e$B!Je(Byield_under(klass, self, rb_ary_new3(1, self))e$B$NItJ,!Ke(B
e$BLdBj$,$”$j$^$7$?$i$3$NItJ,$OL5;k$7$F$/$@$5$$!#e(B

Index: vm_core.h

— vm_core.h (revision 16174)
+++ vm_core.h (working copy)
@@ -337,6 +337,7 @@
VALUE dfp; / share with method frame if it’s only block */
rb_iseq_t *iseq;
VALUE proc;

  • NODE *cref;
    } rb_block_t;

#define GetThreadPtr(obj, ptr)
Index: eval.c

— eval.c (revision 16174)
+++ eval.c (working copy)
@@ -1845,6 +1845,9 @@
block = *blockptr;
block.self = self;
*th->cfp->lfp = GC_GUARDED_PTR(&block);

  • stored_cref = block.cref;

  • block.cref = vm_cref_push(th, under, NOEX_PUBLIC);

  • block.cref->nd_file = stored_cref;
    }

    while (!RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
    @@ -1922,7 +1925,7 @@
    rb_raise(rb_eArgError, “wrong number of arguments (%d for 0)”,
    argc);
    }

  • return yield_under(klass, self, Qundef);
  • return yield_under(klass, self, rb_ary_new3(1, self));
    }
    else {
    char *file = “(eval)”;
    Index: vm.c
    ===================================================================
    — vm.c (revision 16174)
    +++ vm.c (working copy)
    @@ -261,6 +261,7 @@
    env->block.lfp = cfp->lfp;
    env->block.dfp = cfp->dfp;
    env->block.iseq = cfp->iseq;

  • env->block.cref = 0;

    if (VMDEBUG &&
    (!(cfp->lfp[-1] == Qnil ||
    @@ -388,6 +389,7 @@
    proc->block.lfp = block->lfp;
    proc->block.dfp = block->dfp;
    proc->block.iseq = block->iseq;

  • proc->block.cref = 0;
    proc->block.proc = procval;
    proc->envval = envval;
    proc->safe_level = th->safe_level;
    @@ -539,6 +541,8 @@
    return vm_call_super(GET_THREAD(), argc, argv);
    }

+void vm_cfp_svar_set(rb_thread_t *th, rb_control_frame_t cfp, VALUE
key, VALUE val);
+
/
C → Ruby: block */

static VALUE
@@ -568,6 +572,10 @@
self, GC_GUARDED_PTR(block->dfp),
iseq->iseq_encoded + opt_pc, cfp->sp + arg_size, block->lfp,
iseq->local_size - arg_size);

  • if (block->cref) {

  •  vm_cfp_svar_set(th, th->cfp, 2, (VALUE)block->cref);
    
  •  block->cref = block->cref->nd_file;
    
  • }

    val = vm_eval_body(th);
    }
    Index: vm_insnhelper.c
    ===================================================================
    — vm_insnhelper.c (revision 16174)
    +++ vm_insnhelper.c (working copy)
    @@ -233,6 +233,7 @@
    blockptr = RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp);
    blockptr->iseq = blockiseq;
    blockptr->proc = 0;

  •  blockptr->cref = 0;
     *block = blockptr;
    

    }
    }