aboutsummaryrefslogtreecommitdiffstats
path: root/lib/forwardable.rb
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-12-30 02:28:59 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-12-30 02:28:59 +0000
commit2e26fa48ffade18988e63eb9e0c9f9e2d7474576 (patch)
treeadd72ea5a4f487a58f983d11633b879d0f43b100 /lib/forwardable.rb
parent6ffebd1ab72c38497a48a9c87f1c1c9a388b7394 (diff)
downloadruby-2e26fa48ffade18988e63eb9e0c9f9e2d7474576.tar.gz
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. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53383 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib/forwardable.rb')
-rw-r--r--lib/forwardable.rb46
1 files changed, 28 insertions, 18 deletions
diff --git a/lib/forwardable.rb b/lib/forwardable.rb
index f27437af82..390e1460cf 100644
--- a/lib/forwardable.rb
+++ b/lib/forwardable.rb
@@ -182,23 +182,28 @@ module Forwardable
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
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