binding_of_caller 0.7.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. checksums.yaml +5 -5
  2. data/.gemtest +0 -0
  3. data/.github/workflows/test.yml +103 -0
  4. data/.gitignore +13 -7
  5. data/.yardopts +0 -0
  6. data/Gemfile +6 -1
  7. data/HISTORY +35 -0
  8. data/LICENSE +0 -0
  9. data/README.md +19 -7
  10. data/Rakefile +4 -132
  11. data/binding_of_caller.gemspec +33 -35
  12. data/lib/binding_of_caller.rb +9 -10
  13. data/lib/binding_of_caller/jruby_interpreted.rb +123 -0
  14. data/lib/binding_of_caller/{mri2.rb → mri.rb} +9 -15
  15. data/lib/binding_of_caller/rubinius.rb +26 -36
  16. data/lib/binding_of_caller/version.rb +1 -1
  17. metadata +34 -109
  18. data/.travis.yml +0 -22
  19. data/examples/example.rb +0 -41
  20. data/ext/binding_of_caller/binding_of_caller.c +0 -225
  21. data/ext/binding_of_caller/extconf.rb +0 -33
  22. data/ext/binding_of_caller/ruby_headers/192/debug.h +0 -36
  23. data/ext/binding_of_caller/ruby_headers/192/dln.h +0 -41
  24. data/ext/binding_of_caller/ruby_headers/192/eval_intern.h +0 -232
  25. data/ext/binding_of_caller/ruby_headers/192/gc.h +0 -77
  26. data/ext/binding_of_caller/ruby_headers/192/id.h +0 -173
  27. data/ext/binding_of_caller/ruby_headers/192/iseq.h +0 -104
  28. data/ext/binding_of_caller/ruby_headers/192/method.h +0 -103
  29. data/ext/binding_of_caller/ruby_headers/192/node.h +0 -483
  30. data/ext/binding_of_caller/ruby_headers/192/regenc.h +0 -211
  31. data/ext/binding_of_caller/ruby_headers/192/regint.h +0 -841
  32. data/ext/binding_of_caller/ruby_headers/192/regparse.h +0 -354
  33. data/ext/binding_of_caller/ruby_headers/192/thread_pthread.h +0 -27
  34. data/ext/binding_of_caller/ruby_headers/192/thread_win32.h +0 -33
  35. data/ext/binding_of_caller/ruby_headers/192/timev.h +0 -21
  36. data/ext/binding_of_caller/ruby_headers/192/transcode_data.h +0 -109
  37. data/ext/binding_of_caller/ruby_headers/192/version.h +0 -63
  38. data/ext/binding_of_caller/ruby_headers/192/vm_core.h +0 -703
  39. data/ext/binding_of_caller/ruby_headers/192/vm_exec.h +0 -184
  40. data/ext/binding_of_caller/ruby_headers/192/vm_insnhelper.h +0 -208
  41. data/ext/binding_of_caller/ruby_headers/192/vm_opts.h +0 -51
  42. data/ext/binding_of_caller/ruby_headers/193/addr2line.h +0 -21
  43. data/ext/binding_of_caller/ruby_headers/193/atomic.h +0 -56
  44. data/ext/binding_of_caller/ruby_headers/193/constant.h +0 -34
  45. data/ext/binding_of_caller/ruby_headers/193/debug.h +0 -41
  46. data/ext/binding_of_caller/ruby_headers/193/dln.h +0 -50
  47. data/ext/binding_of_caller/ruby_headers/193/encdb.h +0 -167
  48. data/ext/binding_of_caller/ruby_headers/193/eval_intern.h +0 -234
  49. data/ext/binding_of_caller/ruby_headers/193/gc.h +0 -98
  50. data/ext/binding_of_caller/ruby_headers/193/id.h +0 -175
  51. data/ext/binding_of_caller/ruby_headers/193/internal.h +0 -227
  52. data/ext/binding_of_caller/ruby_headers/193/iseq.h +0 -125
  53. data/ext/binding_of_caller/ruby_headers/193/method.h +0 -105
  54. data/ext/binding_of_caller/ruby_headers/193/node.h +0 -503
  55. data/ext/binding_of_caller/ruby_headers/193/parse.h +0 -186
  56. data/ext/binding_of_caller/ruby_headers/193/regenc.h +0 -219
  57. data/ext/binding_of_caller/ruby_headers/193/regint.h +0 -851
  58. data/ext/binding_of_caller/ruby_headers/193/regparse.h +0 -362
  59. data/ext/binding_of_caller/ruby_headers/193/revision.h +0 -1
  60. data/ext/binding_of_caller/ruby_headers/193/thread_pthread.h +0 -51
  61. data/ext/binding_of_caller/ruby_headers/193/thread_win32.h +0 -40
  62. data/ext/binding_of_caller/ruby_headers/193/timev.h +0 -21
  63. data/ext/binding_of_caller/ruby_headers/193/transcode_data.h +0 -117
  64. data/ext/binding_of_caller/ruby_headers/193/transdb.h +0 -189
  65. data/ext/binding_of_caller/ruby_headers/193/version.h +0 -52
  66. data/ext/binding_of_caller/ruby_headers/193/vm_core.h +0 -755
  67. data/ext/binding_of_caller/ruby_headers/193/vm_exec.h +0 -184
  68. data/ext/binding_of_caller/ruby_headers/193/vm_insnhelper.h +0 -220
  69. data/ext/binding_of_caller/ruby_headers/193/vm_opts.h +0 -51
  70. data/test/test_binding_of_caller.rb +0 -149
@@ -1,14 +1,13 @@
1
- dlext = RbConfig::CONFIG['DLEXT']
1
+ require "binding_of_caller/version"
2
2
 
3
- def mri_2?
4
- defined?(RUBY_ENGINE) && RUBY_ENGINE == "ruby" &&
5
- RUBY_VERSION =~ /^2/
6
- end
7
-
8
- if mri_2?
9
- require 'binding_of_caller/mri2'
10
- elsif defined?(RUBY_ENGINE) && RUBY_ENGINE == "ruby"
11
- require "binding_of_caller.#{dlext}"
3
+ if defined?(RUBY_ENGINE) && RUBY_ENGINE == "ruby"
4
+ if RUBY_VERSION =~ /^[23]/
5
+ require 'binding_of_caller/mri'
6
+ else
7
+ puts "This version of binding_of_caller doesn't support this version of Ruby"
8
+ end
12
9
  elsif defined?(Rubinius)
13
10
  require 'binding_of_caller/rubinius'
11
+ elsif defined?(JRuby)
12
+ require 'binding_of_caller/jruby_interpreted'
14
13
  end
@@ -0,0 +1,123 @@
1
+ module BindingOfCaller
2
+ class JRubyBindingHolder
3
+ java_import org.jruby.RubyBinding
4
+
5
+ def initialize(binding)
6
+ @binding = binding
7
+ end
8
+
9
+ def eval(code, file = nil, line = nil)
10
+ b = JRuby.dereference(RubyBinding.new(JRuby.runtime, Binding, @binding))
11
+ if (file == nil)
12
+ Kernel.eval code, b
13
+ else
14
+ Kernel.eval code, b, file, line
15
+ end
16
+ end
17
+
18
+ def frame_type
19
+ case
20
+ when block?
21
+ :block
22
+ when eval?
23
+ :eval
24
+ when top?
25
+ :top
26
+ else
27
+ :method
28
+ end
29
+ end
30
+
31
+ def frame_description
32
+ "#{block_desc}#{method_desc}"
33
+ end
34
+
35
+ private
36
+
37
+ def block?
38
+ @binding.getDynamicScope().getStaticScope().isBlockScope()
39
+ end
40
+
41
+ def eval?
42
+ @binding.getFrame().getKlazz().nil? && @binding.getLine() != 0
43
+ end
44
+
45
+ def top?
46
+ @binding.getFrame().getKlazz().nil? && @binding.getLine() == 0
47
+ end
48
+
49
+ def block_desc
50
+ if frame_type == :block
51
+ "block in "
52
+ end
53
+ end
54
+
55
+ def method_desc
56
+ @binding.getFrame().getName() || "<main>"
57
+ end
58
+ end
59
+
60
+ module BindingExtensions
61
+ def of_caller(index = 1)
62
+ index += 1 # always omit this frame
63
+ JRuby.runtime.current_context.binding_of_caller(index)
64
+ end
65
+
66
+ def callers
67
+ ary = []
68
+ n = 2
69
+ while binding = of_caller(n)
70
+ ary << binding
71
+ n += 1
72
+ end
73
+ ary
74
+ end
75
+
76
+ def frame_count
77
+ callers.count - 1
78
+ end
79
+
80
+ def frame_type
81
+ nil
82
+ end
83
+
84
+ def frame_description
85
+ nil
86
+ end
87
+ end
88
+ end
89
+
90
+
91
+ class org::jruby::runtime::ThreadContext
92
+ java_import org.jruby.runtime.Binding
93
+ java_import org.jruby.RubyInstanceConfig::CompileMode
94
+
95
+ field_accessor :frameStack, :frameIndex,
96
+ :scopeStack, :scopeIndex,
97
+ :backtrace, :backtraceIndex
98
+
99
+ def binding_of_caller(index)
100
+ unless JRuby.runtime.instance_config.compile_mode == CompileMode::OFF
101
+ raise RuntimeError, "caller binding only supported in interpreter"
102
+ end
103
+
104
+ index += 1 # always omit this frame
105
+
106
+ return nil if index > frameIndex
107
+
108
+ frame = frameStack[frameIndex - index]
109
+
110
+ return binding_of_caller(index - 1) if index > scopeIndex
111
+
112
+ scope = scopeStack[scopeIndex - index]
113
+ element = backtrace[backtraceIndex - index]
114
+
115
+ binding = Binding.new(frame, scope.static_scope.module, scope, element.clone)
116
+
117
+ BindingOfCaller::JRubyBindingHolder.new(binding)
118
+ end
119
+ end
120
+
121
+ class ::Binding
122
+ include BindingOfCaller::BindingExtensions
123
+ end
@@ -17,25 +17,19 @@ module BindingOfCaller
17
17
  # @return [Array<Binding>]
18
18
  def callers
19
19
  ary = []
20
-
21
- RubyVM::DebugInspector.open do |i|
22
- n = 0
23
- loop do
24
- begin
25
- b = i.frame_binding(n)
26
20
 
27
- if b
28
- iseq = i.frame_iseq(n)
29
- b.instance_variable_set(:@iseq, iseq)
30
- ary << b
31
- end
32
- rescue ArgumentError
33
- break
21
+ RubyVM::DebugInspector.open do |dc|
22
+ locs = dc.backtrace_locations
23
+
24
+ locs.size.times do |i|
25
+ b = dc.frame_binding(i)
26
+ if b
27
+ b.instance_variable_set(:@iseq, dc.frame_iseq(i))
28
+ ary << b
34
29
  end
35
- n += 1
36
30
  end
37
31
  end
38
-
32
+
39
33
  ary.drop(1)
40
34
  end
41
35
 
@@ -4,21 +4,11 @@ module BindingOfCaller
4
4
  # Retrieve the binding of the nth caller of the current frame.
5
5
  # @return [Binding]
6
6
  def of_caller(n)
7
- bt = Rubinius::VM.backtrace(1 + n, true).first
7
+ location = Rubinius::VM.backtrace(1 + n, true).first
8
8
 
9
- b = Binding.setup(
10
- bt.variables,
11
- bt.variables.method,
12
- bt.static_scope,
13
- bt.variables.self,
14
- bt
15
- )
9
+ raise RuntimeError, "Invalid frame, gone beyond end of stack!" if location.nil?
16
10
 
17
- b.instance_variable_set(:@frame_description, bt.describe)
18
-
19
- b
20
- rescue
21
- raise RuntimeError, "Invalid frame, gone beyond end of stack!"
11
+ setup_binding_from_location(location)
22
12
  end
23
13
 
24
14
  # The description of the frame.
@@ -30,44 +20,44 @@ module BindingOfCaller
30
20
  # Return bindings for all caller frames.
31
21
  # @return [Array<Binding>]
32
22
  def callers
33
- ary = []
34
- n = 0
35
- loop do
36
- begin
37
- ary << Binding.of_caller(n)
38
- rescue
39
- break
40
- end
41
- n += 1
42
- end
43
- ary.drop_while do |v|
44
- !(v.frame_type == :method && v.eval("__method__") == :callers)
45
- end.drop(1)
23
+ Rubinius::VM.backtrace(1, true).map &(method(:setup_binding_from_location).
24
+ to_proc)
46
25
  end
47
26
 
48
27
  # Number of parent frames available at the point of call.
49
28
  # @return [Fixnum]
50
29
  def frame_count
51
- callers.size - 1
30
+ Rubinius::VM.backtrace(1).count
52
31
  end
53
32
 
54
33
  # The type of the frame.
55
34
  # @return [Symbol]
56
35
  def frame_type
57
- case self.variables.method.metadata.to_a.first.to_s
58
- when /block/
59
- :block
60
- when /eval/
36
+ if compiled_code.for_module_body?
37
+ :class
38
+ elsif compiled_code.for_eval?
61
39
  :eval
40
+ elsif compiled_code.is_block?
41
+ :block
62
42
  else
63
- if frame_description =~ /__(?:class|module)_init__/
64
- :class
65
- else
66
- :method
67
- end
43
+ :method
68
44
  end
69
45
  end
70
46
 
47
+ protected
48
+
49
+ def setup_binding_from_location(location)
50
+ binding = Binding.setup location.variables,
51
+ location.variables.method,
52
+ location.constant_scope,
53
+ location.variables.self,
54
+ location
55
+
56
+ binding.instance_variable_set :@frame_description,
57
+ location.describe.gsub("{ } in", "block in")
58
+
59
+ binding
60
+ end
71
61
  end
72
62
  end
73
63
 
@@ -1,3 +1,3 @@
1
1
  module BindingOfCaller
2
- VERSION = "0.7.1"
2
+ VERSION = "1.0.0"
3
3
  end
metadata CHANGED
@@ -1,154 +1,79 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: binding_of_caller
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Mair (banisterfiend)
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-02-16 00:00:00.000000000 Z
11
+ date: 2020-12-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: debug_inspector
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '>='
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 0.0.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '>='
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.0.1
27
- - !ruby/object:Gem::Dependency
28
- name: bacon
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - '>='
32
- - !ruby/object:Gem::Version
33
- version: '0'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - '>='
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: rake
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - '>='
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - '>='
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- description: Retrieve the binding of a method's caller. Can also retrieve bindings
56
- even further up the stack.
57
- email: jrmair@gmail.com
27
+ description: |
28
+ Provides the Binding#of_caller method.
29
+
30
+ Using binding_of_caller we can grab bindings from higher up the call stack and evaluate code in that context.
31
+ Allows access to bindings arbitrarily far up the call stack, not limited to just the immediate caller.
32
+
33
+ Recommended for use only in debugging situations. Do not use this in production apps.
34
+ email:
35
+ - jrmair@gmail.com
58
36
  executables: []
59
- extensions:
60
- - ext/binding_of_caller/extconf.rb
37
+ extensions: []
61
38
  extra_rdoc_files: []
62
39
  files:
63
- - .gemtest
64
- - .gitignore
65
- - .travis.yml
66
- - .yardopts
40
+ - ".gemtest"
41
+ - ".github/workflows/test.yml"
42
+ - ".gitignore"
43
+ - ".yardopts"
67
44
  - Gemfile
68
45
  - HISTORY
69
46
  - LICENSE
70
47
  - README.md
71
48
  - Rakefile
72
49
  - binding_of_caller.gemspec
73
- - examples/example.rb
74
- - ext/binding_of_caller/binding_of_caller.c
75
- - ext/binding_of_caller/extconf.rb
76
- - ext/binding_of_caller/ruby_headers/192/debug.h
77
- - ext/binding_of_caller/ruby_headers/192/dln.h
78
- - ext/binding_of_caller/ruby_headers/192/eval_intern.h
79
- - ext/binding_of_caller/ruby_headers/192/gc.h
80
- - ext/binding_of_caller/ruby_headers/192/id.h
81
- - ext/binding_of_caller/ruby_headers/192/iseq.h
82
- - ext/binding_of_caller/ruby_headers/192/method.h
83
- - ext/binding_of_caller/ruby_headers/192/node.h
84
- - ext/binding_of_caller/ruby_headers/192/regenc.h
85
- - ext/binding_of_caller/ruby_headers/192/regint.h
86
- - ext/binding_of_caller/ruby_headers/192/regparse.h
87
- - ext/binding_of_caller/ruby_headers/192/thread_pthread.h
88
- - ext/binding_of_caller/ruby_headers/192/thread_win32.h
89
- - ext/binding_of_caller/ruby_headers/192/timev.h
90
- - ext/binding_of_caller/ruby_headers/192/transcode_data.h
91
- - ext/binding_of_caller/ruby_headers/192/version.h
92
- - ext/binding_of_caller/ruby_headers/192/vm_core.h
93
- - ext/binding_of_caller/ruby_headers/192/vm_exec.h
94
- - ext/binding_of_caller/ruby_headers/192/vm_insnhelper.h
95
- - ext/binding_of_caller/ruby_headers/192/vm_opts.h
96
- - ext/binding_of_caller/ruby_headers/193/addr2line.h
97
- - ext/binding_of_caller/ruby_headers/193/atomic.h
98
- - ext/binding_of_caller/ruby_headers/193/constant.h
99
- - ext/binding_of_caller/ruby_headers/193/debug.h
100
- - ext/binding_of_caller/ruby_headers/193/dln.h
101
- - ext/binding_of_caller/ruby_headers/193/encdb.h
102
- - ext/binding_of_caller/ruby_headers/193/eval_intern.h
103
- - ext/binding_of_caller/ruby_headers/193/gc.h
104
- - ext/binding_of_caller/ruby_headers/193/id.h
105
- - ext/binding_of_caller/ruby_headers/193/internal.h
106
- - ext/binding_of_caller/ruby_headers/193/iseq.h
107
- - ext/binding_of_caller/ruby_headers/193/method.h
108
- - ext/binding_of_caller/ruby_headers/193/node.h
109
- - ext/binding_of_caller/ruby_headers/193/parse.h
110
- - ext/binding_of_caller/ruby_headers/193/regenc.h
111
- - ext/binding_of_caller/ruby_headers/193/regint.h
112
- - ext/binding_of_caller/ruby_headers/193/regparse.h
113
- - ext/binding_of_caller/ruby_headers/193/revision.h
114
- - ext/binding_of_caller/ruby_headers/193/thread_pthread.h
115
- - ext/binding_of_caller/ruby_headers/193/thread_win32.h
116
- - ext/binding_of_caller/ruby_headers/193/timev.h
117
- - ext/binding_of_caller/ruby_headers/193/transcode_data.h
118
- - ext/binding_of_caller/ruby_headers/193/transdb.h
119
- - ext/binding_of_caller/ruby_headers/193/version.h
120
- - ext/binding_of_caller/ruby_headers/193/vm_core.h
121
- - ext/binding_of_caller/ruby_headers/193/vm_exec.h
122
- - ext/binding_of_caller/ruby_headers/193/vm_insnhelper.h
123
- - ext/binding_of_caller/ruby_headers/193/vm_opts.h
124
50
  - lib/binding_of_caller.rb
125
- - lib/binding_of_caller/mri2.rb
51
+ - lib/binding_of_caller/jruby_interpreted.rb
52
+ - lib/binding_of_caller/mri.rb
126
53
  - lib/binding_of_caller/rubinius.rb
127
54
  - lib/binding_of_caller/version.rb
128
- - test/test_binding_of_caller.rb
129
- homepage: http://github.com/banister/binding_of_caller
130
- licenses: []
131
- metadata: {}
132
- post_install_message:
55
+ homepage: https://github.com/banister/binding_of_caller
56
+ licenses:
57
+ - MIT
58
+ metadata:
59
+ changelog_uri: https://github.com/banister/binding_of_caller/releases
60
+ post_install_message:
133
61
  rdoc_options: []
134
62
  require_paths:
135
63
  - lib
136
64
  required_ruby_version: !ruby/object:Gem::Requirement
137
65
  requirements:
138
- - - '>='
66
+ - - ">="
139
67
  - !ruby/object:Gem::Version
140
- version: '0'
68
+ version: 2.0.0
141
69
  required_rubygems_version: !ruby/object:Gem::Requirement
142
70
  requirements:
143
- - - '>='
71
+ - - ">="
144
72
  - !ruby/object:Gem::Version
145
73
  version: '0'
146
74
  requirements: []
147
- rubyforge_project:
148
- rubygems_version: 2.0.0.rc.2
149
- signing_key:
75
+ rubygems_version: 3.1.4
76
+ signing_key:
150
77
  specification_version: 4
151
- summary: Retrieve the binding of a method's caller. Can also retrieve bindings even
152
- further up the stack.
153
- test_files:
154
- - test/test_binding_of_caller.rb
78
+ summary: Retrieve the binding of a method's caller, or further up the stack.
79
+ test_files: []