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