ruby-internal 0.6.0 → 0.7.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.
- data/README +204 -6
- data/ext/cached/ruby-1.6.8/internal/binding/block.h +35 -0
- data/ext/cached/ruby-1.6.8/internal/method/method.h +19 -0
- data/ext/cached/ruby-1.6.8/internal/module/classpath.c +3 -0
- data/ext/cached/ruby-1.6.8/internal/module/classpath.h +8 -0
- data/ext/cached/ruby-1.6.8/internal/node/block.h +35 -0
- data/ext/cached/ruby-1.6.8/internal/node/global_entry.h +15 -0
- data/ext/cached/ruby-1.6.8/internal/node/node_type_descrip.c +149 -0
- data/ext/cached/ruby-1.6.8/internal/node/nodeinfo.c +5582 -0
- data/ext/cached/ruby-1.6.8/internal/node/nodeinfo.h +69 -0
- data/ext/cached/ruby-1.6.8/internal/proc/block.h +35 -0
- data/ext/cached/ruby-1.6.8/internal/tag/tag.h +15 -0
- data/ext/cached/ruby-1.6.8/internal/vm/instruction/insns_info.c +39 -0
- data/ext/cached/ruby-1.6.8/internal/vm/instruction/insns_info.h +21 -0
- data/ext/cached/ruby-1.6.8/internal/vm/iseq/insns_info.inc +12 -0
- data/ext/cached/ruby-1.6.8/internal/vm/iseq/iseq_load.inc +9 -0
- data/ext/cached/ruby-1.8.0/internal/node/node_type_descrip.c +91 -91
- data/ext/cached/ruby-1.8.0/internal/node/nodeinfo.c +1909 -1909
- data/ext/cached/ruby-1.8.0/internal/vm/iseq/iseq_load.inc +9 -0
- data/ext/cached/ruby-1.8.1/internal/node/node_type_descrip.c +90 -90
- data/ext/cached/ruby-1.8.1/internal/node/nodeinfo.c +1946 -1946
- data/ext/cached/ruby-1.8.1/internal/vm/iseq/iseq_load.inc +9 -0
- data/ext/cached/ruby-1.8.2/internal/node/node_type_descrip.c +90 -90
- data/ext/cached/ruby-1.8.2/internal/node/nodeinfo.c +1946 -1946
- data/ext/cached/ruby-1.8.2/internal/vm/iseq/iseq_load.inc +9 -0
- data/ext/cached/ruby-1.8.3/internal/node/node_type_descrip.c +90 -90
- data/ext/cached/ruby-1.8.3/internal/node/nodeinfo.c +1946 -1946
- data/ext/cached/ruby-1.8.3/internal/vm/iseq/iseq_load.inc +9 -0
- data/ext/cached/ruby-1.8.4/internal/node/node_type_descrip.c +90 -90
- data/ext/cached/ruby-1.8.4/internal/node/nodeinfo.c +1946 -1946
- data/ext/cached/ruby-1.8.4/internal/vm/iseq/iseq_load.inc +9 -0
- data/ext/cached/ruby-1.8.5/internal/node/node_type_descrip.c +90 -90
- data/ext/cached/ruby-1.8.5/internal/node/nodeinfo.c +1909 -1909
- data/ext/cached/ruby-1.8.5/internal/vm/iseq/iseq_load.inc +9 -0
- data/ext/cached/ruby-1.8.6/internal/node/node_type_descrip.c +90 -90
- data/ext/cached/ruby-1.8.6/internal/node/nodeinfo.c +1909 -1909
- data/ext/cached/ruby-1.8.6/internal/vm/iseq/iseq_load.inc +9 -0
- data/ext/cached/ruby-1.8.7/internal/node/node_type_descrip.c +90 -90
- data/ext/cached/ruby-1.8.7/internal/node/nodeinfo.c +1909 -1909
- data/ext/cached/ruby-1.8.7/internal/vm/iseq/iseq_load.inc +9 -0
- data/ext/cached/ruby-1.9.0/internal/node/node_type_descrip.c +85 -85
- data/ext/cached/ruby-1.9.0/internal/node/nodeinfo.c +1800 -1800
- data/ext/cached/ruby-1.9.0/internal/vm/iseq/iseq_load.inc +13 -0
- data/ext/cached/ruby-1.9.0/internal/yarv-headers/transdb.h +51 -51
- data/ext/cached/ruby-1.9.1/internal/node/node_type_descrip.c +85 -85
- data/ext/cached/ruby-1.9.1/internal/node/nodeinfo.c +1800 -1800
- data/ext/cached/ruby-1.9.1/internal/vm/instruction/insns_info.h +1 -2
- data/ext/cached/ruby-1.9.1/internal/vm/iseq/iseq_load.inc +356 -0
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/eval_intern.h +15 -9
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/id.h +45 -66
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/iseq.h +12 -3
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/node.h +2 -2
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/parse.h +23 -138
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/revision.h +1 -1
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/transcode_data.h +9 -2
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/transdb.h +62 -0
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/version.h +17 -23
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/vm_core.h +20 -29
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/vm_exec.h +4 -7
- data/ext/cached/ruby-1.9.1/internal/yarv-headers/vm_insnhelper.h +6 -5
- data/ext/internal/module/cfp.h +13 -0
- data/ext/internal/module/extconf.rb +2 -2
- data/ext/internal/module/module.c +3 -8
- data/ext/internal/node/nodes.rb +2 -1
- data/ext/internal/vm/iseq/iseq.c +2 -3
- data/ext/internal/vm/iseq/iseq_load.inc.rpp +61 -0
- data/ext/internal/yarv-headers/debug.h +36 -0
- data/ext/internal/yarv-headers/dln.h +41 -0
- data/ext/internal/yarv-headers/encdb.h +147 -0
- data/ext/internal/yarv-headers/eval_intern.h +215 -0
- data/ext/internal/yarv-headers/gc.h +75 -0
- data/ext/internal/yarv-headers/id.h +163 -0
- data/ext/internal/yarv-headers/iseq.h +103 -0
- data/ext/internal/yarv-headers/node.h +516 -0
- data/ext/internal/yarv-headers/parse.h +188 -0
- data/ext/internal/yarv-headers/regenc.h +207 -0
- data/ext/internal/yarv-headers/regint.h +842 -0
- data/ext/internal/yarv-headers/regparse.h +351 -0
- data/ext/internal/yarv-headers/revision.h +1 -0
- data/ext/internal/yarv-headers/thread_pthread.h +24 -0
- data/ext/internal/yarv-headers/thread_win32.h +33 -0
- data/ext/internal/yarv-headers/transcode_data.h +106 -0
- data/ext/internal/yarv-headers/transdb.h +147 -0
- data/ext/internal/yarv-headers/version.h +54 -0
- data/ext/internal/yarv-headers/vm_core.h +646 -0
- data/ext/internal/yarv-headers/vm_exec.h +184 -0
- data/ext/internal/yarv-headers/vm_insnhelper.h +195 -0
- data/ext/internal/yarv-headers/vm_opts.h +51 -0
- data/publish_rdoc.rb +4 -0
- metadata +52 -2
data/README
CHANGED
|
@@ -1,7 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
Ruby-internal is a Ruby library that provides direct access to Ruby's
|
|
2
|
+
(MRI or YARV) internal data structures.
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
How is ruby-internal useful? You can:
|
|
5
|
+
|
|
6
|
+
* dump and load methods and procs and classes
|
|
7
|
+
* inspect and pretty-print ascii charts of node trees
|
|
8
|
+
* inspect and print ascii charts of class hierarchies
|
|
9
|
+
* use the provided code obfuscator (nwobfusc.rb) so your code can't easily be read.
|
|
10
|
+
* use it to build a just-in-time compiler (see Ludicrous).
|
|
11
|
+
|
|
12
|
+
== Installation
|
|
13
|
+
|
|
14
|
+
To install ruby-internal:
|
|
15
|
+
|
|
16
|
+
$ gem install ruby-internal
|
|
17
|
+
|
|
18
|
+
== Building from source
|
|
5
19
|
|
|
6
20
|
To build and run the tests:
|
|
7
21
|
ruby setup.rb config
|
|
@@ -11,16 +25,195 @@ Or, if you are on ruby 1.9 (or another version of ruby that doesn't have
|
|
|
11
25
|
pre-parsed ruby source included in the distribution), you'll need to
|
|
12
26
|
pass a special command-line option in the config step so the build
|
|
13
27
|
scripts can find ruby's source code:
|
|
28
|
+
|
|
14
29
|
ruby setup.rb config --ruby-source-path=/path/to/ruby
|
|
15
30
|
ruby setup.rb setup
|
|
16
31
|
|
|
17
32
|
To install:
|
|
18
33
|
ruby install.rb install
|
|
19
34
|
|
|
20
|
-
|
|
21
|
-
|
|
35
|
+
== Sample code
|
|
36
|
+
|
|
37
|
+
This will dump the class Foo (including its instance methods, class variables,
|
|
38
|
+
etc.) and re-load it:
|
|
39
|
+
|
|
40
|
+
:include: sample/dump_class.rb
|
|
41
|
+
|
|
42
|
+
== Ruby-internal and irb
|
|
43
|
+
|
|
44
|
+
Ruby-internal is very useful as a tool for digging into the internals of Ruby
|
|
45
|
+
and figuring out what the interpreter is doing with your code. To use
|
|
46
|
+
ruby-internal with irb, put the following in your .irbrc:
|
|
47
|
+
|
|
48
|
+
:include: sample/irbrc
|
|
49
|
+
|
|
50
|
+
Now you can print node trees:
|
|
51
|
+
|
|
52
|
+
irb(main):001:0> pp (proc { 1 + 1 }.body)
|
|
53
|
+
NODE_NEWLINE at (irb):1
|
|
54
|
+
|-nth = 1
|
|
55
|
+
+-next = NODE_CALL at (irb):1
|
|
56
|
+
|-recv = NODE_LIT at (irb):1
|
|
57
|
+
| +-lit = 1
|
|
58
|
+
|-args = NODE_ARRAY at (irb):1
|
|
59
|
+
| |-alen = 1
|
|
60
|
+
| |-head = NODE_LIT at (irb):1
|
|
61
|
+
| | +-lit = 1
|
|
62
|
+
| +-next = false
|
|
63
|
+
+-mid = :+
|
|
64
|
+
=> nil
|
|
65
|
+
|
|
66
|
+
And view class hierarchies:
|
|
67
|
+
|
|
68
|
+
irb(main):004:0> puts Object.new.classtree
|
|
69
|
+
#<Object:0x40330ce8>
|
|
70
|
+
+-class = Object
|
|
71
|
+
|-class = #<Class:Object>
|
|
72
|
+
| |-class = Class
|
|
73
|
+
| | |-class = #<Class:Class>
|
|
74
|
+
| | | |-class = #<Class:Class> (*)
|
|
75
|
+
| | | +-super = #<Class:Module>
|
|
76
|
+
| | | |-class = Class (*)
|
|
77
|
+
| | | +-super = #<Class:Object> (*)
|
|
78
|
+
| | +-super = Module
|
|
79
|
+
| | |-class = #<Class:Module> (*)
|
|
80
|
+
| | +-super = Object (*)
|
|
81
|
+
| +-super = Class (*)
|
|
82
|
+
+-super = #<PP::ObjectMixin?:0x40349568>
|
|
83
|
+
+-class = PP::ObjectMixin?
|
|
84
|
+
|-class = Module (*)
|
|
85
|
+
+-super = #<Kernel:0x4033507c>
|
|
86
|
+
+-class = Kernel
|
|
87
|
+
=> nil
|
|
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
|
+
== YARV support
|
|
22
127
|
|
|
23
|
-
|
|
128
|
+
Yes, ruby-internal works with YARV, too. The difference when using YARV
|
|
129
|
+
is that sometimes you have nodes, and sometimes you have instruction
|
|
130
|
+
sequences. So whereas pre-YARV you would have a pure AST, with YARV you
|
|
131
|
+
get structures that look like this:
|
|
132
|
+
|
|
133
|
+
irb(main):001:0> def foo; 1 + 1; end
|
|
134
|
+
=> nil
|
|
135
|
+
irb(main):002:0> pp method(:foo).body
|
|
136
|
+
NODE_METHOD at (irb):1
|
|
137
|
+
|-noex = PUBLIC
|
|
138
|
+
|-body = <ISeq:foo@(irb)>
|
|
139
|
+
| |-0000 trace 8
|
|
140
|
+
| |-0002 trace 1
|
|
141
|
+
| |-0004 putobject 1
|
|
142
|
+
| |-0006 putobject 1
|
|
143
|
+
| |-0008 opt_plus
|
|
144
|
+
| |-0009 trace 16
|
|
145
|
+
| +-0011 leave
|
|
146
|
+
+-cnt = 0
|
|
147
|
+
|
|
148
|
+
You can also access the original AST with Node.compile:
|
|
149
|
+
|
|
150
|
+
irb(main):001:0> n = Node.compile_string('1+1')
|
|
151
|
+
=> #>Node::SCOPE:0x40420af0>
|
|
152
|
+
irb(main):002:0> pp n
|
|
153
|
+
NODE_SCOPE at (compiled):1
|
|
154
|
+
|-rval = NODE_CALL at (compiled):1
|
|
155
|
+
| |-recv = NODE_LIT at (compiled):1
|
|
156
|
+
| | +-lit = 1
|
|
157
|
+
| |-args = NODE_ARRAY at (compiled):1
|
|
158
|
+
| | |-alen = 1
|
|
159
|
+
| | |-head = NODE_LIT at (compiled):1
|
|
160
|
+
| | | +-lit = 1
|
|
161
|
+
| | +-next = false
|
|
162
|
+
| +-mid = :+
|
|
163
|
+
|-tbl = nil
|
|
164
|
+
+-next = false
|
|
165
|
+
|
|
166
|
+
compile it to a bytecode sequence:
|
|
167
|
+
|
|
168
|
+
irb(main):003:0> is = n.bytecode_compile()
|
|
169
|
+
=> <ISeq:<main>@(compiled)>
|
|
170
|
+
irb(main):004:0> puts is.disasm
|
|
171
|
+
== disasm: >ISeq:>main>@(compiled)>=====================================
|
|
172
|
+
0000 trace 1 ( 1)
|
|
173
|
+
0002 putobject 1
|
|
174
|
+
0004 putobject 1
|
|
175
|
+
0006 opt_plus
|
|
176
|
+
0007 leave
|
|
177
|
+
=> nil
|
|
178
|
+
|
|
179
|
+
iterate over the bytecode sequence:
|
|
180
|
+
|
|
181
|
+
irb(main):004:0> is.each { |i| puts "#{i.inspect} #{i.length} #{i.operand_types.inspect}" }
|
|
182
|
+
#<VM::Instruction::TRACE:0x40412324 @operands=[1]> 2 [:num]
|
|
183
|
+
#<VM::Instruction::PUTOBJECT:0x404121d0 @operands=[1]> 2 [:value]
|
|
184
|
+
#<VM::Instruction::PUTOBJECT:0x4041207c @operands=[1]> 2 [:value]
|
|
185
|
+
#<VM::Instruction::OPT_PLUS:0x40411f28 @operands=[]> 1 []
|
|
186
|
+
#<VM::Instruction::LEAVE:0x40411e24 @operands=[]> 1 []
|
|
187
|
+
=> nil
|
|
188
|
+
|
|
189
|
+
then decompile it:
|
|
190
|
+
|
|
191
|
+
irb(main):005:0> require 'as_expression'
|
|
192
|
+
=> true
|
|
193
|
+
irb(main):006:0> is.as_expression
|
|
194
|
+
=> "1 + 1"
|
|
195
|
+
|
|
196
|
+
There are still a few missing features (particularly in the decompiler),
|
|
197
|
+
but expect to see more exciting tools for working with bytecode in the
|
|
198
|
+
future!
|
|
199
|
+
|
|
200
|
+
== Other tools
|
|
201
|
+
|
|
202
|
+
Ruby-internal comes with two useful tools, nwdump and nwobfusc. The
|
|
203
|
+
nwdump tool works in much the same way as the older Pragmatic nodedump
|
|
204
|
+
tool. If you require it from the command line:
|
|
205
|
+
|
|
206
|
+
$ ruby -rinternal/node/dump test.rb
|
|
207
|
+
|
|
208
|
+
it will dump your program's syntax tree. The nwobfusc tool is similar:
|
|
209
|
+
|
|
210
|
+
$ ruby -rinternal/obfusc test.rb > test2.rb
|
|
211
|
+
|
|
212
|
+
but its output is an obfuscated version of your program. The program
|
|
213
|
+
must be run on the same version of both ruby-internal and the
|
|
214
|
+
interpreter.
|
|
215
|
+
|
|
216
|
+
== Some notes about security
|
|
24
217
|
|
|
25
218
|
- Data can always be inspected.
|
|
26
219
|
- Methods that could potentially cause a crash if used incorrectly are
|
|
@@ -29,3 +222,8 @@ Some notes about security:
|
|
|
29
222
|
disallowed with $SAFE >= 4.
|
|
30
223
|
- Methods that load marshalled data do taint checks with $SAFE >= 1.
|
|
31
224
|
|
|
225
|
+
== Future directions
|
|
226
|
+
|
|
227
|
+
* Load/dump the state of the ruby interpreter
|
|
228
|
+
* Manipulate the AST/bytecode on-the-fly
|
|
229
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#ifndef ruby_internal_block__h_
|
|
2
|
+
#define ruby_internal_block__h_
|
|
3
|
+
|
|
4
|
+
#include <ruby.h>
|
|
5
|
+
|
|
6
|
+
#ifndef RUBY_VM
|
|
7
|
+
#include "env.h"
|
|
8
|
+
#endif
|
|
9
|
+
|
|
10
|
+
struct BLOCKTAG {
|
|
11
|
+
struct RBasic super;
|
|
12
|
+
long dst;
|
|
13
|
+
long flags;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
struct BLOCK {
|
|
17
|
+
NODE *var;
|
|
18
|
+
NODE *body;
|
|
19
|
+
VALUE self;
|
|
20
|
+
struct FRAME frame;
|
|
21
|
+
struct SCOPE *scope;
|
|
22
|
+
struct BLOCKTAG *tag;
|
|
23
|
+
VALUE klass;
|
|
24
|
+
int iter;
|
|
25
|
+
int vmode;
|
|
26
|
+
int flags;
|
|
27
|
+
struct RVarmap *dyna_vars;
|
|
28
|
+
VALUE orig_thread;
|
|
29
|
+
VALUE wrapper;
|
|
30
|
+
struct BLOCK *prev;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
#endif
|
|
35
|
+
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#ifndef ruby_internal_method__h_
|
|
2
|
+
#define ruby_internal_method__h_
|
|
3
|
+
|
|
4
|
+
#include <ruby.h>
|
|
5
|
+
|
|
6
|
+
#include "internal/node/ruby_internal_node.h"
|
|
7
|
+
|
|
8
|
+
struct METHOD {
|
|
9
|
+
VALUE klass, oklass;
|
|
10
|
+
VALUE recv;
|
|
11
|
+
ID id, oid;
|
|
12
|
+
NODE *body;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
#define METHOD_OCLASS(m) m->klass
|
|
16
|
+
#define METHOD_RCLASS(m) m->klass
|
|
17
|
+
|
|
18
|
+
#endif
|
|
19
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#ifndef ruby_internal_block__h_
|
|
2
|
+
#define ruby_internal_block__h_
|
|
3
|
+
|
|
4
|
+
#include <ruby.h>
|
|
5
|
+
|
|
6
|
+
#ifndef RUBY_VM
|
|
7
|
+
#include "env.h"
|
|
8
|
+
#endif
|
|
9
|
+
|
|
10
|
+
struct BLOCKTAG {
|
|
11
|
+
struct RBasic super;
|
|
12
|
+
long dst;
|
|
13
|
+
long flags;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
struct BLOCK {
|
|
17
|
+
NODE *var;
|
|
18
|
+
NODE *body;
|
|
19
|
+
VALUE self;
|
|
20
|
+
struct FRAME frame;
|
|
21
|
+
struct SCOPE *scope;
|
|
22
|
+
struct BLOCKTAG *tag;
|
|
23
|
+
VALUE klass;
|
|
24
|
+
int iter;
|
|
25
|
+
int vmode;
|
|
26
|
+
int flags;
|
|
27
|
+
struct RVarmap *dyna_vars;
|
|
28
|
+
VALUE orig_thread;
|
|
29
|
+
VALUE wrapper;
|
|
30
|
+
struct BLOCK *prev;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
#endif
|
|
35
|
+
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
#include "node_type_descrip.h"
|
|
2
|
+
#include "version.h"
|
|
3
|
+
|
|
4
|
+
Node_Type_Descrip node_type_descrips_unsorted[] = {
|
|
5
|
+
{ NODE_ALIAS, NEN_1ST, NEN_2ND, NEN_NONE, "ALIAS" },
|
|
6
|
+
#ifdef HAVE_NODE_ALLOCA
|
|
7
|
+
{ NODE_ALLOCA, NEN_CFNC, NEN_VALUE, NEN_CNT, "ALLOCA" },
|
|
8
|
+
#endif
|
|
9
|
+
{ NODE_AND, NEN_1ST, NEN_2ND, NEN_NONE, "AND" },
|
|
10
|
+
{ NODE_ARGS, NEN_REST, NEN_OPT, NEN_CNT, "ARGS" },
|
|
11
|
+
{ NODE_ARGSCAT, NEN_HEAD, NEN_BODY, NEN_NONE, "ARGSCAT" },
|
|
12
|
+
{ NODE_ARGSPUSH, NEN_HEAD, NEN_BODY, NEN_NONE, "ARGSPUSH" },
|
|
13
|
+
{ NODE_ARRAY, NEN_HEAD, NEN_ALEN, NEN_NEXT, "ARRAY" },
|
|
14
|
+
{ NODE_ATTRSET, NEN_VID, NEN_NONE, NEN_NONE, "ATTRSET" },
|
|
15
|
+
{ NODE_BACK_REF, NEN_NTH, NEN_CNT, NEN_NONE, "BACK_REF" },
|
|
16
|
+
{ NODE_BEGIN, NEN_BODY, NEN_NONE, NEN_NONE, "BEGIN" },
|
|
17
|
+
{ NODE_BLOCK, NEN_HEAD, NEN_NEXT, NEN_NONE, "BLOCK" },
|
|
18
|
+
{ NODE_BLOCK_ARG, NEN_CNT, NEN_NONE, NEN_NONE, "BLOCK_ARG" },
|
|
19
|
+
{ NODE_BLOCK_PASS, NEN_BODY, NEN_ITER, NEN_NONE, "BLOCK_PASS" },
|
|
20
|
+
{ NODE_BMETHOD, NEN_CVAL, NEN_NONE, NEN_NONE, "BMETHOD" },
|
|
21
|
+
{ NODE_BREAK, NEN_STTS, NEN_NONE, NEN_NONE, "BREAK" },
|
|
22
|
+
{ NODE_CALL, NEN_ARGS, NEN_MID, NEN_RECV, "CALL" },
|
|
23
|
+
{ NODE_CASE, NEN_HEAD, NEN_BODY, NEN_NEXT, "CASE" },
|
|
24
|
+
{ NODE_CDECL, NEN_VALUE, NEN_VID, NEN_NONE, "CDECL" },
|
|
25
|
+
{ NODE_CFUNC, NEN_CFNC, NEN_ARGC, NEN_NONE, "CFUNC" },
|
|
26
|
+
{ NODE_CLASS, NEN_BODY, NEN_CNAME, NEN_SUPER, "CLASS" },
|
|
27
|
+
{ NODE_COLON2, NEN_HEAD, NEN_MID, NEN_NONE, "COLON2" },
|
|
28
|
+
{ NODE_COLON3, NEN_MID, NEN_NONE, NEN_NONE, "COLON3" },
|
|
29
|
+
{ NODE_CONST, NEN_VID, NEN_NONE, NEN_NONE, "CONST" },
|
|
30
|
+
{ NODE_CREF, NEN_BODY, NEN_NEXT, NEN_CLSS, "CREF" },
|
|
31
|
+
{ NODE_CVAR, NEN_VID, NEN_NONE, NEN_NONE, "CVAR" },
|
|
32
|
+
{ NODE_CVASGN, NEN_VALUE, NEN_VID, NEN_NONE, "CVASGN" },
|
|
33
|
+
{ NODE_CVDECL, NEN_VALUE, NEN_VID, NEN_NONE, "CVDECL" },
|
|
34
|
+
{ NODE_DASGN, NEN_VALUE, NEN_VID, NEN_NONE, "DASGN" },
|
|
35
|
+
{ NODE_DASGN_CURR, NEN_VALUE, NEN_VID, NEN_NONE, "DASGN_CURR" },
|
|
36
|
+
{ NODE_DEFINED, NEN_HEAD, NEN_NONE, NEN_NONE, "DEFINED" },
|
|
37
|
+
{ NODE_DEFN, NEN_DEFN, NEN_MID, NEN_NOEX, "DEFN" },
|
|
38
|
+
{ NODE_DEFS, NEN_DEFN, NEN_MID, NEN_RECV, "DEFS" },
|
|
39
|
+
{ NODE_DMETHOD, NEN_CVAL, NEN_NONE, NEN_NONE, "DMETHOD" },
|
|
40
|
+
{ NODE_DOT2, NEN_BEG, NEN_END, NEN_STATE, "DOT2" },
|
|
41
|
+
{ NODE_DOT3, NEN_BEG, NEN_END, NEN_STATE, "DOT3" },
|
|
42
|
+
{ NODE_DREGX, NEN_LIT, NEN_CFLAG, NEN_NEXT, "DREGX" },
|
|
43
|
+
{ NODE_DREGX_ONCE, NEN_LIT, NEN_CFLAG, NEN_NEXT, "DREGX_ONCE" },
|
|
44
|
+
{ NODE_DSTR, NEN_LIT, NEN_NEXT, NEN_NONE, "DSTR" },
|
|
45
|
+
{ NODE_DVAR, NEN_VID, NEN_NONE, NEN_NONE, "DVAR" },
|
|
46
|
+
{ NODE_DXSTR, NEN_LIT, NEN_NEXT, NEN_NONE, "DXSTR" },
|
|
47
|
+
{ NODE_ENSURE, NEN_HEAD, NEN_ENSR, NEN_NONE, "ENSURE" },
|
|
48
|
+
{ NODE_EVSTR, NEN_LIT, NEN_NONE, NEN_NONE, "EVSTR" },
|
|
49
|
+
{ NODE_FALSE, NEN_NONE, NEN_NONE, NEN_NONE, "FALSE" },
|
|
50
|
+
{ NODE_FBODY, NEN_HEAD, NEN_ORIG, NEN_MID, "FBODY" },
|
|
51
|
+
{ NODE_FCALL, NEN_ARGS, NEN_MID, NEN_NONE, "FCALL" },
|
|
52
|
+
{ NODE_FLIP2, NEN_BEG, NEN_END, NEN_CNT, "FLIP2" },
|
|
53
|
+
{ NODE_FLIP3, NEN_BEG, NEN_END, NEN_CNT, "FLIP3" },
|
|
54
|
+
{ NODE_FOR, NEN_BODY, NEN_ITER, NEN_VAR, "FOR" },
|
|
55
|
+
{ NODE_GASGN, NEN_VALUE, NEN_VID, NEN_ENTRY, "GASGN" },
|
|
56
|
+
{ NODE_GVAR, NEN_VID, NEN_ENTRY, NEN_NONE, "GVAR" },
|
|
57
|
+
{ NODE_HASH, NEN_HEAD, NEN_NONE, NEN_NONE, "HASH" },
|
|
58
|
+
{ NODE_IASGN, NEN_VALUE, NEN_VID, NEN_NONE, "IASGN" },
|
|
59
|
+
{ NODE_IF, NEN_COND, NEN_BODY, NEN_ELSE, "IF" },
|
|
60
|
+
{ NODE_IFUNC, NEN_CFNC, NEN_TVAL, NEN_STATE, "IFUNC" },
|
|
61
|
+
{ NODE_ITER, NEN_BODY, NEN_ITER, NEN_VAR, "ITER" },
|
|
62
|
+
{ NODE_IVAR, NEN_VID, NEN_NONE, NEN_NONE, "IVAR" },
|
|
63
|
+
{ NODE_LASGN, NEN_VALUE, NEN_VID, NEN_CNT, "LASGN" },
|
|
64
|
+
{ NODE_LIT, NEN_LIT, NEN_NONE, NEN_NONE, "LIT" },
|
|
65
|
+
{ NODE_LVAR, NEN_VID, NEN_CNT, NEN_NONE, "LVAR" },
|
|
66
|
+
{ NODE_MASGN, NEN_ARGS, NEN_HEAD, NEN_VALUE, "MASGN" },
|
|
67
|
+
{ NODE_MATCH, NEN_HEAD, NEN_VALUE, NEN_NONE, "MATCH" },
|
|
68
|
+
{ NODE_MATCH2, NEN_VALUE, NEN_RECV, NEN_NONE, "MATCH2" },
|
|
69
|
+
{ NODE_MATCH3, NEN_VALUE, NEN_RECV, NEN_NONE, "MATCH3" },
|
|
70
|
+
{ NODE_MEMO, NEN_NONE, NEN_NONE, NEN_NONE, "MEMO" },
|
|
71
|
+
{ NODE_METHOD, NEN_BODY, NEN_NOEX, NEN_NONE, "METHOD" },
|
|
72
|
+
{ NODE_MODULE, NEN_BODY, NEN_CNAME, NEN_NONE, "MODULE" },
|
|
73
|
+
{ NODE_NEWLINE, NEN_NEXT, NEN_NONE, NEN_NONE, "NEWLINE" },
|
|
74
|
+
{ NODE_NEXT, NEN_STTS, NEN_NONE, NEN_NONE, "NEXT" },
|
|
75
|
+
{ NODE_NIL, NEN_NONE, NEN_NONE, NEN_NONE, "NIL" },
|
|
76
|
+
{ NODE_NOT, NEN_BODY, NEN_NONE, NEN_NONE, "NOT" },
|
|
77
|
+
{ NODE_NTH_REF, NEN_NTH, NEN_CNT, NEN_NONE, "NTH_REF" },
|
|
78
|
+
{ NODE_OPT_N, NEN_BODY, NEN_NONE, NEN_NONE, "OPT_N" },
|
|
79
|
+
{ NODE_OP_ASGN1, NEN_ARGS, NEN_MID, NEN_RECV, "OP_ASGN1" },
|
|
80
|
+
{ NODE_OP_ASGN2, NEN_VALUE, NEN_NEXT, NEN_RECV, "OP_ASGN2" },
|
|
81
|
+
{ NODE_OP_ASGN2_ARG, NEN_VID, NEN_AID, NEN_MID, "OP_ASGN2_ARG" },
|
|
82
|
+
{ NODE_OP_ASGN_AND, NEN_VALUE, NEN_RECV, NEN_NONE, "OP_ASGN_AND" },
|
|
83
|
+
{ NODE_OP_ASGN_OR, NEN_AID, NEN_VALUE, NEN_RECV, "OP_ASGN_OR" },
|
|
84
|
+
{ NODE_OR, NEN_1ST, NEN_2ND, NEN_NONE, "OR" },
|
|
85
|
+
{ NODE_POSTEXE, NEN_NONE, NEN_NONE, NEN_NONE, "POSTEXE" },
|
|
86
|
+
{ NODE_REDO, NEN_NONE, NEN_NONE, NEN_NONE, "REDO" },
|
|
87
|
+
{ NODE_RESBODY, NEN_HEAD, NEN_ARGS, NEN_BODY, "RESBODY" },
|
|
88
|
+
{ NODE_RESCUE, NEN_HEAD, NEN_ELSE, NEN_RESQ, "RESCUE" },
|
|
89
|
+
{ NODE_RETRY, NEN_NONE, NEN_NONE, NEN_NONE, "RETRY" },
|
|
90
|
+
{ NODE_RETURN, NEN_STTS, NEN_NONE, NEN_NONE, "RETURN" },
|
|
91
|
+
{ NODE_SCLASS, NEN_BODY, NEN_RECV, NEN_NONE, "SCLASS" },
|
|
92
|
+
{ NODE_SCOPE, NEN_TBL, NEN_RVAL, NEN_NEXT, "SCOPE" },
|
|
93
|
+
{ NODE_SELF, NEN_NONE, NEN_NONE, NEN_NONE, "SELF" },
|
|
94
|
+
{ NODE_STR, NEN_LIT, NEN_NONE, NEN_NONE, "STR" },
|
|
95
|
+
{ NODE_SUPER, NEN_ARGS, NEN_NONE, NEN_NONE, "SUPER" },
|
|
96
|
+
{ NODE_TRUE, NEN_NONE, NEN_NONE, NEN_NONE, "TRUE" },
|
|
97
|
+
{ NODE_UNDEF, NEN_MID, NEN_NONE, NEN_NONE, "UNDEF" },
|
|
98
|
+
{ NODE_UNTIL, NEN_BODY, NEN_COND, NEN_STATE, "UNTIL" },
|
|
99
|
+
{ NODE_VALIAS, NEN_1ST, NEN_2ND, NEN_NONE, "VALIAS" },
|
|
100
|
+
{ NODE_VCALL, NEN_MID, NEN_NONE, NEN_NONE, "VCALL" },
|
|
101
|
+
{ NODE_WHEN, NEN_HEAD, NEN_BODY, NEN_NEXT, "WHEN" },
|
|
102
|
+
{ NODE_WHILE, NEN_BODY, NEN_COND, NEN_STATE, "WHILE" },
|
|
103
|
+
{ NODE_XSTR, NEN_LIT, NEN_NONE, NEN_NONE, "XSTR" },
|
|
104
|
+
{ NODE_YIELD, NEN_HEAD, NEN_STATE, NEN_NONE, "YIELD" },
|
|
105
|
+
{ NODE_ZARRAY, NEN_NONE, NEN_NONE, NEN_NONE, "ZARRAY" },
|
|
106
|
+
{ NODE_ZSUPER, NEN_NONE, NEN_NONE, NEN_NONE, "ZSUPER" },
|
|
107
|
+
{ NODE_LAST, NEN_NONE, NEN_NONE, NEN_NONE, "LAST" },
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
static Node_Type_Descrip * node_type_descrips[NUM_NODE_TYPE_DESCRIPS];
|
|
111
|
+
static int node_type_descrips_initialized = 0;
|
|
112
|
+
|
|
113
|
+
static void init_node_type_descrips()
|
|
114
|
+
{
|
|
115
|
+
if(!node_type_descrips_initialized)
|
|
116
|
+
{
|
|
117
|
+
Node_Type_Descrip * descrip;
|
|
118
|
+
memset(node_type_descrips, 0, sizeof(node_type_descrips));
|
|
119
|
+
for(descrip = node_type_descrips_unsorted;
|
|
120
|
+
descrip->nt != NODE_LAST;
|
|
121
|
+
++descrip)
|
|
122
|
+
{
|
|
123
|
+
if(node_type_descrips[descrip->nt])
|
|
124
|
+
{
|
|
125
|
+
rb_raise(rb_eRuntimeError, "duplicate entry for node type %d (%s is also %s)\n", descrip->nt, descrip->name, node_type_descrips[descrip->nt]->name);
|
|
126
|
+
}
|
|
127
|
+
else
|
|
128
|
+
{
|
|
129
|
+
node_type_descrips[descrip->nt] = descrip;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
node_type_descrips_initialized = 1;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/* Given a node, find out the types of the three elements it contains */
|
|
137
|
+
Node_Type_Descrip const * node_type_descrip(enum node_type nt)
|
|
138
|
+
{
|
|
139
|
+
init_node_type_descrips();
|
|
140
|
+
if(node_type_descrips[nt])
|
|
141
|
+
{
|
|
142
|
+
return node_type_descrips[nt];
|
|
143
|
+
}
|
|
144
|
+
else
|
|
145
|
+
{
|
|
146
|
+
rb_raise(rb_eArgError, "Unknown node type %d", nt);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|