[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]