ruby-internal 0.6.0 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. data/README +204 -6
  2. data/ext/cached/ruby-1.6.8/internal/binding/block.h +35 -0
  3. data/ext/cached/ruby-1.6.8/internal/method/method.h +19 -0
  4. data/ext/cached/ruby-1.6.8/internal/module/classpath.c +3 -0
  5. data/ext/cached/ruby-1.6.8/internal/module/classpath.h +8 -0
  6. data/ext/cached/ruby-1.6.8/internal/node/block.h +35 -0
  7. data/ext/cached/ruby-1.6.8/internal/node/global_entry.h +15 -0
  8. data/ext/cached/ruby-1.6.8/internal/node/node_type_descrip.c +149 -0
  9. data/ext/cached/ruby-1.6.8/internal/node/nodeinfo.c +5582 -0
  10. data/ext/cached/ruby-1.6.8/internal/node/nodeinfo.h +69 -0
  11. data/ext/cached/ruby-1.6.8/internal/proc/block.h +35 -0
  12. data/ext/cached/ruby-1.6.8/internal/tag/tag.h +15 -0
  13. data/ext/cached/ruby-1.6.8/internal/vm/instruction/insns_info.c +39 -0
  14. data/ext/cached/ruby-1.6.8/internal/vm/instruction/insns_info.h +21 -0
  15. data/ext/cached/ruby-1.6.8/internal/vm/iseq/insns_info.inc +12 -0
  16. data/ext/cached/ruby-1.6.8/internal/vm/iseq/iseq_load.inc +9 -0
  17. data/ext/cached/ruby-1.8.0/internal/node/node_type_descrip.c +91 -91
  18. data/ext/cached/ruby-1.8.0/internal/node/nodeinfo.c +1909 -1909
  19. data/ext/cached/ruby-1.8.0/internal/vm/iseq/iseq_load.inc +9 -0
  20. data/ext/cached/ruby-1.8.1/internal/node/node_type_descrip.c +90 -90
  21. data/ext/cached/ruby-1.8.1/internal/node/nodeinfo.c +1946 -1946
  22. data/ext/cached/ruby-1.8.1/internal/vm/iseq/iseq_load.inc +9 -0
  23. data/ext/cached/ruby-1.8.2/internal/node/node_type_descrip.c +90 -90
  24. data/ext/cached/ruby-1.8.2/internal/node/nodeinfo.c +1946 -1946
  25. data/ext/cached/ruby-1.8.2/internal/vm/iseq/iseq_load.inc +9 -0
  26. data/ext/cached/ruby-1.8.3/internal/node/node_type_descrip.c +90 -90
  27. data/ext/cached/ruby-1.8.3/internal/node/nodeinfo.c +1946 -1946
  28. data/ext/cached/ruby-1.8.3/internal/vm/iseq/iseq_load.inc +9 -0
  29. data/ext/cached/ruby-1.8.4/internal/node/node_type_descrip.c +90 -90
  30. data/ext/cached/ruby-1.8.4/internal/node/nodeinfo.c +1946 -1946
  31. data/ext/cached/ruby-1.8.4/internal/vm/iseq/iseq_load.inc +9 -0
  32. data/ext/cached/ruby-1.8.5/internal/node/node_type_descrip.c +90 -90
  33. data/ext/cached/ruby-1.8.5/internal/node/nodeinfo.c +1909 -1909
  34. data/ext/cached/ruby-1.8.5/internal/vm/iseq/iseq_load.inc +9 -0
  35. data/ext/cached/ruby-1.8.6/internal/node/node_type_descrip.c +90 -90
  36. data/ext/cached/ruby-1.8.6/internal/node/nodeinfo.c +1909 -1909
  37. data/ext/cached/ruby-1.8.6/internal/vm/iseq/iseq_load.inc +9 -0
  38. data/ext/cached/ruby-1.8.7/internal/node/node_type_descrip.c +90 -90
  39. data/ext/cached/ruby-1.8.7/internal/node/nodeinfo.c +1909 -1909
  40. data/ext/cached/ruby-1.8.7/internal/vm/iseq/iseq_load.inc +9 -0
  41. data/ext/cached/ruby-1.9.0/internal/node/node_type_descrip.c +85 -85
  42. data/ext/cached/ruby-1.9.0/internal/node/nodeinfo.c +1800 -1800
  43. data/ext/cached/ruby-1.9.0/internal/vm/iseq/iseq_load.inc +13 -0
  44. data/ext/cached/ruby-1.9.0/internal/yarv-headers/transdb.h +51 -51
  45. data/ext/cached/ruby-1.9.1/internal/node/node_type_descrip.c +85 -85
  46. data/ext/cached/ruby-1.9.1/internal/node/nodeinfo.c +1800 -1800
  47. data/ext/cached/ruby-1.9.1/internal/vm/instruction/insns_info.h +1 -2
  48. data/ext/cached/ruby-1.9.1/internal/vm/iseq/iseq_load.inc +356 -0
  49. data/ext/cached/ruby-1.9.1/internal/yarv-headers/eval_intern.h +15 -9
  50. data/ext/cached/ruby-1.9.1/internal/yarv-headers/id.h +45 -66
  51. data/ext/cached/ruby-1.9.1/internal/yarv-headers/iseq.h +12 -3
  52. data/ext/cached/ruby-1.9.1/internal/yarv-headers/node.h +2 -2
  53. data/ext/cached/ruby-1.9.1/internal/yarv-headers/parse.h +23 -138
  54. data/ext/cached/ruby-1.9.1/internal/yarv-headers/revision.h +1 -1
  55. data/ext/cached/ruby-1.9.1/internal/yarv-headers/transcode_data.h +9 -2
  56. data/ext/cached/ruby-1.9.1/internal/yarv-headers/transdb.h +62 -0
  57. data/ext/cached/ruby-1.9.1/internal/yarv-headers/version.h +17 -23
  58. data/ext/cached/ruby-1.9.1/internal/yarv-headers/vm_core.h +20 -29
  59. data/ext/cached/ruby-1.9.1/internal/yarv-headers/vm_exec.h +4 -7
  60. data/ext/cached/ruby-1.9.1/internal/yarv-headers/vm_insnhelper.h +6 -5
  61. data/ext/internal/module/cfp.h +13 -0
  62. data/ext/internal/module/extconf.rb +2 -2
  63. data/ext/internal/module/module.c +3 -8
  64. data/ext/internal/node/nodes.rb +2 -1
  65. data/ext/internal/vm/iseq/iseq.c +2 -3
  66. data/ext/internal/vm/iseq/iseq_load.inc.rpp +61 -0
  67. data/ext/internal/yarv-headers/debug.h +36 -0
  68. data/ext/internal/yarv-headers/dln.h +41 -0
  69. data/ext/internal/yarv-headers/encdb.h +147 -0
  70. data/ext/internal/yarv-headers/eval_intern.h +215 -0
  71. data/ext/internal/yarv-headers/gc.h +75 -0
  72. data/ext/internal/yarv-headers/id.h +163 -0
  73. data/ext/internal/yarv-headers/iseq.h +103 -0
  74. data/ext/internal/yarv-headers/node.h +516 -0
  75. data/ext/internal/yarv-headers/parse.h +188 -0
  76. data/ext/internal/yarv-headers/regenc.h +207 -0
  77. data/ext/internal/yarv-headers/regint.h +842 -0
  78. data/ext/internal/yarv-headers/regparse.h +351 -0
  79. data/ext/internal/yarv-headers/revision.h +1 -0
  80. data/ext/internal/yarv-headers/thread_pthread.h +24 -0
  81. data/ext/internal/yarv-headers/thread_win32.h +33 -0
  82. data/ext/internal/yarv-headers/transcode_data.h +106 -0
  83. data/ext/internal/yarv-headers/transdb.h +147 -0
  84. data/ext/internal/yarv-headers/version.h +54 -0
  85. data/ext/internal/yarv-headers/vm_core.h +646 -0
  86. data/ext/internal/yarv-headers/vm_exec.h +184 -0
  87. data/ext/internal/yarv-headers/vm_insnhelper.h +195 -0
  88. data/ext/internal/yarv-headers/vm_opts.h +51 -0
  89. data/publish_rdoc.rb +4 -0
  90. metadata +52 -2
data/README CHANGED
@@ -1,7 +1,21 @@
1
- This is ruby-internal, a library that provides access to the internals
2
- of the ruby interpreter.
1
+ Ruby-internal is a Ruby library that provides direct access to Ruby's
2
+ (MRI or YARV) internal data structures.
3
3
 
4
- See the file LICENSE for license and copyright information.
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
- See the generated documentation (in the doc/ directory) and the examples
21
- (in the directory example/) for usage.
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
- Some notes about security:
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,3 @@
1
+ #include "classpath.h"
2
+
3
+
@@ -0,0 +1,8 @@
1
+ #ifndef CLASSPATH_H
2
+ #define CLASSPATH_H
3
+
4
+ #include "ruby.h"
5
+
6
+
7
+ #endif
8
+
@@ -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,15 @@
1
+ #ifndef global_entry__h_
2
+ #define global_entry__h_
3
+
4
+ struct global_entry {
5
+ ID id;
6
+ void *data;
7
+ VALUE (*getter)();
8
+ void (*setter)();
9
+ void (*marker)();
10
+ int block_trace;
11
+ struct trace_var *trace;
12
+ };
13
+
14
+ #endif
15
+
@@ -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
+