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

yarv-diff:267

From: ko1 atdot.net
Date: 16 Feb 2006 10:58:39 -0000
Subject: [yarv-diff:267] r430 - in trunk: . sample test/ruby test/socket

Author: ko1
Date: 2006-02-16 19:58:39 +0900 (Thu, 16 Feb 2006)
New Revision: 430

Modified:
   trunk/
   trunk/ChangeLog
   trunk/compile.c
   trunk/disasm.c
   trunk/insns.def
   trunk/sample/test.rb
   trunk/test.rb
   trunk/test/ruby/test_readpartial.rb
   trunk/test/socket/test_tcp.rb
   trunk/thread.c
   trunk/vm.c
Log:
 r650@lermite:  ko1 | 2006-02-16 19:58:38 +0900
 	* compile.c : fix analysis of block parameter
 
 	* disasm.c : remove rb_bug() (temporarily)
 
 	* insns.def, vm.c : fix passing block parameter
 
 	* sample/test.rb : add "Proc = YARVCore::VM::Proc"
 
 	* test/ruby/test_readpartial.rb : disable on mswin32
 
 	* test/socket/test_tcp.rb : ditto
 
 	* thread.c : fix syntax error (for non GCC)
 



Property changes on: trunk
___________________________________________________________________
Name: svk:merge
   - 81cd9672-7512-7e48-ae48-6936450e977d:/local/yarv/trunk:648
   + 81cd9672-7512-7e48-ae48-6936450e977d:/local/yarv/trunk:650

Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2006-02-15 13:40:56 UTC (rev 429)
+++ trunk/ChangeLog	2006-02-16 10:58:39 UTC (rev 430)
@@ -4,6 +4,23 @@
 #  from Mon, 03 May 2004 01:24:19 +0900
 #
 
+2006-02-16(Thu) 19:51:52 +0900  Koichi Sasada  <ko1 atdot.net>
+
+	* compile.c : fix analysis of block parameter
+
+	* disasm.c : remove rb_bug() (temporarily)
+
+	* insns.def, vm.c : fix passing block parameter
+
+	* sample/test.rb : add "Proc = YARVCore::VM::Proc"
+
+	* test/ruby/test_readpartial.rb : disable on mswin32
+
+	* test/socket/test_tcp.rb : ditto
+
+	* thread.c : fix syntax error (for non GCC)
+
+
 2006-02-15(Wed) 22:34:04 +0900  Koichi Sasada  <ko1 atdot.net>
 
 	* eval_method.h : move rb_clear_cache_by_id position

Modified: trunk/compile.c
===================================================================
--- trunk/compile.c	2006-02-15 13:40:56 UTC (rev 429)
+++ trunk/compile.c	2006-02-16 10:58:39 UTC (rev 430)
@@ -138,10 +138,10 @@
     DECL_ANCHOR(list_anchor);
     yarv_iseq_t *iseq;
     NODE *node = (NODE *) narg;
+    GetISeqVal(self, iseq);
 
     debugs("[compile step 1 (traverse each node)]\n");
 
-    GetISeqVal(self, iseq);
 
     iseq->node = node;
 
@@ -788,33 +788,7 @@
 VALUE
 iseq_assemble_setup(VALUE self, VALUE args, VALUE locals, VALUE insn_ary)
 {
-    yarv_iseq_t *iseq;
-    int alen = RARRAY(args)->len, llen = RARRAY(locals)->len;
-    int i;
-
-    GetISeqVal(self, iseq);
-
-    /* setup iseq (args, locals) */
-    iseq->argc = RARRAY(args)->len;
-
-    /* TODO: rest and opt should be supported */
-    iseq->arg_simple = 1;
-
-    if (iseq->local_tbl) {
-	ruby_xfree(iseq->local_tbl);
-    }
-    iseq->local_tbl = (ID *)ALLOC_N(ID *, alen + llen);
-    iseq->local_size = alen + llen;
-
-    for (i = 0; i < alen; i++) {
-	iseq->local_tbl[i] = SYM2ID(RARRAY(args)->ptr[i]);
-    }
-    for (i = 0; i < llen; i++) {
-	iseq->local_tbl[i + alen] = SYM2ID(RARRAY(locals)->ptr[i]);
-    }
-
-    iseq->catch_table_ary = rb_ary_new();
-    // return iseq_setup(self, insn_ary, iseq);
+    /* unsupported */
     return Qnil;
 }
 
@@ -943,6 +917,7 @@
 	}
     }
 
+    /* translate to block inlining code */
     if (iseq->special_block_builder != 0) {
 	node = ((NODE * (*)(yarv_iseq_t *, NODE *, NODE *, VALUE, VALUE))
 		iseq->special_block_builder) (iseq, node, lnode->nd_var,
@@ -1003,38 +978,44 @@
 	NODE *nargs = node->nd_var;
 	switch (nd_type(nargs)) {
 	case NODE_MASGN:{
-		int i = 0;
-		if (nargs->nd_head != 0) {
-		    nargs = nargs->nd_head;
-		    while (nargs) {
-			if (nd_type(nargs->nd_head) != NODE_DASGN_CURR) {
-			    /* idx-th param, current level */
+	    NODE *massign = nargs;
+	    int i = 0;
+	    if (nargs->nd_head != 0) {
+		NODE *lhsn = massign->nd_head;
+		
+		while (lhsn) {
+		    if (nd_type(lhsn->nd_head) != NODE_DASGN_CURR) {
+			/* idx-th param, current level */
 
-			    ADD_INSN2(anchor, nd_line(node),
-				      getdynamic,
-				      INT2FIX(iseq->local_size - i),
-				      INT2FIX(0));
-			    set_block_initializer(iseq, nargs->nd_head,
-						  anchor);
-			}
-			i++;
-			nargs = nargs->nd_next;
+			ADD_INSN2(anchor, nd_line(node),
+				  getdynamic,
+				  INT2FIX(iseq->local_size - i),
+				  INT2FIX(0));
+			set_block_initializer(iseq, lhsn->nd_head,
+					      anchor);
 		    }
+		    i++;
+		    lhsn = lhsn->nd_next;
 		}
+	    }
 
-		if ((long)node->nd_var->nd_args > 0) {
-		    iseq->argc++;
-		    iseq->arg_rest = i + 1;
+	    /* check rest */
+	    if ((long)massign->nd_args > 0) {
+		iseq->argc++;
+		iseq->arg_rest = i + 1;
 
-		    if (nd_type(node->nd_var->nd_args) != NODE_DASGN_CURR) {
-			ADD_INSN2(anchor, nd_line(node), getdynamic,
-				  INT2FIX(iseq->local_size - i), INT2FIX(0));
-			set_block_initializer(iseq, node->nd_var->nd_args,
-					      anchor);
-		    }
+		if (nd_type(massign->nd_args) != NODE_DASGN_CURR) {
+		    ADD_INSN2(anchor, nd_line(node), getdynamic,
+			      INT2FIX(iseq->local_size - i), INT2FIX(0));
+		    set_block_initializer(iseq, massign->nd_args,
+					  anchor);
 		}
-		break;
 	    }
+	    else if (i == 1) {
+		iseq->arg_rest = -1;
+	    }
+	    break;
+	}
 
 	case NODE_DASGN_CURR:
 	    break;

Modified: trunk/disasm.c
===================================================================
--- trunk/disasm.c	2006-02-15 13:40:56 UTC (rev 429)
+++ trunk/disasm.c	2006-02-16 10:58:39 UTC (rev 430)
@@ -26,7 +26,7 @@
 	    return iiary[i].line_no;
 	}
     }
-    rb_bug("find_line_no: can't find %lu", pos);
+    // rb_bug("find_line_no: can't find %lu", pos);
     return 0;
 }
 

Modified: trunk/insns.def
===================================================================
--- trunk/insns.def	2006-02-15 13:40:56 UTC (rev 429)
+++ trunk/insns.def	2006-02-16 10:58:39 UTC (rev 430)
@@ -1292,7 +1292,6 @@
     iseq = block->iseq;
 
     if (BUILTIN_TYPE(iseq) != T_NODE) {
-
 	if (flag & VM_CALL_ARGS_SPLAT_BIT) {
 	    VALUE ary = TOPN(0);
 	    if (CLASS_OF(ary) != rb_cArray) {
@@ -1311,18 +1310,24 @@
 	}
 
 	if (0) {
+	    printf("     argc: %d\n", argc);
 	    printf("iseq argc: %d\n", iseq->argc);
 	    printf("iseq rest: %d\n", iseq->arg_rest);
 	    printf("iseq blck: %d\n", iseq->arg_block);
 	}
 
-	if (iseq->argc == 1) {
+	if (iseq->argc == 1 && iseq->arg_rest != -1) {
+	    /* TODO: for backward compatibility */
 	    if (argc > 1) {
-		/* TODO: for backward compatibility */
 		INC_SP(1 - argc);
 		*(GET_SP() - 1) = rb_ary_new4(argc, GET_SP() - 1);
 		argc = 1;
 	    }
+	    else if (iseq->arg_rest > 0) {
+		INC_SP(1 - argc);
+		*(GET_SP() - 1) = rb_ary_new4(argc, GET_SP() - 1);
+		argc = 1;
+	    }
 	}
 	else {
 	    if (argc == 1) {
@@ -1340,27 +1345,31 @@
 		}
 	    }
 	    if (iseq->arg_rest != 0) {
-		/*
-		 * a1 a2 a3 r1 r2 r3 _
-		 *          ^r (=3)  ^sp, argc = 6
-		 */
-		int rest = iseq->arg_rest - 1;
-		int alen;
-		VALUE *rv = GET_SP() - (argc - rest);
-
-		if (argc > rest) {
-		    alen = argc - rest;
+		if (iseq->arg_rest == -1) {
 		}
 		else {
-		    VALUE *p = GET_SP();
-		    while (p != rv) {
-			*p++ = Qnil;
+		    /*
+		     * a1 a2 a3 r1 r2 r3 _
+		     *          ^r (=3)  ^sp, argc = 6
+		     */
+		    int rest = iseq->arg_rest - 1;
+		    int alen;
+		    VALUE *rv = GET_SP() - (argc - rest);
+
+		    if (argc > rest) {
+			alen = argc - rest;
 		    }
-		    alen = 0;
+		    else {
+			VALUE *p = GET_SP();
+			while (p != rv) {
+			    *p++ = Qnil;
+			}
+			alen = 0;
+		    }
+		    argc = rest + 1;
+		    *rv = rb_ary_new4(alen, rv);
+		    SET_SP(rv + 1);
 		}
-		argc = rest + 1;
-		*rv = rb_ary_new4(alen, rv);
-		SET_SP(rv + 1);
 	    }
 	}
 

Modified: trunk/sample/test.rb
===================================================================
--- trunk/sample/test.rb	2006-02-15 13:40:56 UTC (rev 429)
+++ trunk/sample/test.rb	2006-02-16 10:58:39 UTC (rev 430)
@@ -1,5 +1,7 @@
 #! /usr/bin/env ruby
 
+Proc = YARVCore::VM::Proc
+
 $KCODE = "none"
 $testnum=0
 $ntest=0

Modified: trunk/test/ruby/test_readpartial.rb
===================================================================
--- trunk/test/ruby/test_readpartial.rb	2006-02-15 13:40:56 UTC (rev 429)
+++ trunk/test/ruby/test_readpartial.rb	2006-02-16 10:58:39 UTC (rev 430)
@@ -49,6 +49,7 @@
       assert_equal('ab', r.readpartial(2))
       assert_equal('c', r.readpartial(2))
 assert false, "TODO: doesn't work on cygwin" if /cygwin/ =~ RUBY_PLATFORM
+assert false, "TODO: doesn't work on mswin32" if /mswin32/ =~ RUBY_PLATFORM
       assert_raises(TimeoutError) {
         timeout(0.1) { r.readpartial(2) }
       }
@@ -64,6 +65,7 @@
       assert_equal("f\n", r.readpartial(4096))
       assert_equal("ghi\n", r.readpartial(4096))
 assert false, "TODO: doesn't work on cygwin" if /cygwin/ =~ RUBY_PLATFORM
+assert false, "TODO: doesn't work on mswin32" if /mswin32/ =~ RUBY_PLATFORM
       assert_raises(TimeoutError) {
         timeout(0.1) { r.readpartial(2) }
       }

Modified: trunk/test/socket/test_tcp.rb
===================================================================
--- trunk/test/socket/test_tcp.rb	2006-02-15 13:40:56 UTC (rev 429)
+++ trunk/test/socket/test_tcp.rb	2006-02-16 10:58:39 UTC (rev 430)
@@ -7,6 +7,7 @@
 
 class TestTCPSocket < Test::Unit::TestCase
   def test_recvfrom # [ruby-dev:24705]
+assert false, "TODO: doesn't work on mswin32" if /mswin32/ =~ RUBY_PLATFORM
     c = s = nil
     svr = TCPServer.new("localhost", 0)
     th = Thread.new {

Modified: trunk/test.rb
===================================================================
--- trunk/test.rb	2006-02-15 13:40:56 UTC (rev 429)
+++ trunk/test.rb	2006-02-16 10:58:39 UTC (rev 430)
@@ -1,3 +1,86 @@
+lambda{|*x| p x}.call
+
+__END__
+
+Proc.new{|a, b| p [a, b]}.call(1, 2, 3)
+
+__END__
+{1=>2, 3=>4}.delete_if{|a,|
+  p [a, ]
+}
+__END__
+
+
+def test_ok arg, foo=true
+  p arg
+end
+
+def marity_test(m)
+  method = self.method(m)
+  test_ok(method.arity == method.to_proc.arity, 2)
+end
+marity_test(:test_ok)
+marity_test(:marity_test)
+marity_test(:p)
+
+__END__
+def f; yield [[]]; end; f {|a,| p a; test_ok(a == [])}
+def f; yield *[[]]; end; f {|a,| p a; test_ok(a == [])}
+
+__END__
+def f; yield []; end; f {|a,b,| p a; test_ok(a == nil)}
+def f; yield [1]; end; f {|a,| test_ok(a == 1)}
+def f; yield [nil]; end; f {|a,| test_ok(a == nil)}
+def f; yield [[]]; end; f {|a,| test_ok(a == [])}
+def f; yield [*[]]; end; f {|a,| test_ok(a == nil)}
+def f; yield [*[1]]; end; f {|a,| test_ok(a == 1)}
+def f; yield [*[1,2]]; end; f {|a,| test_ok(a == 1)}
+
+__END__
+
+f = lambda{|*x| p x; x}
+test_ok(f.call(42) == [42])
+test_ok(f.call([42]) == [[42]])
+test_ok(f.call([[42]]) == [[[42]]])
+test_ok(f.call([42,55]) == [[42,55]])
+test_ok(f.call(42,55) == [42,55])
+
+__END__
+
+
+__END__
+def iter
+  yield 1
+end
+
+iter{|*x|p x}
+#iter{|*|p x}
+iter{|x,|p x}
+__END__
+
+lambda  {|*x| p x}.call
+Proc.new{|*x| p x}.call
+__END__
+
+
+def iter
+  yield 1, 2, 3, 4
+end
+
+iter{|x, y,|
+  p [x, y]
+}
+
+
+__END__
+
+require 'set'
+
+set = Set.new(1..10)
+ret = set.delete_if { |i| p i; i > 10 }
+
+__END__
+
 p Proc === Proc.new{} #=> false
 __END__
 a = 1

Modified: trunk/thread.c
===================================================================
--- trunk/thread.c	2006-02-15 13:40:56 UTC (rev 429)
+++ trunk/thread.c	2006-02-16 10:58:39 UTC (rev 430)
@@ -652,9 +652,10 @@
 rb_thread_kill(VALUE thread)
 {
     yarv_thread_t *th;
-    GetThreadVal(thread, th);
     int status;
 
+    GetThreadVal(thread, th);
+
     if (th != GET_THREAD() && th->safe_level < 4) {
 	rb_secure(4);
     }

Modified: trunk/vm.c
===================================================================
--- trunk/vm.c	2006-02-15 13:40:56 UTC (rev 429)
+++ trunk/vm.c	2006-02-16 10:58:39 UTC (rev 430)
@@ -543,34 +543,40 @@
     return val;
 }
 
-VALUE
-th_invoke_yield(yarv_thread_t *th, int argc, VALUE *argv)
+static int
+th_yield_setup_args(yarv_iseq_t *iseq, int argc, VALUE *argv, VALUE **ret)
 {
-    yarv_control_frame_t *cfp = th->cfp;
-    yarv_block_t *block = GC_GUARDED_PTR_REF(cfp->lfp[0]);
-    VALUE val;
-    if (block == 0) {
-	th_localjump_error("no block given", Qnil, 0);
+    if (0) {
+	printf("     argc: %d\n", argc);
+	printf("iseq argc: %d\n", iseq->argc);
+	printf("iseq rest: %d\n", iseq->arg_rest);
+	printf("iseq blck: %d\n", iseq->arg_block);
     }
+
+    if (iseq->argc == 1 && iseq->arg_rest != -1) {
+	if (argc > 1) {
+	    argv[0] = rb_ary_new4(argc, argv);
+	    argc = 1;
+	}
+	else if (iseq->arg_rest > 0) {
+	    argv[0] = rb_ary_new4(argc, argv);
+	    argc = 1;
+	}
+    }
     else {
-	if (BUILTIN_TYPE(block->iseq) != T_NODE) {
-	    if (block->iseq->argc == 1) {
-		if (argc > 1) {
-		    argv[0] = rb_ary_new4(argc, argv);
-		    argc = 1;
-		}
+	if (argc == 1 && !SPECIAL_CONST_P(argv[0]) &&
+	    BUILTIN_TYPE(argv[0]) == T_ARRAY) {
+	    argc = RARRAY(argv[0])->len;
+	    argv = RARRAY(argv[0])->ptr;
+	}
+	
+	if (iseq->arg_rest != 0) {
+	    if (iseq->arg_rest == -1) {
+		/* */
 	    }
 	    else {
-		if (argc == 1 && !SPECIAL_CONST_P(argv[0]) &&
-		    BUILTIN_TYPE(argv[0]) == T_ARRAY) {
-		    argc = RARRAY(argv[0])->len;
-		    argv = RARRAY(argv[0])->ptr;
-		}
-	    }
+		int rest = iseq->arg_rest - 1;
 
-	    if (block->iseq->arg_rest != 0) {
-		int rest = block->iseq->arg_rest - 1;
-
 		if (argc <= rest) {
 		    VALUE ary = rb_ary_new4(argc, argv);
 		    rb_ary_store(ary, rest, rb_ary_new());
@@ -582,12 +588,37 @@
 		    argc = rest + 1;
 		}
 	    }
+	}
+    }
+    if (argc > iseq->argc) {
+	argc = iseq->argc;
+    }
 
+    if (ret) {
+	*ret = argv;
+    }
+    return argc;
+}
+
+VALUE
+th_invoke_yield(yarv_thread_t *th, int argc, VALUE *argv)
+{
+    yarv_control_frame_t *cfp = th->cfp;
+    yarv_block_t *block = GC_GUARDED_PTR_REF(cfp->lfp[0]);
+    VALUE val;
+    if (block == 0) {
+	th_localjump_error("no block given", Qnil, 0);
+    }
+    else {
+	if (BUILTIN_TYPE(block->iseq) != T_NODE) {
+	    yarv_iseq_t *iseq = block->iseq;
+	    argc = th_yield_setup_args(iseq, argc, argv, &argv);
+
 	    th_set_finish_env(th);
-	    th_set_env(th, block->iseq, FRAME_MAGIC_BLOCK,
+	    th_set_env(th, iseq, FRAME_MAGIC_BLOCK,
 		       block->self, GC_GUARDED_PTR(block->dfp),
-		       block->iseq->iseq_encoded, th->cfp->sp, block->lfp,
-		       block->iseq->local_size, argc, argv);
+		       iseq->iseq_encoded, th->cfp->sp, block->lfp,
+		       iseq->local_size, argc, argv);
 	    val = th_eval_body(th);
 	}
 	else {
@@ -605,6 +636,7 @@
 	return th_invoke_yield_cfunc(th, &proc->block, argc, argv);
     }
     else {
+	argc = th_yield_setup_args(proc->block.iseq, argc, argv, &argv);
 	th_set_finish_env(th);
 	th_set_env(th, proc->block.iseq,
 		   FRAME_MAGIC_PROC, self, (VALUE)proc->block.dfp,


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

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