ruby-internal 0.8.2 → 0.8.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -86,43 +86,6 @@ And view class hierarchies:
86
86
  +-class = Kernel
87
87
  => nil
88
88
 
89
- View method signatures:
90
-
91
- irb(main):015:0> def foo(a, b, *rest, &block); end; method(:foo).signature
92
- => #<MethodSig::Signature:0x4037093c @origin_class=Object, @arg_info={:b=>"b",
93
- :block=>"&block", :a=>"a", :rest=>"*rest"}, @name="foo", @arg_names=[:a,
94
- :b, :rest, :block]>
95
- irb(main):016:0> proc { |x, y, *rest| }.signature
96
- => #<Proc::Signature:0x4036cf30 @args=#<Proc::Arguments:0x4036d020 @rest_arg=2,
97
- @multiple_assignment=true, @names=[:x, :y, :rest]>, @arg_info={:x=>"x", :y=>"y",
98
- :rest=>"*rest"}>
99
-
100
- And reconstruct compiled methods:
101
-
102
- irb(main):001:0> def foo(a, b, *rest, &block)
103
- irb(main):002:1> begin
104
- irb(main):003:2* if not a and not b then
105
- irb(main):004:3* raise "Need more input!"
106
- irb(main):005:3> end
107
- irb(main):006:2> return a + b
108
- irb(main):007:2> ensure
109
- irb(main):008:2* puts "In ensure block"
110
- irb(main):009:2> end
111
- irb(main):010:1> end
112
- => nil
113
- irb(main):011:0> m = method(:foo)
114
- => #<Method: Object#foo>
115
- irb(main):012:0> puts m.as_code
116
- def foo(a, b, *rest, &block)
117
- begin
118
- (raise("Need more input!")) if (not a and not b)
119
- return a + b
120
- ensure
121
- puts("In ensure block")
122
- end
123
- end
124
- => nil
125
-
126
89
  == YARV support
127
90
 
128
91
  Yes, ruby-internal works with YARV, too. The difference when using YARV
@@ -186,7 +149,7 @@ iterate over the bytecode sequence:
186
149
  #<VM::Instruction::LEAVE:0x40411e24 @operands=[]> 1 []
187
150
  => nil
188
151
 
189
- then decompile it:
152
+ then decompile it (using ruby-decompiler):
190
153
 
191
154
  irb(main):005:0> require 'as_expression'
192
155
  => true
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-internal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.2
4
+ version: 0.8.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -39,34 +39,21 @@ executables:
39
39
  extensions:
40
40
  - Rakefile
41
41
  extra_rdoc_files:
42
- - README
42
+ - README.rdoc
43
43
  files:
44
44
  - lib/internal/node/to_a.rb
45
- - lib/internal/node/as_code.rb
46
45
  - lib/internal/node/obfusc.rb
47
46
  - lib/internal/node/dump.rb
48
47
  - lib/internal/node/pp.rb
49
- - lib/internal/node/as_expression.rb
50
48
  - lib/internal/module.rb
51
49
  - lib/internal/proc.rb
52
50
  - lib/internal/binding.rb
53
51
  - lib/internal/vm/inline_cache.rb
54
- - lib/internal/vm/iseq/as_code.rb
55
- - lib/internal/vm/iseq/as_expression.rb
56
52
  - lib/internal/vm/instruction.rb
57
53
  - lib/internal/vm/iseq.rb
58
54
  - lib/internal/vm/control_frame.rb
59
- - lib/internal/vm/bytedecoder.rb
60
55
  - lib/internal/vm/constants.rb
61
56
  - lib/internal/object.rb
62
- - lib/internal/method/origin.rb
63
- - lib/internal/method/signature.rb
64
- - lib/internal/method/signature/signature.rb
65
- - lib/internal/method/signature/argument.rb
66
- - lib/internal/method/signature/iseq.rb
67
- - lib/internal/method/signature/node.rb
68
- - lib/internal/method/as_code.rb
69
- - lib/internal/method/as_expression.rb
70
57
  - lib/internal/vm.rb
71
58
  - lib/internal/object/as_code.rb
72
59
  - lib/internal/thread.rb
@@ -75,10 +62,6 @@ files:
75
62
  - lib/internal/obfusc.rb
76
63
  - lib/internal/debug.rb
77
64
  - lib/internal/tag.rb
78
- - lib/internal/module/as_code.rb
79
- - lib/internal/proc/signature.rb
80
- - lib/internal/proc/as_code.rb
81
- - lib/internal/proc/as_expression.rb
82
65
  - lib/internal/method.rb
83
66
  - lib/internal/node.rb
84
67
  - ext/mkmf-ruby-internal.rb
@@ -344,17 +327,13 @@ files:
344
327
  - example/simple_client.rb
345
328
  - example/triangle_client.rb
346
329
  - example/README
347
- - test/test_methodsig.rb
348
330
  - test/test_dump_method.rb
349
331
  - test/test_dump_proc.rb
350
332
  - test/test_proc.rb
351
333
  - test/test_helpers.rb
352
334
  - test/test_method.rb
353
- - test/test_as_code.rb
354
335
  - test/node_samples.rb
355
336
  - test/test_node.rb
356
- - test/expression_samples.rb
357
- - test/test_as_expression.rb
358
337
  - test/test_module.rb
359
338
  - test/test_dump_class.rb
360
339
  - pre-install.rb
@@ -370,7 +349,7 @@ files:
370
349
  - COPYING
371
350
  - LGPL
372
351
  - LICENSE
373
- - README
352
+ - README.rdoc
374
353
  - TODO
375
354
  - metaconfig
376
355
  - Rakefile
@@ -404,14 +383,11 @@ signing_key:
404
383
  specification_version: 3
405
384
  summary: A library that provides acccess to the internals of the ruby interpreter
406
385
  test_files:
407
- - test/test_methodsig.rb
408
386
  - test/test_dump_method.rb
409
387
  - test/test_dump_proc.rb
410
388
  - test/test_proc.rb
411
389
  - test/test_helpers.rb
412
390
  - test/test_method.rb
413
- - test/test_as_code.rb
414
391
  - test/test_node.rb
415
- - test/test_as_expression.rb
416
392
  - test/test_module.rb
417
393
  - test/test_dump_class.rb
@@ -1,58 +0,0 @@
1
- require 'internal/node/as_code'
2
- require 'internal/vm/iseq/as_code'
3
- require 'internal/method'
4
- require 'internal/method/signature'
5
-
6
- module MethodAsCode
7
- # Returns a string representation of the method definition/body.
8
- #
9
- # irb(main):001:0> def foo(a, b, *rest, &block)
10
- # irb(main):002:1> begin
11
- # irb(main):003:2* if not a and not b then
12
- # irb(main):004:3* raise "Need more input!"
13
- # irb(main):005:3> end
14
- # irb(main):006:2> return a + b
15
- # irb(main):007:2> ensure
16
- # irb(main):008:2* puts "In ensure block"
17
- # irb(main):009:2> end
18
- # irb(main):010:1> end
19
- # => nil
20
- # irb(main):011:0> m = method(:foo)
21
- # => #<Method: Object#foo>
22
- # irb(main):012:0> puts m.as_code
23
- # def foo(a, b, *rest, &block)
24
- # begin
25
- # (raise("Need more input!")) if (not a and not b)
26
- # return a + b
27
- # ensure
28
- # puts("In ensure block")
29
- # end
30
- # end
31
- #
32
- def as_code(indent=0, name=nil)
33
- sig = self.signature
34
- if self.body.respond_to?(:body) then
35
- # YARV
36
- body_expression = self.body.body.as_code(indent+1)
37
- else
38
- # pre-YARV
39
- body_expression = self.body ? self.body.as_code(indent+1) : ''
40
- end
41
- name ||= sig.name
42
- s = "#{' '*indent}def #{name}(#{sig.param_list})\n"
43
- if body_expression then
44
- s += "#{body_expression}\n"
45
- end
46
- s += "#{' '*indent}end"
47
- return s
48
- end
49
- end
50
-
51
- class Method
52
- include MethodAsCode
53
- end
54
-
55
- class UnboundMethod
56
- include MethodAsCode
57
- end
58
-
@@ -1,33 +0,0 @@
1
- require 'internal/node/as_expression'
2
- require 'internal/vm/iseq/as_expression'
3
- require 'internal/method/signature'
4
- require 'internal/method'
5
-
6
- module MethodAsExpression
7
- # Return a single-line string representation of a method
8
- # TODO: this method would be more aptly named "as_expression_string".
9
- def as_expression
10
- sig = self.signature
11
- if self.body.respond_to?(:body) then
12
- # YARV
13
- body_expression = self.body.body.as_expression
14
- else
15
- # pre-YARV
16
- body_expression = self.body.as_expression
17
- end
18
- if body_expression then
19
- return "def #{sig.name}(#{sig.param_list}); #{body_expression}; end"
20
- else
21
- return "def #{sig.name}(#{sig.param_list}); end"
22
- end
23
- end
24
- end
25
-
26
- class Method
27
- include MethodAsExpression
28
- end
29
-
30
- class UnboundMethod
31
- include MethodAsExpression
32
- end
33
-
@@ -1,29 +0,0 @@
1
- module MethodOrigin
2
- # An abstraction for a method origin.
3
- class Origin
4
- attr_reader :file, :line
5
-
6
- def initialize(file, line)
7
- @file = file
8
- @line = line
9
- end
10
-
11
- def to_s
12
- return "#{file}:#{line}"
13
- end
14
- end
15
-
16
- # Return a Method::Origin representing where the method was defined.
17
- def origin
18
- block = body().next
19
- return Origin.new(block.nd_file, block.nd_line)
20
- end
21
- end
22
-
23
- class Method
24
- include MethodOrigin
25
- end
26
-
27
- class UnboundMethod
28
- include MethodOrigin
29
- end
@@ -1,147 +0,0 @@
1
- require 'internal/method'
2
- require 'internal/node'
3
- require 'internal/node/as_expression'
4
- require 'internal/method/signature/argument'
5
- require 'internal/method/signature/node'
6
- require 'internal/method/signature/signature'
7
-
8
- if defined?(RubyVM) then
9
- require 'internal/vm/bytedecoder'
10
- require 'internal/method/signature/iseq'
11
- end
12
-
13
- module MethodSig
14
- # Return the names of the local variables of this method.
15
- def local_vars
16
- return self.body.local_vars
17
- end
18
-
19
- # Return the names of the arguments this method takes, in the order in
20
- # which they appear in the argument list.
21
- def argument_names
22
- return self.body.argument_names
23
- end
24
-
25
- def args_node
26
- return self.body.args_node
27
- end
28
- private :args_node
29
-
30
- # If this method has a "rest" argument, that is, it has an argument
31
- # that is preceded by an asterisk (*) in the argument list, then
32
- # return its index, otherwise return nil.
33
- def rest_arg
34
- return self.body.rest_arg
35
- end
36
-
37
- # If this method has a "block" argument, that is, it has an argument
38
- # that is preceded by an ampersand (&) in the argument list, then
39
- # return its index, otherwise return nil.
40
- def block_arg
41
- return self.body.block_arg
42
- end
43
-
44
- def set_optional_args(args, args_node, names)
45
- self.body.set_optional_args(args, args_node, names)
46
- end
47
- private :set_optional_args
48
-
49
- # Return a hash mapping each argument name to a description of that
50
- # argument.
51
- def arguments
52
- names = self.argument_names()
53
- block_arg = self.block_arg()
54
-
55
- args = {}
56
- names.each do |name|
57
- args[name] = Argument.new(name, false, false)
58
- end
59
-
60
- # Optional args
61
- args_node = args_node()
62
- set_optional_args(args, args_node, names)
63
-
64
- # Rest arg
65
- if self.rest_arg then
66
- rest_name = names[rest_arg]
67
- args[rest_name] = Argument.new(rest_name, true, false)
68
- end
69
-
70
- # Block arg
71
- if block_arg then
72
- block_name = names[block_arg]
73
- args[block_name] = Argument.new(block_name, false, true)
74
- end
75
-
76
- return args
77
- end
78
- end
79
-
80
- class Method
81
- include MethodSig
82
-
83
- # Return a String representing the method's signature.
84
- def signature
85
- return Signature.new(
86
- attached_class(),
87
- method_oid().to_s,
88
- argument_names(),
89
- arguments())
90
- end
91
- end
92
-
93
- class UnboundMethod
94
- include MethodSig
95
-
96
- # Return a String representing the method's signature.
97
- def signature
98
- return Signature.new(
99
- origin_class(),
100
- method_oid().to_s,
101
- argument_names(),
102
- arguments())
103
- end
104
- end
105
-
106
- if __FILE__ == $0 then
107
- def foo(); end
108
- puts method(:foo).signature
109
-
110
- def foo(foo); end
111
- puts method(:foo).signature
112
-
113
- def foo(foo, bar); end
114
- puts method(:foo).signature
115
-
116
- def foo(foo=42, bar=10); end
117
- puts method(:foo).signature
118
-
119
- def foo(*args); end
120
- puts method(:foo).signature
121
-
122
- def foo(foo, bar=42, *args, &block); end
123
- puts method(:foo).signature
124
- puts method(:foo).origin
125
-
126
- def foo(foo, bar=obj.foo(1, 2, foo(10)), *args, &block); end
127
- puts method(:foo).signature
128
-
129
- def foo(foo, bar=obj.foo(1 + 1), *args, &block); end
130
- puts method(:foo).signature
131
-
132
- def foo(foo, bar=true ? false : 0, *args, &block); end
133
- puts method(:foo).signature
134
-
135
- def foo(foo, bar=true, *args, &block); end
136
- puts method(:foo).signature
137
-
138
- def foo(foo, bar=nil, *args, &block); end
139
- puts method(:foo).signature
140
-
141
- def foo(foo, bar={1=>2}, *args, &block); end
142
- puts method(:foo).signature
143
-
144
- def foo(foo, bar=[1,2], *args, &block); end
145
- puts method(:foo).signature
146
- end
147
-
@@ -1,102 +0,0 @@
1
-
2
- module MethodSig
3
- class Argument
4
- attr_reader :name
5
-
6
- def required?
7
- return !optional?
8
- end
9
-
10
- def optional?
11
- return rest? || block?
12
- end
13
-
14
- def rest?
15
- return @is_rest
16
- end
17
-
18
- def block?
19
- return @is_block
20
- end
21
-
22
- def default
23
- return nil
24
- end
25
-
26
- def initialize(name, is_rest, is_block)
27
- @name = name
28
- @is_rest = is_rest
29
- @is_block = is_block
30
- end
31
-
32
- def to_s
33
- if @is_rest then
34
- prefix = "*"
35
- elsif @is_block then
36
- prefix = "&"
37
- end
38
-
39
- if self.default then
40
- suffix = "=#{default()}"
41
- end
42
-
43
- return "#{prefix}#{@name}#{suffix}"
44
- end
45
- end
46
-
47
- class OptionalArgument < Argument
48
- def optional?
49
- return true
50
- end
51
- end
52
-
53
- class NodeOptionalArgument < OptionalArgument
54
- attr_reader :node_for_default
55
- attr_reader :default
56
-
57
- def initialize(name, default, node_for_default, is_rest, is_block)
58
- super(name, is_rest, is_block)
59
- @default = default
60
- @node_for_default = node_for_default
61
- end
62
- end
63
-
64
- class YarvOptionalArgument < OptionalArgument
65
- attr_reader :iseq
66
- attr_reader :pc_start
67
- attr_reader :local_idx
68
-
69
- def initialize(name, iseq, pc_start, local_idx, is_rest, is_block)
70
- super(name, is_rest, is_block)
71
- @iseq = iseq
72
- @pc_start = pc_start
73
- @local_idx = local_idx
74
- @default = nil
75
- end
76
-
77
- def inspect
78
- default()
79
- super
80
- end
81
-
82
- def default
83
- return @default if @default
84
-
85
- env = Internal::ByteDecoder::Environment.new(@iseq.local_table())
86
- local_table_idx = local_table_idx()
87
- @iseq.bytedecode(env, @pc_start) do |instr|
88
- RubyVM::Instruction::SETLOCAL === instr &&
89
- instr.operands[0] == local_table_idx
90
- end
91
- expressions = env.expressions + env.stack
92
-
93
- @default = expressions[0].rhs.to_s
94
- return @default
95
- end
96
-
97
- def local_table_idx
98
- return @iseq.local_table.size - @local_idx + 1
99
- end
100
- end
101
- end
102
-