yarv-diff:143
From: ko1 atdot.net
Date: 3 Dec 2005 13:28:34 -0000
Subject: [yarv-diff:143] r302 - trunk
Author: ko1
Date: 2005-12-03 22:28:33 +0900 (Sat, 03 Dec 2005)
New Revision: 302
Modified:
trunk/ChangeLog
trunk/blockinlining.c
trunk/compile.c
trunk/numeric.c
trunk/range.c
trunk/test.rb
trunk/yarvcore.c
trunk/yarvcore.h
Log:
* blockinlining.c, compile.c, yarvcore.c, yarvcore.h,
numeric.c, range.c : collect block inlining logic to blockinlining.c
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2005-12-03 11:37:46 UTC (rev 301)
+++ trunk/ChangeLog 2005-12-03 13:28:33 UTC (rev 302)
@@ -4,6 +4,12 @@
# from Mon, 03 May 2004 01:24:19 +0900
#
+2005-12-03(Sat) 22:27:08 +0900 Koichi Sasada <ko1 atdot.net>
+
+ * blockinlining.c, compile.c, yarvcore.c, yarvcore.h,
+ numeric.c, range.c : collect block inlining logic to blockinlining.c
+
+
2005-12-03(Sat) 20:24:07 +0900 Koichi Sasada <ko1 atdot.net>
* blockinlining.c, common.mk : add blockinlining.c
Modified: trunk/blockinlining.c
===================================================================
--- trunk/blockinlining.c 2005-12-03 11:37:46 UTC (rev 301)
+++ trunk/blockinlining.c 2005-12-03 13:28:33 UTC (rev 302)
@@ -6,7 +6,7 @@
VALUE parent, VALUE type, VALUE opt);
VALUE
-yarv_iseq_special_block(yarv_iseq_t * iseq, ID id)
+yarv_iseq_special_block(yarv_iseq_t * iseq, void *builder)
{
VALUE parent = Qfalse;
VALUE iseqval;
@@ -17,8 +17,8 @@
return 0;
}
- if(iseq->cached_special_block_type){
- if(iseq->cached_special_block_type == id){
+ if(iseq->cached_special_block_builder){
+ if(iseq->cached_special_block_builder == builder){
return iseq->cached_special_block;
}
else{
@@ -26,18 +26,233 @@
}
}
else{
- iseq->cached_special_block_type = 1;
+ iseq->cached_special_block_builder = (void *)1;
}
if(iseq->parent_iseq){
parent = iseq->parent_iseq->self;
}
iseqval = yarv_new_iseqval((VALUE)iseq->node, iseq->name,
- iseq->file_name, parent, iseq->type, ID2SYM(id));
+ iseq->file_name, parent, iseq->type,
+ GC_GUARDED_PTR(builder));
if(0){
printf("%s\n", RSTRING(iseq_disasm(iseqval))->ptr);
}
- iseq->cached_special_block = iseqval;
- iseq->cached_special_block_type = id;
+ iseq->cached_special_block = iseqval;
+ iseq->cached_special_block_builder = builder;
return iseqval;
}
+static NODE *
+new_block(NODE *head, NODE *tail)
+{
+ head = NEW_BLOCK(head);
+ tail = NEW_BLOCK(tail);
+ head->nd_next = tail;
+ return head;
+}
+
+static NODE *
+new_ary(NODE *head, NODE *tail)
+{
+ head = NEW_ARRAY(head);
+ head->nd_next = tail;
+ return head;
+}
+
+static NODE*
+build_Integer_times_node(yarv_iseq_t *iseq, NODE *node,
+ VALUE param_vars, VALUE local_vars)
+{
+ /* Special Block for Integer#times
+ {|e, _self|
+ _e = e
+ while(e < _self)
+ e = _e
+ redo_point:
+ BODY
+ next_point:
+ _e = _e.succ
+ end
+ }
+
+ {|e, _self|
+ while(e < _self)
+ BODY
+ next_point:
+ e = e.succ
+ end
+ }
+ */
+ ID _self = rb_intern("#_self");
+ if(iseq->argc == 0){
+ ID e = rb_intern("#e");
+ rb_ary_push(param_vars, ID2SYM(e));
+ rb_ary_push(param_vars, ID2SYM(_self));
+ iseq->argc+=2;
+
+ node =
+ NEW_WHILE(
+ NEW_CALL(NEW_DVAR(e), idLT, new_ary(NEW_DVAR(_self), 0)),
+ new_block(NEW_OPTBLOCK(node),
+ NEW_DASGN(e, NEW_CALL(NEW_DVAR(e), idSucc, 0))),
+ Qundef);
+ }
+ else{
+ ID _e = rb_intern("#_e");
+ ID e = SYM2ID(rb_ary_entry(param_vars, 0));
+ rb_ary_push(param_vars, ID2SYM(_self));
+ rb_ary_push(local_vars, ID2SYM(_e));
+ iseq->argc++;
+
+ node =
+ new_block(
+ NEW_DASGN(_e, NEW_DVAR(e)),
+ NEW_WHILE(
+ NEW_CALL(NEW_DVAR(_e), idLT, new_ary(NEW_DVAR(_self), 0)),
+ new_block(
+ NEW_DASGN(e, NEW_DVAR(_e)),
+ new_block(NEW_OPTBLOCK(node),
+ NEW_DASGN(_e, NEW_CALL(NEW_DVAR(_e), idSucc, 0)))),
+ Qundef));
+ }
+ return node;
+}
+
+VALUE
+yarv_invoke_Integer_times_specail_block(VALUE num)
+{
+ yarv_thread_t *th = GET_THREAD();
+ yarv_block_t *orig_block = GC_GUARDED_PTR_REF(th->cfp->lfp[0]);
+
+ if(orig_block && BUILTIN_TYPE(orig_block->iseq) != T_NODE){
+ VALUE tsiseqval = yarv_iseq_special_block(orig_block->iseq, build_Integer_times_node);
+ yarv_iseq_t *tsiseq;
+ VALUE argv[2], val;
+
+ if(tsiseqval){
+ yarv_block_t block = *orig_block;
+ GetISeqVal(tsiseqval, tsiseq);
+ block.iseq = tsiseq;
+ th->cfp->lfp[0] = GC_GUARDED_PTR(&block);
+ argv[0] = INT2FIX(0);
+ argv[1] = num;
+ val = th_invoke_yield(th, 2, argv);
+ if(val == Qundef){
+ return num;
+ }
+ else{
+ return val;
+ }
+ }
+ }
+ return Qundef;
+}
+
+static NODE *
+build_Range_each_node(yarv_iseq_t *iseq, NODE *node,
+ VALUE param_vars, VALUE local_vars, ID mid)
+{
+ /* Special Block for Range#each
+ {|e, _last|
+ _e = e
+ while _e < _last
+ e = _e
+ next_point:
+ BODY
+ redo_point:
+ _e = _e.succ
+ end
+ }
+ {|e, _last|
+ while e < _last
+ BODY
+ redo_point:
+ e = e.succ
+ end
+ }
+ */
+ ID _last = rb_intern("#_last");
+ if(iseq->argc == 0){
+ ID e = rb_intern("#e");
+ rb_ary_push(param_vars, ID2SYM(e));
+ rb_ary_push(param_vars, ID2SYM(_last));
+ iseq->argc+=2;
+
+ node =
+ NEW_WHILE(
+ NEW_CALL(NEW_DVAR(e), mid, new_ary(NEW_DVAR(_last), 0)),
+ new_block(NEW_OPTBLOCK(node),
+ NEW_DASGN(e, NEW_CALL(NEW_DVAR(e), idSucc, 0))),
+ Qundef);
+ }
+ else{
+ ID _e = rb_intern("#_e");
+ ID e = SYM2ID(rb_ary_entry(param_vars, 0));
+ rb_ary_push(param_vars, ID2SYM(_last));
+ rb_ary_push(local_vars, ID2SYM(_e));
+ iseq->argc++;
+
+ node =
+ new_block(
+ NEW_DASGN(_e, NEW_DVAR(e)),
+ NEW_WHILE(
+ NEW_CALL(NEW_DVAR(_e), mid, new_ary(NEW_DVAR(_last), 0)),
+ new_block(
+ NEW_DASGN(e, NEW_DVAR(_e)),
+ new_block(NEW_OPTBLOCK(node),
+ NEW_DASGN(_e, NEW_CALL(NEW_DVAR(_e), idSucc, 0)))),
+ Qundef));
+ }
+ return node;
+}
+
+static NODE *
+build_Range_each_node_LE(yarv_iseq_t *iseq, NODE *node,
+ VALUE param_vars, VALUE local_vars)
+{
+ return build_Range_each_node(iseq, node,
+ param_vars, local_vars, idLE);
+}
+
+static NODE *
+build_Range_each_node_LT(yarv_iseq_t *iseq, NODE *node,
+ VALUE param_vars, VALUE local_vars)
+{
+ return build_Range_each_node(iseq, node,
+ param_vars, local_vars, idLT);
+}
+
+VALUE
+yarv_invoke_Range_each_special_block(VALUE range,
+ VALUE beg, VALUE end, int excl)
+{
+ yarv_thread_t *th = GET_THREAD();
+ yarv_block_t *orig_block = GC_GUARDED_PTR_REF(th->cfp->lfp[0]);
+
+ if(BUILTIN_TYPE(orig_block->iseq) != T_NODE){
+ void *builder =
+ excl ? build_Range_each_node_LT : build_Range_each_node_LE;
+ VALUE tsiseqval = yarv_iseq_special_block(orig_block->iseq, builder);
+ yarv_iseq_t *tsiseq;
+ VALUE argv[2];
+
+ if(tsiseqval){
+ VALUE val;
+ yarv_block_t block = *orig_block;
+ GetISeqVal(tsiseqval, tsiseq);
+ block.iseq = tsiseq;
+ th->cfp->lfp[0] = GC_GUARDED_PTR(&block);
+ argv[0] = beg;
+ argv[1] = end;
+ val = th_invoke_yield(th, 2, argv);
+ if(val == Qundef){
+ return range;
+ }
+ else{
+ return val;
+ }
+ }
+ }
+ return Qundef;
+}
+
Modified: trunk/compile.c
===================================================================
--- trunk/compile.c 2005-12-03 11:37:46 UTC (rev 301)
+++ trunk/compile.c 2005-12-03 13:28:33 UTC (rev 302)
@@ -818,160 +818,6 @@
return COMPILE_OK;
}
-static NODE *
-new_block(NODE *head, NODE *tail)
-{
- head = NEW_BLOCK(head);
- tail = NEW_BLOCK(tail);
- head->nd_next = tail;
- return head;
-}
-
-static NODE *
-new_ary(NODE *head, NODE *tail)
-{
- head = NEW_ARRAY(head);
- head->nd_next = tail;
- return head;
-}
-
-static NODE*
-make_special_block_body(yarv_iseq_t *iseq, NODE *node,
- VALUE param_vars, VALUE local_vars)
-{
- if(iseq->special_block_type == idTimes &&
- iseq->argc < 2 && iseq->arg_simple){
- /* Special Block for Integer#times
- {|e, _self|
- _e = e
- while(e < _self)
- e = _e
- redo_point:
- BODY
- next_point:
- _e = _e.succ
- end
- }
-
- {|e, _self|
- while(e < _self)
- BODY
- next_point:
- e = e.succ
- end
- }
- */
- ID _self = rb_intern("#_self");
- if(iseq->argc == 0){
- ID e = rb_intern("#e");
- rb_ary_push(param_vars, ID2SYM(e));
- rb_ary_push(param_vars, ID2SYM(_self));
- iseq->argc+=2;
-
- node =
- NEW_WHILE(
- NEW_CALL(NEW_DVAR(e), idLT, new_ary(NEW_DVAR(_self), 0)),
- new_block(NEW_OPTBLOCK(node),
- NEW_DASGN(e, NEW_CALL(NEW_DVAR(e), idSucc, 0))),
- Qundef);
- }
- else{
- ID _e = rb_intern("#_e");
- ID e = SYM2ID(rb_ary_entry(param_vars, 0));
- rb_ary_push(param_vars, ID2SYM(_self));
- rb_ary_push(local_vars, ID2SYM(_e));
- iseq->argc++;
-
- node =
- new_block(
- NEW_DASGN(_e, NEW_DVAR(e)),
- NEW_WHILE(
- NEW_CALL(NEW_DVAR(_e), idLT, new_ary(NEW_DVAR(_self), 0)),
- new_block(
- NEW_DASGN(e, NEW_DVAR(_e)),
- new_block(NEW_OPTBLOCK(node),
- NEW_DASGN(_e, NEW_CALL(NEW_DVAR(_e), idSucc, 0)))),
- Qundef));
- }
- }
- else if((iseq->special_block_type == idRangeEachLT ||
- iseq->special_block_type == idRangeEachLE) &&
- iseq->argc < 2 && iseq->arg_simple){
- /* Special Block for Range#each
- {|e, _last|
- _e = e
- while _e < _last
- e = _e
- next_point:
- BODY
- redo_point:
- _e = _e.succ
- end
- }
- {|e, _last|
- while e < _last
- BODY
- redo_point:
- e = e.succ
- end
- }
- */
- ID _last = rb_intern("#_last");
- ID mid = iseq->special_block_type == idRangeEachLT ? idLT : idLE;
-
- if(iseq->argc == 0){
- ID e = rb_intern("#e");
- rb_ary_push(param_vars, ID2SYM(e));
- rb_ary_push(param_vars, ID2SYM(_last));
- iseq->argc+=2;
-
- node =
- NEW_WHILE(
- NEW_CALL(NEW_DVAR(e), mid, new_ary(NEW_DVAR(_last), 0)),
- new_block(NEW_OPTBLOCK(node),
- NEW_DASGN(e, NEW_CALL(NEW_DVAR(e), idSucc, 0))),
- 1);
- }
- else{
- ID _e = rb_intern("#_e");
- ID e = SYM2ID(rb_ary_entry(param_vars, 0));
- rb_ary_push(param_vars, ID2SYM(_last));
- rb_ary_push(local_vars, ID2SYM(_e));
- iseq->argc++;
-
- node =
- new_block(
- NEW_DASGN(_e, NEW_DVAR(e)),
- NEW_WHILE(
- NEW_CALL(NEW_DVAR(_e), mid, new_ary(NEW_DVAR(_last), 0)),
- new_block(
- NEW_DASGN(e, NEW_DVAR(_e)),
- new_block(NEW_OPTBLOCK(node),
- NEW_DASGN(_e, NEW_CALL(NEW_DVAR(_e), idSucc, 0)))),
- 1));
- }
- }
-#if 0
- else if(){
- /* Special Block for Array#each
- {|e, _self|
- _i = 0
- _j = 0
- while(_j = _i; _i = _i.succ; e = _self[_i]; _j < _self.length)
- BODY
- end
- }
- */
- nn = new_block(...);
- }
-#endif
- else{
- rb_bug("Unsupport special block type: %s",
- rb_id2name(iseq->special_block_type));
- }
- return node;
-}
-
static int
search_block_local_variables(NODE *node, VALUE local_vars)
{
@@ -1088,9 +934,9 @@
iseq->arg_simple = 1;
}
- if(iseq->special_block_type != 0){
- node = make_special_block_body(iseq, node,
- param_vars, local_vars);
+ if(iseq->special_block_builder != 0){
+ node = ((NODE *(*)(yarv_iseq_t *, NODE*, VALUE, VALUE))
+ iseq->special_block_builder)(iseq, node, param_vars, local_vars);
}
rb_ary_concat(param_vars, local_vars);
Modified: trunk/numeric.c
===================================================================
--- trunk/numeric.c 2005-12-03 11:37:46 UTC (rev 301)
+++ trunk/numeric.c 2005-12-03 13:28:33 UTC (rev 302)
@@ -11,7 +11,6 @@
**********************************************************************/
#include "ruby.h"
-#include "yarv.h"
#include <ctype.h>
#include <math.h>
#include <stdio.h>
@@ -2729,31 +2728,9 @@
static VALUE
int_dotimes(VALUE num)
{
- if(1){
- yarv_thread_t *th = GET_THREAD();
- yarv_block_t *orig_block = GC_GUARDED_PTR_REF(th->cfp->lfp[0]);
-
- if(BUILTIN_TYPE(orig_block->iseq) != T_NODE){
- VALUE tsiseqval = yarv_iseq_special_block(orig_block->iseq, idTimes);
- yarv_iseq_t *tsiseq;
- VALUE argv[2], val;
-
- if(tsiseqval){
- yarv_block_t block = *orig_block;
- GetISeqVal(tsiseqval, tsiseq);
- block.iseq = tsiseq;
- th->cfp->lfp[0] = GC_GUARDED_PTR(&block);
- argv[0] = INT2FIX(0);
- argv[1] = num;
- val = th_invoke_yield(th, 2, argv);
- if(val == Qundef){
- return num;
- }
- else{
- return val;
- }
- }
- }
+ VALUE val;
+ if((val = yarv_invoke_Integer_times_specail_block(num)) != Qundef){
+ return val;
}
if (FIXNUM_P(num)) {
Modified: trunk/range.c
===================================================================
--- trunk/range.c 2005-12-03 11:37:46 UTC (rev 301)
+++ trunk/range.c 2005-12-03 13:28:33 UTC (rev 302)
@@ -366,41 +366,20 @@
* 10 11 12 13 14 15
*/
-#include "yarv.h"
-
static VALUE
range_each(VALUE range)
{
- VALUE beg, end;
-
+ VALUE beg, end, val;
+
RETURN_ENUMERATOR(range, 0, 0);
beg = rb_ivar_get(range, id_beg);
end = rb_ivar_get(range, id_end);
-
- if(1){
- yarv_thread_t *th = GET_THREAD();
- yarv_block_t *orig_block = GC_GUARDED_PTR_REF(th->cfp->lfp[0]);
- if(BUILTIN_TYPE(orig_block->iseq) != T_NODE){
- ID id = EXCL(range) ? idRangeEachLT : idRangeEachLE;
- VALUE tsiseqval = yarv_iseq_special_block(orig_block->iseq, id);
- yarv_iseq_t *tsiseq;
- VALUE argv[2];
-
- if(tsiseqval){
- yarv_block_t block = *orig_block;
- GetISeqVal(tsiseqval, tsiseq);
- block.iseq = tsiseq;
- th->cfp->lfp[0] = GC_GUARDED_PTR(&block);
- argv[0] = beg;
- argv[1] = end;
- th_invoke_yield(th, 2, argv);
- return range;
- }
- }
+ val = yarv_invoke_Range_each_special_block(range, beg, end, EXCL(range));
+ if(val != Qundef){
+ return val;
}
-
if (!rb_respond_to(beg, id_succ)) {
rb_raise(rb_eTypeError, "can't iterate from %s",
rb_obj_classname(beg));
Modified: trunk/test.rb
===================================================================
--- trunk/test.rb 2005-12-03 11:37:46 UTC (rev 301)
+++ trunk/test.rb 2005-12-03 13:28:33 UTC (rev 302)
@@ -1,9 +1,14 @@
-r = (1..3)
-p r.map{|e|
- e+1
+3.times{|e|
+ p e
}
__END__
+[[1,2],[3,4]].each{|a, b|
+ p [a, b]
+}
+
+
+__END__
i=:foo
prs = []
3.times{|e|
Modified: trunk/yarvcore.c
===================================================================
--- trunk/yarvcore.c 2005-12-03 11:37:46 UTC (rev 301)
+++ trunk/yarvcore.c 2005-12-03 13:28:33 UTC (rev 302)
@@ -424,11 +424,9 @@
iseq->arg_rest = 0;
iseq->arg_block = 0;
iseq->klass = 0;
- if(opt){
- iseq->special_block_type = SYM2ID(opt);
- }
- iseq->cached_special_block_type = 0;
- iseq->cached_special_block = 0;
+ iseq->special_block_builder = GC_GUARDED_PTR_REF(opt);
+ iseq->cached_special_block_builder = 0;
+ iseq->cached_special_block = 0;
/* set class nest stack */
if(type == ISEQ_TYPE_CLASS){
Modified: trunk/yarvcore.h
===================================================================
--- trunk/yarvcore.h 2005-12-03 11:37:46 UTC (rev 301)
+++ trunk/yarvcore.h 2005-12-03 13:28:33 UTC (rev 302)
@@ -205,8 +205,8 @@
NODE *node;
- ID special_block_type;
- ID cached_special_block_type;
+ void *special_block_builder;
+ void *cached_special_block_builder;
VALUE cached_special_block;
/* sequence size */
--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml