binding_of_caller 0.7.2 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gemtest +0 -0
- data/.github/workflows/test.yml +108 -0
- data/.gitignore +12 -7
- data/.yardopts +0 -0
- data/Gemfile +6 -1
- data/LICENSE +0 -0
- data/README.md +17 -5
- data/Rakefile +4 -132
- data/binding_of_caller.gemspec +33 -35
- data/lib/binding_of_caller/jruby_interpreted.rb +123 -0
- data/lib/binding_of_caller/{mri2.rb → mri.rb} +8 -14
- data/lib/binding_of_caller/rubinius.rb +21 -28
- data/lib/binding_of_caller/version.rb +1 -1
- data/lib/binding_of_caller.rb +9 -10
- metadata +33 -109
- data/.travis.yml +0 -23
- data/HISTORY +0 -0
- data/examples/example.rb +0 -41
- data/ext/binding_of_caller/binding_of_caller.c +0 -225
- data/ext/binding_of_caller/extconf.rb +0 -33
- data/ext/binding_of_caller/ruby_headers/192/debug.h +0 -36
- data/ext/binding_of_caller/ruby_headers/192/dln.h +0 -41
- data/ext/binding_of_caller/ruby_headers/192/eval_intern.h +0 -232
- data/ext/binding_of_caller/ruby_headers/192/id.h +0 -173
- data/ext/binding_of_caller/ruby_headers/192/iseq.h +0 -104
- data/ext/binding_of_caller/ruby_headers/192/method.h +0 -103
- data/ext/binding_of_caller/ruby_headers/192/node.h +0 -483
- data/ext/binding_of_caller/ruby_headers/192/regenc.h +0 -211
- data/ext/binding_of_caller/ruby_headers/192/regint.h +0 -841
- data/ext/binding_of_caller/ruby_headers/192/regparse.h +0 -354
- data/ext/binding_of_caller/ruby_headers/192/rubys_gc.h +0 -77
- data/ext/binding_of_caller/ruby_headers/192/thread_pthread.h +0 -27
- data/ext/binding_of_caller/ruby_headers/192/thread_win32.h +0 -33
- data/ext/binding_of_caller/ruby_headers/192/timev.h +0 -21
- data/ext/binding_of_caller/ruby_headers/192/transcode_data.h +0 -109
- data/ext/binding_of_caller/ruby_headers/192/version.h +0 -55
- data/ext/binding_of_caller/ruby_headers/192/vm_core.h +0 -703
- data/ext/binding_of_caller/ruby_headers/192/vm_exec.h +0 -184
- data/ext/binding_of_caller/ruby_headers/192/vm_insnhelper.h +0 -208
- data/ext/binding_of_caller/ruby_headers/192/vm_opts.h +0 -51
- data/ext/binding_of_caller/ruby_headers/193/addr2line.h +0 -21
- data/ext/binding_of_caller/ruby_headers/193/atomic.h +0 -56
- data/ext/binding_of_caller/ruby_headers/193/constant.h +0 -34
- data/ext/binding_of_caller/ruby_headers/193/debug.h +0 -41
- data/ext/binding_of_caller/ruby_headers/193/dln.h +0 -50
- data/ext/binding_of_caller/ruby_headers/193/encdb.h +0 -167
- data/ext/binding_of_caller/ruby_headers/193/eval_intern.h +0 -234
- data/ext/binding_of_caller/ruby_headers/193/id.h +0 -175
- data/ext/binding_of_caller/ruby_headers/193/internal.h +0 -227
- data/ext/binding_of_caller/ruby_headers/193/iseq.h +0 -125
- data/ext/binding_of_caller/ruby_headers/193/method.h +0 -105
- data/ext/binding_of_caller/ruby_headers/193/node.h +0 -503
- data/ext/binding_of_caller/ruby_headers/193/parse.h +0 -186
- data/ext/binding_of_caller/ruby_headers/193/regenc.h +0 -219
- data/ext/binding_of_caller/ruby_headers/193/regint.h +0 -851
- data/ext/binding_of_caller/ruby_headers/193/regparse.h +0 -362
- data/ext/binding_of_caller/ruby_headers/193/revision.h +0 -1
- data/ext/binding_of_caller/ruby_headers/193/rubys_gc.h +0 -98
- data/ext/binding_of_caller/ruby_headers/193/thread_pthread.h +0 -51
- data/ext/binding_of_caller/ruby_headers/193/thread_win32.h +0 -40
- data/ext/binding_of_caller/ruby_headers/193/timev.h +0 -21
- data/ext/binding_of_caller/ruby_headers/193/transcode_data.h +0 -117
- data/ext/binding_of_caller/ruby_headers/193/transdb.h +0 -189
- data/ext/binding_of_caller/ruby_headers/193/version.h +0 -52
- data/ext/binding_of_caller/ruby_headers/193/vm_core.h +0 -755
- data/ext/binding_of_caller/ruby_headers/193/vm_exec.h +0 -184
- data/ext/binding_of_caller/ruby_headers/193/vm_insnhelper.h +0 -220
- data/ext/binding_of_caller/ruby_headers/193/vm_opts.h +0 -51
- data/test/test_binding_of_caller.rb +0 -161
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 0254f3b28703e0ce22f22a5835efdc9ac7f8d7756eb018c9700174d2dab1bf00
|
4
|
+
data.tar.gz: e87d62228e3eca329d9315c15f329a1d163be3ff7aee49702ddc604b4fe85e52
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 91989097e5c3d8420c2fc4cb8071a262879325cbe59d16f6bbb35cb86b0f2be42ab1d27b515c0497a4deea863d0f0f60b6e8dce446ce2c4bb777f7699e87d8e1
|
7
|
+
data.tar.gz: 13a9eb1a35130ba007dc12517cdac063e623faeef11d7533d57c6762fe25664ad224711d3902d10fe1c081c089c91314fd8c661720b15c6bcc02e3c873caba6e
|
data/.gemtest
CHANGED
File without changes
|
@@ -0,0 +1,108 @@
|
|
1
|
+
name: Test
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ master ]
|
6
|
+
schedule:
|
7
|
+
- cron: '0 0 11,25 * *' # roughly every two weeks to run on new Ruby versions
|
8
|
+
pull_request:
|
9
|
+
branches: [ master ]
|
10
|
+
workflow_dispatch:
|
11
|
+
|
12
|
+
jobs:
|
13
|
+
test:
|
14
|
+
name: "Unit"
|
15
|
+
runs-on: ubuntu-latest
|
16
|
+
strategy:
|
17
|
+
fail-fast: false
|
18
|
+
matrix:
|
19
|
+
ruby:
|
20
|
+
- "2.1"
|
21
|
+
- "2.2"
|
22
|
+
- "2.3"
|
23
|
+
- "2.4"
|
24
|
+
- "2.5"
|
25
|
+
- "2.6"
|
26
|
+
- "2.7"
|
27
|
+
- "3.0"
|
28
|
+
- "3.1"
|
29
|
+
- "3.2"
|
30
|
+
exclude:
|
31
|
+
# 2.2 segfaults on recent Ubuntu: https://github.com/ruby/setup-ruby/issues/496
|
32
|
+
- { ruby: "2.2" }
|
33
|
+
|
34
|
+
steps:
|
35
|
+
|
36
|
+
- uses: actions/checkout@v2
|
37
|
+
|
38
|
+
- name: Set up Ruby
|
39
|
+
uses: ruby/setup-ruby@v1
|
40
|
+
with:
|
41
|
+
ruby-version: ${{ matrix.ruby }}
|
42
|
+
bundler-cache: true
|
43
|
+
|
44
|
+
- name: Test
|
45
|
+
run: bundle exec rspec -f doc
|
46
|
+
|
47
|
+
system:
|
48
|
+
name: "System"
|
49
|
+
runs-on: ${{ matrix.os }}
|
50
|
+
strategy:
|
51
|
+
fail-fast: false
|
52
|
+
matrix:
|
53
|
+
os:
|
54
|
+
- macos-latest
|
55
|
+
- ubuntu-latest
|
56
|
+
- windows-latest
|
57
|
+
ruby:
|
58
|
+
- "2"
|
59
|
+
- "3.0"
|
60
|
+
- "jruby"
|
61
|
+
- "truffleruby"
|
62
|
+
exclude:
|
63
|
+
# Windows releases of jruby and truffleruby have issues. Skip them for now.
|
64
|
+
- { ruby: "jruby", os: "windows-latest" }
|
65
|
+
- { ruby: "truffleruby", os: "windows-latest" }
|
66
|
+
|
67
|
+
steps:
|
68
|
+
|
69
|
+
- uses: actions/checkout@v2
|
70
|
+
|
71
|
+
- name: Determine ruby version name
|
72
|
+
id: ruby_version
|
73
|
+
run: |
|
74
|
+
if [[ $OS == 'windows-latest' && $RUBY == '3.0' ]]; then
|
75
|
+
# Windows doesn't have 3.0, so run head there but nowhere else.
|
76
|
+
echo "::set-output name=release::head"
|
77
|
+
else
|
78
|
+
echo "::set-output name=release::$RUBY"
|
79
|
+
fi
|
80
|
+
shell: bash
|
81
|
+
env:
|
82
|
+
OS: ${{ matrix.os }}
|
83
|
+
RUBY: ${{ matrix.ruby }}
|
84
|
+
|
85
|
+
- name: Set up Ruby
|
86
|
+
uses: ruby/setup-ruby@v1
|
87
|
+
with:
|
88
|
+
ruby-version: ${{ steps.ruby_version.outputs.release }}
|
89
|
+
bundler-cache: true
|
90
|
+
|
91
|
+
- name: Install gem
|
92
|
+
run: bundle exec rake install
|
93
|
+
|
94
|
+
- name: Create directory for gem test
|
95
|
+
run: mkdir -p tmp/gem-test
|
96
|
+
|
97
|
+
- name: Create test Gemfile
|
98
|
+
run: echo "gem 'binding_of_caller'" > Gemfile
|
99
|
+
working-directory: ./tmp/gem-test
|
100
|
+
|
101
|
+
- name: Test gem load
|
102
|
+
run: bundle exec ruby -e "require 'binding_of_caller'"
|
103
|
+
|
104
|
+
- name: Test gem functionality
|
105
|
+
if: ${{ matrix.ruby != 'jruby' && matrix.ruby != 'truffleruby' }}
|
106
|
+
run: bundle exec ruby -e "require 'binding_of_caller'; binding.of_caller(0).eval('var = :hello')"
|
107
|
+
env:
|
108
|
+
JRUBY_OPTS: "--dev" # This will support JRuby once the gem is updated to support JRuby 9.x
|
data/.gitignore
CHANGED
data/.yardopts
CHANGED
File without changes
|
data/Gemfile
CHANGED
data/LICENSE
CHANGED
File without changes
|
data/README.md
CHANGED
@@ -1,11 +1,12 @@
|
|
1
|
-
[![Build Status](https://
|
1
|
+
[![Build Status](https://github.com/banister/binding_of_caller/workflows/Test/badge.svg?branch=master&event=push)](https://github.com/banister/binding_of_caller/actions?query=branch%3Amaster)
|
2
|
+
[![Gem Version](https://img.shields.io/gem/v/binding_of_caller.svg)](https://rubygems.org/gems/binding_of_caller)
|
2
3
|
|
3
4
|
binding_of_caller
|
4
|
-
|
5
|
+
=================
|
5
6
|
|
6
7
|
(C) John Mair (banisterfiend) 2012
|
7
8
|
|
8
|
-
_Retrieve the binding of a method's caller in MRI
|
9
|
+
_Retrieve the binding of a method's caller in MRI (>= 2.0.0) and RBX (Rubinius)_
|
9
10
|
|
10
11
|
The `binding_of_caller` gem provides the `Binding#of_caller` method.
|
11
12
|
|
@@ -15,7 +16,7 @@ call stack, not limited to just the immediate caller.
|
|
15
16
|
|
16
17
|
**Recommended for use only in debugging situations. Do not use this in production apps.**
|
17
18
|
|
18
|
-
**
|
19
|
+
**Works in MRI Ruby (>= 2.0) and RBX (Rubinius)**
|
19
20
|
|
20
21
|
* Install the [gem](https://rubygems.org/gems/binding_of_caller): `gem install binding_of_caller`
|
21
22
|
* See the [source code](http://github.com/banister/binding_of_caller)
|
@@ -52,8 +53,19 @@ This project is a spinoff from the [Pry REPL project.](http://pry.github.com)
|
|
52
53
|
Features and limitations
|
53
54
|
-------------------------
|
54
55
|
|
55
|
-
*
|
56
|
+
* Works in MRI (>= 2.0.0) and RBX (Rubinius)
|
57
|
+
* For MRI 1.9.x, use version "~> 0.8" of the gem, which included support for MRI before 2.0.
|
56
58
|
* Does not work in 1.8.7, but there is a well known (continuation-based) hack to get a `Binding#of_caller` there.
|
59
|
+
* There is experimental support for jruby 1.7.x, but it only works in interpreted
|
60
|
+
mode (i.e. use the option `-Djruby.compile.mode=OFF` or append
|
61
|
+
`compile.mode=OFF` to your `.jrubyrc`)
|
62
|
+
|
63
|
+
Development
|
64
|
+
-----------
|
65
|
+
|
66
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
67
|
+
|
68
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
57
69
|
|
58
70
|
Contact
|
59
71
|
-------
|
data/Rakefile
CHANGED
@@ -1,134 +1,6 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rspec/core/rake_task"
|
3
3
|
|
4
|
-
|
4
|
+
RSpec::Core::RakeTask.new(:spec)
|
5
5
|
|
6
|
-
|
7
|
-
require 'rubygems/package_task'
|
8
|
-
|
9
|
-
require "binding_of_caller/version"
|
10
|
-
|
11
|
-
CLOBBER.include("**/*.#{dlext}", "**/*~", "**/*#*", "**/*.log", "**/*.o")
|
12
|
-
CLEAN.include("ext/**/*.#{dlext}", "ext/**/*.log", "ext/**/*.o",
|
13
|
-
"ext/**/*~", "ext/**/*#*", "ext/**/*.obj", "**/*#*", "**/*#*.*",
|
14
|
-
"ext/**/*.def", "ext/**/*.pdb", "**/*_flymake*.*", "**/*_flymake", "**/*.rbc")
|
15
|
-
|
16
|
-
def mri_2?
|
17
|
-
defined?(RUBY_ENGINE) && RUBY_ENGINE == "ruby" &&
|
18
|
-
RUBY_VERSION =~ /^2/
|
19
|
-
end
|
20
|
-
|
21
|
-
def apply_spec_defaults(s)
|
22
|
-
s.name = "binding_of_caller"
|
23
|
-
s.summary = "Retrieve the binding of a method's caller. Can also retrieve bindings even further up the stack."
|
24
|
-
s.version = BindingOfCaller::VERSION
|
25
|
-
s.date = Time.now.strftime '%Y-%m-%d'
|
26
|
-
s.author = "John Mair (banisterfiend)"
|
27
|
-
s.email = 'jrmair@gmail.com'
|
28
|
-
s.description = s.summary
|
29
|
-
s.require_path = 'lib'
|
30
|
-
s.add_dependency 'debug_inspector', '>= 0.0.1'
|
31
|
-
s.add_development_dependency 'bacon'
|
32
|
-
s.add_development_dependency 'rake'
|
33
|
-
s.homepage = "http://github.com/banister/binding_of_caller"
|
34
|
-
s.has_rdoc = 'yard'
|
35
|
-
s.files = `git ls-files`.split("\n")
|
36
|
-
s.test_files = `git ls-files -- test/*`.split("\n")
|
37
|
-
end
|
38
|
-
|
39
|
-
desc "Show version"
|
40
|
-
task :version do
|
41
|
-
puts "BindingOfCaller version: #{BindingOfCaller::VERSION}"
|
42
|
-
end
|
43
|
-
|
44
|
-
desc "run tests"
|
45
|
-
task :default => [:test]
|
46
|
-
|
47
|
-
desc "Run tests"
|
48
|
-
task :test do
|
49
|
-
unless defined?(Rubinius)
|
50
|
-
Rake::Task['compile'].execute
|
51
|
-
end
|
52
|
-
|
53
|
-
$stdout.puts("\033[33m")
|
54
|
-
sh "bacon -Itest -rubygems -a -q"
|
55
|
-
$stdout.puts("\033[0m")
|
56
|
-
|
57
|
-
unless defined?(Rubinius)
|
58
|
-
Rake::Task['cleanup'].execute
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
task :pry do
|
63
|
-
puts "loading binding_of_caller into pry"
|
64
|
-
sh "pry -r ./lib/binding_of_caller"
|
65
|
-
end
|
66
|
-
|
67
|
-
desc "generate gemspec"
|
68
|
-
task :gemspec => "ruby:gemspec"
|
69
|
-
|
70
|
-
namespace :ruby do
|
71
|
-
spec = Gem::Specification.new do |s|
|
72
|
-
apply_spec_defaults(s)
|
73
|
-
s.platform = Gem::Platform::RUBY
|
74
|
-
s.extensions = ["ext/binding_of_caller/extconf.rb"]
|
75
|
-
end
|
76
|
-
|
77
|
-
Gem::PackageTask.new(spec) do |pkg|
|
78
|
-
pkg.need_zip = false
|
79
|
-
pkg.need_tar = false
|
80
|
-
end
|
81
|
-
|
82
|
-
desc "Generate gemspec file"
|
83
|
-
task :gemspec do
|
84
|
-
File.open("#{spec.name}.gemspec", "w") do |f|
|
85
|
-
f << spec.to_ruby
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
desc "build the binaries"
|
91
|
-
task :compile => :cleanup do
|
92
|
-
if !mri_2?
|
93
|
-
chdir "./ext/binding_of_caller/" do
|
94
|
-
sh "ruby extconf.rb"
|
95
|
-
sh "make"
|
96
|
-
sh "cp *.#{dlext} ../../lib/"
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
desc 'cleanup the extensions'
|
102
|
-
task :cleanup do
|
103
|
-
if !mri_2?
|
104
|
-
sh 'rm -rf lib/binding_of_caller.so'
|
105
|
-
chdir "./ext/binding_of_caller/" do
|
106
|
-
sh 'make clean'
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
desc "reinstall gem"
|
112
|
-
task :reinstall => :gems do
|
113
|
-
sh "gem uninstall binding_of_caller" rescue nil
|
114
|
-
sh "gem install #{direc}/pkg/binding_of_caller-#{BindingOfCaller::VERSION}.gem"
|
115
|
-
end
|
116
|
-
|
117
|
-
task :install => :reinstall
|
118
|
-
|
119
|
-
desc "build all platform gems at once"
|
120
|
-
task :gems => [:clean, :rmgems, "ruby:gem"]
|
121
|
-
|
122
|
-
task :gem => [:gems]
|
123
|
-
|
124
|
-
desc "remove all platform gems"
|
125
|
-
task :rmgems => ["ruby:clobber_package"]
|
126
|
-
|
127
|
-
desc "build and push latest gems"
|
128
|
-
task :pushgems => :gems do
|
129
|
-
chdir("./pkg") do
|
130
|
-
Dir["*.gem"].each do |gemfile|
|
131
|
-
sh "gem push #{gemfile}"
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|
6
|
+
task :default => :spec
|
data/binding_of_caller.gemspec
CHANGED
@@ -1,37 +1,35 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
Gem::Specification.new do |
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
s.add_dependency(%q<rake>, [">= 0"])
|
31
|
-
end
|
32
|
-
else
|
33
|
-
s.add_dependency(%q<debug_inspector>, [">= 0.0.1"])
|
34
|
-
s.add_dependency(%q<bacon>, [">= 0"])
|
35
|
-
s.add_dependency(%q<rake>, [">= 0"])
|
1
|
+
require_relative 'lib/binding_of_caller/version'
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = "binding_of_caller"
|
5
|
+
spec.version = BindingOfCaller::VERSION
|
6
|
+
spec.authors = ["John Mair (banisterfiend)"]
|
7
|
+
spec.email = ["jrmair@gmail.com"]
|
8
|
+
|
9
|
+
spec.summary = %q{Retrieve the binding of a method's caller, or further up the stack.}
|
10
|
+
spec.description = <<-TXT
|
11
|
+
Provides the Binding#of_caller method.
|
12
|
+
|
13
|
+
Using binding_of_caller we can grab bindings from higher up the call stack and evaluate code in that context.
|
14
|
+
Allows access to bindings arbitrarily far up the call stack, not limited to just the immediate caller.
|
15
|
+
|
16
|
+
Recommended for use only in debugging situations. Do not use this in production apps.
|
17
|
+
TXT
|
18
|
+
spec.homepage = "https://github.com/banister/binding_of_caller"
|
19
|
+
spec.license = "MIT"
|
20
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.0.0")
|
21
|
+
|
22
|
+
spec.metadata = {
|
23
|
+
"changelog_uri" => "https://github.com/banister/binding_of_caller/releases",
|
24
|
+
}
|
25
|
+
|
26
|
+
# Specify which files should be added to the gem when it is released.
|
27
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
28
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
29
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|examples|bin)/}) }
|
36
30
|
end
|
31
|
+
|
32
|
+
spec.require_paths = ["lib"]
|
33
|
+
|
34
|
+
spec.add_dependency "debug_inspector", ">= 1.2.0"
|
37
35
|
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
|
-
rescue ArgumentError
|
27
|
-
break
|
28
|
-
end
|
29
20
|
|
21
|
+
DebugInspector.open do |dc|
|
22
|
+
locs = dc.backtrace_locations
|
23
|
+
|
24
|
+
locs.size.times do |i|
|
25
|
+
b = dc.frame_binding(i)
|
30
26
|
if b
|
31
|
-
b.instance_variable_set(:@iseq,
|
27
|
+
b.instance_variable_set(:@iseq, dc.frame_iseq(i))
|
32
28
|
ary << b
|
33
29
|
end
|
34
|
-
|
35
|
-
n += 1
|
36
30
|
end
|
37
31
|
end
|
38
|
-
|
32
|
+
|
39
33
|
ary.drop(1)
|
40
34
|
end
|
41
35
|
|
@@ -49,7 +43,7 @@ module BindingOfCaller
|
|
49
43
|
# @return [Symbol]
|
50
44
|
def frame_type
|
51
45
|
return nil if !@iseq
|
52
|
-
|
46
|
+
|
53
47
|
# apparently the 9th element of the iseq array holds the frame type
|
54
48
|
# ...not sure how reliable this is.
|
55
49
|
@frame_type ||= @iseq.to_a[9]
|
@@ -4,22 +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
|
-
|
7
|
+
location = Rubinius::VM.backtrace(1 + n, true).first
|
8
8
|
|
9
|
-
raise RuntimeError, "Invalid frame, gone beyond end of stack!" if
|
9
|
+
raise RuntimeError, "Invalid frame, gone beyond end of stack!" if location.nil?
|
10
10
|
|
11
|
-
|
12
|
-
bt.variables,
|
13
|
-
bt.variables.method,
|
14
|
-
bt.constant_scope,
|
15
|
-
bt.variables.self,
|
16
|
-
bt
|
17
|
-
)
|
18
|
-
|
19
|
-
b.instance_variable_set :@frame_description,
|
20
|
-
bt.describe.gsub("{ } in", "block in")
|
21
|
-
|
22
|
-
b
|
11
|
+
setup_binding_from_location(location)
|
23
12
|
end
|
24
13
|
|
25
14
|
# The description of the frame.
|
@@ -31,25 +20,14 @@ module BindingOfCaller
|
|
31
20
|
# Return bindings for all caller frames.
|
32
21
|
# @return [Array<Binding>]
|
33
22
|
def callers
|
34
|
-
|
35
|
-
|
36
|
-
loop do
|
37
|
-
begin
|
38
|
-
ary << Binding.of_caller(n)
|
39
|
-
rescue
|
40
|
-
break
|
41
|
-
end
|
42
|
-
n += 1
|
43
|
-
end
|
44
|
-
ary.drop_while do |v|
|
45
|
-
!(v.frame_type == :method && v.eval("__method__") == :callers)
|
46
|
-
end.drop(1)
|
23
|
+
Rubinius::VM.backtrace(1, true).map &(method(:setup_binding_from_location).
|
24
|
+
to_proc)
|
47
25
|
end
|
48
26
|
|
49
27
|
# Number of parent frames available at the point of call.
|
50
28
|
# @return [Fixnum]
|
51
29
|
def frame_count
|
52
|
-
|
30
|
+
Rubinius::VM.backtrace(1).count
|
53
31
|
end
|
54
32
|
|
55
33
|
# The type of the frame.
|
@@ -65,6 +43,21 @@ module BindingOfCaller
|
|
65
43
|
:method
|
66
44
|
end
|
67
45
|
end
|
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
|
68
61
|
end
|
69
62
|
end
|
70
63
|
|