yarv-diff:179
From: ko1 atdot.net
Date: 28 Dec 2005 14:43:01 -0000
Subject: [yarv-diff:179] r337 - trunk
Author: ko1
Date: 2005-12-28 23:43:01 +0900 (Wed, 28 Dec 2005)
New Revision: 337
Modified:
trunk/ChangeLog
trunk/class.c
trunk/compile.c
trunk/eval_proc.c
trunk/gc.c
trunk/insns.def
trunk/test.rb
trunk/yarvcore.c
trunk/yarvcore.h
Log:
* class.c (method_entry) : fixed for undefed method ([yarv-dev:743])
* compile.c : fix errinfo dvar id (#$!)
and fix NODE_ERRINFO compilation
* eval_proc.c, yarvcore.c : support YARVCore::VM::Proc.new
* insns.def : remove useless TODO comments
* insns.def : fix to use strict array conversion on
checkarrayinclude
* insns.def : fix defined?(yield) ([yarv-dev:744])
* yarvcore.h : change yarv_iseq_t layout
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2005-12-28 07:50:55 UTC (rev 336)
+++ trunk/ChangeLog 2005-12-28 14:43:01 UTC (rev 337)
@@ -4,6 +4,25 @@
# from Mon, 03 May 2004 01:24:19 +0900
#
+2005-12-28(Wed) 23:35:06 +0900 Koichi Sasada <ko1 atdot.net>
+
+ * class.c (method_entry) : fixed for undefed method ([yarv-dev:743])
+
+ * compile.c : fix errinfo dvar id (#$!)
+ and fix NODE_ERRINFO compilation
+
+ * eval_proc.c, yarvcore.c : support YARVCore::VM::Proc.new
+
+ * insns.def : remove useless TODO comments
+
+ * insns.def : fix to use strict array conversion on
+ checkarrayinclude
+
+ * insns.def : fix defined?(yield) ([yarv-dev:744])
+
+ * yarvcore.h : change yarv_iseq_t layout
+
+
2005-12-28(Wed) 16:49:55 +0900 Minero Aoki <aamine loveruby.net>
* test/ruby/test_eval.rb: add TODO comment.
Modified: trunk/class.c
===================================================================
--- trunk/class.c 2005-12-28 07:50:55 UTC (rev 336)
+++ trunk/class.c 2005-12-28 14:43:01 UTC (rev 337)
@@ -540,16 +540,24 @@
static int
method_entry(ID key, NODE *body, st_table *list)
{
- long type;
- body = body->nd_body;
+ long type;
- if (key == ID_ALLOCATOR) return ST_CONTINUE;
- if (!st_lookup(list, key, 0)) {
- if (!body->nd_body) type = -1; /* none */
- else type = VISI(body->nd_noex);
- st_add_direct(list, key, type);
+ if (body == 0 /* undefed method */ ||
+ key == ID_ALLOCATOR) {
+ return ST_CONTINUE;
+ }
+ body = body->nd_body;
+
+ if (!st_lookup(list, key, 0)) {
+ if (!body->nd_body) {
+ type = -1; /* none */
}
- return ST_CONTINUE;
+ else {
+ type = VISI(body->nd_noex);
+ }
+ st_add_direct(list, key, type);
+ }
+ return ST_CONTINUE;
}
static VALUE
Modified: trunk/compile.c
===================================================================
--- trunk/compile.c 2005-12-28 07:50:55 UTC (rev 336)
+++ trunk/compile.c 2005-12-28 14:43:01 UTC (rev 337)
@@ -837,7 +837,7 @@
static ID id_dollar_bang;
if(!id_dollar_bang){
- id_dollar_bang = rb_intern("__$!");
+ id_dollar_bang = rb_intern("#$!");
}
iseq->local_tbl = (ID*)ALLOC_N(ID*, 1);
iseq->local_size = 1;
@@ -4152,7 +4152,21 @@
ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(1), INT2FIX(0));
}
else{
- ADD_INSN(ret, nd_line(node), putnil);
+ yarv_iseq_t *ip = iseq;
+ int level = 0;
+ while(ip){
+ if(ip->type == ISEQ_TYPE_RESCUE){
+ break;
+ }
+ ip = ip->parent_iseq;
+ level++;
+ }
+ if(ip){
+ ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(1), INT2FIX(level));
+ }
+ else{
+ ADD_INSN(ret, nd_line(node), putnil);
+ }
}
}
break;
Modified: trunk/eval_proc.c
===================================================================
--- trunk/eval_proc.c 2005-12-28 07:50:55 UTC (rev 336)
+++ trunk/eval_proc.c 2005-12-28 14:43:01 UTC (rev 337)
@@ -177,17 +177,20 @@
*/
static VALUE
-proc_s_new(argc, argv, klass)
- int argc;
- VALUE *argv;
- VALUE klass;
+proc_s_new(int argc, VALUE *argv, VALUE klass)
{
- VALUE block = proc_alloc(klass, Qfalse);
+ VALUE block = proc_alloc(klass, Qfalse);
- rb_obj_call_init(block, argc, argv);
- return block;
+ rb_obj_call_init(block, argc, argv);
+ return block;
}
+VALUE
+rb_proc_s_new(int argc, VALUE *argv, VALUE klass)
+{
+ return proc_s_new(argc, argv, klass);
+}
+
/*
* call-seq:
* proc { |...| block } => a_proc
Modified: trunk/gc.c
===================================================================
--- trunk/gc.c 2005-12-28 07:50:55 UTC (rev 336)
+++ trunk/gc.c 2005-12-28 14:43:01 UTC (rev 337)
@@ -119,7 +119,7 @@
if (size == 0) size = 1;
malloc_increase += size;
- if (malloc_increase > malloc_limit) { // || gc_debug_flag) {
+ if (malloc_increase > malloc_limit) // || gc_debug_flag) {
garbage_collect();
}
RUBY_CRITICAL(mem = malloc(size));
Modified: trunk/insns.def
===================================================================
--- trunk/insns.def 2005-12-28 07:50:55 UTC (rev 336)
+++ trunk/insns.def 2005-12-28 14:43:01 UTC (rev 337)
@@ -621,7 +621,7 @@
result = Qfalse;
if(TYPE(ary) != T_ARRAY){
- ary = rb_ary_to_ary(ary);
+ ary = rb_Array(ary);
}
if(flag == Qtrue){
@@ -638,7 +638,6 @@
obj = Qfalse;
/* NODE_WHEN */
for(i=0; i< RARRAY(ary)->len; i++){
- // TODO: fix me (use another method dispatch)
if(RTEST(RARRAY(ary)->ptr[i])){
obj = result = Qtrue;
break;
@@ -886,7 +885,7 @@
VALUE klass;
NODE *newbody;
yarv_iseq_t *iseq;
- int noex = NOEX_PUBLIC; /* TODO: really? */
+ int noex = NOEX_PUBLIC;
if(FIXNUM_P(obj) || SYMBOL_P(obj)){
rb_raise(rb_eTypeError,
@@ -1009,7 +1008,9 @@
}
break;
case DEFINED_YIELD:
- expr_type = "yield";
+ if(GET_BLOCK_PTR()){
+ expr_type = "yield";
+ }
break;
default:
rb_bug("unimplemented defined? type (vm)");
@@ -1039,8 +1040,6 @@
yarv_block_t *blockptr;
VALUE proc;
- /* TODO : eliminate it */
-
blockptr = GET_BLOCK_PTR_IN_CFP(GET_CFP());
blockptr->iseq = blockiseq;
blockptr->proc = 0;
@@ -1348,8 +1347,8 @@
(...)
(VALUE val) // inc += - op_argc;
{
- /* TODO */
#if YARV_AOT_COMPILED
+ /* TODO: */
rb_bug("...");
#else
tmp_num = op_argc;
@@ -1823,7 +1822,6 @@
PUSH(recv); PUSH(obj);
tmp_id = idPLUS;
goto LABEL_IS_SC(start_init_in_send_for_opt_1);
- /* TODO */
#endif
}
}
@@ -1859,7 +1857,6 @@
PUSH(recv); PUSH(obj);
tmp_id = idMINUS;
goto LABEL_IS_SC(start_init_in_send_for_opt_1);
- /* TODO */
#endif
}
}
@@ -1916,7 +1913,6 @@
PUSH(recv); PUSH(obj);
tmp_id = idMULT;
goto LABEL_IS_SC(start_init_in_send_for_opt_1);
- /* TODO */
#endif
}
}
@@ -1985,7 +1981,6 @@
PUSH(recv); PUSH(obj);
tmp_id = idDIV;
goto LABEL_IS_SC(start_init_in_send_for_opt_1);
- /* TODO */
#endif
}
}
@@ -2074,7 +2069,6 @@
PUSH(recv); PUSH(obj);
tmp_id = idMOD;
goto LABEL_IS_SC(start_init_in_send_for_opt_1);
- /* TODO */
#endif
}
}
@@ -2149,7 +2143,6 @@
PUSH(recv); PUSH(obj);
tmp_id = idEq;
goto LABEL_IS_SC(start_init_in_send_for_opt_1);
- /* TODO */
#endif
}
}
@@ -2184,7 +2177,6 @@
PUSH(recv); PUSH(obj);
tmp_id = idLT;
goto LABEL_IS_SC(start_init_in_send_for_opt_1);
- /* TODO */
#endif
}
}
@@ -2218,7 +2210,6 @@
PUSH(recv); PUSH(obj);
tmp_id = idLE;
goto LABEL_IS_SC(start_init_in_send_for_opt_1);
- /* TODO */
#endif
}
}
@@ -2258,9 +2249,7 @@
#else
PUSH(recv); PUSH(obj);
tmp_id = idLTLT;
- /* TODO */
goto LABEL_IS_SC(start_init_in_send_for_opt_1);
-
#endif
}
}
@@ -2297,7 +2286,6 @@
PUSH(recv); PUSH(obj);
tmp_id = idAREF;
goto LABEL_IS_SC(start_init_in_send_for_opt_1);
- /* TODO */
#endif
}
}
@@ -2338,7 +2326,6 @@
PUSH(set);
tmp_id = idASET;
goto LABEL_IS_SC(start_init_in_send_for_opt_2);
- /* TODO */
#endif
}
}
Modified: trunk/test.rb
===================================================================
--- trunk/test.rb 2005-12-28 07:50:55 UTC (rev 336)
+++ trunk/test.rb 2005-12-28 14:43:01 UTC (rev 337)
@@ -1,468 +1,27 @@
-require 'test/unit'
-class Array
- def iter_test1
- collect{|e| [e, yield(e)]}.sort{|a,b|a[1]<=>b[1]}
+class BlockWrapper
+ def initialize(block)
+ @block = block
end
- def iter_test2
- a = collect{|e| [e, yield(e)]}
- a.sort{|a,b|a[1]<=>b[1]}
+
+ def call
+ @block.call
end
end
-class TestIterator < Test::Unit::TestCase
- def ttt
- assert(iterator?)
- end
- def test_iterator
- assert(!iterator?)
+def register(&block)
+ # @h[BlockWrapper.new(block)] = 1
+ @h[1] = BlockWrapper.new(block)
+end
- ttt{}
+def m
+ puts 'THRU'
+end
- # yield at top level !! here's not toplevel
- assert(!defined?(yield))
- end
-
- def test_array
- $x = [1, 2, 3, 4]
- $y = []
-
- # iterator over array
- for i in $x
- $y.push i
- end
- assert_equal($x, $y)
- end
-
- def tt
- 1.upto(10) {|i|
- yield i
- }
- end
-
- def tt2(dummy)
- yield 1
- end
-
- def tt3(&block)
- tt2(raise(ArgumentError,""),&block)
- end
-
- def test_nested_iterator
- i = 0
- tt{|i| break if i == 5}
- assert_equal(5, i)
-
- assert_raises(ArgumentError) do
- tt3{}
- end
- end
-
- def tt4 &block
- tt2(raise(ArgumentError,""),&block)
- end
-
- def test_block_argument_without_paren
- assert_raises(ArgumentError) do
- tt4{}
- end
- end
-
- # iterator break/redo/next/retry
- def test_break
- done = true
- loop{
- break
- done = false # should not reach here
- }
- assert(done)
-
- done = false
- $bad = false
- loop {
- break if done
- done = true
- next
- $bad = true # should not reach here
- }
- assert(!$bad)
-
- done = false
- $bad = false
- loop {
- break if done
- done = true
- redo
- $bad = true # should not reach here
- }
- assert(!$bad)
-
- $x = []
- for i in 1 .. 7
- $x.push i
- end
- assert_equal(7, $x.size)
- assert_equal([1, 2, 3, 4, 5, 6, 7], $x)
-
- $done = false
- $x = []
- for i in 1 .. 7 # see how retry works in iterator loop
- if i == 4 and not $done
- $done = true
- retry
- end
- $x.push(i)
- end
- assert_equal(10, $x.size)
- assert_equal([1, 2, 3, 1, 2, 3, 4, 5, 6, 7], $x)
- end
-
- def test_append_method_to_built_in_class
- $x = [[1,2],[3,4],[5,6]]
- assert_equal($x.iter_test1{|x|x}, $x.iter_test2{|x|x})
- end
-
- class IterTest
- def initialize(e); @body = e; end
-
- def each0(&block); @body.each(&block); end
- def each1(&block); @body.each {|*x| block.call(*x) } end
- def each2(&block); @body.each {|*x| block.call(x) } end
- def each3(&block); @body.each {|x| block.call(*x) } end
- def each4(&block); @body.each {|x| block.call(x) } end
- def each5; @body.each {|*x| yield(*x) } end
- def each6; @body.each {|*x| yield(x) } end
- def each7; @body.each {|x| yield(*x) } end
- def each8; @body.each {|x| yield(x) } end
-
- def f(a)
- a
- end
- end
-
- def test_itertest
- assert_equal([1], IterTest.new(nil).method(:f).to_proc.call([1]))
- m = /\w+/.match("abc")
- assert_equal([m], IterTest.new(nil).method(:f).to_proc.call([m]))
-
- IterTest.new([0]).each0 {|x| assert_equal(0, x)}
- IterTest.new([1]).each1 {|x| assert_equal(1, x)}
- IterTest.new([2]).each2 {|x| assert_equal([2], x)}
- IterTest.new([4]).each4 {|x| assert_equal(4, x)}
- IterTest.new([5]).each5 {|x| assert_equal(5, x)}
- IterTest.new([6]).each6 {|x| assert_equal([6], x)}
- IterTest.new([8]).each8 {|x| assert_equal(8, x)}
-
- IterTest.new([[0]]).each0 {|x| assert_equal([0], x)}
- IterTest.new([[1]]).each1 {|x| assert_equal([1], x)}
- IterTest.new([[2]]).each2 {|x| assert_equal([[2]], x)}
- IterTest.new([[3]]).each3 {|x| assert_equal(3, x)}
- IterTest.new([[4]]).each4 {|x| assert_equal([4], x)}
- IterTest.new([[5]]).each5 {|x| assert_equal([5], x)}
- IterTest.new([[6]]).each6 {|x| assert_equal([[6]], x)}
- IterTest.new([[7]]).each7 {|x| assert_equal(7, x)}
- IterTest.new([[8]]).each8 {|x| assert_equal([8], x)}
-
- IterTest.new([[0,0]]).each0 {|x| assert_equal([0,0], x)}
- IterTest.new([[8,8]]).each8 {|x| assert_equal([8,8], x)}
- end
-
- def m(var)
- var
- end
-
- def m1
- m(block_given?)
- end
-
- def m2
- m(block_given?,&proc{})
- end
-
- def test_block_given
- assert(m1{p 'test'})
- assert(m2{p 'test'})
- assert(!m1())
- assert(!m2())
- end
-
- def m3(var, &block)
- m(yield(var), &block)
- end
-
- def m4(&block)
- m(m1(), &block)
- end
-
- def test_block_passing
- assert(!m4())
- assert(!m4 {})
- assert_equal(100, m3(10) {|x|x*x})
- end
-
- class C
- include Enumerable
- def initialize
- @a = [1,2,3]
- end
- def each(&block)
- @a.each(&block)
- end
- end
-
- def test_collect
- assert_equal([1,2,3], C.new.collect{|n| n})
- end
-
- def test_proc
- assert_instance_of(Proc, lambda{})
- assert_instance_of(Proc, Proc.new{})
- lambda{|a|assert_equal(a, 1)}.call(1)
- end
-
- def test_block
- assert_instance_of(NilClass, get_block)
- assert_instance_of(Proc, get_block{})
- end
-
- def test_argument
- assert_nothing_raised {lambda{||}.call}
- assert_raises(ArgumentError) {lambda{||}.call(1)}
- assert_nothing_raised {lambda{|a,|}.call(1)}
- assert_raises(ArgumentError) {lambda{|a,|}.call()}
- assert_raises(ArgumentError) {lambda{|a,|}.call(1,2)}
- end
-
- def get_block(&block)
- block
- end
-
- def test_get_block
- assert_instance_of(Proc, get_block{})
- assert_nothing_raised {get_block{||}.call()}
- assert_nothing_raised {get_block{||}.call(1)}
- assert_nothing_raised {get_block{|a,|}.call(1)}
- assert_nothing_raised {get_block{|a,|}.call()}
- assert_nothing_raised {get_block{|a,|}.call(1,2)}
-
- assert_nothing_raised {get_block(&lambda{||}).call()}
- assert_raises(ArgumentError) {get_block(&lambda{||}).call(1)}
- assert_nothing_raised {get_block(&lambda{|a,|}).call(1)}
- assert_raises(ArgumentError) {get_block(&lambda{|a,|}).call(1,2)}
-
- block = get_block{11}
- assert_instance_of(Proc, block)
- assert_instance_of(Proc, block.to_proc)
- assert_equal(block.clone.call, 11)
- assert_instance_of(Proc, get_block(&block))
-
- lmd = lambda{44}
- assert_instance_of(Proc, lmd)
- assert_instance_of(Proc, lmd.to_proc)
- assert_equal(lmd.clone.call, 44)
- assert_instance_of(Proc, get_block(&lmd))
-
- assert_equal(1, Proc.new{|a,| a}.call(1,2,3))
- assert_nothing_raised {Proc.new{|a,|}.call(1,2)}
- end
-
- def return1_test
- Proc.new {
- return 55
- }.call + 5
- end
-
- def test_return1
- assert_equal(55, return1_test())
- end
-
- def return2_test
- lambda {
- return 55
- }.call + 5
- end
-
- def test_return2
- assert_equal(60, return2_test())
- end
-
- def proc_call(&b)
- b.call
- end
- def proc_yield()
- yield
- end
- def proc_return1
- proc_call{return 42}+1
- end
-
- def test_proc_return1
- assert_equal(42, proc_return1())
- end
-
- def proc_return2
- proc_yield{return 42}+1
- end
-
- def test_proc_return2
- assert_equal(42, proc_return2())
- end
-
- def test_ljump
- assert_raises(LocalJumpError) {get_block{break}.call}
-
- # cannot use assert_nothing_raised due to passing block.
- begin
- val = lambda{break 11}.call
- rescue LocalJumpError
- assert(false, "LocalJumpError occurred from break in lambda")
- else
- assert(11, val)
- end
-
- block = get_block{11}
- lmd = lambda{44}
- assert_equal(0, block.arity)
- assert_equal(0, lmd.arity)
- assert_equal(0, lambda{||}.arity)
- assert_equal(1, lambda{|a|}.arity)
- assert_equal(1, lambda{|a,|}.arity)
- assert_equal(2, lambda{|a,b|}.arity)
- end
-
- def marity_test(m)
- mobj = method(m)
- assert_equal(mobj.arity, mobj.to_proc.arity)
- end
-
- def test_marity
- marity_test(:assert)
- marity_test(:marity_test)
- marity_test(:p)
-
- lambda(&method(:assert)).call(true)
- lambda(&get_block{|a,n| assert(a,n)}).call(true, "marity")
- end
-
- def foo
- yield([:key, :value])
- end
- def bar(&blk)
- blk.call([:key, :value])
- end
-
- def test_yield_vs_call
- foo{|k,v| assert_equal([:key, :value], [k,v])}
- bar{|k,v| assert_equal([:key, :value], [k,v])}
- end
-
- class H
- def each
- yield [:key, :value]
- end
- end
-
- def test_assoc_yield
- [{:key=>:value}, H.new].each {|h|
- h.each{|a| assert_equal([:key, :value], a)}
- h.each{|*a| assert_equal([[:key, :value]], a)}
- h.each{|k,v| assert_equal([:key, :value], [k,v])}
- }
- end
-
- class ITER_TEST1
- def a
- block_given?
- end
- end
-
- class ITER_TEST2 < ITER_TEST1
- include Test::Unit::Assertions
- def a
- assert(super)
- super
- end
- end
-
- def test_iter_test2
- assert(ITER_TEST2.new.a {})
- end
-
- class ITER_TEST3
- def foo x
- return yield if block_given?
- x
- end
- end
-
- class ITER_TEST4 < ITER_TEST3
- include Test::Unit::Assertions
- def foo x
- assert_equal(super, yield)
- assert_equal(x, super(x, &nil))
- end
- end
-
- def test_iter4
- ITER_TEST4.new.foo(44){55}
- end
-
- def test_break__nested_loop1
- _test_break__nested_loop1 do
- break
- end
- end
-
- def _test_break__nested_loop1
- while true
- yield
- end
- assert(false, "must not reach here")
- end
-
- def test_break__nested_loop2
- _test_break__nested_loop2 do
- break
- end
- end
-
- def _test_break__nested_loop2
- until false
- yield
- end
- assert(false, "must not reach here")
- end
-
- def test_break__nested_loop3
- _test_break__nested_loop3 do
- break
- end
- end
-
- def _test_break__nested_loop3
- loop do
- yield
- end
- assert(false, "must not reach here")
- end
-
- def test_break_from_enum
- result = ["a"].inject("ng") {|x,y| break "ok"}
- assert_equal("ok", result)
- end
-
- def _test_return_trace_func(x)
- set_trace_func(proc {})
- [].fetch(2) {return x}
- ensure
- set_trace_func(nil)
- end
-
- def test_return_trace_func
- ok = "returned gracefully"
- result = "skipped"
- result = _test_return_trace_func(ok)
- ensure
- assert_equal(ok, result)
- return
- end
+def call
+ @h[1].call
end
+
+@h = {}
+register(&method(:m))
+GC.start
+call
Modified: trunk/yarvcore.c
===================================================================
--- trunk/yarvcore.c 2005-12-28 07:50:55 UTC (rev 336)
+++ trunk/yarvcore.c 2005-12-28 14:43:01 UTC (rev 337)
@@ -923,11 +923,14 @@
VALUE Init_yarvthread();
extern VALUE *rb_gc_stack_start;
+VALUE rb_proc_s_new(int argc, VALUE *argv, VALUE klass);
+
VALUE
sdr(){
yarv_bug();
return Qnil;
}
+
char yarv_version[0x20];
char *yarv_options = ""
#if OPT_DIRECT_THREADED_CODE
@@ -1025,6 +1028,7 @@
rb_define_method(cYarvProc, "to_proc", proc_to_proc, 0);
rb_define_method(cYarvProc, "clone", proc_clone, 0);
rb_define_method(cYarvProc, "arity", proc_arity, 0);
+ rb_define_singleton_method(cYarvProc, "new", rb_proc_s_new, -1);
/* misc */
Modified: trunk/yarvcore.h
===================================================================
--- trunk/yarvcore.h 2005-12-28 07:50:55 UTC (rev 336)
+++ trunk/yarvcore.h 2005-12-28 14:43:01 UTC (rev 337)
@@ -195,6 +195,9 @@
struct yarv_iseq_struct;
struct yarv_iseq_struct{
+ /* instruction sequence type */
+ VALUE type;
+
VALUE self;
VALUE name; /* String: iseq name */
VALUE *iseq; /* iseq */
@@ -248,10 +251,7 @@
/* for stack overflow check */
int stack_max;
- /* instruction sequence type */
- int type;
-
- /* klass/module nest information stack */
+ /* klass/module nest information stack (cref) */
VALUE klass_nest_stack; /* Array */
VALUE klass;
--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml