ruby-changes:15785
From: mame <ko1@a...>
Date: Mon, 10 May 2010 03:21:59 +0900 (JST)
Subject: [ruby-changes:15785] Ruby:r27714 (trunk): * compile.c (iseq_compile_each), vm_insnhelper.c (vm_invoke_block,
mame 2010-05-10 03:21:39 +0900 (Mon, 10 May 2010) New Revision: 27714 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=27714 Log: * compile.c (iseq_compile_each), vm_insnhelper.c (vm_invoke_block, vm_throw): allow "return" and "yield" even in singleton class definition. based on a patch from wanabe <s.wanabe AT gmail.com> for "return". [ruby-core:21379] [ruby-dev:40975] * insns.def (defineclass): ditto (straightforwardly push block ptr, instead of dfp ptr with special flag). * vm_core.h (RUBY_VM_CLASS_SPECIAL_P): ditto (no longer needed). * proc.c (proc_new): ditto (remove handling for special flag). * bootstraptest/test_jump.rb: add tests for above. Modified files: trunk/ChangeLog trunk/bootstraptest/test_jump.rb trunk/compile.c trunk/insns.def trunk/proc.c trunk/vm.c trunk/vm_core.h trunk/vm_insnhelper.c Index: ChangeLog =================================================================== --- ChangeLog (revision 27713) +++ ChangeLog (revision 27714) @@ -1,3 +1,19 @@ +Mon May 10 02:58:33 2010 Yusuke Endoh <mame@t...> + + * compile.c (iseq_compile_each), vm_insnhelper.c (vm_invoke_block, + vm_throw): allow "return" and "yield" even in singleton class + definition. based on a patch from wanabe <s.wanabe AT gmail.com> + for "return". [ruby-core:21379] [ruby-dev:40975] + + * insns.def (defineclass): ditto (straightforwardly push block ptr, + instead of dfp ptr with special flag). + + * vm_core.h (RUBY_VM_CLASS_SPECIAL_P): ditto (no longer needed). + + * proc.c (proc_new): ditto (remove handling for special flag). + + * bootstraptest/test_jump.rb: add tests for above. + Mon May 10 02:29:51 2010 Yusuke Endoh <mame@t...> * cont.c (fiber_switch): raise FiberError when returning to dead Index: insns.def =================================================================== --- insns.def (revision 27713) +++ insns.def (revision 27714) @@ -953,7 +953,7 @@ /* 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(); Index: bootstraptest/test_jump.rb =================================================================== --- bootstraptest/test_jump.rb (revision 27713) +++ bootstraptest/test_jump.rb (revision 27714) @@ -282,3 +282,27 @@ break end }, '[ruby-core:28172]' + +assert_equal "true", %q{ + class Object + def return_eigenclass + class << self + return self + end + end + end + s = "foo" + s.return_eigenclass == class << s; self; end +}, '[ruby-core:21379]' + +assert_equal "true", %q{ + class Object + def yield_eigenclass + class << self + yield self + end + end + end + s = "foo" + s.yield_eigenclass {|c| c == class << s; self; end } +}, '[ruby-dev:40975]' Index: vm_core.h =================================================================== --- vm_core.h (revision 27713) +++ vm_core.h (revision 27714) @@ -597,8 +597,6 @@ #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)) Index: compile.c =================================================================== --- compile.c (revision 27713) +++ compile.c (revision 27714) @@ -4225,7 +4225,7 @@ 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 { @@ -4265,7 +4265,7 @@ 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")); } Index: proc.c =================================================================== --- proc.c (revision 27713) +++ proc.c (revision 27714) @@ -375,16 +375,14 @@ 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) { block = GC_GUARDED_PTR_REF(cfp->lfp[0]); Index: vm.c =================================================================== --- vm.c (revision 27713) +++ vm.c (revision 27714) @@ -477,7 +477,6 @@ } if (GC_GUARDED_PTR_REF(cfp->lfp[0])) { - if (!RUBY_VM_CLASS_SPECIAL_P(cfp->lfp[0])) { rb_proc_t *p; blockprocval = vm_make_proc_from_block( @@ -486,7 +485,6 @@ GetProcPtr(blockprocval, p); *cfp->lfp = GC_GUARDED_PTR(&p->block); } - } envval = rb_vm_make_env_object(th, cfp); Index: vm_insnhelper.c =================================================================== --- vm_insnhelper.c (revision 27713) +++ vm_insnhelper.c (revision 27714) @@ -913,8 +913,9 @@ 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; @@ -1434,6 +1435,11 @@ search_parent: if (cfp->iseq->type != ISEQ_TYPE_BLOCK) { + 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; @@ -1499,10 +1505,17 @@ 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(); /* check orphan and get dfp */ while ((VALUE *) cfp < th->stack + th->stack_size) { + 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; -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/