Ruby  2.7.1p83(2020-03-31revisiona0c7c23c9cec0d0ffcba012279cd652d28ad5bf3)
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 
1124 };
1125 
1126 static void
1127 init_node_buffer_list(node_buffer_list_t * nb, node_buffer_elem_t *head)
1128 {
1129  nb->idx = 0;
1130  nb->len = NODE_BUF_DEFAULT_LEN;
1131  nb->head = nb->last = head;
1132  nb->head->len = nb->len;
1133  nb->head->next = NULL;
1134 }
1135 
1136 static node_buffer_t *
1137 rb_node_buffer_new(void)
1138 {
1139  const size_t bucket_size = offsetof(node_buffer_elem_t, buf) + NODE_BUF_DEFAULT_LEN * sizeof(NODE);
1140  const size_t alloc_size = sizeof(node_buffer_t) + (bucket_size * 2);
1141  STATIC_ASSERT(
1142  integer_overflow,
1144  > sizeof(node_buffer_t) + 2 * sizeof(node_buffer_elem_t));
1145  node_buffer_t *nb = ruby_xmalloc(alloc_size);
1146  init_node_buffer_list(&nb->unmarkable, (node_buffer_elem_t*)&nb[1]);
1147  init_node_buffer_list(&nb->markable, (node_buffer_elem_t*)((size_t)nb->unmarkable.head + bucket_size));
1148  nb->mark_hash = Qnil;
1149  return nb;
1150 }
1151 
1152 static void
1153 node_buffer_list_free(node_buffer_list_t * nb)
1154 {
1155  node_buffer_elem_t *nbe = nb->head;
1156 
1157  while (nbe != nb->last) {
1158  void *buf = nbe;
1159  nbe = nbe->next;
1160  xfree(buf);
1161  }
1162 }
1163 
1164 static void
1165 rb_node_buffer_free(node_buffer_t *nb)
1166 {
1167  node_buffer_list_free(&nb->unmarkable);
1168  node_buffer_list_free(&nb->markable);
1169  xfree(nb);
1170 }
1171 
1172 static NODE *
1173 ast_newnode_in_bucket(node_buffer_list_t *nb)
1174 {
1175  if (nb->idx >= nb->len) {
1176  long n = nb->len * 2;
1177  node_buffer_elem_t *nbe;
1179  nbe->len = n;
1180  nb->idx = 0;
1181  nb->len = n;
1182  nbe->next = nb->head;
1183  nb->head = nbe;
1184  }
1185  return &nb->head->buf[nb->idx++];
1186 }
1187 
1188 NODE *
1190 {
1191  node_buffer_t *nb = ast->node_buffer;
1192  switch (type) {
1193  case NODE_MATCH:
1194  case NODE_LIT:
1195  case NODE_STR:
1196  case NODE_XSTR:
1197  case NODE_DSTR:
1198  case NODE_DXSTR:
1199  case NODE_DREGX:
1200  case NODE_DSYM:
1201  case NODE_ARGS:
1202  case NODE_SCOPE:
1203  case NODE_ARYPTN:
1204  return ast_newnode_in_bucket(&nb->markable);
1205  default:
1206  return ast_newnode_in_bucket(&nb->unmarkable);
1207  }
1208 }
1209 
1210 void
1212 {
1213  (void)ast;
1214  (void)n;
1215  /* should we implement freelist? */
1216 }
1217 
1218 rb_ast_t *
1220 {
1221  node_buffer_t *nb = rb_node_buffer_new();
1222  rb_ast_t *ast = (rb_ast_t *)rb_imemo_new(imemo_ast, 0, 0, 0, (VALUE)nb);
1223  return ast;
1224 }
1225 
1226 typedef void node_itr_t(void *ctx, NODE * node);
1227 
1228 static void
1229 iterate_buffer_elements(node_buffer_elem_t *nbe, long len, node_itr_t *func, void *ctx)
1230 {
1231  long cursor;
1232  for (cursor = 0; cursor < len; cursor++) {
1233  func(ctx, &nbe->buf[cursor]);
1234  }
1235 }
1236 
1237 static void
1238 iterate_node_values(node_buffer_list_t *nb, node_itr_t * func, void *ctx)
1239 {
1240  node_buffer_elem_t *nbe = nb->head;
1241 
1242  /* iterate over the head first because it's not full */
1243  iterate_buffer_elements(nbe, nb->idx, func, ctx);
1244 
1245  nbe = nbe->next;
1246  while (nbe) {
1247  iterate_buffer_elements(nbe, nbe->len, func, ctx);
1248  nbe = nbe->next;
1249  }
1250 }
1251 
1252 static void
1253 mark_ast_value(void *ctx, NODE * node)
1254 {
1255  switch (nd_type(node)) {
1256  case NODE_SCOPE:
1257  {
1258  ID *buf = node->nd_tbl;
1259  if (buf) {
1260  unsigned int size = (unsigned int)*buf;
1262  }
1263  break;
1264  }
1265  case NODE_ARYPTN:
1266  {
1267  struct rb_ary_pattern_info *apinfo = node->nd_apinfo;
1268  rb_gc_mark_movable(apinfo->imemo);
1269  break;
1270  }
1271  case NODE_ARGS:
1272  {
1273  struct rb_args_info *args = node->nd_ainfo;
1274  rb_gc_mark_movable(args->imemo);
1275  break;
1276  }
1277  case NODE_MATCH:
1278  case NODE_LIT:
1279  case NODE_STR:
1280  case NODE_XSTR:
1281  case NODE_DSTR:
1282  case NODE_DXSTR:
1283  case NODE_DREGX:
1284  case NODE_DSYM:
1285  rb_gc_mark_movable(node->nd_lit);
1286  break;
1287  default:
1288  rb_bug("unreachable node %s", ruby_node_name(nd_type(node)));
1289  }
1290 }
1291 
1292 static void
1293 update_ast_value(void *ctx, NODE * node)
1294 {
1295  switch (nd_type(node)) {
1296  case NODE_SCOPE:
1297  {
1298  ID *buf = node->nd_tbl;
1299  if (buf) {
1300  unsigned int size = (unsigned int)*buf;
1301  buf[size + 1] = rb_gc_location((VALUE)buf[size + 1]);
1302  }
1303  break;
1304  }
1305  case NODE_ARYPTN:
1306  {
1307  struct rb_ary_pattern_info *apinfo = node->nd_apinfo;
1308  apinfo->imemo = rb_gc_location(apinfo->imemo);
1309  break;
1310  }
1311  case NODE_ARGS:
1312  {
1313  struct rb_args_info *args = node->nd_ainfo;
1314  args->imemo = rb_gc_location(args->imemo);
1315  break;
1316  }
1317  case NODE_LIT:
1318  case NODE_STR:
1319  case NODE_XSTR:
1320  case NODE_DSTR:
1321  case NODE_DXSTR:
1322  case NODE_DREGX:
1323  case NODE_DSYM:
1324  node->nd_lit = rb_gc_location(node->nd_lit);
1325  break;
1326  default:
1327  rb_bug("unreachable");
1328  }
1329 }
1330 
1331 void
1333 {
1334  if (ast->node_buffer) {
1335  node_buffer_t *nb = ast->node_buffer;
1336 
1337  iterate_node_values(&nb->markable, update_ast_value, NULL);
1338  }
1339 }
1340 
1341 void
1343 {
1344  if (ast->node_buffer) rb_gc_mark(ast->node_buffer->mark_hash);
1346  if (ast->node_buffer) {
1347  node_buffer_t *nb = ast->node_buffer;
1348 
1349  iterate_node_values(&nb->markable, mark_ast_value, NULL);
1350  }
1351 }
1352 
1353 void
1355 {
1356  if (ast->node_buffer) {
1357  rb_node_buffer_free(ast->node_buffer);
1358  ast->node_buffer = 0;
1359  }
1360 }
1361 
1362 static size_t
1363 buffer_list_size(node_buffer_list_t *nb)
1364 {
1365  size_t size = 0;
1366  node_buffer_elem_t *nbe = nb->head;
1367  while (nbe != nb->last) {
1368  nbe = nbe->next;
1369  size += offsetof(node_buffer_elem_t, buf) + nb->len * sizeof(NODE);
1370  }
1371  return size;
1372 }
1373 
1374 size_t
1376 {
1377  size_t size = 0;
1378  node_buffer_t *nb = ast->node_buffer;
1379 
1380  if (nb) {
1382  size += buffer_list_size(&nb->unmarkable);
1383  size += buffer_list_size(&nb->markable);
1384  }
1385  return size;
1386 }
1387 
1388 void
1390 {
1391  rb_ast_free(ast);
1392 }
1393 
1394 void
1396 {
1397  if (NIL_P(ast->node_buffer->mark_hash)) {
1398  RB_OBJ_WRITE(ast, &ast->node_buffer->mark_hash, rb_ident_hash_new());
1399  }
1400  rb_hash_aset(ast->node_buffer->mark_hash, obj, Qtrue);
1401 }
NODE_NEXT
@ NODE_NEXT
Definition: node.h:47
NODE_COLON3
@ NODE_COLON3
Definition: node.h:119
i
uint32_t i
Definition: rb_mjit_min_header-2.7.1.h:5425
NODE_NIL
@ NODE_NIL
Definition: node.h:125
ID
unsigned long ID
Definition: ruby.h:103
ruby_node_name
const char * ruby_node_name(int node)
Definition: iseq.c:2534
obj
const VALUE VALUE obj
Definition: rb_mjit_min_header-2.7.1.h:5703
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:132
NODE_DSYM
@ NODE_DSYM
Definition: node.h:131
rb_ast_newnode
NODE * rb_ast_newnode(rb_ast_t *ast, enum node_type type)
Definition: node.c:1189
NODE_HSHPTN
@ NODE_HSHPTN
Definition: node.h:135
NODE_RESCUE
@ NODE_RESCUE
Definition: node.h:51
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:64
nd_head
#define nd_head
Definition: node.h:214
rb_ident_hash_new
VALUE rb_ident_hash_new(void)
Definition: hash.c:4272
node_buffer_struct::mark_hash
VALUE mark_hash
Definition: node.c:1123
nd_orig
#define nd_orig
Definition: node.h:271
NODE_TRUE
@ NODE_TRUE
Definition: node.h:126
node_itr_t
void node_itr_t(void *ctx, NODE *node)
Definition: node.c:1226
NODE_MATCH3
@ NODE_MATCH3
Definition: node.h:92
NODE_NTH_REF
@ NODE_NTH_REF
Definition: node.h:88
NODE_ZLIST
@ NODE_ZLIST
Definition: node.h:77
NODE_SPECIAL_EXCESSIVE_COMMA
#define NODE_SPECIAL_EXCESSIVE_COMMA
Definition: node.h:385
NODE_DREGX
@ NODE_DREGX
Definition: node.h:99
node_buffer_list_t::last
node_buffer_elem_t * last
Definition: node.c:1117
NODE_OR
@ NODE_OR
Definition: node.h:55
NODE_ARYPTN
@ NODE_ARYPTN
Definition: node.h:134
rb_ast_dispose
void rb_ast_dispose(rb_ast_t *ast)
Definition: node.c:1389
NODE_OP_ASGN_OR
@ NODE_OP_ASGN_OR
Definition: node.h:67
n
const char size_t n
Definition: rb_mjit_min_header-2.7.1.h:5417
nd_pconst
#define nd_pconst
Definition: node.h:276
NODE_HASH
@ NODE_HASH
Definition: node.h:79
ruby_xmalloc
void * ruby_xmalloc(size_t size)
Definition: gc.c:11969
NODE_CONST
@ NODE_CONST
Definition: node.h:86
node_buffer_struct::unmarkable
node_buffer_list_t unmarkable
Definition: node.c:1121
NODE_LASGN
@ NODE_LASGN
Definition: node.h:57
rb_str_new_cstr
#define rb_str_new_cstr(str)
Definition: rb_mjit_min_header-2.7.1.h:6078
A_LONG
#define A_LONG(val)
Definition: node.c:25
NODE_FLIP2
@ NODE_FLIP2
Definition: node.h:122
NODE_ARGSPUSH
@ NODE_ARGSPUSH
Definition: node.h:107
NODE_FOR
@ NODE_FOR
Definition: node.h:44
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:36
offsetof
#define offsetof(p_type, field)
Definition: addrinfo.h:186
NODE_OP_ASGN2
@ NODE_OP_ASGN2
Definition: node.h:65
NODE_ARGSCAT
@ NODE_ARGSCAT
Definition: node.h:106
rb_xmalloc_mul_add
void * rb_xmalloc_mul_add(size_t x, size_t y, size_t z)
Definition: gc.c:10175
rb_gc_location
VALUE rb_gc_location(VALUE value)
Definition: gc.c:8113
NODE_DOT2
@ NODE_DOT2
Definition: node.h:120
NODE_EVSTR
@ NODE_EVSTR
Definition: node.h:98
nd_stts
#define nd_stts
Definition: node.h:228
rb_ast_mark
void rb_ast_mark(rb_ast_t *ast)
Definition: node.c:1342
NODE_UNTIL
@ NODE_UNTIL
Definition: node.h:42
NODE_CVASGN
@ NODE_CVASGN
Definition: node.h:63
NODE_AND
@ NODE_AND
Definition: node.h:54
NODE_LIT
@ NODE_LIT
Definition: node.h:93
NODE_MASGN
@ NODE_MASGN
Definition: node.h:56
nd_vid
#define nd_vid
Definition: node.h:231
NODE_DXSTR
@ NODE_DXSTR
Definition: node.h:97
NODE_OPCALL
@ NODE_OPCALL
Definition: node.h:70
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:1219
NODE_OP_ASGN_AND
@ NODE_OP_ASGN_AND
Definition: node.h:66
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:58
NODE_BLOCK
@ NODE_BLOCK
Definition: node.h:33
NULL
#define NULL
Definition: _sdbm.c:101
char
#define char
Definition: rb_mjit_min_header-2.7.1.h:2844
NODE_ERRINFO
@ NODE_ERRINFO
Definition: node.h:128
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:104
NODE_DSTR
@ NODE_DSTR
Definition: node.h:95
ruby.h
NODE_SPLAT
@ NODE_SPLAT
Definition: node.h:108
NODE_ITER
@ NODE_ITER
Definition: node.h:43
NODE_CDECL
@ NODE_CDECL
Definition: node.h:62
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:87
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:1211
NODE_IN
@ NODE_IN
Definition: node.h:40
rb_ast_body_struct::compile_option
VALUE compile_option
Definition: node.h:396
NODE_ZSUPER
@ NODE_ZSUPER
Definition: node.h:75
NODE_LAMBDA
@ NODE_LAMBDA
Definition: node.h:133
NODE_SUPER
@ NODE_SUPER
Definition: node.h:74
NODE_VCALL
@ NODE_VCALL
Definition: node.h:72
NODE_VALIAS
@ NODE_VALIAS
Definition: node.h:113
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:111
NODE_UNLESS
@ NODE_UNLESS
Definition: node.h:35
void
void
Definition: rb_mjit_min_header-2.7.1.h:13198
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:110
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:431
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:450
nd_value
#define nd_value
Definition: node.h:241
NODE_CLASS
@ NODE_CLASS
Definition: node.h:115
rb_ast_memsize
size_t rb_ast_memsize(const rb_ast_t *ast)
Definition: node.c:1375
NODE_IF
@ NODE_IF
Definition: node.h:34
NODE_ENSURE
@ NODE_ENSURE
Definition: node.h:53
rb_ast_update_references
void rb_ast_update_references(rb_ast_t *ast)
Definition: node.c:1332
D_DEDENT
#define D_DEDENT
Definition: node.c:22
NODE_MATCH2
@ NODE_MATCH2
Definition: node.h:91
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:38
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:59
nd_nth
#define nd_nth
Definition: node.h:266
NODE_COLON2
@ NODE_COLON2
Definition: node.h:118
NODE_DOT3
@ NODE_DOT3
Definition: node.h:121
node_type
node_type
Definition: node.h:22
NODE_BREAK
@ NODE_BREAK
Definition: node.h:46
NODE_GVAR
@ NODE_GVAR
Definition: node.h:84
rb_ast_add_mark_object
void rb_ast_add_mark_object(rb_ast_t *ast, VALUE obj)
Definition: node.c:1395
NODE_XSTR
@ NODE_XSTR
Definition: node.h:96
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:1354
NODE_ARGS
@ NODE_ARGS
Definition: node.h:101
rb_gc_mark_movable
void rb_gc_mark_movable(VALUE ptr)
Definition: gc.c:5208
NODE_DVAR
@ NODE_DVAR
Definition: node.h:83
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:112
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:68
A_INDENT
#define A_INDENT
Definition: node.c:20
NODE_POSTARG
@ NODE_POSTARG
Definition: node.h:105
D_NULL_NODE
#define D_NULL_NODE
Definition: node.c:37
NODE_SELF
@ NODE_SELF
Definition: node.h:124
NODE_LVAR
@ NODE_LVAR
Definition: node.h:82
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:94
add_option_arg::count
st_index_t count
Definition: node.c:104
NODE_IVAR
@ NODE_IVAR
Definition: node.h:85
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
NODE_BEGIN
@ NODE_BEGIN
Definition: node.h:50
NODE_POSTEXE
@ NODE_POSTEXE
Definition: node.h:130
NODE_RESBODY
@ NODE_RESBODY
Definition: node.h:52
rb_bug
void rb_bug(const char *fmt,...)
Definition: error.c:634
NODE_RETURN
@ NODE_RETURN
Definition: node.h:80
NODE_FALSE
@ NODE_FALSE
Definition: node.h:127
NODE_ONCE
@ NODE_ONCE
Definition: node.h:100
STATIC_ASSERT
#define STATIC_ASSERT(name, expr)
Definition: internal.h:230
NODE_IASGN
@ NODE_IASGN
Definition: node.h:61
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:102
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:39
NODE_BLOCK_PASS
@ NODE_BLOCK_PASS
Definition: node.h:109
NODE_MATCH
@ NODE_MATCH
Definition: node.h:90
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:2847
int
__inline__ int
Definition: rb_mjit_min_header-2.7.1.h:2807
node_buffer_elem_struct
Definition: node.c:1108
NODE_OPT_ARG
@ NODE_OPT_ARG
Definition: node.h:103
NODE_CALL
@ NODE_CALL
Definition: node.h:69
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:37
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:457
NODE_FCALL
@ NODE_FCALL
Definition: node.h:71
rb_gc_mark
void rb_gc_mark(VALUE ptr)
Definition: gc.c:5214
NODE_YIELD
@ NODE_YIELD
Definition: node.h:81
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:114
nd_cpath
#define nd_cpath
Definition: node.h:258
FLEX_ARY_LEN
#define FLEX_ARY_LEN
Definition: internal.h:2625
NODE_BACK_REF
@ NODE_BACK_REF
Definition: node.h:89
NODE_DEFINED
@ NODE_DEFINED
Definition: node.h:129
NODE_REQUIRED_KEYWORD_P
#define NODE_REQUIRED_KEYWORD_P(node)
Definition: node.h:382
NODE_LAST
@ NODE_LAST
Definition: node.h:136
NODE_VALUES
@ NODE_VALUES
Definition: node.h:78
NODE_FLIP3
@ NODE_FLIP3
Definition: node.h:123
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:48
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:453
NODE_MODULE
@ NODE_MODULE
Definition: node.h:116
nd_2nd
#define nd_2nd
Definition: node.h:226
NODE_QCALL
@ NODE_QCALL
Definition: node.h:73
NODE_SCOPE
@ NODE_SCOPE
Definition: node.h:32
NODE_RETRY
@ NODE_RETRY
Definition: node.h:49
NODE_LIST
@ NODE_LIST
Definition: node.h:76
F_INT
#define F_INT(name, ann)
Definition: node.c:64
NODE_FOR_MASGN
@ NODE_FOR_MASGN
Definition: node.h:45
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:41
NODE_SCLASS
@ NODE_SCLASS
Definition: node.h:117
name
const char * name
Definition: nkf.c:208
NODE_GASGN
@ NODE_GASGN
Definition: node.h:60