yarv-diff:85
From: ko1 atdot.net
Date: 15 Aug 2005 23:33:22 -0000
Subject: [yarv-diff:85] r241 - in trunk: . rb yarvtest
Author: ko1
Date: 2005-08-16 08:33:21 +0900 (Tue, 16 Aug 2005)
New Revision: 241
Added:
trunk/rb/parse.rb
trunk/yarvtest/test_yield.rb
Modified:
trunk/ChangeLog
trunk/common.mk
trunk/compile.c
trunk/eval.c
trunk/insns.def
trunk/test.rb
trunk/test1.rb
trunk/vm.c
trunk/yarvcore.c
trunk/yarvtest/test_method.rb
Log:
* eval.c : fix to support rb_yield_0 with multiple values
* common.mk : add parse, run1p ruelse
* compile.c : support yield with ARGSCAT/SPLAT
* vm.c, insns.def : fix yield arguments to do compatible behaviour
* yarvtest/test_yield.rb : added for above
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2005-08-15 21:01:19 UTC (rev 240)
+++ trunk/ChangeLog 2005-08-15 23:33:21 UTC (rev 241)
@@ -4,6 +4,19 @@
# from Mon, 03 May 2004 01:24:19 +0900
#
+2005-08-16(Tue) 08:29:47 +0900 Koichi Sasada <ko1 atdot.net>
+
+ * eval.c : fix to support rb_yield_0 with multiple values
+
+ * common.mk : add parse, run1p ruelse
+
+ * compile.c : support yield with ARGSCAT/SPLAT
+
+ * vm.c, insns.def : fix yield arguments to do compatible behaviour
+
+ * yarvtest/test_yield.rb : added for above
+
+
2005-08-16(Tue) 06:00:17 +0900 Koichi Sasada <ko1 atdot.net>
* insns.def : fix to set klass_nest_stack on singleton
@@ -11,6 +24,7 @@
* yarvtest/test_method.rb : add a test for above
+
2005-08-16(Tue) 05:34:48 +0900 Koichi Sasada <ko1 atdot.net>
* test1.rb : added. gdb and run1 rule run this script
Modified: trunk/common.mk
===================================================================
--- trunk/common.mk 2005-08-15 21:01:19 UTC (rev 240)
+++ trunk/common.mk 2005-08-15 23:33:21 UTC (rev 241)
@@ -400,6 +400,13 @@
run1: all
$(MINIRUBY) $(srcdir)/test1.rb
+parse: all
+ $(MINIRUBY) $(srcdir)/rb/parse.rb $(srcdir)/test1.rb
+
+run1p: all
+ $(MINIRUBY) $(srcdir)/rb/parse.rb $(srcdir)/test1.rb
+ $(MINIRUBY) $(srcdir)/test1.rb
+
benchmark: all
$(BASERUBY) -I$(srcdir) $(srcdir)/benchmark/run_rite.rb $(OPT) $(ITEMS) --yarv-program=$(MINIRUBY) --ruby-program=$(BASERUBY)
Modified: trunk/compile.c
===================================================================
--- trunk/compile.c 2005-08-15 21:01:19 UTC (rev 240)
+++ trunk/compile.c 2005-08-15 23:33:21 UTC (rev 241)
@@ -3045,6 +3045,7 @@
case NODE_YIELD:{
DECL_ANCHOR(args);
int argc;
+ unsigned long flag = 0;
if(iseqobj->type == ISEQ_TYPE_TOP ||
iseqobj->type == ISEQ_TYPE_CLASS){
@@ -3059,15 +3060,32 @@
debugs("argc: %d\n", argc);
}
else{
- COMPILE(args, "nd_head(1)", node->nd_head);
- argc = 1;
+ if(nd_type(node->nd_head) == NODE_ARGSCAT){
+ flag |= VM_CALL_ARGS_SPLAT_BIT;
+
+ compile_array(self, iseqobj, args, node->nd_head->nd_head, Qfalse);
+ POP_ELEMENT(args);
+ argc = LIST_SIZE(args) + 1;
+
+ COMPILE(args, "args(cat: splat)", node->nd_head->nd_body);
+ }
+ else if(nd_type(node->nd_head) == NODE_SPLAT){
+ flag |= VM_CALL_ARGS_SPLAT_BIT;
+
+ argc = 1;
+ COMPILE(args, "splat", node->nd_head->nd_head);
+ }
+ else{
+ COMPILE(args, "nd_head(1)", node->nd_head);
+ argc = 1;
+ }
}
}
else{
argc = 0;
}
ADD_SEQ (ret, args);
- ADD_INSN2(ret, nd_line(node), yield, I2F(argc), I2F(0));
+ ADD_INSN2(ret, nd_line(node), yield, I2F(argc), I2F(flag));
if(poped){
ADD_INSN(ret, nd_line(node), pop);
Modified: trunk/eval.c
===================================================================
--- trunk/eval.c 2005-08-15 21:01:19 UTC (rev 240)
+++ trunk/eval.c 2005-08-15 23:33:21 UTC (rev 241)
@@ -3198,7 +3198,15 @@
RARRAY(val)->len, RARRAY(val)->ptr);
}
else{
- return th_invoke_yield(GET_THREAD(), 1, &val);
+ int argc = 1;
+ VALUE *argv = &val;
+
+ if(argc == 1 && CLASS_OF(argv[0]) == rb_cValues){
+ argc = RARRAY(argv[0])->len;
+ argv = RARRAY(argv[0])->ptr;
+ }
+
+ return th_invoke_yield(GET_THREAD(), argc, argv);
}
}
Modified: trunk/insns.def
===================================================================
--- trunk/insns.def 2005-08-15 21:01:19 UTC (rev 240)
+++ trunk/insns.def 2005-08-15 23:33:21 UTC (rev 241)
@@ -1223,10 +1223,37 @@
iseq = block->iseq;
if(BUILTIN_TYPE(iseq) != T_NODE){
- if(argc > iseq->argc){
+
+ if(flag & VM_CALL_ARGS_SPLAT_BIT){
+ VALUE ary = TOPN(0);
+ if(CLASS_OF(ary) != rb_cArray){
+ /* not a [BUG] */
+ }
+ else{
+ VALUE *ptr = RARRAY(ary)->ptr;
+ VALUE *dst = GET_SP() - 1;
+ int i, len = RARRAY(ary)->len;
+ for(i=0; i<len; i++){
+ dst[i] = ptr[i];
+ }
+ argc += i-1;
+ INC_SP(i-1);
+ }
+ }
+
+ if(iseq->argc == 1 &&
+ argc > 1){
+ /* TODO: for backward compatibility */
+
+ INC_SP(1-argc);
+ *(GET_SP()-1) = rb_ary_new4(argc, GET_SP()-1);
+ argc = 1;
+ }
+ else if(argc > iseq->argc){
INC_SP(iseq->argc - argc);
- argc -= num - iseq->argc;
+ argc -= argc - iseq->argc;
}
+
th_set_env(th, iseq,
FRAME_MAGIC_BLOCK, block->self, (VALUE)block->dfp,
iseq->iseq_encoded, GET_SP(), block->lfp,
Added: trunk/rb/parse.rb
===================================================================
--- trunk/rb/parse.rb 2005-08-15 21:01:19 UTC (rev 240)
+++ trunk/rb/parse.rb 2005-08-15 23:33:21 UTC (rev 241)
@@ -0,0 +1,5 @@
+$file = ARGV[0]
+$str = ARGF.read
+puts $str
+$parsed = YARVCore::parse($str, $file, 1)
+puts $parsed.disasm
Modified: trunk/test.rb
===================================================================
--- trunk/test.rb 2005-08-15 21:01:19 UTC (rev 240)
+++ trunk/test.rb 2005-08-15 23:33:21 UTC (rev 241)
@@ -1,5 +1,14 @@
$prog = <<'__EOP__'
+def iter args
+ yield [1, 2]
+end
+iter([1]){|e|
+ p e
+}
+
+
+__END__
1.times{|e|
begin
rescue => err
Modified: trunk/test1.rb
===================================================================
--- trunk/test1.rb 2005-08-15 21:01:19 UTC (rev 240)
+++ trunk/test1.rb 2005-08-15 23:33:21 UTC (rev 241)
@@ -0,0 +1,30 @@
+def iter args
+ yield *args
+end
+
+iter([]){|a, b|
+ p [a, b]
+}
+iter([1]){|a, b|
+ p [a, b]
+}
+iter([1, 2]){|a, b|
+ p [a, b]
+}
+iter([1, 2, 3]){|a, b|
+ p [a, b]
+}
+
+iter([]){|a|
+ p [a]
+}
+iter([1]){|a|
+ p [a]
+}
+iter([1, 2]){|a|
+ p [a]
+}
+iter([1, 2, 3]){|a|
+ p [a]
+}
+
Modified: trunk/vm.c
===================================================================
--- trunk/vm.c 2005-08-15 21:01:19 UTC (rev 240)
+++ trunk/vm.c 2005-08-15 23:33:21 UTC (rev 241)
@@ -358,7 +358,9 @@
}
-VALUE th_invoke_yield(yarv_thread_t *th, int argc, VALUE *argv){
+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;
@@ -368,6 +370,21 @@
}
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;
+ }
+ }
+ else{
+ if(argc == 1 && !IMMEDIATE_P(argv[0]) &&
+ BUILTIN_TYPE(argv[0]) == T_ARRAY){
+ argc = RARRAY(argv[0])->len;
+ argv = RARRAY(argv[0])->ptr;
+ }
+ }
+
th_set_finish_env(th);
th_set_env(th, block->iseq, FRAME_MAGIC_BLOCK,
block->self, GC_GUARDED_PTR(block->dfp),
Modified: trunk/yarvcore.c
===================================================================
--- trunk/yarvcore.c 2005-08-15 21:01:19 UTC (rev 240)
+++ trunk/yarvcore.c 2005-08-15 23:33:21 UTC (rev 241)
@@ -214,7 +214,7 @@
static VALUE compile_string(VALUE str, VALUE file, VALUE line){
NODE *node;
node = rb_compile_string(StringValueCStr(file), str, NUM2INT(line));
-
+
if(ruby_nerrs > 0){
ruby_nerrs = 0;
rb_exc_raise(ruby_errinfo);
@@ -254,12 +254,14 @@
}
static VALUE yarvcore_parse(VALUE self, VALUE str, VALUE file, VALUE line){
- VALUE node = compile_string(str, file, line);
+ VALUE node;
VALUE argv[5];
VALUE iseq;
+ node = compile_string(str, file, line);
+
argv[0] = node;
- argv[1] = rb_str_new2("main");
+ argv[1] = rb_str_new2("<main>");
argv[2] = file;
argv[3] = Qfalse;
argv[4] = ISEQ_TYPE_TOP;
Modified: trunk/yarvtest/test_method.rb
===================================================================
--- trunk/yarvtest/test_method.rb 2005-08-15 21:01:19 UTC (rev 240)
+++ trunk/yarvtest/test_method.rb 2005-08-15 23:33:21 UTC (rev 241)
@@ -1,6 +1,4 @@
require 'yarvtest/yarvtest'
-
-
class TestMethod < YarvTestBase
def test_simple_method
Added: trunk/yarvtest/test_yield.rb
===================================================================
--- trunk/yarvtest/test_yield.rb 2005-08-15 21:01:19 UTC (rev 240)
+++ trunk/yarvtest/test_yield.rb 2005-08-15 23:33:21 UTC (rev 241)
@@ -0,0 +1,145 @@
+require 'yarvtest/yarvtest'
+class TestYield < YarvTestBase
+ def test_simple
+ ae %q{
+ def iter
+ yield
+ end
+ iter{
+ 1
+ }
+ }
+ end
+
+ def test_hash_each
+ ae %q{
+ h = {:a => 1}
+ a = []
+ h.each{|k, v|
+ a << [k, v]
+ }
+ h.each{|kv|
+ a << kv
+ }
+ a
+ }
+ end
+
+ def test_ary_each
+ ae %q{
+ ans = []
+ ary = [1,2,3]
+ ary.each{|a, b, c, d|
+ ans << [a, b, c, d]
+ }
+ ary.each{|a, b, c|
+ ans << [a, b, c]
+ }
+ ary.each{|a, b|
+ ans << [a, b]
+ }
+ ary.each{|a|
+ ans << [a]
+ }
+ ans
+ }
+ end
+
+ def test_iter
+ ae %q{
+ def iter *args
+ yield *args
+ end
+
+ ans = []
+ ary = [1,2,3]
+ ary.each{|a, b, c, d|
+ ans << [a, b, c, d]
+ }
+ ary.each{|a, b, c|
+ ans << [a, b, c]
+ }
+ ary.each{|a, b|
+ ans << [a, b]
+ }
+ ary.each{|a|
+ ans << [a]
+ }
+ ans
+ }
+ end
+
+ def test_iter2
+ ae %q{
+ def iter args
+ yield *args
+ end
+ ans = []
+ iter([]){|a, b|
+ ans << [a, b]
+ }
+ iter([1]){|a, b|
+ ans << [a, b]
+ }
+ iter([1, 2]){|a, b|
+ ans << [a, b]
+ }
+ iter([1, 2, 3]){|a, b|
+ ans << [a, b]
+ }
+ ans
+ }
+ ae %q{
+ def iter args
+ yield *args
+ end
+ ans = []
+
+ iter([]){|a|
+ ans << a
+ }
+ iter([1]){|a|
+ ans << a
+ }
+ iter([1, 2]){|a|
+ ans << a
+ }
+ iter([1, 2, 3]){|a|
+ ans << a
+ }
+ ans
+ }
+ end
+
+ def test_argscat
+ ae %q{
+ def iter
+ yield 1, *[2, 3]
+ end
+
+ iter{|a, b, c|
+ [a, b, c]
+ }
+ }
+ ae %q{
+ def iter
+ yield 1, *[]
+ end
+
+ iter{|a, b, c|
+ [a, b, c]
+ }
+ }
+ ae %q{
+ def iter
+ yield 1, *2
+ end
+
+ iter{|a, b, c|
+ [a, b, c]
+ }
+ }
+ end
+end
+
+
--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml