[前][次][番号順一覧][スレッド一覧]

ruby-changes:3762

From: ko1@a...
Date: Sat, 26 Jan 2008 17:27:14 +0900 (JST)
Subject: [ruby-changes:3762] ko1 - Ruby:r15251 (trunk): * compile.c, compile.h: fix to calculate correct stack depth

ko1	2008-01-26 17:27:00 +0900 (Sat, 26 Jan 2008)

  New Revision: 15251

  Modified files:
    trunk/ChangeLog
    trunk/compile.c
    trunk/compile.h

  Log:
    * compile.c, compile.h: fix to calculate correct stack depth
      at each instruction.
    


  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/compile.c?r1=15251&r2=15250&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=15251&r2=15250&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/compile.h?r1=15251&r2=15250&diff_format=u

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 15250)
+++ ChangeLog	(revision 15251)
@@ -1,3 +1,8 @@
+Sat Jan 26 17:22:46 2008  Koichi Sasada  <ko1@a...>
+
+	* compile.c, compile.h: fix to calculate correct stack depth
+	   at each instruction.
+
 Sat Jan 26 09:41:02 2008  NARUSE, Yui  <naruse@r...>
 
 	* lib/rexml/doctype.rb, test/rss/test_maker_itunes.rb: replace
Index: compile.c
===================================================================
--- compile.c	(revision 15250)
+++ compile.c	(revision 15251)
@@ -348,7 +348,6 @@
     verify_list("add", anchor);
 }
 
-#if 0 /* unused */
 /*
  * elem1, elemX => elem1, elem2, elemX
  */
@@ -362,7 +361,6 @@
 	elem2->next->prev = elem2;
     }
 }
-#endif
 
 #if 0 /* unused */
 /*
@@ -1007,8 +1005,11 @@
 	    }
 	  case ISEQ_ELEMENT_ADJUST:
 	    {
-		pos += 2 /* insn + 1 operand */;
-		k++;
+		ADJUST *adjust = (ADJUST *)list;
+		if (adjust->line_no != -1) {
+		    pos += 2 /* insn + 1 operand */;
+		    k++;
+		}
 		break;
 	    }
 	  default:
@@ -1180,26 +1181,28 @@
 		    sp = 0;
 		}
 
-		if (orig_sp - sp > 0) {
-		    insn_info_table[k].line_no = adjust->line_no;
-		    insn_info_table[k].position = pos;
-		    insn_info_table[k].sp = sp;
-		    k++;
-		    generated_iseq[pos++] = BIN(adjuststack);
-		    generated_iseq[pos++] = orig_sp - sp;
+		if (adjust->line_no != -1) {
+		    if (orig_sp - sp > 0) {
+			insn_info_table[k].line_no = adjust->line_no;
+			insn_info_table[k].position = pos;
+			insn_info_table[k].sp = sp;
+			k++;
+			generated_iseq[pos++] = BIN(adjuststack);
+			generated_iseq[pos++] = orig_sp - sp;
+		    }
+		    else if (orig_sp - sp == 0) {
+			/* jump to next insn */
+			insn_info_table[k].line_no = adjust->line_no;
+			insn_info_table[k].position = pos;
+			insn_info_table[k].sp = sp;
+			k++;
+			generated_iseq[pos++] = BIN(jump);
+			generated_iseq[pos++] = 0;
+		    }
+		    else {
+			rb_bug("iseq_set_sequence: adjust bug");
+		    }
 		}
-		else if (orig_sp - sp == 0) {
-		    /* jump to next insn */
-		    insn_info_table[k].line_no = adjust->line_no;
-		    insn_info_table[k].position = pos;
-		    insn_info_table[k].sp = sp;
-		    k++;
-		    generated_iseq[pos++] = BIN(jump);
-		    generated_iseq[pos++] = 0;
-		}
-		else {
-		    rb_bug("iseq_set_sequence: adjust bug");
-		}
 		break;
 	    }
 	  default:
@@ -1209,7 +1212,7 @@
 	list = list->next;
     }
 
-#if 0
+#if 0 /* XXX */
     /* this check need dead code elimination */
     if (sp != 1) {
 	rb_bug("SP is not 0 on %s (%d)\n", RSTRING_PTR(iseq->name), sp);
@@ -1401,11 +1404,13 @@
 	     *  leave
 	     */
 	    INSN *eiobj = new_insn_core(iseq, iobj->line_no, BIN(leave),
-					diobj->operand_size,
-					diobj->operands);
+					diobj->operand_size, diobj->operands);
+	    INSN *popiobj = new_insn_core(iseq, iobj->line_no,
+					  BIN(pop), 0, 0);
 	    /* replace */
 	    REPLACE_ELEM((LINK_ELEMENT *)iobj, (LINK_ELEMENT *)eiobj);
-	    iobj = eiobj;
+	    INSERT_ELEM_NEXT((LINK_ELEMENT *)eiobj, (LINK_ELEMENT *)popiobj);
+	    iobj = popiobj;
 	}
 	/*
 	 * useless jump elimination (if/unless destination):
@@ -2982,18 +2987,26 @@
 
 	if (iseq->compile_data->redo_label != 0) {
 	    /* while/until */
+	    LABEL *splabel = NEW_LABEL(0);
+	    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_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_INSNL(ret, nd_line(node), jump, iseq->compile_data->end_label);
+	    ADD_ADJUST_RESTORE(ret, splabel);
+
+	    if (!poped) {
+		ADD_INSN(ret, nd_line(node), putnil);
+	    }
 	}
 	else if (iseq->type == ISEQ_TYPE_BLOCK) {
 	  break_by_insn:
 	    /* escape from block */
 	    COMPILE(ret, "break val (block)", node->nd_stts);
-	    ADD_INSN1(ret, nd_line(node), throw,
-		      INT2FIX(level | 0x02) /* TAG_BREAK */ );
+	    ADD_INSN1(ret, nd_line(node), throw, INT2FIX(level | 0x02) /* TAG_BREAK */ );
+	    if (poped) {
+		ADD_INSN(ret, nd_line(node), pop);
+	    }
 	}
 	else if (iseq->type == ISEQ_TYPE_EVAL) {
 	  break_in_eval:
@@ -3026,21 +3039,29 @@
       }
       case NODE_NEXT:{
 	unsigned long level = 0;
-	int pop_after_throw = 0;
 
 	if (iseq->compile_data->redo_label != 0) {
+	    LABEL *splabel = NEW_LABEL(0);
 	    debugs("next in while loop\n");
+	    ADD_LABEL(ret, splabel);
+	    add_ensure_iseq(ret, iseq);
 	    ADD_ADJUST(ret, nd_line(node), iseq->compile_data->redo_label);
-	    add_ensure_iseq(ret, iseq);
 	    ADD_INSNL(ret, nd_line(node), jump, iseq->compile_data->start_label);
+	    ADD_ADJUST_RESTORE(ret, splabel);
 	}
 	else if (iseq->compile_data->end_label) {
+	    LABEL *splabel = NEW_LABEL(0);
 	    debugs("next in block\n");
+	    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_INSNL(ret, nd_line(node), jump,
-		      iseq->compile_data->end_label);
+	    ADD_INSNL(ret, nd_line(node), jump, iseq->compile_data->end_label);
+	    ADD_ADJUST_RESTORE(ret, splabel);
+
+	    if (!poped) {
+		ADD_INSN(ret, nd_line(node), putnil);
+	    }
 	}
 	else if (iseq->type == ISEQ_TYPE_EVAL) {
 	  next_in_eval:
@@ -3067,9 +3088,9 @@
 	    }
 	    if (ip != 0) {
 		COMPILE(ret, "next val", node->nd_stts);
-		ADD_INSN1(ret, nd_line(node), throw,
-			  INT2FIX(level | 0x03) /* TAG_NEXT */ );
-		if (pop_after_throw) {
+		ADD_INSN1(ret, nd_line(node), throw, INT2FIX(level | 0x03) /* TAG_NEXT */ );
+
+		if (poped) {
 		    ADD_INSN(ret, nd_line(node), pop);
 		}
 	    }
@@ -3081,23 +3102,29 @@
       }
       case NODE_REDO:{
 	if (iseq->compile_data->redo_label) {
+	    LABEL *splabel = NEW_LABEL(0);
 	    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_INSNL(ret, nd_line(node), jump,
-		      iseq->compile_data->redo_label);
+	    ADD_INSNL(ret, nd_line(node), jump, iseq->compile_data->redo_label);
+	    ADD_ADJUST_RESTORE(ret, splabel);
 	}
 	else if (iseq->type == ISEQ_TYPE_EVAL) {
 	  redo_in_eval:
 	    COMPILE_ERROR((ERROR_ARGS "Can't escape from eval with redo"));
 	}
 	else if (iseq->compile_data->start_label) {
+	    LABEL *splabel = NEW_LABEL(0);
+
+	    debugs("redo in block");
+	    ADD_LABEL(ret, splabel);
 	    add_ensure_iseq(ret, iseq);
 	    ADD_ADJUST(ret, nd_line(node), iseq->compile_data->start_label);
-	    ADD_INSNL(ret, nd_line(node), jump,
-		      iseq->compile_data->start_label);
-	    if (!poped) { /* for stack consistency */
+	    ADD_INSNL(ret, nd_line(node), jump, iseq->compile_data->start_label);
+	    ADD_ADJUST_RESTORE(ret, splabel);
+
+	    if (!poped) {
 		ADD_INSN(ret, nd_line(node), putnil);
 	    }
 	}
@@ -3121,8 +3148,11 @@
 	    }
 	    if (ip != 0) {
 		ADD_INSN(ret, nd_line(node), putnil);
-		ADD_INSN1(ret, nd_line(node), throw,
-			  INT2FIX(level | 0x05) /* TAG_REDO */ );
+		ADD_INSN1(ret, nd_line(node), throw, INT2FIX(level | 0x05) /* TAG_REDO */ );
+
+		if (poped) {
+		    ADD_INSN(ret, nd_line(node), pop);
+		}
 	    }
 	    else {
 		COMPILE_ERROR((ERROR_ARGS "Invalid redo"));
@@ -3133,8 +3163,7 @@
       case NODE_RETRY:{
 	if (iseq->type == ISEQ_TYPE_RESCUE) {
 	    ADD_INSN(ret, nd_line(node), putnil);
-	    ADD_INSN1(ret, nd_line(node), throw,
-		      INT2FIX(0x04) /* TAG_RETRY */ );
+	    ADD_INSN1(ret, nd_line(node), throw, INT2FIX(0x04) /* TAG_RETRY */ );
 
 	    if (poped) {
 		ADD_INSN(ret, nd_line(node), pop);
@@ -3153,11 +3182,10 @@
 	LABEL *lstart = NEW_LABEL(nd_line(node));
 	LABEL *lend = NEW_LABEL(nd_line(node));
 	LABEL *lcont = NEW_LABEL(nd_line(node));
-	VALUE rescue = NEW_CHILD_ISEQVAL(node->nd_resq,
-					 rb_str_concat(rb_str_new2
-						       ("rescue in "),
-						       iseq->name),
-					 ISEQ_TYPE_RESCUE);
+	VALUE rescue = NEW_CHILD_ISEQVAL(
+	    node->nd_resq,
+	    rb_str_concat(rb_str_new2("rescue in "), iseq->name),
+	    ISEQ_TYPE_RESCUE);
 
 	ADD_LABEL(ret, lstart);
 	COMPILE(ret, "rescue head", node->nd_head);
@@ -3840,8 +3868,11 @@
 		break;
 	    }
 	    else {
+		LABEL *splabel = 0;
 
 		if (is->type == ISEQ_TYPE_METHOD) {
+		    splabel = NEW_LABEL(0);
+		    ADD_LABEL(ret, splabel);
 		    ADD_ADJUST(ret, nd_line(node), 0);
 		}
 
@@ -3850,8 +3881,10 @@
 		if (is->type == ISEQ_TYPE_METHOD) {
 		    add_ensure_iseq(ret, iseq);
 		    ADD_INSN(ret, nd_line(node), leave);
-		    if (poped) {
-			ADD_INSN(ret, nd_line(node), pop);
+		    ADD_ADJUST_RESTORE(ret, splabel);
+
+		    if (!poped) {
+			ADD_INSN(ret, nd_line(node), putnil);
 		    }
 		}
 		else {
@@ -4637,6 +4670,12 @@
 		printf("[none]\n");
 		break;
 	    }
+	  case ISEQ_ELEMENT_ADJUST:
+	    {
+		ADJUST *adjust = (ADJUST *)link;
+		printf("adjust: [label: %d]\n", adjust->label->label_no);
+		break;
+	    }
 	  default:
 	    /* ignore */
 	    rb_raise(rb_eSyntaxError, "dump_disasm_list error: %ld\n", FIX2LONG(link->type));
Index: compile.h
===================================================================
--- compile.h	(revision 15250)
+++ compile.h	(revision 15251)
@@ -167,6 +167,9 @@
 #define ADD_ADJUST(seq, line, label) \
   ADD_ELEM(seq, (LINK_ELEMENT *) new_adjust_body(iseq, label, line))
 
+#define ADD_ADJUST_RESTORE(seq, label) \
+  ADD_ELEM(seq, (LINK_ELEMENT *) new_adjust_body(iseq, label, -1))
+
 #define ADD_CATCH_ENTRY(type, ls, le, iseqv, lc)		\
     (rb_ary_push(iseq->compile_data->catch_table_ary,		\
 		 rb_ary_new3(5, type,				\

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]