mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	* compile.c: fix to add "ensure" codes across "while" clause
before "return" expression. [ruby-dev:37967] * bootstraptest/test_flow.rb: add a test. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@22363 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									cd2434deb6
								
							
						
					
					
						commit
						c9e4dc308f
					
				
					 3 changed files with 66 additions and 31 deletions
				
			
		| 
						 | 
				
			
			@ -1,3 +1,10 @@
 | 
			
		|||
Tue Feb 17 05:41:08 2009  Koichi Sasada  <ko1@atdot.net>
 | 
			
		||||
 | 
			
		||||
	* compile.c: fix to add "ensure" codes across "while" clause
 | 
			
		||||
	  before "return" expression.  [ruby-dev:37967]
 | 
			
		||||
 | 
			
		||||
	* bootstraptest/test_flow.rb: add a test.
 | 
			
		||||
 | 
			
		||||
Tue Feb 17 01:53:35 2009  Tanaka Akira  <akr@fsij.org>
 | 
			
		||||
 | 
			
		||||
	* ext/socket/mkconstants.rb: generate rb_define_const directly for
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -200,7 +200,9 @@ assert_equal %q{[1, 2, 3, 5, 8, 9]}, %q{$a = []; begin; ; $a << 1
 | 
			
		|||
  end; $a << 8
 | 
			
		||||
; $a << 9
 | 
			
		||||
; rescue Exception; $a << 99; end; $a}
 | 
			
		||||
assert_equal %q{[1, 2, 3, 5, 99]}, %q{$a = []; begin; ; $a << 1
 | 
			
		||||
assert_equal %q{[1, 2, 3, 5, 99]}, %q{
 | 
			
		||||
$a = [];
 | 
			
		||||
begin; ; $a << 1
 | 
			
		||||
  while true; $a << 2
 | 
			
		||||
    begin; $a << 3
 | 
			
		||||
      break; $a << 4
 | 
			
		||||
| 
						 | 
				
			
			@ -488,4 +490,15 @@ assert_equal %q{[:ok, :ok2, :last]}, %q{
 | 
			
		|||
    a << :last
 | 
			
		||||
  end
 | 
			
		||||
  a
 | 
			
		||||
   }
 | 
			
		||||
}
 | 
			
		||||
assert_equal %Q{ENSURE\n}, %q{
 | 
			
		||||
  def test
 | 
			
		||||
    while true
 | 
			
		||||
      return
 | 
			
		||||
    end
 | 
			
		||||
  ensure
 | 
			
		||||
    puts("ENSURE")
 | 
			
		||||
  end
 | 
			
		||||
  test
 | 
			
		||||
}, '[ruby-dev:37967]'
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										55
									
								
								compile.c
									
										
									
									
									
								
							
							
						
						
									
										55
									
								
								compile.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -2749,6 +2749,17 @@ make_name_for_block(rb_iseq_t *iseq)
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
push_ensure_entry(rb_iseq_t *iseq,
 | 
			
		||||
		  struct iseq_compile_data_ensure_node_stack *enl,
 | 
			
		||||
		  struct ensure_range *er, NODE *node)
 | 
			
		||||
{
 | 
			
		||||
    enl->ensure_node = node;
 | 
			
		||||
    enl->prev = iseq->compile_data->ensure_node_stack;	/* prev */
 | 
			
		||||
    enl->erange = er;
 | 
			
		||||
    iseq->compile_data->ensure_node_stack = enl;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
add_ensure_range(rb_iseq_t *iseq, struct ensure_range *erange,
 | 
			
		||||
		 LABEL *lstart, LABEL *lend)
 | 
			
		||||
| 
						 | 
				
			
			@ -2768,7 +2779,7 @@ add_ensure_range(rb_iseq_t *iseq, struct ensure_range *erange,
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
add_ensure_iseq(LINK_ANCHOR *ret, rb_iseq_t *iseq)
 | 
			
		||||
add_ensure_iseq(LINK_ANCHOR *ret, rb_iseq_t *iseq, int is_return)
 | 
			
		||||
{
 | 
			
		||||
    struct iseq_compile_data_ensure_node_stack *enlp =
 | 
			
		||||
	iseq->compile_data->ensure_node_stack;
 | 
			
		||||
| 
						 | 
				
			
			@ -2777,19 +2788,25 @@ add_ensure_iseq(LINK_ANCHOR *ret, rb_iseq_t *iseq)
 | 
			
		|||
 | 
			
		||||
    INIT_ANCHOR(ensure);
 | 
			
		||||
    while (enlp) {
 | 
			
		||||
	if (enlp->erange != 0) {
 | 
			
		||||
	    DECL_ANCHOR(ensure_part);
 | 
			
		||||
	    LABEL *lstart = NEW_LABEL(0);
 | 
			
		||||
	    LABEL *lend = NEW_LABEL(0);
 | 
			
		||||
 | 
			
		||||
	    INIT_ANCHOR(ensure_part);
 | 
			
		||||
 | 
			
		||||
	    add_ensure_range(iseq, enlp->erange, lstart, lend);
 | 
			
		||||
 | 
			
		||||
	    iseq->compile_data->ensure_node_stack = enlp->prev;
 | 
			
		||||
	    ADD_LABEL(ensure_part, lstart);
 | 
			
		||||
	    COMPILE_POPED(ensure_part, "ensure part", enlp->ensure_node);
 | 
			
		||||
	    ADD_LABEL(ensure_part, lend);
 | 
			
		||||
 | 
			
		||||
	    ADD_SEQ(ensure, ensure_part);
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
	    if (!is_return) {
 | 
			
		||||
		break;
 | 
			
		||||
	    }
 | 
			
		||||
	}
 | 
			
		||||
	enlp = enlp->prev;
 | 
			
		||||
    }
 | 
			
		||||
    iseq->compile_data->ensure_node_stack = prev_enlp;
 | 
			
		||||
| 
						 | 
				
			
			@ -3123,8 +3140,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
 | 
			
		|||
	LABEL *prev_redo_label = iseq->compile_data->redo_label;
 | 
			
		||||
	VALUE prev_loopval_popped = iseq->compile_data->loopval_popped;
 | 
			
		||||
 | 
			
		||||
	struct iseq_compile_data_ensure_node_stack *enlp =
 | 
			
		||||
	    iseq->compile_data->ensure_node_stack;
 | 
			
		||||
	struct iseq_compile_data_ensure_node_stack enl;
 | 
			
		||||
 | 
			
		||||
	LABEL *next_label = iseq->compile_data->start_label = NEW_LABEL(nd_line(node));	/* next  */
 | 
			
		||||
	LABEL *redo_label = iseq->compile_data->redo_label = NEW_LABEL(nd_line(node));	/* redo  */
 | 
			
		||||
| 
						 | 
				
			
			@ -3135,7 +3151,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
 | 
			
		|||
	LABEL *tmp_label = NULL;
 | 
			
		||||
 | 
			
		||||
	iseq->compile_data->loopval_popped = 0;
 | 
			
		||||
	iseq->compile_data->ensure_node_stack = 0;
 | 
			
		||||
	push_ensure_entry(iseq, &enl, 0, 0);
 | 
			
		||||
 | 
			
		||||
	if (type == NODE_OPT_N || node->nd_state == 1) {
 | 
			
		||||
	    ADD_INSNL(ret, nd_line(node), jump, next_label);
 | 
			
		||||
| 
						 | 
				
			
			@ -3197,7 +3213,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
 | 
			
		|||
	iseq->compile_data->end_label = prev_end_label;
 | 
			
		||||
	iseq->compile_data->redo_label = prev_redo_label;
 | 
			
		||||
	iseq->compile_data->loopval_popped = prev_loopval_popped;
 | 
			
		||||
	iseq->compile_data->ensure_node_stack = enlp;
 | 
			
		||||
	iseq->compile_data->ensure_node_stack = iseq->compile_data->ensure_node_stack->prev;
 | 
			
		||||
	break;
 | 
			
		||||
      }
 | 
			
		||||
      case NODE_ITER:
 | 
			
		||||
| 
						 | 
				
			
			@ -3246,7 +3262,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
 | 
			
		|||
	    ADD_LABEL(ret, splabel);
 | 
			
		||||
	    ADD_ADJUST(ret, nd_line(node), iseq->compile_data->redo_label);
 | 
			
		||||
	    COMPILE_(ret, "break val (while/until)", node->nd_stts, iseq->compile_data->loopval_popped);
 | 
			
		||||
	    add_ensure_iseq(ret, iseq);
 | 
			
		||||
	    add_ensure_iseq(ret, iseq, 0);
 | 
			
		||||
	    ADD_INSNL(ret, nd_line(node), jump, iseq->compile_data->end_label);
 | 
			
		||||
	    ADD_ADJUST_RESTORE(ret, splabel);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3306,7 +3322,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
 | 
			
		|||
	    debugs("next in while loop\n");
 | 
			
		||||
	    ADD_LABEL(ret, splabel);
 | 
			
		||||
	    COMPILE(ret, "next val/valid syntax?", node->nd_stts);
 | 
			
		||||
	    add_ensure_iseq(ret, iseq);
 | 
			
		||||
	    add_ensure_iseq(ret, iseq, 0);
 | 
			
		||||
	    ADD_ADJUST(ret, nd_line(node), iseq->compile_data->redo_label);
 | 
			
		||||
	    ADD_INSNL(ret, nd_line(node), jump, iseq->compile_data->start_label);
 | 
			
		||||
	    ADD_ADJUST_RESTORE(ret, splabel);
 | 
			
		||||
| 
						 | 
				
			
			@ -3317,7 +3333,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
 | 
			
		|||
	    ADD_LABEL(ret, splabel);
 | 
			
		||||
	    ADD_ADJUST(ret, nd_line(node), iseq->compile_data->start_label);
 | 
			
		||||
	    COMPILE(ret, "next val", node->nd_stts);
 | 
			
		||||
	    add_ensure_iseq(ret, iseq);
 | 
			
		||||
	    add_ensure_iseq(ret, iseq, 0);
 | 
			
		||||
	    ADD_INSNL(ret, nd_line(node), jump, iseq->compile_data->end_label);
 | 
			
		||||
	    ADD_ADJUST_RESTORE(ret, splabel);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3372,7 +3388,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
 | 
			
		|||
	    debugs("redo in while");
 | 
			
		||||
	    ADD_LABEL(ret, splabel);
 | 
			
		||||
	    ADD_ADJUST(ret, nd_line(node), iseq->compile_data->redo_label);
 | 
			
		||||
	    add_ensure_iseq(ret, iseq);
 | 
			
		||||
	    add_ensure_iseq(ret, iseq, 0);
 | 
			
		||||
	    ADD_INSNL(ret, nd_line(node), jump, iseq->compile_data->redo_label);
 | 
			
		||||
	    ADD_ADJUST_RESTORE(ret, splabel);
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -3385,7 +3401,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
 | 
			
		|||
 | 
			
		||||
	    debugs("redo in block");
 | 
			
		||||
	    ADD_LABEL(ret, splabel);
 | 
			
		||||
	    add_ensure_iseq(ret, iseq);
 | 
			
		||||
	    add_ensure_iseq(ret, iseq, 0);
 | 
			
		||||
	    ADD_ADJUST(ret, nd_line(node), iseq->compile_data->start_label);
 | 
			
		||||
	    ADD_INSNL(ret, nd_line(node), jump, iseq->compile_data->start_label);
 | 
			
		||||
	    ADD_ADJUST_RESTORE(ret, splabel);
 | 
			
		||||
| 
						 | 
				
			
			@ -3542,19 +3558,17 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
 | 
			
		|||
	LABEL *lstart = NEW_LABEL(nd_line(node));
 | 
			
		||||
	LABEL *lend = NEW_LABEL(nd_line(node));
 | 
			
		||||
	LABEL *lcont = NEW_LABEL(nd_line(node));
 | 
			
		||||
	struct ensure_range er = { 0 };
 | 
			
		||||
	struct ensure_range er;
 | 
			
		||||
	struct iseq_compile_data_ensure_node_stack enl;
 | 
			
		||||
	struct ensure_range *erange;
 | 
			
		||||
 | 
			
		||||
	INIT_ANCHOR(ensr);
 | 
			
		||||
	er.begin = lstart;
 | 
			
		||||
	er.end = lend;
 | 
			
		||||
	enl.ensure_node = node->nd_ensr;
 | 
			
		||||
	enl.prev = iseq->compile_data->ensure_node_stack;	/* prev */
 | 
			
		||||
	enl.erange = &er;
 | 
			
		||||
	COMPILE_POPED(ensr, "ensure ensr", node->nd_ensr);
 | 
			
		||||
 | 
			
		||||
	iseq->compile_data->ensure_node_stack = &enl;
 | 
			
		||||
	er.begin = lstart;
 | 
			
		||||
	er.end = lend;
 | 
			
		||||
	er.next = 0;
 | 
			
		||||
	push_ensure_entry(iseq, &enl, &er, node->nd_ensr);
 | 
			
		||||
 | 
			
		||||
	ADD_LABEL(ret, lstart);
 | 
			
		||||
	COMPILE_(ret, "ensure head", node->nd_head, poped);
 | 
			
		||||
| 
						 | 
				
			
			@ -3573,6 +3587,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
 | 
			
		|||
			    ensure, lcont);
 | 
			
		||||
	    erange = erange->next;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	iseq->compile_data->ensure_node_stack = enl.prev;
 | 
			
		||||
	break;
 | 
			
		||||
      }
 | 
			
		||||
| 
						 | 
				
			
			@ -4171,7 +4186,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
 | 
			
		|||
		COMPILE(ret, "return nd_stts (return val)", node->nd_stts);
 | 
			
		||||
 | 
			
		||||
		if (is->type == ISEQ_TYPE_METHOD) {
 | 
			
		||||
		    add_ensure_iseq(ret, iseq);
 | 
			
		||||
		    add_ensure_iseq(ret, iseq, 1);
 | 
			
		||||
		    ADD_INSN(ret, nd_line(node), leave);
 | 
			
		||||
		    ADD_ADJUST_RESTORE(ret, splabel);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue