ruby-changes:23705
From: ko1 <ko1@a...>
Date: Tue, 22 May 2012 17:31:51 +0900 (JST)
Subject: [ruby-changes:23705] ko1:r35756 (trunk): * vm_core.h: add a data type rb_location_t to store iseq location
ko1 2012-05-22 17:31:38 +0900 (Tue, 22 May 2012) New Revision: 35756 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=35756 Log: * vm_core.h: add a data type rb_location_t to store iseq location information. rb_location_t#filename, filepath, name and line_no was moved from rb_iseq_t. rb_location_t#basename is a new field which is similar to `name' field without any decoration. `name' field contains some decoration such as `block in foo'. `basename' only contains `foo'. rb_iseq_t contains memory object of rb_location_t. * iseq.c: setup rb_location_t for each rb_iseq_t memory objects. * compile.c, proc.c, vm.c, vm_dump.c, vm_eval.c, vm_insnhelper.c, vm_method.c: support about it. Modified files: trunk/ChangeLog trunk/compile.c trunk/iseq.c trunk/proc.c trunk/vm.c trunk/vm_core.h trunk/vm_dump.c trunk/vm_eval.c trunk/vm_insnhelper.c trunk/vm_method.c Index: ChangeLog =================================================================== --- ChangeLog (revision 35755) +++ ChangeLog (revision 35756) @@ -1,3 +1,19 @@ +Tue May 22 16:49:15 2012 Koichi Sasada <ko1@a...> + + * vm_core.h: add a data type rb_location_t to store iseq location + information. + rb_location_t#filename, filepath, name and line_no was moved from + rb_iseq_t. rb_location_t#basename is a new field which is + similar to `name' field without any decoration. + `name' field contains some decoration such as `block in foo'. + `basename' only contains `foo'. + rb_iseq_t contains memory object of rb_location_t. + + * iseq.c: setup rb_location_t for each rb_iseq_t memory objects. + + * compile.c, proc.c, vm.c, vm_dump.c, vm_eval.c, vm_insnhelper.c, + vm_method.c: support about it. + Tue May 22 00:45:05 2012 Yusuke Endoh <mame@t...> * struct.c (rb_struct_members): Refactoring. As Struct#members had Index: vm_core.h =================================================================== --- vm_core.h (revision 35755) +++ vm_core.h (revision 35756) @@ -150,6 +150,14 @@ #define GetISeqPtr(obj, ptr) \ GetCoreDataFromValue((obj), rb_iseq_t, (ptr)) +typedef struct rb_location_struct { + VALUE filename; + VALUE filepath; + VALUE basename; + VALUE name; + size_t line_no; +} rb_location_t; + struct rb_iseq_struct; struct rb_iseq_struct { @@ -169,16 +177,14 @@ ISEQ_TYPE_DEFINED_GUARD } type; /* instruction sequence type */ - VALUE name; /* String: iseq name */ - VALUE filename; /* file information where this sequence from */ - VALUE filepath; /* real file path or nil */ + rb_location_t location; + VALUE *iseq; /* iseq (insn number and operands) */ VALUE *iseq_encoded; /* encoded iseq */ unsigned long iseq_size; VALUE mark_ary; /* Array: includes operands which should be GC marked */ VALUE coverage; /* coverage array */ - unsigned short line_no; - + /* insn info, must be freed */ struct iseq_line_info_entry *line_info_table; size_t line_info_size; Index: iseq.c =================================================================== --- iseq.c (revision 35755) +++ iseq.c (revision 35756) @@ -69,8 +69,8 @@ if (!iseq->orig) { /* It's possible that strings are freed */ if (0) { - RUBY_GC_INFO("%s @ %s\n", RSTRING_PTR(iseq->name), - RSTRING_PTR(iseq->filename)); + RUBY_GC_INFO("%s @ %s\n", RSTRING_PTR(iseq->location.name), + RSTRING_PTR(iseq->location.filename)); } if (iseq->iseq != iseq->iseq_encoded) { @@ -99,11 +99,14 @@ if (ptr) { rb_iseq_t *iseq = ptr; - RUBY_GC_INFO("%s @ %s\n", RSTRING_PTR(iseq->name), RSTRING_PTR(iseq->filename)); + RUBY_GC_INFO("%s @ %s\n", RSTRING_PTR(iseq->location.name), RSTRING_PTR(iseq->location.filename)); RUBY_MARK_UNLESS_NULL(iseq->mark_ary); - RUBY_MARK_UNLESS_NULL(iseq->name); - RUBY_MARK_UNLESS_NULL(iseq->filename); - RUBY_MARK_UNLESS_NULL(iseq->filepath); + + RUBY_MARK_UNLESS_NULL(iseq->location.name); + RUBY_MARK_UNLESS_NULL(iseq->location.basename); + RUBY_MARK_UNLESS_NULL(iseq->location.filename); + RUBY_MARK_UNLESS_NULL(iseq->location.filepath); + RUBY_MARK_UNLESS_NULL((VALUE)iseq->cref_stack); RUBY_MARK_UNLESS_NULL(iseq->klass); RUBY_MARK_UNLESS_NULL(iseq->coverage); @@ -175,6 +178,17 @@ return TypedData_Make_Struct(klass, rb_iseq_t, &iseq_data_type, iseq); } +static rb_location_t * +iseq_location_setup(rb_iseq_t *iseq, VALUE filename, VALUE filepath, VALUE name, size_t line_no) +{ + rb_location_t *loc = &iseq->location; + loc->filename = filename; + loc->filepath = filepath; + loc->name = loc->basename = name; + loc->line_no = line_no; + return loc; +} + static void set_relation(rb_iseq_t *iseq, const VALUE parent) { @@ -225,23 +239,26 @@ VALUE parent, enum iseq_type type, VALUE block_opt, const rb_compile_option_t *option) { + iseq->type = type; + iseq->arg_rest = -1; + iseq->arg_block = -1; + iseq->arg_keyword = -1; + iseq->klass = 0; + set_relation(iseq, parent); + OBJ_FREEZE(name); OBJ_FREEZE(filename); - iseq->name = name; - iseq->filename = filename; - iseq->filepath = filepath; - iseq->line_no = (unsigned short)line_no; /* TODO: really enough? */ + iseq_location_setup(iseq, filename, filepath, name, line_no); + if (iseq != iseq->local_iseq) { + iseq->location.basename = iseq->local_iseq->location.name; + } + iseq->defined_method_id = 0; iseq->mark_ary = rb_ary_tmp_new(3); OBJ_UNTRUST(iseq->mark_ary); RBASIC(iseq->mark_ary)->klass = 0; - iseq->type = type; - iseq->arg_rest = -1; - iseq->arg_block = -1; - iseq->arg_keyword = -1; - iseq->klass = 0; /* * iseq->special_block_builder = GC_GUARDED_PTR_REF(block_opt); @@ -269,8 +286,6 @@ iseq->compile_data->option = option; iseq->compile_data->last_coverable_line = -1; - set_relation(iseq, parent); - iseq->coverage = Qfalse; if (!GET_THREAD()->parse_in_eval) { VALUE coverages = rb_get_coverages(); @@ -292,7 +307,7 @@ compile_data_free(data); if (RTEST(err)) { - rb_funcall2(err, rb_intern("set_backtrace"), 1, &iseq->filename); + rb_funcall2(err, rb_intern("set_backtrace"), 1, &iseq->location.filename); rb_exc_raise(err); } return Qtrue; @@ -560,7 +575,7 @@ make_compile_option(&option, opt); if (th->base_block && th->base_block->iseq) { - return rb_iseq_new_with_opt(node, th->base_block->iseq->name, + return rb_iseq_new_with_opt(node, th->base_block->iseq->location.name, file, filepath, line, th->base_block->iseq->self, ISEQ_TYPE_EVAL, &option); } @@ -636,7 +651,7 @@ { rb_iseq_t *iseq; GetISeqPtr(val, iseq); - if (!iseq->name) { + if (!iseq->location.name) { rb_raise(rb_eTypeError, "uninitialized InstructionSequence"); } return iseq; @@ -654,13 +669,13 @@ { rb_iseq_t *iseq; GetISeqPtr(self, iseq); - if (!iseq->name) { + if (!iseq->location.name) { return rb_sprintf("#<%s: uninitialized>", rb_obj_classname(self)); } return rb_sprintf("<%s:%s@%s>", rb_obj_classname(self), - RSTRING_PTR(iseq->name), RSTRING_PTR(iseq->filename)); + RSTRING_PTR(iseq->location.name), RSTRING_PTR(iseq->location.filename)); } static @@ -677,7 +692,7 @@ int rb_iseq_first_lineno(const rb_iseq_t *iseq) { - return FIX2INT(iseq->line_no); + return FIX2INT(iseq->location.line_no); } /* TODO: search algorithm is brute force. @@ -808,7 +823,7 @@ { rb_iseq_t *iseq = (rb_iseq_t *)op; if (iseq) { - ret = iseq->name; + ret = iseq->location.name; if (child) { rb_ary_push(child, iseq->self); } @@ -1342,10 +1357,10 @@ rb_ary_push(val, INT2FIX(ISEQ_MINOR_VERSION)); /* minor */ rb_ary_push(val, INT2FIX(1)); rb_ary_push(val, misc); - rb_ary_push(val, iseq->name); - rb_ary_push(val, iseq->filename); - rb_ary_push(val, iseq->filepath); - rb_ary_push(val, iseq->line_no); + rb_ary_push(val, iseq->location.name); + rb_ary_push(val, iseq->location.filename); + rb_ary_push(val, iseq->location.filepath); + rb_ary_push(val, iseq->location.line_no); rb_ary_push(val, type); rb_ary_push(val, locals); rb_ary_push(val, args); @@ -1482,9 +1497,9 @@ /* copy iseq */ *iseq = *iseq_template; - iseq->name = rb_str_new2(name); - iseq->filename = rb_str_new2(filename); - iseq->line_no = line_no; + iseq->location.name = rb_str_new2(name); + iseq->location.filename = rb_str_new2(filename); + iseq->location.line_no = line_no; iseq->mark_ary = rb_ary_tmp_new(3); OBJ_UNTRUST(iseq->mark_ary); iseq->self = iseqval; Index: compile.c =================================================================== --- compile.c (revision 35755) +++ compile.c (revision 35756) @@ -166,10 +166,10 @@ #define NEW_LABEL(l) new_label_body(iseq, (l)) #define iseq_filename(iseq) \ - (((rb_iseq_t*)DATA_PTR(iseq))->filename) + (((rb_iseq_t*)DATA_PTR(iseq))->location.filename) #define iseq_filepath(iseq) \ - (((rb_iseq_t*)DATA_PTR(iseq))->filepath) + (((rb_iseq_t*)DATA_PTR(iseq))->location.filepath) #define NEW_ISEQVAL(node, name, type, line_no) \ new_child_iseq(iseq, (node), (name), 0, (type), (line_no)) @@ -423,7 +423,7 @@ return COMPILE_OK; } -#define ruby_sourcefile RSTRING_PTR(iseq->filename) +#define ruby_sourcefile RSTRING_PTR(iseq->location.filename) static int iseq_add_mark_object_compile_time(rb_iseq_t *iseq, VALUE v) @@ -491,13 +491,13 @@ break; } case ISEQ_TYPE_CLASS: { - ADD_TRACE(ret, FIX2INT(iseq->line_no), RUBY_EVENT_CLASS); + ADD_TRACE(ret, FIX2INT(iseq->location.line_no), RUBY_EVENT_CLASS); COMPILE(ret, "scoped node", node->nd_body); ADD_TRACE(ret, nd_line(node), RUBY_EVENT_END); break; } case ISEQ_TYPE_METHOD: { - ADD_TRACE(ret, FIX2INT(iseq->line_no), RUBY_EVENT_CALL); + ADD_TRACE(ret, FIX2INT(iseq->location.line_no), RUBY_EVENT_CALL); COMPILE(ret, "scoped node", node->nd_body); ADD_TRACE(ret, nd_line(node), RUBY_EVENT_RETURN); break; @@ -1376,7 +1376,7 @@ default: dump_disasm_list(FIRST_ELEMENT(anchor)); dump_disasm_list(list); - rb_compile_error(RSTRING_PTR(iseq->filename), line, + rb_compile_error(RSTRING_PTR(iseq->location.filename), line, "error: set_sequence"); break; } @@ -1419,7 +1419,7 @@ if (iobj->operand_size != len - 1) { /* printf("operand size miss! (%d, %d)\n", iobj->operand_size, len); */ dump_disasm_list(list); - rb_compile_error(RSTRING_PTR(iseq->filename), iobj->line_no, + rb_compile_error(RSTRING_PTR(iseq->location.filename), iobj->line_no, "operand size miss! (%d for %d)", iobj->operand_size, len - 1); xfree(generated_iseq); @@ -1436,7 +1436,7 @@ /* label(destination position) */ lobj = (LABEL *)operands[j]; if (!lobj->set) { - rb_compile_error(RSTRING_PTR(iseq->filename), iobj->line_no, + rb_compile_error(RSTRING_PTR(iseq->location.filename), iobj->line_no, "unknown label"); } if (lobj->sp == -1) { @@ -1502,7 +1502,7 @@ } break; default: - rb_compile_error(RSTRING_PTR(iseq->filename), iobj->line_no, + rb_compile_error(RSTRING_PTR(iseq->location.filename), iobj->line_no, "unknown operand type: %c", type); xfree(generated_iseq); xfree(line_info_table); @@ -2045,7 +2045,7 @@ dump_disasm_list((LINK_ELEMENT *)iobj); dump_disasm_list((LINK_ELEMENT *)lobj); printf("\n-- %d, %d\n", lobj->sc_state, nstate); - rb_compile_error(RSTRING_PTR(iseq->filename), iobj->line_no, + rb_compile_error(RSTRING_PTR(iseq->location.filename), iobj->line_no, "insn_set_sc_state error\n"); return 0; } @@ -2147,7 +2147,7 @@ case SCS_XX: goto normal_insn; default: - rb_compile_error(RSTRING_PTR(iseq->filename), iobj->line_no, + rb_compile_error(RSTRING_PTR(iseq->location.filename), iobj->line_no, "unreachable"); } /* remove useless pop */ @@ -2449,7 +2449,7 @@ } else { if (rb_hash_lookup(literals, lit) != Qnil) { - rb_compile_warning(RSTRING_PTR(iseq->filename), nd_line(val), "duplicated when clause is ignored"); + rb_compile_warning(RSTRING_PTR(iseq->location.filename), nd_line(val), "duplicated when clause is ignored"); } else { rb_hash_aset(literals, lit, (VALUE)(l1) | 1); @@ -2897,7 +2897,7 @@ VALUE rescue = NEW_CHILD_ISEQVAL(NEW_NIL(), rb_str_concat(rb_str_new2 ("defined guard in "), - iseq->name), + iseq->location.name), ISEQ_TYPE_DEFINED_GUARD, 0); APPEND_LABEL(ret, lcur, lstart); ADD_LABEL(ret, lend); @@ -2924,10 +2924,10 @@ } if (level == 1) { - return rb_sprintf("block in %s", RSTRING_PTR(ip->name)); + return rb_sprintf("block in %s", RSTRING_PTR(ip->location.name)); } else { - return rb_sprintf("block (%d levels) in %s", level, RSTRING_PTR(ip->name)); + return rb_sprintf("block (%d levels) in %s", level, RSTRING_PTR(ip->location.name)); } } @@ -3649,7 +3649,7 @@ LABEL *lcont = NEW_LABEL(nd_line(node)); VALUE rescue = NEW_CHILD_ISEQVAL( node->nd_resq, - rb_str_concat(rb_str_new2("rescue in "), iseq->name), + rb_str_concat(rb_str_new2("rescue in "), iseq->location.name), ISEQ_TYPE_RESCUE, nd_line(node)); ADD_LABEL(ret, lstart); @@ -3731,7 +3731,7 @@ VALUE ensure = NEW_CHILD_ISEQVAL(node->nd_ensr, rb_str_concat(rb_str_new2 ("ensure in "), - iseq->name), + iseq->location.name), ISEQ_TYPE_ENSURE, nd_line(node)); LABEL *lstart = NEW_LABEL(nd_line(node)); LABEL *lend = NEW_LABEL(nd_line(node)); @@ -4917,7 +4917,7 @@ LABEL *lfin = NEW_LABEL(nd_line(node)); LABEL *ltrue = NEW_LABEL(nd_line(node)); VALUE key = rb_sprintf("flipflag/%s-%p-%d", - RSTRING_PTR(iseq->name), (void *)iseq, + RSTRING_PTR(iseq->location.name), (void *)iseq, iseq->compile_data->flip_cnt++); hide_obj(key); @@ -5454,12 +5454,12 @@ if (st_lookup(insn_table, (st_data_t)insn, &insn_id) == 0) { /* TODO: exception */ RB_GC_GUARD(insn) = rb_inspect(insn); - rb_compile_error(RSTRING_PTR(iseq->filename), line_no, + rb_compile_error(RSTRING_PTR(iseq->location.filename), line_no, "unknown instruction: %s", RSTRING_PTR(insn)); } if (argc != insn_len((VALUE)insn_id)-1) { - rb_compile_error(RSTRING_PTR(iseq->filename), line_no, + rb_compile_error(RSTRING_PTR(iseq->location.filename), line_no, "operand size mismatch"); } Index: vm_eval.c =================================================================== --- vm_eval.c (revision 35755) +++ vm_eval.c (revision 35756) @@ -1776,7 +1776,7 @@ rb_thread_t *th = GET_THREAD(); rb_control_frame_t *cfp = th->cfp; cfp = vm_get_ruby_level_caller_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp)); - if (cfp != 0) return cfp->iseq->filepath; + if (cfp != 0) return cfp->iseq->location.filepath; return Qnil; } Index: proc.c =================================================================== --- proc.c (revision 35755) +++ proc.c (revision 35756) @@ -322,7 +322,7 @@ GetBindingPtr(bindval, bind); bind->env = rb_vm_make_env_object(th, cfp); - bind->filename = cfp->iseq->filename; + bind->filename = cfp->iseq->location.filename; bind->line_no = rb_vm_get_sourceline(cfp); return bindval; } @@ -699,7 +699,7 @@ VALUE loc[2]; if (!iseq) return Qnil; - loc[0] = iseq->filename; + loc[0] = iseq->location.filename; if (iseq->line_info_table) { loc[1] = INT2FIX(rb_iseq_first_lineno(iseq)); } @@ -849,7 +849,7 @@ line_no = rb_iseq_first_lineno(iseq); } str = rb_sprintf("#<%s:%p@%s:%d%s>", cname, (void *)self, - RSTRING_PTR(iseq->filename), + RSTRING_PTR(iseq->location.filename), line_no, is_lambda); } else { @@ -1980,7 +1980,7 @@ GetBindingPtr(bindval, bind); bind->env = proc->envval; if (RUBY_VM_NORMAL_ISEQ_P(proc->block.iseq)) { - bind->filename = proc->block.iseq->filename; + bind->filename = proc->block.iseq->location.filename; bind->line_no = rb_iseq_first_lineno(proc->block.iseq); } else { Index: vm_method.c =================================================================== --- vm_method.c (revision 35755) +++ vm_method.c (revision 35756) @@ -224,9 +224,9 @@ default: break; } - if (iseq && !NIL_P(iseq->filename)) { + if (iseq && !NIL_P(iseq->location.filename)) { int line = iseq->line_info_table ? rb_iseq_first_lineno(iseq) : 0; - rb_compile_warning(RSTRING_PTR(iseq->filename), line, + rb_compile_warning(RSTRING_PTR(iseq->location.filename), line, "previous definition of %s was here", rb_id2name(old_def->original_id)); } @@ -307,7 +307,7 @@ th = GET_THREAD(); cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp); if (cfp && (line = rb_vm_get_sourceline(cfp))) { - VALUE location = rb_ary_new3(2, cfp->iseq->filename, INT2FIX(line)); + VALUE location = rb_ary_new3(2, cfp->iseq->location.filename, INT2FIX(line)); def->body.attr.location = rb_ary_freeze(location); } break; Index: vm.c =================================================================== --- vm.c (revision 35755) +++ vm.c (revision 35756) @@ -767,8 +767,8 @@ rb_iseq_t *iseq = cfp->iseq; line_no = rb_vm_get_sourceline(cfp); - file = iseq->filename; - if ((*iter)(arg, file, line_no, iseq->name)) break; + file = iseq->location.filename; + if ((*iter)(arg, file, line_no, iseq->location.name)) break; } } else if (RUBYVM_CFUNC_FRAME_P(cfp)) { @@ -833,7 +833,7 @@ rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp); if (cfp) { - return cfp->iseq->filename; + return cfp->iseq->location.filename; } else { return Qnil; @@ -847,7 +847,7 @@ rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp); if (cfp) { - return RSTRING_PTR(cfp->iseq->filename); + return RSTRING_PTR(cfp->iseq->location.filename); } else { return 0; @@ -1511,9 +1511,9 @@ if (cfp->pc != 0) { rb_iseq_t *iseq = cfp->iseq; int line_no = rb_vm_get_sourceline(cfp); - char *file = RSTRING_PTR(iseq->filename); + char *file = RSTRING_PTR(iseq->location.filename); str = rb_sprintf("%s:%d:in `%s'", - file, line_no, RSTRING_PTR(iseq->name)); + file, line_no, RSTRING_PTR(iseq->location.name)); } } else if (cfp->me->def->original_id) { @@ -2258,7 +2258,7 @@ rb_thread_t *th = GET_VM()->main_thread; rb_control_frame_t *cfp = (void *)(th->stack + th->stack_size); --cfp; - cfp->iseq->filename = filename; + cfp->iseq->location.filename = filename; } #if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE Index: vm_dump.c =================================================================== --- vm_dump.c (revision 35755) +++ vm_dump.c (revision 35756) @@ -38,7 +38,7 @@ VALUE tmp; if (cfp->block_iseq != 0 && BUILTIN_TYPE(cfp->block_iseq) != T_NODE) { - biseq_name = ""; /* RSTRING(cfp->block_iseq->name)->ptr; */ + biseq_name = ""; /* RSTRING(cfp->block_iseq->location.name)->ptr; */ } if (lfp < 0 || (size_t)lfp > th->stack_size) { @@ -110,10 +110,10 @@ } else { pc = cfp->pc - cfp->iseq->iseq_encoded; - iseq_name = RSTRING_PTR(cfp->iseq->name); + iseq_name = RSTRING_PTR(cfp->iseq->location.name); line = rb_vm_get_sourceline(cfp); if (line) { - snprintf(posbuf, MAX_POSBUF, "%s:%d", RSTRING_PTR(cfp->iseq->filename), line); + snprintf(posbuf, MAX_POSBUF, "%s:%d", RSTRING_PTR(cfp->iseq->location.filename), line); } } } @@ -271,7 +271,7 @@ else { argc = iseq->argc; local_size = iseq->local_size; - name = RSTRING_PTR(iseq->name); + name = RSTRING_PTR(iseq->location.name); } /* stack trace header */ Index: vm_insnhelper.c =================================================================== --- vm_insnhelper.c (revision 35755) +++ vm_insnhelper.c (revision 35756) @@ -133,8 +133,8 @@ int line_no = rb_iseq_first_lineno(iseq); err_line = rb_sprintf("%s:%d:in `%s'", - RSTRING_PTR(iseq->filename), - line_no, RSTRING_PTR(iseq->name)); + RSTRING_PTR(iseq->location.filename), + line_no, RSTRING_PTR(iseq->location.name)); rb_funcall(bt, rb_intern("unshift"), 1, err_line); } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/