node-marshal 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,60 +1,60 @@
1
- #ifndef RUBY_API_VERSION_MAJOR
2
- #error Cannot find Ruby version constants
3
- #endif
4
-
5
- /* Macros that depend on Ruby version */
6
- // Pre-2.0 Ruby versions don't use this version
7
- #if RUBY_API_VERSION_MAJOR == 2
8
- #define USE_RB_ARGS_INFO 1
9
- #endif
10
-
11
- #if RUBY_API_VERSION_MAJOR == 1
12
- #define RESET_GC_FLAGS 1
13
- #endif
14
-
15
-
16
- /* Some constants */
17
- // Magic value with the version of the format
18
- #define NODEMARSHAL_MAGIC "NODEMARSHAL11"
19
- // Type of the node "Child"
20
- #define NT_NULL 0
21
- #define NT_UNKNOWN 1
22
- #define NT_NODE 2
23
- #define NT_VALUE 3
24
- #define NT_ID 4
25
- #define NT_INTEGER 5
26
- #define NT_LONG 5
27
- #define NT_ARGS 6
28
- #define NT_ENTRY 7
29
- #define NT_IDTABLE 8
30
- #define NT_MEMORY 9
31
-
32
- /* Value locations */
33
- #define VL_RAW 0 // Just here
34
- #define VL_NODE 1 // Global table of nodes
35
- #define VL_ID 2 // Global table of identifiers
36
- #define VL_GVAR 3 // Global variables table
37
- #define VL_IDTABLE 4 // Global table of local ID tables
38
- #define VL_ARGS 5 // Global table of arguments info structures
39
- #define VL_LIT 6 // Global table of literals
40
-
41
- /* base85r.c */
42
- void base85r_init_tables();
43
- VALUE base85r_encode(VALUE input);
44
- VALUE base85r_decode(VALUE input);
45
-
46
- /* nodechk.c */
47
- void check_nodes_child_info(int pos);
48
- void init_nodes_table(int *nodes_ctbl, int num_of_entries);
49
-
50
- /* Parts of node.h from Ruby source code */
51
- #if (RUBY_API_VERSION_MAJOR == 2) && (RUBY_API_VERSION_MINOR == 3)
52
- #include "node230.h"
53
- #elif (RUBY_API_VERSION_MAJOR == 2) && (RUBY_API_VERSION_MINOR == 2)
54
- #include "node220.h"
55
- #elif (RUBY_API_VERSION_MAJOR == 1) && (RUBY_API_VERSION_MINOR == 9)
56
- #include "node193.h"
57
- #else
58
- #include "node220.h"
59
- #error Unsupported version of Ruby
60
- #endif
1
+ #ifndef RUBY_API_VERSION_MAJOR
2
+ #error Cannot find Ruby version constants
3
+ #endif
4
+
5
+ /* Macros that depend on Ruby version */
6
+ // Pre-2.0 Ruby versions don't use this version
7
+ #if RUBY_API_VERSION_MAJOR == 2
8
+ #define USE_RB_ARGS_INFO 1
9
+ #endif
10
+
11
+ #if RUBY_API_VERSION_MAJOR == 1
12
+ #define RESET_GC_FLAGS 1
13
+ #endif
14
+
15
+
16
+ /* Some constants */
17
+ // Magic value with the version of the format
18
+ #define NODEMARSHAL_MAGIC "NODEMARSHAL11"
19
+ // Type of the node "Child"
20
+ #define NT_NULL 0
21
+ #define NT_UNKNOWN 1
22
+ #define NT_NODE 2
23
+ #define NT_VALUE 3
24
+ #define NT_ID 4
25
+ #define NT_INTEGER 5
26
+ #define NT_LONG 5
27
+ #define NT_ARGS 6
28
+ #define NT_ENTRY 7
29
+ #define NT_IDTABLE 8
30
+ #define NT_MEMORY 9
31
+
32
+ /* Value locations */
33
+ #define VL_RAW 0 // Just here
34
+ #define VL_NODE 1 // Global table of nodes
35
+ #define VL_ID 2 // Global table of identifiers
36
+ #define VL_GVAR 3 // Global variables table
37
+ #define VL_IDTABLE 4 // Global table of local ID tables
38
+ #define VL_ARGS 5 // Global table of arguments info structures
39
+ #define VL_LIT 6 // Global table of literals
40
+
41
+ /* base85r.c */
42
+ void base85r_init_tables();
43
+ VALUE base85r_encode(VALUE input);
44
+ VALUE base85r_decode(VALUE input);
45
+
46
+ /* nodechk.c */
47
+ void check_nodes_child_info(int pos);
48
+ void init_nodes_table(int *nodes_ctbl, int num_of_entries);
49
+
50
+ /* Parts of node.h from Ruby source code */
51
+ #if (RUBY_API_VERSION_MAJOR == 2) && (RUBY_API_VERSION_MINOR == 3)
52
+ #include "node230.h"
53
+ #elif (RUBY_API_VERSION_MAJOR == 2) && (RUBY_API_VERSION_MINOR == 2)
54
+ #include "node220.h"
55
+ #elif (RUBY_API_VERSION_MAJOR == 1) && (RUBY_API_VERSION_MINOR == 9)
56
+ #include "node193.h"
57
+ #else
58
+ #include "node220.h"
59
+ #error Unsupported version of Ruby
60
+ #endif
@@ -1,615 +1,619 @@
1
- /*
2
- * This file contains information about Ruby nodes
3
- * Supported Ruby versions:
4
- * - Ruby 1.9.3
5
- * - Ruby 2.2.1
6
- * - Ruby 2.3.0
7
- *
8
- * Fragments from Ruby source code are used here
9
- * (mainly from node.c, gc.c)
10
- *
11
- * License: BSD-2-Clause
12
- *
13
- */
14
- #include <stdio.h>
15
- #include <stdlib.h>
16
- #include <inttypes.h>
17
- #include <ruby.h>
18
- #include <ruby/version.h>
19
- #include "nodedump.h"
20
-
21
- /* Information about nodes types
22
-
23
- NODE_ARRAY contains an undocumented feature: if an array contains
24
- more than 1 element the 2nd child of 2nd element will contain
25
- a reference to the last element of the array (and have NT_NODE
26
- not NT_LONG type)
27
- Another case is Hash: every 2nd element of NODE_ARRAY chain
28
- has NT_NODE type (see nodedump.c for details)
29
-
30
- Such child is ignored by GC because there is a reference to it
31
- from another place of Ruby AST.
32
- */
33
- static int nodes_child_info[][4] =
34
- {
35
- {NODE_BLOCK, NT_NODE, NT_NULL, NT_NODE},
36
- {NODE_IF, NT_NODE, NT_NODE, NT_NODE},
37
-
38
- {NODE_CASE, NT_NODE, NT_NODE, NT_NULL},
39
- {NODE_WHEN, NT_NODE, NT_NODE, NT_NODE},
40
-
41
- {NODE_OPT_N, NT_NULL, NT_NODE, NT_LONG}, // ???
42
- {NODE_WHILE, NT_NODE, NT_NODE, NT_LONG},
43
- {NODE_UNTIL, NT_NODE, NT_NODE, NT_LONG},
44
-
45
- {NODE_ITER, NT_VALUE, NT_NODE, NT_NODE}, // ???
46
- {NODE_FOR, NT_VALUE, NT_NODE, NT_NODE},
47
-
48
- {NODE_BREAK, NT_NODE, NT_NULL, NT_NULL},
49
- {NODE_NEXT, NT_NODE, NT_NULL, NT_NULL},
50
- {NODE_RETURN, NT_NODE, NT_NULL, NT_NULL},
51
-
52
- {NODE_REDO, NT_NULL, NT_NULL, NT_NULL},
53
- {NODE_RETRY, NT_NULL, NT_NULL, NT_NULL},
54
-
55
- {NODE_BEGIN, NT_NULL, NT_NODE, NT_NULL},
56
-
57
- {NODE_RESCUE, NT_NODE, NT_NODE, NT_NODE},
58
- {NODE_RESBODY, NT_NODE, NT_NODE, NT_NODE},
59
- {NODE_ENSURE, NT_NODE, NT_NULL, NT_NODE},
60
-
61
- {NODE_AND, NT_NODE, NT_NODE, NT_NULL},
62
- {NODE_OR, NT_NODE, NT_NODE, NT_NULL},
63
-
64
- {NODE_MASGN, NT_NODE, NT_NODE, NT_NODE},
65
-
66
- {NODE_LASGN, NT_ID, NT_NODE, NT_NULL},
67
- {NODE_DASGN, NT_ID, NT_NODE, NT_NULL},
68
- {NODE_DASGN_CURR, NT_ID, NT_NODE, NT_NULL},
69
- {NODE_IASGN, NT_ID, NT_NODE, NT_NULL},
70
- {NODE_CVASGN, NT_ID, NT_NODE, NT_NULL},
71
-
72
- {NODE_GASGN, NT_NULL, NT_NODE, NT_ENTRY},
73
-
74
- {NODE_CDECL, NT_ID, NT_NODE, NT_NODE},
75
-
76
- {NODE_OP_ASGN1, NT_NODE, NT_ID, NT_NODE},
77
- {NODE_OP_ASGN2, NT_NODE, NT_NODE, NT_NODE},
78
-
79
- {NODE_OP_ASGN_AND, NT_NODE, NT_NODE, NT_NULL},
80
- {NODE_OP_ASGN_OR, NT_NODE, NT_NODE, NT_NULL},
81
-
82
- {NODE_CALL, NT_NODE, NT_ID, NT_NODE},
83
- {NODE_FCALL, NT_NULL, NT_ID, NT_NODE},
84
- {NODE_VCALL, NT_NULL, NT_ID, NT_NULL},
85
- #ifdef NODE_QCALL
86
- {NODE_QCALL, NT_NODE, NT_ID, NT_NODE}, /* &. operator from Ruby 2.3 */
87
- #endif
88
-
89
- {NODE_SUPER, NT_NULL, NT_NULL, NT_NODE},
90
- {NODE_ZSUPER, NT_NULL, NT_NULL, NT_NULL},
91
- {NODE_ARRAY, NT_NODE, NT_LONG, NT_NODE}, /* 2nd child has undocumented variants (see above) */
92
- {NODE_VALUES, NT_NODE, NT_LONG, NT_NODE},
93
- {NODE_ZARRAY, NT_NULL, NT_NULL, NT_NULL},
94
-
95
- {NODE_HASH, NT_NODE, NT_NULL, NT_NULL},
96
- {NODE_YIELD, NT_NODE, NT_NULL, NT_NULL},
97
-
98
- {NODE_LVAR, NT_ID, NT_NULL, NT_NULL},
99
- {NODE_DVAR, NT_ID, NT_NULL, NT_NULL},
100
- {NODE_IVAR, NT_ID, NT_NULL, NT_NULL},
101
- {NODE_CONST, NT_ID, NT_NULL, NT_NULL},
102
- {NODE_CVAR, NT_ID, NT_NULL, NT_NULL},
103
-
104
- {NODE_GVAR, NT_NULL, NT_NULL, NT_ENTRY},
105
-
106
- {NODE_NTH_REF, NT_NULL, NT_LONG, NT_NULL},
107
- {NODE_BACK_REF, NT_NULL, NT_LONG, NT_LONG},
108
-
109
- {NODE_MATCH, NT_VALUE, NT_NULL, NT_NULL},
110
- {NODE_MATCH2, NT_NODE, NT_NODE, NT_NULL},
111
- {NODE_MATCH3, NT_NODE, NT_NODE, NT_NULL},
112
-
113
- {NODE_LIT, NT_VALUE, NT_NULL, NT_NULL},
114
- {NODE_STR, NT_VALUE, NT_NULL, NT_NULL},
115
- {NODE_XSTR, NT_VALUE, NT_NULL, NT_NULL},
116
-
117
- {NODE_DSTR, NT_VALUE, NT_NULL, NT_NODE},
118
- {NODE_DXSTR, NT_VALUE, NT_NULL, NT_NODE},
119
- {NODE_DREGX, NT_VALUE, NT_NULL, NT_NODE},
120
- {NODE_DREGX_ONCE, NT_VALUE, NT_NULL, NT_NODE},
121
- {NODE_DSYM, NT_VALUE, NT_NULL, NT_NODE},
122
-
123
- {NODE_EVSTR, NT_NULL, NT_NODE, NT_NULL},
124
-
125
- {NODE_ARGSCAT, NT_NODE, NT_NODE, NT_NULL},
126
- {NODE_ARGSPUSH, NT_NODE, NT_NODE, NT_NULL},
127
- {NODE_SPLAT, NT_NODE, NT_NULL, NT_NULL},
128
- {NODE_BLOCK_PASS, NT_NODE, NT_NODE, NT_NODE}, // ???
129
-
130
- {NODE_DEFN, NT_NULL, NT_ID, NT_NODE},
131
- {NODE_DEFS, NT_NODE, NT_ID, NT_NODE},
132
- {NODE_ALIAS, NT_NODE, NT_NODE, NT_NULL},
133
- {NODE_VALIAS, NT_ID, NT_ID, NT_NULL},
134
- {NODE_UNDEF, NT_NULL, NT_NODE, NT_NULL},
135
-
136
- {NODE_CLASS, NT_NODE, NT_NODE, NT_NODE},
137
- {NODE_MODULE, NT_NODE, NT_NODE, NT_NULL},
138
- {NODE_SCLASS, NT_NODE, NT_NODE, NT_NULL},
139
-
140
- {NODE_COLON2, NT_NODE, NT_ID, NT_NULL},
141
- {NODE_COLON3, NT_NULL, NT_ID, NT_NULL},
142
-
143
- {NODE_DOT2, NT_NODE, NT_NODE, NT_NULL},
144
- {NODE_DOT3, NT_NODE, NT_NODE, NT_NULL},
145
- {NODE_FLIP2, NT_NODE, NT_NODE, NT_NULL},
146
- {NODE_FLIP3, NT_NODE, NT_NODE, NT_NULL},
147
-
148
- {NODE_SELF, NT_NULL, NT_NULL, NT_NULL},
149
- {NODE_NIL, NT_NULL, NT_NULL, NT_NULL},
150
- {NODE_TRUE, NT_NULL, NT_NULL, NT_NULL},
151
- {NODE_FALSE, NT_NULL, NT_NULL, NT_NULL},
152
- {NODE_ERRINFO, NT_NULL, NT_NULL, NT_NULL},
153
-
154
- {NODE_DEFINED, NT_NODE, NT_NULL, NT_NULL},
155
-
156
- {NODE_POSTEXE, NT_NULL, NT_NODE, NT_NULL},
157
- {NODE_ATTRASGN, NT_NODE, NT_ID, NT_NODE},
158
- {NODE_PRELUDE, NT_NODE, NT_NODE, NT_NULL},
159
-
160
- {NODE_LAMBDA, NT_NULL, NT_NODE, NT_NULL},
161
-
162
- {NODE_OPT_ARG, NT_NULL, NT_NODE, NT_NODE},
163
- {NODE_POSTARG, NT_NODE, NT_NODE, NT_NULL},
164
-
165
- #ifdef USE_RB_ARGS_INFO
166
- {NODE_ARGS, NT_NULL, NT_VALUE, NT_ARGS}, // ???
167
- #else
168
- {NODE_ARGS, NT_NODE, NT_NULL, NT_NODE}, // ???
169
- #endif
170
- {NODE_SCOPE, NT_IDTABLE, NT_NODE, NT_NODE},
171
-
172
- {NODE_ARGS_AUX, NT_LONG, NT_LONG, NT_NODE},
173
-
174
- {-1, 0, 0, 0}
175
- };
176
-
177
-
178
-
179
- /*
180
- * Check the correctness of nodes table from the viewpoint
181
- * This function is based on Ruby source code (node.c)
182
- */
183
- void check_nodes_child_info(int pos)
184
- {
185
- int type = nodes_child_info[pos][0];
186
- int isval[3] = {0, 0, 0};
187
- int isval_tbl[3] = {1, 1, 1};
188
- int i;
189
- /* Check NODE_LAMBDA position */
190
- if (strcmp(ruby_node_name(NODE_LAMBDA), "NODE_LAMBDA"))
191
- {
192
- rb_raise(rb_eArgError, "Invalid NODE_LAMBDA position");
193
- }
194
- /* RUBY 1.9.3 VARIANT */
195
- #if RUBY_API_VERSION_MAJOR == 1
196
- switch (type)
197
- {
198
- case NODE_IF: /* 1,2,3 */
199
- case NODE_FOR:
200
- case NODE_ITER:
201
- case NODE_WHEN:
202
- case NODE_MASGN:
203
- case NODE_RESCUE:
204
- case NODE_RESBODY:
205
- case NODE_CLASS:
206
- case NODE_BLOCK_PASS:
207
- isval[0] = 1;
208
- isval[1] = 1;
209
- isval[2] = 1;
210
- break;
211
-
212
- case NODE_BLOCK: /* 1,3 */
213
- case NODE_OPTBLOCK:
214
- case NODE_ARRAY:
215
- case NODE_DSTR:
216
- case NODE_DXSTR:
217
- case NODE_DREGX:
218
- case NODE_DREGX_ONCE:
219
- case NODE_ENSURE:
220
- case NODE_CALL:
221
- case NODE_DEFS:
222
- case NODE_OP_ASGN1:
223
- case NODE_ARGS:
224
- isval[0] = 1;
225
- isval[2] = 1;
226
- break;
227
-
228
- case NODE_SUPER: /* 3 */
229
- case NODE_FCALL:
230
- case NODE_DEFN:
231
- case NODE_ARGS_AUX:
232
- isval[2] = 1;
233
- break;
234
-
235
- case NODE_WHILE: /* 1,2 */
236
- case NODE_UNTIL:
237
- case NODE_AND:
238
- case NODE_OR:
239
- case NODE_CASE:
240
- case NODE_SCLASS:
241
- case NODE_DOT2:
242
- case NODE_DOT3:
243
- case NODE_FLIP2:
244
- case NODE_FLIP3:
245
- case NODE_MATCH2:
246
- case NODE_MATCH3:
247
- case NODE_OP_ASGN_OR:
248
- case NODE_OP_ASGN_AND:
249
- case NODE_MODULE:
250
- case NODE_ALIAS:
251
- // case NODE_VALIAS:
252
- case NODE_ARGSCAT:
253
- isval[0] = 1;
254
- isval[1] = 1;
255
- break;
256
-
257
- case NODE_GASGN: /* 2 */
258
- case NODE_LASGN:
259
- case NODE_DASGN:
260
- case NODE_DASGN_CURR:
261
- case NODE_IASGN:
262
- case NODE_IASGN2:
263
- case NODE_CVASGN:
264
- // case NODE_COLON3:
265
- case NODE_OPT_N:
266
- case NODE_EVSTR:
267
- case NODE_UNDEF:
268
- case NODE_POSTEXE:
269
- isval[1] = 1;
270
- break;
271
-
272
- case NODE_HASH: /* 1 */
273
- case NODE_LIT:
274
- case NODE_STR:
275
- case NODE_XSTR:
276
- case NODE_DEFINED:
277
- case NODE_MATCH:
278
- case NODE_RETURN:
279
- case NODE_BREAK:
280
- case NODE_NEXT:
281
- case NODE_YIELD:
282
- case NODE_COLON2:
283
- case NODE_SPLAT:
284
- case NODE_TO_ARY:
285
- isval[0] = 1;
286
- break;
287
-
288
- case NODE_SCOPE: /* 2,3 */
289
- case NODE_CDECL:
290
- case NODE_OPT_ARG:
291
- isval[1] = 1;
292
- isval[2] = 1;
293
- break;
294
-
295
- case NODE_ZARRAY: /* - */
296
- case NODE_ZSUPER:
297
- case NODE_VCALL:
298
- case NODE_GVAR:
299
- case NODE_LVAR:
300
- case NODE_DVAR:
301
- case NODE_IVAR:
302
- case NODE_CVAR:
303
- case NODE_NTH_REF:
304
- case NODE_BACK_REF:
305
- case NODE_REDO:
306
- case NODE_RETRY:
307
- case NODE_SELF:
308
- case NODE_NIL:
309
- case NODE_TRUE:
310
- case NODE_FALSE:
311
- case NODE_ERRINFO:
312
- case NODE_BLOCK_ARG:
313
- break;
314
-
315
- default:
316
- return;
317
- }
318
- #elif (RUBY_API_VERSION_MAJOR == 2) && (RUBY_API_VERSION_MINOR == 2)
319
- /* RUBY 2.2.1 VARIANT */
320
- switch (type)
321
- {
322
- case NODE_IF: /* 1,2,3 */
323
- case NODE_FOR:
324
- case NODE_ITER:
325
- case NODE_WHEN:
326
- case NODE_MASGN:
327
- case NODE_RESCUE:
328
- case NODE_RESBODY:
329
- case NODE_CLASS:
330
- case NODE_BLOCK_PASS:
331
- isval[0] = 1;
332
- isval[1] = 1;
333
- isval[2] = 1;
334
- break;
335
-
336
- case NODE_BLOCK: /* 1,3 */
337
- case NODE_ARRAY:
338
- case NODE_DSTR:
339
- case NODE_DXSTR:
340
- case NODE_DREGX:
341
- case NODE_DREGX_ONCE:
342
- case NODE_ENSURE:
343
- case NODE_CALL:
344
- case NODE_DEFS:
345
- case NODE_OP_ASGN1:
346
- isval[0] = 1;
347
- isval[2] = 1;
348
- break;
349
-
350
- case NODE_SUPER: /* 3 */
351
- case NODE_FCALL:
352
- case NODE_DEFN:
353
- case NODE_ARGS_AUX:
354
- isval[2] = 1;
355
- break;
356
-
357
- case NODE_WHILE: /* 1,2 */
358
- case NODE_UNTIL:
359
- case NODE_AND:
360
- case NODE_OR:
361
- case NODE_CASE:
362
- case NODE_SCLASS:
363
- case NODE_DOT2:
364
- case NODE_DOT3:
365
- case NODE_FLIP2:
366
- case NODE_FLIP3:
367
- case NODE_MATCH2:
368
- case NODE_MATCH3:
369
- case NODE_OP_ASGN_OR:
370
- case NODE_OP_ASGN_AND:
371
- case NODE_MODULE:
372
- case NODE_ALIAS:
373
- //case NODE_VALIAS:
374
- case NODE_ARGSCAT:
375
- isval[0] = 1;
376
- isval[1] = 1;
377
- break;
378
-
379
- case NODE_GASGN: /* 2 */
380
- case NODE_LASGN:
381
- case NODE_DASGN:
382
- case NODE_DASGN_CURR:
383
- case NODE_IASGN:
384
- case NODE_IASGN2:
385
- case NODE_CVASGN:
386
- //case NODE_COLON3:
387
- case NODE_OPT_N:
388
- case NODE_EVSTR:
389
- case NODE_UNDEF:
390
- case NODE_POSTEXE:
391
- isval[1] = 1;
392
- break;
393
-
394
- case NODE_HASH: /* 1 */
395
- case NODE_LIT:
396
- case NODE_STR:
397
- case NODE_XSTR:
398
- case NODE_DEFINED:
399
- case NODE_MATCH:
400
- case NODE_RETURN:
401
- case NODE_BREAK:
402
- case NODE_NEXT:
403
- case NODE_YIELD:
404
- case NODE_COLON2:
405
- case NODE_SPLAT:
406
- case NODE_TO_ARY:
407
- isval[0] = 1;
408
- break;
409
-
410
- case NODE_SCOPE: /* 2,3 */
411
- case NODE_CDECL:
412
- case NODE_OPT_ARG:
413
- isval[1] = 1;
414
- isval[2] = 1;
415
- break;
416
-
417
- case NODE_ARGS: /* custom */
418
- isval[1] = 1;
419
- break;
420
-
421
- case NODE_ZARRAY: /* - */
422
- case NODE_ZSUPER:
423
- case NODE_VCALL:
424
- case NODE_GVAR:
425
- case NODE_LVAR:
426
- case NODE_DVAR:
427
- case NODE_IVAR:
428
- case NODE_CVAR:
429
- case NODE_NTH_REF:
430
- case NODE_BACK_REF:
431
- case NODE_REDO:
432
- case NODE_RETRY:
433
- case NODE_SELF:
434
- case NODE_NIL:
435
- case NODE_TRUE:
436
- case NODE_FALSE:
437
- case NODE_ERRINFO:
438
- case NODE_BLOCK_ARG:
439
- break;
440
-
441
- default: /* unlisted NODE */
442
- //printf("Warning: unknown node %s in the initial table\n",
443
- // ruby_node_name(nodes_child_info[pos][0]));
444
- return;
445
- }
446
- #elif (RUBY_API_VERSION_MAJOR == 2) && (RUBY_API_VERSION_MINOR == 3)
447
- switch (type)
448
- {
449
- case NODE_IF: /* 1,2,3 */
450
- case NODE_FOR:
451
- case NODE_ITER:
452
- case NODE_WHEN:
453
- case NODE_MASGN:
454
- case NODE_RESCUE:
455
- case NODE_RESBODY:
456
- case NODE_CLASS:
457
- case NODE_BLOCK_PASS:
458
- isval[1] = 1;
459
- /* fall through */
460
- case NODE_BLOCK: /* 1,3 */
461
- case NODE_ARRAY:
462
- case NODE_DSTR:
463
- case NODE_DXSTR:
464
- case NODE_DREGX:
465
- case NODE_DREGX_ONCE:
466
- case NODE_ENSURE:
467
- case NODE_CALL:
468
- case NODE_DEFS:
469
- case NODE_OP_ASGN1:
470
- isval[0] = 1;
471
- /* fall through */
472
- case NODE_SUPER: /* 3 */
473
- case NODE_FCALL:
474
- case NODE_DEFN:
475
- case NODE_ARGS_AUX:
476
- isval[2] = 1;
477
- break;
478
-
479
- case NODE_WHILE: /* 1,2 */
480
- case NODE_UNTIL:
481
- case NODE_AND:
482
- case NODE_OR:
483
- case NODE_CASE:
484
- case NODE_SCLASS:
485
- case NODE_DOT2:
486
- case NODE_DOT3:
487
- case NODE_FLIP2:
488
- case NODE_FLIP3:
489
- case NODE_MATCH2:
490
- case NODE_MATCH3:
491
- case NODE_OP_ASGN_OR:
492
- case NODE_OP_ASGN_AND:
493
- case NODE_MODULE:
494
- case NODE_ALIAS:
495
- //case NODE_VALIAS:
496
- case NODE_ARGSCAT:
497
- isval[0] = 1;
498
- /* fall through */
499
- case NODE_GASGN: /* 2 */
500
- case NODE_LASGN:
501
- case NODE_DASGN:
502
- case NODE_DASGN_CURR:
503
- case NODE_IASGN:
504
- case NODE_IASGN2:
505
- case NODE_CVASGN:
506
- //case NODE_COLON3:
507
- case NODE_OPT_N:
508
- case NODE_EVSTR:
509
- case NODE_UNDEF:
510
- case NODE_POSTEXE:
511
- isval[1] = 1;
512
- break;
513
-
514
- case NODE_HASH: /* 1 */
515
- case NODE_LIT:
516
- case NODE_STR:
517
- case NODE_XSTR:
518
- case NODE_DEFINED:
519
- case NODE_MATCH:
520
- case NODE_RETURN:
521
- case NODE_BREAK:
522
- case NODE_NEXT:
523
- case NODE_YIELD:
524
- case NODE_COLON2:
525
- case NODE_SPLAT:
526
- case NODE_TO_ARY:
527
- isval[0] = 1;
528
- break;
529
-
530
- case NODE_SCOPE: /* 2,3 */
531
- case NODE_CDECL:
532
- case NODE_OPT_ARG:
533
- isval[1] = 1;
534
- isval[2] = 1;
535
- break;
536
-
537
- case NODE_ARGS: /* custom */
538
- isval[1] = 1;
539
- break;
540
-
541
- case NODE_ZARRAY: /* - */
542
- case NODE_ZSUPER:
543
- case NODE_VCALL:
544
- case NODE_GVAR:
545
- case NODE_LVAR:
546
- case NODE_DVAR:
547
- case NODE_IVAR:
548
- case NODE_CVAR:
549
- case NODE_NTH_REF:
550
- case NODE_BACK_REF:
551
- case NODE_REDO:
552
- case NODE_RETRY:
553
- case NODE_SELF:
554
- case NODE_NIL:
555
- case NODE_TRUE:
556
- case NODE_FALSE:
557
- case NODE_ERRINFO:
558
- case NODE_BLOCK_ARG:
559
- break;
560
- /* NODE_ALLOCA EXCLUDED */
561
- default: /* unlisted NODE */
562
- return;
563
- }
564
- #endif
565
-
566
- for (i = 0; i < 3; i++)
567
- isval_tbl[i] = (nodes_child_info[pos][i+1] == NT_NODE || nodes_child_info[pos][i+1] == NT_VALUE) ? 1 : 0;
568
-
569
- if ( (isval[0] - isval_tbl[0] != 0) ||
570
- (isval[1] - isval_tbl[1] != 0) ||
571
- (isval[2] - isval_tbl[2] != 0) )
572
- {
573
- rb_raise(rb_eArgError, "Bad node entry in the initial table (%s): %d%d%d instead of %d%d%d",
574
- ruby_node_name(nodes_child_info[pos][0]),
575
- isval[0], isval[1], isval[2], isval_tbl[0], isval_tbl[1], isval_tbl[2]);
576
- }
577
-
578
- }
579
-
580
- /*
581
- * Converts nodes_child_info 2D array of int into nodes_ctbl 1D array of int
582
- *
583
- * nodes_child_info is similar to hash by the structure: each 1D subarray
584
- * has the next structure:
585
- * {NODE_ID, NT_CHILD1_TYPE, NT_CHILD2_TYPE, NT_CHILD3_TYPE}
586
- */
587
- void init_nodes_table(int *nodes_ctbl, int num_of_entries)
588
- {
589
- int pos, i;
590
- /* Check the input array using information from Ruby source code */
591
- for (pos = 0; nodes_child_info[pos][0] != -1; pos++)
592
- {
593
- check_nodes_child_info(pos);
594
- }
595
- /* Initialize output array by NT_UNKNOWN (if node is not defined
596
- in the input table the types of its childs are unknown) */
597
- for (i = 0; i < num_of_entries * 3; i++)
598
- {
599
- nodes_ctbl[i] = NT_UNKNOWN;
600
- }
601
- /* Fill output array */
602
- for (pos = 0; nodes_child_info[pos][0] != -1; pos++)
603
- {
604
- int index = nodes_child_info[pos][0], offset;
605
- if (index < 0 || index > num_of_entries)
606
- {
607
- rb_raise(rb_eArgError, "NODE ID %d is out or nodes_ctbl array boundaries", index);
608
- }
609
- offset = index * 3;
610
- nodes_ctbl[offset++] = nodes_child_info[pos][1];
611
- nodes_ctbl[offset++] = nodes_child_info[pos][2];
612
- nodes_ctbl[offset++] = nodes_child_info[pos][3];
613
- }
614
- }
615
-
1
+ /*
2
+ * This file contains information about Ruby nodes
3
+ * Supported Ruby versions:
4
+ * - Ruby 1.9.3
5
+ * - Ruby 2.2.1
6
+ * - Ruby 2.3.0
7
+ *
8
+ * Fragments from Ruby source code are used here
9
+ * (mainly from node.c, gc.c)
10
+ *
11
+ * License: BSD-2-Clause
12
+ *
13
+ */
14
+ #include <stdio.h>
15
+ #include <stdlib.h>
16
+ #include <inttypes.h>
17
+ #include <ruby.h>
18
+ #include <ruby/version.h>
19
+ #include "nodedump.h"
20
+
21
+ /* Information about nodes types
22
+
23
+ NODE_ARRAY contains an undocumented feature: if an array contains
24
+ more than 1 element the 2nd child of 2nd element will contain
25
+ a reference to the last element of the array (and have NT_NODE
26
+ not NT_LONG type)
27
+ Another case is Hash: every 2nd element of NODE_ARRAY chain
28
+ has NT_NODE type (see nodedump.c for details)
29
+
30
+ Such child is ignored by GC because there is a reference to it
31
+ from another place of Ruby AST.
32
+
33
+ NODE_LASGN and NODE_DASGN_CURR have special value -1 of the 2nd
34
+ child (that is usually node not a number)
35
+ */
36
+ static int nodes_child_info[][4] =
37
+ {
38
+ {NODE_BLOCK, NT_NODE, NT_NULL, NT_NODE},
39
+ {NODE_IF, NT_NODE, NT_NODE, NT_NODE},
40
+
41
+ {NODE_CASE, NT_NODE, NT_NODE, NT_NULL},
42
+ {NODE_WHEN, NT_NODE, NT_NODE, NT_NODE},
43
+
44
+ {NODE_OPT_N, NT_NULL, NT_NODE, NT_LONG}, /* ??? */
45
+ {NODE_WHILE, NT_NODE, NT_NODE, NT_LONG},
46
+ {NODE_UNTIL, NT_NODE, NT_NODE, NT_LONG},
47
+
48
+ {NODE_ITER, NT_VALUE, NT_NODE, NT_NODE}, /* ??? */
49
+ {NODE_FOR, NT_VALUE, NT_NODE, NT_NODE},
50
+
51
+ {NODE_BREAK, NT_NODE, NT_NULL, NT_NULL},
52
+ {NODE_NEXT, NT_NODE, NT_NULL, NT_NULL},
53
+ {NODE_RETURN, NT_NODE, NT_NULL, NT_NULL},
54
+
55
+ {NODE_REDO, NT_NULL, NT_NULL, NT_NULL},
56
+ {NODE_RETRY, NT_NULL, NT_NULL, NT_NULL},
57
+
58
+ {NODE_BEGIN, NT_NULL, NT_NODE, NT_NULL},
59
+
60
+ {NODE_RESCUE, NT_NODE, NT_NODE, NT_NODE},
61
+ {NODE_RESBODY, NT_NODE, NT_NODE, NT_NODE},
62
+ {NODE_ENSURE, NT_NODE, NT_NULL, NT_NODE},
63
+
64
+ {NODE_AND, NT_NODE, NT_NODE, NT_NULL},
65
+ {NODE_OR, NT_NODE, NT_NODE, NT_NULL},
66
+
67
+ {NODE_MASGN, NT_NODE, NT_NODE, NT_NODE},
68
+
69
+ {NODE_LASGN, NT_ID, NT_NODE, NT_NULL},
70
+ {NODE_DASGN, NT_ID, NT_NODE, NT_NULL},
71
+ {NODE_DASGN_CURR, NT_ID, NT_NODE, NT_NULL},
72
+ {NODE_IASGN, NT_ID, NT_NODE, NT_NULL},
73
+ {NODE_CVASGN, NT_ID, NT_NODE, NT_NULL},
74
+
75
+ {NODE_GASGN, NT_NULL, NT_NODE, NT_ENTRY},
76
+
77
+ {NODE_CDECL, NT_ID, NT_NODE, NT_NODE},
78
+
79
+ {NODE_OP_ASGN1, NT_NODE, NT_ID, NT_NODE},
80
+ {NODE_OP_ASGN2, NT_NODE, NT_NODE, NT_NODE},
81
+
82
+ {NODE_OP_ASGN_AND, NT_NODE, NT_NODE, NT_NULL},
83
+ {NODE_OP_ASGN_OR, NT_NODE, NT_NODE, NT_NULL},
84
+
85
+ {NODE_CALL, NT_NODE, NT_ID, NT_NODE},
86
+ {NODE_FCALL, NT_NULL, NT_ID, NT_NODE},
87
+ {NODE_VCALL, NT_NULL, NT_ID, NT_NULL},
88
+ #ifdef NODE_QCALL
89
+ {NODE_QCALL, NT_NODE, NT_ID, NT_NODE}, /* &. operator from Ruby 2.3 */
90
+ #endif
91
+
92
+ {NODE_SUPER, NT_NULL, NT_NULL, NT_NODE},
93
+ {NODE_ZSUPER, NT_NULL, NT_NULL, NT_NULL},
94
+ {NODE_ARRAY, NT_NODE, NT_LONG, NT_NODE}, /* 2nd child has undocumented variants (see above) */
95
+ {NODE_VALUES, NT_NODE, NT_LONG, NT_NODE},
96
+ {NODE_ZARRAY, NT_NULL, NT_NULL, NT_NULL},
97
+
98
+ {NODE_HASH, NT_NODE, NT_NULL, NT_NULL},
99
+ {NODE_YIELD, NT_NODE, NT_NULL, NT_NULL},
100
+
101
+ {NODE_LVAR, NT_ID, NT_NULL, NT_NULL},
102
+ {NODE_DVAR, NT_ID, NT_NULL, NT_NULL},
103
+ {NODE_IVAR, NT_ID, NT_NULL, NT_NULL},
104
+ {NODE_CONST, NT_ID, NT_NULL, NT_NULL},
105
+ {NODE_CVAR, NT_ID, NT_NULL, NT_NULL},
106
+
107
+ {NODE_GVAR, NT_NULL, NT_NULL, NT_ENTRY},
108
+
109
+ {NODE_NTH_REF, NT_NULL, NT_LONG, NT_NULL},
110
+ {NODE_BACK_REF, NT_NULL, NT_LONG, NT_LONG},
111
+
112
+ {NODE_MATCH, NT_VALUE, NT_NULL, NT_NULL},
113
+ {NODE_MATCH2, NT_NODE, NT_NODE, NT_NULL},
114
+ {NODE_MATCH3, NT_NODE, NT_NODE, NT_NULL},
115
+
116
+ {NODE_LIT, NT_VALUE, NT_NULL, NT_NULL},
117
+ {NODE_STR, NT_VALUE, NT_NULL, NT_NULL},
118
+ {NODE_XSTR, NT_VALUE, NT_NULL, NT_NULL},
119
+
120
+ {NODE_DSTR, NT_VALUE, NT_NULL, NT_NODE},
121
+ {NODE_DXSTR, NT_VALUE, NT_NULL, NT_NODE},
122
+ {NODE_DREGX, NT_VALUE, NT_NULL, NT_NODE},
123
+ {NODE_DREGX_ONCE, NT_VALUE, NT_NULL, NT_NODE},
124
+ {NODE_DSYM, NT_VALUE, NT_NULL, NT_NODE},
125
+
126
+ {NODE_EVSTR, NT_NULL, NT_NODE, NT_NULL},
127
+
128
+ {NODE_ARGSCAT, NT_NODE, NT_NODE, NT_NULL},
129
+ {NODE_ARGSPUSH, NT_NODE, NT_NODE, NT_NULL},
130
+ {NODE_SPLAT, NT_NODE, NT_NULL, NT_NULL},
131
+ {NODE_BLOCK_PASS, NT_NODE, NT_NODE, NT_NODE}, /* ??? */
132
+
133
+ {NODE_DEFN, NT_NULL, NT_ID, NT_NODE},
134
+ {NODE_DEFS, NT_NODE, NT_ID, NT_NODE},
135
+ {NODE_ALIAS, NT_NODE, NT_NODE, NT_NULL},
136
+ {NODE_VALIAS, NT_ID, NT_ID, NT_NULL},
137
+ {NODE_UNDEF, NT_NULL, NT_NODE, NT_NULL},
138
+
139
+ {NODE_CLASS, NT_NODE, NT_NODE, NT_NODE},
140
+ {NODE_MODULE, NT_NODE, NT_NODE, NT_NULL},
141
+ {NODE_SCLASS, NT_NODE, NT_NODE, NT_NULL},
142
+
143
+ {NODE_COLON2, NT_NODE, NT_ID, NT_NULL},
144
+ {NODE_COLON3, NT_NULL, NT_ID, NT_NULL},
145
+
146
+ {NODE_DOT2, NT_NODE, NT_NODE, NT_NULL},
147
+ {NODE_DOT3, NT_NODE, NT_NODE, NT_NULL},
148
+ {NODE_FLIP2, NT_NODE, NT_NODE, NT_NULL},
149
+ {NODE_FLIP3, NT_NODE, NT_NODE, NT_NULL},
150
+
151
+ {NODE_SELF, NT_NULL, NT_NULL, NT_NULL},
152
+ {NODE_NIL, NT_NULL, NT_NULL, NT_NULL},
153
+ {NODE_TRUE, NT_NULL, NT_NULL, NT_NULL},
154
+ {NODE_FALSE, NT_NULL, NT_NULL, NT_NULL},
155
+ {NODE_ERRINFO, NT_NULL, NT_NULL, NT_NULL},
156
+
157
+ {NODE_DEFINED, NT_NODE, NT_NULL, NT_NULL},
158
+
159
+ {NODE_POSTEXE, NT_NULL, NT_NODE, NT_NULL},
160
+ {NODE_ATTRASGN, NT_NODE, NT_ID, NT_NODE},
161
+ {NODE_PRELUDE, NT_NODE, NT_NODE, NT_NULL},
162
+
163
+ {NODE_LAMBDA, NT_NULL, NT_NODE, NT_NULL},
164
+
165
+ {NODE_OPT_ARG, NT_NULL, NT_NODE, NT_NODE},
166
+ {NODE_POSTARG, NT_NODE, NT_NODE, NT_NULL},
167
+
168
+ #ifdef USE_RB_ARGS_INFO
169
+ {NODE_ARGS, NT_NULL, NT_VALUE, NT_ARGS}, /* ??? */
170
+ {NODE_KW_ARG, NT_NULL, NT_NODE, NT_NODE},
171
+ #else
172
+ {NODE_ARGS, NT_NODE, NT_NULL, NT_NODE}, /* ??? */
173
+ #endif
174
+ {NODE_SCOPE, NT_IDTABLE, NT_NODE, NT_NODE},
175
+
176
+ {NODE_ARGS_AUX, NT_LONG, NT_LONG, NT_NODE},
177
+
178
+ {-1, 0, 0, 0}
179
+ };
180
+
181
+
182
+
183
+ /*
184
+ * Check the correctness of nodes table from the viewpoint
185
+ * This function is based on Ruby source code (node.c)
186
+ */
187
+ void check_nodes_child_info(int pos)
188
+ {
189
+ int type = nodes_child_info[pos][0];
190
+ int isval[3] = {0, 0, 0};
191
+ int isval_tbl[3] = {1, 1, 1};
192
+ int i;
193
+ /* Check NODE_LAMBDA position */
194
+ if (strcmp(ruby_node_name(NODE_LAMBDA), "NODE_LAMBDA"))
195
+ {
196
+ rb_raise(rb_eArgError, "Invalid NODE_LAMBDA position");
197
+ }
198
+ /* RUBY 1.9.3 VARIANT */
199
+ #if RUBY_API_VERSION_MAJOR == 1
200
+ switch (type)
201
+ {
202
+ case NODE_IF: /* 1,2,3 */
203
+ case NODE_FOR:
204
+ case NODE_ITER:
205
+ case NODE_WHEN:
206
+ case NODE_MASGN:
207
+ case NODE_RESCUE:
208
+ case NODE_RESBODY:
209
+ case NODE_CLASS:
210
+ case NODE_BLOCK_PASS:
211
+ isval[0] = 1;
212
+ isval[1] = 1;
213
+ isval[2] = 1;
214
+ break;
215
+
216
+ case NODE_BLOCK: /* 1,3 */
217
+ case NODE_OPTBLOCK:
218
+ case NODE_ARRAY:
219
+ case NODE_DSTR:
220
+ case NODE_DXSTR:
221
+ case NODE_DREGX:
222
+ case NODE_DREGX_ONCE:
223
+ case NODE_ENSURE:
224
+ case NODE_CALL:
225
+ case NODE_DEFS:
226
+ case NODE_OP_ASGN1:
227
+ case NODE_ARGS:
228
+ isval[0] = 1;
229
+ isval[2] = 1;
230
+ break;
231
+
232
+ case NODE_SUPER: /* 3 */
233
+ case NODE_FCALL:
234
+ case NODE_DEFN:
235
+ case NODE_ARGS_AUX:
236
+ isval[2] = 1;
237
+ break;
238
+
239
+ case NODE_WHILE: /* 1,2 */
240
+ case NODE_UNTIL:
241
+ case NODE_AND:
242
+ case NODE_OR:
243
+ case NODE_CASE:
244
+ case NODE_SCLASS:
245
+ case NODE_DOT2:
246
+ case NODE_DOT3:
247
+ case NODE_FLIP2:
248
+ case NODE_FLIP3:
249
+ case NODE_MATCH2:
250
+ case NODE_MATCH3:
251
+ case NODE_OP_ASGN_OR:
252
+ case NODE_OP_ASGN_AND:
253
+ case NODE_MODULE:
254
+ case NODE_ALIAS:
255
+ // case NODE_VALIAS:
256
+ case NODE_ARGSCAT:
257
+ isval[0] = 1;
258
+ isval[1] = 1;
259
+ break;
260
+
261
+ case NODE_GASGN: /* 2 */
262
+ case NODE_LASGN:
263
+ case NODE_DASGN:
264
+ case NODE_DASGN_CURR:
265
+ case NODE_IASGN:
266
+ case NODE_IASGN2:
267
+ case NODE_CVASGN:
268
+ // case NODE_COLON3:
269
+ case NODE_OPT_N:
270
+ case NODE_EVSTR:
271
+ case NODE_UNDEF:
272
+ case NODE_POSTEXE:
273
+ isval[1] = 1;
274
+ break;
275
+
276
+ case NODE_HASH: /* 1 */
277
+ case NODE_LIT:
278
+ case NODE_STR:
279
+ case NODE_XSTR:
280
+ case NODE_DEFINED:
281
+ case NODE_MATCH:
282
+ case NODE_RETURN:
283
+ case NODE_BREAK:
284
+ case NODE_NEXT:
285
+ case NODE_YIELD:
286
+ case NODE_COLON2:
287
+ case NODE_SPLAT:
288
+ case NODE_TO_ARY:
289
+ isval[0] = 1;
290
+ break;
291
+
292
+ case NODE_SCOPE: /* 2,3 */
293
+ case NODE_CDECL:
294
+ case NODE_OPT_ARG:
295
+ isval[1] = 1;
296
+ isval[2] = 1;
297
+ break;
298
+
299
+ case NODE_ZARRAY: /* - */
300
+ case NODE_ZSUPER:
301
+ case NODE_VCALL:
302
+ case NODE_GVAR:
303
+ case NODE_LVAR:
304
+ case NODE_DVAR:
305
+ case NODE_IVAR:
306
+ case NODE_CVAR:
307
+ case NODE_NTH_REF:
308
+ case NODE_BACK_REF:
309
+ case NODE_REDO:
310
+ case NODE_RETRY:
311
+ case NODE_SELF:
312
+ case NODE_NIL:
313
+ case NODE_TRUE:
314
+ case NODE_FALSE:
315
+ case NODE_ERRINFO:
316
+ case NODE_BLOCK_ARG:
317
+ break;
318
+
319
+ default:
320
+ return;
321
+ }
322
+ #elif (RUBY_API_VERSION_MAJOR == 2) && (RUBY_API_VERSION_MINOR == 2)
323
+ /* RUBY 2.2.1 VARIANT */
324
+ switch (type)
325
+ {
326
+ case NODE_IF: /* 1,2,3 */
327
+ case NODE_FOR:
328
+ case NODE_ITER:
329
+ case NODE_WHEN:
330
+ case NODE_MASGN:
331
+ case NODE_RESCUE:
332
+ case NODE_RESBODY:
333
+ case NODE_CLASS:
334
+ case NODE_BLOCK_PASS:
335
+ isval[0] = 1;
336
+ isval[1] = 1;
337
+ isval[2] = 1;
338
+ break;
339
+
340
+ case NODE_BLOCK: /* 1,3 */
341
+ case NODE_ARRAY:
342
+ case NODE_DSTR:
343
+ case NODE_DXSTR:
344
+ case NODE_DREGX:
345
+ case NODE_DREGX_ONCE:
346
+ case NODE_ENSURE:
347
+ case NODE_CALL:
348
+ case NODE_DEFS:
349
+ case NODE_OP_ASGN1:
350
+ isval[0] = 1;
351
+ isval[2] = 1;
352
+ break;
353
+
354
+ case NODE_SUPER: /* 3 */
355
+ case NODE_FCALL:
356
+ case NODE_DEFN:
357
+ case NODE_ARGS_AUX:
358
+ isval[2] = 1;
359
+ break;
360
+
361
+ case NODE_WHILE: /* 1,2 */
362
+ case NODE_UNTIL:
363
+ case NODE_AND:
364
+ case NODE_OR:
365
+ case NODE_CASE:
366
+ case NODE_SCLASS:
367
+ case NODE_DOT2:
368
+ case NODE_DOT3:
369
+ case NODE_FLIP2:
370
+ case NODE_FLIP3:
371
+ case NODE_MATCH2:
372
+ case NODE_MATCH3:
373
+ case NODE_OP_ASGN_OR:
374
+ case NODE_OP_ASGN_AND:
375
+ case NODE_MODULE:
376
+ case NODE_ALIAS:
377
+ //case NODE_VALIAS:
378
+ case NODE_ARGSCAT:
379
+ isval[0] = 1;
380
+ isval[1] = 1;
381
+ break;
382
+
383
+ case NODE_GASGN: /* 2 */
384
+ case NODE_LASGN:
385
+ case NODE_DASGN:
386
+ case NODE_DASGN_CURR:
387
+ case NODE_IASGN:
388
+ case NODE_IASGN2:
389
+ case NODE_CVASGN:
390
+ //case NODE_COLON3:
391
+ case NODE_OPT_N:
392
+ case NODE_EVSTR:
393
+ case NODE_UNDEF:
394
+ case NODE_POSTEXE:
395
+ isval[1] = 1;
396
+ break;
397
+
398
+ case NODE_HASH: /* 1 */
399
+ case NODE_LIT:
400
+ case NODE_STR:
401
+ case NODE_XSTR:
402
+ case NODE_DEFINED:
403
+ case NODE_MATCH:
404
+ case NODE_RETURN:
405
+ case NODE_BREAK:
406
+ case NODE_NEXT:
407
+ case NODE_YIELD:
408
+ case NODE_COLON2:
409
+ case NODE_SPLAT:
410
+ case NODE_TO_ARY:
411
+ isval[0] = 1;
412
+ break;
413
+
414
+ case NODE_SCOPE: /* 2,3 */
415
+ case NODE_CDECL:
416
+ case NODE_OPT_ARG:
417
+ isval[1] = 1;
418
+ isval[2] = 1;
419
+ break;
420
+
421
+ case NODE_ARGS: /* custom */
422
+ isval[1] = 1;
423
+ break;
424
+
425
+ case NODE_ZARRAY: /* - */
426
+ case NODE_ZSUPER:
427
+ case NODE_VCALL:
428
+ case NODE_GVAR:
429
+ case NODE_LVAR:
430
+ case NODE_DVAR:
431
+ case NODE_IVAR:
432
+ case NODE_CVAR:
433
+ case NODE_NTH_REF:
434
+ case NODE_BACK_REF:
435
+ case NODE_REDO:
436
+ case NODE_RETRY:
437
+ case NODE_SELF:
438
+ case NODE_NIL:
439
+ case NODE_TRUE:
440
+ case NODE_FALSE:
441
+ case NODE_ERRINFO:
442
+ case NODE_BLOCK_ARG:
443
+ break;
444
+
445
+ default: /* unlisted NODE */
446
+ //printf("Warning: unknown node %s in the initial table\n",
447
+ // ruby_node_name(nodes_child_info[pos][0]));
448
+ return;
449
+ }
450
+ #elif (RUBY_API_VERSION_MAJOR == 2) && (RUBY_API_VERSION_MINOR == 3)
451
+ switch (type)
452
+ {
453
+ case NODE_IF: /* 1,2,3 */
454
+ case NODE_FOR:
455
+ case NODE_ITER:
456
+ case NODE_WHEN:
457
+ case NODE_MASGN:
458
+ case NODE_RESCUE:
459
+ case NODE_RESBODY:
460
+ case NODE_CLASS:
461
+ case NODE_BLOCK_PASS:
462
+ isval[1] = 1;
463
+ /* fall through */
464
+ case NODE_BLOCK: /* 1,3 */
465
+ case NODE_ARRAY:
466
+ case NODE_DSTR:
467
+ case NODE_DXSTR:
468
+ case NODE_DREGX:
469
+ case NODE_DREGX_ONCE:
470
+ case NODE_ENSURE:
471
+ case NODE_CALL:
472
+ case NODE_DEFS:
473
+ case NODE_OP_ASGN1:
474
+ isval[0] = 1;
475
+ /* fall through */
476
+ case NODE_SUPER: /* 3 */
477
+ case NODE_FCALL:
478
+ case NODE_DEFN:
479
+ case NODE_ARGS_AUX:
480
+ isval[2] = 1;
481
+ break;
482
+
483
+ case NODE_WHILE: /* 1,2 */
484
+ case NODE_UNTIL:
485
+ case NODE_AND:
486
+ case NODE_OR:
487
+ case NODE_CASE:
488
+ case NODE_SCLASS:
489
+ case NODE_DOT2:
490
+ case NODE_DOT3:
491
+ case NODE_FLIP2:
492
+ case NODE_FLIP3:
493
+ case NODE_MATCH2:
494
+ case NODE_MATCH3:
495
+ case NODE_OP_ASGN_OR:
496
+ case NODE_OP_ASGN_AND:
497
+ case NODE_MODULE:
498
+ case NODE_ALIAS:
499
+ //case NODE_VALIAS:
500
+ case NODE_ARGSCAT:
501
+ isval[0] = 1;
502
+ /* fall through */
503
+ case NODE_GASGN: /* 2 */
504
+ case NODE_LASGN:
505
+ case NODE_DASGN:
506
+ case NODE_DASGN_CURR:
507
+ case NODE_IASGN:
508
+ case NODE_IASGN2:
509
+ case NODE_CVASGN:
510
+ //case NODE_COLON3:
511
+ case NODE_OPT_N:
512
+ case NODE_EVSTR:
513
+ case NODE_UNDEF:
514
+ case NODE_POSTEXE:
515
+ isval[1] = 1;
516
+ break;
517
+
518
+ case NODE_HASH: /* 1 */
519
+ case NODE_LIT:
520
+ case NODE_STR:
521
+ case NODE_XSTR:
522
+ case NODE_DEFINED:
523
+ case NODE_MATCH:
524
+ case NODE_RETURN:
525
+ case NODE_BREAK:
526
+ case NODE_NEXT:
527
+ case NODE_YIELD:
528
+ case NODE_COLON2:
529
+ case NODE_SPLAT:
530
+ case NODE_TO_ARY:
531
+ isval[0] = 1;
532
+ break;
533
+
534
+ case NODE_SCOPE: /* 2,3 */
535
+ case NODE_CDECL:
536
+ case NODE_OPT_ARG:
537
+ isval[1] = 1;
538
+ isval[2] = 1;
539
+ break;
540
+
541
+ case NODE_ARGS: /* custom */
542
+ isval[1] = 1;
543
+ break;
544
+
545
+ case NODE_ZARRAY: /* - */
546
+ case NODE_ZSUPER:
547
+ case NODE_VCALL:
548
+ case NODE_GVAR:
549
+ case NODE_LVAR:
550
+ case NODE_DVAR:
551
+ case NODE_IVAR:
552
+ case NODE_CVAR:
553
+ case NODE_NTH_REF:
554
+ case NODE_BACK_REF:
555
+ case NODE_REDO:
556
+ case NODE_RETRY:
557
+ case NODE_SELF:
558
+ case NODE_NIL:
559
+ case NODE_TRUE:
560
+ case NODE_FALSE:
561
+ case NODE_ERRINFO:
562
+ case NODE_BLOCK_ARG:
563
+ break;
564
+ /* NODE_ALLOCA EXCLUDED */
565
+ default: /* unlisted NODE */
566
+ return;
567
+ }
568
+ #endif
569
+
570
+ for (i = 0; i < 3; i++)
571
+ isval_tbl[i] = (nodes_child_info[pos][i+1] == NT_NODE || nodes_child_info[pos][i+1] == NT_VALUE) ? 1 : 0;
572
+
573
+ if ( (isval[0] - isval_tbl[0] != 0) ||
574
+ (isval[1] - isval_tbl[1] != 0) ||
575
+ (isval[2] - isval_tbl[2] != 0) )
576
+ {
577
+ rb_raise(rb_eArgError, "Bad node entry in the initial table (%s): %d%d%d instead of %d%d%d",
578
+ ruby_node_name(nodes_child_info[pos][0]),
579
+ isval[0], isval[1], isval[2], isval_tbl[0], isval_tbl[1], isval_tbl[2]);
580
+ }
581
+
582
+ }
583
+
584
+ /*
585
+ * Converts nodes_child_info 2D array of int into nodes_ctbl 1D array of int
586
+ *
587
+ * nodes_child_info is similar to hash by the structure: each 1D subarray
588
+ * has the next structure:
589
+ * {NODE_ID, NT_CHILD1_TYPE, NT_CHILD2_TYPE, NT_CHILD3_TYPE}
590
+ */
591
+ void init_nodes_table(int *nodes_ctbl, int num_of_entries)
592
+ {
593
+ int pos, i;
594
+ /* Check the input array using information from Ruby source code */
595
+ for (pos = 0; nodes_child_info[pos][0] != -1; pos++)
596
+ {
597
+ check_nodes_child_info(pos);
598
+ }
599
+ /* Initialize output array by NT_UNKNOWN (if node is not defined
600
+ in the input table the types of its childs are unknown) */
601
+ for (i = 0; i < num_of_entries * 3; i++)
602
+ {
603
+ nodes_ctbl[i] = NT_UNKNOWN;
604
+ }
605
+ /* Fill output array */
606
+ for (pos = 0; nodes_child_info[pos][0] != -1; pos++)
607
+ {
608
+ int index = nodes_child_info[pos][0], offset;
609
+ if (index < 0 || index > num_of_entries)
610
+ {
611
+ rb_raise(rb_eArgError, "NODE ID %d is out or nodes_ctbl array boundaries", index);
612
+ }
613
+ offset = index * 3;
614
+ nodes_ctbl[offset++] = nodes_child_info[pos][1];
615
+ nodes_ctbl[offset++] = nodes_child_info[pos][2];
616
+ nodes_ctbl[offset++] = nodes_child_info[pos][3];
617
+ }
618
+ }
619
+