/* call-seq:
* iseq.each(&block) => nil
*
* Yields each instruction in the sequence.
*/
static VALUE iseq_each(VALUE self)
{
rb_iseq_t *iseqdat = iseq_check(self);
VALUE * seq;
for(seq = iseqdat->iseq; seq < iseqdat->iseq + iseqdat->iseq_size; )
{
VALUE insn = *seq++;
int op_type_idx;
int len = insn_len(insn);
VALUE args = rb_ary_new();
for(op_type_idx = 0; op_type_idx < len-1; ++op_type_idx, ++seq)
{
switch(insn_op_type(insn, op_type_idx))
{
case TS_VALUE:
rb_ary_push(args, *seq);
break;
case TS_LINDEX:
case TS_DINDEX:
case TS_NUM:
rb_ary_push(args, INT2FIX(*seq));
break;
case TS_ISEQ:
{
rb_iseq_t * iseq = (rb_iseq_t *)*seq;
if(iseq)
{
rb_ary_push(args, iseq->self);
}
else
{
rb_ary_push(args, Qnil);
}
break;
}
case TS_GENTRY:
{
struct global_entry *entry = (struct global_entry *)*seq;
rb_ary_push(args, ID2SYM(rb_intern(rb_id2name(entry->id))));
break;
}
case TS_OFFSET:
rb_ary_push(args, Qnil);
/* TODO */
break;
case TS_VARIABLE:
rb_ary_push(args, Qnil);
/* TODO */
break;
case TS_CDHASH:
rb_ary_push(args, Qnil);
/* TODO */
break;
case TS_IC:
{
NODE * ic = (NODE *)*seq;
rb_ary_push(args, wrap_node_as(ic, rb_cInlineCache));
break;
}
case TS_ID:
rb_ary_push(args, ID2SYM(*seq));
break;
}
}
rb_yield(rb_class_new_instance(
RARRAY(args)->len,
RARRAY(args)->ptr,
instruction_class[insn]));
}
return Qnil;
}