diff options
Diffstat (limited to 'blockinlining.c')
-rw-r--r-- | blockinlining.c | 464 |
1 files changed, 0 insertions, 464 deletions
diff --git a/blockinlining.c b/blockinlining.c deleted file mode 100644 index f9eb8af229..0000000000 --- a/blockinlining.c +++ /dev/null @@ -1,464 +0,0 @@ -/********************************************************************** - - blockinlining.c - - - $Author$ - - Copyright (C) 2004-2007 Koichi Sasada - -**********************************************************************/ - -#include "ruby/ruby.h" -#include "vm_core.h" - -static VALUE -iseq_special_block(rb_iseq_t *iseq, void *builder) -{ -#if OPT_BLOCKINLINING - VALUE parent = Qfalse; - VALUE iseqval; - - if (iseq->argc > 1 || iseq->arg_simple == 0) { - /* argument check */ - return 0; - } - - if (iseq->cached_special_block_builder) { - if (iseq->cached_special_block_builder == builder) { - return iseq->cached_special_block; - } - else { - return 0; - } - } - else { - iseq->cached_special_block_builder = (void *)1; - } - - if (iseq->parent_iseq) { - parent = iseq->parent_iseq->self; - } - iseqval = rb_iseq_new_with_bopt(iseq->node, iseq->name, iseq->filename, - parent, iseq->type, - GC_GUARDED_PTR(builder)); - if (0) { - printf("%s\n", RSTRING_PTR(rb_iseq_disasm(iseqval))); - } - iseq->cached_special_block = iseqval; - iseq->cached_special_block_builder = builder; - return iseqval; -#else - return 0; -#endif -} - -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 * -new_assign(NODE * lnode, NODE * rhs) -{ - switch (nd_type(lnode)) { - case NODE_LASGN:{ - return NEW_NODE(NODE_LASGN, lnode->nd_vid, rhs, lnode->nd_cnt); - /* NEW_LASGN(lnode->nd_vid, rhs); */ - } - case NODE_GASGN:{ - return NEW_GASGN(lnode->nd_vid, rhs); - } - case NODE_DASGN:{ - return NEW_DASGN(lnode->nd_vid, rhs); - } - case NODE_ATTRASGN:{ - NODE *args = 0; - if (lnode->nd_args) { - args = NEW_ARRAY(lnode->nd_args->nd_head); - args->nd_next = NEW_ARRAY(rhs); - args->nd_alen = 2; - } - else { - args = NEW_ARRAY(rhs); - } - - return NEW_ATTRASGN(lnode->nd_recv, - lnode->nd_mid, - args); - } - default: - rb_bug("unimplemented (block inlining): %s", ruby_node_name(nd_type(lnode))); - } - return 0; -} - -static NODE * -build_Integer_times_node(rb_iseq_t *iseq, NODE * node, NODE * lnode, - 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; - CONST_ID(_self, "#_self"); - if (iseq->argc == 0) { - ID e; - CONST_ID(e, "#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; - ID e = SYM2ID(rb_ary_entry(param_vars, 0)); - NODE *assign; - - CONST_ID(_e, "#_e"); - rb_ary_push(param_vars, ID2SYM(_self)); - rb_ary_push(local_vars, ID2SYM(_e)); - iseq->argc++; - - if (nd_type(lnode) == NODE_DASGN_CURR) { - assign = NEW_DASGN(e, NEW_DVAR(_e)); - } - else { - assign = new_assign(lnode, NEW_DVAR(_e)); - } - - 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(assign, - new_block(NEW_OPTBLOCK(node), - NEW_DASGN(_e, - NEW_CALL - (NEW_DVAR(_e), - idSucc, 0)))), - Qundef)); - } - return node; -} - -VALUE -invoke_Integer_times_special_block(VALUE num) -{ - rb_thread_t *th = GET_THREAD(); - rb_block_t *orig_block = GC_GUARDED_PTR_REF(th->cfp->lfp[0]); - - if (orig_block && BUILTIN_TYPE(orig_block->iseq) != T_NODE) { - VALUE tsiseqval = iseq_special_block(orig_block->iseq, - build_Integer_times_node); - rb_iseq_t *tsiseq; - VALUE argv[2], val; - - if (tsiseqval) { - rb_block_t block = *orig_block; - GetISeqPtr(tsiseqval, tsiseq); - block.iseq = tsiseq; - th->cfp->lfp[0] = GC_GUARDED_PTR(&block); - argv[0] = INT2FIX(0); - argv[1] = num; - val = rb_yield_values(2, argv); - if (val == Qundef) { - return num; - } - else { - return val; - } - } - } - return Qundef; -} - -static NODE * -build_Range_each_node(rb_iseq_t *iseq, NODE * node, NODE * lnode, - 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; - CONST_ID(_last, "#_last"); - if (iseq->argc == 0) { - ID e; - CONST_ID(e, "#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; - ID e = SYM2ID(rb_ary_entry(param_vars, 0)); - NODE *assign; - - CONST_ID(_e, "#_e"); - rb_ary_push(param_vars, ID2SYM(_last)); - rb_ary_push(local_vars, ID2SYM(_e)); - iseq->argc++; - - if (nd_type(lnode) == NODE_DASGN_CURR) { - assign = NEW_DASGN(e, NEW_DVAR(_e)); - } - else { - assign = new_assign(lnode, NEW_DVAR(_e)); - } - - 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(assign, - 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(rb_iseq_t *iseq, NODE * node, NODE * lnode, - VALUE param_vars, VALUE local_vars) -{ - return build_Range_each_node(iseq, node, lnode, - param_vars, local_vars, idLE); -} - -static NODE * -build_Range_each_node_LT(rb_iseq_t *iseq, NODE * node, NODE * lnode, - VALUE param_vars, VALUE local_vars) -{ - return build_Range_each_node(iseq, node, lnode, - param_vars, local_vars, idLT); -} - -VALUE -invoke_Range_each_special_block(VALUE range, - VALUE beg, VALUE end, int excl) -{ - rb_thread_t *th = GET_THREAD(); - rb_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 = iseq_special_block(orig_block->iseq, builder); - rb_iseq_t *tsiseq; - VALUE argv[2]; - - if (tsiseqval) { - VALUE val; - rb_block_t block = *orig_block; - GetISeqPtr(tsiseqval, tsiseq); - block.iseq = tsiseq; - th->cfp->lfp[0] = GC_GUARDED_PTR(&block); - argv[0] = beg; - argv[1] = end; - val = rb_yield_values(2, argv); - if (val == Qundef) { - return range; - } - else { - return val; - } - } - } - return Qundef; -} - - -static NODE * -build_Array_each_node(rb_iseq_t *iseq, NODE * node, NODE * lnode, - VALUE param_vars, VALUE local_vars) -{ - /* Special block for Array#each - ary.each{|e| - BODY - } - => - {|e, _self| - _i = 0 - while _i < _self.length - e = _self[_i] - redo_point: - BODY - next_point: - _i = _i.succ - end - } - - ary.each{ - BODY - } - => - {|_i, _self| - _i = 0 - while _i < _self.length - redo_point: - BODY - next_point: - _i = _i.succ - end - } - */ - - ID _self, _i; - - CONST_ID(_self, "#_self"); - CONST_ID(_i, "#_i"); - if (iseq->argc == 0) { - ID _e; - CONST_ID(_e, "#_e"); - rb_ary_push(param_vars, ID2SYM(_e)); - rb_ary_push(param_vars, ID2SYM(_self)); - iseq->argc += 2; - rb_ary_push(local_vars, ID2SYM(_i)); - - node = - new_block(NEW_DASGN(_i, NEW_LIT(INT2FIX(0))), - NEW_WHILE(NEW_CALL(NEW_DVAR(_i), idLT, - new_ary(NEW_CALL - (NEW_DVAR(_self), idLength, - 0), 0)), - new_block(NEW_OPTBLOCK(node), - NEW_DASGN(_i, - NEW_CALL(NEW_DVAR(_i), - idSucc, 0))), - Qundef)); - } - else { - ID e = SYM2ID(rb_ary_entry(param_vars, 0)); - NODE *assign; - - rb_ary_push(param_vars, ID2SYM(_self)); - iseq->argc++; - rb_ary_push(local_vars, ID2SYM(_i)); - - if (nd_type(lnode) == NODE_DASGN_CURR) { - assign = NEW_DASGN(e, - NEW_CALL(NEW_DVAR(_self), idAREF, - new_ary(NEW_DVAR(_i), 0))); - } - else { - assign = new_assign(lnode, - NEW_CALL(NEW_DVAR(_self), idAREF, - new_ary(NEW_DVAR(_i), 0))); - } - - node = - new_block(NEW_DASGN(_i, NEW_LIT(INT2FIX(0))), - NEW_WHILE(NEW_CALL(NEW_DVAR(_i), idLT, - new_ary(NEW_CALL - (NEW_DVAR(_self), idLength, - 0), 0)), new_block(assign, - new_block - (NEW_OPTBLOCK - (node), - NEW_DASGN - (_i, - NEW_CALL - (NEW_DVAR - (_i), - idSucc, - 0)))), - Qundef)); - } - return node; -} - -VALUE -invoke_Array_each_special_block(VALUE ary) -{ - rb_thread_t *th = GET_THREAD(); - rb_block_t *orig_block = GC_GUARDED_PTR_REF(th->cfp->lfp[0]); - - if (BUILTIN_TYPE(orig_block->iseq) != T_NODE) { - VALUE tsiseqval = iseq_special_block(orig_block->iseq, - build_Array_each_node); - rb_iseq_t *tsiseq; - VALUE argv[2]; - - if (tsiseqval) { - VALUE val; - rb_block_t block = *orig_block; - GetISeqPtr(tsiseqval, tsiseq); - block.iseq = tsiseq; - th->cfp->lfp[0] = GC_GUARDED_PTR(&block); - argv[0] = 0; - argv[1] = ary; - val = rb_yield_values(2, argv); - if (val == Qundef) { - return ary; - } - else { - return val; - } - } - } - return Qundef; -} |