rubymirrors 0.0.1 → 0.0.2

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.
@@ -16,7 +16,7 @@ module AbstractReflection
16
16
  def defining_class
17
17
  raise CapabilitiesExceeded
18
18
  end
19
-
19
+
20
20
  # @return [String] The source code of this method
21
21
  def source
22
22
  raise CapabilitiesExceeded
@@ -39,7 +39,7 @@ module AbstractReflection
39
39
 
40
40
  # Queries the method for it's arguments and returns a list of
41
41
  # mirrors that hold name and value information.
42
- #
42
+ #
43
43
  # @return [Array<FieldMirror>]
44
44
  def arguments
45
45
  raise CapabilitiesExceeded
@@ -1,4 +1,5 @@
1
1
  require 'maglev/reflection/core_ext/module'
2
+ require 'maglev/reflection/core_ext/class'
2
3
 
3
4
  module Maglev
4
5
  class Reflection
@@ -0,0 +1,3 @@
1
+ class Class
2
+ primitive '__subclasses', '_subclasses'
3
+ end
@@ -0,0 +1,3 @@
1
+ class Exception
2
+ primitive '__resume', 'resume:'
3
+ end
@@ -15,9 +15,14 @@ class GsNMethod
15
15
  primitive '__ip_steps', '_ipSteps'
16
16
  primitive '__opcode_info_at', '_opcodeInfoAt:'
17
17
  primitive '__in_class', 'inClass'
18
+ primitive '__all_breakpoints_source_offsets', '_allBreakpointsSourceOffsets'
19
+ primitive '__set_break_at', 'setBreakAtStepPoint:'
20
+ primitive '__clear_break_at', 'clearBreakAtStepPoint:'
18
21
  end
19
22
 
20
23
  class UnboundMethod
24
+ primitive '__nonbridge_meth', '_nonBridgeMeth'
25
+
21
26
  def __st_gsmeth
22
27
  @_st_gsmeth
23
28
  end
@@ -37,5 +37,4 @@ class Module
37
37
  primitive '__inst_var_names', 'instVarNames'
38
38
  primitive '__compile_method_category_environment_id', 'compileMethod:category:environmentId:'
39
39
  primitive '__compile_method_category_environment_id', 'compileMethod:category:environmentId:'
40
- primitive '__subclasses', 'subclasses'
41
40
  end
@@ -0,0 +1,21 @@
1
+ require File.expand_path("../method.rb", __FILE__)
2
+ require File.expand_path("../thread.rb", __FILE__)
3
+
4
+ class ExecBlock
5
+ primitive 'shift', 'shift'
6
+ primitive 'reset', 'reset'
7
+ end
8
+
9
+ class Proc
10
+ def __shift
11
+ @_st_block.shift
12
+ end
13
+
14
+ def __reset
15
+ @_st_block.reset
16
+ end
17
+ end
18
+
19
+ class Thread
20
+ primitive 'call', 'call:'
21
+ end
@@ -13,7 +13,8 @@ class Thread
13
13
  # Remove all frames above [Fixnum]
14
14
  primitive '__trim_stack_to_level', '_trimStackToLevel:'
15
15
  # Change temporary at level to value
16
- primitive '__frame_at_temp_named_put', '_frameAt:tempNamed:put:'
16
+ primitive '__frame_at_temp_at_put', '_frameAt:tempAt:put:'
17
+ primitive '__frame_at_offset_of_temp_named', '_frameAt:offsetOfTempNamed:'
17
18
  # => Array
18
19
  # with:
19
20
  # 1 gsMethod
@@ -33,7 +34,7 @@ class Thread
33
34
  primitive 'convert_to_persistable_state', "convertToPersistableState"
34
35
  primitive 'convert_to_runnable_state', 'convertToRunnableState'
35
36
  primitive '__ar_stack', 'arStack'
36
- primitive '__client_data', '_clientData'
37
+ primitive '__client_data', 'clientData'
37
38
  # Private. Returns an Array describing the specified level in the receiver.
38
39
  # aLevel == 1 is top of stack. If aLevel is less than 1 or greater than
39
40
  # stackDepth, returns nil.
@@ -62,6 +63,12 @@ class Thread
62
63
 
63
64
  class_primitive '__installPartialContinuation_atLevel_value', 'installPartialContinuation:atLevel:value:'
64
65
  class_primitive '__partialContinuationFromLevel_to', 'partialContinuationFromLevel:to:'
66
+
67
+ # Re-add behavior which was removed in GS 3.1.0.1
68
+ def __frame_at_temp_named_put(frameidx, tempname, value)
69
+ offset = __frame_at_offset_of_temp_named(frameidx, tempname)
70
+ __frame_at_temp_at_put(frameidx, offset, value)
71
+ end
65
72
  end
66
73
 
67
74
  # require 'maglev/objectlog'
@@ -1,4 +1,5 @@
1
1
  require 'maglev/reflection/core_ext/module'
2
+ require 'maglev/reflection/core_ext/class'
2
3
 
3
4
  module Maglev
4
5
  class Reflection
@@ -113,7 +113,29 @@ module Maglev
113
113
  gsmeth.__in_class.remove_method(selector)
114
114
  end
115
115
 
116
+ def breakpoints
117
+ gsmeth.__all_breakpoints_source_offsets
118
+ end
119
+
120
+ def break(source_offset = 1)
121
+ step_point = find_step_point_just_before(source_offset)
122
+ if gsmeth.__is_method_for_block
123
+ gsmeth.__set_break_at_step_point(step_point)
124
+ else
125
+ @subject.__nonbridge_meth.__set_break_at_step_point(step_point)
126
+ end
127
+ end
128
+
129
+ def clear_break(source_offset)
130
+ gsmeth.__clear_break_at(find_step_point_just_before(source_offset))
131
+ end
132
+
116
133
  private
134
+ def find_step_point_just_before(source_offset)
135
+ nxt = step_offsets.detect {|o| o > source_offset }
136
+ [step_offsets.index(nxt) - 1, 1].max
137
+ end
138
+
117
139
  def wrap_gsmeth(gsmethod)
118
140
  label = gsmethod.__name.to_s
119
141
  cls = gsmethod.__in_class
@@ -0,0 +1,50 @@
1
+ class PartialContinuation
2
+ attr_accessor :markerBlock, :partial
3
+
4
+ def self.currentDomarkerBlock(block, markerBlock)
5
+ if (marker = markerBlock.call).nil?
6
+ raise RuntimeError, 'Marker not found when capturing partial continuation.'
7
+ end
8
+ return block.call to_offset_markerBlock(marker, 1, markerBlock)
9
+ end
10
+
11
+ def self.to_offset_markerBlock(method, offset, &block)
12
+ idx = find_frame_for(method)
13
+ partial = Thread.__partialContinuationFromLevel_to(3 + offset, idx)
14
+ new.tap do |o|
15
+ o.partial = partial
16
+ o.markerBlock = block
17
+ end
18
+ end
19
+
20
+ def self.find_frame_for(method)
21
+ index = 1
22
+ while frame = Thread.current.__frame_contents_at(index) do
23
+ if frame[0] == method
24
+ return level
25
+ else
26
+ level += 1
27
+ end
28
+ end
29
+ nil
30
+ end
31
+
32
+ def call(arg = nil)
33
+ marker = markerBlock.call
34
+ if marker.nil?
35
+ marker = Thread.current.__frame_contents_at(2).first
36
+ frameIndex = 2
37
+ else
38
+ frameIndex = self.class.find_frame_for marker
39
+ end
40
+ Thread.current.__installPartialContinuation_atLevel_value partial, frameIndex, arg
41
+ end
42
+
43
+ alias [] call
44
+ end
45
+
46
+ def test_callcc
47
+ PartialContinuation.currentDomarkerBlock
48
+ currentDo: aBlock
49
+ markerBlock: [ self callbackMarker ]
50
+ end
@@ -23,7 +23,7 @@ module Ruby
23
23
  end
24
24
 
25
25
  def line
26
- source_location.last
26
+ source_location.last - 1
27
27
  end
28
28
 
29
29
  def line=(num)
@@ -77,6 +77,25 @@ module Ruby
77
77
 
78
78
  def source
79
79
  try_send(:source) or raise(CapabilitiesExceeded)
80
+ rescue => e
81
+ e.message
82
+ end
83
+
84
+ def source=(str)
85
+ src = try_send(:source)
86
+ raise "cannot write to source location" unless file and line and File.writable?(file)
87
+
88
+ f = File.read(file).lines.to_a
89
+ srclen = src.lines.to_a.size
90
+ prefix = f[0...line].join
91
+ method_src = f[line...line + srclen].join
92
+ postfix = f[line + srclen..-1].join
93
+ raise "source differs from runtime" unless method_src.strip == src.strip
94
+
95
+ File.open(file, 'w') {|f| f << prefix << str << postfix }
96
+ defining_class.reflectee.class_eval(str, file, line)
97
+ rescue Exception => e
98
+ raise CapabilitiesExceeded, e.message
80
99
  end
81
100
 
82
101
  def step_offsets
@@ -90,10 +109,14 @@ module Ruby
90
109
 
91
110
  offsets = [0]
92
111
  sends.each do |name|
93
- offsets << (source[offsets.last..-1] =~ /#{Regexp.escape(name)}/)
112
+ next_offset = source[offsets.last..-1] =~ /#{Regexp.escape(name)}/
113
+ break unless next_offset
114
+ offsets << next_offset
94
115
  end
95
116
  offsets.shift
96
117
  Hash[*sends.zip(offsets).flatten]
118
+ rescue Exception
119
+ return {}
97
120
  end
98
121
 
99
122
  private
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "rubymirrors"
3
- s.version = "0.0.1"
3
+ s.version = "0.0.2"
4
4
  s.platform = Gem::Platform::RUBY
5
5
  s.authors = ["Tim Felgentreff"]
6
6
  s.email = ["timfelgentreff@gmail.com"]
metadata CHANGED
@@ -1,64 +1,85 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: rubymirrors
3
- version: !ruby/object:Gem::Version
4
- hash: 29
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 0
9
- - 1
10
- version: 0.0.1
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Tim Felgentreff
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-11-10 00:00:00 Z
12
+ date: 2012-10-25 00:00:00.000000000 Z
19
13
  dependencies: []
14
+ description: ! '## A mirror API for Ruby
15
+
20
16
 
21
- description: |
22
- ## A mirror API for Ruby
23
-
24
17
  In various [research][p1] [projects][p2] the advantages of having a [mirror
18
+
25
19
  API][p3] to separate reflection from a language implementation have
20
+
26
21
  been discussed, and "industry grade" implementations exist for
22
+
27
23
  [Java][p4] and [C#][p5]. This project aims at providing a number of
24
+
28
25
  specs and classes that document a mirror API for Ruby. The mirror
26
+
29
27
  implementation that is part of this project will use only those
28
+
30
29
  language facilities that are available across Ruby implementations.
30
+
31
31
  The specs, however, will also test behavior that cannot be provided in
32
+
32
33
  such a manner. The idea here is that in time, all implementations
34
+
33
35
  provide their own implementation of the mirror API, and all
36
+
34
37
  implementations collaborate on this one spec.
35
-
38
+
39
+
36
40
  Why do this, you ask? Because Ruby needs tools, and those tools need
41
+
37
42
  to be written in Ruby. If they are not, then people will be excluded from
43
+
38
44
  tinkering with their tools, thus impeding innovation. You only have to
39
- look at Emacs or Smalltalk to see what's possible when programmers can
45
+
46
+ look at Emacs or Smalltalk to see what''s possible when programmers can
47
+
40
48
  extend their tools, all tools, in a language they feel comfortable
49
+
41
50
  in. If we have a standard mirror API, all tools that are written **for**
51
+
42
52
  Ruby, **in** Ruby, can be shared across implementations, while at the same time
53
+
43
54
  allowing language implementers to use the facilities of their platform
55
+
44
56
  to provide optimal reflective capabilities without tying them to
57
+
45
58
  internals.
46
-
47
- [p1]: http://www.cs.virginia.edu/~lorenz/papers/icse03/icse2003.pdf "Pluggable Reflection: Decoupling Meta-Interface and Implementation"
48
- [p2]: http://bracha.org/newspeak-spec.pdf "Newspeak Programming Language Draft Specification, Version 0.06, pages 40 onward"
49
- [p3]: http://www.hpi.uni-potsdam.de/hirschfeld/events/past/media/100105_Bracha_2010_LinguisticReflectionViaMirrors_HPI.mp4 "Linguistic Reflection Via Mirrors"
50
- [p4]: http://bracha.org/mirrors.pdf "Mirrors: Design Principles for Meta-level Facilities of Object-Oriented Programming Languages"
51
- [p5]: http://oreilly.com/catalog/progcsharp/chapter/ch18.html "See esp. 18-3, highlighting how C# reflection works on assembly rather than VM objects"
52
-
53
- email:
59
+
60
+
61
+ [p1]: http://www.cs.virginia.edu/~lorenz/papers/icse03/icse2003.pdf "Pluggable Reflection:
62
+ Decoupling Meta-Interface and Implementation"
63
+
64
+ [p2]: http://bracha.org/newspeak-spec.pdf "Newspeak Programming Language Draft Specification,
65
+ Version 0.06, pages 40 onward"
66
+
67
+ [p3]: http://www.hpi.uni-potsdam.de/hirschfeld/events/past/media/100105_Bracha_2010_LinguisticReflectionViaMirrors_HPI.mp4
68
+ "Linguistic Reflection Via Mirrors"
69
+
70
+ [p4]: http://bracha.org/mirrors.pdf "Mirrors: Design Principles for Meta-level Facilities
71
+ of Object-Oriented Programming Languages"
72
+
73
+ [p5]: http://oreilly.com/catalog/progcsharp/chapter/ch18.html "See esp. 18-3, highlighting
74
+ how C# reflection works on assembly rather than VM objects"
75
+
76
+ '
77
+ email:
54
78
  - timfelgentreff@gmail.com
55
79
  executables: []
56
-
57
80
  extensions: []
58
-
59
81
  extra_rdoc_files: []
60
-
61
- files:
82
+ files:
62
83
  - Gemfile
63
84
  - README.md
64
85
  - Rakefile
@@ -74,11 +95,14 @@ files:
74
95
  - lib/abstract_reflection/thread_mirror.rb
75
96
  - lib/maglev/reflection.rb
76
97
  - lib/maglev/reflection/class_mirror.rb
98
+ - lib/maglev/reflection/core_ext/class.rb
77
99
  - lib/maglev/reflection/core_ext/class_organizer.rb
100
+ - lib/maglev/reflection/core_ext/exception.rb
78
101
  - lib/maglev/reflection/core_ext/maglev.rb
79
102
  - lib/maglev/reflection/core_ext/method.rb
80
103
  - lib/maglev/reflection/core_ext/module.rb
81
104
  - lib/maglev/reflection/core_ext/object.rb
105
+ - lib/maglev/reflection/core_ext/proc.rb
82
106
  - lib/maglev/reflection/core_ext/thread.rb
83
107
  - lib/maglev/reflection/field_mirror.rb
84
108
  - lib/maglev/reflection/field_mirror/fixed_instance_variable_mirror.rb
@@ -86,6 +110,7 @@ files:
86
110
  - lib/maglev/reflection/mirror.rb
87
111
  - lib/maglev/reflection/object_mirror.rb
88
112
  - lib/maglev/reflection/stack_frame_mirror.rb
113
+ - lib/maglev/reflection/support/partial_continuation.rb
89
114
  - lib/maglev/reflection/thread_mirror.rb
90
115
  - lib/rubinius/reflection.rb
91
116
  - lib/ruby/reflection.rb
@@ -120,40 +145,29 @@ files:
120
145
  - spec/thread_spec.rb
121
146
  homepage:
122
147
  licenses: []
123
-
124
- metadata: {}
125
-
126
148
  post_install_message:
127
149
  rdoc_options: []
128
-
129
- require_paths:
150
+ require_paths:
130
151
  - lib
131
- required_ruby_version: !ruby/object:Gem::Requirement
152
+ required_ruby_version: !ruby/object:Gem::Requirement
132
153
  none: false
133
- requirements:
134
- - - ">="
135
- - !ruby/object:Gem::Version
136
- hash: 3
137
- segments:
138
- - 0
139
- version: "0"
140
- required_rubygems_version: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - ! '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ required_rubygems_version: !ruby/object:Gem::Requirement
141
159
  none: false
142
- requirements:
143
- - - ">="
144
- - !ruby/object:Gem::Version
145
- hash: 3
146
- segments:
147
- - 0
148
- version: "0"
160
+ requirements:
161
+ - - ! '>='
162
+ - !ruby/object:Gem::Version
163
+ version: '0'
149
164
  requirements: []
150
-
151
165
  rubyforge_project:
152
- rubygems_version: 1.8.10
166
+ rubygems_version: 1.8.23
153
167
  signing_key:
154
- specification_version: 4
168
+ specification_version: 3
155
169
  summary: Mirror API for Ruby
156
- test_files:
170
+ test_files:
157
171
  - spec/class_spec.rb
158
172
  - spec/field_spec.rb
159
173
  - spec/fixtures/class_spec.rb