6460-1_9_3.patch

Kazuki Tsujimoto, 07/01/2012 07:13 PM

Download (3.6 KB)

View differences:

bootstraptest/test_flow.rb
543 543
    end
544 544
  end
545 545
  e = Bug5234.new
546
}],
547
 ['[ruby-dev:45656]', %q{
548
  class Bug6460
549
    include Enumerable
550
    def each
551
      begin
552
        yield :foo
553
      ensure
554
        1.times { Proc.new }
555
      end
556
    end
557
  end
558
  e = Bug6460.new
546 559
}]].each do |bug, src|
547 560
  assert_equal "foo", src + %q{e.detect {true}}, bug
548 561
  assert_equal "true", src + %q{e.any? {true}}, bug
proc.c
417 417
    }
418 418

  
419 419
    procval = rb_vm_make_proc(th, block, klass);
420
    rb_vm_rewrite_dfp_in_errinfo(th, cfp);
421 420

  
422 421
    if (is_lambda) {
423 422
	rb_proc_t *proc;
vm.c
424 424
    if (!RUBY_VM_NORMAL_ISEQ_P(cfp->iseq)) {
425 425
	/* TODO */
426 426
	env->block.iseq = 0;
427
    } else {
428
	rb_vm_rewrite_dfp_in_errinfo(th, cfp);
429 427
    }
430 428
    return envval;
431 429
}
......
480 478
    }
481 479

  
482 480
    envval = vm_make_env_each(th, cfp, cfp->dfp, cfp->lfp);
481
    rb_vm_rewrite_dfp_in_errinfo(th);
483 482

  
484 483
    if (PROCDEBUG) {
485 484
	check_env_value(envval);
......
489 488
}
490 489

  
491 490
void
492
rb_vm_rewrite_dfp_in_errinfo(rb_thread_t *th, rb_control_frame_t *cfp)
493
{
494
    /* rewrite dfp in errinfo to point to heap */
495
    if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq) &&
496
	(cfp->iseq->type == ISEQ_TYPE_RESCUE ||
497
	 cfp->iseq->type == ISEQ_TYPE_ENSURE)) {
498
	VALUE errinfo = cfp->dfp[-2]; /* #$! */
499
	if (RB_TYPE_P(errinfo, T_NODE)) {
500
	    VALUE *escape_dfp = GET_THROWOBJ_CATCH_POINT(errinfo);
501
	    if (! ENV_IN_HEAP_P(th, escape_dfp)) {
502
		VALUE dfpval = *escape_dfp;
503
		if (CLASS_OF(dfpval) == rb_cEnv) {
504
		    rb_env_t *dfpenv;
505
		    GetEnvPtr(dfpval, dfpenv);
506
		    SET_THROWOBJ_CATCH_POINT(errinfo, (VALUE)(dfpenv->env + dfpenv->local_size));
491
rb_vm_rewrite_dfp_in_errinfo(rb_thread_t *th)
492
{
493
    rb_control_frame_t *cfp = th->cfp;
494
    while (!RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp)) {
495
	/* rewrite dfp in errinfo to point to heap */
496
	if (RUBY_VM_NORMAL_ISEQ_P(cfp->iseq) &&
497
	    (cfp->iseq->type == ISEQ_TYPE_RESCUE ||
498
	     cfp->iseq->type == ISEQ_TYPE_ENSURE)) {
499
	    VALUE errinfo = cfp->dfp[-2]; /* #$! */
500
	    if (RB_TYPE_P(errinfo, T_NODE)) {
501
		VALUE *escape_dfp = GET_THROWOBJ_CATCH_POINT(errinfo);
502
		if (! ENV_IN_HEAP_P(th, escape_dfp)) {
503
		    VALUE dfpval = *escape_dfp;
504
		    if (CLASS_OF(dfpval) == rb_cEnv) {
505
			rb_env_t *dfpenv;
506
			GetEnvPtr(dfpval, dfpenv);
507
			SET_THROWOBJ_CATCH_POINT(errinfo, (VALUE)(dfpenv->env + dfpenv->local_size));
508
		    }
507 509
		}
508 510
	    }
509 511
	}
512
	cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
510 513
    }
511 514
}
512 515

  
vm_core.h
651 651
			int argc, const VALUE *argv, const rb_block_t *blockptr);
652 652
VALUE rb_vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass);
653 653
VALUE rb_vm_make_env_object(rb_thread_t *th, rb_control_frame_t *cfp);
654
void rb_vm_rewrite_dfp_in_errinfo(rb_thread_t *th, rb_control_frame_t *cfp);
654
void rb_vm_rewrite_dfp_in_errinfo(rb_thread_t *th);
655 655
void rb_vm_inc_const_missing_count(void);
656 656
void rb_vm_gvl_destroy(rb_vm_t *vm);
657 657
VALUE rb_vm_call(rb_thread_t *th, VALUE recv, VALUE id, int argc,