# \[Bug #3141\] yield in an eigenclass definition

**URL:** <https://www.ruby-forum.com/t/bug-3141-yield-in-an-eigenclass-definition/186863>\
**Category:** Development\
**Created:** [April 13, 2010, 3:48pm UTC](https://www.ruby-forum.com/t/bug-3141-yield-in-an-eigenclass-definition/186863 "2010-04-13T15:48:56Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Yusuke\_E](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/f08c70/32.png) [@Yusuke\_E](https://www.ruby-forum.com/u/Yusuke_E)\
**Post date:** [April 13, 2010, 3:48pm UTC](https://www.ruby-forum.com/t/bug-3141-yield-in-an-eigenclass-definition/186863/1 "2010-04-13T15:48:56Z")

</div>

Bug #3141: yield in an eigenclass definition  
[http://redmine.ruby-lang.org/issues/show/3141](http://redmine.ruby-lang.org/issues/show/3141)

e$B5/I\<\<Te(B: Yusuke E.  
e$B%9%F!\<%?%9e(B: Open, e$BM%@hEYe(B: Normal  
e$BC4Ev\<Te(B: Yusuke E., e$B%+%F%4%je(B: core, Target version: 1.9.2  
ruby -v: ruby 1.9.2dev (2010-04-13 trunk 27329) [i686-linux]

e$B$5$5$@$5$se(B  
e$B1sF#$G$9!#e(B

#1018 e$B$K4XO"$7$^$9$,!"FC0[%/%i%9Dj5A$NCf$Ge(B yield  
e$B$,$G$-$^$;$s!#e(B

class Object  
def yield\_eigenclass  
class \<\< self  
yield self  
end  
end  
end

Object.yield\_eigenclass {|c| p c }

$ ruby19 t.rb  
t.rb:4: Invalid yield  
t.rb: compile error (SyntaxError)

e$BD4$Y$F$$$FCN$C$?$N$G$9$,!"e(Bdfp[0] e$B$K$Oe(B

- ISEQ\_TYPE\_METHOD, \_CFUNC, \_FINISH, \_TOP e$B$N\>l9g$Oe(B rb\_block\_t\*
- e$B$=$l0J30$N\>l9g$OA0$N%U%l!\<%`$Ne(B dfp (vm\_throw e$B$G;H$&e(B)

e$B$,F~$C$F$$$k$s$G$9$Me(B (e$B$J$s$H$$$&e(B dirty hack e$B!D!De(B)  
e$B!#e(B  
vm\_push\_frame e$B$Ne(B 5 e$BHVL$N0z?te(B (specval)  
e$B$KEO$5$l$kCM$O$:$C$HFfe(B  
e$B$G$7$?!#e(B

ISEQ\_TYPE\_CLASS e$B$Ne(B dfp[0] e$B$K$OA0$N%U%l!\<%`$Ne(B dfp  
e$B$,F~$C$F$$$^$9!#e(B  
(e$B%V%m%C%/$X$N%]%$%s%?$H6hJL$G$-$k$h$&!“2\<$+$ie(B 2  
e$B%S%C%HL$rN)$F$Fe(B  
e$B$\*$/$H$$$&!”$5$i$J$ke(B dirty hack (RUBY\_VM\_CLASS\_SPECIAL\_P)  
e$B$r8+$Fe(B  
e$BL$,$D$V$l$^$7$?e(B)

e$B0lJ}$G!“e(BISEQ\_TYPE\_CLASS  
e$B0J2\<$NJ8L.$+$i$O%V%m%C%/$X$N;2\>H$,$J$$e(B  
e$B\>uBV$K$J$C$F$$$k$H;W$$$^$7$?!#$3$3$^$G!”\>-Mh$N\<+J,$N$?$a$N%a%b!#e(B

e$B$=$3$G!"e(BISEQ\_TYPE\_CLASS e$B$Ne(B dfp[0] e$B$K$be(B rb\_block\_t\*  
e$B$rF~$l$k$3$H$Ke(B  
e$B$7$^$;$s$+!#e(B

e$B%a%j%C%He(B:  
- e$B\>e5-$N%3!\<%I$,F0$/e(B  
- RUBY\_VM\_CLASS\_SPECIAL\_P e$B$Ne(B dirty hack e$B$,ITMW$K$J$ke(B

e$B%G%a%j%C%He(B:  
- vm\_throw e$B$GJ,4t$,A}$($k\>l9g$,$"$ke(B

e$B%G%a%j%C%H$K$D$$$F$O!"e(Bbreak e$B$G0J2\<$rH4$1$k$4$H$Ke(B 1  
e$B2sJ,4t$,A}$(e(B  
e$B$^$9!#e(B

- e$B%/%i%9Dj5Ae(B 1.times { class C; break; end }
- rescue e$B@ae(B 1.times { begin; …; rescue; break; end }
- ensure e$B@ae(B 1.times { begin; …; ensure; break; end }

e$B$3$3$K%/%i%9Dj5A$,Mh$k$3$H$OHs\>o$K%l%"$G$9$7!“e(Brescue e$B@a$de(B  
ensure  
e$B@a$r%M%9%H$9$k$3$H$b%l%”$@$H;W$&$N$G!“LdBj$K$J$i$J$$$s$8$c$J$$e(B  
e$B$+$J!”$H;W$$$^$9!#e(B

e$B$H$$$&$o$1$G%Q%C%A$G$9!#e(B#1018 e$B$Ne(B wanabe  
e$B$5$s$N%Q%C%A$b4^$_$^$9!#e(B  
make test-rubyspec e$B$He(B make check  
e$B$GFC$K%(%i!\<$,A}$($J$$46$8$Je(B  
e$B$3$H$O3NG’$7$F$$$^$9!#%3%_%C%H$7$F$b$$$$$G$7$g$&$+!#e(B

diff --git a/compile.c b/compile.c  
index 64411f9…7748fca 100644  
— a/compile.c  
+++ b/compile.c  
@@ -4229,7 +4229,7 @@ iseq\_compile\_each(rb\_iseq\_t \*iseq, LINK\_ANCHOR  
\*ret, NODE \* node, int poped)  
rb\_iseq\_t \*is = iseq;

if (is) {

- 

```
 if (is->type == ISEQ_TYPE_TOP || is->type == ISEQ_TYPE_CLASS) {

```

- 

```
 if (is->type == ISEQ_TYPE_TOP) {

```

COMPILE\_ERROR((ERROR\_ARGS “Invalid return”));  
}  
else {  
@@ -4269,7 +4269,7 @@ iseq\_compile\_each(rb\_iseq\_t \*iseq, LINK\_ANCHOR  
\*ret, NODE \* node, int poped)  
unsigned long flag = 0;

INIT\_ANCHOR(args);

- if (iseq-\>type == ISEQ\_TYPE\_TOP || iseq-\>type == ISEQ\_TYPE\_CLASS) {

- if (iseq-\>type == ISEQ\_TYPE\_TOP) {  
COMPILE\_ERROR((ERROR\_ARGS “Invalid yield”));  
}

diff --git a/insns.def b/insns.def  
index 9541465…14485f2 100644  
— a/insns.def  
+++ b/insns.def  
@@ -953,7 +953,7 @@ defineclass

```
 /* enter scope */
 vm_push_frame(th, class_iseq,

```

- 

```
 VM_FRAME_MAGIC_CLASS, klass, (VALUE) GET_DFP() | 0x02,

```

- 

```
 VM_FRAME_MAGIC_CLASS, klass, (VALUE) GET_BLOCK_PTR(),
 class_iseq->iseq_encoded, GET_SP(), 0,
 class_iseq->local_size);

```

RESTORE\_REGS();  
diff --git a/proc.c b/proc.c  
index eff7a0b…5fa46f1 100644  
— a/proc.c  
+++ b/proc.c  
@@ -374,16 +374,14 @@ proc\_new(VALUE klass, int is\_lambda)  
rb\_control\_frame\_t \*cfp = th-\>cfp;  
rb\_block\_t \*block;

- if ((GC\_GUARDED\_PTR\_REF(cfp-\>lfp[0])) != 0 &&
- !RUBY\_VM\_CLASS\_SPECIAL\_P(cfp-\>lfp[0])) {

- if ((GC\_GUARDED\_PTR\_REF(cfp-\>lfp[0])) != 0) {

block = GC\_GUARDED\_PTR\_REF(cfp-\>lfp[0]);  
}  
else {  
cfp = RUBY\_VM\_PREVIOUS\_CONTROL\_FRAME(cfp);

- if ((GC\_GUARDED\_PTR\_REF(cfp-\>lfp[0])) != 0 &&
- 

```
 !RUBY_VM_CLASS_SPECIAL_P(cfp->lfp[0])) {

```

- if ((GC\_GUARDED\_PTR\_REF(cfp-\>lfp[0])) != 0) {

diff --git a/vm.c b/vm.c  
index 678fcb8…e5de8ac 100644  
— a/vm.c  
+++ b/vm.c  
@@ -477,7 +477,6 @@ rb\_vm\_make\_proc(rb\_thread\_t \*th, const rb\_block\_t  
\*block, VALUE klass)  
}

```
 if (GC_GUARDED_PTR_REF(cfp->lfp[0])) {

```

- if (!RUBY\_VM\_CLASS\_SPECIAL\_P(cfp-\>lfp[0])) {  
rb\_proc\_t \*p;

@@ -486,7 +485,6 @@ rb\_vm\_make\_proc(rb\_thread\_t \*th, const rb\_block\_t  
\*block, VALUE klass)  
GetProcPtr(blockprocval, p);  
\*cfp-\>lfp = GC\_GUARDED\_PTR(&p-\>block);  
}

- }

diff --git a/vm\_core.h b/vm\_core.h  
index b5c1bf0…7ee1c1c 100644  
— a/vm\_core.h  
+++ b/vm\_core.h  
@@ -592,8 +592,6 @@ typedef rb\_control\_frame\_t \*  
#define RUBY\_VM\_NORMAL\_ISEQ\_P(ptr)   
(ptr && !RUBY\_VM\_IFUNC\_P(ptr))

## -#define RUBY\_VM\_CLASS\_SPECIAL\_P(ptr) (((VALUE)(ptr)) & 0x02)

#define RUBY\_VM\_GET\_BLOCK\_PTR\_IN\_CFP(cfp) ((rb\_block\_t  
\*)(&(cfp)-\>self))  
#define RUBY\_VM\_GET\_CFP\_FROM\_BLOCK\_PTR(b)   
((rb\_control\_frame\_t \*)((VALUE \*)(b) - 5))  
diff --git a/vm\_insnhelper.c b/vm\_insnhelper.c  
index cd74c8e…ae28ef3 100644  
— a/vm\_insnhelper.c  
+++ b/vm\_insnhelper.c  
@@ -890,8 +890,9 @@ vm\_invoke\_block(rb\_thread\_t \*th, rb\_control\_frame\_t  
\*reg\_cfp, rb\_num\_t num, rb\_n  
const rb\_block\_t \*block = GET\_BLOCK\_PTR();  
rb\_iseq\_t \*iseq;  
int argc = (int)num;

- int type = GET\_ISEQ()-\>local\_iseq-\>type;

- if (GET\_ISEQ()-\>local\_iseq-\>type != ISEQ\_TYPE\_METHOD || block == 0)  
{

- if ((type != ISEQ\_TYPE\_METHOD && type != ISEQ\_TYPE\_CLASS) || block  
== 0) {  
rb\_vm\_localjump\_error(“no block given (yield)”, Qnil, 0);  
}  
iseq = block-\>iseq;  
@@ -1411,6 +1412,11 @@ vm\_throw(rb\_thread\_t \*th, rb\_control\_frame\_t  
\*reg\_cfp,

- 

```
   if (cfp->iseq->type == ISEQ_TYPE_CLASS) {

```

- 

```
 cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);

```

- 

```
 dfp = cfp->dfp;

```

- 

```
 goto search_parent;

```

- 

```
   }
   dfp = GC_GUARDED_PTR_REF((VALUE *) *dfp);
   base_iseq = base_iseq->parent_iseq;

```

@@ -1476,10 +1482,17 @@ vm\_throw(rb\_thread\_t \*th, rb\_control\_frame\_t  
\*reg\_cfp,  
else if (state == TAG\_RETURN) {  
rb\_control\_frame\_t \*cfp = GET\_CFP();  
VALUE \*dfp = GET\_DFP();

- VALUE \* const lfp = GET\_LFP();

- VALUE \*lfp = GET\_LFP();

- 

```
   if (!lfp) {

```

- 

```
 lfp = cfp->lfp;

```

- 

```
   }

```

- 

```
   if (cfp->dfp == lfp && cfp->iseq->type == ISEQ_TYPE_CLASS) {

```

- 

```
 lfp = 0;

```

- 

```
   }

```

- 

```
   if (cfp->lfp == lfp) {
 if (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_LAMBDA) {
     VALUE *tdfp = dfp;

```

–  
Yusuke E. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![Yusuke\_E](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/f08c70/32.png) [@Yusuke\_E](https://www.ruby-forum.com/u/Yusuke_E)\
**Post date:** [May 4, 2010, 5:45am UTC](https://www.ruby-forum.com/t/bug-3141-yield-in-an-eigenclass-definition/186863/2 "2010-05-04T05:45:12Z")

</div>

e$B%A%1%C%He(B #3141 e$B$,99?7$5$l$^$7$?!#e(B (by Koichi Sasada)

## e$BJV;v$,CY$/$J$C$F$9$\_$^$;$s!%e(B e$B$3$l$,NI$$$H;W$$$^$9!%$h$m$7$/$\*4j$$$7$^$9!%e(B

[http://redmine.ruby-lang.org/issues/show/3141](http://redmine.ruby-lang.org/issues/show/3141)

---

<div class="post-metadata">

**Author:** ![Yusuke\_E](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/y/f08c70/32.png) [@Yusuke\_E](https://www.ruby-forum.com/u/Yusuke_E)\
**Post date:** [May 9, 2010, 8:28pm UTC](https://www.ruby-forum.com/t/bug-3141-yield-in-an-eigenclass-definition/186863/3 "2010-05-09T20:28:03Z")

</div>

e$B%A%1%C%He(B #3141 e$B$,99?7$5$l$^$7$?!#e(B (by Yusuke E.)

e$B%9%F!\<%?%9e(B Opene$B$+$ie(BClosede$B$KJQ99e(B  
e$B?JD=e(B % 0e$B$+$ie(B100e$B$KJQ99e(B

This issue was solved with changeset r27714.  
Yusuke, thank you for reporting this issue.  
Your contribution to Ruby is greatly appreciated.  
May Ruby be with you.

* * *

[http://redmine.ruby-lang.org/issues/show/3141](http://redmine.ruby-lang.org/issues/show/3141)
