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

ruby-changes:41311

From: nobu <ko1@a...>
Date: Wed, 30 Dec 2015 11:29:03 +0900 (JST)
Subject: [ruby-changes:41311] nobu:r53383 (trunk): forwardable.rb: adjust backtrace by tail call

nobu	2015-12-30 11:28:59 +0900 (Wed, 30 Dec 2015)

  New Revision: 53383

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=53383

  Log:
    forwardable.rb: adjust backtrace by tail call
    
    * lib/forwardable.rb (def_instance_delegator): adjust backtrace of
      method body by tail call optimization.  adjusting the delegated
      target is still done by deleting backtrace.
    * lib/forwardable.rb (def_single_delegator): ditto.

  Modified files:
    trunk/ChangeLog
    trunk/lib/forwardable.rb
    trunk/test/test_forwardable.rb
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 53382)
+++ ChangeLog	(revision 53383)
@@ -1,3 +1,11 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Wed Dec 30 11:28:57 2015  Nobuyoshi Nakada  <nobu@r...>
+
+	* lib/forwardable.rb (def_instance_delegator): adjust backtrace of
+	  method body by tail call optimization.  adjusting the delegated
+	  target is still done by deleting backtrace.
+
+	* lib/forwardable.rb (def_single_delegator): ditto.
+
 Wed Dec 30 11:18:42 2015  Elliot Winkler  <elliot.winkler@g...>
 
 	* lib/forwardable.rb (def_instance_delegator) fix delegating to
Index: lib/forwardable.rb
===================================================================
--- lib/forwardable.rb	(revision 53382)
+++ lib/forwardable.rb	(revision 53383)
@@ -182,23 +182,28 @@ module Forwardable https://github.com/ruby/ruby/blob/trunk/lib/forwardable.rb#L182
       accessor = "#{accessor}()"
     end
 
-    line_no = __LINE__; str = %{
+    line_no = __LINE__; str = %{proc do
       def #{ali}(*args, &block)
         begin
-          #{accessor}.__send__(:#{method}, *args, &block)
-        rescue ::Exception
-          $@.delete_if{|s| ::Forwardable::FILE_REGEXP =~ s} unless ::Forwardable::debug
-          ::Kernel::raise
-        end
+          #{accessor}
+        ensure
+          $@.delete_if {|s| ::Forwardable::FILE_REGEXP =~ s} if $@ and !::Forwardable::debug
+        end.__send__(:#{method}, *args, &block)
       end
-    }
+    end}
+
+    gen = RubyVM::InstructionSequence
+          .compile(str, __FILE__, __FILE__, line_no,
+                   trace_instruction: false,
+                   tailcall_optimization: true)
+          .eval
+
     # If it's not a class or module, it's an instance
     begin
-      module_eval(str, __FILE__, line_no)
+      module_eval(&gen)
     rescue
-      instance_eval(str, __FILE__, line_no)
+      instance_eval(&gen)
     end
-
   end
 
   alias delegate instance_delegate
@@ -278,18 +283,23 @@ module SingleForwardable https://github.com/ruby/ruby/blob/trunk/lib/forwardable.rb#L283
       accessor = "#{accessor}()"
     end
 
-    line_no = __LINE__; str = %{
+    line_no = __LINE__; str = %{proc do
       def #{ali}(*args, &block)
         begin
-          #{accessor}.__send__(:#{method}, *args, &block)
-        rescue ::Exception
-          $@.delete_if{|s| ::Forwardable::FILE_REGEXP =~ s} unless ::Forwardable::debug
-          ::Kernel::raise
-        end
+          #{accessor}
+        ensure
+          $@.delete_if {|s| ::Forwardable::FILE_REGEXP =~ s} if $@ and !::Forwardable::debug
+        end.__send__(:#{method}, *args, &block)
       end
-    }
+    end}
+
+    gen = RubyVM::InstructionSequence
+          .compile(str, __FILE__, __FILE__, line_no,
+                   trace_instruction: false,
+                   tailcall_optimization: true)
+          .eval
 
-    instance_eval(str, __FILE__, line_no)
+    instance_eval(&gen)
   end
 
   alias delegate single_delegate
Index: test/test_forwardable.rb
===================================================================
--- test/test_forwardable.rb	(revision 53382)
+++ test/test_forwardable.rb	(revision 53383)
@@ -187,6 +187,7 @@ class TestForwardable < Test::Unit::Test https://github.com/ruby/ruby/blob/trunk/test/test_forwardable.rb#L187
     extend Forwardable
 
     def_delegator :bar, :baz
+    def_delegator :caller, :itself, :c
 
     class Exception
     end
@@ -197,6 +198,7 @@ class TestForwardable < Test::Unit::Test https://github.com/ruby/ruby/blob/trunk/test/test_forwardable.rb#L198
       Foo.new.baz
     }
     assert_not_match(/\/forwardable\.rb/, e.backtrace[0])
+    assert_equal(caller(0, 1)[0], Foo.new.c[0])
   end
 
   class Foo2 < BasicObject

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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