[前][次][番号順一覧][スレッド一覧][生データ]

yarv-diff:133

From: ko1 atdot.net
Date: 18 Nov 2005 20:59:48 -0000
Subject: [yarv-diff:133] r290 - in trunk: . yarvtest

Author: ko1
Date: 2005-11-19 05:59:48 +0900 (Sat, 19 Nov 2005)
New Revision: 290

Modified:
   trunk/ChangeLog
   trunk/compile.c
   trunk/compile.h
   trunk/eval.c
   trunk/eval_proc.c
   trunk/insns.def
   trunk/test.rb
   trunk/vm.c
   trunk/vm_dump.c
   trunk/yarvcore.c
   trunk/yarvtest/test_syn.rb
Log:
	* compile.c : useless jump elimination (if/unless destination)

	* eval.c : rb_iter_break support,
	 fix rb_iterate (clear errinfo if break)

	* eval_proc.c : support rb_node_arity (YARV_METHOD_NODE)

	* insns.def : change variable name

	* vm.c : fix th_invoke_yield and add th_iter_break()

	* vm_dump.c : fix yarv_bug()

	* yarvcore.c : fix proc_mark to check IFUNC node and add
	global ruby method SDR() for debug

	* yarvtest/test_syn.rb : add a test for all condition combination



Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2005-11-14 21:00:51 UTC (rev 289)
+++ trunk/ChangeLog	2005-11-18 20:59:48 UTC (rev 290)
@@ -4,7 +4,27 @@
 #  from Mon, 03 May 2004 01:24:19 +0900
 #
 
+2005-11-19(Sat) 05:48:50 +0900  Koichi Sasada  <ko1 atdot.net>
 
+	* compile.c : useless jump elimination (if/unless destination)
+
+	* eval.c : rb_iter_break support,
+	 fix rb_iterate (clear errinfo if break)
+
+	* eval_proc.c : support rb_node_arity (YARV_METHOD_NODE)
+
+	* insns.def : change variable name
+
+	* vm.c : fix th_invoke_yield and add th_iter_break()
+
+	* vm_dump.c : fix yarv_bug()
+
+	* yarvcore.c : fix proc_mark to check IFUNC node and add
+	global ruby method SDR() for debug
+
+	* yarvtest/test_syn.rb : add a test for all condition combination
+
+
 2005-11-15(Tue) 05:52:58 +0900  Koichi Sasada  <ko1 atdot.net>
 
 	* lib/forwardable.rb : added

Modified: trunk/compile.c
===================================================================
--- trunk/compile.c	2005-11-14 21:00:51 UTC (rev 289)
+++ trunk/compile.c	2005-11-18 20:59:48 UTC (rev 290)
@@ -66,7 +66,9 @@
 static void debug_list(LINK_ANCHOR *anchor);
 #endif
 
+void dump_disasm_anchor(LINK_ANCHOR *anc);
 void dump_disasm_list(LINK_ELEMENT* elem);
+
 static int insn_data_length(INSN *insnobj);
 static int insn_data_line_no(INSN *insnobj);
 static int insn_ret_num(int insn);
@@ -237,7 +239,7 @@
      iseqobj->type == ISEQ_TYPE_ENSURE){
     
     ADD_INSN2(list_anchor, 0, getdynamic, I2F(1), I2F(0));
-    ADD_INSN1(list_anchor, 0, throw, I2F(0));
+    ADD_INSN1(list_anchor, 0, throw, I2F(0) /* continue throw */);
   }
   else{
     ADD_INSN(list_anchor, iseqobj->compile_data->last_line, end);
@@ -429,10 +431,6 @@
   return anchor->anchor.next;
 }
 
-static void dump_disasm_anchor(LINK_ANCHOR *anc){
-  dump_disasm_list(FIRST_ELEMENT(anc));
-}
-
 static LINK_ELEMENT *
 LAST_ELEMENT(LINK_ANCHOR *anchor)
 {
@@ -1426,22 +1424,23 @@
 iseq_optimize(yarv_iseq_t *iseqobj, LINK_ANCHOR *anchor)
 {
   LINK_ELEMENT *list;
-  /*
-   *  useless jump elimination:
-   *     jump LABEL1
-   *     ...
-   *   LABEL1:
-   *     jump LABEL2
-   *
-   *   => in this case, first jump instruction should jump tp
-   *      LABEL2 directly
-   */
   list = FIRST_ELEMENT(anchor);
   // dump_disasm_list(list);
   while(list){
     if(list->type == ISEQ_ELEMENT_INSN){
-      INSN *niobj, *diobj, *piobj, *iobj = (INSN *)list;
+      INSN *iobj = (INSN *)list;
       if(iobj->insn_id == BIN(jump)){
+        INSN *niobj, *diobj, *piobj;
+        /*
+         *  useless jump elimination:
+         *     jump LABEL1
+         *     ...
+         *   LABEL1:
+         *     jump LABEL2
+         *
+         *   => in this case, first jump instruction should jump tp
+         *      LABEL2 directly
+         */
         diobj = (INSN*)get_destination_insn(iobj);
         niobj = (INSN*)get_next_insn(iobj);
         
@@ -1460,6 +1459,7 @@
                        (LINK_ELEMENT *)eiobj);
         }
         /*
+         * useless jump elimination (if/unless destination):
          *   if   L1
          *   jump L2
          * L1:
@@ -1481,7 +1481,26 @@
             REMOVE_ELEM(&iobj->link);
           }
         }
+        if(0){
+          debugs("jump: \n");
+          dump_disasm_anchor(anchor);
+        }
       }
+      if(iobj->insn_id == BIN(if) ||
+         iobj->insn_id == BIN(unless)){
+        /*
+         *   if L1
+         *   ...
+         * L1:
+         *   jump L2
+         * =>
+         *   if L2
+         */
+        INSN *nobj = (INSN *)get_destination_insn(iobj);
+        if(nobj->insn_id == BIN(jump)){
+          OPERAND_AT(iobj, 0) = OPERAND_AT(nobj, 0);
+        }
+      }
 
       if(iobj->insn_id == BIN(end)){
         INSN *piobj = (INSN*)get_prev_insn((INSN*)list);
@@ -1818,7 +1837,7 @@
     break;
   }
   default:
-    COMPILE(ret, "branch condition", cond);
+    COMPILE  (ret, "branch condition", cond);
     ADD_INSNL(ret, nd_line(cond), unless, else_label);
     ADD_INSNL(ret, nd_line(cond), jump,   then_label);
     break;
@@ -2580,9 +2599,9 @@
       ADD_INSNL(ret, nd_line(node), jump, iseqobj->compile_data->end_label);
     }
     else if(iseqobj->type == ISEQ_TYPE_BLOCK){
-    break_by_jump:
+    break_by_insn:
       /* escape from block */
-      COMPILE(ret, "break val(block)", node->nd_stts);
+      COMPILE(ret, "break val (block)", node->nd_stts);
       ADD_INSN1(ret, nd_line(node), throw, I2F(level | 0x02) /* TAG_BREAK */);
     }
     else{
@@ -2592,20 +2611,19 @@
         level++;
         if(ip->type == ISEQ_TYPE_BLOCK){
           level <<= 16;
-          goto break_by_jump;
+          goto break_by_insn;
         }
         else if(ip->compile_data->redo_label != 0){
           level = 0x8000;
           if(ip->compile_data->loopval_popped == 0){
             level |= 0x4000;
           }
-          goto break_by_jump;
+          goto break_by_insn;
         }
         ip = ip->parent_iseq;
       }
       COMPILE_ERROR(("can't put break"));
     }
-
     break;
   }
   case NODE_NEXT:{
@@ -2821,7 +2839,7 @@
                     node->nd_head,  /* lhsn  */
                     0);
     if(!poped){
-      ADD_INSN(ret, nd_line(node), putnil);
+      ADD_INSN1(ret, nd_line(node), putobject, Qtrue);
     }
     break;
   }
@@ -4131,6 +4149,11 @@
 }
 
 void
+dump_disasm_anchor(LINK_ANCHOR *anc){
+  dump_disasm_list(FIRST_ELEMENT(anc));
+}
+
+void
 dump_disasm_list(struct iseq_link_element *link)
 {
   int pos = 0;

Modified: trunk/compile.h
===================================================================
--- trunk/compile.h	2005-11-14 21:00:51 UTC (rev 289)
+++ trunk/compile.h	2005-11-18 20:59:48 UTC (rev 290)
@@ -28,7 +28,7 @@
 
 #if 0
 #undef  CPDEBUG
-#define CPDEBUG 2
+#define CPDEBUG 10
 #endif
 
 #if CPDEBUG > 0

Modified: trunk/eval.c
===================================================================
--- trunk/eval.c	2005-11-14 21:00:51 UTC (rev 289)
+++ trunk/eval.c	2005-11-18 20:59:48 UTC (rev 290)
@@ -893,13 +893,12 @@
     return Qfalse;
 }
 
+NORETURN(void th_iter_break _((yarv_thread_t *)));
 
-
-
 void
 rb_iter_break()
 {
-  UNSUPPORTED(rb_iter_break)
+  th_iter_break(GET_THREAD());
 }
 
 NORETURN(static void rb_longjmp _((int, VALUE)));
@@ -1186,11 +1185,11 @@
       argc = RARRAY(argv[0])->len;
       argv = RARRAY(argv[0])->ptr;
     }
-
     return th_invoke_yield(GET_THREAD(), argc, argv);
   }
 }
 
+
 VALUE
 rb_yield(val)
     VALUE val;
@@ -1290,14 +1289,18 @@
   else if (state == TAG_BREAK /* TODO: more check */ ) {
     // TODO: Fix me
     state = 0;
+    th->state = 0;
+    th->errinfo = Qnil;
   }
   else if (state == TAG_RETRY) {
     state = 0;
+    th->state = 0;
+    th->errinfo = Qnil;
     goto iter_retry;
   }
   TH_POP_TAG();
 
-  switch (state) {
+  switch (state){
   case 0:
     break;
   default:

Modified: trunk/eval_proc.c
===================================================================
--- trunk/eval_proc.c	2005-11-14 21:00:51 UTC (rev 289)
+++ trunk/eval_proc.c	2005-11-18 20:59:48 UTC (rev 290)
@@ -831,35 +831,45 @@
 }
 
 int
-rb_node_arity(body)
-    NODE *body;
+rb_node_arity(NODE *body)
 {
-    int n;
+  int n;
 
-    switch (nd_type(body)) {
-      case NODE_CFUNC:
-	if (body->nd_argc < 0) return -1;
-	return body->nd_argc;
-      case NODE_ZSUPER:
-	return -1;
-      case NODE_ATTRSET:
-	return 1;
-      case NODE_IVAR:
-	return 0;
-      case NODE_BMETHOD:
-	return rb_proc_arity(body->nd_cval);
-      case NODE_SCOPE:
-	body = body->nd_next;	/* skip NODE_SCOPE */
-	if (nd_type(body) == NODE_BLOCK)
-	    body = body->nd_head;
-	if (!body) return 0;
-	n = body->nd_frml ? RARRAY(body->nd_frml)->len : 0;
-	if (body->nd_opt || body->nd_rest)
-	    n = -n-1;
-	return n;
-      default:
-	rb_raise(rb_eArgError, "invalid node 0x%x", nd_type(body));
+  switch (nd_type(body)) {
+  case NODE_CFUNC:
+    if (body->nd_argc < 0) return -1;
+    return body->nd_argc;
+  case NODE_ZSUPER:
+    return -1;
+  case NODE_ATTRSET:
+    return 1;
+  case NODE_IVAR:
+    return 0;
+  case NODE_BMETHOD:
+    return rb_proc_arity(body->nd_cval);
+  case NODE_SCOPE:
+    body = body->nd_next;	/* skip NODE_SCOPE */
+    if (nd_type(body) == NODE_BLOCK)
+      body = body->nd_head;
+    if (!body) return 0;
+    n = body->nd_frml ? RARRAY(body->nd_frml)->len : 0;
+    if (body->nd_opt || body->nd_rest)
+      n = -n-1;
+    return n;
+  case YARV_METHOD_NODE:{
+    yarv_iseq_t *iseq;
+    GetISeqVal((VALUE)body->nd_body, iseq);
+    if(iseq->arg_rest == 0 &&
+       iseq->arg_opts == 0){
+      return iseq->argc;
     }
+    else{
+      return -iseq->argc-1;
+    }
+  }
+  default:
+    rb_raise(rb_eArgError, "invalid node 0x%x", nd_type(body));
+  }
 }
 
 /*
@@ -998,7 +1008,6 @@
 bmcall(VALUE args, VALUE method)
 {
   volatile VALUE a;
-
   if(CLASS_OF(args) != rb_cArray){
     args = rb_ary_new3(1, args);
   }

Modified: trunk/insns.def
===================================================================
--- trunk/insns.def	2005-11-14 21:00:51 UTC (rev 289)
+++ trunk/insns.def	2005-11-18 20:59:48 UTC (rev 290)
@@ -1518,7 +1518,7 @@
       }
     }
     else{
-      if(state == TAG_BREAK || throw_state == TAG_RETRY){
+      if(state == TAG_BREAK || state == TAG_RETRY){
         pt = GC_GUARDED_PTR_REF((VALUE*)*GET_DFP());
         for(i=0; i<level; i++){
           pt = GC_GUARDED_PTR_REF((VALUE*)*pt);

Modified: trunk/test.rb
===================================================================
--- trunk/test.rb	2005-11-14 21:00:51 UTC (rev 289)
+++ trunk/test.rb	2005-11-18 20:59:48 UTC (rev 290)
@@ -1,2 +1,12 @@
 
+$:.unshift './lib'
+
 require 'test/unit'
+GC.start
+class Foo < Test::Unit::TestCase
+  def test_foo
+    assert_equal(1, 2)
+  end
+end
+
+

Modified: trunk/vm.c
===================================================================
--- trunk/vm.c	2005-11-14 21:00:51 UTC (rev 289)
+++ trunk/vm.c	2005-11-18 20:59:48 UTC (rev 290)
@@ -511,7 +511,7 @@
         }
       }
       else{
-        if(argc == 1 && !IMMEDIATE_P(argv[0]) &&
+        if(argc == 1 && !SPECIAL_CONST_P(argv[0]) &&
            BUILTIN_TYPE(argv[0]) == T_ARRAY){
           argc = RARRAY(argv[0])->len;
           argv = RARRAY(argv[0])->ptr;
@@ -795,8 +795,6 @@
   return th_backtrace(th, level);
 }
 
-
-
 /*
  *
  * vm main loop helper functions
@@ -1021,6 +1019,15 @@
   rb_exc_raise(exc);
 }
 
+void
+th_iter_break(yarv_thread_t *th){
+  yarv_control_frame_t *cfp = th->cfp;
+  VALUE *dfp = GC_GUARDED_PTR_REF(*cfp->dfp);
+  
+  th->state = TAG_BREAK;
+  th->errinfo = (VALUE)NEW_THROW_OBJECT(Qnil, (VALUE)dfp, TAG_BREAK);
+  TH_JUMP_TAG(th, TAG_BREAK);
+}
 
 VALUE yarv_unredefined_flag = 0x01;
 
@@ -1167,9 +1174,12 @@
     
   exception_handler:
     cont_pc = cont_sp = catch_iseqval = 0;
-    while(th->cfp->pc == 0 || th->cfp->iseq == 0){
+    
+    while(th->cfp->pc == 0 ||
+          th->cfp->iseq == 0){
       th->cfp++;
     }
+    
     cfp = th->cfp;
     epc = cfp->pc - cfp->iseq->iseq_encoded;
 

Modified: trunk/vm_dump.c
===================================================================
--- trunk/vm_dump.c	2005-11-14 21:00:51 UTC (rev 289)
+++ trunk/vm_dump.c	2005-11-18 20:59:48 UTC (rev 290)
@@ -487,6 +487,10 @@
 void
 yarv_bug(){
   yarv_thread_t *th = GET_THREAD();
-  dp(th_backtrace(th, 0));
+  VALUE bt = th_backtrace(th, 0);
+  int i;
+  for(i=0; i<RARRAY(bt)->len; i++){
+    dp(RARRAY(bt)->ptr[i]);
+  }
   SDR();
 }

Modified: trunk/yarvcore.c
===================================================================
--- trunk/yarvcore.c	2005-11-14 21:00:51 UTC (rev 289)
+++ trunk/yarvcore.c	2005-11-18 20:59:48 UTC (rev 290)
@@ -65,24 +65,28 @@
 
 #if MARK_FREE_DEBUG
 static int g_indent = 0;
-static void gc_debug_indent(){
+
+static void
+gc_debug_indent(){
   int i;
   for(i=0; i<g_indent; i++){
     printf(" ");
   }
 }
-void MARK_REPORT(char *msg, int st){
+static void
+MARK_REPORT_BODY(char *msg, int st, void *ptr){
   if(st == 0){
     g_indent--;
   }
   gc_debug_indent();
-  printf("mark: %s\n", msg);
+  printf("mark: %s (%p)\n", msg, ptr);
   if(st){
     g_indent++;
   }
 }
+#define MARK_REPORT(msg, st) MARK_REPORT_BODY(msg, st, ptr)
 #define GC_INFO gc_debug_indent(); printf
-#define FREE_REPORT(msg) printf("free: %s\n", msg)
+#define FREE_REPORT(msg) printf("free: %s (%p)\n", msg, ptr)
 
 #else
 #define MARK_REPORT(msg, st)
@@ -775,9 +779,13 @@
   yarv_proc_t *proc;
   MARK_REPORT("-> proc", 1);
   if(ptr){
+    
     proc = ptr;
     MARK_UNLESS_NULL(proc->envval);
     MARK_UNLESS_NULL(proc->blockprocval);
+    if(BUILTIN_TYPE(proc->block.iseq) == T_NODE){
+      MARK_UNLESS_NULL((VALUE)(proc->block.iseq));
+    }
   }
   MARK_REPORT("<- proc", 0);
 }
@@ -831,6 +839,11 @@
 VALUE Init_yarvthread();
 extern VALUE *rb_gc_stack_start;
 
+VALUE
+sdr(){
+  yarv_bug();
+  return Qnil;
+}
 char yarv_version[0x20];
 char *yarv_options = ""
 #if   OPT_DIRECT_THREADED_CODE
@@ -934,6 +947,7 @@
   rb_define_global_function("once", yarv_once, 0);
   rb_define_global_function("cfunc", cfunc, 0);
   rb_define_global_function("yarv_caller", yarv_caller, 1);
+  rb_define_global_function("SDR", sdr, 0);
   
   /* Integer#times */
   rb_define_method(rb_cInteger, "times", yarv_Integer_times, 0);

Modified: trunk/yarvtest/test_syn.rb
===================================================================
--- trunk/yarvtest/test_syn.rb	2005-11-14 21:00:51 UTC (rev 289)
+++ trunk/yarvtest/test_syn.rb	2005-11-18 20:59:48 UTC (rev 290)
@@ -454,8 +454,70 @@
       defined?(a.class)
     }
   end
-  
-end
 
+  def test_condition
+    ae %q{
 
+      def make_perm ary, num
+        if num == 1
+          ary.map{|e| [e]}
+        else
+          base = make_perm(ary, num-1)
+          res  = []
+          base.each{|b|
+            ary.each{|e|
+              res << [e] + b
+            }
+          }
+          res
+        end
+      end
+      
+      def each_test
+        conds = make_perm(['fv', 'tv'], 3)
+        bangs = make_perm(['', '!'], 3)
+        exprs = make_perm(['and', 'or'], 3)
+        ['if', 'unless'].each{|syn|
+          conds.each{|cs|
+            bangs.each{|bs|
+              exprs.each{|es|
+                yield(syn, cs, bs, es)
+              }
+            }
+          }
+        }
+      end
+      
+      fv = false
+      tv = true
+      
+      $ans = []
+      each_test{|syn, conds, bangs, exprs|
+        c1, c2, c3 = conds
+        bang1, bang2, bang3 = bangs
+        e1, e2 = exprs
+        eval %Q{
+          #{syn} #{bang1}#{c1} #{e1} #{bang2}#{c2} #{e2} #{bang3}#{c3}
+            $ans << :then
+          else
+            $ans << :false
+          end
+        }
+      }
+    
+      each_test{|syn, conds, bangs, exprs|
+        c1, c2, c3 = conds
+        bang1, bang2, bang3 = bangs
+        e1, e2 = exprs
+        eval %Q{
+          #{syn} #{bang1}#{c1} #{e1} #{bang2}#{c2} #{e2} #{bang3}#{c3}
+            $ans << :then
+          end
+          $ans << :sep
+        }
+      }
+      $ans
+    }
+  end
+end
 


-- 
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml

[前][次][番号順一覧][スレッド一覧][生データ]