Ruby  2.7.2p137(2020-10-01revision5445e0435260b449decf2ac16f9d09bae3cafe72)
node.c
Go to the documentation of this file.
1 /**********************************************************************
2 
3  node.c - ruby node tree
4 
5  $Author: mame $
6  created at: 09/12/06 21:23:44 JST
7 
8  Copyright (C) 2009 Yusuke Endoh
9 
10 **********************************************************************/
11 
12 #include "ruby/ruby.h"
13 #include "vm_core.h"
14 
15 #define NODE_BUF_DEFAULT_LEN 16
16 
17 #define A(str) rb_str_cat2(buf, (str))
18 #define AR(str) rb_str_concat(buf, (str))
19 
20 #define A_INDENT add_indent(buf, indent)
21 #define D_INDENT rb_str_cat2(indent, next_indent)
22 #define D_DEDENT rb_str_resize(indent, RSTRING_LEN(indent) - 4)
23 #define A_ID(id) add_id(buf, (id))
24 #define A_INT(val) rb_str_catf(buf, "%d", (val))
25 #define A_LONG(val) rb_str_catf(buf, "%ld", (val))
26 #define A_LIT(lit) AR(rb_inspect(lit))
27 #define A_NODE_HEADER(node, term) \
28  rb_str_catf(buf, "@ %s (line: %d, location: (%d,%d)-(%d,%d))%s"term, \
29  ruby_node_name(nd_type(node)), nd_line(node), \
30  nd_first_lineno(node), nd_first_column(node), \
31  nd_last_lineno(node), nd_last_column(node), \
32  (node->flags & NODE_FL_NEWLINE ? "*" : ""))
33 #define A_FIELD_HEADER(len, name, term) \
34  rb_str_catf(buf, "+- %.*s:"term, (len), (name))
35 #define D_FIELD_HEADER(len, name, term) (A_INDENT, A_FIELD_HEADER(len, name, term))
36 
37 #define D_NULL_NODE (A_INDENT, A("(null node)\n"))
38 #define D_NODE_HEADER(node) (A_INDENT, A_NODE_HEADER(node, "\n"))
39 
40 #define COMPOUND_FIELD(len, name) \
41  FIELD_BLOCK((D_FIELD_HEADER((len), (name), "\n"), D_INDENT), D_DEDENT)
42 
43 #define COMPOUND_FIELD1(name, ann) \
44  COMPOUND_FIELD(FIELD_NAME_LEN(name, ann), \
45  FIELD_NAME_DESC(name, ann))
46 
47 #define FIELD_NAME_DESC(name, ann) name " (" ann ")"
48 #define FIELD_NAME_LEN(name, ann) (int)( \
49  comment ? \
50  rb_strlen_lit(FIELD_NAME_DESC(name, ann)) : \
51  rb_strlen_lit(name))
52 #define SIMPLE_FIELD(len, name) \
53  FIELD_BLOCK(D_FIELD_HEADER((len), (name), " "), A("\n"))
54 
55 #define FIELD_BLOCK(init, reset) \
56  for (init, field_flag = 1; \
57  field_flag; /* should be optimized away */ \
58  reset, field_flag = 0)
59 
60 #define SIMPLE_FIELD1(name, ann) SIMPLE_FIELD(FIELD_NAME_LEN(name, ann), FIELD_NAME_DESC(name, ann))
61 #define F_CUSTOM1(name, ann) SIMPLE_FIELD1(#name, ann)
62 #define F_ID(name, ann) SIMPLE_FIELD1(#name, ann) A_ID(node->name)
63 #define F_GENTRY(name, ann) SIMPLE_FIELD1(#name, ann) A_ID((node->name)->id)
64 #define F_INT(name, ann) SIMPLE_FIELD1(#name, ann) A_INT(node->name)
65 #define F_LONG(name, ann) SIMPLE_FIELD1(#name, ann) A_LONG(node->name)
66 #define F_LIT(name, ann) SIMPLE_FIELD1(#name, ann) A_LIT(node->name)
67 #define F_MSG(name, ann, desc) SIMPLE_FIELD1(#name, ann) A(desc)
68 
69 #define F_NODE(name, ann) \
70  COMPOUND_FIELD1(#name, ann) {dump_node(buf, indent, comment, node->name);}
71 
72 #define ANN(ann) \
73  if (comment) { \
74  A_INDENT; A("| # " ann "\n"); \
75  }
76 
77 #define LAST_NODE (next_indent = " ")
78 
79 static void
80 add_indent(VALUE buf, VALUE indent)
81 {
82  AR(indent);
83 }
84 
85 static void
86 add_id(VALUE buf, ID id)
87 {
88  if (id == 0) {
89  A("(null)");
90  }
91  else {
92  VALUE str = rb_id2str(id);
93  if (str) {
94  A(":"); AR(str);
95  }
96  else {
97  rb_str_catf(buf, "(internal variable: 0x%"PRIsVALUE")", id);
98  }
99  }
100 }
101 
105 };
106 
107 static void dump_node(VALUE, VALUE, int, const NODE *);
108 static const char default_indent[] = "| ";
109 
110 static void
111 dump_array(VALUE buf, VALUE indent, int comment, const NODE *node)
112 {
113  int field_flag;
114  const char *next_indent = default_indent;
115  F_LONG(nd_alen, "length");
116  F_NODE(nd_head, "element");
117  while (node->nd_next && nd_type(node->nd_next) == NODE_LIST) {
118  node = node->nd_next;
119  F_NODE(nd_head, "element");
120  }
121  LAST_NODE;
122  F_NODE(nd_next, "next element");
123 }
124 
125 static void
126 dump_node(VALUE buf, VALUE indent, int comment, const NODE * node)
127 {
128  int field_flag;
129  int i;
130  const char *next_indent = default_indent;
131  enum node_type type;
132 
133  if (!node) {
134  D_NULL_NODE;
135  return;
136  }
137 
138  D_NODE_HEADER(node);
139 
140  type = nd_type(node);
141  switch (type) {
142  case NODE_BLOCK:
143  ANN("statement sequence");
144  ANN("format: [nd_head]; ...; [nd_next]");
145  ANN("example: foo; bar");
146  i = 0;
147  do {
148  A_INDENT;
149  rb_str_catf(buf, "+- nd_head (%s%d):\n",
150  comment ? "statement #" : "", ++i);
151  if (!node->nd_next) LAST_NODE;
152  D_INDENT;
153  dump_node(buf, indent, comment, node->nd_head);
154  D_DEDENT;
155  } while (node->nd_next &&
156  nd_type(node->nd_next) == NODE_BLOCK &&
157  (node = node->nd_next, 1));
158  if (node->nd_next) {
159  LAST_NODE;
160  F_NODE(nd_next, "next block");
161  }
162  return;
163 
164  case NODE_IF:
165  ANN("if statement");
166  ANN("format: if [nd_cond] then [nd_body] else [nd_else] end");
167  ANN("example: if x == 1 then foo else bar end");
168  F_NODE(nd_cond, "condition expr");
169  F_NODE(nd_body, "then clause");
170  LAST_NODE;
171  F_NODE(nd_else, "else clause");
172  return;
173 
174  case NODE_UNLESS:
175  ANN("unless statement");
176  ANN("format: unless [nd_cond] then [nd_body] else [nd_else] end");
177  ANN("example: unless x == 1 then foo else bar end");
178  F_NODE(nd_cond, "condition expr");
179  F_NODE(nd_body, "then clause");
180  LAST_NODE;
181  F_NODE(nd_else, "else clause");
182  return;
183 
184  case NODE_CASE:
185  ANN("case statement");
186  ANN("format: case [nd_head]; [nd_body]; end");
187  ANN("example: case x; when 1; foo; when 2; bar; else baz; end");
188  F_NODE(nd_head, "case expr");
189  LAST_NODE;
190  F_NODE(nd_body, "when clauses");
191  return;
192  case NODE_CASE2:
193  ANN("case statement with no head");
194  ANN("format: case; [nd_body]; end");
195  ANN("example: case; when 1; foo; when 2; bar; else baz; end");
196  F_NODE(nd_head, "case expr");
197  LAST_NODE;
198  F_NODE(nd_body, "when clauses");
199  return;
200  case NODE_CASE3:
201  ANN("case statement (pattern matching)");
202  ANN("format: case [nd_head]; [nd_body]; end");
203  ANN("example: case x; in 1; foo; in 2; bar; else baz; end");
204  F_NODE(nd_head, "case expr");
205  LAST_NODE;
206  F_NODE(nd_body, "in clauses");
207  return;
208 
209  case NODE_WHEN:
210  ANN("when clause");
211  ANN("format: when [nd_head]; [nd_body]; (when or else) [nd_next]");
212  ANN("example: case x; when 1; foo; when 2; bar; else baz; end");
213  F_NODE(nd_head, "when value");
214  F_NODE(nd_body, "when body");
215  LAST_NODE;
216  F_NODE(nd_next, "next when clause");
217  return;
218 
219  case NODE_IN:
220  ANN("in clause");
221  ANN("format: in [nd_head]; [nd_body]; (in or else) [nd_next]");
222  ANN("example: case x; in 1; foo; in 2; bar; else baz; end");
223  F_NODE(nd_head, "in pattern");
224  F_NODE(nd_body, "in body");
225  LAST_NODE;
226  F_NODE(nd_next, "next in clause");
227  return;
228 
229  case NODE_WHILE:
230  ANN("while statement");
231  ANN("format: while [nd_cond]; [nd_body]; end");
232  ANN("example: while x == 1; foo; end");
233  goto loop;
234  case NODE_UNTIL:
235  ANN("until statement");
236  ANN("format: until [nd_cond]; [nd_body]; end");
237  ANN("example: until x == 1; foo; end");
238  loop:
239  F_CUSTOM1(nd_state, "begin-end-while?") {
240  A_INT((int)node->nd_state);
241  A((node->nd_state == 1) ? " (while-end)" : " (begin-end-while)");
242  }
243  F_NODE(nd_cond, "condition");
244  LAST_NODE;
245  F_NODE(nd_body, "body");
246  return;
247 
248  case NODE_ITER:
249  ANN("method call with block");
250  ANN("format: [nd_iter] { [nd_body] }");
251  ANN("example: 3.times { foo }");
252  goto iter;
253  case NODE_FOR:
254  ANN("for statement");
255  ANN("format: for * in [nd_iter] do [nd_body] end");
256  ANN("example: for i in 1..3 do foo end");
257  iter:
258  F_NODE(nd_iter, "iteration receiver");
259  LAST_NODE;
260  F_NODE(nd_body, "body");
261  return;
262 
263  case NODE_FOR_MASGN:
264  ANN("vars of for statement with masgn");
265  ANN("format: for [nd_var] in ... do ... end");
266  ANN("example: for x, y in 1..3 do foo end");
267  LAST_NODE;
268  F_NODE(nd_var, "var");
269  return;
270 
271  case NODE_BREAK:
272  ANN("break statement");
273  ANN("format: break [nd_stts]");
274  ANN("example: break 1");
275  goto jump;
276  case NODE_NEXT:
277  ANN("next statement");
278  ANN("format: next [nd_stts]");
279  ANN("example: next 1");
280  goto jump;
281  case NODE_RETURN:
282  ANN("return statement");
283  ANN("format: return [nd_stts]");
284  ANN("example: return 1");
285  jump:
286  LAST_NODE;
287  F_NODE(nd_stts, "value");
288  return;
289 
290  case NODE_REDO:
291  ANN("redo statement");
292  ANN("format: redo");
293  ANN("example: redo");
294  return;
295 
296  case NODE_RETRY:
297  ANN("retry statement");
298  ANN("format: retry");
299  ANN("example: retry");
300  return;
301 
302  case NODE_BEGIN:
303  ANN("begin statement");
304  ANN("format: begin; [nd_body]; end");
305  ANN("example: begin; 1; end");
306  LAST_NODE;
307  F_NODE(nd_body, "body");
308  return;
309 
310  case NODE_RESCUE:
311  ANN("rescue clause");
312  ANN("format: begin; [nd_body]; (rescue) [nd_resq]; else [nd_else]; end");
313  ANN("example: begin; foo; rescue; bar; else; baz; end");
314  F_NODE(nd_head, "body");
315  F_NODE(nd_resq, "rescue clause list");
316  LAST_NODE;
317  F_NODE(nd_else, "rescue else clause");
318  return;
319 
320  case NODE_RESBODY:
321  ANN("rescue clause (cont'd)");
322  ANN("format: rescue [nd_args]; [nd_body]; (rescue) [nd_head]");
323  ANN("example: begin; foo; rescue; bar; else; baz; end");
324  F_NODE(nd_args, "rescue exceptions");
325  F_NODE(nd_body, "rescue clause");
326  LAST_NODE;
327  F_NODE(nd_head, "next rescue clause");
328  return;
329 
330  case NODE_ENSURE:
331  ANN("ensure clause");
332  ANN("format: begin; [nd_head]; ensure; [nd_ensr]; end");
333  ANN("example: begin; foo; ensure; bar; end");
334  F_NODE(nd_head, "body");
335  LAST_NODE;
336  F_NODE(nd_ensr, "ensure clause");
337  return;
338 
339  case NODE_AND:
340  ANN("&& operator");
341  ANN("format: [nd_1st] && [nd_2nd]");
342  ANN("example: foo && bar");
343  goto andor;
344  case NODE_OR:
345  ANN("|| operator");
346  ANN("format: [nd_1st] || [nd_2nd]");
347  ANN("example: foo || bar");
348  andor:
349  while (1) {
350  F_NODE(nd_1st, "left expr");
351  if (!node->nd_2nd || nd_type(node->nd_2nd) != (int)type)
352  break;
353  node = node->nd_2nd;
354  }
355  LAST_NODE;
356  F_NODE(nd_2nd, "right expr");
357  return;
358 
359  case NODE_MASGN:
360  ANN("multiple assignment");
361  ANN("format: [nd_head], [nd_args] = [nd_value]");
362  ANN("example: a, b = foo");
363  F_NODE(nd_value, "rhsn");
364  F_NODE(nd_head, "lhsn");
365  if (NODE_NAMED_REST_P(node->nd_args)) {
366  LAST_NODE;
367  F_NODE(nd_args, "splatn");
368  }
369  else {
370  F_MSG(nd_args, "splatn", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
371  }
372  return;
373 
374  case NODE_LASGN:
375  ANN("local variable assignment");
376  ANN("format: [nd_vid](lvar) = [nd_value]");
377  ANN("example: x = foo");
378  F_ID(nd_vid, "local variable");
379  if (NODE_REQUIRED_KEYWORD_P(node)) {
380  F_MSG(nd_value, "rvalue", "NODE_SPECIAL_REQUIRED_KEYWORD (required keyword argument)");
381  }
382  else {
383  LAST_NODE;
384  F_NODE(nd_value, "rvalue");
385  }
386  return;
387  case NODE_DASGN:
388  ANN("dynamic variable assignment (out of current scope)");
389  ANN("format: [nd_vid](dvar) = [nd_value]");
390  ANN("example: x = nil; 1.times { x = foo }");
391  F_ID(nd_vid, "local variable");
392  LAST_NODE;
393  F_NODE(nd_value, "rvalue");
394  return;
395  case NODE_DASGN_CURR:
396  ANN("dynamic variable assignment (in current scope)");
397  ANN("format: [nd_vid](current dvar) = [nd_value]");
398  ANN("example: 1.times { x = foo }");
399  F_ID(nd_vid, "local variable");
400  if (NODE_REQUIRED_KEYWORD_P(node)) {
401  F_MSG(nd_value, "rvalue", "NODE_SPECIAL_REQUIRED_KEYWORD (required keyword argument)");
402  }
403  else {
404  LAST_NODE;
405  F_NODE(nd_value, "rvalue");
406  }
407  return;
408  case NODE_IASGN:
409  ANN("instance variable assignment");
410  ANN("format: [nd_vid](ivar) = [nd_value]");
411  ANN("example: @x = foo");
412  F_ID(nd_vid, "instance variable");
413  LAST_NODE;
414  F_NODE(nd_value, "rvalue");
415  return;
416  case NODE_CVASGN:
417  ANN("class variable assignment");
418  ANN("format: [nd_vid](cvar) = [nd_value]");
419  ANN("example: @@x = foo");
420  F_ID(nd_vid, "class variable");
421  LAST_NODE;
422  F_NODE(nd_value, "rvalue");
423  return;
424  case NODE_GASGN:
425  ANN("global variable assignment");
426  ANN("format: [nd_entry](gvar) = [nd_value]");
427  ANN("example: $x = foo");
428  F_GENTRY(nd_entry, "global variable");
429  LAST_NODE;
430  F_NODE(nd_value, "rvalue");
431  return;
432 
433  case NODE_CDECL:
434  ANN("constant declaration");
435  ANN("format: [nd_else]::[nd_vid](constant) = [nd_value]");
436  ANN("example: X = foo");
437  if (node->nd_vid) {
438  F_ID(nd_vid, "constant");
439  F_MSG(nd_else, "extension", "not used");
440  }
441  else {
442  F_MSG(nd_vid, "constant", "0 (see extension field)");
443  F_NODE(nd_else, "extension");
444  }
445  LAST_NODE;
446  F_NODE(nd_value, "rvalue");
447  return;
448 
449  case NODE_OP_ASGN1:
450  ANN("array assignment with operator");
451  ANN("format: [nd_recv] [ [nd_args->nd_head] ] [nd_mid]= [nd_args->nd_body]");
452  ANN("example: ary[1] += foo");
453  F_NODE(nd_recv, "receiver");
454  F_ID(nd_mid, "operator");
455  F_NODE(nd_args->nd_head, "index");
456  LAST_NODE;
457  F_NODE(nd_args->nd_body, "rvalue");
458  return;
459 
460  case NODE_OP_ASGN2:
461  ANN("attr assignment with operator");
462  ANN("format: [nd_recv].[attr] [nd_next->nd_mid]= [nd_value]");
463  ANN(" where [attr]: [nd_next->nd_vid]");
464  ANN("example: struct.field += foo");
465  F_NODE(nd_recv, "receiver");
466  F_CUSTOM1(nd_next->nd_vid, "attr") {
467  if (node->nd_next->nd_aid) A("? ");
468  A_ID(node->nd_next->nd_vid);
469  }
470  F_ID(nd_next->nd_mid, "operator");
471  LAST_NODE;
472  F_NODE(nd_value, "rvalue");
473  return;
474 
475  case NODE_OP_ASGN_AND:
476  ANN("assignment with && operator");
477  ANN("format: [nd_head] &&= [nd_value]");
478  ANN("example: foo &&= bar");
479  goto asgn_andor;
480  case NODE_OP_ASGN_OR:
481  ANN("assignment with || operator");
482  ANN("format: [nd_head] ||= [nd_value]");
483  ANN("example: foo ||= bar");
484  asgn_andor:
485  F_NODE(nd_head, "variable");
486  LAST_NODE;
487  F_NODE(nd_value, "rvalue");
488  return;
489 
490  case NODE_OP_CDECL:
491  ANN("constant declaration with operator");
492  ANN("format: [nd_head](constant) [nd_aid]= [nd_value]");
493  ANN("example: A::B ||= 1");
494  F_NODE(nd_head, "constant");
495  F_ID(nd_aid, "operator");
496  LAST_NODE;
497  F_NODE(nd_value, "rvalue");
498  return;
499 
500  case NODE_CALL:
501  ANN("method invocation");
502  ANN("format: [nd_recv].[nd_mid]([nd_args])");
503  ANN("example: obj.foo(1)");
504  F_ID(nd_mid, "method id");
505  F_NODE(nd_recv, "receiver");
506  LAST_NODE;
507  F_NODE(nd_args, "arguments");
508  return;
509 
510  case NODE_OPCALL:
511  ANN("method invocation");
512  ANN("format: [nd_recv] [nd_mid] [nd_args]");
513  ANN("example: foo + bar");
514  F_ID(nd_mid, "method id");
515  F_NODE(nd_recv, "receiver");
516  LAST_NODE;
517  F_NODE(nd_args, "arguments");
518  return;
519 
520  case NODE_FCALL:
521  ANN("function call");
522  ANN("format: [nd_mid]([nd_args])");
523  ANN("example: foo(1)");
524  F_ID(nd_mid, "method id");
525  LAST_NODE;
526  F_NODE(nd_args, "arguments");
527  return;
528 
529  case NODE_VCALL:
530  ANN("function call with no argument");
531  ANN("format: [nd_mid]");
532  ANN("example: foo");
533  F_ID(nd_mid, "method id");
534  return;
535 
536  case NODE_QCALL:
537  ANN("safe method invocation");
538  ANN("format: [nd_recv]&.[nd_mid]([nd_args])");
539  ANN("example: obj&.foo(1)");
540  F_ID(nd_mid, "method id");
541  F_NODE(nd_recv, "receiver");
542  LAST_NODE;
543  F_NODE(nd_args, "arguments");
544  return;
545 
546  case NODE_SUPER:
547  ANN("super invocation");
548  ANN("format: super [nd_args]");
549  ANN("example: super 1");
550  LAST_NODE;
551  F_NODE(nd_args, "arguments");
552  return;
553 
554  case NODE_ZSUPER:
555  ANN("super invocation with no argument");
556  ANN("format: super");
557  ANN("example: super");
558  return;
559 
560  case NODE_LIST:
561  ANN("list constructor");
562  ANN("format: [ [nd_head], [nd_next].. ] (length: [nd_alen])");
563  ANN("example: [1, 2, 3]");
564  goto ary;
565  case NODE_VALUES:
566  ANN("return arguments");
567  ANN("format: [ [nd_head], [nd_next].. ] (length: [nd_alen])");
568  ANN("example: return 1, 2, 3");
569  ary:
570  dump_array(buf, indent, comment, node);
571  return;
572 
573  case NODE_ZLIST:
574  ANN("empty list constructor");
575  ANN("format: []");
576  ANN("example: []");
577  return;
578 
579  case NODE_HASH:
580  if (!node->nd_brace) {
581  ANN("keyword arguments");
582  ANN("format: nd_head");
583  ANN("example: a: 1, b: 2");
584  }
585  else {
586  ANN("hash constructor");
587  ANN("format: { [nd_head] }");
588  ANN("example: { 1 => 2, 3 => 4 }");
589  }
590  F_CUSTOM1(nd_brace, "keyword arguments or hash literal") {
591  switch (node->nd_brace) {
592  case 0: A("0 (keyword argument)"); break;
593  case 1: A("1 (hash literal)"); break;
594  }
595  }
596  LAST_NODE;
597  F_NODE(nd_head, "contents");
598  return;
599 
600  case NODE_YIELD:
601  ANN("yield invocation");
602  ANN("format: yield [nd_head]");
603  ANN("example: yield 1");
604  LAST_NODE;
605  F_NODE(nd_head, "arguments");
606  return;
607 
608  case NODE_LVAR:
609  ANN("local variable reference");
610  ANN("format: [nd_vid](lvar)");
611  ANN("example: x");
612  F_ID(nd_vid, "local variable");
613  return;
614  case NODE_DVAR:
615  ANN("dynamic variable reference");
616  ANN("format: [nd_vid](dvar)");
617  ANN("example: 1.times { x = 1; x }");
618  F_ID(nd_vid, "local variable");
619  return;
620  case NODE_IVAR:
621  ANN("instance variable reference");
622  ANN("format: [nd_vid](ivar)");
623  ANN("example: @x");
624  F_ID(nd_vid, "instance variable");
625  return;
626  case NODE_CONST:
627  ANN("constant reference");
628  ANN("format: [nd_vid](constant)");
629  ANN("example: X");
630  F_ID(nd_vid, "constant");
631  return;
632  case NODE_CVAR:
633  ANN("class variable reference");
634  ANN("format: [nd_vid](cvar)");
635  ANN("example: @@x");
636  F_ID(nd_vid, "class variable");
637  return;
638 
639  case NODE_GVAR:
640  ANN("global variable reference");
641  ANN("format: [nd_entry](gvar)");
642  ANN("example: $x");
643  F_GENTRY(nd_entry, "global variable");
644  return;
645 
646  case NODE_NTH_REF:
647  ANN("nth special variable reference");
648  ANN("format: $[nd_nth]");
649  ANN("example: $1, $2, ..");
650  F_CUSTOM1(nd_nth, "variable") { A("$"); A_LONG(node->nd_nth); }
651  return;
652 
653  case NODE_BACK_REF:
654  ANN("back special variable reference");
655  ANN("format: $[nd_nth]");
656  ANN("example: $&, $`, $', $+");
657  F_CUSTOM1(nd_nth, "variable") {
658  char name[3];
659  name[0] = '$';
660  name[1] = (char)node->nd_nth;
661  name[2] = '\0';
662  A(name);
663  }
664  return;
665 
666  case NODE_MATCH:
667  ANN("match expression (against $_ implicitly)");
668  ANN("format: [nd_lit] (in condition)");
669  ANN("example: if /foo/; foo; end");
670  F_LIT(nd_lit, "regexp");
671  return;
672 
673  case NODE_MATCH2:
674  ANN("match expression (regexp first)");
675  ANN("format: [nd_recv] =~ [nd_value]");
676  ANN("example: /foo/ =~ 'foo'");
677  F_NODE(nd_recv, "regexp (receiver)");
678  if (!node->nd_args) LAST_NODE;
679  F_NODE(nd_value, "string (argument)");
680  if (node->nd_args) {
681  LAST_NODE;
682  F_NODE(nd_args, "named captures");
683  }
684  return;
685 
686  case NODE_MATCH3:
687  ANN("match expression (regexp second)");
688  ANN("format: [nd_recv] =~ [nd_value]");
689  ANN("example: 'foo' =~ /foo/");
690  F_NODE(nd_recv, "string (receiver)");
691  LAST_NODE;
692  F_NODE(nd_value, "regexp (argument)");
693  return;
694 
695  case NODE_LIT:
696  ANN("literal");
697  ANN("format: [nd_lit]");
698  ANN("example: 1, /foo/");
699  goto lit;
700  case NODE_STR:
701  ANN("string literal");
702  ANN("format: [nd_lit]");
703  ANN("example: 'foo'");
704  goto lit;
705  case NODE_XSTR:
706  ANN("xstring literal");
707  ANN("format: [nd_lit]");
708  ANN("example: `foo`");
709  lit:
710  F_LIT(nd_lit, "literal");
711  return;
712 
713  case NODE_ONCE:
714  ANN("once evaluation");
715  ANN("format: [nd_body]");
716  ANN("example: /foo#{ bar }baz/o");
717  LAST_NODE;
718  F_NODE(nd_body, "body");
719  return;
720  case NODE_DSTR:
721  ANN("string literal with interpolation");
722  ANN("format: [nd_lit]");
723  ANN("example: \"foo#{ bar }baz\"");
724  goto dlit;
725  case NODE_DXSTR:
726  ANN("xstring literal with interpolation");
727  ANN("format: [nd_lit]");
728  ANN("example: `foo#{ bar }baz`");
729  goto dlit;
730  case NODE_DREGX:
731  ANN("regexp literal with interpolation");
732  ANN("format: [nd_lit]");
733  ANN("example: /foo#{ bar }baz/");
734  goto dlit;
735  case NODE_DSYM:
736  ANN("symbol literal with interpolation");
737  ANN("format: [nd_lit]");
738  ANN("example: :\"foo#{ bar }baz\"");
739  dlit:
740  F_LIT(nd_lit, "preceding string");
741  F_NODE(nd_next->nd_head, "interpolation");
742  LAST_NODE;
743  F_NODE(nd_next->nd_next, "tailing strings");
744  return;
745 
746  case NODE_EVSTR:
747  ANN("interpolation expression");
748  ANN("format: \"..#{ [nd_lit] }..\"");
749  ANN("example: \"foo#{ bar }baz\"");
750  LAST_NODE;
751  F_NODE(nd_body, "body");
752  return;
753 
754  case NODE_ARGSCAT:
755  ANN("splat argument following arguments");
756  ANN("format: ..(*[nd_head], [nd_body..])");
757  ANN("example: foo(*ary, post_arg1, post_arg2)");
758  F_NODE(nd_head, "preceding array");
759  LAST_NODE;
760  F_NODE(nd_body, "following array");
761  return;
762 
763  case NODE_ARGSPUSH:
764  ANN("splat argument following one argument");
765  ANN("format: ..(*[nd_head], [nd_body])");
766  ANN("example: foo(*ary, post_arg)");
767  F_NODE(nd_head, "preceding array");
768  LAST_NODE;
769  F_NODE(nd_body, "following element");
770  return;
771 
772  case NODE_SPLAT:
773  ANN("splat argument");
774  ANN("format: *[nd_head]");
775  ANN("example: foo(*ary)");
776  LAST_NODE;
777  F_NODE(nd_head, "splat'ed array");
778  return;
779 
780  case NODE_BLOCK_PASS:
781  ANN("arguments with block argument");
782  ANN("format: ..([nd_head], &[nd_body])");
783  ANN("example: foo(x, &blk)");
784  F_NODE(nd_head, "other arguments");
785  LAST_NODE;
786  F_NODE(nd_body, "block argument");
787  return;
788 
789  case NODE_DEFN:
790  ANN("method definition");
791  ANN("format: def [nd_mid] [nd_defn]; end");
792  ANN("example: def foo; bar; end");
793  F_ID(nd_mid, "method name");
794  LAST_NODE;
795  F_NODE(nd_defn, "method definition");
796  return;
797 
798  case NODE_DEFS:
799  ANN("singleton method definition");
800  ANN("format: def [nd_recv].[nd_mid] [nd_defn]; end");
801  ANN("example: def obj.foo; bar; end");
802  F_NODE(nd_recv, "receiver");
803  F_ID(nd_mid, "method name");
804  LAST_NODE;
805  F_NODE(nd_defn, "method definition");
806  return;
807 
808  case NODE_ALIAS:
809  ANN("method alias statement");
810  ANN("format: alias [nd_1st] [nd_2nd]");
811  ANN("example: alias bar foo");
812  F_NODE(nd_1st, "new name");
813  LAST_NODE;
814  F_NODE(nd_2nd, "old name");
815  return;
816 
817  case NODE_VALIAS:
818  ANN("global variable alias statement");
819  ANN("format: alias [nd_alias](gvar) [nd_orig](gvar)");
820  ANN("example: alias $y $x");
821  F_ID(nd_alias, "new name");
822  F_ID(nd_orig, "old name");
823  return;
824 
825  case NODE_UNDEF:
826  ANN("method undef statement");
827  ANN("format: undef [nd_undef]");
828  ANN("example: undef foo");
829  LAST_NODE;
830  F_NODE(nd_undef, "old name");
831  return;
832 
833  case NODE_CLASS:
834  ANN("class definition");
835  ANN("format: class [nd_cpath] < [nd_super]; [nd_body]; end");
836  ANN("example: class C2 < C; ..; end");
837  F_NODE(nd_cpath, "class path");
838  F_NODE(nd_super, "superclass");
839  LAST_NODE;
840  F_NODE(nd_body, "class definition");
841  return;
842 
843  case NODE_MODULE:
844  ANN("module definition");
845  ANN("format: module [nd_cpath]; [nd_body]; end");
846  ANN("example: module M; ..; end");
847  F_NODE(nd_cpath, "module path");
848  LAST_NODE;
849  F_NODE(nd_body, "module definition");
850  return;
851 
852  case NODE_SCLASS:
853  ANN("singleton class definition");
854  ANN("format: class << [nd_recv]; [nd_body]; end");
855  ANN("example: class << obj; ..; end");
856  F_NODE(nd_recv, "receiver");
857  LAST_NODE;
858  F_NODE(nd_body, "singleton class definition");
859  return;
860 
861  case NODE_COLON2:
862  ANN("scoped constant reference");
863  ANN("format: [nd_head]::[nd_mid]");
864  ANN("example: M::C");
865  F_ID(nd_mid, "constant name");
866  LAST_NODE;
867  F_NODE(nd_head, "receiver");
868  return;
869 
870  case NODE_COLON3:
871  ANN("top-level constant reference");
872  ANN("format: ::[nd_mid]");
873  ANN("example: ::Object");
874  F_ID(nd_mid, "constant name");
875  return;
876 
877  case NODE_DOT2:
878  ANN("range constructor (incl.)");
879  ANN("format: [nd_beg]..[nd_end]");
880  ANN("example: 1..5");
881  goto dot;
882  case NODE_DOT3:
883  ANN("range constructor (excl.)");
884  ANN("format: [nd_beg]...[nd_end]");
885  ANN("example: 1...5");
886  goto dot;
887  case NODE_FLIP2:
888  ANN("flip-flop condition (incl.)");
889  ANN("format: [nd_beg]..[nd_end]");
890  ANN("example: if (x==1)..(x==5); foo; end");
891  goto dot;
892  case NODE_FLIP3:
893  ANN("flip-flop condition (excl.)");
894  ANN("format: [nd_beg]...[nd_end]");
895  ANN("example: if (x==1)...(x==5); foo; end");
896  dot:
897  F_NODE(nd_beg, "begin");
898  LAST_NODE;
899  F_NODE(nd_end, "end");
900  return;
901 
902  case NODE_SELF:
903  ANN("self");
904  ANN("format: self");
905  ANN("example: self");
906  return;
907 
908  case NODE_NIL:
909  ANN("nil");
910  ANN("format: nil");
911  ANN("example: nil");
912  return;
913 
914  case NODE_TRUE:
915  ANN("true");
916  ANN("format: true");
917  ANN("example: true");
918  return;
919 
920  case NODE_FALSE:
921  ANN("false");
922  ANN("format: false");
923  ANN("example: false");
924  return;
925 
926  case NODE_ERRINFO:
927  ANN("virtual reference to $!");
928  ANN("format: rescue => id");
929  ANN("example: rescue => id");
930  return;
931 
932  case NODE_DEFINED:
933  ANN("defined? expression");
934  ANN("format: defined?([nd_head])");
935  ANN("example: defined?(foo)");
936  F_NODE(nd_head, "expr");
937  return;
938 
939  case NODE_POSTEXE:
940  ANN("post-execution");
941  ANN("format: END { [nd_body] }");
942  ANN("example: END { foo }");
943  LAST_NODE;
944  F_NODE(nd_body, "END clause");
945  return;
946 
947  case NODE_ATTRASGN:
948  ANN("attr assignment");
949  ANN("format: [nd_recv].[nd_mid] = [nd_args]");
950  ANN("example: struct.field = foo");
951  F_NODE(nd_recv, "receiver");
952  F_ID(nd_mid, "method name");
953  LAST_NODE;
954  F_NODE(nd_args, "arguments");
955  return;
956 
957  case NODE_LAMBDA:
958  ANN("lambda expression");
959  ANN("format: -> [nd_body]");
960  ANN("example: -> { foo }");
961  LAST_NODE;
962  F_NODE(nd_body, "lambda clause");
963  return;
964 
965  case NODE_OPT_ARG:
966  ANN("optional arguments");
967  ANN("format: def method_name([nd_body=some], [nd_next..])");
968  ANN("example: def foo(a, b=1, c); end");
969  F_NODE(nd_body, "body");
970  LAST_NODE;
971  F_NODE(nd_next, "next");
972  return;
973 
974  case NODE_KW_ARG:
975  ANN("keyword arguments");
976  ANN("format: def method_name([nd_body=some], [nd_next..])");
977  ANN("example: def foo(a:1, b:2); end");
978  F_NODE(nd_body, "body");
979  LAST_NODE;
980  F_NODE(nd_next, "next");
981  return;
982 
983  case NODE_POSTARG:
984  ANN("post arguments");
985  ANN("format: *[nd_1st], [nd_2nd..] = ..");
986  ANN("example: a, *rest, z = foo");
987  if (NODE_NAMED_REST_P(node->nd_1st)) {
988  F_NODE(nd_1st, "rest argument");
989  }
990  else {
991  F_MSG(nd_1st, "rest argument", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
992  }
993  LAST_NODE;
994  F_NODE(nd_2nd, "post arguments");
995  return;
996 
997  case NODE_ARGS:
998  ANN("method parameters");
999  ANN("format: def method_name(.., [nd_opt=some], *[nd_rest], [nd_pid], .., &[nd_body])");
1000  ANN("example: def foo(a, b, opt1=1, opt2=2, *rest, y, z, &blk); end");
1001  F_INT(nd_ainfo->pre_args_num, "count of mandatory (pre-)arguments");
1002  F_NODE(nd_ainfo->pre_init, "initialization of (pre-)arguments");
1003  F_INT(nd_ainfo->post_args_num, "count of mandatory post-arguments");
1004  F_NODE(nd_ainfo->post_init, "initialization of post-arguments");
1005  F_ID(nd_ainfo->first_post_arg, "first post argument");
1006  F_CUSTOM1(nd_ainfo->rest_arg, "rest argument") {
1007  if (node->nd_ainfo->rest_arg == NODE_SPECIAL_EXCESSIVE_COMMA) {
1008  A("1 (excessed comma)");
1009  }
1010  else {
1011  A_ID(node->nd_ainfo->rest_arg);
1012  }
1013  }
1014  F_ID(nd_ainfo->block_arg, "block argument");
1015  F_NODE(nd_ainfo->opt_args, "optional arguments");
1016  F_NODE(nd_ainfo->kw_args, "keyword arguments");
1017  LAST_NODE;
1018  F_NODE(nd_ainfo->kw_rest_arg, "keyword rest argument");
1019  return;
1020 
1021  case NODE_SCOPE:
1022  ANN("new scope");
1023  ANN("format: [nd_tbl]: local table, [nd_args]: arguments, [nd_body]: body");
1024  F_CUSTOM1(nd_tbl, "local table") {
1025  ID *tbl = node->nd_tbl;
1026  int i;
1027  int size = tbl ? (int)*tbl++ : 0;
1028  if (size == 0) A("(empty)");
1029  for (i = 0; i < size; i++) {
1030  A_ID(tbl[i]); if (i < size - 1) A(",");
1031  }
1032  }
1033  F_NODE(nd_args, "arguments");
1034  LAST_NODE;
1035  F_NODE(nd_body, "body");
1036  return;
1037 
1038  case NODE_ARYPTN:
1039  ANN("array pattern");
1040  ANN("format: [nd_pconst]([pre_args], ..., *[rest_arg], [post_args], ...)");
1041  F_NODE(nd_pconst, "constant");
1042  F_NODE(nd_apinfo->pre_args, "pre arguments");
1043  if (NODE_NAMED_REST_P(node->nd_apinfo->rest_arg)) {
1044  F_NODE(nd_apinfo->rest_arg, "rest argument");
1045  }
1046  else {
1047  F_MSG(nd_apinfo->rest_arg, "rest argument", "NODE_SPECIAL_NO_NAME_REST (rest argument without name)");
1048  }
1049  LAST_NODE;
1050  F_NODE(nd_apinfo->post_args, "post arguments");
1051  return;
1052 
1053  case NODE_HSHPTN:
1054  ANN("hash pattern");
1055  ANN("format: [nd_pconst]([nd_pkwargs], ..., **[nd_pkwrestarg])");
1056  F_NODE(nd_pconst, "constant");
1057  F_NODE(nd_pkwargs, "keyword arguments");
1058  LAST_NODE;
1059  if (node->nd_pkwrestarg == NODE_SPECIAL_NO_REST_KEYWORD) {
1060  F_MSG(nd_pkwrestarg, "keyword rest argument", "NODE_SPECIAL_NO_REST_KEYWORD (**nil)");
1061  }
1062  else {
1063  F_NODE(nd_pkwrestarg, "keyword rest argument");
1064  }
1065  return;
1066 
1067  case NODE_ARGS_AUX:
1068  case NODE_LAST:
1069  break;
1070  }
1071 
1072  rb_bug("dump_node: unknown node: %s", ruby_node_name(nd_type(node)));
1073 }
1074 
1075 VALUE
1076 rb_parser_dump_tree(const NODE *node, int comment)
1077 {
1079  "###########################################################\n"
1080  "## Do NOT use this node dump for any purpose other than ##\n"
1081  "## debug and research. Compatibility is not guaranteed. ##\n"
1082  "###########################################################\n\n"
1083  );
1084  dump_node(buf, rb_str_new_cstr("# "), comment, node);
1085  return buf;
1086 }
1087 
1088 /* Setup NODE structure.
1089  * NODE is not an object managed by GC, but it imitates an object
1090  * so that it can work with `RB_TYPE_P(obj, T_NODE)`.
1091  * This dirty hack is needed because Ripper jumbles NODEs and other type
1092  * objects.
1093  */
1094 void
1096 {
1097  n->flags = T_NODE;
1098  nd_set_type(n, type);
1099  n->u1.value = a0;
1100  n->u2.value = a1;
1101  n->u3.value = a2;
1102  n->nd_loc.beg_pos.lineno = 0;
1103  n->nd_loc.beg_pos.column = 0;
1104  n->nd_loc.end_pos.lineno = 0;
1105  n->nd_loc.end_pos.column = 0;
1106 }
1107 
1108 typedef struct node_buffer_elem_struct {
1110  long len;
1113 
1114 typedef struct {
1115  long idx, len;
1119 
1125 };
1126 
1127 static void
1128 init_node_buffer_list(node_buffer_list_t * nb, node_buffer_elem_t *head)
1129 {
1130  nb->idx = 0;
1131  nb->len = NODE_BUF_DEFAULT_LEN;
1132  nb->head = nb->last = head;
1133  nb->head->len = nb->len;
1134  nb->head->next = NULL;
1135 }
1136 
1137 static node_buffer_t *
1138 rb_node_buffer_new(void)
1139 {
1140  const size_t bucket_size = offsetof(node_buffer_elem_t, buf) + NODE_BUF_DEFAULT_LEN * sizeof(NODE);
1141  const size_t alloc_size = sizeof(node_buffer_t) + (bucket_size * 2);
1142  STATIC_ASSERT(
1143  integer_overflow,
1145  > sizeof(node_buffer_t) + 2 * sizeof(node_buffer_elem_t));
1146  node_buffer_t *nb = ruby_xmalloc(alloc_size);
1147  init_node_buffer_list(&nb->unmarkable, (node_buffer_elem_t*)&nb[1]);
1148  init_node_buffer_list(&nb->markable, (node_buffer_elem_t*)((size_t)nb->unmarkable.head + bucket_size));
1149  nb->local_tables = 0;
1150  nb->mark_hash = Qnil;
1151  return nb;
1152 }
1153 
1154 static void
1155 node_buffer_list_free(node_buffer_list_t * nb)
1156 {
1157  node_buffer_elem_t *nbe = nb->head;
1158 
1159  while (nbe != nb->last) {
1160  void *buf = nbe;
1161  nbe = nbe->next;
1162  xfree(buf);
1163  }
1164 }
1165 
1166 static void
1167 rb_node_buffer_free(node_buffer_t *nb)
1168 {
1169  node_buffer_list_free(&nb->unmarkable);
1170  node_buffer_list_free(&nb->markable);
1171  ID * local_table = nb->local_tables;
1172  while (local_table) {
1173  unsigned int size = (unsigned int)*local_table;
1174  ID * next_table = (ID *)local_table[size + 1];
1175  xfree(local_table);
1176  local_table = next_table;
1177  }
1178  xfree(nb);
1179 }
1180 
1181 static NODE *
1182 ast_newnode_in_bucket(node_buffer_list_t *nb)
1183 {
1184  if (nb->idx >= nb->len) {
1185  long n = nb->len * 2;
1186  node_buffer_elem_t *nbe;
1188  nbe->len = n;
1189  nb->idx = 0;
1190  nb->len = n;
1191  nbe->next = nb->head;
1192  nb->head = nbe;
1193  }
1194  return &nb->head->buf[nb->idx++];
1195 }
1196 
1197 NODE *
1199 {
1200  node_buffer_t *nb = ast->node_buffer;
1201  switch (type) {
1202  case NODE_MATCH:
1203  case NODE_LIT:
1204  case NODE_STR:
1205  case NODE_XSTR:
1206  case NODE_DSTR:
1207  case NODE_DXSTR:
1208  case NODE_DREGX:
1209  case NODE_DSYM:
1210  case NODE_ARGS:
1211  case NODE_ARYPTN:
1212  return ast_newnode_in_bucket(&nb->markable);
1213  default:
1214  return ast_newnode_in_bucket(&nb->unmarkable);
1215  }
1216 }
1217 
1218 void
1220 {
1221  unsigned int size = (unsigned int)*buf;
1222  buf[size + 1] = (ID)ast->node_buffer->local_tables;
1223  ast->node_buffer->local_tables = buf;
1224 }
1225 
1226 void
1228 {
1229  (void)ast;
1230  (void)n;
1231  /* should we implement freelist? */
1232 }
1233 
1234 rb_ast_t *
1236 {
1237  node_buffer_t *nb = rb_node_buffer_new();
1238  rb_ast_t *ast = (rb_ast_t *)rb_imemo_new(imemo_ast, 0, 0, 0, (VALUE)nb);
1239  return ast;
1240 }
1241 
1242 typedef void node_itr_t(void *ctx, NODE * node);
1243 
1244 static void
1245 iterate_buffer_elements(node_buffer_elem_t *nbe, long len, node_itr_t *func, void *ctx)
1246 {
1247  long cursor;
1248  for (cursor = 0; cursor < len; cursor++) {
1249  func(ctx, &nbe->buf[cursor]);
1250  }
1251 }
1252 
1253 static void
1254 iterate_node_values(node_buffer_list_t *nb, node_itr_t * func, void *ctx)
1255 {
1256  node_buffer_elem_t *nbe = nb->head;
1257 
1258  /* iterate over the head first because it's not full */
1259  iterate_buffer_elements(nbe, nb->idx, func, ctx);
1260 
1261  nbe = nbe->next;
1262  while (nbe) {
1263  iterate_buffer_elements(nbe, nbe->len, func, ctx);
1264  nbe = nbe->next;
1265  }
1266 }
1267 
1268 static void
1269 mark_ast_value(void *ctx, NODE * node)
1270 {
1271  switch (nd_type(node)) {
1272  case NODE_ARYPTN:
1273  {
1274  struct rb_ary_pattern_info *apinfo = node->nd_apinfo;
1275  rb_gc_mark_movable(apinfo->imemo);
1276  break;
1277  }
1278  case NODE_ARGS:
1279  {
1280  struct rb_args_info *args = node->nd_ainfo;
1281  rb_gc_mark_movable(args->imemo);
1282  break;
1283  }
1284  case NODE_MATCH:
1285  case NODE_LIT:
1286  case NODE_STR:
1287  case NODE_XSTR:
1288  case NODE_DSTR:
1289  case NODE_DXSTR:
1290  case NODE_DREGX:
1291  case NODE_DSYM:
1292  rb_gc_mark_movable(node->nd_lit);
1293  break;
1294  default:
1295  rb_bug("unreachable node %s", ruby_node_name(nd_type(node)));
1296  }
1297 }
1298 
1299 static void
1300 update_ast_value(void *ctx, NODE * node)
1301 {
1302  switch (nd_type(node)) {
1303  case NODE_ARYPTN:
1304  {
1305  struct rb_ary_pattern_info *apinfo = node->nd_apinfo;
1306  apinfo->imemo = rb_gc_location(apinfo->imemo);
1307  break;
1308  }
1309  case NODE_ARGS:
1310  {
1311  struct rb_args_info *args = node->nd_ainfo;
1312  args->imemo = rb_gc_location(args->imemo);
1313  break;
1314  }
1315  case NODE_LIT:
1316  case NODE_STR:
1317  case NODE_XSTR:
1318  case NODE_DSTR:
1319  case NODE_DXSTR:
1320  case NODE_DREGX:
1321  case NODE_DSYM:
1322  node->nd_lit = rb_gc_location(node->nd_lit);
1323  break;
1324  default:
1325  rb_bug("unreachable");
1326  }
1327 }
1328 
1329 void
1331 {
1332  if (ast->node_buffer) {
1333  node_buffer_t *nb = ast->node_buffer;
1334 
1335  iterate_node_values(&nb->markable, update_ast_value, NULL);
1336  }
1337 }
1338 
1339 void
1341 {
1342  if (ast->node_buffer) rb_gc_mark(ast->node_buffer->mark_hash);
1344  if (ast->node_buffer) {
1345  node_buffer_t *nb = ast->node_buffer;
1346 
1347  iterate_node_values(&nb->markable, mark_ast_value, NULL);
1348  }
1349 }
1350 
1351 void
1353 {
1354  if (ast->node_buffer) {
1355  rb_node_buffer_free(ast->node_buffer);
1356  ast->node_buffer = 0;
1357  }
1358 }
1359 
1360 static size_t
1361 buffer_list_size(node_buffer_list_t *nb)
1362 {
1363  size_t size = 0;
1364  node_buffer_elem_t *nbe = nb->head;
1365  while (nbe != nb->last) {
1366  nbe = nbe->next;
1367  size += offsetof(node_buffer_elem_t, buf) + nb->len * sizeof(NODE);
1368  }
1369  return size;
1370 }
1371 
1372 size_t
1374 {
1375  size_t size = 0;
1376  node_buffer_t *nb = ast->node_buffer;
1377 
1378  if (nb) {
1380  size += buffer_list_size(&nb->unmarkable);
1381  size += buffer_list_size(&nb->markable);
1382  }
1383  return size;
1384 }
1385 
1386 void
1388 {
1389  rb_ast_free(ast);
1390 }
1391 
1392 void
1394 {
1395  if (NIL_P(ast->node_buffer->mark_hash)) {
1396  RB_OBJ_WRITE(ast, &ast->node_buffer->mark_hash, rb_ident_hash_new());
1397  }
1398  rb_hash_aset(ast->node_buffer->mark_hash, obj, Qtrue);
1399 }
NODE_NEXT
@ NODE_NEXT
Definition: node.h:38
NODE_COLON3
@ NODE_COLON3
Definition: node.h:110
NODE_NIL
@ NODE_NIL
Definition: node.h:116
ID
unsigned long ID
Definition: ruby.h:103
ruby_node_name
const char * ruby_node_name(int node)
Definition: iseq.c:2534
node_buffer_elem_struct::next
struct node_buffer_elem_struct * next
Definition: node.c:1109
add_option_arg
Definition: node.c:102
NODE_ATTRASGN
@ NODE_ATTRASGN
Definition: node.h:123
NODE_DSYM
@ NODE_DSYM
Definition: node.h:122
rb_ast_newnode
NODE * rb_ast_newnode(rb_ast_t *ast, enum node_type type)
Definition: node.c:1198
NODE_HSHPTN
@ NODE_HSHPTN
Definition: node.h:126
NODE_RESCUE
@ NODE_RESCUE
Definition: node.h:42
rb_ast_struct::body
rb_ast_body_t body
Definition: node.h:402
nd_state
#define nd_state
Definition: node.h:263
F_GENTRY
#define F_GENTRY(name, ann)
Definition: node.c:63
NODE_OP_ASGN1
@ NODE_OP_ASGN1
Definition: node.h:55
nd_head
#define nd_head
Definition: node.h:214
rb_ident_hash_new
VALUE rb_ident_hash_new(void)
Definition: hash.c:4278
node_buffer_struct::mark_hash
VALUE mark_hash
Definition: node.c:1124
nd_orig
#define nd_orig
Definition: node.h:271
NODE_TRUE
@ NODE_TRUE
Definition: node.h:117
node_itr_t
void node_itr_t(void *ctx, NODE *node)
Definition: node.c:1242
NODE_MATCH3
@ NODE_MATCH3
Definition: node.h:83
NODE_NTH_REF
@ NODE_NTH_REF
Definition: node.h:79
NODE_ZLIST
@ NODE_ZLIST
Definition: node.h:68
NODE_SPECIAL_EXCESSIVE_COMMA
#define NODE_SPECIAL_EXCESSIVE_COMMA
Definition: node.h:385
NODE_DREGX
@ NODE_DREGX
Definition: node.h:90
node_buffer_list_t::last
node_buffer_elem_t * last
Definition: node.c:1117
NODE_OR
@ NODE_OR
Definition: node.h:46
int
__inline__ int
Definition: rb_mjit_min_header-2.7.2.h:2845
NODE_ARYPTN
@ NODE_ARYPTN
Definition: node.h:125
rb_ast_dispose
void rb_ast_dispose(rb_ast_t *ast)
Definition: node.c:1387
NODE_OP_ASGN_OR
@ NODE_OP_ASGN_OR
Definition: node.h:58
nd_pconst
#define nd_pconst
Definition: node.h:276
NODE_HASH
@ NODE_HASH
Definition: node.h:70
ruby_xmalloc
void * ruby_xmalloc(size_t size)
Definition: gc.c:11978
NODE_CONST
@ NODE_CONST
Definition: node.h:77
node_buffer_struct::unmarkable
node_buffer_list_t unmarkable
Definition: node.c:1121
i
uint32_t i
Definition: rb_mjit_min_header-2.7.2.h:5460
NODE_LASGN
@ NODE_LASGN
Definition: node.h:48
A_LONG
#define A_LONG(val)
Definition: node.c:25
NODE_FLIP2
@ NODE_FLIP2
Definition: node.h:113
NODE_ARGSPUSH
@ NODE_ARGSPUSH
Definition: node.h:98
NODE_FOR
@ NODE_FOR
Definition: node.h:35
NODE_BUF_DEFAULT_LEN
#define NODE_BUF_DEFAULT_LEN
Definition: node.c:15
VALUE
unsigned long VALUE
Definition: ruby.h:102
NODE_CASE
@ NODE_CASE
Definition: node.h:27
offsetof
#define offsetof(p_type, field)
Definition: addrinfo.h:186
NODE_OP_ASGN2
@ NODE_OP_ASGN2
Definition: node.h:56
NODE_ARGSCAT
@ NODE_ARGSCAT
Definition: node.h:97
rb_xmalloc_mul_add
void * rb_xmalloc_mul_add(size_t x, size_t y, size_t z)
Definition: gc.c:10176
rb_gc_location
VALUE rb_gc_location(VALUE value)
Definition: gc.c:8114
NODE_DOT2
@ NODE_DOT2
Definition: node.h:111
NODE_EVSTR
@ NODE_EVSTR
Definition: node.h:89
nd_stts
#define nd_stts
Definition: node.h:228
rb_ast_mark
void rb_ast_mark(rb_ast_t *ast)
Definition: node.c:1340
NODE_UNTIL
@ NODE_UNTIL
Definition: node.h:33
NODE_CVASGN
@ NODE_CVASGN
Definition: node.h:54
NODE_AND
@ NODE_AND
Definition: node.h:45
NODE_LIT
@ NODE_LIT
Definition: node.h:84
NODE_MASGN
@ NODE_MASGN
Definition: node.h:47
nd_vid
#define nd_vid
Definition: node.h:231
NODE_DXSTR
@ NODE_DXSTR
Definition: node.h:88
NODE_OPCALL
@ NODE_OPCALL
Definition: node.h:61
NODE_SPECIAL_NO_REST_KEYWORD
#define NODE_SPECIAL_NO_REST_KEYWORD
Definition: node.h:386
rb_ast_new
rb_ast_t * rb_ast_new(void)
Definition: node.c:1235
NODE_OP_ASGN_AND
@ NODE_OP_ASGN_AND
Definition: node.h:57
rb_id2str
#define rb_id2str(id)
Definition: vm_backtrace.c:30
T_NODE
#define T_NODE
Definition: ruby.h:545
NODE_DASGN
@ NODE_DASGN
Definition: node.h:49
NODE_BLOCK
@ NODE_BLOCK
Definition: node.h:24
NULL
#define NULL
Definition: _sdbm.c:101
NODE_ERRINFO
@ NODE_ERRINFO
Definition: node.h:119
nd_aid
#define nd_aid
Definition: node.h:242
F_LONG
#define F_LONG(name, ann)
Definition: node.c:65
PRIsVALUE
#define PRIsVALUE
Definition: ruby.h:166
NODE_KW_ARG
@ NODE_KW_ARG
Definition: node.h:95
NODE_DSTR
@ NODE_DSTR
Definition: node.h:86
ruby.h
NODE_SPLAT
@ NODE_SPLAT
Definition: node.h:99
NODE_ITER
@ NODE_ITER
Definition: node.h:34
NODE_CDECL
@ NODE_CDECL
Definition: node.h:53
rb_ast_struct::node_buffer
node_buffer_t * node_buffer
Definition: node.h:401
F_MSG
#define F_MSG(name, ann, desc)
Definition: node.c:67
NODE_CVAR
@ NODE_CVAR
Definition: node.h:78
rb_imemo_new
VALUE rb_imemo_new(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0)
Definition: gc.c:2308
node_buffer_list_t
Definition: node.c:1114
imemo_ast
@ imemo_ast
Definition: internal.h:1142
rb_ast_delete_node
void rb_ast_delete_node(rb_ast_t *ast, NODE *n)
Definition: node.c:1227
NODE_IN
@ NODE_IN
Definition: node.h:31
void
void
Definition: rb_mjit_min_header-2.7.2.h:13241
rb_ast_body_struct::compile_option
VALUE compile_option
Definition: node.h:396
NODE_ZSUPER
@ NODE_ZSUPER
Definition: node.h:66
NODE_LAMBDA
@ NODE_LAMBDA
Definition: node.h:124
NODE_SUPER
@ NODE_SUPER
Definition: node.h:65
NODE_VCALL
@ NODE_VCALL
Definition: node.h:63
NODE_VALIAS
@ NODE_VALIAS
Definition: node.h:104
nd_super
#define nd_super
Definition: node.h:259
F_CUSTOM1
#define F_CUSTOM1(name, ann)
Definition: node.c:61
NODE_DEFS
@ NODE_DEFS
Definition: node.h:102
NODE_UNLESS
@ NODE_UNLESS
Definition: node.h:26
nd_undef
#define nd_undef
Definition: node.h:272
nd_args
#define nd_args
Definition: node.h:253
nd_defn
#define nd_defn
Definition: node.h:256
rb_ast_struct
Definition: node.h:399
rb_parser_dump_tree
VALUE rb_parser_dump_tree(const NODE *node, int comment)
Definition: node.c:1076
NODE_DEFN
@ NODE_DEFN
Definition: node.h:101
node_buffer_struct::markable
node_buffer_list_t markable
Definition: node.c:1122
rb_node_init
void rb_node_init(NODE *n, enum node_type type, VALUE a0, VALUE a1, VALUE a2)
Definition: node.c:1095
A_INT
#define A_INT(val)
Definition: node.c:24
nd_ainfo
#define nd_ainfo
Definition: node.h:254
rb_args_info
Definition: node.h:432
ANN
#define ANN(ann)
Definition: node.c:72
A
#define A(str)
Definition: node.c:17
nd_ensr
#define nd_ensr
Definition: node.h:223
nd_alias
#define nd_alias
Definition: node.h:270
node_buffer_elem_t
struct node_buffer_elem_struct node_buffer_elem_t
rb_args_info::imemo
VALUE imemo
Definition: node.h:451
nd_value
#define nd_value
Definition: node.h:241
NODE_CLASS
@ NODE_CLASS
Definition: node.h:106
rb_ast_memsize
size_t rb_ast_memsize(const rb_ast_t *ast)
Definition: node.c:1373
NODE_IF
@ NODE_IF
Definition: node.h:25
NODE_ENSURE
@ NODE_ENSURE
Definition: node.h:44
rb_ast_update_references
void rb_ast_update_references(rb_ast_t *ast)
Definition: node.c:1330
D_DEDENT
#define D_DEDENT
Definition: node.c:22
NODE_MATCH2
@ NODE_MATCH2
Definition: node.h:82
nd_set_type
#define nd_set_type(n, t)
Definition: node.h:189
nd_tbl
#define nd_tbl
Definition: node.h:236
nd_pkwargs
#define nd_pkwargs
Definition: node.h:277
nd_entry
#define nd_entry
Definition: node.h:230
st_index_t
st_data_t st_index_t
Definition: st.h:50
nd_body
#define nd_body
Definition: node.h:219
NODE_CASE3
@ NODE_CASE3
Definition: node.h:29
nd_end
#define nd_end
Definition: node.h:262
AR
#define AR(str)
Definition: node.c:18
vm_core.h
NODE_DASGN_CURR
@ NODE_DASGN_CURR
Definition: node.h:50
nd_nth
#define nd_nth
Definition: node.h:266
NODE_COLON2
@ NODE_COLON2
Definition: node.h:109
NODE_DOT3
@ NODE_DOT3
Definition: node.h:112
rb_ast_add_local_table
void rb_ast_add_local_table(rb_ast_t *ast, ID *buf)
Definition: node.c:1219
node_type
node_type
Definition: node.h:22
NODE_BREAK
@ NODE_BREAK
Definition: node.h:37
node_buffer_struct::local_tables
ID * local_tables
Definition: node.c:1123
NODE_GVAR
@ NODE_GVAR
Definition: node.h:75
rb_ast_add_mark_object
void rb_ast_add_mark_object(rb_ast_t *ast, VALUE obj)
Definition: node.c:1393
NODE_XSTR
@ NODE_XSTR
Definition: node.h:87
size
int size
Definition: encoding.c:58
node_buffer_elem_struct::buf
NODE buf[FLEX_ARY_LEN]
Definition: node.c:1111
rb_ast_free
void rb_ast_free(rb_ast_t *ast)
Definition: node.c:1352
NODE_ARGS
@ NODE_ARGS
Definition: node.h:92
rb_gc_mark_movable
void rb_gc_mark_movable(VALUE ptr)
Definition: gc.c:5209
NODE_DVAR
@ NODE_DVAR
Definition: node.h:74
LAST_NODE
#define LAST_NODE
Definition: node.c:77
nd_mid
#define nd_mid
Definition: node.h:252
NODE_ALIAS
@ NODE_ALIAS
Definition: node.h:103
A
Definition: nested_struct10.c:12
RB_OBJ_WRITE
#define RB_OBJ_WRITE(a, slot, b)
Definition: ruby.h:1508
nd_pkwrestarg
#define nd_pkwrestarg
Definition: node.h:278
nd_cond
#define nd_cond
Definition: node.h:218
node_buffer_elem_struct::len
long len
Definition: node.c:1110
NODE_OP_CDECL
@ NODE_OP_CDECL
Definition: node.h:59
A_INDENT
#define A_INDENT
Definition: node.c:20
NODE_POSTARG
@ NODE_POSTARG
Definition: node.h:96
D_NULL_NODE
#define D_NULL_NODE
Definition: node.c:37
NODE_SELF
@ NODE_SELF
Definition: node.h:115
NODE_LVAR
@ NODE_LVAR
Definition: node.h:73
F_ID
#define F_ID(name, ann)
Definition: node.c:62
nd_var
#define nd_var
Definition: node.h:238
NODE_STR
@ NODE_STR
Definition: node.h:85
add_option_arg::count
st_index_t count
Definition: node.c:104
NODE_IVAR
@ NODE_IVAR
Definition: node.h:76
node_buffer_list_t::head
node_buffer_elem_t * head
Definition: node.c:1116
nd_beg
#define nd_beg
Definition: node.h:261
buf
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4322
nd_iter
#define nd_iter
Definition: node.h:239
obj
const VALUE VALUE obj
Definition: rb_mjit_min_header-2.7.2.h:5738
NODE_BEGIN
@ NODE_BEGIN
Definition: node.h:41
NODE_POSTEXE
@ NODE_POSTEXE
Definition: node.h:121
NODE_RESBODY
@ NODE_RESBODY
Definition: node.h:43
rb_bug
void rb_bug(const char *fmt,...)
Definition: error.c:636
NODE_RETURN
@ NODE_RETURN
Definition: node.h:71
NODE_FALSE
@ NODE_FALSE
Definition: node.h:118
NODE_ONCE
@ NODE_ONCE
Definition: node.h:91
next_table
#define next_table
STATIC_ASSERT
#define STATIC_ASSERT(name, expr)
Definition: internal.h:230
NODE_IASGN
@ NODE_IASGN
Definition: node.h:52
add_option_arg::indent
VALUE indent
Definition: node.c:103
nd_recv
#define nd_recv
Definition: node.h:251
NODE_ARGS_AUX
@ NODE_ARGS_AUX
Definition: node.h:93
nd_lit
#define nd_lit
Definition: node.h:244
D_NODE_HEADER
#define D_NODE_HEADER(node)
Definition: node.c:38
A_ID
#define A_ID(id)
Definition: node.c:23
NODE_NAMED_REST_P
#define NODE_NAMED_REST_P(node)
Definition: node.h:384
str
char str[HTML_ESCAPE_MAX_LEN+1]
Definition: escape.c:18
NODE_WHEN
@ NODE_WHEN
Definition: node.h:30
NODE_BLOCK_PASS
@ NODE_BLOCK_PASS
Definition: node.h:100
NODE_MATCH
@ NODE_MATCH
Definition: node.h:81
nd_1st
#define nd_1st
Definition: node.h:225
rb_hash_aset
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
Definition: hash.c:2852
node_buffer_elem_struct
Definition: node.c:1108
NODE_OPT_ARG
@ NODE_OPT_ARG
Definition: node.h:94
NODE_CALL
@ NODE_CALL
Definition: node.h:60
NIL_P
#define NIL_P(v)
Definition: ruby.h:482
nd_alen
#define nd_alen
Definition: node.h:215
nd_else
#define nd_else
Definition: node.h:220
NODE_CASE2
@ NODE_CASE2
Definition: node.h:28
node_buffer_list_t::len
long len
Definition: node.c:1115
NODE
struct RNode NODE
xfree
#define xfree
Definition: defines.h:216
F_LIT
#define F_LIT(name, ann)
Definition: node.c:66
rb_ary_pattern_info::imemo
VALUE imemo
Definition: node.h:458
NODE_FCALL
@ NODE_FCALL
Definition: node.h:62
rb_gc_mark
void rb_gc_mark(VALUE ptr)
Definition: gc.c:5215
NODE_YIELD
@ NODE_YIELD
Definition: node.h:72
Qtrue
#define Qtrue
Definition: ruby.h:468
rb_str_catf
VALUE rb_str_catf(VALUE str, const char *format,...)
Definition: sprintf.c:1237
F_NODE
#define F_NODE(name, ann)
Definition: node.c:69
len
uint8_t len
Definition: escape.c:17
node_buffer_struct
Definition: node.c:1120
D_INDENT
#define D_INDENT
Definition: node.c:21
nd_next
#define nd_next
Definition: node.h:216
add_option_arg::buf
VALUE buf
Definition: node.c:103
NODE_UNDEF
@ NODE_UNDEF
Definition: node.h:105
nd_cpath
#define nd_cpath
Definition: node.h:258
FLEX_ARY_LEN
#define FLEX_ARY_LEN
Definition: internal.h:2626
NODE_BACK_REF
@ NODE_BACK_REF
Definition: node.h:80
NODE_DEFINED
@ NODE_DEFINED
Definition: node.h:120
NODE_REQUIRED_KEYWORD_P
#define NODE_REQUIRED_KEYWORD_P(node)
Definition: node.h:382
NODE_LAST
@ NODE_LAST
Definition: node.h:127
rb_str_new_cstr
#define rb_str_new_cstr(str)
Definition: rb_mjit_min_header-2.7.2.h:6113
NODE_VALUES
@ NODE_VALUES
Definition: node.h:69
NODE_FLIP3
@ NODE_FLIP3
Definition: node.h:114
nd_type
#define nd_type(n)
Definition: node.h:188
nd_resq
#define nd_resq
Definition: node.h:222
Qnil
#define Qnil
Definition: ruby.h:469
node_buffer_list_t::idx
long idx
Definition: node.c:1115
NODE_REDO
@ NODE_REDO
Definition: node.h:39
nd_brace
#define nd_brace
Definition: node.h:274
node_buffer_t
typedefRUBY_SYMBOL_EXPORT_BEGIN struct node_buffer_struct node_buffer_t
Definition: node.h:392
rb_ary_pattern_info
Definition: node.h:454
NODE_MODULE
@ NODE_MODULE
Definition: node.h:107
char
#define char
Definition: rb_mjit_min_header-2.7.2.h:2884
nd_2nd
#define nd_2nd
Definition: node.h:226
NODE_QCALL
@ NODE_QCALL
Definition: node.h:64
NODE_SCOPE
@ NODE_SCOPE
Definition: node.h:23
NODE_RETRY
@ NODE_RETRY
Definition: node.h:40
NODE_LIST
@ NODE_LIST
Definition: node.h:67
F_INT
#define F_INT(name, ann)
Definition: node.c:64
NODE_FOR_MASGN
@ NODE_FOR_MASGN
Definition: node.h:36
ruby::backward::cxxanyargs::type
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:39
RNode
Definition: node.h:149
nd_apinfo
#define nd_apinfo
Definition: node.h:280
NODE_WHILE
@ NODE_WHILE
Definition: node.h:32
NODE_SCLASS
@ NODE_SCLASS
Definition: node.h:108
name
const char * name
Definition: nkf.c:208
NODE_GASGN
@ NODE_GASGN
Definition: node.h:51
n
const char size_t n
Definition: rb_mjit_min_header-2.7.2.h:5452