зеркало из https://github.com/github/ruby.git
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
This commit is contained in:
Родитель
d8eb5ade4f
Коммит
6fd18ca51b
|
@ -1,3 +1,11 @@
|
|||
Wed Dec 30 11:28:57 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* 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@gmail.com>
|
||||
|
||||
* lib/forwardable.rb (def_instance_delegator) fix delegating to
|
||||
|
|
|
@ -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}
|
||||
|
||||
instance_eval(str, __FILE__, line_no)
|
||||
gen = RubyVM::InstructionSequence
|
||||
.compile(str, __FILE__, __FILE__, line_no,
|
||||
trace_instruction: false,
|
||||
tailcall_optimization: true)
|
||||
.eval
|
||||
|
||||
instance_eval(&gen)
|
||||
end
|
||||
|
||||
alias delegate single_delegate
|
||||
|
|
|
@ -187,6 +187,7 @@ class TestForwardable < Test::Unit::TestCase
|
|||
extend Forwardable
|
||||
|
||||
def_delegator :bar, :baz
|
||||
def_delegator :caller, :itself, :c
|
||||
|
||||
class Exception
|
||||
end
|
||||
|
@ -197,6 +198,7 @@ class TestForwardable < Test::Unit::TestCase
|
|||
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
|
||||
|
|
Загрузка…
Ссылка в новой задаче