diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | compile.c | 77 | ||||
-rw-r--r-- | iseq.c | 50 |
3 files changed, 78 insertions, 53 deletions
@@ -1,3 +1,7 @@ +Mon Jul 2 05:29:07 2007 Koichi Sasada <[email protected]> + + * compile.c, iseq.c: fix iseq some of load/store process. + Mon Jul 2 03:09:36 2007 Koichi Sasada <[email protected]> * yarvcore.h, compile.c, insnhelper.ci, iseq.c, vm.c: @@ -4542,12 +4542,11 @@ iseq_build_exception(rb_iseq_t *iseq, struct st_table *labels_table, return COMPILE_OK; } - struct st_table *insn_make_insn_table(void); static int iseq_build_body(rb_iseq_t *iseq, LINK_ANCHOR *anchor, - VALUE body, VALUE line, struct st_table *labels_table) + VALUE body, struct st_table *labels_table) { /* TODO: body should be freezed */ VALUE *ptr = RARRAY_PTR(body); @@ -4577,14 +4576,16 @@ iseq_build_body(rb_iseq_t *iseq, LINK_ANCHOR *anchor, VALUE *argv = 0; int argc = RARRAY_LEN(obj) - 1; VALUE insn_id; + VALUE insn; - if (st_lookup(insn_table, rb_ary_entry(obj, 0), &insn_id) == 0) { + insn = rb_ary_entry(obj, 0); + if (st_lookup(insn_table, insn, &insn_id) == 0) { /* TODO: exception */ - rb_bug("unknown instruction: "); + rb_raise(rb_eRuntimeError, "unknown instruction: %s", rb_inspect(insn)); } if (argc != insn_len(insn_id)-1) { - rb_bug("operand size mismatch"); + rb_raise(rb_eRuntimeError, "operand size mismatch"); } if (argc > 0) { @@ -4610,15 +4611,13 @@ iseq_build_body(rb_iseq_t *iseq, LINK_ANCHOR *anchor, { if (op != Qnil) { if (TYPE(op) == T_ARRAY) { - argv[j] = - iseq_load(0, op, iseq->self, Qnil); + argv[j] = iseq_load(0, op, iseq->self, Qnil); } else if (CLASS_OF(op) == rb_cISeq) { argv[j] = op; } else { - /* TODO: exception */ - rb_bug("not an iseq"); + rb_raise(rb_eRuntimeError, "ISEQ is required"); } iseq_add_mark_object(iseq, argv[j]); } @@ -4670,9 +4669,14 @@ iseq_build_body(rb_iseq_t *iseq, LINK_ANCHOR *anchor, return COMPILE_OK; } +#define CHECK_ARRAY(v) rb_convert_type(v, T_ARRAY, "Array", "to_ary") +#define CHECK_STRING(v) rb_convert_type(v, T_STRING, "String", "to_str") +#define CHECK_SYMBOL(v) rb_convert_type(v, T_SYMBOL, "Symbol", "to_sym") +#define CHECK_INTEGER(v) (NUM2LONG(v), v) + VALUE -iseq_build_from_ary(rb_iseq_t *iseq, VALUE line, - VALUE locals, VALUE args, VALUE exception, VALUE body) +iseq_build_from_ary(rb_iseq_t *iseq, VALUE locals, VALUE args, + VALUE exception, VALUE body) { int i; int opt = 0; @@ -4687,45 +4691,50 @@ iseq_build_from_ary(rb_iseq_t *iseq, VALUE line, opt = 1; } - iseq->local_size = opt + RARRAY_LEN(locals); - iseq->local_table_size = iseq->local_size; - iseq->local_table = (ID *)ALLOC_N(ID *, iseq->local_size); - tbl = iseq->local_table + opt; + iseq->local_table_size = opt + RARRAY_LEN(locals); + iseq->local_table = tbl = (ID *)ALLOC_N(ID *, iseq->local_table_size); + iseq->local_size = opt + iseq->local_table_size; for (i=0; i<RARRAY_LEN(locals); i++) { - tbl[i] = SYM2ID(RARRAY_PTR(locals)[i]); + tbl[i] = SYM2ID(CHECK_SYMBOL(RARRAY_PTR(locals)[i])); } /* args */ if (FIXNUM_P(args)) { - iseq->argc = FIX2INT(args); + iseq->arg_size = iseq->argc = FIX2INT(args); iseq->arg_simple = 1; } else { - /* - * [argc, # argc - * opts, # opts - * [label1, label2, ...] # opt labels - * rest_iex, - * block_idx, - * ] - * or - * argc (Fixnum) # arg_simple - */ int i = 0; - VALUE argc = rb_ary_entry(args, i++); - VALUE arg_opts = rb_ary_entry(args, i++); - VALUE arg_opt_labels = rb_ary_entry(args, i++); - VALUE arg_rest = rb_ary_entry(args, i++); - VALUE arg_block = rb_ary_entry(args, i++); + VALUE argc = CHECK_INTEGER(rb_ary_entry(args, i++)); + VALUE arg_opts = CHECK_INTEGER(rb_ary_entry(args, i++)); + VALUE arg_opt_labels = CHECK_ARRAY(rb_ary_entry(args, i++)); + VALUE arg_post_len = CHECK_INTEGER(rb_ary_entry(args, i++)); + VALUE arg_post_start = CHECK_INTEGER(rb_ary_entry(args, i++)); + VALUE arg_rest = CHECK_INTEGER(rb_ary_entry(args, i++)); + VALUE arg_block = CHECK_INTEGER(rb_ary_entry(args, i++)); iseq->argc = FIX2INT(argc); iseq->arg_opts = FIX2INT(arg_opts); iseq->arg_rest = FIX2INT(arg_rest); + iseq->arg_post_len = FIX2INT(arg_post_len); + iseq->arg_post_start = FIX2INT(arg_post_start); iseq->arg_block = FIX2INT(arg_block); - iseq->arg_opt_table = (VALUE *)ALLOC_N(VALUE, iseq->arg_opts); + if (iseq->arg_block != -1) { + iseq->arg_size = iseq->arg_block + 1; + } + else if (iseq->arg_post_len) { + iseq->arg_size = iseq->arg_post_start + iseq->arg_post_len; + } + else if (iseq->arg_rest != -1) { + iseq->arg_size = iseq->arg_rest + 1; + } + else { + iseq->arg_size = iseq->argc + iseq->arg_opts; + } + for (i=0; i<RARRAY_LEN(arg_opt_labels); i++) { iseq->arg_opt_table[i] = (VALUE)register_label(iseq, labels_table, @@ -4737,6 +4746,6 @@ iseq_build_from_ary(rb_iseq_t *iseq, VALUE line, iseq_build_exception(iseq, labels_table, exception); /* body */ - iseq_build_body(iseq, anchor, body, line, labels_table); + iseq_build_body(iseq, anchor, body, labels_table); return iseq->self; } @@ -304,8 +304,8 @@ rb_iseq_new_with_bopt(NODE *node, VALUE name, VALUE filename, bopt, &COMPILE_OPTION_DEFAULT); } -VALUE iseq_build_from_ary(rb_iseq_t *iseq, VALUE line, - VALUE locals, VALUE args, VALUE exception, VALUE body); +VALUE iseq_build_from_ary(rb_iseq_t *iseq, VALUE locals, VALUE args, + VALUE exception, VALUE body); #define CHECK_ARRAY(v) rb_convert_type(v, T_ARRAY, "Array", "to_ary") #define CHECK_STRING(v) rb_convert_type(v, T_STRING, "String", "to_str") @@ -344,10 +344,12 @@ iseq_load(VALUE self, VALUE data, VALUE parent, VALUE opt) type = CHECK_SYMBOL(rb_ary_entry(data, 8)); locals = CHECK_ARRAY(rb_ary_entry(data, 9)); - args = rb_ary_entry(data, 10); + + args = rb_ary_entry(data, 10); if (FIXNUM_P(args) || (args = CHECK_ARRAY(args))) { /* */ } + exception = CHECK_ARRAY(rb_ary_entry(data, 11)); body = CHECK_ARRAY(rb_ary_entry(data, 12)); @@ -377,7 +379,7 @@ iseq_load(VALUE self, VALUE data, VALUE parent, VALUE opt) prepare_iseq_build(iseq, name, filename, parent, iseq_type, 0, &option); - iseq_build_from_ary(iseq, line, locals, args, exception, body); + iseq_build_from_ary(iseq, locals, args, exception, body); cleanup_iseq_build(iseq); return iseqval; @@ -1108,7 +1110,7 @@ cdhash_each(VALUE key, VALUE value, VALUE ary) VALUE iseq_data_to_ary(rb_iseq_t *iseq) { - int i, pos; + int i, pos, line = 0, insn_pos = 0; VALUE *seq; VALUE val = rb_ary_new(); @@ -1117,8 +1119,8 @@ iseq_data_to_ary(rb_iseq_t *iseq) VALUE args = rb_ary_new(); VALUE body = rb_ary_new(); /* [[:insn1, ...], ...] */ VALUE nbody; - VALUE line = rb_ary_new(); VALUE exception = rb_ary_new(); /* [[....]] */ + VALUE misc = rb_hash_new(); static VALUE insn_syms[YARV_MAX_INSTRUCTION_SIZE]; struct st_table *labels_table = st_init_numtable(); @@ -1173,11 +1175,12 @@ iseq_data_to_ary(rb_iseq_t *iseq) /* * [argc, # argc * [label1, label2, ...] # opts - * rest_iex, - * block_idx, + * rest index, + * post_len + * post_start + * block index, + * simple, * ] - * or - * argc (Fixnum) # arg_simple */ VALUE arg_opt_labels = rb_ary_new(); int j; @@ -1188,15 +1191,17 @@ iseq_data_to_ary(rb_iseq_t *iseq) } /* commit */ - if (iseq->arg_simple) { + if (iseq->arg_simple == 1) { args = INT2FIX(iseq->argc); } else { rb_ary_push(args, INT2FIX(iseq->argc)); - rb_ary_push(args, INT2FIX(iseq->arg_opts)); rb_ary_push(args, arg_opt_labels); + rb_ary_push(args, INT2FIX(iseq->arg_post_len)); + rb_ary_push(args, INT2FIX(iseq->arg_post_start)); rb_ary_push(args, INT2FIX(iseq->arg_rest)); rb_ary_push(args, INT2FIX(iseq->arg_block)); + rb_ary_push(args, INT2FIX(iseq->arg_simple)); } } @@ -1294,7 +1299,7 @@ iseq_data_to_ary(rb_iseq_t *iseq) rb_ary_push(exception, ary); } - /* make body with labels */ + /* make body with labels and insert line number */ body = rb_ary_new(); for (i=0, pos=0; i<RARRAY_LEN(nbody); i++) { @@ -1305,26 +1310,33 @@ iseq_data_to_ary(rb_iseq_t *iseq) rb_ary_push(body, label); } + if (iseq->insn_info_table[i].line_no != line) { + line = iseq->insn_info_table[i].line_no; + rb_ary_push(body, INT2FIX(line)); + } + rb_ary_push(body, ary); pos += RARRAY_LEN(ary); } st_free_table(labels_table); - /* build array */ + rb_hash_aset(misc, ID2SYM(rb_intern("arg_size")), INT2FIX(iseq->arg_size)); + rb_hash_aset(misc, ID2SYM(rb_intern("local_size")), INT2FIX(iseq->local_size)); + rb_hash_aset(misc, ID2SYM(rb_intern("stack_max")), INT2FIX(iseq->stack_max)); - /* [magic, major_version, minor_version, format_type, misc, - * name, filename, line, - * type, args, vars, exception_table, body] + /* + * [:magic, :major_version, :minor_version, :format_type, :misc, + * :name, :filename, :type, :locals, :args, + * :catch_table, :bytecode] */ rb_ary_push(val, rb_str_new2("YARVInstructionSimpledataFormat")); rb_ary_push(val, INT2FIX(1)); rb_ary_push(val, INT2FIX(1)); rb_ary_push(val, INT2FIX(1)); - rb_ary_push(val, Qnil); + rb_ary_push(val, misc); rb_ary_push(val, iseq->name); rb_ary_push(val, iseq->filename); - rb_ary_push(val, line); rb_ary_push(val, type); rb_ary_push(val, locals); rb_ary_push(val, args); |