bindex 0.1.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 (165) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.travis.yml +48 -0
  4. data/CONTRIBUTING.md +15 -0
  5. data/Gemfile +10 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +38 -0
  8. data/Rakefile +48 -0
  9. data/bindex.gemspec +27 -0
  10. data/ext/bindex/bindex.h +11 -0
  11. data/ext/bindex/bindings.c +106 -0
  12. data/ext/bindex/com/gsamokovarov/bindex/BindingBuilder.java.erb +17 -0
  13. data/ext/bindex/com/gsamokovarov/bindex/CurrentBindingsIterator.java +54 -0
  14. data/ext/bindex/com/gsamokovarov/bindex/RubyBindingsCollector.java +34 -0
  15. data/ext/bindex/com/gsamokovarov/bindex/SetExceptionBindingsEventHook.java +21 -0
  16. data/ext/bindex/com/gsamokovarov/bindex/ThreadContextInterfaceException.java +14 -0
  17. data/ext/bindex/com/gsamokovarov/bindex/ThreadContextInternals.java +54 -0
  18. data/ext/bindex/cruby.c +34 -0
  19. data/ext/bindex/extconf.rb +29 -0
  20. data/ext/bindex/ruby_193.h +101 -0
  21. data/ext/bindex/ruby_193/addr2line.h +21 -0
  22. data/ext/bindex/ruby_193/constant.h +34 -0
  23. data/ext/bindex/ruby_193/debug.h +41 -0
  24. data/ext/bindex/ruby_193/dln.h +50 -0
  25. data/ext/bindex/ruby_193/encdb.h +167 -0
  26. data/ext/bindex/ruby_193/eval_intern.h +234 -0
  27. data/ext/bindex/ruby_193/gc.h +99 -0
  28. data/ext/bindex/ruby_193/id.h +177 -0
  29. data/ext/bindex/ruby_193/internal.h +242 -0
  30. data/ext/bindex/ruby_193/iseq.h +126 -0
  31. data/ext/bindex/ruby_193/method.h +105 -0
  32. data/ext/bindex/ruby_193/node.h +504 -0
  33. data/ext/bindex/ruby_193/parse.h +302 -0
  34. data/ext/bindex/ruby_193/probes.h +369 -0
  35. data/ext/bindex/ruby_193/regenc.h +219 -0
  36. data/ext/bindex/ruby_193/regint.h +850 -0
  37. data/ext/bindex/ruby_193/regparse.h +362 -0
  38. data/ext/bindex/ruby_193/revision.h +1 -0
  39. data/ext/bindex/ruby_193/ruby_atomic.h +175 -0
  40. data/ext/bindex/ruby_193/siphash.h +48 -0
  41. data/ext/bindex/ruby_193/thread_pthread.h +51 -0
  42. data/ext/bindex/ruby_193/thread_win32.h +40 -0
  43. data/ext/bindex/ruby_193/timev.h +21 -0
  44. data/ext/bindex/ruby_193/transcode_data.h +117 -0
  45. data/ext/bindex/ruby_193/transdb.h +186 -0
  46. data/ext/bindex/ruby_193/verconf.h +12 -0
  47. data/ext/bindex/ruby_193/version.h +52 -0
  48. data/ext/bindex/ruby_193/vm_core.h +763 -0
  49. data/ext/bindex/ruby_193/vm_exec.h +184 -0
  50. data/ext/bindex/ruby_193/vm_insnhelper.h +220 -0
  51. data/ext/bindex/ruby_193/vm_opts.h +51 -0
  52. data/ext/bindex/ruby_20.h +142 -0
  53. data/ext/bindex/ruby_20/addr2line.h +21 -0
  54. data/ext/bindex/ruby_20/constant.h +36 -0
  55. data/ext/bindex/ruby_20/dln.h +50 -0
  56. data/ext/bindex/ruby_20/encdb.h +169 -0
  57. data/ext/bindex/ruby_20/eval_intern.h +241 -0
  58. data/ext/bindex/ruby_20/gc.h +104 -0
  59. data/ext/bindex/ruby_20/id.h +135 -0
  60. data/ext/bindex/ruby_20/internal.h +395 -0
  61. data/ext/bindex/ruby_20/iseq.h +140 -0
  62. data/ext/bindex/ruby_20/method.h +138 -0
  63. data/ext/bindex/ruby_20/node.h +541 -0
  64. data/ext/bindex/ruby_20/parse.h +292 -0
  65. data/ext/bindex/ruby_20/probes.h +369 -0
  66. data/ext/bindex/ruby_20/probes_helper.h +67 -0
  67. data/ext/bindex/ruby_20/regenc.h +227 -0
  68. data/ext/bindex/ruby_20/regint.h +915 -0
  69. data/ext/bindex/ruby_20/regparse.h +367 -0
  70. data/ext/bindex/ruby_20/revision.h +1 -0
  71. data/ext/bindex/ruby_20/ruby_atomic.h +170 -0
  72. data/ext/bindex/ruby_20/siphash.h +48 -0
  73. data/ext/bindex/ruby_20/thread_pthread.h +56 -0
  74. data/ext/bindex/ruby_20/thread_win32.h +45 -0
  75. data/ext/bindex/ruby_20/timev.h +21 -0
  76. data/ext/bindex/ruby_20/transcode_data.h +127 -0
  77. data/ext/bindex/ruby_20/transdb.h +190 -0
  78. data/ext/bindex/ruby_20/verconf.h +12 -0
  79. data/ext/bindex/ruby_20/version.h +52 -0
  80. data/ext/bindex/ruby_20/vm_core.h +1018 -0
  81. data/ext/bindex/ruby_20/vm_debug.h +41 -0
  82. data/ext/bindex/ruby_20/vm_exec.h +173 -0
  83. data/ext/bindex/ruby_20/vm_insnhelper.h +274 -0
  84. data/ext/bindex/ruby_20/vm_opts.h +56 -0
  85. data/ext/bindex/ruby_21.h +142 -0
  86. data/ext/bindex/ruby_21/addr2line.h +21 -0
  87. data/ext/bindex/ruby_21/constant.h +36 -0
  88. data/ext/bindex/ruby_21/dln.h +51 -0
  89. data/ext/bindex/ruby_21/encdb.h +170 -0
  90. data/ext/bindex/ruby_21/eval_intern.h +260 -0
  91. data/ext/bindex/ruby_21/gc.h +101 -0
  92. data/ext/bindex/ruby_21/id.h +210 -0
  93. data/ext/bindex/ruby_21/internal.h +889 -0
  94. data/ext/bindex/ruby_21/iseq.h +136 -0
  95. data/ext/bindex/ruby_21/method.h +142 -0
  96. data/ext/bindex/ruby_21/node.h +543 -0
  97. data/ext/bindex/ruby_21/parse.h +298 -0
  98. data/ext/bindex/ruby_21/probes.h +401 -0
  99. data/ext/bindex/ruby_21/probes_helper.h +67 -0
  100. data/ext/bindex/ruby_21/regenc.h +223 -0
  101. data/ext/bindex/ruby_21/regint.h +911 -0
  102. data/ext/bindex/ruby_21/regparse.h +363 -0
  103. data/ext/bindex/ruby_21/revision.h +1 -0
  104. data/ext/bindex/ruby_21/ruby_atomic.h +170 -0
  105. data/ext/bindex/ruby_21/siphash.h +48 -0
  106. data/ext/bindex/ruby_21/thread_native.h +23 -0
  107. data/ext/bindex/ruby_21/thread_pthread.h +56 -0
  108. data/ext/bindex/ruby_21/thread_win32.h +45 -0
  109. data/ext/bindex/ruby_21/timev.h +42 -0
  110. data/ext/bindex/ruby_21/transcode_data.h +123 -0
  111. data/ext/bindex/ruby_21/transdb.h +190 -0
  112. data/ext/bindex/ruby_21/verconf.h +13 -0
  113. data/ext/bindex/ruby_21/version.h +52 -0
  114. data/ext/bindex/ruby_21/vm_core.h +1043 -0
  115. data/ext/bindex/ruby_21/vm_debug.h +37 -0
  116. data/ext/bindex/ruby_21/vm_exec.h +182 -0
  117. data/ext/bindex/ruby_21/vm_insnhelper.h +273 -0
  118. data/ext/bindex/ruby_21/vm_opts.h +56 -0
  119. data/ext/bindex/ruby_21preview.h +146 -0
  120. data/ext/bindex/ruby_21preview/addr2line.h +21 -0
  121. data/ext/bindex/ruby_21preview/constant.h +36 -0
  122. data/ext/bindex/ruby_21preview/dln.h +51 -0
  123. data/ext/bindex/ruby_21preview/encdb.h +270 -0
  124. data/ext/bindex/ruby_21preview/eval_intern.h +217 -0
  125. data/ext/bindex/ruby_21preview/gc.h +100 -0
  126. data/ext/bindex/ruby_21preview/id.h +169 -0
  127. data/ext/bindex/ruby_21preview/internal.h +765 -0
  128. data/ext/bindex/ruby_21preview/iseq.h +136 -0
  129. data/ext/bindex/ruby_21preview/method.h +141 -0
  130. data/ext/bindex/ruby_21preview/node.h +543 -0
  131. data/ext/bindex/ruby_21preview/parse.h +298 -0
  132. data/ext/bindex/ruby_21preview/probes.h +385 -0
  133. data/ext/bindex/ruby_21preview/probes_helper.h +67 -0
  134. data/ext/bindex/ruby_21preview/regenc.h +223 -0
  135. data/ext/bindex/ruby_21preview/regint.h +911 -0
  136. data/ext/bindex/ruby_21preview/regparse.h +363 -0
  137. data/ext/bindex/ruby_21preview/revision.h +1 -0
  138. data/ext/bindex/ruby_21preview/ruby_atomic.h +130 -0
  139. data/ext/bindex/ruby_21preview/siphash.h +48 -0
  140. data/ext/bindex/ruby_21preview/thread_native.h +23 -0
  141. data/ext/bindex/ruby_21preview/thread_pthread.h +56 -0
  142. data/ext/bindex/ruby_21preview/thread_win32.h +45 -0
  143. data/ext/bindex/ruby_21preview/timev.h +42 -0
  144. data/ext/bindex/ruby_21preview/transcode_data.h +123 -0
  145. data/ext/bindex/ruby_21preview/transdb.h +190 -0
  146. data/ext/bindex/ruby_21preview/verconf.h +13 -0
  147. data/ext/bindex/ruby_21preview/version.h +53 -0
  148. data/ext/bindex/ruby_21preview/vm_core.h +1017 -0
  149. data/ext/bindex/ruby_21preview/vm_debug.h +37 -0
  150. data/ext/bindex/ruby_21preview/vm_exec.h +180 -0
  151. data/ext/bindex/ruby_21preview/vm_insnhelper.h +272 -0
  152. data/ext/bindex/ruby_21preview/vm_opts.h +56 -0
  153. data/lib/bindex.rb +10 -0
  154. data/lib/bindex/jruby.rb +20 -0
  155. data/lib/bindex/jruby_internals.jar +0 -0
  156. data/lib/bindex/jruby_internals_9k.jar +0 -0
  157. data/lib/bindex/rubinius.rb +56 -0
  158. data/lib/bindex/version.rb +3 -0
  159. data/test/exception_test.rb +45 -0
  160. data/test/fixtures/basic_nested_fixture.rb +13 -0
  161. data/test/fixtures/custom_error_fixture.rb +9 -0
  162. data/test/fixtures/eval_nested_fixture.rb +13 -0
  163. data/test/fixtures/flat_fixture.rb +7 -0
  164. data/test/test_helper.rb +17 -0
  165. metadata +270 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 30c71c3e8372b14f944f36e0d4bbbbeef20afa73
4
+ data.tar.gz: d01dd1e87366ad5eabdc415890c0c8efee3bb5dc
5
+ SHA512:
6
+ metadata.gz: 38aa516e2594f473fcc7cdc4e412240d01a29da7866ca043fff5f1119bf7e70b54f04e7545b9225995a34934dab9c8a52579a27292e46a4a7c6d0a2d885a8db4
7
+ data.tar.gz: 8307b1fe43ca21e3bbd83dee6a69818d1c3a7f3fbccf7951d8861d13a5aae3bae6d1b353412f42a54cedaaf9fd61470ea887e4efe5c049adb7b5e75f69399507
@@ -0,0 +1,16 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ .ycm_extra_conf.py*
15
+ mkmf.log
16
+ ext/bindex/com/gsamokovarov/bindex/BindingBuilder.java
@@ -0,0 +1,48 @@
1
+ language: ruby
2
+
3
+ rvm:
4
+ - ruby-1.9.3-p551
5
+ - ruby-1.9.3-p550
6
+ - ruby-1.9.3-p547
7
+ - ruby-1.9.3-p545
8
+ - ruby-1.9.3-p484
9
+
10
+ - ruby-2.0.0-p598
11
+ - ruby-2.0.0-p576
12
+ - ruby-2.0.0-p481
13
+ - ruby-2.0.0-p451
14
+ - ruby-2.0.0-p353
15
+ - ruby-2.0.0-p247
16
+ - ruby-2.0.0-p195
17
+ - ruby-2.0.0-p0
18
+
19
+ - ruby-2.1.5
20
+ - ruby-2.1.4
21
+ - ruby-2.1.3
22
+ - ruby-2.1.2-clang
23
+ - ruby-2.1.2
24
+ - ruby-2.1.1-clang
25
+ - ruby-2.1.1
26
+ - ruby-2.1.0-rc1
27
+ - ruby-2.1.0-preview2
28
+ - ruby-2.1.0-preview1
29
+ - ruby-2.1.0
30
+
31
+ - ruby-head
32
+
33
+ - rbx-2.2.7
34
+ - rbx-2.2.6
35
+ - rbx-2.2.2
36
+
37
+ - jruby-head
38
+ - jruby-1.7.9-d19
39
+ - jruby-1.7.17
40
+ - jruby-1.7.11
41
+
42
+ env:
43
+ global:
44
+ - JRUBY_OPTS=-J-Djruby.compile.mode=OFF
45
+
46
+ before_install: gem install bundler
47
+
48
+ sudo: false
@@ -0,0 +1,15 @@
1
+ # Contributing
2
+
3
+ 1. Fork it ( https://github.com/gsamokovarov/bindex/fork )
4
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
5
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
6
+ 4. Push to the branch (`git push origin my-new-feature`)
7
+ 5. Create a new Pull Request
8
+
9
+ ## Etiquette
10
+
11
+ If you want to contribute code, which is not your own or is heavily inspired by
12
+ someone else's code, please give them a warm shoutout in the pull request (or
13
+ the commit message) and the code itself.
14
+
15
+ Of course, don't try to sneak in non MIT compatible code.
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ # Rubinius 2.2.2 travis tests complain about this one.
6
+ platforms :rbx do
7
+ gem "rubysl-mutex_m"
8
+ gem "rubysl-open3"
9
+ gem "rubysl-singleton"
10
+ end
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Genadi Samokovarov
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,38 @@
1
+ # Bindex [![Build Status](https://travis-ci.org/gsamokovarov/bindex.svg?branch=master)](https://travis-ci.org/gsamokovarov/bindex)
2
+
3
+ When Ruby raises an exception, it leaves you backtraces to help you figure out
4
+ where did the exception originated in. Bindex gives you the bindings as well.
5
+ This can help you introspect the state of the Ruby program when the exception
6
+ happened.
7
+
8
+ ### Usage
9
+
10
+ **Do not** use this gem on production environments. The performance penalty isn't
11
+ worth it anywhere outside of development.
12
+
13
+ ## Support
14
+
15
+ ### CRuby
16
+
17
+ CRuby 1.9.2 and below is **not** supported.
18
+
19
+ ### JRuby
20
+
21
+ To get the best support, run JRuby in interpreted mode.
22
+
23
+ ```bash
24
+ export JRUBY_OPTS=-J-Djruby.compile.mode=OFF
25
+
26
+ # If you run JRuby 1.7.12 and above, you can use:
27
+ export JRUBY_OPTS=--dev
28
+ ```
29
+
30
+ ### Rubinius
31
+
32
+ Internal errors like `ZeroDevisionError` aren't caught.
33
+
34
+ ## Credits
35
+
36
+ Thanks to John Mair for his work on binding_of_caller, which is a huge
37
+ inspiration. Thanks to Charlie Somerville for better_errors where the idea
38
+ comes from. Thanks to Koichi Sasada for the debug inspector API in CRuby.
@@ -0,0 +1,48 @@
1
+ require 'erb'
2
+ require 'bundler/gem_tasks'
3
+ require 'rake/testtask'
4
+
5
+ def jruby_9k?
6
+ JRUBY_VERSION.start_with?('9')
7
+ end
8
+
9
+ def root
10
+ Pathname.new File.expand_path('..', __FILE__)
11
+ end
12
+
13
+ def render_template(template_path, target = nil)
14
+ target ||= root.join(template_path).to_s.chomp('.erb')
15
+ template = ERB.new File.read(root.join(template_path))
16
+ File.write target, template.result(binding)
17
+ end
18
+
19
+ Rake::TestTask.new do |t|
20
+ t.libs << 'test'
21
+ t.test_files = FileList['test/*_test.rb']
22
+ t.verbose = true
23
+ end
24
+
25
+ case RUBY_ENGINE
26
+ when 'ruby'
27
+ require 'rake/extensiontask'
28
+
29
+ Rake::ExtensionTask.new('bindex') do |ext|
30
+ ext.name = 'cruby'
31
+ ext.lib_dir = 'lib/bindex'
32
+ end
33
+
34
+ task default: [:clean, :compile, :test]
35
+ when 'jruby'
36
+ require 'rake/javaextensiontask'
37
+
38
+ Rake::JavaExtensionTask.new('bindex') do |ext|
39
+ ext.name = jruby_9k? ? 'jruby_internals_9k' : 'jruby_internals'
40
+ ext.lib_dir = 'lib/bindex'
41
+ end
42
+
43
+ render_template 'ext/bindex/com/gsamokovarov/bindex/BindingBuilder.java.erb'
44
+
45
+ task default: [:clean, :compile, :test]
46
+ else
47
+ task default: [:test]
48
+ end
@@ -0,0 +1,27 @@
1
+ $LOAD_PATH << File.expand_path('../lib', __FILE__)
2
+
3
+ require 'bindex/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "bindex"
7
+ spec.version = Bindex::VERSION
8
+ spec.authors = ["Genadi Samokovarov"]
9
+ spec.email = ["gsamokovarov@gmail.com"]
10
+ spec.extensions = ["ext/bindex/extconf.rb"]
11
+ spec.summary = "Bindings for your Ruby exceptions"
12
+ spec.homepage = "https://github.com/gsamokovarov/bindex"
13
+ spec.license = "MIT"
14
+
15
+ spec.required_ruby_version = ">= 1.9.3"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0")
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+ spec.extensions = ["ext/bindex/extconf.rb"]
22
+
23
+ spec.add_development_dependency "minitest", "~> 5.4"
24
+ spec.add_development_dependency "bundler"
25
+ spec.add_development_dependency "rake"
26
+ spec.add_development_dependency "rake-compiler"
27
+ end
@@ -0,0 +1,11 @@
1
+ #ifndef _BINDEX_H
2
+ #define _BINDEX_H
3
+
4
+ #include <ruby.h>
5
+
6
+ VALUE current_bindings(void);
7
+
8
+ /* This will come from one of the ruby_*.h files. */
9
+ extern VALUE rb_check_backtrace(VALUE);
10
+
11
+ #endif
@@ -0,0 +1,106 @@
1
+ #include "bindex.h"
2
+
3
+ #ifdef RUBY_193
4
+
5
+ #include "ruby_193.h"
6
+
7
+ static rb_thread_t *current_thread;
8
+
9
+ #define GetCoreDataFromValueAsExpr(obj, type, ptr) \
10
+ ((ptr) = (type*)DATA_PTR(obj))
11
+
12
+ #define ruby_current_thread \
13
+ GetCoreDataFromValueAsExpr(rb_thread_current(), rb_thread_t, current_thread)
14
+
15
+ /*
16
+ * Create a binding from a thread and control frame.
17
+ *
18
+ * Based on rb_binding new, defined in proc.c. A major difference from
19
+ * rb_binding_new is that it doesn't raises an exception, when we try to create
20
+ * Binding on top of a Fiber.
21
+ *
22
+ * The reason for this is that binding_new is to be used in exception handling
23
+ * code. If we raise, it may lead to an infinite recursion.
24
+ *
25
+ * Also, we'll assume a bit more hostile environment and check if cfp->iseq is
26
+ * NULL.
27
+ *
28
+ * Ruby nil is returned when the control frame pointer isn't suitable.
29
+ */
30
+
31
+ static VALUE
32
+ binding_new(rb_thread_t *th, rb_control_frame_t *cfp)
33
+ {
34
+ VALUE bindval;
35
+ rb_binding_t *bind;
36
+
37
+ if (cfp == NULL || cfp->iseq == NULL) {
38
+ return Qnil;
39
+ }
40
+
41
+ bindval = binding_alloc(rb_cBinding);
42
+
43
+ GetBindingPtr(bindval, bind);
44
+ bind->env = rb_vm_make_env_object(th, cfp);
45
+ bind->filename = cfp->iseq->filename;
46
+ bind->line_no = rb_vm_get_sourceline(cfp);
47
+ return bindval;
48
+ }
49
+
50
+ VALUE
51
+ current_bindings(void)
52
+ {
53
+ rb_thread_t *th = GET_THREAD();
54
+ rb_control_frame_t *cfp = th->cfp;
55
+ rb_control_frame_t *cfp_limit = RUBY_VM_END_CONTROL_FRAME(th);
56
+ VALUE binding, bindings = rb_ary_new();
57
+
58
+ while (cfp_limit > cfp) {
59
+ cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
60
+ binding = binding_new(th, cfp);
61
+
62
+ if (!NIL_P(binding)) {
63
+ rb_ary_push(bindings, binding);
64
+ }
65
+ }
66
+
67
+ return bindings;
68
+ }
69
+
70
+ #else
71
+
72
+ #include <ruby/debug.h>
73
+
74
+ #ifdef RUBY_20
75
+ #include "ruby_20.h"
76
+ #elif RUBY_21
77
+ #include "ruby_21.h"
78
+ #elif RUBY_21PREVIEW
79
+ #include "ruby_21preview.h"
80
+ #endif
81
+
82
+ static VALUE
83
+ current_bindings_callback(const rb_debug_inspector_t *context, void *data)
84
+ {
85
+ VALUE locations = rb_debug_inspector_backtrace_locations(context);
86
+ VALUE binding, bindings = rb_ary_new();
87
+ long i, length = RARRAY_LEN(locations);
88
+
89
+ for (i = 0; i < length; i++) {
90
+ binding = rb_debug_inspector_frame_binding_get(context, i);
91
+
92
+ if (!NIL_P(binding)) {
93
+ rb_ary_push(bindings, binding);
94
+ }
95
+ }
96
+
97
+ return bindings;
98
+ }
99
+
100
+ VALUE
101
+ current_bindings(void)
102
+ {
103
+ return rb_debug_inspector_open(current_bindings_callback, NULL);
104
+ }
105
+
106
+ #endif
@@ -0,0 +1,17 @@
1
+ package com.gsamokovarov.bindex;
2
+
3
+ import org.jruby.runtime.DynamicScope;
4
+ import org.jruby.runtime.Binding;
5
+ import org.jruby.runtime.Frame;
6
+ import org.jruby.runtime.DynamicScope;
7
+ import org.jruby.runtime.backtrace.BacktraceElement;
8
+
9
+ class BindingBuilder {
10
+ public static Binding build(Frame frame, DynamicScope scope, BacktraceElement element) {
11
+ <% if jruby_9k? %>
12
+ return new Binding(frame, scope, element.clone());
13
+ <% else %>
14
+ return new Binding(frame, scope.getStaticScope().getModule(), scope, element.clone());
15
+ <% end %>
16
+ }
17
+ }
@@ -0,0 +1,54 @@
1
+ package com.gsamokovarov.bindex;
2
+
3
+ import org.jruby.runtime.ThreadContext;
4
+ import org.jruby.runtime.DynamicScope;
5
+ import org.jruby.runtime.Binding;
6
+ import org.jruby.runtime.Frame;
7
+ import org.jruby.runtime.DynamicScope;
8
+ import org.jruby.runtime.backtrace.BacktraceElement;
9
+ import java.util.Iterator;
10
+ import java.util.NoSuchElementException;
11
+
12
+ class CurrentBindingsIterator implements Iterator<Binding> {
13
+ private Frame[] frameStack;
14
+ private int frameIndex;
15
+
16
+ private DynamicScope[] scopeStack;
17
+ private int scopeIndex;
18
+
19
+ private BacktraceElement[] backtrace;
20
+ private int backtraceIndex;
21
+
22
+ CurrentBindingsIterator(ThreadContext context) {
23
+ ThreadContextInternals contextInternals = new ThreadContextInternals(context);
24
+
25
+ this.frameStack = contextInternals.getFrameStack();
26
+ this.frameIndex = contextInternals.getFrameIndex();
27
+
28
+ this.scopeStack = contextInternals.getScopeStack();
29
+ this.scopeIndex = contextInternals.getScopeIndex();
30
+
31
+ this.backtrace = contextInternals.getBacktrace();
32
+ this.backtraceIndex = contextInternals.getBacktraceIndex();
33
+ }
34
+
35
+ public boolean hasNext() {
36
+ return frameIndex >= 0 && scopeIndex >= 0 && backtraceIndex >= 0;
37
+ }
38
+
39
+ public Binding next() {
40
+ if (!hasNext()) {
41
+ throw new NoSuchElementException();
42
+ }
43
+
44
+ Frame frame = frameStack[frameIndex--];
45
+ DynamicScope scope = scopeStack[scopeIndex--];
46
+ BacktraceElement element = backtrace[backtraceIndex--];
47
+
48
+ return BindingBuilder.build(frame, scope, element);
49
+ }
50
+
51
+ public void remove() {
52
+ throw new UnsupportedOperationException();
53
+ }
54
+ }
@@ -0,0 +1,34 @@
1
+ package com.gsamokovarov.bindex;
2
+
3
+ import org.jruby.runtime.ThreadContext;
4
+ import org.jruby.runtime.Binding;
5
+ import org.jruby.runtime.DynamicScope;
6
+ import org.jruby.runtime.builtin.IRubyObject;
7
+ import org.jruby.RubyBinding;
8
+ import org.jruby.RubyArray;
9
+ import org.jruby.Ruby;
10
+ import java.util.Iterator;
11
+
12
+ public class RubyBindingsCollector {
13
+ private final Ruby runtime;
14
+ private Iterator<Binding> iterator;
15
+
16
+ public static RubyArray collectCurrentFor(ThreadContext context) {
17
+ return new RubyBindingsCollector(context).collectCurrent();
18
+ }
19
+
20
+ private RubyBindingsCollector(ThreadContext context) {
21
+ this.iterator = new CurrentBindingsIterator(context);
22
+ this.runtime = context.getRuntime();
23
+ }
24
+
25
+ private RubyArray collectCurrent() {
26
+ RubyArray bindings = RubyArray.newArray(runtime);
27
+
28
+ while (iterator.hasNext()) {
29
+ bindings.append(((IRubyObject) RubyBinding.newBinding(runtime, iterator.next())));
30
+ }
31
+
32
+ return bindings;
33
+ }
34
+ }