yarv-diff:145
From: ko1 atdot.net
Date: 8 Dec 2005 16:30:23 -0000
Subject: [yarv-diff:145] r304 - in trunk: . yarvtest
Author: ko1
Date: 2005-12-09 01:30:22 +0900 (Fri, 09 Dec 2005)
New Revision: 304
Modified:
trunk/ChangeLog
trunk/array.c
trunk/blockinlining.c
trunk/common.mk
trunk/compile.c
trunk/debug.c
trunk/debug.h
trunk/eval.c
trunk/eval_method.h
trunk/gc.c
trunk/insns.def
trunk/numeric.c
trunk/range.c
trunk/test.rb
trunk/vm.c
trunk/vm_opts.h.base
trunk/yarvcore.c
trunk/yarvcore.h
trunk/yarvtest/test_flow.rb
Log:
* array.c, numeric.c, range.c : add prototype of
block inlining function
* blockinlining.c, vm_opts.h.base : add block inlining flag
* common.mk, debug.h, debug.c : add debug_breakpoint() for gdb
* compile.c : fix to use size_t on compile_data_alloc(),
fix illegal cast, fix to set arg_simple at compiling block,
* compile.c, vm.c : fix NODE_NEXT, NODE_BREAK logic
* yarvtest/test_flow.rb : add a test for above
* yarvcore.c, yarvcore.h, compile.c, eval.c : remove
yarv_iseq_t#root_iseq and add yarv_iseq_t#local_iseq and fix
to use this member field
* eval_method.h : fix indent
* gc.c : fix indent
* insns.def, compile.c : remove "zsuper" instruction (use "super"
instead). This is because NODE_ZSUPER represent with only "super"
instruction
* yarvcore.c : add proc_arity
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2005-12-04 19:07:52 UTC (rev 303)
+++ trunk/ChangeLog 2005-12-08 16:30:22 UTC (rev 304)
@@ -4,6 +4,37 @@
# from Mon, 03 May 2004 01:24:19 +0900
#
+2005-12-09(Fri) 01:13:37 +0900 Koichi Sasada <ko1 atdot.net>
+
+ * array.c, numeric.c, range.c : add prototype of
+ block inlining function
+
+ * blockinlining.c, vm_opts.h.base : add block inlining flag
+
+ * common.mk, debug.h, debug.c : add debug_breakpoint() for gdb
+
+ * compile.c : fix to use size_t on compile_data_alloc(),
+ fix illegal cast, fix to set arg_simple at compiling block,
+
+ * compile.c, vm.c : fix NODE_NEXT, NODE_BREAK logic
+
+ * yarvtest/test_flow.rb : add a test for above
+
+ * yarvcore.c, yarvcore.h, compile.c, eval.c : remove
+ yarv_iseq_t#root_iseq and add yarv_iseq_t#local_iseq and fix
+ to use this member field
+
+ * eval_method.h : fix indent
+
+ * gc.c : fix indent
+
+ * insns.def, compile.c : remove "zsuper" instruction (use "super"
+ instead). This is because NODE_ZSUPER represent with only "super"
+ instruction
+
+ * yarvcore.c : add proc_arity
+
+
2005-12-05(Mon) 03:58:30 +0900 Koichi Sasada <ko1 atdot.net>
* array.c, blockinlining.c : support block inlining for Array#each
Modified: trunk/array.c
===================================================================
--- trunk/array.c 2005-12-04 19:07:52 UTC (rev 303)
+++ trunk/array.c 2005-12-08 16:30:22 UTC (rev 304)
@@ -1130,6 +1130,8 @@
* a -- b -- c --
*/
+VALUE yarv_invoke_Array_each_special_block(VALUE ary);
+
VALUE
rb_ary_each(VALUE ary)
{
Modified: trunk/blockinlining.c
===================================================================
--- trunk/blockinlining.c 2005-12-04 19:07:52 UTC (rev 303)
+++ trunk/blockinlining.c 2005-12-08 16:30:22 UTC (rev 304)
@@ -5,12 +5,13 @@
VALUE yarv_new_iseqval(VALUE node, VALUE name, VALUE file,
VALUE parent, VALUE type, VALUE opt);
-VALUE
+static VALUE
yarv_iseq_special_block(yarv_iseq_t * iseq, void *builder)
{
VALUE parent = Qfalse;
VALUE iseqval;
+#if OPT_BLOCKINLINING
if(iseq->argc > 1 ||
iseq->arg_simple == 0){
/* argument check */
@@ -40,6 +41,9 @@
iseq->cached_special_block = iseqval;
iseq->cached_special_block_builder = builder;
return iseqval;
+#else
+ return 0;
+#endif
}
static NODE *
@@ -119,7 +123,7 @@
}
VALUE
-yarv_invoke_Integer_times_specail_block(VALUE num)
+yarv_invoke_Integer_times_special_block(VALUE num)
{
yarv_thread_t *th = GET_THREAD();
yarv_block_t *orig_block = GC_GUARDED_PTR_REF(th->cfp->lfp[0]);
Modified: trunk/common.mk
===================================================================
--- trunk/common.mk 2005-12-04 19:07:52 UTC (rev 303)
+++ trunk/common.mk 2005-12-08 16:30:22 UTC (rev 304)
@@ -470,7 +470,8 @@
# vm.o : CFLAGS += -fno-crossjumping
run.gdb:
- echo run > run.gdb
+ echo b debug_breakpoint > run.gdb
+ echo run >> run.gdb
gdb: all run.gdb
gdb -x run.gdb --quiet --args $(MINIRUBY) -I$(srcdir)/lib $(srcdir)/test.rb
Modified: trunk/compile.c
===================================================================
--- trunk/compile.c 2005-12-04 19:07:52 UTC (rev 303)
+++ trunk/compile.c 2005-12-08 16:30:22 UTC (rev 304)
@@ -274,8 +274,8 @@
return iseq_setup(self, list_anchor);
}
-
VALUE th_eval(void *);
+
static int
iseq_translate_direct_threaded_code(yarv_iseq_t *iseq)
{
@@ -310,7 +310,7 @@
static void *
-compile_data_alloc(yarv_iseq_t *iseq, int size)
+compile_data_alloc(yarv_iseq_t *iseq, size_t size)
{
void *ptr = 0;
struct iseq_compile_data_storage *storage = iseq->compile_data->storage_current;
@@ -625,11 +625,6 @@
for(i=0; i<argc; i++){
VALUE v = va_arg(argv, VALUE);
operands[i] = v;
-
- /* TODO: need GC mark? */
- //if(!SPECIAL_CONST_P(v)){
- // rb_ary_push(iseq->iseq_mark_ary, v);
- //}
}
va_end(argv);
}
@@ -896,7 +891,7 @@
}
if(node->nd_var->nd_args){
NODE *sn = node->nd_var->nd_args;
- if((int)sn != -1){
+ if((long)sn != -1){
if(nd_type(sn) == NODE_DASGN_CURR){
rb_ary_push(param_vars, ID2SYM(sn->nd_vid));
}
@@ -938,14 +933,6 @@
}
}
- if(iseq->arg_opts ||
- iseq->arg_rest){
- iseq->arg_simple = 0;
- }
- else{
- iseq->arg_simple = 1;
- }
-
if(iseq->special_block_builder != 0){
node = ((NODE *(*)(yarv_iseq_t *, NODE*, VALUE, VALUE))
iseq->special_block_builder)(iseq, node, param_vars, local_vars);
@@ -1021,7 +1008,7 @@
}
}
- if((int)node->nd_var->nd_args > 0){
+ if((long)node->nd_var->nd_args > 0){
iseq->argc++;
iseq->arg_rest = i + 1;
@@ -1047,6 +1034,14 @@
}
}
+ if(iseq->arg_opts ||
+ iseq->arg_rest){
+ iseq->arg_simple = 0;
+ }
+ else{
+ iseq->arg_simple = 1;
+ }
+
if(nd_type(node) == NODE_FOR){
iseq->compile_data->for_iseq = 1;
}
@@ -1853,32 +1848,7 @@
return COMPILE_OK;
}
-static yarv_iseq_t *
-get_root_iseq_object(yarv_iseq_t *iop)
-{
- yarv_iseq_t *iseq = iop;
- while(iseq){
- if(iseq->parent_iseq &&
- iseq->type != ISEQ_TYPE_CLASS){
- iseq = iseq->parent_iseq;
- }
- else{
- return iseq;
- }
- }
- /* unreachable */
- rb_bug("get_root_iseq_object error");
- return 0;
-}
-
static int
-get_root_iseq_localsize(yarv_iseq_t *iseq)
-{
- iseq = get_root_iseq_object(iseq);
- return iseq->local_size;
-}
-
-static int
compile_branch_condition(VALUE self, yarv_iseq_t *iseq,
LINK_ANCHOR *ret, NODE *cond,
LABEL *then_label, LABEL *else_label)
@@ -2390,6 +2360,7 @@
}
return COMPILE_OK;
}
+
iseq->compile_data->last_line = nd_line(node);
debug_nodeprint(node);
@@ -2726,20 +2697,20 @@
}
else{
yarv_iseq_t *ip = iseq->parent_iseq;
-
while(ip){
level++;
- if(ip->type == ISEQ_TYPE_BLOCK){
- level <<= 16;
- goto break_by_insn;
- }
- else if(ip->compile_data->redo_label != 0){
+ if(ip->compile_data->redo_label != 0){
level = 0x8000;
if(ip->compile_data->loopval_popped == 0){
+ /* need value */
level |= 0x4000;
}
goto break_by_insn;
}
+ else if(ip->type == ISEQ_TYPE_BLOCK){
+ level <<= 16;
+ goto break_by_insn;
+ }
ip = ip->parent_iseq;
}
COMPILE_ERROR(("can't put break"));
@@ -2763,12 +2734,10 @@
while(ip){
level = 0x8000;
if(ip->type == ISEQ_TYPE_BLOCK){
+ level |= 0x4000;
break;
}
else if(ip->compile_data->redo_label != 0){
- if(ip->compile_data->loopval_popped == 0){
- level |= 0x4000;
- }
break;
}
ip = ip->parent_iseq;
@@ -2971,7 +2940,7 @@
}
case NODE_LASGN:{
- int idx = get_root_iseq_localsize(iseq) + 2 - node->nd_cnt;
+ int idx = iseq->local_iseq->local_size + 2 - node->nd_cnt;
debugs("lvar: %d\n", idx);
COMPILE(ret, "lvalue", node->nd_value);
@@ -3370,37 +3339,57 @@
}
break;
}
- case NODE_SUPER:{
+ case NODE_SUPER:
+ case NODE_ZSUPER:{
DECL_ANCHOR(args);
VALUE argc;
VALUE flag = 0;
VALUE block = 0;
VALUE parent_block = iseq->compile_data->current_block;
iseq->compile_data->current_block = Qfalse;
-
- /* args */
- if(type != NODE_VCALL && node->nd_args){
- if(nd_type(node->nd_args) == NODE_SPLAT){
- COMPILE(args, "args(splat)", node->nd_args->nd_head);
- argc = I2F(1);
- flag |= VM_CALL_ARGS_SPLAT_BIT;
- }
- else if(nd_type(node->nd_args) == NODE_ARGSCAT){
- compile_array(self, iseq, args, node->nd_args->nd_head, Qfalse);
- POP_ELEMENT(args);
-
- argc = LIST_SIZE(args) + 1;
- COMPILE(args, "args(cat: splat)", node->nd_args->nd_body);
- flag |= VM_CALL_ARGS_SPLAT_BIT;
+ if(nd_type(node) == NODE_SUPER){
+ /* args */
+ if(type != NODE_VCALL && node->nd_args){
+ if(nd_type(node->nd_args) == NODE_SPLAT){
+ COMPILE(args, "args(splat)", node->nd_args->nd_head);
+ argc = I2F(1);
+ flag |= VM_CALL_ARGS_SPLAT_BIT;
+ }
+ else if(nd_type(node->nd_args) == NODE_ARGSCAT){
+ compile_array(self, iseq, args, node->nd_args->nd_head, Qfalse);
+ POP_ELEMENT(args);
+
+ argc = LIST_SIZE(args) + 1;
+ COMPILE(args, "args(cat: splat)", node->nd_args->nd_body);
+
+ flag |= VM_CALL_ARGS_SPLAT_BIT;
+ }
+ else{
+ compile_array(self, iseq, args, node->nd_args, Qfalse);
+ argc = OPERAND_AT(POP_ELEMENT(args), 0);
+ }
}
else{
- compile_array(self, iseq, args, node->nd_args, Qfalse);
- argc = OPERAND_AT(POP_ELEMENT(args), 0);
- }
+ argc = I2F(0);
+ }
}
else{
- argc = I2F(0);
+ /* NODE_ZSUPER */
+ int i;
+ yarv_iseq_t *liseq = iseq->local_iseq;
+
+ argc = I2F(liseq->argc);
+
+ /* normal arguments */
+ for(i=0; i<liseq->argc; i++){
+ int idx = liseq->local_size - i;
+ ADD_INSN1(args, nd_line(node), getlocal, I2F(idx));
+ }
+ /* optional arguments */
+
+ /* rest arguments */
+
}
ADD_INSN(ret, nd_line(node), putnil); /* dummy reciever */
@@ -3425,28 +3414,6 @@
}
break;
}
- case NODE_ZSUPER:{
- VALUE block = 0;
- VALUE parent_block = iseq->compile_data->current_block;
- iseq->compile_data->current_block = Qfalse;
-
- /* block */
- if(parent_block){
- if(parent_block & 1){
- rb_bug("zsuper with blockval");
- }
- else{
- block = parent_block;
- }
- }
-
- ADD_INSN1(ret, nd_line(node), zsuper, block);
-
- if(poped){
- ADD_INSN(ret, nd_line(node), pop);
- }
- break;
- }
case NODE_ARRAY:{
compile_array(self, iseq, ret, node, Qtrue);
if(poped){
@@ -3590,7 +3557,7 @@
}
case NODE_LVAR:{
if(!poped){
- int idx = get_root_iseq_localsize(iseq) + 2 - node->nd_cnt;
+ int idx = iseq->local_iseq->local_size + 2 - node->nd_cnt;
debugs("idx: %d\n", idx);
ADD_INSN1(ret, nd_line(node), getlocal, I2F(idx));
}
@@ -4366,7 +4333,7 @@
}
default:
/* ignore */
- printf("%d\n", FIX2INT(link->type));
+ printf("%ld\n", FIX2INT(link->type));
rb_bug("dump_disasm_list error");
}
link = link->next;
Modified: trunk/debug.c
===================================================================
--- trunk/debug.c 2005-12-04 19:07:52 UTC (rev 303)
+++ trunk/debug.c 2005-12-08 16:30:22 UTC (rev 304)
@@ -46,3 +46,9 @@
rb_gc();
}
+void
+debug_breakpoint()
+{
+ /* */
+}
+
Modified: trunk/debug.h
===================================================================
--- trunk/debug.h 2005-12-04 19:07:52 UTC (rev 303)
+++ trunk/debug.h 2005-12-08 16:30:22 UTC (rev 304)
@@ -17,6 +17,7 @@
#define dpv(h,v) debug_value(-1, 0, h, v)
#define dp(v) debug_value(-1, 0, "", v)
#define dpi(i) debug_id (-1, 0, "", i)
+#define bp() debug_breakpoint()
void gc_check_func();
Modified: trunk/eval.c
===================================================================
--- trunk/eval.c 2005-12-04 19:07:52 UTC (rev 303)
+++ trunk/eval.c 2005-12-08 16:30:22 UTC (rev 304)
@@ -1928,13 +1928,10 @@
th->base_block = GET_BLOCK_PTR_IN_CFP(cfp);
th->base_block->iseq = cfp->iseq;
}
-
- if((iseq = th->base_block->iseq->root_iseq) == 0){
- iseq = th->base_block->iseq;
- }
+
+ iseq = th->base_block->iseq->local_iseq;
th->base_local_tbl = iseq->local_tbl;
th->base_local_size = iseq->local_size;
-
result = yarvcore_eval(0, src, rb_str_new2(file), INT2FIX(line));
}
POP_TAG();
Modified: trunk/eval_method.h
===================================================================
--- trunk/eval_method.h 2005-12-04 19:07:52 UTC (rev 303)
+++ trunk/eval_method.h 2005-12-08 16:30:22 UTC (rev 304)
@@ -288,57 +288,51 @@
}
static void
-rb_export_method(klass, name, noex)
- VALUE klass;
- ID name;
- ID noex;
+rb_export_method(VALUE klass, ID name, ID noex)
{
- NODE *body;
- VALUE origin;
+ NODE *body;
+ VALUE origin;
- if (klass == rb_cObject) {
- rb_secure(4);
+ if (klass == rb_cObject) {
+ rb_secure(4);
+ }
+ body = search_method(klass, name, &origin);
+ if (!body && TYPE(klass) == T_MODULE) {
+ body = search_method(rb_cObject, name, &origin);
+ }
+ if (!body || !body->nd_body) {
+ print_undef(klass, name);
+ }
+ if (body->nd_noex != noex) {
+ if (klass == origin) {
+ body->nd_noex = noex;
}
- body = search_method(klass, name, &origin);
- if (!body && TYPE(klass) == T_MODULE) {
- body = search_method(rb_cObject, name, &origin);
+ else {
+ rb_add_method(klass, name, NEW_ZSUPER(), noex);
}
- if (!body || !body->nd_body) {
- print_undef(klass, name);
- }
- if (body->nd_noex != noex) {
- if (klass == origin) {
- body->nd_noex = noex;
- }
- else {
- rb_add_method(klass, name, NEW_ZSUPER(), noex);
- }
- }
+ }
}
int
-rb_method_boundp(klass, id, ex)
- VALUE klass;
- ID id;
- int ex;
+rb_method_boundp(VALUE klass, ID id, int ex)
{
- struct cache_entry *ent;
- int noex;
+ struct cache_entry *ent;
+ int noex;
- /* is it in the method cache? */
- ent = cache + EXPR1(klass, id);
- if (ent->mid == id && ent->klass == klass) {
- if (ex && (ent->noex & NOEX_PRIVATE))
- return Qfalse;
- if (!ent->method) return Qfalse;
- return Qtrue;
- }
- if (rb_get_method_body(&klass, &id, &noex)) {
- if (ex && (noex & NOEX_PRIVATE))
- return Qfalse;
- return Qtrue;
- }
- return Qfalse;
+ /* is it in the method cache? */
+ ent = cache + EXPR1(klass, id);
+ if (ent->mid == id && ent->klass == klass) {
+ if (ex && (ent->noex & NOEX_PRIVATE))
+ return Qfalse;
+ if (!ent->method) return Qfalse;
+ return Qtrue;
+ }
+ if (rb_get_method_body(&klass, &id, &noex)) {
+ if (ex && (noex & NOEX_PRIVATE))
+ return Qfalse;
+ return Qtrue;
+ }
+ return Qfalse;
}
void
@@ -588,11 +582,10 @@
*/
static VALUE
-rb_mod_alias_method(mod, newname, oldname)
- VALUE mod, newname, oldname;
+rb_mod_alias_method(VALUE mod, VALUE newname, VALUE oldname)
{
- rb_alias(mod, rb_to_id(newname), rb_to_id(oldname));
- return mod;
+ rb_alias(mod, rb_to_id(newname), rb_to_id(oldname));
+ return mod;
}
Modified: trunk/gc.c
===================================================================
--- trunk/gc.c 2005-12-04 19:07:52 UTC (rev 303)
+++ trunk/gc.c 2005-12-08 16:30:22 UTC (rev 304)
@@ -109,28 +109,27 @@
void *
ruby_xmalloc(long size)
{
- void *mem;
+ void *mem;
- if (size < 0) {
- rb_raise(rb_eNoMemError, "negative allocation size (or too big)");
- }
- if (size == 0) size = 1;
- malloc_increase += size;
+ if (size < 0) {
+ rb_raise(rb_eNoMemError, "negative allocation size (or too big)");
+ }
+ if (size == 0) size = 1;
+ malloc_increase += size;
- if (malloc_increase > malloc_limit) {
- garbage_collect();
+ if (malloc_increase > malloc_limit) {
+ garbage_collect();
+ }
+ RUBY_CRITICAL(mem = malloc(size));
+ if (!mem) {
+ if (garbage_collect()) {
+ RUBY_CRITICAL(mem = malloc(size));
}
- RUBY_CRITICAL(mem = malloc(size));
if (!mem) {
- if (garbage_collect()) {
- RUBY_CRITICAL(mem = malloc(size));
- }
- if (!mem) {
- rb_memerror();
- }
+ rb_memerror();
}
-
- return mem;
+ }
+ return mem;
}
void *
Modified: trunk/insns.def
===================================================================
--- trunk/insns.def 2005-12-04 19:07:52 UTC (rev 303)
+++ trunk/insns.def 2005-12-08 16:30:22 UTC (rev 304)
@@ -1347,32 +1347,6 @@
/**
@c method/iterator
- @e super
- @j super
- */
-DEFINE_INSN
-zsuper
-(BLOCKISEQ blockiseq)
-(...)
-(VALUE val)
-{
-#if YARV_AOT_COMPILED
-#else
- tmp_blockptr = 0;
- if(blockiseq){
- tmp_blockptr = GET_BLOCK_PTR_IN_CFP(GET_CFP());
- tmp_blockptr->iseq = blockiseq;
- tmp_blockptr->proc = 0;
- }
- else{
- tmp_blockptr = GET_BLOCK_PTR();
- }
- goto LABEL_IS_SC(start_init_in_zsuper);
-#endif
-}
-
-/**
- @c method/iterator
@e yield(args) # args.size => num, flag shows expand argument or not
@j yield(args) # args.size => num
*/
Modified: trunk/numeric.c
===================================================================
--- trunk/numeric.c 2005-12-04 19:07:52 UTC (rev 303)
+++ trunk/numeric.c 2005-12-08 16:30:22 UTC (rev 304)
@@ -2725,11 +2725,13 @@
* 0 1 2 3 4
*/
+VALUE yarv_invoke_Integer_times_special_block(VALUE);
+
static VALUE
int_dotimes(VALUE num)
{
VALUE val;
- if((val = yarv_invoke_Integer_times_specail_block(num)) != Qundef){
+ if((val = yarv_invoke_Integer_times_special_block(num)) != Qundef){
return val;
}
Modified: trunk/range.c
===================================================================
--- trunk/range.c 2005-12-04 19:07:52 UTC (rev 303)
+++ trunk/range.c 2005-12-08 16:30:22 UTC (rev 304)
@@ -366,6 +366,8 @@
* 10 11 12 13 14 15
*/
+VALUE yarv_invoke_Range_each_special_block(VALUE, VALUE, VALUE, int);
+
static VALUE
range_each(VALUE range)
{
Modified: trunk/test.rb
===================================================================
--- trunk/test.rb 2005-12-04 19:07:52 UTC (rev 303)
+++ trunk/test.rb 2005-12-08 16:30:22 UTC (rev 304)
@@ -1,178 +1,144 @@
+1.times{
+ j = 0
+ 1.times{
+ p j
+ }
+}
+__END__
+eval %q{
+ a = 0
+ 1.times{
+ p a
+ }
+}
+__END__
+a = 1
+1.times{
+ p a
+ a = 1
+}
__END__
-begin
- while true
- begin
- break
- ensure
- p :ensure
- raise
- end
+class C
+ def m *args
+ p args
end
-rescue
end
-__END__
-begin
- (1..2).each do
- begin
- break
- ensure
- p :ensure
- raise
- end
+class D < C
+ def m a, b, c
+ super(a, b, c)
+ super
end
-rescue Exception
- p :rescue
end
+D.new.m(1, 2, 3)
+
__END__
-ary = [1, 2, 3]
-ary.each{
- begin
- break
- ensure
- raise
+def m arg
+ arg
+end
+
+m(while true
+ class C
+ break :foo
end
-}
+end)
__END__
-begin
- [1,2].each do
- p 1
- begin
+
+p 1.times{
+ while true
+ class C
break
- ensure
- raise StandardError
end
end
-rescue
-
-end
-__END__
-
-[1,[2, :b],3].each{|e, f|
- p [e, f]
+ p :foo
}
-
+p :bar
__END__
-3.times{
+
+1.times{
class C
next
end
}
+
__END__
-C=1
+$a = []; begin; ; $a << 1
+ 3.times{; $a << 2
+ class C; $a << 3
+ next; $a << 4
+ end; $a << 5
+ }; $a << 6
+ ; $a << 7
+; rescue Exception; $a << 99; end; $a
+__END__
+
+if false
i=0
while i<2
i+=1
- C
+ class C
+ next 10
+ end
end
-__END__
-1.times{
- C
-# p 1
-}
-__END__
-class C
- Const = :ok
- def m
- 1.times{
- Const
- p 1
- }
+p 1
+else
+
+$a = []
+begin
+ i=0
+ while i<3
+ i+=1
+ class C
+ next 10
+ end
end
+ $a << 9
+rescue Exception
end
-C.new.m
-__END__
-3.times{|e|
- p e
-}
-
+p $a
+end
__END__
-[[1,2],[3,4]].each{|a, b|
- p [a, b]
-}
-
-__END__
-i=:foo
-prs = []
-3.times{|e|
- prs << lambda{
- p i
- p e
+$a = []
+begin
+ $a << 1
+ 3.times{
+ $a << 2
+ class C
+ $a << 3
+ next
+ $a << 4
+ end
+ $a << 5
}
-}
+ $a << 6
+ $a << 7
+rescue Exception
+ $a << 99
+end
+$a
-prs.each{|pr|
- pr.call
-}
-
-
__END__
-3.times{
- p :a
+
+[1].each{|e|
class C
- p :b
next
end
- p :d
}
-p :e
__END__
-
-p 3.times{|bl|
- break 10
-}
-
-__END__
-
-3.times{|e|
- p e
- next if e < 1
- p self
-}
-
-
-__END__
-i = 0
-while i<30000000 # benchmark loop 1
- i+=1
-end
-__END__
-30000000.times{|i|
-}
-
-__END__
-3.times{|i|
- 4.times{|j|
- p [i, j]
- }
- 5.times{|j|
- p [i, j]
- }
-}
-__END__
-
-
-1.times{
- max = 30000000
- max.times{}
- # i=0; while i<max; i=i.succ; end
-}
-__END__
3.times{
+ class C
+ class D
+ next
+ end
+ end
}
-__END__
-i=0
-while i<3
- i+=1
-end
-
Modified: trunk/vm.c
===================================================================
--- trunk/vm.c 2005-12-04 19:07:52 UTC (rev 303)
+++ trunk/vm.c 2005-12-08 16:30:22 UTC (rev 304)
@@ -1297,7 +1297,6 @@
else if(entry->type == CATCH_TYPE_RETRY){
VALUE *escape_dfp;
escape_dfp = GET_THROWOBJ_CATCH_POINT(err);
-
if(cfp->dfp == escape_dfp){
cfp->pc = cfp->iseq->iseq_encoded + entry->cont;
th->errinfo = Qnil;
@@ -1319,15 +1318,17 @@
if(entry->type == CATCH_TYPE_ENSURE){
catch_iseqval = entry->iseq;
- cont_pc = entry->cont;
- cont_sp = entry->sp;
+ cont_pc = entry->cont;
+ cont_sp = entry->sp;
break;
}
else if(entry->type == type){
cfp->pc = cfp->iseq->iseq_encoded + entry->cont;
cfp->sp = cfp->bp + entry->sp;
- if(state != TAG_REDO && state != TAG_NEXT && escape_dfp){
+ if(!(state == TAG_REDO) &&
+ !(state == TAG_NEXT && !escape_dfp) &&
+ !(state == TAG_BREAK && !escape_dfp)){
#if OPT_STACK_CACHING
initial = (GET_THROWOBJ_VAL(err));
#else
@@ -1342,10 +1343,12 @@
}
else if(state == TAG_REDO){
type = CATCH_TYPE_REDO;
+ escape_dfp = GET_THROWOBJ_CATCH_POINT(err);
goto search_restart_point;
}
else if(state == TAG_NEXT){
type = CATCH_TYPE_NEXT;
+ escape_dfp = GET_THROWOBJ_CATCH_POINT(err);
goto search_restart_point;
}
else{
Modified: trunk/vm_opts.h.base
===================================================================
--- trunk/vm_opts.h.base 2005-12-04 19:07:52 UTC (rev 303)
+++ trunk/vm_opts.h.base 2005-12-08 16:30:22 UTC (rev 304)
@@ -18,6 +18,7 @@
/* architecture independent */
#define OPT_BASIC_OPERATIONS 0
#define OPT_INLINE_METHOD_CACHE 0
+#define OPT_BLOCKINLINING 0
/* architecture independent, affects generated code */
#define OPT_OPERANDS_UNIFICATION 0
Modified: trunk/yarvcore.c
===================================================================
--- trunk/yarvcore.c 2005-12-04 19:07:52 UTC (rev 303)
+++ trunk/yarvcore.c 2005-12-08 16:30:22 UTC (rev 304)
@@ -458,16 +458,23 @@
iseq->compile_data->storage_head->size = INITIAL_ISEQ_COMPILE_DATA_STORAGE_BUFF_SIZE;
iseq->compile_data->storage_head->buff = (char *)(&iseq->compile_data->storage_head->buff + 1);
- if(parent && CLASS_OF(parent) == cYarvISeq){
+ if(type == ISEQ_TYPE_TOP ||
+ type == ISEQ_TYPE_METHOD ||
+ type == ISEQ_TYPE_CLASS){
+ iseq->local_iseq = iseq;
+ }
+ else{
yarv_iseq_t *piseq;
GetISeqVal(parent, piseq);
+ iseq->local_iseq = piseq->local_iseq;
+ }
+
+ if(RTEST(parent)){
+ yarv_iseq_t *piseq;
+ GetISeqVal(parent, piseq);
iseq->parent_iseq = piseq;
-
- while(piseq->parent_iseq){
- piseq = piseq->parent_iseq;
- }
- iseq->root_iseq = piseq;
}
+
return Qtrue;
}
@@ -862,6 +869,26 @@
}
}
+static VALUE
+proc_arity(VALUE self)
+{
+ yarv_proc_t *proc;
+ yarv_iseq_t *iseq;
+ GetProcVal(self, proc);
+ iseq = proc->block.iseq;
+ if(iseq && BUILTIN_TYPE(iseq) != T_NODE){
+ if(iseq->arg_rest == 0 &&
+ iseq->arg_opts == 0){
+ return INT2FIX(iseq->argc);
+ }
+ else{
+ return INT2FIX(-iseq->argc-1);
+ }
+ }
+ else{
+ return INT2FIX(-1);
+ }
+}
/********************************************************************/
static VALUE yarv_once(){
@@ -979,6 +1006,7 @@
rb_define_method(cYarvProc, "[]", proc_call, -1);
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);
/* misc */
Modified: trunk/yarvcore.h
===================================================================
--- trunk/yarvcore.h 2005-12-04 19:07:52 UTC (rev 303)
+++ trunk/yarvcore.h 2005-12-08 16:30:22 UTC (rev 304)
@@ -267,8 +267,8 @@
/* for child iseq */
struct yarv_iseq_struct *parent_iseq;
- struct yarv_iseq_struct *root_iseq;
-
+ struct yarv_iseq_struct *local_iseq;
+
struct iseq_compile_data *compile_data;
};
Modified: trunk/yarvtest/test_flow.rb
===================================================================
--- trunk/yarvtest/test_flow.rb 2005-12-04 19:07:52 UTC (rev 303)
+++ trunk/yarvtest/test_flow.rb 2005-12-08 16:30:22 UTC (rev 304)
@@ -453,6 +453,19 @@
end
end
}
+ ae %q{
+ 1.times{
+ while true
+ class C
+ begin
+ break
+ ensure
+ break
+ end
+ end
+ end
+ }
+ }
end
end
--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml