e$B%o%J%Y$H?=$7$^$9!#e(B
[ruby-core:14813] e$B$KBP$9$k%Q%C%A$r=q$-$^$7$?!#e(B
e$B%V%m%C%/0z?t$,M?$($i$l$?%V%m%C%/!"$*$h$Se(B define_method
e$B$N%V%m%C%/Cf$G$Ne(B
given_block? e$B$He(B yield e$B$N5sF0$,JQ$o$j$^$9!#e(B
e$B%V%m%C%/%U%l!<%`$Ne(B bp
e$B$r2!$7>e$2!"$G$-$?7d4V$K6/0z$K%V%m%C%/0z?t$r;}$?$;$F$$$^$9!#e(B
Index: vm_core.h
— vm_core.h (revision 15984)
+++ vm_core.h (working copy)
@@ -608,6 +608,7 @@
VALUE vm_yield(rb_thread_t *th, int argc, VALUE *argv);
VALUE vm_call0(rb_thread_t *th, VALUE klass, VALUE recv, VALUE id, ID
oid,
int argc, const VALUE *argv, NODE *body, int nosuper);
+rb_block_t *vm_get_block(rb_control_frame_t *cfp);
int vm_get_sourceline(rb_control_frame_t *);
Index: eval.c
— eval.c (revision 15984)
+++ eval.c (working copy)
@@ -837,11 +837,10 @@
JUMP_TAG(tag);
}
-int
-rb_block_given_p(void)
+static inline VALUE
+block_given_p(rb_control_frame_t *cfp)
{
- rb_thread_t *th = GET_THREAD();
- if (GC_GUARDED_PTR_REF(th->cfp->lfp[0])) {
- if (vm_get_block(cfp)) {
return Qtrue;
}
else {
@@ -850,6 +849,12 @@
}
int
+rb_block_given_p(void)
+{
- return block_given_p(GET_THREAD()->cfp);
+}
+int
rb_iterator_p()
{
return rb_block_given_p();
@@ -882,13 +887,9 @@
{
rb_thread_t *th = GET_THREAD();
rb_control_frame_t *cfp = th->cfp;
+
cfp = vm_get_ruby_level_cfp(th,
RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));
- if (GC_GUARDED_PTR_REF(cfp->lfp[0])) {
- return Qtrue;
- }
- else {
- return Qfalse;
- }
- return block_given_p(cfp);
}
VALUE rb_eThreadError;
Index: vm.c
— vm.c (revision 15984)
+++ vm.c (working copy)
@@ -539,6 +539,30 @@
return vm_call_super(GET_THREAD(), argc, argv);
}
+rb_block_t *
+vm_get_block(rb_control_frame_t *cfp) {
- rb_block_t *block = 0;
- if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
- if (cfp->iseq->type == ISEQ_TYPE_BLOCK) {
-
block = ((rb_block_t *)(GC_GUARDED_PTR_REF(cfp->dfp[1])));
-
if (cfp->iseq->defined_method_id) {
- return block;
-
}
- }
- else if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq->local_iseq)) {
-
if (cfp->iseq->local_iseq->type != ISEQ_TYPE_METHOD) {
- return 0;
-
}
- }
- }
- if (!block) {
- block = ((rb_block_t *)(GC_GUARDED_PTR_REF(cfp->lfp[0])));
- }
- return block;
+}
/* C -> Ruby: block */
static VALUE
@@ -568,6 +592,7 @@
self, GC_GUARDED_PTR(block->dfp),
iseq->iseq_encoded + opt_pc, cfp->sp + arg_size, block->lfp,
iseq->local_size - arg_size);
-
vm_add_specval(th, GC_GUARDED_PTR(blockptr));
val = vm_eval_body(th);
}
@@ -1316,6 +1341,7 @@
vm_push_frame(th, catch_iseq, FRAME_MAGIC_BLOCK,
cfp->self, (VALUE)cfp->dfp, catch_iseq->iseq_encoded,
cfp->sp + 1, cfp->lfp, catch_iseq->local_size - 1); -
vm_add_specval(th, 0); state = 0; th->errinfo = Qnil;
Index: vm_insnhelper.c
— vm_insnhelper.c (revision 15984)
+++ vm_insnhelper.c (working copy)
@@ -68,6 +68,14 @@
}
static inline void
+vm_add_specval(rb_thread_t *th, VALUE specval)
+{
- *th->cfp->bp = specval;
- th->cfp->sp++;
- th->cfp->bp++;
+}
+static inline void
vm_pop_frame(rb_thread_t *th)
{
#if COLLECT_PROFILE
@@ -792,11 +800,12 @@
vm_invoke_block(rb_thread_t *th, rb_control_frame_t *reg_cfp,
rb_num_t num, rb_num_t flag)
{
VALUE val;
- rb_block_t *block = GET_BLOCK_PTR();
- rb_block_t *block = 0;
rb_iseq_t *iseq;
int argc = num;
- if (GET_ISEQ()->local_iseq->type != ISEQ_TYPE_METHOD || block == 0)
{
-
block = vm_get_block(reg_cfp);
-
if (block == 0) {
vm_localjump_error(“no block given (yield)”, Qnil, 0);
}
iseq = block->iseq;
@@ -817,6 +826,7 @@
FRAME_MAGIC_BLOCK, block->self, (VALUE) block->dfp,
iseq->iseq_encoded + opt_pc, rsp + arg_size, block->lfp,
iseq->local_size - arg_size); -
vm_add_specval(th, 0);
return Qundef;
}