ruby-changes:26028
From: ko1 <ko1@a...>
Date: Sat, 1 Dec 2012 03:02:52 +0900 (JST)
Subject: [ruby-changes:26028] ko1:r38085 (trunk): * iseq.c: add RubyVM::InstructionSequence (ISeq) inspection methods.
ko1 2012-12-01 03:02:43 +0900 (Sat, 01 Dec 2012) New Revision: 38085 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=38085 Log: * iseq.c: add RubyVM::InstructionSequence (ISeq) inspection methods. * ISeq#path returns path of this ISeq written. * ISeq#absolute_path returns absolute path. * ISeq#label returns label (method name and so on). * ISeq#base_label returns base label (see Thread::Backtrace::Location). * ISeq#first_lineno returns first line number of this ISeq. * ISeq.of(obj) returns ISeq object which obj (Proc or Method) is contains. * test/ruby/test_iseq.rb: add tests. Modified files: trunk/ChangeLog trunk/iseq.c trunk/test/ruby/test_iseq.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 38084) +++ ChangeLog (revision 38085) @@ -1,3 +1,16 @@ +Sat Dec 1 02:56:19 2012 Koichi Sasada <ko1@a...> + + * iseq.c: add RubyVM::InstructionSequence (ISeq) inspection methods. + * ISeq#path returns path of this ISeq written. + * ISeq#absolute_path returns absolute path. + * ISeq#label returns label (method name and so on). + * ISeq#base_label returns base label (see Thread::Backtrace::Location). + * ISeq#first_lineno returns first line number of this ISeq. + * ISeq.of(obj) returns ISeq object which obj (Proc or Method) + is contains. + + * test/ruby/test_iseq.rb: add tests. + Sat Dec 1 02:58:51 2012 Eric Hodel <drbrain@s...> * include/ruby/ruby.h (rb_event_flag_t): Maintain integer precision Index: iseq.c =================================================================== --- iseq.c (revision 38084) +++ iseq.c (revision 38085) @@ -799,6 +799,46 @@ RSTRING_PTR(iseq->location.label), RSTRING_PTR(iseq->location.path)); } +static VALUE +iseq_path(VALUE self) +{ + rb_iseq_t *iseq; + GetISeqPtr(self, iseq); + return iseq->location.path; +} + +static VALUE +iseq_absolute_path(VALUE self) +{ + rb_iseq_t *iseq; + GetISeqPtr(self, iseq); + return iseq->location.absolute_path; +} + +static VALUE +iseq_label(VALUE self) +{ + rb_iseq_t *iseq; + GetISeqPtr(self, iseq); + return iseq->location.label; +} + +static VALUE +iseq_base_label(VALUE self) +{ + rb_iseq_t *iseq; + GetISeqPtr(self, iseq); + return iseq->location.base_label; +} + +static VALUE +iseq_first_lineno(VALUE self) +{ + rb_iseq_t *iseq; + GetISeqPtr(self, iseq); + return iseq->location.first_lineno; +} + static VALUE iseq_data_to_ary(rb_iseq_t *iseq); @@ -1290,6 +1330,28 @@ return str; } +static VALUE +iseq_s_of(VALUE klass, VALUE body) +{ + VALUE ret = Qnil; + rb_iseq_t *iseq; + + rb_secure(1); + + if (rb_obj_is_proc(body)) { + rb_proc_t *proc; + GetProcPtr(body, proc); + iseq = proc->block.iseq; + if (RUBY_VM_NORMAL_ISEQ_P(iseq)) { + ret = iseq->self; + } + } + else if ((iseq = rb_method_get_iseq(body)) != 0) { + ret = iseq->self; + } + return ret; +} + /* * call-seq: * InstructionSequence.disasm(body) -> str @@ -1342,27 +1404,12 @@ * 0012 leave * */ + static VALUE iseq_s_disasm(VALUE klass, VALUE body) { - VALUE ret = Qnil; - rb_iseq_t *iseq; - - rb_secure(1); - - if (rb_obj_is_proc(body)) { - rb_proc_t *proc; - GetProcPtr(body, proc); - iseq = proc->block.iseq; - if (RUBY_VM_NORMAL_ISEQ_P(iseq)) { - ret = rb_iseq_disasm(iseq->self); - } - } - else if ((iseq = rb_method_get_iseq(body)) != 0) { - ret = rb_iseq_disasm(iseq->self); - } - - return ret; + VALUE iseqval = iseq_s_of(klass, body); + return NIL_P(iseqval) ? Qnil : rb_iseq_disasm(iseqval); } const char * @@ -2019,6 +2066,13 @@ rb_define_method(rb_cISeq, "to_a", iseq_to_a, 0); rb_define_method(rb_cISeq, "eval", iseq_eval, 0); + /* location APIs */ + rb_define_method(rb_cISeq, "path", iseq_path, 0); + rb_define_method(rb_cISeq, "absolute_path", iseq_absolute_path, 0); + rb_define_method(rb_cISeq, "label", iseq_label, 0); + rb_define_method(rb_cISeq, "base_label", iseq_base_label, 0); + rb_define_method(rb_cISeq, "first_lineno", iseq_first_lineno, 0); + /* experimental */ rb_define_method(rb_cISeq, "line_trace_all", rb_iseq_line_trace_all, 0); rb_define_method(rb_cISeq, "line_trace_specify", rb_iseq_line_trace_specify, 2); @@ -2039,4 +2093,5 @@ rb_define_singleton_method(rb_cISeq, "compile_option=", iseq_s_compile_option_set, 1); rb_define_singleton_method(rb_cISeq, "disasm", iseq_s_disasm, 1); rb_define_singleton_method(rb_cISeq, "disassemble", iseq_s_disasm, 1); + rb_define_singleton_method(rb_cISeq, "of", iseq_s_of, 1); } Index: test/ruby/test_iseq.rb =================================================================== --- test/ruby/test_iseq.rb (revision 38084) +++ test/ruby/test_iseq.rb (revision 38085) @@ -49,4 +49,23 @@ } assert_equal([2, 5], result) end + + LINE_OF_HERE = __LINE__ + def test_location + iseq = ISeq.of(method(:test_location)) + + assert_equal(__FILE__, iseq.path) + assert(/#{__FILE__}/ =~ iseq.absolute_path) + assert_equal("test_location", iseq.label) + assert_equal("test_location", iseq.base_label) + assert_equal(LINE_OF_HERE+1, iseq.first_lineno) + + line = __LINE__ + iseq = ISeq.of(Proc.new{}) + assert_equal(__FILE__, iseq.path) + assert(/#{__FILE__}/ =~ iseq.absolute_path) + assert_equal("test_location", iseq.base_label) + assert_equal("block in test_location", iseq.label) + assert_equal(line+1, iseq.first_lineno) + end end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/