Ruby 2.7.0p0(2019-12-25revision647ee6f091eafcce70ffb75ddf7e121e192ab217)

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
102 struct add_option_arg {
103 VALUE buf, indent;
104 st_index_t count;
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 {
1078 VALUE buf = rb_str_new_cstr(
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
1095 rb_node_init(NODE *n, enum node_type type, VALUE a0, VALUE a1, VALUE a2)
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 {
1109 struct node_buffer_elem_struct *next;
1110 long len;
1111 NODE buf[FLEX_ARY_LEN];
1112 } node_buffer_elem_t;
1113
1114 typedef struct {
1115 long idx, len;
1116 node_buffer_elem_t *head;
1117 node_buffer_elem_t *last;
1118 } node_buffer_list_t;
1119
1120 struct node_buffer_struct {
1121 node_buffer_list_t unmarkable;
1122 node_buffer_list_t markable;
1123 VALUE mark_hash;
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,
1143 offsetof(node_buffer_elem_t, buf) + NODE_BUF_DEFAULT_LEN * sizeof(NODE)
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;
1178 nbe = rb_xmalloc_mul_add(n, sizeof(NODE), offsetof(node_buffer_elem_t, buf));
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 *
1189 rb_ast_newnode(rb_ast_t *ast, enum node_type type)
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
1211 rb_ast_delete_node(rb_ast_t *ast, NODE *n)
1212 {
1213 (void)ast;
1214 (void)n;
1215 /* should we implement freelist? */
1216 }
1217
1218 rb_ast_t *
1219 rb_ast_new(void)
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;
1261 rb_gc_mark_movable((VALUE)buf[size + 1]);
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
1332 rb_ast_update_references(rb_ast_t *ast)
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
1342 rb_ast_mark(rb_ast_t *ast)
1343 {
1344 if (ast->node_buffer) rb_gc_mark(ast->node_buffer->mark_hash);
1345 if (ast->body.compile_option) rb_gc_mark(ast->body.compile_option);
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
1354 rb_ast_free(rb_ast_t *ast)
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
1375 rb_ast_memsize(const rb_ast_t *ast)
1376 {
1377 size_t size = 0;
1378 node_buffer_t *nb = ast->node_buffer;
1379
1380 if (nb) {
1381 size += sizeof(node_buffer_t) + offsetof(node_buffer_elem_t, buf) + NODE_BUF_DEFAULT_LEN * sizeof(NODE);
1382 size += buffer_list_size(&nb->unmarkable);
1383 size += buffer_list_size(&nb->markable);
1384 }
1385 return size;
1386 }
1387
1388 void
1389 rb_ast_dispose(rb_ast_t *ast)
1390 {
1391 rb_ast_free(ast);
1392 }
1393
1394 void
1395 rb_ast_add_mark_object(rb_ast_t *ast, VALUE obj)
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
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
void
void
Definition: rb_mjit_min_header-2.7.0.h:13273
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:4203
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
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:11950
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
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:10156
rb_gc_location
VALUE rb_gc_location(VALUE value)
Definition: gc.c:8111
NODE_DOT2
@ NODE_DOT2
Definition: node.h:120
NODE_EVSTR
@ NODE_EVSTR
Definition: node.h:98
int
__inline__ int
Definition: rb_mjit_min_header-2.7.0.h:2839
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
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:2306
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
obj
const VALUE VALUE obj
Definition: rb_mjit_min_header-2.7.0.h:5742
NODE_UNLESS
@ NODE_UNLESS
Definition: node.h:35
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
i
uint32_t i
Definition: rb_mjit_min_header-2.7.0.h:5464
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:5206
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
rb_str_new_cstr
#define rb_str_new_cstr(str)
Definition: rb_mjit_min_header-2.7.0.h:6117
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
char
#define char
Definition: rb_mjit_min_header-2.7.0.h:2876
node_buffer_list_t::head
node_buffer_elem_t * head
Definition: node.c:1116
nd_beg
#define nd_beg
Definition: node.h:261
n
const char size_t n
Definition: rb_mjit_min_header-2.7.0.h:5456
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:2779
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:5212
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:2620
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