3#define OLD_ISEQ NEW_ISEQ
6#define NEW_ISEQ(node, name, type, line_no) \
7 pm_new_child_iseq(iseq, (node), parser, rb_fstring(name), 0, (type), (line_no))
9#define OLD_CHILD_ISEQ NEW_CHILD_ISEQ
12#define NEW_CHILD_ISEQ(node, name, type, line_no) \
13 pm_new_child_iseq(iseq, (node), parser, rb_fstring(name), iseq, (type), (line_no))
15#define PM_COMPILE(node) \
16 pm_compile_node(iseq, (node), ret, src, popped, scope_node)
18#define PM_COMPILE_INTO_ANCHOR(_ret, node) \
19 pm_compile_node(iseq, (node), _ret, src, popped, scope_node)
21#define PM_COMPILE_POPPED(node) \
22 pm_compile_node(iseq, (node), ret, src, true, scope_node)
24#define PM_COMPILE_NOT_POPPED(node) \
25 pm_compile_node(iseq, (node), ret, src, false, scope_node)
28 ADD_INSN(ret, &dummy_line_node, pop);
30#define PM_POP_IF_POPPED \
33#define PM_POP_UNLESS_POPPED \
37 ADD_INSN(ret, &dummy_line_node, dup);
39#define PM_DUP_UNLESS_POPPED \
43 ADD_INSN(ret, &dummy_line_node, putself);
46 ADD_INSN(ret, &dummy_line_node, putnil);
48#define PM_PUTNIL_UNLESS_POPPED \
49 if (!popped) PM_PUTNIL;
52 ADD_INSN(ret, &dummy_line_node, swap);
54#define PM_SWAP_UNLESS_POPPED \
58 ADD_INSN(ret, &dummy_line_node, nop);
71#define TEMP_CONSTANT_IDENTIFIER ((pm_constant_id_t)(1 << 31))
75 int first_lineno,
const rb_iseq_t *parent,
int isolated_depth,
82 char *end = (
char *) node->base.location.end;
84 size_t length = end - start;
101 rb_bug(
"Unexpected integer base");
104 return rb_int_parse_cstr(start, length, &end, NULL, base, RB_INT_PARSE_DEFAULT);
112 size_t length = end - start;
114 char *buffer = malloc(length + 1);
115 memcpy(buffer, start, length);
117 buffer[length] =
'\0';
129 size_t length = end - start;
133 char *buffer = malloc(length + 1);
134 memcpy(buffer, start, length);
136 buffer[length] =
'\0';
138 char *decimal = memchr(buffer,
'.', length);
140 size_t seen_decimal = decimal - buffer;
141 size_t fraclen = length - seen_decimal - 1;
142 memmove(decimal, decimal + 1, fraclen + 1);
144 VALUE v = rb_cstr_to_inum(buffer, 10,
false);
145 res = rb_rational_new(v, rb_int_positive_pow(10, fraclen));
151 VALUE number = rb_int_parse_cstr((
const char *)start, length, NULL, NULL, -10, RB_INT_PARSE_DEFAULT);
161 VALUE imaginary_part;
164 imaginary_part = parse_float(node->
numeric);
172 imaginary_part = parse_rational(node->
numeric);
176 rb_bug(
"Unexpected numeric type on imaginary number");
179 return rb_complex_raw(
INT2FIX(0), imaginary_part);
186 return rb_enc_str_new((
const char *) pm_string_source(
string), pm_string_length(
string), enc);
199 encoding = rb_ascii8bit_encoding();
201 encoding = rb_utf8_encoding();
203 encoding = rb_enc_from_index(rb_enc_find_index(parser->
encoding->
name));
206 return rb_enc_str_new((
const char *) pm_string_source(
string), pm_string_length(
string), encoding);
210parse_symbol(
const uint8_t *start,
const uint8_t *end,
pm_parser_t *parser)
213 return rb_intern3((
const char *) start, end - start, enc);
219 const uint8_t *start = pm_string_source(
string);
220 return parse_symbol(start, start + pm_string_length(
string), parser);
226 return parse_symbol(location->
start, location->
end, parser);
230pm_optimizable_range_item_p(
pm_node_t *node)
235#define RE_OPTION_ENCODING_SHIFT 8
250 rb_char_to_option_kcode(
'n', &flags, &dummy);
254 rb_char_to_option_kcode(
'e', &flags, &dummy);
255 flags |= (
'e' << RE_OPTION_ENCODING_SHIFT);
259 rb_char_to_option_kcode(
's', &flags, &dummy);
260 flags |= (
's' << RE_OPTION_ENCODING_SHIFT);
264 rb_char_to_option_kcode(
'u', &flags, &dummy);
265 flags |= (
'u' << RE_OPTION_ENCODING_SHIFT);
269 flags |= ONIG_OPTION_IGNORECASE;
273 flags |= ONIG_OPTION_MULTILINE;
277 flags |= ONIG_OPTION_EXTEND;
286 return rb_ascii8bit_encoding();
290 return rb_enc_get_from_index(ENCINDEX_EUC_JP);
294 return rb_enc_get_from_index(ENCINDEX_Windows_31J);
298 return rb_utf8_encoding();
301 return rb_enc_from_index(rb_enc_find_index(parser->
encoding->
name));
310pm_static_literal_p(
const pm_node_t *node)
312 return node->
flags & PM_NODE_FLAG_STATIC_LITERAL;
320 return rb_enc_reg_new(RSTRING_PTR(regex_str), RSTRING_LEN(regex_str), enc, pm_reg_flags((
const pm_node_t *)cast));
333 assert(pm_static_literal_p(node));
340 VALUE value = rb_ary_hidden_new(elements->
size);
341 for (
size_t index = 0; index < elements->
size; index++) {
342 rb_ary_push(value, pm_static_literal_value(elements->
nodes[index], scope_node, parser));
351 return parse_float(node);
356 VALUE array = rb_ary_hidden_new(elements->
size * 2);
357 for (
size_t index = 0; index < elements->
size; index++) {
360 VALUE pair[2] = { pm_static_literal_value(cast->key, scope_node, parser), pm_static_literal_value(cast->value, scope_node, parser) };
361 rb_ary_cat(array, pair, 2);
364 VALUE value = rb_hash_new_with_size(elements->
size);
367 value = rb_obj_hide(value);
378 return parse_rational(node);
382 return pm_new_regex(cast, parser);
386 if (!encoding) rb_bug(
"Encoding not found!");
387 return rb_enc_from_encoding(encoding);
407 rb_raise(rb_eArgError,
"Don't have a literal value for this type");
452 int lineno = (int) line_column.
line;
454 nd_set_line(&line_node->node, lineno);
455 nd_set_node_id(&line_node->node, lineno);
456 line_node->lineno = lineno;
469 int lineno = (int)pm_newline_list_line_column(&newline_list, cond->
location.
start).
line;
470 NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
474 LABEL *label = NEW_LABEL(lineno);
475 if (!then_label) then_label = label;
476 else if (!else_label) else_label = label;
478 pm_compile_branch_condition(iseq, seq, cond, then_label, else_label, src, popped, scope_node);
480 if (LIST_INSN_SIZE_ONE(seq)) {
481 INSN *insn = (
INSN *)ELEM_FIRST_INSN(FIRST_ELEMENT(seq));
482 if (insn->insn_id == BIN(jump) && (
LABEL *)(insn->operands[0]) == label)
485 if (!label->refcnt) {
489 ADD_LABEL(seq, label);
500 NODE dummy_line_node = generate_dummy_line_node(ISEQ_BODY(iseq)->location.first_lineno, -1);
501 LABEL *lend = NEW_LABEL(lineno);
505 rb_num_t count = ISEQ_FLIP_CNT_INCREMENT(ISEQ_BODY(iseq)->local_iseq) + VM_SVAR_FLIPFLOP_START;
508 ADD_INSN2(ret, &dummy_line_node, getspecial, key,
INT2FIX(0));
509 ADD_INSNL(ret, &dummy_line_node, branchif, lend);
511 if (flip_flop_node->
left) {
512 PM_COMPILE(flip_flop_node->
left);
518 ADD_INSNL(ret, &dummy_line_node, branchunless, else_label);
519 ADD_INSN1(ret, &dummy_line_node, putobject,
Qtrue);
520 ADD_INSN1(ret, &dummy_line_node, setspecial, key);
522 ADD_INSNL(ret, &dummy_line_node, jump, then_label);
525 ADD_LABEL(ret, lend);
526 if (flip_flop_node->
right) {
527 PM_COMPILE(flip_flop_node->
right);
533 ADD_INSNL(ret, &dummy_line_node, branchunless, then_label);
534 ADD_INSN1(ret, &dummy_line_node, putobject,
Qfalse);
535 ADD_INSN1(ret, &dummy_line_node, setspecial, key);
536 ADD_INSNL(ret, &dummy_line_node, jump, then_label);
546 int lineno = (int) pm_newline_list_line_column(&newline_list, cond->
location.
start).
line;
547 NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
553 pm_compile_logical(iseq, ret, and_node->
left, NULL, else_label, src, popped, scope_node);
554 cond = and_node->
right;
559 pm_compile_logical(iseq, ret, or_node->
left, then_label, NULL, src, popped, scope_node);
560 cond = or_node->
right;
565 ADD_INSNL(ret, &dummy_line_node, jump, else_label);
576 ADD_INSNL(ret, &dummy_line_node, jump, then_label);
579 pm_compile_flip_flop((
pm_flip_flop_node_t *)cond, else_label, then_label, iseq, lineno, ret, src, popped, scope_node);
584 pm_compile_defined_expr(iseq, defined_node->
value, ret, src, popped, scope_node, dummy_line_node, lineno,
true);
588 DECL_ANCHOR(cond_seq);
589 INIT_ANCHOR(cond_seq);
591 pm_compile_node(iseq, cond, cond_seq, src,
false, scope_node);
592 ADD_SEQ(ret, cond_seq);
596 ADD_INSNL(ret, &dummy_line_node, branchunless, else_label);
597 ADD_INSNL(ret, &dummy_line_node, jump, then_label);
604 NODE dummy_line_node = generate_dummy_line_node(line, line);
606 DECL_ANCHOR(cond_seq);
608 LABEL *then_label, *else_label, *end_label;
610 INIT_ANCHOR(cond_seq);
611 then_label = NEW_LABEL(line);
612 else_label = NEW_LABEL(line);
615 pm_compile_branch_condition(iseq, cond_seq, predicate, then_label, else_label, src,
false, scope_node);
616 ADD_SEQ(ret, cond_seq);
618 if (then_label->refcnt) {
619 ADD_LABEL(ret, then_label);
621 DECL_ANCHOR(then_seq);
622 INIT_ANCHOR(then_seq);
624 pm_compile_node(iseq, (
pm_node_t *)node_body, then_seq, src, popped, scope_node);
626 PM_PUTNIL_UNLESS_POPPED;
629 if (else_label->refcnt) {
630 end_label = NEW_LABEL(line);
631 ADD_INSNL(then_seq, &dummy_line_node, jump, end_label);
633 ADD_INSN(then_seq, &dummy_line_node, pop);
636 ADD_SEQ(ret, then_seq);
639 if (else_label->refcnt) {
640 ADD_LABEL(ret, else_label);
642 DECL_ANCHOR(else_seq);
643 INIT_ANCHOR(else_seq);
645 pm_compile_node(iseq, (
pm_node_t *)node_else, else_seq, src, popped, scope_node);
648 PM_PUTNIL_UNLESS_POPPED;
651 ADD_SEQ(ret, else_seq);
655 ADD_LABEL(ret, end_label);
664 NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
666 LABEL *prev_start_label = ISEQ_COMPILE_DATA(iseq)->start_label;
667 LABEL *prev_end_label = ISEQ_COMPILE_DATA(iseq)->end_label;
668 LABEL *prev_redo_label = ISEQ_COMPILE_DATA(iseq)->redo_label;
671 LABEL *next_label = ISEQ_COMPILE_DATA(iseq)->start_label = NEW_LABEL(lineno);
672 LABEL *redo_label = ISEQ_COMPILE_DATA(iseq)->redo_label = NEW_LABEL(lineno);
673 LABEL *break_label = ISEQ_COMPILE_DATA(iseq)->end_label = NEW_LABEL(lineno);
674 LABEL *end_label = NEW_LABEL(lineno);
675 LABEL *adjust_label = NEW_LABEL(lineno);
677 LABEL *next_catch_label = NEW_LABEL(lineno);
678 LABEL *tmp_label = NULL;
682 tmp_label = NEW_LABEL(lineno);
683 ADD_INSNL(ret, &dummy_line_node, jump, tmp_label);
687 ADD_INSNL(ret, &dummy_line_node, jump, next_label);
690 ADD_LABEL(ret, adjust_label);
692 ADD_LABEL(ret, next_catch_label);
694 ADD_INSNL(ret, &dummy_line_node, jump, next_label);
695 if (tmp_label) ADD_LABEL(ret, tmp_label);
697 ADD_LABEL(ret, redo_label);
699 PM_COMPILE_POPPED((
pm_node_t *)statements);
702 ADD_LABEL(ret, next_label);
705 pm_compile_branch_condition(iseq, ret, predicate, redo_label, end_label, src, popped, scope_node);
707 pm_compile_branch_condition(iseq, ret, predicate, end_label, redo_label, src, popped, scope_node);
710 ADD_LABEL(ret, end_label);
711 ADD_ADJUST_RESTORE(ret, adjust_label);
715 ADD_LABEL(ret, break_label);
719 ADD_CATCH_ENTRY(CATCH_TYPE_BREAK, redo_label, break_label, NULL,
721 ADD_CATCH_ENTRY(CATCH_TYPE_NEXT, redo_label, break_label, NULL,
723 ADD_CATCH_ENTRY(CATCH_TYPE_REDO, redo_label, break_label, NULL,
724 ISEQ_COMPILE_DATA(iseq)->redo_label);
726 ISEQ_COMPILE_DATA(iseq)->start_label = prev_start_label;
727 ISEQ_COMPILE_DATA(iseq)->end_label = prev_end_label;
728 ISEQ_COMPILE_DATA(iseq)->redo_label = prev_redo_label;
735 size_t parts_size = parts->
size;
737 if (parts_size > 0) {
738 for (
size_t index = 0; index < parts_size; index++) {
743 ADD_INSN1(ret, &dummy_line_node, putobject, parse_string(&string_node->
unescaped, parser));
746 PM_COMPILE_NOT_POPPED(part);
748 ADD_INSN1(ret, &dummy_line_node, objtostring, new_callinfo(iseq, idTo_s, 0, VM_CALL_FCALL | VM_CALL_ARGS_SIMPLE , NULL, FALSE));
749 ADD_INSN(ret, &dummy_line_node, anytostring);
767 rb_bug(
"This local does not exist");
770 st_data_t local_index;
772 if (!st_lookup(scope_node->index_lookup_table, constant_id, &local_index)) {
774 return pm_lookup_local_index_any_scope(iseq, scope_node->previous, constant_id);
777 return scope_node->local_table_for_iseq_size - (int)local_index;
783 st_data_t local_index;
785 if (!st_lookup(scope_node->index_lookup_table, constant_id, &local_index)) {
786 rb_bug(
"This local does not exist");
789 return scope_node->local_table_for_iseq_size - (int)local_index;
795 for(uint32_t i = 0; i < depth; i++) {
796 scope_node = scope_node->previous;
797 iseq = (
rb_iseq_t *)ISEQ_BODY(iseq)->parent_iseq;
800 return pm_lookup_local_index_any_scope(iseq, scope_node, constant_id);
813 rb_bug(
"[PRISM] constant_id out of range: %u", (
unsigned int)constant_id);
815 return scope_node->constants[constant_id - 1];
820 VALUE name,
const rb_iseq_t *parent,
enum rb_iseq_type type,
int line_no)
822 debugs(
"[new_child_iseq]> ---------------------------------------\n");
823 int isolated_depth = ISEQ_COMPILE_DATA(iseq)->isolated_depth;
824 rb_iseq_t * ret_iseq = pm_iseq_new_with_opt(&node, parser, name,
825 rb_iseq_path(iseq), rb_iseq_realpath(iseq),
827 isolated_depth ? isolated_depth + 1 : 0,
828 type, ISEQ_COMPILE_DATA(iseq)->option);
829 debugs(
"[new_child_iseq]< ---------------------------------------\n");
841 return VM_DEFINECLASS_FLAG_SCOPED;
845 ADD_INSN1(ret, line_node, putobject, rb_cObject);
846 return VM_DEFINECLASS_FLAG_SCOPED;
851 ADD_INSN1(ret, line_node, putspecialobject,
852 INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE));
858pm_compile_call_and_or_write_node(
bool and_node,
pm_node_t *receiver,
pm_node_t *value,
pm_constant_id_t write_name,
pm_constant_id_t read_name,
bool safe_nav,
LINK_ANCHOR *
const ret,
rb_iseq_t *iseq,
int lineno,
const uint8_t * src,
bool popped,
pm_scope_node_t *scope_node)
860 LABEL *call_end_label = NEW_LABEL(lineno);
861 LABEL *else_label = NEW_LABEL(lineno);
862 LABEL *end_label = NEW_LABEL(lineno);
863 NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
868 flag = VM_CALL_FCALL;
871 PM_COMPILE_NOT_POPPED(receiver);
875 ADD_INSNL(ret, &dummy_line_node, branchnil, else_label);
878 ID write_name_id = pm_constant_id_lookup(scope_node, write_name);
879 ID read_name_id = pm_constant_id_lookup(scope_node, read_name);
882 ADD_SEND_WITH_FLAG(ret, &dummy_line_node, read_name_id,
INT2FIX(0),
INT2FIX(flag));
884 PM_DUP_UNLESS_POPPED;
887 ADD_INSNL(ret, &dummy_line_node, branchunless, call_end_label);
891 ADD_INSNL(ret, &dummy_line_node, branchif, call_end_label);
894 PM_POP_UNLESS_POPPED;
896 PM_COMPILE_NOT_POPPED(value);
899 ADD_INSN1(ret, &dummy_line_node, topn,
INT2FIX(1));
901 ID aid = rb_id_attrset(write_name_id);
902 ADD_SEND_WITH_FLAG(ret, &dummy_line_node, aid,
INT2FIX(1),
INT2FIX(flag));
903 ADD_INSNL(ret, &dummy_line_node, jump, end_label);
904 ADD_LABEL(ret, call_end_label);
911 ADD_LABEL(ret, else_label);
914 ADD_LABEL(ret, end_label);
920pm_compile_index_write_nodes_add_send(
bool popped,
LINK_ANCHOR *
const ret,
rb_iseq_t *iseq,
NODE dummy_line_node,
VALUE argc,
int flag,
int block_offset)
923 ADD_INSN1(ret, &dummy_line_node, setn, FIXNUM_INC(argc, 2 + block_offset));
926 if (flag & VM_CALL_ARGS_SPLAT) {
927 ADD_INSN1(ret, &dummy_line_node, newarray,
INT2FIX(1));
928 if (block_offset > 0) {
929 ADD_INSN1(ret, &dummy_line_node, dupn,
INT2FIX(3));
933 ADD_INSN(ret, &dummy_line_node, concatarray);
934 if (block_offset > 0) {
935 ADD_INSN1(ret, &dummy_line_node, setn,
INT2FIX(3));
938 ADD_SEND_WITH_FLAG(ret, &dummy_line_node, idASET, argc,
INT2FIX(flag));
941 if (block_offset > 0) {
944 ADD_SEND_WITH_FLAG(ret, &dummy_line_node, idASET, FIXNUM_INC(argc, 1),
INT2FIX(flag));
955 if (arguments_node == NULL) {
956 if (*flags & VM_CALL_FCALL) {
957 *flags |= VM_CALL_VCALL;
964 bool has_splat =
false;
968 int post_splat_counter = 0;
970 for (
size_t index = 0; index < arguments_node_list.
size; index++) {
979 if (has_keyword_splat) {
980 int cur_hash_size = 0;
983 bool new_hash_emitted =
false;
984 for (
size_t i = 0; i <
len; i++) {
993 PM_COMPILE_NOT_POPPED(assoc->
key);
994 PM_COMPILE_NOT_POPPED(assoc->
value);
1000 if (new_hash_emitted) {
1001 ADD_SEND(ret, &dummy_line_node, id_core_hash_merge_ptr,
INT2FIX(cur_hash_size * 2 + 1));
1004 ADD_INSN1(ret, &dummy_line_node, newhash,
INT2FIX(cur_hash_size * 2));
1006 new_hash_emitted =
true;
1014 ADD_INSN1(ret, &dummy_line_node, putspecialobject,
INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
1016 ADD_INSN1(ret, &dummy_line_node, newhash,
INT2FIX(0));
1017 new_hash_emitted =
true;
1023 *flags |= VM_CALL_KW_SPLAT_MUT;
1027 PM_COMPILE_NOT_POPPED(assoc_splat->
value);
1029 *flags |= VM_CALL_KW_SPLAT;
1032 ADD_SEND(ret, &dummy_line_node, id_core_hash_merge_kwd,
INT2FIX(2));
1036 ADD_INSN1(ret, &dummy_line_node, putspecialobject,
INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
1044 rb_bug(
"Unknown type");
1056 *flags |= VM_CALL_KWARG;
1057 VALUE *keywords = (*kw_arg)->keywords;
1058 (*kw_arg)->references = 0;
1059 (*kw_arg)->keyword_len = (int)
len;
1061 for (
size_t i = 0; i <
len; i++) {
1064 keywords[i] = pm_static_literal_value(key, scope_node, parser);
1065 PM_COMPILE_NOT_POPPED(assoc->
value);
1071 *flags |= VM_CALL_KW_SPLAT;
1075 *flags |= VM_CALL_KW_SPLAT_MUT;
1078 for (
size_t i = 0; i <
len; i++) {
1080 PM_COMPILE_NOT_POPPED(assoc->
key);
1081 PM_COMPILE_NOT_POPPED(assoc->
value);
1084 ADD_INSN1(ret, &dummy_line_node, newhash,
INT2FIX(
len * 2));
1090 *flags |= VM_CALL_ARGS_SPLAT;
1094 PM_COMPILE_NOT_POPPED(splat_node->
expression);
1097 ADD_INSN1(ret, &dummy_line_node, splatarray,
Qfalse);
1100 post_splat_counter = 0;
1106 *flags |= VM_CALL_ARGS_BLOCKARG | VM_CALL_ARGS_SPLAT;
1107 ADD_GETLOCAL(ret, &dummy_line_node, 3, 0);
1108 ADD_INSN1(ret, &dummy_line_node, splatarray, RBOOL(arguments_node_list.
size > 1));
1109 ADD_INSN2(ret, &dummy_line_node, getblockparamproxy,
INT2FIX(4),
INT2FIX(0));
1114 post_splat_counter++;
1115 PM_COMPILE_NOT_POPPED(argument);
1121 ADD_INSN1(ret, &dummy_line_node, newarray,
INT2FIX(post_splat_counter));
1122 ADD_INSN1(ret, &dummy_line_node, splatarray,
Qfalse);
1123 ADD_INSN(ret, &dummy_line_node, concatarray);
1126 else if (index == arguments_node_list.
size - 1) {
1127 if (post_splat_counter > 1) {
1128 ADD_INSN1(ret, &dummy_line_node, newarray,
INT2FIX(post_splat_counter));
1129 ADD_INSN1(ret, &dummy_line_node, splatarray,
Qfalse);
1130 ADD_INSN(ret, &dummy_line_node, concatarray);
1133 ADD_INSN1(ret, &dummy_line_node, newarray,
INT2FIX(post_splat_counter));
1134 ADD_INSN(ret, &dummy_line_node, concatarray);
1147pm_compile_index_and_or_write_node(
bool and_node,
pm_node_t *receiver,
pm_node_t *value,
pm_arguments_node_t *arguments,
pm_node_t *block,
LINK_ANCHOR *
const ret,
rb_iseq_t *iseq,
int lineno,
const uint8_t * src,
bool popped,
pm_scope_node_t *scope_node,
pm_parser_t *parser)
1149 NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
1150 PM_PUTNIL_UNLESS_POPPED;
1152 PM_COMPILE_NOT_POPPED(receiver);
1159 argc_int = pm_setup_args(arguments, &flag, NULL, iseq, ret, src, popped, scope_node, dummy_line_node, parser);
1163 int block_offset = 0;
1166 PM_COMPILE_NOT_POPPED(block);
1167 flag |= VM_CALL_ARGS_BLOCKARG;
1171 ADD_INSN1(ret, &dummy_line_node, dupn, FIXNUM_INC(argc, 1 + block_offset));
1173 ADD_SEND_WITH_FLAG(ret, &dummy_line_node, idAREF, argc,
INT2FIX(flag));
1175 LABEL *label = NEW_LABEL(lineno);
1176 LABEL *lfin = NEW_LABEL(lineno);
1181 ADD_INSNL(ret, &dummy_line_node, branchunless, label);
1185 ADD_INSNL(ret, &dummy_line_node, branchif, label);
1190 PM_COMPILE_NOT_POPPED(value);
1192 pm_compile_index_write_nodes_add_send(popped, ret, iseq, dummy_line_node, argc, flag, block_offset);
1194 ADD_INSNL(ret, &dummy_line_node, jump, lfin);
1195 ADD_LABEL(ret, label);
1197 ADD_INSN1(ret, &dummy_line_node, setn, FIXNUM_INC(argc, 2 + block_offset));
1199 ADD_INSN1(ret, &dummy_line_node, adjuststack, FIXNUM_INC(argc, 2 + block_offset));
1200 ADD_LABEL(ret, lfin);
1237 for (
size_t index = 0; index < cast->
lefts.
size; index++) {
1238 pushed = pm_compile_multi_write_lhs(iseq, dummy_line_node, src, popped, cast->
lefts.
nodes[index], ret, scope_node, pushed,
false);
1246 pushed = pm_compile_multi_write_lhs(iseq, dummy_line_node, src, popped, cast->
parent, ret, scope_node, pushed,
false);
1248 ADD_INSN1(ret, &dummy_line_node, putobject, rb_cObject);
1255 pushed = pm_compile_multi_write_lhs(iseq, dummy_line_node, src, popped, cast->
parent, ret, scope_node, pushed,
false);
1258 ADD_INSN1(ret, &dummy_line_node, putobject, rb_cObject);
1260 pushed = pm_compile_multi_write_lhs(iseq, dummy_line_node, src, popped, cast->
child, ret, scope_node, pushed, cast->
parent);
1265 ADD_INSN1(ret, &dummy_line_node, putobject, RBOOL(!nested));
1266 ADD_INSN1(ret, &dummy_line_node, getconstant,
ID2SYM(pm_constant_id_lookup(scope_node, cast->
name)));
1267 pushed = pushed + 2;
1283#define PM_PATTERN_BASE_INDEX_OFFSET_DECONSTRUCTED_CACHE 0
1284#define PM_PATTERN_BASE_INDEX_OFFSET_ERROR_STRING 1
1285#define PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_P 2
1286#define PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_MATCHEE 3
1287#define PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_KEY 4
1292static int pm_compile_pattern(
rb_iseq_t *iseq,
pm_scope_node_t *scope_node,
const pm_node_t *node,
LINK_ANCHOR *
const ret,
const uint8_t *src,
LABEL *matched_label,
LABEL *unmatched_label,
bool in_single_pattern,
bool in_alternation_pattern,
bool use_deconstructed_cache,
unsigned int base_index);
1302 pm_line_node(&line, scope_node, node);
1304 LABEL *match_succeeded_label = NEW_LABEL(line.lineno);
1306 ADD_INSN(ret, &line.node, dup);
1307 ADD_INSNL(ret, &line.node, branchif, match_succeeded_label);
1309 ADD_INSN1(ret, &line.node, putspecialobject,
INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
1310 ADD_INSN1(ret, &line.node, putobject, message);
1311 ADD_INSN1(ret, &line.node, topn,
INT2FIX(3));
1312 ADD_SEND(ret, &line.node, id_core_sprintf,
INT2FIX(2));
1313 ADD_INSN1(ret, &line.node, setn,
INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_ERROR_STRING + 1));
1315 ADD_INSN1(ret, &line.node, putobject,
Qfalse);
1316 ADD_INSN1(ret, &line.node, setn,
INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_P + 2));
1318 ADD_INSN(ret, &line.node, pop);
1319 ADD_INSN(ret, &line.node, pop);
1320 ADD_LABEL(ret, match_succeeded_label);
1334 pm_line_node(&line, scope_node, node);
1336 LABEL *match_succeeded_label = NEW_LABEL(line.lineno);
1338 ADD_INSN(ret, &line.node, dup);
1339 ADD_INSNL(ret, &line.node, branchif, match_succeeded_label);
1341 ADD_INSN1(ret, &line.node, putspecialobject,
INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
1342 ADD_INSN1(ret, &line.node, putobject, message);
1343 ADD_INSN1(ret, &line.node, topn,
INT2FIX(3));
1344 ADD_INSN(ret, &line.node, dup);
1345 ADD_SEND(ret, &line.node, idLength,
INT2FIX(0));
1346 ADD_INSN1(ret, &line.node, putobject, length);
1347 ADD_SEND(ret, &line.node, id_core_sprintf,
INT2FIX(4));
1348 ADD_INSN1(ret, &line.node, setn,
INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_ERROR_STRING + 1));
1350 ADD_INSN1(ret, &line.node, putobject,
Qfalse);
1351 ADD_INSN1(ret, &line.node, setn,
INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_P + 2));
1353 ADD_INSN(ret, &line.node, pop);
1354 ADD_INSN(ret, &line.node, pop);
1355 ADD_LABEL(ret, match_succeeded_label);
1369 pm_line_node(&line, scope_node, node);
1371 LABEL *match_succeeded_label = NEW_LABEL(line.lineno);
1373 ADD_INSN(ret, &line.node, dup);
1374 ADD_INSNL(ret, &line.node, branchif, match_succeeded_label);
1376 ADD_INSN1(ret, &line.node, putspecialobject,
INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
1377 ADD_INSN1(ret, &line.node, putobject, rb_fstring_lit(
"%p === %p does not return true"));
1378 ADD_INSN1(ret, &line.node, topn,
INT2FIX(3));
1379 ADD_INSN1(ret, &line.node, topn,
INT2FIX(5));
1380 ADD_SEND(ret, &line.node, id_core_sprintf,
INT2FIX(3));
1381 ADD_INSN1(ret, &line.node, setn,
INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_ERROR_STRING + 1));
1382 ADD_INSN1(ret, &line.node, putobject,
Qfalse);
1383 ADD_INSN1(ret, &line.node, setn,
INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_P + 2));
1384 ADD_INSN(ret, &line.node, pop);
1385 ADD_INSN(ret, &line.node, pop);
1387 ADD_LABEL(ret, match_succeeded_label);
1388 ADD_INSN1(ret, &line.node, setn,
INT2FIX(2));
1389 ADD_INSN(ret, &line.node, pop);
1390 ADD_INSN(ret, &line.node, pop);
1402pm_compile_pattern_match(
rb_iseq_t *iseq,
pm_scope_node_t *scope_node,
const pm_node_t *node,
LINK_ANCHOR *
const ret,
const uint8_t *src,
LABEL *unmatched_label,
bool in_single_pattern,
bool in_alternation_pattern,
bool use_deconstructed_cache,
unsigned int base_index)
1404 LABEL *matched_label = NEW_LABEL(nd_line(node));
1405 CHECK(pm_compile_pattern(iseq, scope_node, node, ret, src, matched_label, unmatched_label, in_single_pattern, in_alternation_pattern, use_deconstructed_cache, base_index));
1406 ADD_LABEL(ret, matched_label);
1416pm_compile_pattern_deconstruct(
rb_iseq_t *iseq,
pm_scope_node_t *scope_node,
const pm_node_t *node,
LINK_ANCHOR *
const ret,
const uint8_t *src,
LABEL *deconstruct_label,
LABEL *match_failed_label,
LABEL *deconstructed_label,
LABEL *type_error_label,
bool in_single_pattern,
bool use_deconstructed_cache,
unsigned int base_index)
1419 pm_line_node(&line, scope_node, node);
1421 if (use_deconstructed_cache) {
1422 ADD_INSN1(ret, &line.node, topn,
INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_DECONSTRUCTED_CACHE));
1423 ADD_INSNL(ret, &line.node, branchnil, deconstruct_label);
1425 ADD_INSN1(ret, &line.node, topn,
INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_DECONSTRUCTED_CACHE));
1426 ADD_INSNL(ret, &line.node, branchunless, match_failed_label);
1428 ADD_INSN(ret, &line.node, pop);
1429 ADD_INSN1(ret, &line.node, topn,
INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_DECONSTRUCTED_CACHE - 1));
1430 ADD_INSNL(ret, &line.node, jump, deconstructed_label);
1432 ADD_INSNL(ret, &line.node, jump, deconstruct_label);
1435 ADD_LABEL(ret, deconstruct_label);
1436 ADD_INSN(ret, &line.node, dup);
1437 ADD_INSN1(ret, &line.node, putobject,
ID2SYM(rb_intern(
"deconstruct")));
1438 ADD_SEND(ret, &line.node, idRespond_to,
INT2FIX(1));
1440 if (use_deconstructed_cache) {
1441 ADD_INSN1(ret, &line.node, setn,
INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_DECONSTRUCTED_CACHE + 1));
1444 if (in_single_pattern) {
1445 CHECK(pm_compile_pattern_generic_error(iseq, scope_node, node, ret, rb_fstring_lit(
"%p does not respond to #deconstruct"), base_index + 1));
1448 ADD_INSNL(ret, &line.node, branchunless, match_failed_label);
1449 ADD_SEND(ret, &line.node, rb_intern(
"deconstruct"),
INT2FIX(0));
1451 if (use_deconstructed_cache) {
1452 ADD_INSN1(ret, &line.node, setn,
INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_DECONSTRUCTED_CACHE));
1455 ADD_INSN(ret, &line.node, dup);
1457 ADD_INSNL(ret, &line.node, branchunless, type_error_label);
1458 ADD_LABEL(ret, deconstructed_label);
1471 pm_line_node(&line, scope_node, node);
1473 ADD_INSN(ret, &line.node, dup);
1474 PM_COMPILE_NOT_POPPED(node);
1476 if (in_single_pattern) {
1477 ADD_INSN1(ret, &line.node, dupn,
INT2FIX(2));
1479 ADD_INSN1(ret, &line.node, checkmatch,
INT2FIX(VM_CHECKMATCH_TYPE_CASE));
1480 if (in_single_pattern) {
1481 CHECK(pm_compile_pattern_eqq_error(iseq, scope_node, node, ret, base_index + 3));
1483 ADD_INSNL(ret, &line.node, branchunless, match_failed_label);
1495 pm_line_node(&line, scope_node, node);
1497 LABEL *key_error_label = NEW_LABEL(line.lineno);
1498 LABEL *cleanup_label = NEW_LABEL(line.lineno);
1501 kw_arg->references = 0;
1502 kw_arg->keyword_len = 2;
1503 kw_arg->keywords[0] =
ID2SYM(rb_intern(
"matchee"));
1504 kw_arg->keywords[1] =
ID2SYM(rb_intern(
"key"));
1506 ADD_INSN1(ret, &line.node, putspecialobject,
INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
1507 ADD_INSN1(ret, &line.node, topn,
INT2FIX(PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_P + 2));
1508 ADD_INSNL(ret, &line.node, branchif, key_error_label);
1511 ADD_INSN1(ret, &line.node, putspecialobject,
INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
1512 ADD_INSN1(ret, &line.node, putobject, rb_fstring_lit(
"%p: %s"));
1513 ADD_INSN1(ret, &line.node, topn,
INT2FIX(4));
1514 ADD_INSN1(ret, &line.node, topn,
INT2FIX(PM_PATTERN_BASE_INDEX_OFFSET_ERROR_STRING + 6));
1515 ADD_SEND(ret, &line.node, id_core_sprintf,
INT2FIX(3));
1516 ADD_SEND(ret, &line.node, id_core_raise,
INT2FIX(2));
1517 ADD_INSNL(ret, &line.node, jump, cleanup_label);
1519 ADD_LABEL(ret, key_error_label);
1521 ADD_INSN1(ret, &line.node, putspecialobject,
INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
1522 ADD_INSN1(ret, &line.node, putobject, rb_fstring_lit(
"%p: %s"));
1523 ADD_INSN1(ret, &line.node, topn,
INT2FIX(4));
1524 ADD_INSN1(ret, &line.node, topn,
INT2FIX(PM_PATTERN_BASE_INDEX_OFFSET_ERROR_STRING + 6));
1525 ADD_SEND(ret, &line.node, id_core_sprintf,
INT2FIX(3));
1526 ADD_INSN1(ret, &line.node, topn,
INT2FIX(PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_MATCHEE + 4));
1527 ADD_INSN1(ret, &line.node, topn,
INT2FIX(PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_KEY + 5));
1528 ADD_SEND_R(ret, &line.node, rb_intern(
"new"),
INT2FIX(1), NULL,
INT2FIX(VM_CALL_KWARG), kw_arg);
1529 ADD_SEND(ret, &line.node, id_core_raise,
INT2FIX(1));
1530 ADD_LABEL(ret, cleanup_label);
1532 ADD_INSN1(ret, &line.node, adjuststack,
INT2FIX(7));
1533 if (!popped) ADD_INSN(ret, &line.node, putnil);
1534 ADD_INSNL(ret, &line.node, jump, done_label);
1535 ADD_INSN1(ret, &line.node, dupn,
INT2FIX(5));
1536 if (popped) ADD_INSN(ret, &line.node, putnil);
1543pm_compile_pattern(
rb_iseq_t *iseq,
pm_scope_node_t *scope_node,
const pm_node_t *node,
LINK_ANCHOR *
const ret,
const uint8_t *src,
LABEL *matched_label,
LABEL *unmatched_label,
bool in_single_pattern,
bool in_alternation_pattern,
bool use_deconstructed_cache,
unsigned int base_index)
1546 pm_line_node(&line, scope_node, node);
1561 const size_t posts_size = cast->
posts.
size;
1562 const size_t minimum_size = requireds_size + posts_size;
1564 bool use_rest_size = (
1565 cast->
rest != NULL &&
1570 LABEL *match_failed_label = NEW_LABEL(line.lineno);
1571 LABEL *type_error_label = NEW_LABEL(line.lineno);
1572 LABEL *deconstruct_label = NEW_LABEL(line.lineno);
1573 LABEL *deconstructed_label = NEW_LABEL(line.lineno);
1575 if (use_rest_size) {
1576 ADD_INSN1(ret, &line.node, putobject,
INT2FIX(0));
1577 ADD_INSN(ret, &line.node, swap);
1582 CHECK(pm_compile_pattern_constant(iseq, scope_node, cast->
constant, ret, src, match_failed_label, in_single_pattern, base_index));
1585 CHECK(pm_compile_pattern_deconstruct(iseq, scope_node, node, ret, src, deconstruct_label, match_failed_label, deconstructed_label, type_error_label, in_single_pattern, use_deconstructed_cache, base_index));
1587 ADD_INSN(ret, &line.node, dup);
1588 ADD_SEND(ret, &line.node, idLength,
INT2FIX(0));
1589 ADD_INSN1(ret, &line.node, putobject,
INT2FIX(minimum_size));
1590 ADD_SEND(ret, &line.node, cast->
rest == NULL ? idEq : idGE,
INT2FIX(1));
1591 if (in_single_pattern) {
1592 VALUE message = cast->
rest == NULL ? rb_fstring_lit(
"%p length mismatch (given %p, expected %p)") : rb_fstring_lit(
"%p length mismatch (given %p, expected %p+)");
1593 CHECK(pm_compile_pattern_length_error(iseq, scope_node, node, ret, message,
INT2FIX(minimum_size), base_index + 1));
1595 ADD_INSNL(ret, &line.node, branchunless, match_failed_label);
1597 for (
size_t index = 0; index < requireds_size; index++) {
1599 ADD_INSN(ret, &line.node, dup);
1600 ADD_INSN1(ret, &line.node, putobject,
INT2FIX(index));
1601 ADD_SEND(ret, &line.node, idAREF,
INT2FIX(1));
1602 CHECK(pm_compile_pattern_match(iseq, scope_node, required, ret, src, match_failed_label, in_single_pattern, in_alternation_pattern,
false, base_index + 1));
1605 if (cast->
rest != NULL) {
1607 ADD_INSN(ret, &line.node, dup);
1608 ADD_INSN1(ret, &line.node, putobject,
INT2FIX(requireds_size));
1609 ADD_INSN1(ret, &line.node, topn,
INT2FIX(1));
1610 ADD_SEND(ret, &line.node, idLength,
INT2FIX(0));
1611 ADD_INSN1(ret, &line.node, putobject,
INT2FIX(minimum_size));
1612 ADD_SEND(ret, &line.node, idMINUS,
INT2FIX(1));
1613 ADD_INSN1(ret, &line.node, setn,
INT2FIX(4));
1614 ADD_SEND(ret, &line.node, idAREF,
INT2FIX(2));
1615 CHECK(pm_compile_pattern_match(iseq, scope_node, ((
const pm_splat_node_t *) cast->
rest)->expression, ret, src, match_failed_label, in_single_pattern, in_alternation_pattern,
false, base_index + 1));
1616 }
else if (posts_size > 0) {
1617 ADD_INSN(ret, &line.node, dup);
1618 ADD_SEND(ret, &line.node, idLength,
INT2FIX(0));
1619 ADD_INSN1(ret, &line.node, putobject,
INT2FIX(minimum_size));
1620 ADD_SEND(ret, &line.node, idMINUS,
INT2FIX(1));
1621 ADD_INSN1(ret, &line.node, setn,
INT2FIX(2));
1622 ADD_INSN(ret, &line.node, pop);
1626 for (
size_t index = 0; index < posts_size; index++) {
1628 ADD_INSN(ret, &line.node, dup);
1630 ADD_INSN1(ret, &line.node, putobject,
INT2FIX(requireds_size + index));
1631 ADD_INSN1(ret, &line.node, topn,
INT2FIX(3));
1632 ADD_SEND(ret, &line.node, idPLUS,
INT2FIX(1));
1633 ADD_SEND(ret, &line.node, idAREF,
INT2FIX(1));
1634 CHECK(pm_compile_pattern_match(iseq, scope_node, post, ret, src, match_failed_label, in_single_pattern, in_alternation_pattern,
false, base_index + 1));
1637 ADD_INSN(ret, &line.node, pop);
1638 if (use_rest_size) {
1639 ADD_INSN(ret, &line.node, pop);
1642 ADD_INSNL(ret, &line.node, jump, matched_label);
1643 ADD_INSN(ret, &line.node, putnil);
1644 if (use_rest_size) {
1645 ADD_INSN(ret, &line.node, putnil);
1648 ADD_LABEL(ret, type_error_label);
1649 ADD_INSN1(ret, &line.node, putspecialobject,
INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
1651 ADD_INSN1(ret, &line.node, putobject, rb_fstring_lit(
"deconstruct must return Array"));
1652 ADD_SEND(ret, &line.node, id_core_raise,
INT2FIX(2));
1653 ADD_INSN(ret, &line.node, pop);
1655 ADD_LABEL(ret, match_failed_label);
1656 ADD_INSN(ret, &line.node, pop);
1657 if (use_rest_size) {
1658 ADD_INSN(ret, &line.node, pop);
1661 ADD_INSNL(ret, &line.node, jump, unmatched_label);
1676 LABEL *match_failed_label = NEW_LABEL(line.lineno);
1677 LABEL *type_error_label = NEW_LABEL(line.lineno);
1678 LABEL *deconstruct_label = NEW_LABEL(line.lineno);
1679 LABEL *deconstructed_label = NEW_LABEL(line.lineno);
1682 CHECK(pm_compile_pattern_constant(iseq, scope_node, cast->
constant, ret, src, match_failed_label, in_single_pattern, base_index));
1685 CHECK(pm_compile_pattern_deconstruct(iseq, scope_node, node, ret, src, deconstruct_label, match_failed_label, deconstructed_label, type_error_label, in_single_pattern, use_deconstructed_cache, base_index));
1687 ADD_INSN(ret, &line.node, dup);
1688 ADD_SEND(ret, &line.node, idLength,
INT2FIX(0));
1689 ADD_INSN1(ret, &line.node, putobject,
INT2FIX(size));
1690 ADD_SEND(ret, &line.node, idGE,
INT2FIX(1));
1691 if (in_single_pattern) {
1692 CHECK(pm_compile_pattern_length_error(iseq, scope_node, node, ret, rb_fstring_lit(
"%p length mismatch (given %p, expected %p+)"),
INT2FIX(size), base_index + 1));
1694 ADD_INSNL(ret, &line.node, branchunless, match_failed_label);
1697 LABEL *while_begin_label = NEW_LABEL(line.lineno);
1698 LABEL *next_loop_label = NEW_LABEL(line.lineno);
1699 LABEL *find_succeeded_label = NEW_LABEL(line.lineno);
1700 LABEL *find_failed_label = NEW_LABEL(line.lineno);
1702 ADD_INSN(ret, &line.node, dup);
1703 ADD_SEND(ret, &line.node, idLength,
INT2FIX(0));
1705 ADD_INSN(ret, &line.node, dup);
1706 ADD_INSN1(ret, &line.node, putobject,
INT2FIX(size));
1707 ADD_SEND(ret, &line.node, idMINUS,
INT2FIX(1));
1708 ADD_INSN1(ret, &line.node, putobject,
INT2FIX(0));
1709 ADD_LABEL(ret, while_begin_label);
1711 ADD_INSN(ret, &line.node, dup);
1712 ADD_INSN1(ret, &line.node, topn,
INT2FIX(2));
1713 ADD_SEND(ret, &line.node, idLE,
INT2FIX(1));
1714 ADD_INSNL(ret, &line.node, branchunless, find_failed_label);
1716 for (
size_t index = 0; index < size; index++) {
1717 ADD_INSN1(ret, &line.node, topn,
INT2FIX(3));
1718 ADD_INSN1(ret, &line.node, topn,
INT2FIX(1));
1721 ADD_INSN1(ret, &line.node, putobject,
INT2FIX(index));
1722 ADD_SEND(ret, &line.node, idPLUS,
INT2FIX(1));
1725 ADD_SEND(ret, &line.node, idAREF,
INT2FIX(1));
1726 CHECK(pm_compile_pattern_match(iseq, scope_node, cast->
requireds.
nodes[index], ret, src, next_loop_label, in_single_pattern, in_alternation_pattern,
false, base_index + 4));
1732 if (left->expression != NULL) {
1733 ADD_INSN1(ret, &line.node, topn,
INT2FIX(3));
1734 ADD_INSN1(ret, &line.node, putobject,
INT2FIX(0));
1735 ADD_INSN1(ret, &line.node, topn,
INT2FIX(2));
1736 ADD_SEND(ret, &line.node, idAREF,
INT2FIX(2));
1737 CHECK(pm_compile_pattern_match(iseq, scope_node, left->expression, ret, src, find_failed_label, in_single_pattern, in_alternation_pattern,
false, base_index + 4));
1743 if (right->expression != NULL) {
1744 ADD_INSN1(ret, &line.node, topn,
INT2FIX(3));
1745 ADD_INSN1(ret, &line.node, topn,
INT2FIX(1));
1746 ADD_INSN1(ret, &line.node, putobject,
INT2FIX(size));
1747 ADD_SEND(ret, &line.node, idPLUS,
INT2FIX(1));
1748 ADD_INSN1(ret, &line.node, topn,
INT2FIX(3));
1749 ADD_SEND(ret, &line.node, idAREF,
INT2FIX(2));
1750 pm_compile_pattern_match(iseq, scope_node, right->expression, ret, src, find_failed_label, in_single_pattern, in_alternation_pattern,
false, base_index + 4);
1753 ADD_INSNL(ret, &line.node, jump, find_succeeded_label);
1755 ADD_LABEL(ret, next_loop_label);
1756 ADD_INSN1(ret, &line.node, putobject,
INT2FIX(1));
1757 ADD_SEND(ret, &line.node, idPLUS,
INT2FIX(1));
1758 ADD_INSNL(ret, &line.node, jump, while_begin_label);
1760 ADD_LABEL(ret, find_failed_label);
1761 ADD_INSN1(ret, &line.node, adjuststack,
INT2FIX(3));
1762 if (in_single_pattern) {
1763 ADD_INSN1(ret, &line.node, putspecialobject,
INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
1764 ADD_INSN1(ret, &line.node, putobject, rb_fstring_lit(
"%p does not match to find pattern"));
1765 ADD_INSN1(ret, &line.node, topn,
INT2FIX(2));
1766 ADD_SEND(ret, &line.node, id_core_sprintf,
INT2FIX(2));
1767 ADD_INSN1(ret, &line.node, setn,
INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_ERROR_STRING + 1));
1769 ADD_INSN1(ret, &line.node, putobject,
Qfalse);
1770 ADD_INSN1(ret, &line.node, setn,
INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_P + 2));
1772 ADD_INSN(ret, &line.node, pop);
1773 ADD_INSN(ret, &line.node, pop);
1775 ADD_INSNL(ret, &line.node, jump, match_failed_label);
1776 ADD_INSN1(ret, &line.node, dupn,
INT2FIX(3));
1778 ADD_LABEL(ret, find_succeeded_label);
1779 ADD_INSN1(ret, &line.node, adjuststack,
INT2FIX(3));
1782 ADD_INSN(ret, &line.node, pop);
1783 ADD_INSNL(ret, &line.node, jump, matched_label);
1784 ADD_INSN(ret, &line.node, putnil);
1786 ADD_LABEL(ret, type_error_label);
1787 ADD_INSN1(ret, &line.node, putspecialobject,
INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
1789 ADD_INSN1(ret, &line.node, putobject, rb_fstring_lit(
"deconstruct must return Array"));
1790 ADD_SEND(ret, &line.node, id_core_raise,
INT2FIX(2));
1791 ADD_INSN(ret, &line.node, pop);
1793 ADD_LABEL(ret, match_failed_label);
1794 ADD_INSN(ret, &line.node, pop);
1795 ADD_INSNL(ret, &line.node, jump, unmatched_label);
1814 LABEL *match_failed_label = NEW_LABEL(line.lineno);
1815 LABEL *type_error_label = NEW_LABEL(line.lineno);
1818 if (has_keys && !has_rest) {
1821 for (
size_t index = 0; index < cast->
elements.
size; index++) {
1829 rb_ary_push(keys, symbol);
1834 CHECK(pm_compile_pattern_constant(iseq, scope_node, cast->
constant, ret, src, match_failed_label, in_single_pattern, base_index));
1837 ADD_INSN(ret, &line.node, dup);
1838 ADD_INSN1(ret, &line.node, putobject,
ID2SYM(rb_intern(
"deconstruct_keys")));
1839 ADD_SEND(ret, &line.node, idRespond_to,
INT2FIX(1));
1840 if (in_single_pattern) {
1841 CHECK(pm_compile_pattern_generic_error(iseq, scope_node, node, ret, rb_fstring_lit(
"%p does not respond to #deconstruct_keys"), base_index + 1));
1843 ADD_INSNL(ret, &line.node, branchunless, match_failed_label);
1846 ADD_INSN(ret, &line.node, putnil);
1848 ADD_INSN1(ret, &line.node, duparray, keys);
1851 ADD_SEND(ret, &line.node, rb_intern(
"deconstruct_keys"),
INT2FIX(1));
1853 ADD_INSN(ret, &line.node, dup);
1855 ADD_INSNL(ret, &line.node, branchunless, type_error_label);
1858 ADD_SEND(ret, &line.node, rb_intern(
"dup"),
INT2FIX(0));
1862 DECL_ANCHOR(match_values);
1863 INIT_ANCHOR(match_values);
1865 for (
size_t index = 0; index < cast->
elements.
size; index++) {
1874 ADD_INSN(ret, &line.node, dup);
1875 ADD_INSN1(ret, &line.node, putobject, symbol);
1876 ADD_SEND(ret, &line.node, rb_intern(
"key?"),
INT2FIX(1));
1878 if (in_single_pattern) {
1879 LABEL *match_succeeded_label = NEW_LABEL(line.lineno);
1881 ADD_INSN(ret, &line.node, dup);
1882 ADD_INSNL(ret, &line.node, branchif, match_succeeded_label);
1884 ADD_INSN1(ret, &line.node, putobject,
rb_str_freeze(rb_sprintf(
"key not found: %+"PRIsVALUE, symbol)));
1885 ADD_INSN1(ret, &line.node, setn,
INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_ERROR_STRING + 2));
1886 ADD_INSN1(ret, &line.node, putobject,
Qtrue);
1887 ADD_INSN1(ret, &line.node, setn,
INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_P + 3));
1888 ADD_INSN1(ret, &line.node, topn,
INT2FIX(3));
1889 ADD_INSN1(ret, &line.node, setn,
INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_MATCHEE + 4));
1890 ADD_INSN1(ret, &line.node, putobject, symbol);
1891 ADD_INSN1(ret, &line.node, setn,
INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_KEY + 5));
1893 ADD_INSN1(ret, &line.node, adjuststack,
INT2FIX(4));
1894 ADD_LABEL(ret, match_succeeded_label);
1897 ADD_INSNL(ret, &line.node, branchunless, match_failed_label);
1898 ADD_INSN(match_values, &line.node, dup);
1899 ADD_INSN1(match_values, &line.node, putobject, symbol);
1900 ADD_SEND(match_values, &line.node, has_rest ? rb_intern(
"delete") : idAREF,
INT2FIX(1));
1902 CHECK(pm_compile_pattern_match(iseq, scope_node, assoc->
value, match_values, src, match_failed_label, in_single_pattern, in_alternation_pattern,
false, base_index + 1));
1905 ADD_SEQ(ret, match_values);
1907 ADD_INSN(ret, &line.node, dup);
1908 ADD_SEND(ret, &line.node, idEmptyP,
INT2FIX(0));
1909 if (in_single_pattern) {
1910 CHECK(pm_compile_pattern_generic_error(iseq, scope_node, node, ret, rb_fstring_lit(
"%p is not empty"), base_index + 1));
1912 ADD_INSNL(ret, &line.node, branchunless, match_failed_label);
1918 ADD_INSN(ret, &line.node, dup);
1919 ADD_SEND(ret, &line.node, idEmptyP,
INT2FIX(0));
1920 if (in_single_pattern) {
1921 pm_compile_pattern_generic_error(iseq, scope_node, node, ret, rb_fstring_lit(
"rest of %p is not empty"), base_index + 1);
1923 ADD_INSNL(ret, &line.node, branchunless, match_failed_label);
1928 ADD_INSN(ret, &line.node, dup);
1929 pm_compile_pattern_match(iseq, scope_node, splat->value, ret, src, match_failed_label, in_single_pattern, in_alternation_pattern,
false, base_index + 1);
1933 rb_bug(
"unreachable");
1938 ADD_INSN(ret, &line.node, pop);
1939 ADD_INSNL(ret, &line.node, jump, matched_label);
1940 ADD_INSN(ret, &line.node, putnil);
1942 ADD_LABEL(ret, type_error_label);
1943 ADD_INSN1(ret, &line.node, putspecialobject,
INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
1945 ADD_INSN1(ret, &line.node, putobject, rb_fstring_lit(
"deconstruct_keys must return Hash"));
1946 ADD_SEND(ret, &line.node, id_core_raise,
INT2FIX(2));
1947 ADD_INSN(ret, &line.node, pop);
1949 ADD_LABEL(ret, match_failed_label);
1950 ADD_INSN(ret, &line.node, pop);
1951 ADD_INSNL(ret, &line.node, jump, unmatched_label);
1966 LABEL *match_failed_label = NEW_LABEL(line.lineno);
1968 ADD_INSN(ret, &line.node, dup);
1969 CHECK(pm_compile_pattern_match(iseq, scope_node, cast->
value, ret, src, match_failed_label, in_single_pattern, in_alternation_pattern, use_deconstructed_cache, base_index + 1));
1970 CHECK(pm_compile_pattern(iseq, scope_node, cast->
target, ret, src, matched_label, match_failed_label, in_single_pattern, in_alternation_pattern,
false, base_index));
1971 ADD_INSN(ret, &line.node, putnil);
1973 ADD_LABEL(ret, match_failed_label);
1974 ADD_INSN(ret, &line.node, pop);
1975 ADD_INSNL(ret, &line.node, jump, unmatched_label);
1984 int index = pm_lookup_local_index(iseq, scope_node, cast->
name);
1990 if (in_alternation_pattern) {
1991 ID id = pm_constant_id_lookup(scope_node, cast->
name);
1992 const char *name = rb_id2name(
id);
1994 if (name && strlen(name) > 0 && name[0] !=
'_') {
1995 COMPILE_ERROR(ERROR_ARGS
"illegal variable in alternative pattern (%"PRIsVALUE
")", rb_id2str(
id));
2000 ADD_SETLOCAL(ret, &line.node, index, (
int) cast->
depth);
2001 ADD_INSNL(ret, &line.node, jump, matched_label);
2009 LABEL *matched_left_label = NEW_LABEL(line.lineno);
2010 LABEL *unmatched_left_label = NEW_LABEL(line.lineno);
2014 ADD_INSN(ret, &line.node, dup);
2015 CHECK(pm_compile_pattern(iseq, scope_node, cast->
left, ret, src, matched_left_label, unmatched_left_label, in_single_pattern,
true,
true, base_index + 1));
2020 ADD_LABEL(ret, matched_left_label);
2021 ADD_INSN(ret, &line.node, pop);
2022 ADD_INSNL(ret, &line.node, jump, matched_label);
2023 ADD_INSN(ret, &line.node, putnil);
2027 ADD_LABEL(ret, unmatched_left_label);
2028 CHECK(pm_compile_pattern(iseq, scope_node, cast->
right, ret, src, matched_label, unmatched_label, in_single_pattern,
true,
true, base_index));
2059 PM_COMPILE_NOT_POPPED(node);
2060 if (in_single_pattern) {
2061 ADD_INSN1(ret, &line.node, dupn,
INT2FIX(2));
2064 ADD_INSN1(ret, &line.node, checkmatch,
INT2FIX(VM_CHECKMATCH_TYPE_CASE));
2066 if (in_single_pattern) {
2067 pm_compile_pattern_eqq_error(iseq, scope_node, node, ret, base_index + 2);
2070 ADD_INSNL(ret, &line.node, branchif, matched_label);
2071 ADD_INSNL(ret, &line.node, jump, unmatched_label);
2080 CHECK(pm_compile_pattern(iseq, scope_node, cast->
variable, ret, src, matched_label, unmatched_label, in_single_pattern, in_alternation_pattern,
true, base_index));
2089 CHECK(pm_compile_pattern(iseq, scope_node, cast->
expression, ret, src, matched_label, unmatched_label, in_single_pattern, in_alternation_pattern,
true, base_index));
2122 CHECK(pm_compile_pattern_match(iseq, scope_node, statement, ret, src, unmatched_label, in_single_pattern, in_alternation_pattern, use_deconstructed_cache, base_index));
2123 PM_COMPILE_NOT_POPPED(predicate);
2125 if (in_single_pattern) {
2126 LABEL *match_succeeded_label = NEW_LABEL(line.lineno);
2128 ADD_INSN(ret, &line.node, dup);
2130 ADD_INSNL(ret, &line.node, branchif, match_succeeded_label);
2132 ADD_INSNL(ret, &line.node, branchunless, match_succeeded_label);
2135 ADD_INSN1(ret, &line.node, putobject, rb_fstring_lit(
"guard clause does not return true"));
2136 ADD_INSN1(ret, &line.node, setn,
INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_ERROR_STRING + 1));
2137 ADD_INSN1(ret, &line.node, putobject,
Qfalse);
2138 ADD_INSN1(ret, &line.node, setn,
INT2FIX(base_index + PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_P + 2));
2140 ADD_INSN(ret, &line.node, pop);
2141 ADD_INSN(ret, &line.node, pop);
2143 ADD_LABEL(ret, match_succeeded_label);
2147 ADD_INSNL(ret, &line.node, branchunless, unmatched_label);
2149 ADD_INSNL(ret, &line.node, branchif, unmatched_label);
2152 ADD_INSNL(ret, &line.node, jump, matched_label);
2159 rb_bug(
"Unexpected node type in pattern matching expression: %s", pm_node_type_to_str(
PM_NODE_TYPE(node)));
2166#undef PM_PATTERN_BASE_INDEX_OFFSET_DECONSTRUCTED_CACHE
2167#undef PM_PATTERN_BASE_INDEX_OFFSET_ERROR_STRING
2168#undef PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_P
2169#undef PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_MATCHEE
2170#undef PM_PATTERN_BASE_INDEX_OFFSET_KEY_ERROR_KEY
2180 scope->previous = previous;
2181 scope->parser = parser;
2183 scope->parameters = NULL;
2185 scope->constants = NULL;
2186 scope->local_depth_offset = 0;
2187 scope->local_table_for_iseq_size = 0;
2190 scope->constants = previous->constants;
2191 scope->local_depth_offset = previous->local_depth_offset;
2193 scope->index_lookup_table = NULL;
2195 pm_constant_id_list_init(&scope->locals);
2200 scope->body = cast->
body;
2201 scope->locals = cast->
locals;
2202 scope->local_depth_offset = 0;
2208 scope->body = cast->
body;
2209 scope->locals = cast->
locals;
2215 scope->body = cast->body;
2216 scope->locals = cast->locals;
2221 scope->local_depth_offset += 1;
2227 scope->local_depth_offset += 1;
2233 scope->local_depth_offset += 1;
2239 scope->body = cast->
body;
2240 scope->locals = cast->
locals;
2245 scope->body = cast->
body;
2246 scope->locals = cast->
locals;
2252 scope->local_depth_offset += 2;
2258 scope->locals = cast->locals;
2264 scope->local_depth_offset += 1;
2270 scope->local_depth_offset += 1;
2275 scope->body = cast->
body;
2276 scope->locals = cast->
locals;
2285 assert(
false &&
"unreachable");
2293pm_compile_defined_expr0(
rb_iseq_t *iseq,
const pm_node_t *node,
LINK_ANCHOR *
const ret,
const uint8_t *src,
bool popped,
pm_scope_node_t *scope_node,
NODE dummy_line_node,
int lineno,
bool in_condition,
LABEL **lfinish,
bool explicit_receiver)
2296 enum defined_type dtype = DEFINED_NOT_DEFINED;
2301 for (
size_t idx = 0; idx < arguments->
size; idx++) {
2303 pm_compile_defined_expr0(iseq, argument, ret, src, popped, scope_node, dummy_line_node, lineno, in_condition, lfinish, explicit_receiver);
2306 lfinish[1] = NEW_LABEL(lineno);
2308 ADD_INSNL(ret, &dummy_line_node, branchunless, lfinish[1]);
2310 dtype = DEFINED_TRUE;
2314 dtype = DEFINED_NIL;
2319 if (parentheses_node->
body == NULL) {
2320 dtype = DEFINED_NIL;
2322 dtype = DEFINED_EXPR;
2327 dtype = DEFINED_SELF;
2330 dtype = DEFINED_TRUE;
2333 dtype = DEFINED_FALSE;
2338 for (
size_t index = 0; index < array_node->
elements.
size; index++) {
2339 pm_compile_defined_expr0(iseq, array_node->
elements.
nodes[index], ret, src, popped, scope_node, dummy_line_node, lineno,
true, lfinish,
false);
2341 lfinish[1] = NEW_LABEL(lineno);
2343 ADD_INSNL(ret, &dummy_line_node, branchunless, lfinish[1]);
2366 dtype = DEFINED_EXPR;
2369 dtype = DEFINED_LVAR;
2371#define PUSH_VAL(type) (in_condition ? Qtrue : rb_iseq_defined_string(type))
2374 ID id = pm_constant_id_lookup(scope_node, instance_variable_read_node->
name);
2375 ADD_INSN3(ret, &dummy_line_node, definedivar,
2376 ID2SYM(
id), get_ivar_ic_value(iseq,
id), PUSH_VAL(DEFINED_IVAR));
2381 ID backref_val =
INT2FIX(rb_intern2(char_ptr, 1)) << 1 | 1;
2384 ADD_INSN3(ret, &dummy_line_node, defined,
INT2FIX(DEFINED_REF),
2386 PUSH_VAL(DEFINED_GVAR));
2394 ADD_INSN3(ret, &dummy_line_node, defined,
INT2FIX(DEFINED_REF),
2395 INT2FIX(reference_number << 1),
2396 PUSH_VAL(DEFINED_GVAR));
2403 ADD_INSN3(ret, &dummy_line_node, defined,
INT2FIX(DEFINED_GVAR),
2404 ID2SYM(pm_constant_id_lookup(scope_node, glabal_variable_read_node->
name)), PUSH_VAL(DEFINED_GVAR));
2410 ADD_INSN3(ret, &dummy_line_node, defined,
INT2FIX(DEFINED_CVAR),
2411 ID2SYM(pm_constant_id_lookup(scope_node, class_variable_read_node->
name)), PUSH_VAL(DEFINED_CVAR));
2418 ADD_INSN3(ret, &dummy_line_node, defined,
INT2FIX(DEFINED_CONST),
2419 ID2SYM(pm_constant_id_lookup(scope_node, constant_node->
name)), PUSH_VAL(DEFINED_CONST));
2424 if (constant_path_node->
parent) {
2426 lfinish[1] = NEW_LABEL(lineno);
2428 pm_compile_defined_expr0(iseq, constant_path_node->
parent, ret, src, popped, scope_node, dummy_line_node, lineno,
true, lfinish,
false);
2429 ADD_INSNL(ret, &dummy_line_node, branchunless, lfinish[1]);
2430 PM_COMPILE(constant_path_node->
parent);
2433 ADD_INSN1(ret, &dummy_line_node, putobject, rb_cObject);
2435 ADD_INSN3(ret, &dummy_line_node, defined,
INT2FIX(DEFINED_CONST_FROM),
2442 ID method_id = pm_constant_id_lookup(scope_node, call_node->
name);
2446 lfinish[1] = NEW_LABEL(lineno);
2449 lfinish[2] = NEW_LABEL(lineno);
2454 pm_compile_defined_expr0(iseq, (
const pm_node_t *)call_node->
arguments, ret, src, popped, scope_node, dummy_line_node, lineno,
true, lfinish,
false);
2455 ADD_INSNL(ret, &dummy_line_node, branchunless, lfinish[1]);
2459 pm_compile_defined_expr0(iseq, call_node->
receiver, ret, src, popped, scope_node, dummy_line_node, lineno,
true, lfinish,
true);
2461 ADD_INSNL(ret, &dummy_line_node, branchunless, lfinish[2]);
2462 ID method_id = pm_constant_id_lookup(scope_node, call_node->
name);
2463 pm_compile_call(iseq, (
const pm_call_node_t *)call_node->
receiver, ret, src, popped, scope_node, method_id, NULL);
2466 ADD_INSNL(ret, &dummy_line_node, branchunless, lfinish[1]);
2470 if (explicit_receiver) {
2474 ADD_INSN3(ret, &dummy_line_node, defined,
INT2FIX(DEFINED_METHOD), rb_id2sym(method_id), PUSH_VAL(DEFINED_METHOD));
2478 if (explicit_receiver) {
2481 ADD_INSN3(ret, &dummy_line_node, defined,
INT2FIX(DEFINED_FUNC), rb_id2sym(method_id), PUSH_VAL(DEFINED_METHOD));
2488 ADD_INSN3(ret, &dummy_line_node, defined,
INT2FIX(DEFINED_YIELD), 0,
2489 PUSH_VAL(DEFINED_YIELD));
2494 ADD_INSN3(ret, &dummy_line_node, defined,
INT2FIX(DEFINED_ZSUPER), 0,
2495 PUSH_VAL(DEFINED_ZSUPER));
2523 dtype = DEFINED_ASGN;
2526 rb_bug(
"Unsupported node %s", pm_node_type_to_str(
PM_NODE_TYPE(node)));
2529 assert(dtype != DEFINED_NOT_DEFINED);
2531 ADD_INSN1(ret, &dummy_line_node, putobject, PUSH_VAL(dtype));
2536pm_defined_expr(
rb_iseq_t *iseq,
const pm_node_t *node,
LINK_ANCHOR *
const ret,
const uint8_t *src,
bool popped,
pm_scope_node_t *scope_node,
NODE dummy_line_node,
int lineno,
bool in_condition,
LABEL **lfinish,
bool explicit_receiver)
2540 pm_compile_defined_expr0(iseq, node, ret, src, popped, scope_node, dummy_line_node, lineno, in_condition, lfinish,
false);
2543 LABEL *lstart = NEW_LABEL(lineno);
2544 LABEL *lend = NEW_LABEL(lineno);
2547 rb_iseq_new_with_callback_new_callback(build_defined_rescue_iseq, NULL);
2549 const rb_iseq_t *rescue = new_child_iseq_with_callback(iseq, ifunc,
2551 ISEQ_BODY(iseq)->location.label),
2552 iseq, ISEQ_TYPE_RESCUE, 0);
2554 lstart->rescued = LABEL_RESCUE_BEG;
2555 lend->rescued = LABEL_RESCUE_END;
2557 APPEND_LABEL(ret, lcur, lstart);
2558 ADD_LABEL(ret, lend);
2559 ADD_CATCH_ENTRY(CATCH_TYPE_RESCUE, lstart, lend, rescue, lfinish[1]);
2569 lfinish[0] = NEW_LABEL(lineno);
2574 pm_defined_expr(iseq, node, ret, src, popped, scope_node, dummy_line_node, lineno, in_condition, lfinish,
false);
2578 ELEM_INSERT_NEXT(last, &new_insn_body(iseq, &dummy_line_node, BIN(putnil), 0)->link);
2581 ADD_LABEL(ret, lfinish[2]);
2584 ADD_LABEL(ret, lfinish[1]);
2587 ADD_LABEL(ret, lfinish[0]);
2595 int lineno = (int)pm_newline_list_line_column(&newline_list, ((
pm_node_t *)call_node)->location.start).line;
2596 NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
2597 LABEL *else_label = NEW_LABEL(lineno);
2598 LABEL *end_label = NEW_LABEL(lineno);
2604 ADD_INSNL(ret, &dummy_line_node, branchnil, else_label);
2610 int orig_argc = pm_setup_args(call_node->arguments, &flags, &kw_arg, iseq, ret, src, popped, scope_node, dummy_line_node, parser);
2616 pm_scope_node_init(call_node->block, &next_scope_node, scope_node, parser);
2618 block_iseq = NEW_CHILD_ISEQ(next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, lineno);
2619 if (ISEQ_BODY(block_iseq)->catch_table) {
2620 ADD_CATCH_ENTRY(CATCH_TYPE_BREAK, start, end_label, block_iseq, end_label);
2622 ISEQ_COMPILE_DATA(iseq)->current_block = block_iseq;
2626 flags |= VM_CALL_VCALL;
2629 if (call_node->block != NULL) {
2630 PM_COMPILE_NOT_POPPED(call_node->block);
2631 flags |= VM_CALL_ARGS_BLOCKARG;
2635 flags |= VM_CALL_ARGS_SIMPLE;
2640 flags |= VM_CALL_FCALL;
2645 ADD_INSN1(ret, &dummy_line_node, setn,
INT2FIX(orig_argc + 1));
2647 ADD_SEND_R(ret, &dummy_line_node, method_id,
INT2FIX(orig_argc), block_iseq,
INT2FIX(flags), kw_arg);
2648 PM_POP_UNLESS_POPPED;
2651 ADD_SEND_R(ret, &dummy_line_node, method_id,
INT2FIX(orig_argc), block_iseq,
INT2FIX(flags), kw_arg);
2655 ADD_INSNL(ret, &dummy_line_node, jump, end_label);
2656 ADD_LABEL(ret, else_label);
2658 ADD_LABEL(ret, end_label);
2668 assert(can_add_ensure_iseq(iseq));
2671 ISEQ_COMPILE_DATA(iseq)->ensure_node_stack;
2673 DECL_ANCHOR(ensure);
2675 INIT_ANCHOR(ensure);
2677 if (enlp->erange != NULL) {
2678 DECL_ANCHOR(ensure_part);
2679 LABEL *lstart = NEW_LABEL(0);
2680 LABEL *lend = NEW_LABEL(0);
2681 INIT_ANCHOR(ensure_part);
2683 add_ensure_range(iseq, enlp->erange, lstart, lend);
2685 ISEQ_COMPILE_DATA(iseq)->ensure_node_stack = enlp->prev;
2686 ADD_LABEL(ensure_part, lstart);
2688 PM_COMPILE_INTO_ANCHOR(ensure_part, (
pm_node_t *)enlp->ensure_node);
2689 ADD_LABEL(ensure_part, lend);
2690 ADD_SEQ(ensure, ensure_part);
2699 ISEQ_COMPILE_DATA(iseq)->ensure_node_stack = prev_enlp;
2700 ADD_SEQ(ret, ensure);
2706 ID local = pm_constant_id_lookup(scope_node, constant_id);
2707 local_table_for_iseq->ids[local_index] = local;
2708 st_insert(index_lookup_table, constant_id, local_index);
2714 for (
size_t m = 0; m < multi->
lefts.
size; m++) {
2720 pm_insert_local_index(req->
name, local_index, index_lookup_table, local_table_for_iseq, scope_node);
2725 local_index = pm_compile_multi_assign_params((
pm_multi_target_node_t *)multi_node, index_lookup_table, local_table_for_iseq, scope_node, local_index);
2729 rb_bug(
"Parameter within a MultiTargetNode isn't allowed");
2738 pm_insert_local_index(req->name, local_index, index_lookup_table, local_table_for_iseq, scope_node);
2743 for (
size_t m = 0; m < multi->
rights.
size; m++) {
2749 pm_insert_local_index(req->
name, local_index, index_lookup_table, local_table_for_iseq, scope_node);
2754 local_index = pm_compile_multi_assign_params((
pm_multi_target_node_t *)multi_node, index_lookup_table, local_table_for_iseq, scope_node, local_index);
2758 rb_bug(
"Parameter within a MultiTargetNode isn't allowed");
2781 int lineno = (int)pm_newline_list_line_column(&newline_list, node->
location.
start).
line;
2782 NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
2784 if (node->
flags & PM_NODE_FLAG_NEWLINE &&
2785 ISEQ_COMPILE_DATA(iseq)->last_line != lineno) {
2788 ISEQ_COMPILE_DATA(iseq)->last_line = lineno;
2789 if (ISEQ_COVERAGE(iseq) && ISEQ_LINE_COVERAGE(iseq)) {
2790 event |= RUBY_EVENT_COVERAGE_LINE;
2792 ADD_TRACE(ret, event);
2799 ADD_INSN1(ret, &dummy_line_node, putspecialobject,
INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
2801 ADD_INSN1(ret, &dummy_line_node, putobject,
ID2SYM(parse_location_symbol(&alias_node->
new_name->
location, parser)));
2802 ADD_INSN1(ret, &dummy_line_node, putobject,
ID2SYM(parse_location_symbol(&alias_node->
old_name->
location, parser)));
2804 ADD_SEND(ret, &dummy_line_node, id_core_set_variable_alias,
INT2FIX(2));
2812 ADD_INSN1(ret, &dummy_line_node, putspecialobject,
INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
2813 ADD_INSN1(ret, &dummy_line_node, putspecialobject,
INT2FIX(VM_SPECIAL_OBJECT_CBASE));
2815 PM_COMPILE_NOT_POPPED(alias_node->
new_name);
2816 PM_COMPILE_NOT_POPPED(alias_node->
old_name);
2818 ADD_SEND(ret, &dummy_line_node, id_core_set_method_alias,
INT2FIX(3));
2827 LABEL *end_label = NEW_LABEL(lineno);
2828 PM_COMPILE_NOT_POPPED(and_node->
left);
2829 PM_DUP_UNLESS_POPPED;
2830 ADD_INSNL(ret, &dummy_line_node, branchunless, end_label);
2832 PM_POP_UNLESS_POPPED;
2833 PM_COMPILE(and_node->
right);
2834 ADD_LABEL(ret, end_label);
2843 for (
size_t index = 0; index < node_list.
size; index++) {
2844 PM_COMPILE(node_list.
nodes[index]);
2846 if (node_list.
size > 1) {
2847 ADD_INSN1(ret, &dummy_line_node, newarray,
INT2FIX(node_list.
size));
2854 if (pm_static_literal_p(node)) {
2861 VALUE value = pm_static_literal_value(node, scope_node, parser);
2862 ADD_INSN1(ret, &dummy_line_node, duparray, value);
2866 ADD_INSN1(ret, &dummy_line_node, newarray,
INT2FIX(0));
2884 if (elements->
size == 1) {
2888 PM_COMPILE_NOT_POPPED(elements->
nodes[0]);
2894 int new_array_size = 0;
2895 bool need_to_concat_array =
false;
2896 for (
size_t index = 0; index < elements->
size; index++) {
2903 if (new_array_size) {
2904 ADD_INSN1(ret, &dummy_line_node, newarray,
INT2FIX(new_array_size));
2908 if (need_to_concat_array) {
2909 ADD_INSN(ret, &dummy_line_node, concatarray);
2915 PM_COMPILE_NOT_POPPED(splat_element->
expression);
2918 ADD_INSN(ret, &dummy_line_node, concatarray);
2922 ADD_INSN1(ret, &dummy_line_node, splatarray,
Qtrue);
2925 need_to_concat_array =
true;
2929 PM_COMPILE_NOT_POPPED(array_element);
2933 if (new_array_size) {
2934 ADD_INSN1(ret, &dummy_line_node, newarray,
INT2FIX(new_array_size));
2935 if (need_to_concat_array) {
2936 ADD_INSN(ret, &dummy_line_node, concatarray);
2944 for (
size_t index = 0; index < elements->
size; index++) {
2945 PM_COMPILE(elements->
nodes[index]);
2949 ADD_INSN1(ret, &dummy_line_node, newarray,
INT2FIX(elements->
size));
2957 PM_COMPILE(assoc_node->
key);
2958 if (assoc_node->
value) {
2959 PM_COMPILE(assoc_node->
value);
2966 PM_COMPILE(assoc_splat_node->
value);
2974 ID backref_val =
INT2FIX(rb_intern2(char_ptr, 1)) << 1 | 1;
2975 ADD_INSN2(ret, &dummy_line_node, getspecial,
INT2FIX(1), backref_val);
2982 LABEL *lstart = NEW_LABEL(lineno);
2983 LABEL *lend = NEW_LABEL(lineno);
2984 LABEL *lcont = NEW_LABEL(lineno);
2991 rb_iseq_t *rescue_iseq = NEW_CHILD_ISEQ(rescue_scope_node,
2993 ISEQ_BODY(iseq)->location.label),
2994 ISEQ_TYPE_RESCUE, 1);
2995 lstart->rescued = LABEL_RESCUE_BEG;
2996 lend->rescued = LABEL_RESCUE_END;
2997 ADD_LABEL(ret, lstart);
2998 bool prev_in_rescue = ISEQ_COMPILE_DATA(iseq)->in_rescue;
2999 ISEQ_COMPILE_DATA(iseq)->in_rescue =
true;
3006 ISEQ_COMPILE_DATA(iseq)->in_rescue = prev_in_rescue;
3009 PM_POP_UNLESS_POPPED;
3013 ADD_LABEL(ret, lend);
3015 ADD_LABEL(ret, lcont);
3018 ADD_CATCH_ENTRY(CATCH_TYPE_RESCUE, lstart, lend, rescue_iseq, lcont);
3019 ADD_CATCH_ENTRY(CATCH_TYPE_RETRY, lend, lcont, NULL, lstart);
3022 LABEL *estart = NEW_LABEL(lineno);
3023 LABEL *eend = NEW_LABEL(lineno);
3024 LABEL *econt = NEW_LABEL(lineno);
3025 ADD_LABEL(ret, estart);
3031 PM_PUTNIL_UNLESS_POPPED;
3034 ADD_LABEL(ret, eend);
3041 ADD_LABEL(ret, econt);
3042 PM_POP_UNLESS_POPPED;
3052 push_ensure_entry(iseq, &enl, &er, (
void *)begin_node->
ensure_clause);
3057 child_iseq = NEW_CHILD_ISEQ(next_scope_node,
3059 ISEQ_TYPE_ENSURE, lineno);
3060 ISEQ_COMPILE_DATA(iseq)->current_block = child_iseq;
3063 erange = ISEQ_COMPILE_DATA(iseq)->ensure_node_stack->erange;
3064 if (estart->link.next != &eend->link) {
3066 ADD_CATCH_ENTRY(CATCH_TYPE_ENSURE, erange->begin, erange->end, child_iseq, econt);
3067 erange = erange->next;
3073 ADD_LABEL(ret, lstart);
3078 PM_PUTNIL_UNLESS_POPPED;
3080 ADD_LABEL(ret, lend);
3093 unsigned long throw_flag = 0;
3094 if (ISEQ_COMPILE_DATA(iseq)->redo_label != 0 && can_add_ensure_iseq(iseq)) {
3096 LABEL *splabel = NEW_LABEL(0);
3097 ADD_LABEL(ret, splabel);
3098 ADD_ADJUST(ret, &dummy_line_node, ISEQ_COMPILE_DATA(iseq)->redo_label);
3105 ADD_INSNL(ret, &dummy_line_node, jump, ISEQ_COMPILE_DATA(iseq)->end_label);
3106 ADD_ADJUST_RESTORE(ret, splabel);
3108 PM_PUTNIL_UNLESS_POPPED;
3113 if (!ISEQ_COMPILE_DATA(ip)) {
3118 if (ISEQ_COMPILE_DATA(ip)->redo_label != 0) {
3119 throw_flag = VM_THROW_NO_ESCAPE_FLAG;
3121 else if (ISEQ_BODY(ip)->
type == ISEQ_TYPE_BLOCK) {
3124 else if (ISEQ_BODY(ip)->
type == ISEQ_TYPE_EVAL) {
3125 COMPILE_ERROR(ERROR_ARGS
"Can't escape from eval with break");
3126 rb_bug(
"Can't escape from eval with break");
3129 ip = ISEQ_BODY(ip)->parent_iseq;
3141 ADD_INSN1(ret, &dummy_line_node,
throw,
INT2FIX(throw_flag | TAG_BREAK));
3146 COMPILE_ERROR(ERROR_ARGS
"Invalid break");
3147 rb_bug(
"Invalid break");
3153 LABEL *start = NEW_LABEL(lineno);
3155 if (call_node->
block) {
3156 ADD_LABEL(ret, start);
3159 ID method_id = pm_constant_id_lookup(scope_node, call_node->
name);
3169 PM_COMPILE_NOT_POPPED(call_node->
receiver);
3172 pm_compile_call(iseq, call_node, ret, src, popped, scope_node, method_id, start);
3180 pm_compile_call_and_or_write_node(
true, call_and_write_node->
receiver, call_and_write_node->
value, call_and_write_node->
write_name, call_and_write_node->
read_name, safe_nav, ret, iseq, lineno, src, popped, scope_node);
3188 pm_compile_call_and_or_write_node(
false, call_or_write_node->
receiver, call_or_write_node->
value, call_or_write_node->
write_name, call_or_write_node->
read_name, safe_nav, ret, iseq, lineno, src, popped, scope_node);
3195 NODE dummy_line_node = generate_dummy_line_node(lineno, lineno);
3200 flag = VM_CALL_FCALL;
3203 PM_COMPILE_NOT_POPPED(call_operator_write_node->
receiver);
3205 ID write_name_id = pm_constant_id_lookup(scope_node, call_operator_write_node->
write_name);
3206 ID read_name_id = pm_constant_id_lookup(scope_node, call_operator_write_node->
read_name);
3207 ID operator_id = pm_constant_id_lookup(scope_node, call_operator_write_node->
operator);
3210 ADD_SEND_WITH_FLAG(ret, &dummy_line_node, read_name_id,
INT2FIX(0),
INT2FIX(flag));
3212 PM_COMPILE_NOT_POPPED(call_operator_write_node->
value);
3213 ADD_SEND(ret, &dummy_line_node, operator_id,
INT2FIX(1));
3217 ADD_INSN1(ret, &dummy_line_node, topn,
INT2FIX(1));
3220 ADD_SEND_WITH_FLAG(ret, &dummy_line_node, write_name_id,
INT2FIX(1),
INT2FIX(flag));
3227 bool has_predicate = case_node->
predicate;
3228 if (has_predicate) {
3229 PM_COMPILE_NOT_POPPED(case_node->
predicate);
3231 LABEL *end_label = NEW_LABEL(lineno);
3238 for (
size_t i = 0; i < conditions.
size; i++) {
3239 label = NEW_LABEL(lineno);
3240 conditions_labels[i] = label;
3241 if (has_predicate) {
3244 for (
size_t i = 0; i < when_node->conditions.size; i++) {
3245 PM_COMPILE_NOT_POPPED(when_node->conditions.nodes[i]);
3246 ADD_INSN1(ret, &dummy_line_node, topn,
INT2FIX(1));
3247 ADD_SEND_WITH_FLAG(ret, &dummy_line_node, idEqq,
INT2NUM(1),
INT2FIX(VM_CALL_FCALL | VM_CALL_ARGS_SIMPLE));
3248 ADD_INSNL(ret, &dummy_line_node, branchif, label);
3252 ADD_INSNL(ret, &dummy_line_node, jump, label);
3257 if (has_predicate) {
3264 PM_PUTNIL_UNLESS_POPPED;
3268 ADD_INSNL(ret, &dummy_line_node, jump, end_label);
3270 for (
size_t i = 0; i < conditions.
size; i++) {
3271 label = conditions_labels[i];
3272 ADD_LABEL(ret, label);
3273 if (has_predicate) {
3278 if (condition_node->statements) {
3279 PM_COMPILE((
pm_node_t *)condition_node->statements);
3282 PM_PUTNIL_UNLESS_POPPED;
3285 ADD_INSNL(ret, &dummy_line_node, jump, end_label);
3288 ADD_LABEL(ret, end_label);
3302 DECL_ANCHOR(body_seq);
3303 INIT_ANCHOR(body_seq);
3308 DECL_ANCHOR(cond_seq);
3309 INIT_ANCHOR(cond_seq);
3313 LABEL *end_label = NEW_LABEL(lineno);
3318 LABEL *else_label = NEW_LABEL(lineno);
3332 if (in_single_pattern) {
3333 ADD_INSN(ret, &dummy_line_node, putnil);
3334 ADD_INSN(ret, &dummy_line_node, putnil);
3335 ADD_INSN1(ret, &dummy_line_node, putobject,
Qfalse);
3336 ADD_INSN(ret, &dummy_line_node, putnil);
3340 ADD_INSN(ret, &dummy_line_node, putnil);
3354 pm_line_node(&in_line, scope_node, (
const pm_node_t *) in_node);
3357 pm_line_node(&pattern_line, scope_node, (
const pm_node_t *) in_node->
pattern);
3360 ADD_INSN(body_seq, &in_line.node, putnil);
3363 LABEL *body_label = NEW_LABEL(in_line.lineno);
3364 ADD_LABEL(body_seq, body_label);
3365 ADD_INSN1(body_seq, &in_line.node, adjuststack,
INT2FIX(in_single_pattern ? 6 : 2));
3375 }
else if (!popped) {
3376 ADD_INSN(body_seq, &in_line.node, putnil);
3379 ADD_INSNL(body_seq, &in_line.node, jump, end_label);
3380 LABEL *next_pattern_label = NEW_LABEL(pattern_line.lineno);
3382 ADD_INSN(cond_seq, &pattern_line.node, dup);
3383 pm_compile_pattern(iseq, scope_node, in_node->
pattern, cond_seq, src, body_label, next_pattern_label, in_single_pattern,
false,
true, 2);
3384 ADD_LABEL(cond_seq, next_pattern_label);
3385 LABEL_UNREMOVABLE(next_pattern_label);
3394 ADD_LABEL(cond_seq, else_label);
3395 ADD_INSN(cond_seq, &dummy_line_node, pop);
3396 ADD_INSN(cond_seq, &dummy_line_node, pop);
3401 if (else_node->statements != NULL) {
3402 PM_COMPILE_INTO_ANCHOR(cond_seq, (
const pm_node_t *) else_node->statements);
3403 }
else if (!popped) {
3404 ADD_INSN(cond_seq, &dummy_line_node, putnil);
3407 ADD_INSNL(cond_seq, &dummy_line_node, jump, end_label);
3408 ADD_INSN(cond_seq, &dummy_line_node, putnil);
3410 ADD_INSN(cond_seq, &dummy_line_node, putnil);
3415 ADD_LABEL(cond_seq, else_label);
3420 if (in_single_pattern) {
3421 pm_compile_pattern_error_handler(iseq, scope_node, node, cond_seq, src, end_label, popped);
3423 ADD_INSN1(cond_seq, &dummy_line_node, putspecialobject,
INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
3425 ADD_INSN1(cond_seq, &dummy_line_node, topn,
INT2FIX(2));
3426 ADD_SEND(cond_seq, &dummy_line_node, id_core_raise,
INT2FIX(2));
3428 ADD_INSN1(cond_seq, &dummy_line_node, adjuststack,
INT2FIX(3));
3429 if (!popped) ADD_INSN(cond_seq, &dummy_line_node, putnil);
3430 ADD_INSNL(cond_seq, &dummy_line_node, jump, end_label);
3431 ADD_INSN1(cond_seq, &dummy_line_node, dupn,
INT2FIX(1));
3432 if (popped) ADD_INSN(cond_seq, &dummy_line_node, putnil);
3439 ADD_SEQ(ret, cond_seq);
3440 ADD_SEQ(ret, body_seq);
3441 ADD_LABEL(ret, end_label);
3448 pm_scope_node_init((
pm_node_t *)class_node, &next_scope_node, scope_node, parser);
3450 ID class_id = pm_constant_id_lookup(scope_node, class_node->
name);
3452 VALUE class_name =
rb_str_freeze(rb_sprintf(
"<class:%"PRIsVALUE
">", rb_id2str(class_id)));
3454 const rb_iseq_t *class_iseq = NEW_CHILD_ISEQ(next_scope_node, class_name, ISEQ_TYPE_CLASS, lineno);
3457 const int flags = VM_DEFINECLASS_TYPE_CLASS |
3458 (class_node->
superclass ? VM_DEFINECLASS_FLAG_HAS_SUPERCLASS : 0) |
3459 pm_compile_class_path(ret, iseq, class_node->
constant_path, &dummy_line_node, src,
false, scope_node);
3462 PM_COMPILE_NOT_POPPED(class_node->
superclass);
3468 ADD_INSN3(ret, &dummy_line_node, defineclass,
ID2SYM(class_id), class_iseq,
INT2FIX(flags));
3477 LABEL *end_label = NEW_LABEL(lineno);
3479 ID class_variable_name_id = pm_constant_id_lookup(scope_node, class_variable_and_write_node->
name);
3480 VALUE class_variable_name_val =
ID2SYM(class_variable_name_id);
3482 ADD_INSN2(ret, &dummy_line_node, getclassvariable,
3483 class_variable_name_val,
3484 get_cvar_ic_value(iseq, class_variable_name_id));
3486 PM_DUP_UNLESS_POPPED;
3488 ADD_INSNL(ret, &dummy_line_node, branchunless, end_label);
3490 PM_POP_UNLESS_POPPED;
3492 PM_COMPILE_NOT_POPPED(class_variable_and_write_node->
value);
3494 PM_DUP_UNLESS_POPPED;
3496 ADD_INSN2(ret, &dummy_line_node, setclassvariable,
3497 class_variable_name_val,
3498 get_cvar_ic_value(iseq, class_variable_name_id));
3499 ADD_LABEL(ret, end_label);
3506 ID class_variable_name_id = pm_constant_id_lookup(scope_node, class_variable_operator_write_node->
name);
3507 VALUE class_variable_name_val =
ID2SYM(class_variable_name_id);
3509 ADD_INSN2(ret, &dummy_line_node, getclassvariable,
3510 class_variable_name_val,
3511 get_cvar_ic_value(iseq, class_variable_name_id));
3513 PM_COMPILE_NOT_POPPED(class_variable_operator_write_node->
value);
3514 ID method_id = pm_constant_id_lookup(scope_node, class_variable_operator_write_node->
operator);
3516 int flags = VM_CALL_ARGS_SIMPLE;
3517 ADD_SEND_WITH_FLAG(ret, &dummy_line_node, method_id,
INT2NUM(1),
INT2FIX(flags));
3519 PM_DUP_UNLESS_POPPED;
3521 ADD_INSN2(ret, &dummy_line_node, setclassvariable,
3522 class_variable_name_val,
3523 get_cvar_ic_value(iseq, class_variable_name_id));
3530 LABEL *end_label = NEW_LABEL(lineno);
3531 LABEL *start_label = NEW_LABEL(lineno);
3533 ADD_INSN(ret, &dummy_line_node, putnil);
3534 ADD_INSN3(ret, &dummy_line_node, defined,
INT2FIX(DEFINED_CVAR),
3535 ID2SYM(pm_constant_id_lookup(scope_node, class_variable_or_write_node->
name)),
Qtrue);
3537 ADD_INSNL(ret, &dummy_line_node, branchunless, start_label);
3539 ID class_variable_name_id = pm_constant_id_lookup(scope_node, class_variable_or_write_node->
name);
3540 VALUE class_variable_name_val =
ID2SYM(class_variable_name_id);
3542 ADD_INSN2(ret, &dummy_line_node, getclassvariable,
3543 class_variable_name_val,
3544 get_cvar_ic_value(iseq, class_variable_name_id));
3546 PM_DUP_UNLESS_POPPED;
3548 ADD_INSNL(ret, &dummy_line_node, branchif, end_label);
3550 PM_POP_UNLESS_POPPED;
3551 ADD_LABEL(ret, start_label);
3553 PM_COMPILE_NOT_POPPED(class_variable_or_write_node->
value);
3555 PM_DUP_UNLESS_POPPED;
3557 ADD_INSN2(ret, &dummy_line_node, setclassvariable,
3558 class_variable_name_val,
3559 get_cvar_ic_value(iseq, class_variable_name_id));
3560 ADD_LABEL(ret, end_label);
3567 ID cvar_name = pm_constant_id_lookup(scope_node, class_variable_read_node->
name);
3568 ADD_INSN2(ret, &dummy_line_node, getclassvariable,
ID2SYM(cvar_name), get_cvar_ic_value(iseq, cvar_name));
3574 ID cvar_name = pm_constant_id_lookup(scope_node, write_node->
name);
3575 ADD_INSN2(ret, &dummy_line_node, setclassvariable,
ID2SYM(cvar_name), get_cvar_ic_value(iseq, cvar_name));
3580 PM_COMPILE_NOT_POPPED(write_node->
value);
3581 PM_DUP_UNLESS_POPPED;
3583 ID cvar_name = pm_constant_id_lookup(scope_node, write_node->
name);
3584 ADD_INSN2(ret, &dummy_line_node, setclassvariable,
ID2SYM(cvar_name), get_cvar_ic_value(iseq, cvar_name));
3589 if (constant_path_node->
parent) {
3590 PM_COMPILE_NOT_POPPED(constant_path_node->
parent);
3592 ADD_INSN1(ret, &dummy_line_node, putobject, rb_cObject);
3594 ADD_INSN1(ret, &dummy_line_node, putobject,
Qfalse);
3599 ADD_INSN1(ret, &dummy_line_node, getconstant,
ID2SYM(pm_constant_id_lookup(scope_node, child->name)));
3606 LABEL *lfin = NEW_LABEL(lineno);
3610 PM_COMPILE_NOT_POPPED(target->
parent);
3613 ADD_INSN1(ret, &dummy_line_node, putobject, rb_cObject);
3617 VALUE child_name =
ID2SYM(pm_constant_id_lookup(scope_node, child->name));
3620 ADD_INSN1(ret, &dummy_line_node, putobject,
Qtrue);
3621 ADD_INSN1(ret, &dummy_line_node, getconstant, child_name);
3623 PM_DUP_UNLESS_POPPED;
3624 ADD_INSNL(ret, &dummy_line_node, branchunless, lfin);
3626 PM_POP_UNLESS_POPPED;
3627 PM_COMPILE_NOT_POPPED(constant_path_and_write_node->
value);
3630 ADD_INSN1(ret, &dummy_line_node, topn,
INT2FIX(1));
3633 ADD_INSN1(ret, &dummy_line_node, dupn,
INT2FIX(2));
3637 ADD_INSN1(ret, &dummy_line_node, setconstant, child_name);
3638 ADD_LABEL(ret, lfin);
3640 PM_SWAP_UNLESS_POPPED;
3648 LABEL *lassign = NEW_LABEL(lineno);
3649 LABEL *lfin = NEW_LABEL(lineno);
3653 PM_COMPILE_NOT_POPPED(target->
parent);
3656 ADD_INSN1(ret, &dummy_line_node, putobject, rb_cObject);
3660 VALUE child_name =
ID2SYM(pm_constant_id_lookup(scope_node, child->name));
3663 ADD_INSN3(ret, &dummy_line_node, defined,
INT2FIX(DEFINED_CONST_FROM), child_name,
Qtrue);
3664 ADD_INSNL(ret, &dummy_line_node, branchunless, lassign);
3667 ADD_INSN1(ret, &dummy_line_node, putobject,
Qtrue);
3668 ADD_INSN1(ret, &dummy_line_node, getconstant, child_name);
3670 PM_DUP_UNLESS_POPPED;
3671 ADD_INSNL(ret, &dummy_line_node, branchif, lfin);
3673 PM_POP_UNLESS_POPPED;
3674 ADD_LABEL(ret, lassign);
3675 PM_COMPILE_NOT_POPPED(constant_path_or_write_node->
value);
3678 ADD_INSN1(ret, &dummy_line_node, topn,
INT2FIX(1));
3681 ADD_INSN1(ret, &dummy_line_node, dupn,
INT2FIX(2));
3685 ADD_INSN1(ret, &dummy_line_node, setconstant, child_name);
3686 ADD_LABEL(ret, lfin);
3688 PM_SWAP_UNLESS_POPPED;
3698 PM_COMPILE_NOT_POPPED(target->
parent);
3701 ADD_INSN1(ret, &dummy_line_node, putobject, rb_cObject);
3705 ADD_INSN1(ret, &dummy_line_node, putobject,
Qtrue);
3708 VALUE child_name =
ID2SYM(pm_constant_id_lookup(scope_node, child->name));
3709 ADD_INSN1(ret, &dummy_line_node, getconstant, child_name);
3711 PM_COMPILE_NOT_POPPED(constant_path_operator_write_node->
value);
3712 ID method_id = pm_constant_id_lookup(scope_node, constant_path_operator_write_node->
operator);
3713 ADD_CALL(ret, &dummy_line_node, method_id,
INT2FIX(1));
3717 ADD_INSN1(ret, &dummy_line_node, topn,
INT2FIX(1));
3721 ADD_INSN1(ret, &dummy_line_node, setconstant, child_name);
3728 PM_COMPILE(cast->
parent);
3739 ADD_INSN1(ret, &dummy_line_node, putobject, rb_cObject);
3741 PM_COMPILE_NOT_POPPED(constant_path_write_node->
value);
3744 ADD_INSN1(ret, &dummy_line_node, topn,
INT2FIX(1));
3747 VALUE constant_name =
ID2SYM(pm_constant_id_lookup(scope_node,
3749 ADD_INSN1(ret, &dummy_line_node, setconstant, constant_name);
3755 ADD_INSN1(ret, &dummy_line_node, putobject,
Qtrue);
3756 ADD_INSN1(ret, &dummy_line_node, getconstant,
ID2SYM(pm_constant_id_lookup(scope_node, constant_read_node->
name)));
3763 LABEL *end_label = NEW_LABEL(lineno);
3765 VALUE constant_name =
ID2SYM(pm_constant_id_lookup(scope_node, constant_and_write_node->
name));
3768 ADD_INSN1(ret, &dummy_line_node, putobject,
Qtrue);
3769 ADD_INSN1(ret, &dummy_line_node, getconstant, constant_name);
3770 PM_DUP_UNLESS_POPPED;
3772 ADD_INSNL(ret, &dummy_line_node, branchunless, end_label);
3774 PM_POP_UNLESS_POPPED;
3776 PM_COMPILE_NOT_POPPED(constant_and_write_node->
value);
3778 PM_DUP_UNLESS_POPPED;
3780 ADD_INSN1(ret, &dummy_line_node, putspecialobject,
INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE));
3781 ADD_INSN1(ret, &dummy_line_node, setconstant, constant_name);
3782 ADD_LABEL(ret, end_label);
3789 ID constant_name = pm_constant_id_lookup(scope_node, constant_operator_write_node->
name);
3791 ADD_INSN1(ret, &dummy_line_node, putobject,
Qtrue);
3792 ADD_INSN1(ret, &dummy_line_node, getconstant,
ID2SYM(constant_name));
3794 PM_COMPILE_NOT_POPPED(constant_operator_write_node->
value);
3795 ID method_id = pm_constant_id_lookup(scope_node, constant_operator_write_node->
operator);
3797 int flags = VM_CALL_ARGS_SIMPLE;
3798 ADD_SEND_WITH_FLAG(ret, &dummy_line_node, method_id,
INT2NUM(1),
INT2FIX(flags));
3800 PM_DUP_UNLESS_POPPED;
3802 ADD_INSN1(ret, &dummy_line_node, putspecialobject,
INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE));
3803 ADD_INSN1(ret, &dummy_line_node, setconstant,
ID2SYM(constant_name));
3810 LABEL *set_label= NEW_LABEL(lineno);
3811 LABEL *end_label = NEW_LABEL(lineno);
3814 VALUE constant_name =
ID2SYM(pm_constant_id_lookup(scope_node, constant_or_write_node->
name));
3816 ADD_INSN3(ret, &dummy_line_node, defined,
INT2FIX(DEFINED_CONST), constant_name,
Qtrue);
3818 ADD_INSNL(ret, &dummy_line_node, branchunless, set_label);
3821 ADD_INSN1(ret, &dummy_line_node, putobject,
Qtrue);
3822 ADD_INSN1(ret, &dummy_line_node, getconstant, constant_name);
3824 PM_DUP_UNLESS_POPPED;
3826 ADD_INSNL(ret, &dummy_line_node, branchif, end_label);
3828 PM_POP_UNLESS_POPPED;
3830 ADD_LABEL(ret, set_label);
3831 PM_COMPILE_NOT_POPPED(constant_or_write_node->
value);
3833 PM_DUP_UNLESS_POPPED;
3835 ADD_INSN1(ret, &dummy_line_node, putspecialobject,
INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE));
3836 ADD_INSN1(ret, &dummy_line_node, setconstant, constant_name);
3837 ADD_LABEL(ret, end_label);
3843 ADD_INSN1(ret, &dummy_line_node, putspecialobject,
INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE));
3844 ADD_INSN1(ret, &dummy_line_node, setconstant,
ID2SYM(pm_constant_id_lookup(scope_node, constant_write_node->
name)));
3849 PM_COMPILE_NOT_POPPED(constant_write_node->
value);
3851 PM_DUP_UNLESS_POPPED;
3853 ADD_INSN1(ret, &dummy_line_node, putspecialobject,
INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE));
3854 ADD_INSN1(ret, &dummy_line_node, setconstant,
ID2SYM(pm_constant_id_lookup(scope_node, constant_write_node->
name)));
3859 ID method_name = pm_constant_id_lookup(scope_node, def_node->
name);
3861 pm_scope_node_init((
pm_node_t *)def_node, &next_scope_node, scope_node, parser);
3862 rb_iseq_t *method_iseq = NEW_ISEQ(next_scope_node, rb_id2str(method_name), ISEQ_TYPE_METHOD, lineno);
3865 PM_COMPILE_NOT_POPPED(def_node->
receiver);
3866 ADD_INSN2(ret, &dummy_line_node, definesmethod,
ID2SYM(method_name), method_iseq);
3869 ADD_INSN2(ret, &dummy_line_node, definemethod,
ID2SYM(method_name), method_iseq);
3874 ADD_INSN1(ret, &dummy_line_node, putobject,
ID2SYM(method_name));
3880 pm_compile_defined_expr(iseq, defined_node->
value, ret, src, popped, scope_node, dummy_line_node, lineno,
false);
3899 PM_COMPILE(embedded_node->
variable);
3904 ADD_INSN1(ret, &dummy_line_node, putobject,
Qfalse);
3910 LABEL *start = NEW_LABEL(lineno);
3911 LABEL *end = NEW_LABEL(lineno);
3912 ADD_LABEL(ret, start);
3914 ISEQ_COMPILE_DATA(iseq)->end_label = end;
3917 ADD_LABEL(ret, end);
3925 PM_PUTNIL_UNLESS_POPPED;
3932 LABEL *final_label = NEW_LABEL(lineno);
3933 LABEL *then_label = NEW_LABEL(lineno);
3934 LABEL *else_label = NEW_LABEL(lineno);
3936 pm_compile_flip_flop(flip_flop_node, else_label, then_label, iseq, lineno, ret, src, popped, scope_node);
3938 ADD_LABEL(ret, then_label);
3939 ADD_INSN1(ret, &dummy_line_node, putobject,
Qtrue);
3940 ADD_INSNL(ret, &dummy_line_node, jump, final_label);
3941 ADD_LABEL(ret, else_label);
3942 ADD_INSN1(ret, &dummy_line_node, putobject,
Qfalse);
3943 ADD_LABEL(ret, final_label);
3948 ADD_INSN1(ret, &dummy_line_node, putobject, parse_float(node));
3955 ISEQ_COMPILE_DATA(iseq)->catch_except_p =
true;
3958 const rb_iseq_t *prevblock = ISEQ_COMPILE_DATA(iseq)->current_block;
3960 LABEL *retry_label = NEW_LABEL(lineno);
3961 LABEL *retry_end_l = NEW_LABEL(lineno);
3964 pm_scope_node_init((
pm_node_t *)for_node, &next_scope_node, scope_node, parser);
3967 pm_constant_id_list_init(&locals);
3969 ADD_LABEL(ret, retry_label);
3973 child_iseq = NEW_CHILD_ISEQ(next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, lineno);
3974 ISEQ_COMPILE_DATA(iseq)->current_block = child_iseq;
3975 ADD_SEND_WITH_BLOCK(ret, &dummy_line_node, idEach,
INT2FIX(0), child_iseq);
3977 ADD_LABEL(ret, retry_end_l);
3980 ISEQ_COMPILE_DATA(iseq)->current_block = prevblock;
3981 ADD_CATCH_ENTRY(CATCH_TYPE_BREAK, retry_label, retry_end_l, child_iseq, retry_end_l);
3985 rb_bug(
"Should never hit the forwarding arguments case directly\n");
3992 int flag = VM_CALL_ZSUPER | VM_CALL_SUPER | VM_CALL_FCALL;
3994 if (forwarding_super_node->
block) {
3996 pm_scope_node_init((
pm_node_t *)forwarding_super_node->
block, &next_scope_node, scope_node, parser);
3997 block = NEW_CHILD_ISEQ(next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, lineno);
4006 const rb_iseq_t *local_iseq = body->local_iseq;
4010 int depth = get_lvar_level(iseq);
4012 if (local_body->
param.flags.has_lead) {
4014 for (
int i = 0; i < local_body->
param.lead_num; i++) {
4015 int idx = local_body->local_table_size - i;
4016 ADD_GETLOCAL(args, &dummy_line_node, idx, depth);
4018 argc += local_body->
param.lead_num;
4022 if (local_body->
param.flags.has_opt) {
4024 for (
int j = 0; j < local_body->
param.opt_num; j++) {
4025 int idx = local_body->local_table_size - (argc + j);
4026 ADD_GETLOCAL(args, &dummy_line_node, idx, depth);
4028 argc += local_body->
param.opt_num;
4031 if (local_body->
param.flags.has_rest) {
4033 int idx = local_body->local_table_size - local_body->
param.rest_start;
4034 ADD_GETLOCAL(args, &dummy_line_node, idx, depth);
4035 ADD_INSN1(args, &dummy_line_node, splatarray,
Qfalse);
4037 argc = local_body->
param.rest_start + 1;
4038 flag |= VM_CALL_ARGS_SPLAT;
4041 if (local_body->
param.flags.has_post) {
4043 int post_len = local_body->
param.post_num;
4044 int post_start = local_body->
param.post_start;
4047 for (; j < post_len; j++) {
4048 int idx = local_body->local_table_size - (post_start + j);
4049 ADD_GETLOCAL(args, &dummy_line_node, idx, depth);
4052 if (local_body->
param.flags.has_rest) {
4054 ADD_INSN1(args, &dummy_line_node, newarray,
INT2FIX(j));
4055 ADD_INSN (args, &dummy_line_node, concatarray);
4058 argc = post_len + post_start;
4062 const struct rb_iseq_param_keyword *
const local_keyword = local_body->
param.keyword;
4063 if (local_body->
param.flags.has_kw) {
4064 int local_size = local_body->local_table_size;
4067 ADD_INSN1(args, &dummy_line_node, putspecialobject,
INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
4069 if (local_body->
param.flags.has_kwrest) {
4070 int idx = local_body->local_table_size - local_keyword->rest_start;
4071 ADD_GETLOCAL(args, &dummy_line_node, idx, depth);
4072 if (local_keyword->num > 0) {
4073 ADD_SEND(args, &dummy_line_node, rb_intern(
"dup"),
INT2FIX(0));
4074 flag |= VM_CALL_KW_SPLAT_MUT;
4078 ADD_INSN1(args, &dummy_line_node, newhash,
INT2FIX(0));
4079 flag |= VM_CALL_KW_SPLAT_MUT;
4082 for (; i < local_keyword->num; ++i) {
4083 ID id = local_keyword->table[i];
4084 int idx = local_size - get_local_var_idx(local_iseq,
id);
4085 ADD_INSN1(args, &dummy_line_node, putobject,
ID2SYM(
id));
4086 ADD_GETLOCAL(args, &dummy_line_node, idx, depth);
4088 ADD_SEND(args, &dummy_line_node, id_core_hash_merge_ptr,
INT2FIX(i * 2 + 1));
4089 flag |= VM_CALL_KW_SPLAT;
4091 else if (local_body->
param.flags.has_kwrest) {
4092 int idx = local_body->local_table_size - local_keyword->rest_start;
4093 ADD_GETLOCAL(args, &dummy_line_node, idx, depth);
4095 flag |= VM_CALL_KW_SPLAT | VM_CALL_KW_SPLAT_MUT;
4099 ADD_INSN2(ret, &dummy_line_node, invokesuper, new_callinfo(iseq, 0, argc, flag, NULL, block != NULL), block);
4106 LABEL *end_label = NEW_LABEL(lineno);
4108 VALUE global_variable_name =
ID2SYM(pm_constant_id_lookup(scope_node, global_variable_and_write_node->
name));
4110 ADD_INSN1(ret, &dummy_line_node, getglobal, global_variable_name);
4112 PM_DUP_UNLESS_POPPED;
4114 ADD_INSNL(ret, &dummy_line_node, branchunless, end_label);
4116 PM_POP_UNLESS_POPPED;
4118 PM_COMPILE_NOT_POPPED(global_variable_and_write_node->
value);
4120 PM_DUP_UNLESS_POPPED;
4122 ADD_INSN1(ret, &dummy_line_node, setglobal, global_variable_name);
4123 ADD_LABEL(ret, end_label);
4130 VALUE global_variable_name =
ID2SYM(pm_constant_id_lookup(scope_node, global_variable_operator_write_node->
name));
4131 ADD_INSN1(ret, &dummy_line_node, getglobal, global_variable_name);
4133 PM_COMPILE_NOT_POPPED(global_variable_operator_write_node->
value);
4134 ID method_id = pm_constant_id_lookup(scope_node, global_variable_operator_write_node->
operator);
4136 int flags = VM_CALL_ARGS_SIMPLE;
4137 ADD_SEND_WITH_FLAG(ret, &dummy_line_node, method_id,
INT2NUM(1),
INT2FIX(flags));
4139 PM_DUP_UNLESS_POPPED;
4141 ADD_INSN1(ret, &dummy_line_node, setglobal, global_variable_name);
4148 LABEL *set_label= NEW_LABEL(lineno);
4149 LABEL *end_label = NEW_LABEL(lineno);
4152 VALUE global_variable_name =
ID2SYM(pm_constant_id_lookup(scope_node, global_variable_or_write_node->
name));
4154 ADD_INSN3(ret, &dummy_line_node, defined,
INT2FIX(DEFINED_GVAR), global_variable_name,
Qtrue);
4156 ADD_INSNL(ret, &dummy_line_node, branchunless, set_label);
4158 ADD_INSN1(ret, &dummy_line_node, getglobal, global_variable_name);
4160 PM_DUP_UNLESS_POPPED;
4162 ADD_INSNL(ret, &dummy_line_node, branchif, end_label);
4164 PM_POP_UNLESS_POPPED;
4166 ADD_LABEL(ret, set_label);
4167 PM_COMPILE_NOT_POPPED(global_variable_or_write_node->
value);
4169 PM_DUP_UNLESS_POPPED;
4171 ADD_INSN1(ret, &dummy_line_node, setglobal, global_variable_name);
4172 ADD_LABEL(ret, end_label);
4178 VALUE global_variable_name =
ID2SYM(pm_constant_id_lookup(scope_node, global_variable_read_node->
name));
4179 ADD_INSN1(ret, &dummy_line_node, getglobal, global_variable_name);
4186 ID ivar_name = pm_constant_id_lookup(scope_node, write_node->
name);
4187 ADD_INSN1(ret, &dummy_line_node, setglobal,
ID2SYM(ivar_name));
4192 PM_COMPILE_NOT_POPPED(write_node->
value);
4193 PM_DUP_UNLESS_POPPED;
4194 ID ivar_name = pm_constant_id_lookup(scope_node, write_node->
name);
4195 ADD_INSN1(ret, &dummy_line_node, setglobal,
ID2SYM(ivar_name));
4201 if (pm_static_literal_p(node)) {
4206 VALUE value = pm_static_literal_value(node, scope_node, parser);
4207 ADD_INSN1(ret, &dummy_line_node, duphash, value);
4225 int elements_of_cur_type = 0;
4226 int allocated_hashes = 0;
4229 ADD_INSN1(ret, &dummy_line_node, putspecialobject,
INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
4230 ADD_INSN1(ret, &dummy_line_node, newhash,
INT2FIX(0));
4234 for (
size_t index = 0; index < elements->
size; index++) {
4238 if (!allocated_hashes) {
4239 ADD_INSN1(ret, &dummy_line_node, newhash,
INT2FIX(elements_of_cur_type * 2));
4243 ADD_SEND(ret, &dummy_line_node, id_core_hash_merge_ptr,
INT2FIX(3));
4246 ADD_SEND(ret, &dummy_line_node, id_core_hash_merge_kwd,
INT2FIX(2));
4250 ADD_INSN1(ret, &dummy_line_node, putspecialobject,
INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
4252 PM_COMPILE(elements->
nodes[index]);
4255 elements_of_cur_type = 0;
4259 elements_of_cur_type++;
4260 PM_COMPILE(elements->
nodes[index]);
4264 PM_COMPILE(elements->
nodes[index]);
4269 if (!allocated_hashes) {
4270 ADD_INSN1(ret, &dummy_line_node, newhash,
INT2FIX(elements_of_cur_type * 2));
4274 ADD_SEND(ret, &dummy_line_node, id_core_hash_merge_ptr,
INT2FIX(3));
4277 ADD_SEND(ret, &dummy_line_node, id_core_hash_merge_kwd,
INT2FIX(2));
4292 pm_compile_if(iseq, line, node_body, node_else, predicate, ret, src, popped, scope_node);
4297 ADD_INSN1(ret, &dummy_line_node, putobject, parse_imaginary((
pm_imaginary_node_t *)node));
4311 PM_COMPILE(cast->
value);
4317 rb_bug(
"Should not ever enter an in node directly");
4323 pm_compile_index_and_or_write_node(
true, index_and_write_node->
receiver, index_and_write_node->
value, index_and_write_node->
arguments, index_and_write_node->
block, ret, iseq, lineno, src, popped, scope_node, parser);
4329 pm_compile_index_and_or_write_node(
false, index_or_write_node->
receiver, index_or_write_node->
value, index_or_write_node->
arguments, index_or_write_node->
block, ret, iseq, lineno, src, popped, scope_node, parser);
4335 PM_PUTNIL_UNLESS_POPPED;
4337 PM_COMPILE_NOT_POPPED(index_operator_write_node->
receiver);
4343 if (index_operator_write_node->
arguments) {
4344 argc_int = pm_setup_args(index_operator_write_node->
arguments, &flag, &keywords, iseq, ret, src, popped, scope_node, dummy_line_node, parser);
4349 int block_offset = 0;
4351 if (index_operator_write_node->
block) {
4352 PM_COMPILE_NOT_POPPED(index_operator_write_node->
block);
4353 flag |= VM_CALL_ARGS_BLOCKARG;
4357 ADD_INSN1(ret, &dummy_line_node, dupn, FIXNUM_INC(argc, 1 + block_offset));
4359 ADD_SEND_WITH_FLAG(ret, &dummy_line_node, idAREF, argc,
INT2FIX(flag));
4361 PM_COMPILE_NOT_POPPED(index_operator_write_node->
value);
4363 ID method_id = pm_constant_id_lookup(scope_node, index_operator_write_node->
operator);
4364 ADD_SEND(ret, &dummy_line_node, method_id,
INT2FIX(1));
4366 pm_compile_index_write_nodes_add_send(popped, ret, iseq, dummy_line_node, argc, flag, block_offset);
4373 LABEL *end_label = NEW_LABEL(lineno);
4374 ID instance_variable_name_id = pm_constant_id_lookup(scope_node, instance_variable_and_write_node->
name);
4375 VALUE instance_variable_name_val =
ID2SYM(instance_variable_name_id);
4377 ADD_INSN2(ret, &dummy_line_node, getinstancevariable, instance_variable_name_val, get_ivar_ic_value(iseq, instance_variable_name_id));
4378 PM_DUP_UNLESS_POPPED;
4380 ADD_INSNL(ret, &dummy_line_node, branchunless, end_label);
4381 PM_POP_UNLESS_POPPED;
4383 PM_COMPILE_NOT_POPPED(instance_variable_and_write_node->
value);
4384 PM_DUP_UNLESS_POPPED;
4386 ADD_INSN2(ret, &dummy_line_node, setinstancevariable, instance_variable_name_val, get_ivar_ic_value(iseq, instance_variable_name_id));
4387 ADD_LABEL(ret, end_label);
4394 ID instance_variable_name_id = pm_constant_id_lookup(scope_node, instance_variable_operator_write_node->
name);
4395 VALUE instance_variable_name_val =
ID2SYM(instance_variable_name_id);
4397 ADD_INSN2(ret, &dummy_line_node, getinstancevariable,
4398 instance_variable_name_val,
4399 get_ivar_ic_value(iseq, instance_variable_name_id));
4401 PM_COMPILE_NOT_POPPED(instance_variable_operator_write_node->
value);
4402 ID method_id = pm_constant_id_lookup(scope_node, instance_variable_operator_write_node->
operator);
4404 int flags = VM_CALL_ARGS_SIMPLE;
4405 ADD_SEND_WITH_FLAG(ret, &dummy_line_node, method_id,
INT2NUM(1),
INT2FIX(flags));
4407 PM_DUP_UNLESS_POPPED;
4409 ADD_INSN2(ret, &dummy_line_node, setinstancevariable,
4410 instance_variable_name_val,
4411 get_ivar_ic_value(iseq, instance_variable_name_id));
4418 LABEL *end_label = NEW_LABEL(lineno);
4420 ID instance_variable_name_id = pm_constant_id_lookup(scope_node, instance_variable_or_write_node->
name);
4421 VALUE instance_variable_name_val =
ID2SYM(instance_variable_name_id);
4423 ADD_INSN2(ret, &dummy_line_node, getinstancevariable, instance_variable_name_val, get_ivar_ic_value(iseq, instance_variable_name_id));
4424 PM_DUP_UNLESS_POPPED;
4426 ADD_INSNL(ret, &dummy_line_node, branchif, end_label);
4427 PM_POP_UNLESS_POPPED;
4429 PM_COMPILE_NOT_POPPED(instance_variable_or_write_node->
value);
4430 PM_DUP_UNLESS_POPPED;
4432 ADD_INSN2(ret, &dummy_line_node, setinstancevariable, instance_variable_name_val, get_ivar_ic_value(iseq, instance_variable_name_id));
4433 ADD_LABEL(ret, end_label);
4440 ID ivar_name = pm_constant_id_lookup(scope_node, instance_variable_read_node->
name);
4441 ADD_INSN2(ret, &dummy_line_node, getinstancevariable,
ID2SYM(ivar_name), get_ivar_ic_value(iseq, ivar_name));
4448 ID ivar_name = pm_constant_id_lookup(scope_node, write_node->
name);
4449 ADD_INSN2(ret, &dummy_line_node, setinstancevariable,
ID2SYM(ivar_name), get_ivar_ic_value(iseq, ivar_name));
4454 PM_COMPILE_NOT_POPPED(write_node->
value);
4456 PM_DUP_UNLESS_POPPED;
4458 ID ivar_name = pm_constant_id_lookup(scope_node, write_node->
name);
4459 ADD_INSN2(ret, &dummy_line_node, setinstancevariable,
4461 get_ivar_ic_value(iseq, ivar_name));
4466 ADD_INSN1(ret, &dummy_line_node, putobject, parse_integer((
pm_integer_node_t *) node));
4475 ADD_INSN1(ret, &dummy_line_node, putobject,
rb_str_new(0, 0));
4479 pm_interpolated_node_compile(&cast->parts, iseq, dummy_line_node, ret, src, popped, scope_node, parser);
4481 ADD_INSN2(ret, &dummy_line_node, toregexp,
INT2FIX(pm_reg_flags(node)),
INT2FIX(parts_size));
4483 ADD_INSN1(ret, &dummy_line_node, getglobal, rb_id2sym(idLASTLINE));
4484 ADD_SEND(ret, &dummy_line_node, idEqTilde,
INT2NUM(1));
4491 const rb_iseq_t *prevblock = ISEQ_COMPILE_DATA(iseq)->current_block;
4493 int ic_index = ISEQ_BODY(iseq)->ise_size++;
4496 pm_scope_node_init((
pm_node_t*)node, &next_scope_node, scope_node, parser);
4498 block_iseq = NEW_CHILD_ISEQ(next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, lineno);
4499 ISEQ_COMPILE_DATA(iseq)->current_block = block_iseq;
4501 ADD_INSN2(ret, &dummy_line_node, once, block_iseq,
INT2FIX(ic_index));
4503 ISEQ_COMPILE_DATA(iseq)->current_block = prevblock;
4511 ADD_INSN1(ret, &dummy_line_node, putobject,
rb_str_new(0, 0));
4515 pm_interpolated_node_compile(&cast->parts, iseq, dummy_line_node, ret, src, popped, scope_node, parser);
4517 ADD_INSN2(ret, &dummy_line_node, toregexp,
INT2FIX(pm_reg_flags(node)),
INT2FIX(parts_size));
4523 pm_interpolated_node_compile(&interp_string_node->
parts, iseq, dummy_line_node, ret, src, popped, scope_node, parser);
4525 size_t parts_size = interp_string_node->
parts.
size;
4526 if (parts_size > 1) {
4527 ADD_INSN1(ret, &dummy_line_node, concatstrings,
INT2FIX((
int)(parts_size)));
4535 pm_interpolated_node_compile(&interp_symbol_node->
parts, iseq, dummy_line_node, ret, src, popped, scope_node, parser);
4537 size_t parts_size = interp_symbol_node->
parts.
size;
4538 if (parts_size > 1) {
4539 ADD_INSN1(ret, &dummy_line_node, concatstrings,
INT2FIX((
int)(parts_size)));
4543 ADD_INSN(ret, &dummy_line_node, intern);
4554 pm_interpolated_node_compile(&interp_x_string_node->
parts, iseq, dummy_line_node, ret, src,
false, scope_node, parser);
4556 size_t parts_size = interp_x_string_node->
parts.
size;
4557 if (parts_size > 1) {
4558 ADD_INSN1(ret, &dummy_line_node, concatstrings,
INT2FIX((
int)(parts_size)));
4561 ADD_SEND_WITH_FLAG(ret, &dummy_line_node, idBackquote,
INT2NUM(1),
INT2FIX(VM_CALL_FCALL | VM_CALL_ARGS_SIMPLE));
4569 for (
size_t index = 0; index < elements.
size; index++) {
4570 PM_COMPILE(elements.
nodes[index]);
4574 ADD_INSN1(ret, &dummy_line_node, newhash,
INT2FIX(elements.
size * 2));
4580 pm_scope_node_init(node, &next_scope_node, scope_node, parser);
4582 const rb_iseq_t *block = NEW_CHILD_ISEQ(next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, lineno);
4585 ADD_INSN1(ret, &dummy_line_node, putspecialobject,
INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
4586 ADD_CALL_WITH_BLOCK(ret, &dummy_line_node, idLambda, argc, block);
4595 LABEL *end_label = NEW_LABEL(lineno);
4598 int depth = local_variable_and_write_node->
depth + scope_node->local_depth_offset;
4599 int local_index = pm_lookup_local_index_with_depth(iseq, scope_node, constant_id, depth);
4600 ADD_GETLOCAL(ret, &dummy_line_node, local_index, depth);
4602 PM_DUP_UNLESS_POPPED;
4604 ADD_INSNL(ret, &dummy_line_node, branchunless, end_label);
4606 PM_POP_UNLESS_POPPED;
4608 PM_COMPILE_NOT_POPPED(local_variable_and_write_node->
value);
4610 PM_DUP_UNLESS_POPPED;
4612 ADD_SETLOCAL(ret, &dummy_line_node, local_index, depth);
4613 ADD_LABEL(ret, end_label);
4622 int depth = local_variable_operator_write_node->
depth + scope_node->local_depth_offset;
4623 int local_index = pm_lookup_local_index_with_depth(iseq, scope_node, constant_id, depth);
4624 ADD_GETLOCAL(ret, &dummy_line_node, local_index, depth);
4626 PM_COMPILE_NOT_POPPED(local_variable_operator_write_node->
value);
4627 ID method_id = pm_constant_id_lookup(scope_node, local_variable_operator_write_node->
operator);
4629 int flags = VM_CALL_ARGS_SIMPLE | VM_CALL_FCALL | VM_CALL_VCALL;
4630 ADD_SEND_WITH_FLAG(ret, &dummy_line_node, method_id,
INT2NUM(1),
INT2FIX(flags));
4632 PM_DUP_UNLESS_POPPED;
4634 ADD_SETLOCAL(ret, &dummy_line_node, local_index, depth);
4641 LABEL *set_label= NEW_LABEL(lineno);
4642 LABEL *end_label = NEW_LABEL(lineno);
4644 ADD_INSN1(ret, &dummy_line_node, putobject,
Qtrue);
4645 ADD_INSNL(ret, &dummy_line_node, branchunless, set_label);
4648 int depth = local_variable_or_write_node->
depth + scope_node->local_depth_offset;
4649 int local_index = pm_lookup_local_index_with_depth(iseq, scope_node, constant_id, depth);
4650 ADD_GETLOCAL(ret, &dummy_line_node, local_index, depth);
4652 PM_DUP_UNLESS_POPPED;
4654 ADD_INSNL(ret, &dummy_line_node, branchif, end_label);
4656 PM_POP_UNLESS_POPPED;
4658 ADD_LABEL(ret, set_label);
4659 PM_COMPILE_NOT_POPPED(local_variable_or_write_node->
value);
4661 PM_DUP_UNLESS_POPPED;
4663 ADD_SETLOCAL(ret, &dummy_line_node, local_index, depth);
4664 ADD_LABEL(ret, end_label);
4672 int index = pm_lookup_local_index_with_depth(iseq, scope_node, local_read_node->
name, local_read_node->
depth);
4673 ADD_GETLOCAL(ret, &dummy_line_node, index, local_read_node->
depth + scope_node->local_depth_offset);
4681 int index = pm_lookup_local_index_any_scope(iseq, scope_node, constant_id);
4683 ADD_SETLOCAL(ret, &dummy_line_node, index, local_write_node->
depth + scope_node->local_depth_offset);
4688 PM_COMPILE_NOT_POPPED(local_write_node->
value);
4690 PM_DUP_UNLESS_POPPED;
4694 int index = pm_lookup_local_index_any_scope(iseq, scope_node, constant_id);
4696 ADD_SETLOCAL(ret, &dummy_line_node, index, local_write_node->
depth + scope_node->local_depth_offset);
4704 VALUE regex =
rb_reg_new(RSTRING_PTR(regex_str), RSTRING_LEN(regex_str), pm_reg_flags(node));
4706 ADD_INSN1(ret, &dummy_line_node, putobject, regex);
4707 ADD_INSN2(ret, &dummy_line_node, getspecial,
INT2FIX(0),
INT2FIX(0));
4708 ADD_SEND(ret, &dummy_line_node, idEqTilde,
INT2NUM(1));
4721 PM_COMPILE_NOT_POPPED(cast->
value);
4726 LABEL *matched_label = NEW_LABEL(lineno);
4727 LABEL *unmatched_label = NEW_LABEL(lineno);
4728 LABEL *done_label = NEW_LABEL(lineno);
4729 pm_compile_pattern(iseq, scope_node, cast->
pattern, ret, src, matched_label, unmatched_label,
false,
false,
true, 2);
4733 ADD_LABEL(ret, unmatched_label);
4737 if (!popped) ADD_INSN1(ret, &dummy_line_node, putobject,
Qfalse);
4738 ADD_INSNL(ret, &dummy_line_node, jump, done_label);
4743 ADD_LABEL(ret, matched_label);
4744 ADD_INSN1(ret, &dummy_line_node, adjuststack,
INT2FIX(2));
4745 if (!popped) ADD_INSN1(ret, &dummy_line_node, putobject,
Qtrue);
4746 ADD_INSNL(ret, &dummy_line_node, jump, done_label);
4748 ADD_LABEL(ret, done_label);
4762 LABEL *matched_label = NEW_LABEL(lineno);
4763 LABEL *unmatched_label = NEW_LABEL(lineno);
4764 LABEL *done_label = NEW_LABEL(lineno);
4768 ADD_INSN(ret, &dummy_line_node, putnil);
4769 ADD_INSN(ret, &dummy_line_node, putnil);
4770 ADD_INSN1(ret, &dummy_line_node, putobject,
Qfalse);
4771 ADD_INSN(ret, &dummy_line_node, putnil);
4772 ADD_INSN(ret, &dummy_line_node, putnil);
4776 PM_COMPILE_NOT_POPPED(cast->
value);
4780 ADD_INSN(ret, &dummy_line_node, dup);
4787 pm_compile_pattern(iseq, scope_node, cast->
pattern, ret, src, matched_label, unmatched_label,
true,
false,
true, 2);
4792 ADD_LABEL(ret, unmatched_label);
4793 pm_compile_pattern_error_handler(iseq, scope_node, node, ret, src, done_label, popped);
4797 ADD_LABEL(ret, matched_label);
4798 ADD_INSN1(ret, &dummy_line_node, adjuststack,
INT2FIX(6));
4799 if (!popped) ADD_INSN(ret, &dummy_line_node, putnil);
4800 ADD_INSNL(ret, &dummy_line_node, jump, done_label);
4802 ADD_LABEL(ret, done_label);
4812 LABEL *fail_label = NEW_LABEL(lineno);
4813 LABEL *end_label = NEW_LABEL(lineno);
4822 ADD_INSN1(ret, &dummy_line_node, getglobal, rb_id2sym(idBACKREF));
4824 ADD_INSNL(ret, &dummy_line_node, branchunless, fail_label);
4830 if (targets_count == 1) {
4835 int index = pm_lookup_local_index(iseq, scope_node, local_target->
name);
4837 ADD_INSN1(ret, &dummy_line_node, putobject, rb_id2sym(pm_constant_id_lookup(scope_node, local_target->
name)));
4838 ADD_SEND(ret, &dummy_line_node, idAREF,
INT2FIX(1));
4839 ADD_LABEL(ret, fail_label);
4840 ADD_SETLOCAL(ret, &dummy_line_node, index, (
int) local_target->
depth);
4847 for (
size_t targets_index = 0; targets_index < targets_count; targets_index++) {
4852 int index = pm_lookup_local_index(iseq, scope_node, local_target->
name);
4854 if (((
size_t) targets_index) < (targets_count - 1)) {
4857 ADD_INSN1(ret, &dummy_line_node, putobject, rb_id2sym(pm_constant_id_lookup(scope_node, local_target->
name)));
4858 ADD_SEND(ret, &dummy_line_node, idAREF,
INT2FIX(1));
4859 ADD_SETLOCAL(ret, &dummy_line_node, index, (
int) local_target->
depth);
4863 ADD_INSNL(ret, &dummy_line_node, jump, end_label);
4867 ADD_LABEL(ret, fail_label);
4870 for (
size_t targets_index = 0; targets_index < targets_count; targets_index++) {
4875 int index = pm_lookup_local_index(iseq, scope_node, local_target->
name);
4878 ADD_SETLOCAL(ret, &dummy_line_node, index, (
int) local_target->
depth);
4883 ADD_LABEL(ret, end_label);
4887 rb_bug(
"A pm_missing_node_t should not exist in prism's AST.");
4893 pm_scope_node_init((
pm_node_t *)module_node, &next_scope_node, scope_node, parser);
4895 ID module_id = pm_constant_id_lookup(scope_node, module_node->
name);
4896 VALUE module_name =
rb_str_freeze(rb_sprintf(
"<module:%"PRIsVALUE
">", rb_id2str(module_id)));
4898 const rb_iseq_t *module_iseq = NEW_CHILD_ISEQ(next_scope_node, module_name, ISEQ_TYPE_CLASS, lineno);
4900 const int flags = VM_DEFINECLASS_TYPE_MODULE |
4901 pm_compile_class_path(ret, iseq, module_node->
constant_path, &dummy_line_node, src,
false, scope_node);
4904 ADD_INSN3(ret, &dummy_line_node, defineclass,
ID2SYM(module_id), module_iseq,
INT2FIX(flags));
4912 int index = pm_lookup_local_index(iseq, scope_node, required_parameter_node->
name);
4914 ADD_SETLOCAL(ret, &dummy_line_node, index, 0);
4919 bool has_rest_expression = (cast->
rest &&
4924 int flag = (int) (
bool) cast->
rights.
size || has_rest_expression;
4926 for (
size_t index = 0; index < cast->
lefts.
size; index++) {
4927 PM_COMPILE_NOT_POPPED(cast->
lefts.
nodes[index]);
4931 if (has_rest_expression) {
4936 PM_COMPILE_NOT_POPPED(expression);
4940 if (!has_rest_expression) {
4943 for (
size_t index = 0; index < cast->
rights.
size; index++) {
4957 for (
size_t index = 0; index < lefts->
size; index++) {
4958 pushed = pm_compile_multi_write_lhs(iseq, dummy_line_node, src, popped, lefts->
nodes[index], ret, scope_node, pushed,
false);
4961 PM_COMPILE_NOT_POPPED(multi_write_node->
value);
4962 PM_DUP_UNLESS_POPPED;
4970 size_t remainder = pushed;
4971 if (popped) remainder--;
4974 ADD_INSN2(ret, &dummy_line_node, expandarray,
INT2FIX(lefts->
size),
INT2FIX((
int) (
bool) (rights->
size || rest_expression)));
4975 for (
size_t index = 0; index < lefts->
size; index++) {
4984 ADD_INSN1(ret, &dummy_line_node, topn,
INT2FIX(pushed));
4985 ADD_INSN1(ret, &dummy_line_node, setconstant,
ID2SYM(name));
4991 argc = args->arguments.size + 1;
4995 ADD_INSN(ret, &dummy_line_node, swap);
4999 ADD_INSN1(ret, &dummy_line_node, topn, vals);
5000 for (
size_t i = 1; i < argc; i++) {
5001 ADD_INSN1(ret, &dummy_line_node, topn, vals);
5003 ADD_INSN1(ret, &dummy_line_node, topn,
INT2FIX(argc));
5006 ADD_SEND(ret, &dummy_line_node, idASET,
INT2FIX(argc));
5015 ADD_INSN1(ret, &dummy_line_node, topn, vals);
5016 ADD_INSN(ret, &dummy_line_node, swap);
5018 ID method_id = pm_constant_id_lookup(scope_node, cast->
name);
5019 ADD_SEND(ret, &dummy_line_node, method_id,
INT2FIX(argc));
5023 PM_COMPILE(lefts->
nodes[index]);
5030 ADD_INSN1(ret, &dummy_line_node, setn,
INT2FIX(pushed));
5032 for (uint8_t index = 0; index < (pushed); index++) {
5038 if (rest_expression) {
5040 PM_COMPILE(rest_expression);
5046 for (
size_t index = 0; index < rights->
size; index++) {
5047 PM_COMPILE(rights->
nodes[index]);
5050 else if (rest_expression) {
5051 PM_COMPILE(rest_expression);
5059 if (ISEQ_COMPILE_DATA(iseq)->redo_label != 0 && can_add_ensure_iseq(iseq)) {
5060 LABEL *splabel = NEW_LABEL(0);
5062 ADD_LABEL(ret, splabel);
5070 pm_add_ensure_iseq(ret, iseq, 0, src, scope_node);
5072 ADD_ADJUST(ret, &dummy_line_node, ISEQ_COMPILE_DATA(iseq)->redo_label);
5073 ADD_INSNL(ret, &dummy_line_node, jump, ISEQ_COMPILE_DATA(iseq)->start_label);
5075 ADD_ADJUST_RESTORE(ret, splabel);
5076 PM_PUTNIL_UNLESS_POPPED;
5078 else if (ISEQ_COMPILE_DATA(iseq)->end_label && can_add_ensure_iseq(iseq)) {
5079 LABEL *splabel = NEW_LABEL(0);
5081 ADD_LABEL(ret, splabel);
5082 ADD_ADJUST(ret, &dummy_line_node, ISEQ_COMPILE_DATA(iseq)->start_label);
5091 pm_add_ensure_iseq(ret, iseq, 0, src, scope_node);
5092 ADD_INSNL(ret, &dummy_line_node, jump, ISEQ_COMPILE_DATA(iseq)->end_label);
5093 ADD_ADJUST_RESTORE(ret, splabel);
5094 splabel->unremovable = FALSE;
5096 PM_PUTNIL_UNLESS_POPPED;
5101 unsigned long throw_flag = 0;
5103 if (!ISEQ_COMPILE_DATA(ip)) {
5108 throw_flag = VM_THROW_NO_ESCAPE_FLAG;
5109 if (ISEQ_COMPILE_DATA(ip)->redo_label != 0) {
5113 else if (ISEQ_BODY(ip)->
type == ISEQ_TYPE_BLOCK) {
5116 else if (ISEQ_BODY(ip)->
type == ISEQ_TYPE_EVAL) {
5117 rb_raise(rb_eArgError,
"Can't escape from eval with next");
5121 ip = ISEQ_BODY(ip)->parent_iseq;
5130 ADD_INSN1(ret, &dummy_line_node,
throw,
INT2FIX(throw_flag | TAG_NEXT));
5135 rb_raise(rb_eArgError,
"Invalid next");
5143 PM_PUTNIL_UNLESS_POPPED
5146 ISEQ_BODY(iseq)->param.flags.accepts_no_kwarg = TRUE;
5152 ADD_INSN2(ret, &dummy_line_node, getspecial,
INT2FIX(1),
INT2FIX(reference_number << 1));
5159 LABEL *end_label = NEW_LABEL(lineno);
5160 PM_COMPILE_NOT_POPPED(or_node->
left);
5162 PM_DUP_UNLESS_POPPED;
5163 ADD_INSNL(ret, &dummy_line_node, branchif, end_label);
5165 PM_POP_UNLESS_POPPED;
5166 PM_COMPILE(or_node->
right);
5167 ADD_LABEL(ret, end_label);
5173 PM_COMPILE_NOT_POPPED(optional_parameter_node->
value);
5175 int index = pm_lookup_local_index(iseq, scope_node, optional_parameter_node->
name);
5177 ADD_SETLOCAL(ret, &dummy_line_node, index, 0);
5182 rb_bug(
"Should not ever enter a parameters node directly");
5189 if (parentheses_node->
body == NULL) {
5190 PM_PUTNIL_UNLESS_POPPED;
5192 PM_COMPILE(parentheses_node->
body);
5200 DECL_ANCHOR(pre_ex);
5201 INIT_ANCHOR(pre_ex);
5205 for (
size_t index = 0; index < node_list.
size; index++) {
5206 pm_compile_node(iseq, node_list.
nodes[index], pre_ex, src,
true, scope_node);
5211 ADD_INSN(pre_ex, &dummy_line_node, putnil);
5214 pre_ex->last->next = ret->anchor.next;
5215 ret->anchor.next = pre_ex->anchor.next;
5216 ret->anchor.next->prev = pre_ex->anchor.next;
5219 ret->last = pre_ex->last;
5226 const rb_iseq_t *prevblock = ISEQ_COMPILE_DATA(iseq)->current_block;
5229 pm_scope_node_init(node, &next_scope_node, scope_node, parser);
5231 child_iseq = NEW_CHILD_ISEQ(next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, lineno);
5232 ISEQ_COMPILE_DATA(iseq)->current_block = child_iseq;
5234 int is_index = ISEQ_BODY(iseq)->ise_size++;
5236 ADD_INSN2(ret, &dummy_line_node, once, child_iseq,
INT2FIX(is_index));
5241 ISEQ_COMPILE_DATA(iseq)->current_block = prevblock;
5246 rb_bug(
"Should not ever enter a program node directly");
5254 if (pm_optimizable_range_item_p(range_node->
left) && pm_optimizable_range_item_p(range_node->
right)) {
5263 ADD_INSN1(ret, &dummy_line_node, putobject, val);
5268 if (range_node->
left == NULL) {
5271 PM_COMPILE(range_node->
left);
5274 if (range_node->
right == NULL) {
5277 PM_COMPILE(range_node->
right);
5281 ADD_INSN1(ret, &dummy_line_node, newrange,
INT2FIX(exclusive));
5288 ADD_INSN1(ret, &dummy_line_node, putobject, parse_rational(node));
5293 if (ISEQ_COMPILE_DATA(iseq)->redo_label && can_add_ensure_iseq(iseq)) {
5294 LABEL *splabel = NEW_LABEL(0);
5296 ADD_LABEL(ret, splabel);
5298 ADD_ADJUST(ret, &dummy_line_node, ISEQ_COMPILE_DATA(iseq)->redo_label);
5300 pm_add_ensure_iseq(ret, iseq, 0, src, scope_node);
5301 ADD_INSNL(ret, &dummy_line_node, jump, ISEQ_COMPILE_DATA(iseq)->redo_label);
5302 ADD_ADJUST_RESTORE(ret, splabel);
5303 PM_PUTNIL_UNLESS_POPPED;
5305 else if (ISEQ_BODY(iseq)->
type != ISEQ_TYPE_EVAL && ISEQ_COMPILE_DATA(iseq)->start_label && can_add_ensure_iseq(iseq)) {
5306 LABEL *splabel = NEW_LABEL(0);
5308 ADD_LABEL(ret, splabel);
5309 pm_add_ensure_iseq(ret, iseq, 0, src, scope_node);
5310 ADD_ADJUST(ret, &dummy_line_node, ISEQ_COMPILE_DATA(iseq)->start_label);
5311 ADD_INSNL(ret, &dummy_line_node, jump, ISEQ_COMPILE_DATA(iseq)->start_label);
5312 ADD_ADJUST_RESTORE(ret, splabel);
5314 PM_PUTNIL_UNLESS_POPPED;
5320 if (!ISEQ_COMPILE_DATA(ip)) {
5325 if (ISEQ_COMPILE_DATA(ip)->redo_label != 0) {
5328 else if (ISEQ_BODY(ip)->
type == ISEQ_TYPE_BLOCK) {
5331 else if (ISEQ_BODY(ip)->
type == ISEQ_TYPE_EVAL) {
5332 rb_bug(
"Invalid redo\n");
5335 ip = ISEQ_BODY(ip)->parent_iseq;
5339 ADD_INSN1(ret, &dummy_line_node,
throw,
INT2FIX(VM_THROW_NO_ESCAPE_FLAG | TAG_REDO));
5344 rb_bug(
"Invalid redo\n");
5353 VALUE regex = pm_new_regex(cast, parser);
5355 ADD_INSN1(ret, &dummy_line_node, putobject, regex);
5360 LABEL *excep_match = NEW_LABEL(lineno);
5361 LABEL *rescue_end = NEW_LABEL(lineno);
5363 ISEQ_COMPILE_DATA(iseq)->end_label = rescue_end;
5366 iseq_set_exception_local_table(iseq);
5369 if (exception_list.
size > 0) {
5370 for (
size_t i = 0; i < exception_list.
size; i++) {
5371 ADD_GETLOCAL(ret, &dummy_line_node, LVAR_ERRINFO, 0);
5372 PM_COMPILE(exception_list.
nodes[i]);
5373 ADD_INSN1(ret, &dummy_line_node, checkmatch,
INT2FIX(VM_CHECKMATCH_TYPE_RESCUE));
5374 ADD_INSN1(ret, &dummy_line_node, branchif, excep_match);
5377 ADD_GETLOCAL(ret, &dummy_line_node, LVAR_ERRINFO, 0);
5379 ADD_INSN1(ret, &dummy_line_node, checkmatch,
INT2FIX(VM_CHECKMATCH_TYPE_RESCUE));
5380 ADD_INSN1(ret, &dummy_line_node, branchif, excep_match);
5382 ADD_INSN1(ret, &dummy_line_node, jump, rescue_end);
5384 ADD_LABEL(ret, excep_match);
5387 ADD_GETLOCAL(ret, &dummy_line_node, LVAR_ERRINFO, 0);
5398 ADD_INSN(ret, &dummy_line_node, leave);
5399 ADD_LABEL(ret, rescue_end);
5404 ADD_GETLOCAL(ret, &dummy_line_node, 1, 0);
5412 pm_scope_node_init((
pm_node_t *)rescue_node, &rescue_scope_node, scope_node, parser);
5414 rb_iseq_t *rescue_iseq = NEW_CHILD_ISEQ(rescue_scope_node,
5416 ISEQ_BODY(iseq)->location.label),
5417 ISEQ_TYPE_RESCUE, 1);
5419 LABEL *lstart = NEW_LABEL(lineno);
5420 LABEL *lend = NEW_LABEL(lineno);
5421 LABEL *lcont = NEW_LABEL(lineno);
5423 lstart->rescued = LABEL_RESCUE_BEG;
5424 lend->rescued = LABEL_RESCUE_END;
5425 ADD_LABEL(ret, lstart);
5427 ADD_LABEL(ret, lend);
5429 ADD_LABEL(ret, lcont);
5433 ADD_CATCH_ENTRY(CATCH_TYPE_RESCUE, lstart, lend, rescue_iseq, lcont);
5434 ADD_CATCH_ENTRY(CATCH_TYPE_RETRY, lend, lcont, NULL, lstart);
5441 enum rb_iseq_type
type = ISEQ_BODY(iseq)->type;
5445 enum rb_iseq_type parent_type = ISEQ_BODY(parent_iseq)->type;
5446 while (parent_type == ISEQ_TYPE_RESCUE || parent_type == ISEQ_TYPE_ENSURE) {
5447 if (!(parent_iseq = ISEQ_BODY(parent_iseq)->parent_iseq))
break;
5448 parent_type = ISEQ_BODY(parent_iseq)->type;
5451 switch (parent_type) {
5453 case ISEQ_TYPE_MAIN:
5455 rb_warn(
"argument of top-level return is ignored");
5457 if (parent_iseq == iseq) {
5458 type = ISEQ_TYPE_METHOD;
5465 if (
type == ISEQ_TYPE_METHOD) {
5466 splabel = NEW_LABEL(0);
5467 ADD_LABEL(ret, splabel);
5468 ADD_ADJUST(ret, &dummy_line_node, 0);
5472 PM_COMPILE_NOT_POPPED((
pm_node_t *)arguments);
5478 if (
type == ISEQ_TYPE_METHOD && can_add_ensure_iseq(iseq)) {
5479 pm_add_ensure_iseq(ret, iseq, 1, src, scope_node);
5481 ADD_INSN(ret, &dummy_line_node, leave);
5482 ADD_ADJUST_RESTORE(ret, splabel);
5484 PM_PUTNIL_UNLESS_POPPED;
5487 ADD_INSN1(ret, &dummy_line_node,
throw,
INT2FIX(TAG_RETURN));
5495 if (ISEQ_BODY(iseq)->
type == ISEQ_TYPE_RESCUE) {
5497 ADD_INSN1(ret, &dummy_line_node,
throw,
INT2FIX(TAG_RETRY));
5501 COMPILE_ERROR(ERROR_ARGS
"Invalid retry");
5502 rb_bug(
"Invalid retry");
5516 pm_node_t *block_param_keyword_rest = NULL;
5520 if (scope_node->parameters) {
5524 parameters_node = block_parameters_node->parameters;
5525 block_locals = &block_parameters_node->locals;
5526 if (parameters_node) {
5527 block_param_keyword_rest = parameters_node->
keyword_rest;
5540 rb_bug(
"Unexpected node type for parameters: %s", pm_node_type_to_str(
PM_NODE_TYPE(node)));
5544 struct rb_iseq_param_keyword *keyword = NULL;
5546 if (parameters_node) {
5547 optionals_list = ¶meters_node->
optionals;
5548 requireds_list = ¶meters_node->
requireds;
5549 keywords_list = ¶meters_node->
keywords;
5550 posts_list = ¶meters_node->
posts;
5552 body->
param.opt_num = 0;
5555 body->
param.lead_num = 0;
5556 body->
param.opt_num = 0;
5562 size_t locals_size = locals->
size;
5565 st_table *index_lookup_table = st_init_numtable();
5567 int table_size = (int) locals_size;
5570 body->
param.lead_num = 1;
5574 if (keywords_list && keywords_list->
size) {
5578 if (requireds_list) {
5579 int number_of_anonymous_locals = 0;
5580 for (
size_t i = 0; i < requireds_list->
size; i++) {
5590 number_of_anonymous_locals++;
5599 if (number_of_anonymous_locals > 1) {
5600 table_size += (number_of_anonymous_locals - 1);
5605 for (
size_t i = 0; i < posts_list->
size; i++) {
5616 if (block_param_keyword_rest) {
5622 if (parameters_node && parameters_node->
keyword_rest &&
5630 local_table_for_iseq->size = table_size;
5650 int local_index = 0;
5654 int required_multis_hidden_index = 0;
5655 int post_multis_hidden_index = 0;
5662 if (requireds_list && requireds_list->
size) {
5663 for (
size_t i = 0; i < requireds_list->
size; i++, local_index++) {
5673 required_multis_hidden_index = local_index;
5674 local = rb_make_temporary_id(local_index);
5675 local_table_for_iseq->ids[local_index] = local;
5683 pm_insert_local_index(param->
name, local_index, index_lookup_table, local_table_for_iseq, scope_node);
5687 rb_bug(
"Unsupported node %s", pm_node_type_to_str(
PM_NODE_TYPE(node)));
5692 body->
param.lead_num = (int) requireds_list->
size;
5693 body->
param.flags.has_lead =
true;
5698 if (optionals_list && optionals_list->
size) {
5699 body->
param.opt_num = (int) optionals_list->
size;
5700 body->
param.flags.has_opt =
true;
5702 for (
size_t i = 0; i < optionals_list->
size; i++, local_index++) {
5704 pm_insert_local_index(name, local_index, index_lookup_table, local_table_for_iseq, scope_node);
5710 if (parameters_node && parameters_node->
rest) {
5711 body->
param.rest_start = local_index;
5715 body->
param.flags.has_rest =
true;
5716 assert(body->
param.rest_start != -1);
5722 pm_insert_local_index(name, local_index, index_lookup_table, local_table_for_iseq, scope_node);
5727 local_table_for_iseq->ids[local_index] = idMULT;
5735 if (posts_list && posts_list->
size) {
5736 body->
param.post_num = (int) posts_list->
size;
5737 body->
param.post_start = local_index;
5738 body->
param.flags.has_post =
true;
5740 for (
size_t i = 0; i < posts_list->
size; i++, local_index++) {
5750 post_multis_hidden_index = local_index;
5751 local = rb_make_temporary_id(local_index);
5752 local_table_for_iseq->ids[local_index] = local;
5760 pm_insert_local_index(param->
name, local_index, index_lookup_table, local_table_for_iseq, scope_node);
5764 rb_bug(
"Unsupported node %s", pm_node_type_to_str(
PM_NODE_TYPE(node)));
5773 if (keywords_list && keywords_list->
size) {
5774 body->
param.keyword = keyword =
ZALLOC_N(
struct rb_iseq_param_keyword, 1);
5775 keyword->num = (int) keywords_list->
size;
5777 body->
param.flags.has_kw =
true;
5778 const VALUE default_values = rb_ary_hidden_new(1);
5783 for (
size_t i = 0; i < keywords_list->
size; i++, local_index++) {
5796 if (pm_static_literal_p(value) &&
5801 rb_ary_push(default_values, pm_static_literal_value(value, scope_node, parser));
5804 rb_ary_push(default_values, complex_mark);
5813 keyword->required_num++;
5817 rb_bug(
"Unexpected keyword parameter node type");
5821 ID local = pm_constant_id_lookup(scope_node, name);
5822 pm_insert_local_index(name, local_index, index_lookup_table, local_table_for_iseq, scope_node);
5826 keyword->bits_start = local_index;
5827 keyword->table = ids;
5831 for (
int i = 0; i <
RARRAY_LEN(default_values); i++) {
5833 if (dv == complex_mark) dv =
Qundef;
5840 keyword->default_values = dvs;
5843 ID local = rb_make_temporary_id(local_index);
5844 local_table_for_iseq->ids[local_index] = local;
5848 if (body->type == ISEQ_TYPE_BLOCK && local_index == 1 && requireds_list && requireds_list->
size == 1) {
5849 body->
param.flags.ambiguous_param0 =
true;
5852 if (parameters_node) {
5861 body->
param.flags.accepts_no_kwarg =
true;
5868 if (!body->
param.flags.has_kw) {
5869 body->
param.keyword = keyword =
ZALLOC_N(
struct rb_iseq_param_keyword, 1);
5872 keyword->rest_start = local_index;
5873 body->
param.flags.has_kwrest =
true;
5877 pm_insert_local_index(constant_id, local_index, index_lookup_table, local_table_for_iseq, scope_node);
5880 local_table_for_iseq->ids[local_index] = idPow;
5888 body->
param.rest_start = local_index;
5889 body->
param.flags.has_rest =
true;
5891 local_table_for_iseq->ids[local_index] = local;
5894 body->
param.block_start = local_index;
5895 body->
param.flags.has_block =
true;
5897 local_table_for_iseq->ids[local_index] = local;
5901 local_table_for_iseq->ids[local_index] = local;
5906 rb_raise(rb_eArgError,
"node type %s not expected as keyword_rest", pm_node_type_to_str(
PM_NODE_TYPE(parameters_node->
keyword_rest)));
5913 if (parameters_node->
block) {
5914 body->
param.block_start = local_index;
5915 body->
param.flags.has_block =
true;
5918 pm_insert_local_index(name, local_index, index_lookup_table, local_table_for_iseq, scope_node);
5935 if (requireds_list && requireds_list->
size) {
5936 for (
size_t i = 0; i < requireds_list->
size; i++) {
5942 local_index = pm_compile_multi_assign_params((
pm_multi_target_node_t *)required, index_lookup_table, local_table_for_iseq, scope_node, local_index);
5948 if (posts_list && posts_list->
size) {
5949 for (
size_t i = 0; i < posts_list->
size; i++) {
5955 local_index = pm_compile_multi_assign_params((
pm_multi_target_node_t *)post, index_lookup_table, local_table_for_iseq, scope_node, local_index);
5962 ID local = rb_make_temporary_id(local_index);
5963 local_table_for_iseq->ids[local_index] = local;
5970 for (
int i = 0; i < maximum; i++, local_index++) {
5972 pm_insert_local_index(constant_id, local_index, index_lookup_table, local_table_for_iseq, scope_node);
5980 uint32_t locals_body_index = 0;
5984 locals_body_index = ((
pm_block_node_t *)scope_node->ast_node)->locals_body_index;
5988 locals_body_index = ((
pm_def_node_t *)scope_node->ast_node)->locals_body_index;
5992 locals_body_index = ((
pm_lambda_node_t *)scope_node->ast_node)->locals_body_index;
5999 if (scope_node->locals.
size) {
6000 for (
size_t i = locals_body_index; i < scope_node->locals.
size; i++) {
6003 pm_insert_local_index(constant_id, local_index, index_lookup_table, local_table_for_iseq, scope_node);
6012 if (block_locals && block_locals->
size) {
6013 for (
size_t i = 0; i < block_locals->
size; i++, local_index++) {
6015 pm_insert_local_index(constant_id, local_index, index_lookup_table, local_table_for_iseq, scope_node);
6023 scope_node->index_lookup_table = index_lookup_table;
6024 iseq_calc_param_size(iseq);
6025 iseq_set_local_table(iseq, local_table_for_iseq);
6026 scope_node->local_table_for_iseq_size = local_table_for_iseq->size;
6030 if (keywords_list && keywords_list->
size) {
6031 for (
size_t i = 0; i < keywords_list->
size; i++, local_index++) {
6044 if (!(pm_static_literal_p(value)) ||
6048 LABEL *end_label = NEW_LABEL(nd_line(&dummy_line_node));
6050 int index = pm_lookup_local_index(iseq, scope_node, name);
6051 int kw_bits_idx = table_size - body->
param.keyword->bits_start;
6052 ADD_INSN2(ret, &dummy_line_node, checkkeyword,
INT2FIX(kw_bits_idx + VM_ENV_DATA_SIZE - 1),
INT2FIX(i));
6053 ADD_INSNL(ret, &dummy_line_node, branchif, end_label);
6055 ADD_SETLOCAL(ret, &dummy_line_node, index, 0);
6057 ADD_LABEL(ret, end_label);
6067 rb_bug(
"Unexpected keyword parameter node type");
6073 if (optionals_list && optionals_list->
size) {
6081 for (
size_t i = 0; i < optionals_list->
size; i++, local_index++) {
6082 label = NEW_LABEL(lineno);
6083 opt_table[i] = label;
6084 ADD_LABEL(ret, label);
6086 PM_COMPILE_NOT_POPPED(optional_node);
6090 label = NEW_LABEL(lineno);
6091 opt_table[optionals_list->
size] = label;
6092 ADD_LABEL(ret, label);
6094 body->
param.opt_table = (
const VALUE *)opt_table;
6097 if (requireds_list && requireds_list->
size) {
6098 for (
size_t i = 0; i < requireds_list->
size; i++) {
6104 ADD_GETLOCAL(ret, &dummy_line_node, table_size - required_multis_hidden_index, 0);
6105 PM_COMPILE(required);
6110 if (posts_list && posts_list->
size) {
6111 for (
size_t i = 0; i < posts_list->
size; i++) {
6117 ADD_GETLOCAL(ret, &dummy_line_node, table_size - post_multis_hidden_index, 0);
6123 switch (body->type) {
6124 case ISEQ_TYPE_BLOCK: {
6125 LABEL *start = ISEQ_COMPILE_DATA(iseq)->start_label = NEW_LABEL(0);
6126 LABEL *end = ISEQ_COMPILE_DATA(iseq)->end_label = NEW_LABEL(0);
6128 start->rescued = LABEL_RESCUE_BEG;
6129 end->rescued = LABEL_RESCUE_END;
6132 NODE dummy_line_node = generate_dummy_line_node(body->location.first_lineno, -1);
6133 if (ISEQ_COMPILE_DATA(iseq)->redo_label != 0) {
6136 ADD_LABEL(ret, start);
6138 if (scope_node->body) {
6143 ADD_INSN1(ret, &dummy_line_node, putspecialobject,
INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
6147 pm_scope_node_init((
pm_node_t *)post_execution_node->statements, &next_scope_node, scope_node, parser);
6149 const rb_iseq_t *block = NEW_CHILD_ISEQ(next_scope_node, make_name_for_block(body->parent_iseq), ISEQ_TYPE_BLOCK, lineno);
6151 ADD_CALL_WITH_BLOCK(ret, &dummy_line_node, id_core_set_postexe,
INT2FIX(0), block);
6156 LABEL *target = NEW_LABEL(lineno);
6157 LABEL *old_start = ISEQ_COMPILE_DATA(iseq)->start_label;
6159 ADD_GETLOCAL(ret, &dummy_line_node, 1, 0);
6160 PM_COMPILE(for_node->
index);
6162 ADD_LABEL(ret, target);
6163 ISEQ_COMPILE_DATA(iseq)->start_label = target;
6164 pm_compile_node(iseq, (
pm_node_t *)(scope_node->body), ret, src, popped, scope_node);
6165 ISEQ_COMPILE_DATA(iseq)->start_label = old_start;
6171 int parts_size = (int)cast->parts.size;
6173 ADD_INSN1(ret, &dummy_line_node, putobject,
rb_str_new(0, 0));
6177 pm_interpolated_node_compile(&cast->parts, iseq, dummy_line_node, ret, src,
false, scope_node, parser);
6182 pm_compile_node(iseq, (
pm_node_t *)(scope_node->body), ret, src, popped, scope_node);
6190 ADD_LABEL(ret, end);
6192 ISEQ_COMPILE_DATA(iseq)->last_line = body->location.code_location.end_pos.lineno;
6195 ADD_CATCH_ENTRY(CATCH_TYPE_REDO, start, end, NULL, start);
6196 ADD_CATCH_ENTRY(CATCH_TYPE_NEXT, start, end, NULL, end);
6199 case ISEQ_TYPE_ENSURE: {
6200 iseq_set_exception_local_table(iseq);
6202 if (scope_node->body) {
6203 PM_COMPILE_POPPED((
pm_node_t *)scope_node->body);
6206 ADD_GETLOCAL(ret, &dummy_line_node, 1, 0);
6207 ADD_INSN1(ret, &dummy_line_node,
throw,
INT2FIX(0));
6210 case ISEQ_TYPE_RESCUE: {
6211 iseq_set_exception_local_table(iseq);
6213 LABEL *lab = NEW_LABEL(lineno);
6214 LABEL *rescue_end = NEW_LABEL(lineno);
6215 ADD_GETLOCAL(ret, &dummy_line_node, LVAR_ERRINFO, 0);
6217 ADD_INSN1(ret, &dummy_line_node, checkmatch,
INT2FIX(VM_CHECKMATCH_TYPE_RESCUE));
6218 ADD_INSN1(ret, &dummy_line_node, branchif, lab);
6219 ADD_INSN1(ret, &dummy_line_node, jump, rescue_end);
6220 ADD_LABEL(ret, lab);
6221 PM_COMPILE((
pm_node_t *)scope_node->body);
6222 ADD_INSN(ret, &dummy_line_node, leave);
6223 ADD_LABEL(ret, rescue_end);
6224 ADD_GETLOCAL(ret, &dummy_line_node, LVAR_ERRINFO, 0);
6227 PM_COMPILE((
pm_node_t *)scope_node->ast_node);
6229 ADD_INSN1(ret, &dummy_line_node,
throw,
INT2FIX(0));
6234 if (scope_node->body) {
6235 PM_COMPILE((
pm_node_t *)scope_node->body);
6242 st_free_table(index_lookup_table);
6245 ADD_INSN(ret, &dummy_line_node, leave);
6257 pm_scope_node_init((
pm_node_t *)singleton_class_node, &next_scope_node, scope_node, parser);
6259 const rb_iseq_t *singleton_class = NEW_ISEQ(next_scope_node, rb_fstring_lit(
"singleton class"), ISEQ_TYPE_CLASS, lineno);
6261 PM_COMPILE_NOT_POPPED(singleton_class_node->
expression);
6264 CONST_ID(singletonclass,
"singletonclass");
6266 ADD_INSN3(ret, &dummy_line_node, defineclass,
6267 ID2SYM(singletonclass), singleton_class,
6268 INT2FIX(VM_DEFINECLASS_TYPE_SINGLETON_CLASS));
6279 VALUE value = pm_static_literal_value(node, scope_node, parser);
6280 ADD_INSN1(ret, &dummy_line_node, putobject, value);
6289 VALUE value = pm_static_literal_value(node, scope_node, parser);
6290 ADD_INSN1(ret, &dummy_line_node, putstring, value);
6299 VALUE value = pm_static_literal_value(node, scope_node, parser);
6300 ADD_INSN1(ret, &dummy_line_node, putobject, value);
6312 ADD_INSN1(ret, &dummy_line_node, splatarray,
Qtrue);
6319 if (node_list.
size > 0) {
6320 for (
size_t index = 0; index < node_list.
size - 1; index++) {
6321 PM_COMPILE_POPPED(node_list.
nodes[index]);
6323 PM_COMPILE(node_list.
nodes[node_list.
size - 1]);
6333 VALUE value = parse_string_encoded(node, &cast->
unescaped, parser);
6335 ADD_INSN1(ret, &dummy_line_node, putobject,
rb_str_freeze(value));
6338 ADD_INSN1(ret, &dummy_line_node, putstring, value);
6350 const rb_iseq_t *parent_block = ISEQ_COMPILE_DATA(iseq)->current_block;
6353 ISEQ_COMPILE_DATA(iseq)->current_block = NULL;
6357 int argc = pm_setup_args(super_node->
arguments, &flags, &keywords, iseq, ret, src, popped, scope_node, dummy_line_node, parser);
6359 flags |= VM_CALL_SUPER | VM_CALL_FCALL;
6361 if (super_node->
block) {
6364 PM_COMPILE_NOT_POPPED(super_node->
block);
6365 flags |= VM_CALL_ARGS_BLOCKARG;
6370 pm_scope_node_init(super_node->
block, &next_scope_node, scope_node, parser);
6371 parent_block = NEW_CHILD_ISEQ(next_scope_node, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, lineno);
6375 rb_bug(
"This node type should never occur on a SuperNode's block");
6381 ADD_INSN2(ret, &dummy_line_node, invokesuper,
6382 new_callinfo(iseq, 0, argc, flags, keywords, parent_block != NULL),
6392 VALUE value = pm_static_literal_value(node, scope_node, parser);
6393 ADD_INSN1(ret, &dummy_line_node, putobject, value);
6400 ADD_INSN1(ret, &dummy_line_node, putobject,
Qtrue);
6406 for (
size_t index = 0; index < undef_node->
names.
size; index++) {
6407 ADD_INSN1(ret, &dummy_line_node, putspecialobject,
INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
6408 ADD_INSN1(ret, &dummy_line_node, putspecialobject,
INT2FIX(VM_SPECIAL_OBJECT_CBASE));
6410 PM_COMPILE_NOT_POPPED(undef_node->
names.
nodes[index]);
6412 ADD_SEND(ret, &dummy_line_node, id_core_undef_method,
INT2NUM(2));
6414 if (index < undef_node->names.size - 1) {
6433 pm_compile_if(iseq, line, node_else, node_body, predicate, ret, src, popped, scope_node);
6442 pm_compile_while(iseq, lineno, flags, node->
type, statements, predicate, ret, src, popped, scope_node);
6446 rb_bug(
"Should not ever enter a when node directly");
6455 pm_compile_while(iseq, lineno, flags, node->
type, statements, predicate, ret, src, popped, scope_node);
6460 VALUE value = parse_string_encoded(node, &cast->
unescaped, parser);
6463 ADD_INSN1(ret, &dummy_line_node, putobject, value);
6464 ADD_SEND_WITH_FLAG(ret, &dummy_line_node, idBackquote,
INT2NUM(1),
INT2FIX(VM_CALL_FCALL | VM_CALL_ARGS_SIMPLE));
6478 argc = pm_setup_args(yield_node->
arguments, &flags, &keywords, iseq, ret, src, popped, scope_node, dummy_line_node, parser);
6481 ADD_INSN1(ret, &dummy_line_node, invokeblock, new_callinfo(iseq, 0, argc, flags, keywords, FALSE));
6487 for (; tmp_iseq != ISEQ_BODY(iseq)->local_iseq; level++ ) {
6488 tmp_iseq = ISEQ_BODY(tmp_iseq)->parent_iseq;
6491 if (level > 0) access_outer_variables(iseq, level, rb_intern(
"yield"),
true);
6510 constants[index] = rb_intern3((
const char *) constant->
start, constant->
length, encoding);
6513 st_table *index_lookup_table = st_init_numtable();
6515 for (
size_t i = 0; i < locals->
size; i++) {
6516 st_insert(index_lookup_table, locals->
ids[i], i);
6518 scope_node->constants = constants;
6519 scope_node->index_lookup_table = index_lookup_table;
6522 iseq_set_sequence(iseq, ret);
6529#define NEW_ISEQ OLD_ISEQ
6531#undef NEW_CHILD_ISEQ
6532#define NEW_CHILD_ISEQ OLD_CHILD_ISEQ
#define RUBY_ASSERT(expr)
Asserts that the given expression is truthy if and only if RUBY_DEBUG is truthy.
@ PM_RANGE_FLAGS_EXCLUDE_END
... operator
pm_node_type
This enum represents every type of node in the Ruby syntax tree.
@ PM_DEFINED_NODE
DefinedNode.
@ PM_PRE_EXECUTION_NODE
PreExecutionNode.
@ PM_RETRY_NODE
RetryNode.
@ PM_CONSTANT_PATH_WRITE_NODE
ConstantPathWriteNode.
@ PM_INDEX_AND_WRITE_NODE
IndexAndWriteNode.
@ PM_SOURCE_LINE_NODE
SourceLineNode.
@ PM_UNLESS_NODE
UnlessNode.
@ PM_EMBEDDED_VARIABLE_NODE
EmbeddedVariableNode.
@ PM_GLOBAL_VARIABLE_OPERATOR_WRITE_NODE
GlobalVariableOperatorWriteNode.
@ PM_GLOBAL_VARIABLE_READ_NODE
GlobalVariableReadNode.
@ PM_RATIONAL_NODE
RationalNode.
@ PM_YIELD_NODE
YieldNode.
@ PM_LOCAL_VARIABLE_AND_WRITE_NODE
LocalVariableAndWriteNode.
@ PM_CONSTANT_AND_WRITE_NODE
ConstantAndWriteNode.
@ PM_CLASS_NODE
ClassNode.
@ PM_FIND_PATTERN_NODE
FindPatternNode.
@ PM_CALL_OPERATOR_WRITE_NODE
CallOperatorWriteNode.
@ PM_MATCH_WRITE_NODE
MatchWriteNode.
@ PM_ARRAY_NODE
ArrayNode.
@ PM_CONSTANT_PATH_TARGET_NODE
ConstantPathTargetNode.
@ PM_PROGRAM_NODE
ProgramNode.
@ PM_MULTI_WRITE_NODE
MultiWriteNode.
@ PM_IMPLICIT_NODE
ImplicitNode.
@ PM_ARGUMENTS_NODE
ArgumentsNode.
@ PM_FORWARDING_SUPER_NODE
ForwardingSuperNode.
@ PM_WHILE_NODE
WhileNode.
@ PM_INTERPOLATED_STRING_NODE
InterpolatedStringNode.
@ PM_FALSE_NODE
FalseNode.
@ PM_FORWARDING_PARAMETER_NODE
ForwardingParameterNode.
@ PM_UNTIL_NODE
UntilNode.
@ PM_MATCH_PREDICATE_NODE
MatchPredicateNode.
@ PM_X_STRING_NODE
XStringNode.
@ PM_LOCAL_VARIABLE_OPERATOR_WRITE_NODE
LocalVariableOperatorWriteNode.
@ PM_LOCAL_VARIABLE_OR_WRITE_NODE
LocalVariableOrWriteNode.
@ PM_INSTANCE_VARIABLE_AND_WRITE_NODE
InstanceVariableAndWriteNode.
@ PM_GLOBAL_VARIABLE_TARGET_NODE
GlobalVariableTargetNode.
@ PM_CONSTANT_TARGET_NODE
ConstantTargetNode.
@ PM_CONSTANT_PATH_AND_WRITE_NODE
ConstantPathAndWriteNode.
@ PM_CAPTURE_PATTERN_NODE
CapturePatternNode.
@ PM_SOURCE_FILE_NODE
SourceFileNode.
@ PM_NO_KEYWORDS_PARAMETER_NODE
NoKeywordsParameterNode.
@ PM_CONSTANT_PATH_OPERATOR_WRITE_NODE
ConstantPathOperatorWriteNode.
@ PM_MULTI_TARGET_NODE
MultiTargetNode.
@ PM_SPLAT_NODE
SplatNode.
@ PM_LAMBDA_NODE
LambdaNode.
@ PM_CLASS_VARIABLE_READ_NODE
ClassVariableReadNode.
@ PM_REQUIRED_KEYWORD_PARAMETER_NODE
RequiredKeywordParameterNode.
@ PM_CALL_TARGET_NODE
CallTargetNode.
@ PM_INTERPOLATED_MATCH_LAST_LINE_NODE
InterpolatedMatchLastLineNode.
@ PM_NUMBERED_PARAMETERS_NODE
NumberedParametersNode.
@ PM_SYMBOL_NODE
SymbolNode.
@ PM_RESCUE_MODIFIER_NODE
RescueModifierNode.
@ PM_ALIAS_METHOD_NODE
AliasMethodNode.
@ PM_MATCH_REQUIRED_NODE
MatchRequiredNode.
@ PM_FORWARDING_ARGUMENTS_NODE
ForwardingArgumentsNode.
@ PM_BACK_REFERENCE_READ_NODE
BackReferenceReadNode.
@ PM_SCOPE_NODE
A special kind of node used for compilation.
@ PM_BLOCK_ARGUMENT_NODE
BlockArgumentNode.
@ PM_MISSING_NODE
MissingNode.
@ PM_IMPLICIT_REST_NODE
ImplicitRestNode.
@ PM_ASSOC_SPLAT_NODE
AssocSplatNode.
@ PM_CLASS_VARIABLE_AND_WRITE_NODE
ClassVariableAndWriteNode.
@ PM_RANGE_NODE
RangeNode.
@ PM_INSTANCE_VARIABLE_OPERATOR_WRITE_NODE
InstanceVariableOperatorWriteNode.
@ PM_LOCAL_VARIABLE_READ_NODE
LocalVariableReadNode.
@ PM_INSTANCE_VARIABLE_OR_WRITE_NODE
InstanceVariableOrWriteNode.
@ PM_REGULAR_EXPRESSION_NODE
RegularExpressionNode.
@ PM_CLASS_VARIABLE_OR_WRITE_NODE
ClassVariableOrWriteNode.
@ PM_BLOCK_PARAMETERS_NODE
BlockParametersNode.
@ PM_CONSTANT_WRITE_NODE
ConstantWriteNode.
@ PM_HASH_PATTERN_NODE
HashPatternNode.
@ PM_INDEX_OPERATOR_WRITE_NODE
IndexOperatorWriteNode.
@ PM_UNDEF_NODE
UndefNode.
@ PM_ALTERNATION_PATTERN_NODE
AlternationPatternNode.
@ PM_ENSURE_NODE
EnsureNode.
@ PM_LOCAL_VARIABLE_WRITE_NODE
LocalVariableWriteNode.
@ PM_SINGLETON_CLASS_NODE
SingletonClassNode.
@ PM_KEYWORD_HASH_NODE
KeywordHashNode.
@ PM_PARENTHESES_NODE
ParenthesesNode.
@ PM_CLASS_VARIABLE_WRITE_NODE
ClassVariableWriteNode.
@ PM_POST_EXECUTION_NODE
PostExecutionNode.
@ PM_CONSTANT_OPERATOR_WRITE_NODE
ConstantOperatorWriteNode.
@ PM_RETURN_NODE
ReturnNode.
@ PM_MODULE_NODE
ModuleNode.
@ PM_ARRAY_PATTERN_NODE
ArrayPatternNode.
@ PM_SUPER_NODE
SuperNode.
@ PM_MATCH_LAST_LINE_NODE
MatchLastLineNode.
@ PM_CONSTANT_PATH_NODE
ConstantPathNode.
@ PM_INTERPOLATED_SYMBOL_NODE
InterpolatedSymbolNode.
@ PM_CALL_AND_WRITE_NODE
CallAndWriteNode.
@ PM_OPTIONAL_KEYWORD_PARAMETER_NODE
OptionalKeywordParameterNode.
@ PM_CLASS_VARIABLE_TARGET_NODE
ClassVariableTargetNode.
@ PM_CASE_MATCH_NODE
CaseMatchNode.
@ PM_BREAK_NODE
BreakNode.
@ PM_CALL_OR_WRITE_NODE
CallOrWriteNode.
@ PM_IMAGINARY_NODE
ImaginaryNode.
@ PM_CONSTANT_READ_NODE
ConstantReadNode.
@ PM_GLOBAL_VARIABLE_WRITE_NODE
GlobalVariableWriteNode.
@ PM_SOURCE_ENCODING_NODE
SourceEncodingNode.
@ PM_BEGIN_NODE
BeginNode.
@ PM_INTERPOLATED_X_STRING_NODE
InterpolatedXStringNode.
@ PM_INSTANCE_VARIABLE_READ_NODE
InstanceVariableReadNode.
@ PM_FLIP_FLOP_NODE
FlipFlopNode.
@ PM_PINNED_VARIABLE_NODE
PinnedVariableNode.
@ PM_REQUIRED_PARAMETER_NODE
RequiredParameterNode.
@ PM_INSTANCE_VARIABLE_WRITE_NODE
InstanceVariableWriteNode.
@ PM_INSTANCE_VARIABLE_TARGET_NODE
InstanceVariableTargetNode.
@ PM_GLOBAL_VARIABLE_AND_WRITE_NODE
GlobalVariableAndWriteNode.
@ PM_RESCUE_NODE
RescueNode.
@ PM_FLOAT_NODE
FloatNode.
@ PM_ASSOC_NODE
AssocNode.
@ PM_INTEGER_NODE
IntegerNode.
@ PM_LOCAL_VARIABLE_TARGET_NODE
LocalVariableTargetNode.
@ PM_STRING_NODE
StringNode.
@ PM_INDEX_OR_WRITE_NODE
IndexOrWriteNode.
@ PM_ALIAS_GLOBAL_VARIABLE_NODE
AliasGlobalVariableNode.
@ PM_PARAMETERS_NODE
ParametersNode.
@ PM_NUMBERED_REFERENCE_READ_NODE
NumberedReferenceReadNode.
@ PM_CONSTANT_PATH_OR_WRITE_NODE
ConstantPathOrWriteNode.
@ PM_GLOBAL_VARIABLE_OR_WRITE_NODE
GlobalVariableOrWriteNode.
@ PM_CONSTANT_OR_WRITE_NODE
ConstantOrWriteNode.
@ PM_STATEMENTS_NODE
StatementsNode.
@ PM_OPTIONAL_PARAMETER_NODE
OptionalParameterNode.
@ PM_PINNED_EXPRESSION_NODE
PinnedExpressionNode.
@ PM_BLOCK_NODE
BlockNode.
@ PM_CLASS_VARIABLE_OPERATOR_WRITE_NODE
ClassVariableOperatorWriteNode.
@ PM_EMBEDDED_STATEMENTS_NODE
EmbeddedStatementsNode.
@ PM_INTERPOLATED_REGULAR_EXPRESSION_NODE
InterpolatedRegularExpressionNode.
@ PM_INDEX_TARGET_NODE
IndexTargetNode.
@ PM_KEYWORD_REST_PARAMETER_NODE
KeywordRestParameterNode.
@ PM_STRING_FLAGS_FROZEN
frozen by virtue of a frozen_string_literal comment
@ PM_ARGUMENTS_NODE_FLAGS_CONTAINS_KEYWORD_SPLAT
if arguments contain keyword splat
#define PM_NODE_FLAG_P(node, flag)
Return true if the given flag is set on the given node.
#define PM_NODE_TYPE_P(node, type)
Return true if the type of the given node matches the given type.
#define PM_NODE_TYPE(node)
Cast the type to an enum to allow the compiler to provide exhaustiveness checking.
@ PM_ARRAY_NODE_FLAGS_CONTAINS_SPLAT
if array contains splat nodes
@ PM_INTEGER_BASE_FLAGS_HEXADECIMAL
0x prefix
@ PM_INTEGER_BASE_FLAGS_OCTAL
0o or 0 prefix
@ PM_INTEGER_BASE_FLAGS_DECIMAL
0d or no prefix
@ PM_INTEGER_BASE_FLAGS_BINARY
0b prefix
@ PM_CALL_NODE_FLAGS_SAFE_NAVIGATION
&.
@ PM_CALL_NODE_FLAGS_ATTRIBUTE_WRITE
a call that is an attribute write, so the value being written should be returned
@ PM_CALL_NODE_FLAGS_VARIABLE_CALL
a call that could have been a local variable
uint16_t pm_node_type_t
This is the type of node embedded in the node struct.
@ PM_REGULAR_EXPRESSION_FLAGS_EUC_JP
e - forces the EUC-JP encoding
@ PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE
i - ignores the case of characters when matching
@ PM_REGULAR_EXPRESSION_FLAGS_ASCII_8BIT
n - forces the ASCII-8BIT encoding
@ PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE
m - allows $ to match the end of lines within strings
@ PM_REGULAR_EXPRESSION_FLAGS_EXTENDED
x - ignores whitespace and allows comments in regular expressions
@ PM_REGULAR_EXPRESSION_FLAGS_ONCE
o - only interpolates values into the regular expression once
@ PM_REGULAR_EXPRESSION_FLAGS_WINDOWS_31J
s - forces the Windows-31J encoding
@ PM_REGULAR_EXPRESSION_FLAGS_UTF_8
u - forces the UTF-8 encoding
uint16_t pm_node_flags_t
These are the flags embedded in the node struct.
@ PM_ENCODING_FLAGS_FORCED_BINARY_ENCODING
internal bytes forced the encoding to binary
@ PM_ENCODING_FLAGS_FORCED_UTF8_ENCODING
internal bytes forced the encoding to UTF-8
@ PM_LOOP_FLAGS_BEGIN_MODIFIER
a loop after a begin statement, so the body is executed first before the condition
#define RUBY_EVENT_B_RETURN
Encountered a next statement.
#define RUBY_EVENT_LINE
Encountered a new line.
#define RUBY_EVENT_RETURN
Encountered a return statement.
#define RUBY_EVENT_B_CALL
Encountered an yield statement.
#define RUBY_EVENT_RESCUE
Encountered a rescue statement.
#define rb_str_new2
Old name of rb_str_new_cstr.
#define ALLOCV
Old name of RB_ALLOCV.
#define Qundef
Old name of RUBY_Qundef.
#define INT2FIX
Old name of RB_INT2FIX.
#define ID2SYM
Old name of RB_ID2SYM.
#define SPECIAL_CONST_P
Old name of RB_SPECIAL_CONST_P.
#define OBJ_FREEZE
Old name of RB_OBJ_FREEZE.
#define ZALLOC_N
Old name of RB_ZALLOC_N.
#define T_HASH
Old name of RUBY_T_HASH.
#define ALLOC_N
Old name of RB_ALLOC_N.
#define Qtrue
Old name of RUBY_Qtrue.
#define INT2NUM
Old name of RB_INT2NUM.
#define Qnil
Old name of RUBY_Qnil.
#define Qfalse
Old name of RUBY_Qfalse.
#define T_ARRAY
Old name of RUBY_T_ARRAY.
#define NIL_P
Old name of RB_NIL_P.
#define DBL2NUM
Old name of rb_float_new.
#define xcalloc
Old name of ruby_xcalloc.
#define CONST_ID
Old name of RUBY_CONST_ID.
VALUE rb_eNotImpError
NotImplementedError exception.
VALUE rb_eStandardError
StandardError exception.
VALUE rb_eTypeError
TypeError exception.
VALUE rb_eNoMatchingPatternError
NoMatchingPatternError exception.
void rb_warn(const char *fmt,...)
Identical to rb_warning(), except it reports unless $VERBOSE is nil.
VALUE rb_eNoMatchingPatternKeyError
NoMatchingPatternKeyError exception.
double rb_cstr_to_dbl(const char *str, int mode)
Converts a textual representation of a real number into a numeric, which is the nearest value that th...
#define RB_OBJ_WRITTEN(old, oldv, young)
Identical to RB_OBJ_WRITE(), except it doesn't write any values, but only a WB declaration.
VALUE rb_enc_reg_new(const char *ptr, long len, rb_encoding *enc, int opts)
Identical to rb_reg_new(), except it additionally takes an encoding.
VALUE rb_range_new(VALUE beg, VALUE end, int excl)
Creates a new Range.
VALUE rb_rational_raw(VALUE num, VALUE den)
Identical to rb_rational_new(), except it skips argument validations.
VALUE rb_reg_new(const char *src, long len, int opts)
Creates a new Regular expression.
VALUE rb_str_tmp_new(long len)
Allocates a "temporary" string.
#define rb_str_new(str, len)
Allocates an instance of rb_cString.
VALUE rb_str_concat(VALUE dst, VALUE src)
Identical to rb_str_append(), except it also accepts an integer as a codepoint.
VALUE rb_str_freeze(VALUE str)
This is the implementation of String#freeze.
#define rb_str_new_cstr(str)
Identical to rb_str_new, except it assumes the passed pointer is a pointer to a C string.
int len
Length of the buffer.
VALUE type(ANYARGS)
ANYARGS-ed function type.
#define PM_KEYWORD_HASH_NODE_FLAGS_SYMBOL_KEYS
Temporary alias for the PM_NODE_FLAG_STATIC_KEYS flag.
uint32_t pm_constant_id_t
A constant id is a unique identifier for a constant in the constant pool.
The main header file for the prism parser.
#define RARRAY_LEN
Just another name of rb_array_len.
#define RARRAY_AREF(a, i)
#define RARRAY_CONST_PTR
Just another name of rb_array_const_ptr.
struct pm_node * old_name
AliasGlobalVariableNode::old_name.
struct pm_node * new_name
AliasGlobalVariableNode::new_name.
struct pm_node * old_name
AliasMethodNode::old_name.
struct pm_node * new_name
AliasMethodNode::new_name.
struct pm_node * left
AlternationPatternNode::left.
struct pm_node * right
AlternationPatternNode::right.
struct pm_node * left
AndNode::left.
struct pm_node * right
AndNode::right.
pm_node_t base
The embedded base node.
struct pm_node_list arguments
ArgumentsNode::arguments.
pm_node_t base
The embedded base node.
struct pm_node_list elements
ArrayNode::elements.
struct pm_node_list requireds
ArrayPatternNode::requireds.
struct pm_node * rest
ArrayPatternNode::rest.
struct pm_node * constant
ArrayPatternNode::constant.
struct pm_node_list posts
ArrayPatternNode::posts.
struct pm_node * value
AssocNode::value.
struct pm_node * key
AssocNode::key.
struct pm_node * value
AssocSplatNode::value.
struct pm_ensure_node * ensure_clause
BeginNode::ensure_clause.
struct pm_rescue_node * rescue_clause
BeginNode::rescue_clause.
struct pm_statements_node * statements
BeginNode::statements.
struct pm_else_node * else_clause
BeginNode::else_clause.
struct pm_node * expression
BlockArgumentNode::expression.
struct pm_node * parameters
BlockNode::parameters.
struct pm_node * body
BlockNode::body.
pm_constant_id_list_t locals
BlockNode::locals.
struct pm_arguments_node * arguments
BreakNode::arguments.
struct pm_node * value
CallAndWriteNode::value.
pm_constant_id_t read_name
CallAndWriteNode::read_name.
pm_constant_id_t write_name
CallAndWriteNode::write_name.
struct pm_node * receiver
CallAndWriteNode::receiver.
struct pm_node * receiver
CallNode::receiver.
pm_constant_id_t name
CallNode::name.
struct pm_arguments_node * arguments
CallNode::arguments.
struct pm_node * block
CallNode::block.
pm_constant_id_t read_name
CallOperatorWriteNode::read_name.
struct pm_node * receiver
CallOperatorWriteNode::receiver.
pm_constant_id_t write_name
CallOperatorWriteNode::write_name.
pm_constant_id_t operator
CallOperatorWriteNode::operator.
struct pm_node * value
CallOperatorWriteNode::value.
struct pm_node * receiver
CallOrWriteNode::receiver.
struct pm_node * value
CallOrWriteNode::value.
pm_constant_id_t write_name
CallOrWriteNode::write_name.
pm_constant_id_t read_name
CallOrWriteNode::read_name.
pm_constant_id_t name
CallTargetNode::name.
struct pm_node * receiver
CallTargetNode::receiver.
struct pm_node * target
CapturePatternNode::target.
struct pm_node * value
CapturePatternNode::value.
struct pm_node_list conditions
CaseMatchNode::conditions.
struct pm_else_node * consequent
CaseMatchNode::consequent.
struct pm_node * predicate
CaseMatchNode::predicate.
struct pm_node * predicate
CaseNode::predicate.
struct pm_else_node * consequent
CaseNode::consequent.
struct pm_node_list conditions
CaseNode::conditions.
struct pm_node * constant_path
ClassNode::constant_path.
pm_constant_id_list_t locals
ClassNode::locals.
pm_constant_id_t name
ClassNode::name.
struct pm_node * body
ClassNode::body.
struct pm_node * superclass
ClassNode::superclass.
ClassVariableAndWriteNode.
struct pm_node * value
ClassVariableAndWriteNode::value.
pm_constant_id_t name
ClassVariableAndWriteNode::name.
ClassVariableOperatorWriteNode.
pm_constant_id_t name
ClassVariableOperatorWriteNode::name.
pm_constant_id_t operator
ClassVariableOperatorWriteNode::operator.
struct pm_node * value
ClassVariableOperatorWriteNode::value.
ClassVariableOrWriteNode.
pm_constant_id_t name
ClassVariableOrWriteNode::name.
struct pm_node * value
ClassVariableOrWriteNode::value.
pm_constant_id_t name
ClassVariableReadNode::name.
pm_constant_id_t name
ClassVariableTargetNode::name.
struct pm_node * value
ClassVariableWriteNode::value.
pm_constant_id_t name
ClassVariableWriteNode::name.
pm_constant_id_t name
ConstantAndWriteNode::name.
struct pm_node * value
ConstantAndWriteNode::value.
size_t size
The number of constant ids in the list.
pm_constant_id_t * ids
The constant ids in the list.
ConstantOperatorWriteNode.
pm_constant_id_t name
ConstantOperatorWriteNode::name.
pm_constant_id_t operator
ConstantOperatorWriteNode::operator.
struct pm_node * value
ConstantOperatorWriteNode::value.
pm_constant_id_t name
ConstantOrWriteNode::name.
struct pm_node * value
ConstantOrWriteNode::value.
ConstantPathAndWriteNode.
struct pm_constant_path_node * target
ConstantPathAndWriteNode::target.
struct pm_node * value
ConstantPathAndWriteNode::value.
struct pm_node * child
ConstantPathNode::child.
struct pm_node * parent
ConstantPathNode::parent.
ConstantPathOperatorWriteNode.
pm_constant_id_t operator
ConstantPathOperatorWriteNode::operator.
struct pm_constant_path_node * target
ConstantPathOperatorWriteNode::target.
struct pm_node * value
ConstantPathOperatorWriteNode::value.
struct pm_node * value
ConstantPathOrWriteNode::value.
struct pm_constant_path_node * target
ConstantPathOrWriteNode::target.
struct pm_node * parent
ConstantPathTargetNode::parent.
struct pm_node * child
ConstantPathTargetNode::child.
struct pm_constant_path_node * target
ConstantPathWriteNode::target.
struct pm_node * value
ConstantPathWriteNode::value.
uint32_t size
The number of buckets in the hash map.
pm_constant_t * constants
The constants that are stored in the buckets.
pm_constant_id_t name
ConstantReadNode::name.
A constant in the pool which effectively stores a string.
size_t length
The length of the string.
const uint8_t * start
A pointer to the start of the string.
pm_constant_id_t name
ConstantTargetNode::name.
struct pm_node * value
ConstantWriteNode::value.
pm_constant_id_t name
ConstantWriteNode::name.
struct pm_parameters_node * parameters
DefNode::parameters.
pm_constant_id_t name
DefNode::name.
struct pm_node * receiver
DefNode::receiver.
struct pm_node * value
DefinedNode::value.
struct pm_statements_node * statements
ElseNode::statements.
struct pm_statements_node * statements
EmbeddedStatementsNode::statements.
struct pm_node * variable
EmbeddedVariableNode::variable.
const char * name
The name of the encoding.
struct pm_statements_node * statements
EnsureNode::statements.
struct pm_node * left
FindPatternNode::left.
struct pm_node * constant
FindPatternNode::constant.
struct pm_node * right
FindPatternNode::right.
struct pm_node_list requireds
FindPatternNode::requireds.
pm_node_t base
The embedded base node.
struct pm_node * left
FlipFlopNode::left.
struct pm_node * right
FlipFlopNode::right.
struct pm_statements_node * statements
ForNode::statements.
struct pm_node * index
ForNode::index.
struct pm_node * collection
ForNode::collection.
struct pm_block_node * block
ForwardingSuperNode::block.
GlobalVariableAndWriteNode.
struct pm_node * value
GlobalVariableAndWriteNode::value.
pm_constant_id_t name
GlobalVariableAndWriteNode::name.
GlobalVariableOperatorWriteNode.
pm_constant_id_t name
GlobalVariableOperatorWriteNode::name.
pm_constant_id_t operator
GlobalVariableOperatorWriteNode::operator.
struct pm_node * value
GlobalVariableOperatorWriteNode::value.
GlobalVariableOrWriteNode.
pm_constant_id_t name
GlobalVariableOrWriteNode::name.
struct pm_node * value
GlobalVariableOrWriteNode::value.
pm_constant_id_t name
GlobalVariableReadNode::name.
GlobalVariableTargetNode.
pm_constant_id_t name
GlobalVariableTargetNode::name.
struct pm_node * value
GlobalVariableWriteNode::value.
pm_constant_id_t name
GlobalVariableWriteNode::name.
struct pm_node_list elements
HashNode::elements.
struct pm_node_list elements
HashPatternNode::elements.
struct pm_node * rest
HashPatternNode::rest.
struct pm_node * constant
HashPatternNode::constant.
struct pm_node * consequent
IfNode::consequent.
struct pm_node * predicate
IfNode::predicate.
struct pm_statements_node * statements
IfNode::statements.
struct pm_node * numeric
ImaginaryNode::numeric.
struct pm_node * value
ImplicitNode::value.
struct pm_statements_node * statements
InNode::statements.
struct pm_node * pattern
InNode::pattern.
struct pm_arguments_node * arguments
IndexAndWriteNode::arguments.
struct pm_node * receiver
IndexAndWriteNode::receiver.
struct pm_node * value
IndexAndWriteNode::value.
struct pm_node * block
IndexAndWriteNode::block.
pm_constant_id_t operator
IndexOperatorWriteNode::operator.
struct pm_node * value
IndexOperatorWriteNode::value.
struct pm_node * block
IndexOperatorWriteNode::block.
struct pm_arguments_node * arguments
IndexOperatorWriteNode::arguments.
struct pm_node * receiver
IndexOperatorWriteNode::receiver.
struct pm_node * receiver
IndexOrWriteNode::receiver.
struct pm_node * value
IndexOrWriteNode::value.
struct pm_arguments_node * arguments
IndexOrWriteNode::arguments.
struct pm_node * block
IndexOrWriteNode::block.
struct pm_node * receiver
IndexTargetNode::receiver.
struct pm_arguments_node * arguments
IndexTargetNode::arguments.
InstanceVariableAndWriteNode.
struct pm_node * value
InstanceVariableAndWriteNode::value.
pm_constant_id_t name
InstanceVariableAndWriteNode::name.
InstanceVariableOperatorWriteNode.
struct pm_node * value
InstanceVariableOperatorWriteNode::value.
pm_constant_id_t name
InstanceVariableOperatorWriteNode::name.
pm_constant_id_t operator
InstanceVariableOperatorWriteNode::operator.
InstanceVariableOrWriteNode.
struct pm_node * value
InstanceVariableOrWriteNode::value.
pm_constant_id_t name
InstanceVariableOrWriteNode::name.
InstanceVariableReadNode.
pm_constant_id_t name
InstanceVariableReadNode::name.
InstanceVariableTargetNode.
pm_constant_id_t name
InstanceVariableTargetNode::name.
InstanceVariableWriteNode.
pm_constant_id_t name
InstanceVariableWriteNode::name.
struct pm_node * value
InstanceVariableWriteNode::value.
pm_node_t base
The embedded base node.
InterpolatedMatchLastLineNode.
struct pm_node_list parts
InterpolatedMatchLastLineNode::parts.
InterpolatedRegularExpressionNode.
struct pm_node_list parts
InterpolatedRegularExpressionNode::parts.
struct pm_node_list parts
InterpolatedStringNode::parts.
struct pm_node_list parts
InterpolatedSymbolNode::parts.
struct pm_node_list parts
InterpolatedXStringNode::parts.
struct pm_node_list elements
KeywordHashNode::elements.
KeywordRestParameterNode.
struct pm_node * body
LambdaNode::body.
struct pm_node * parameters
LambdaNode::parameters.
pm_constant_id_list_t locals
LambdaNode::locals.
A line and column in a string.
size_t line
The line number.
Currently, the ADD_INSN family of macros expects a NODE as the second parameter.
LocalVariableAndWriteNode.
pm_constant_id_t name
LocalVariableAndWriteNode::name.
uint32_t depth
LocalVariableAndWriteNode::depth.
struct pm_node * value
LocalVariableAndWriteNode::value.
LocalVariableOperatorWriteNode.
uint32_t depth
LocalVariableOperatorWriteNode::depth.
struct pm_node * value
LocalVariableOperatorWriteNode::value.
pm_constant_id_t operator
LocalVariableOperatorWriteNode::operator.
pm_constant_id_t name
LocalVariableOperatorWriteNode::name.
LocalVariableOrWriteNode.
uint32_t depth
LocalVariableOrWriteNode::depth.
struct pm_node * value
LocalVariableOrWriteNode::value.
pm_constant_id_t name
LocalVariableOrWriteNode::name.
uint32_t depth
LocalVariableReadNode::depth.
pm_constant_id_t name
LocalVariableReadNode::name.
uint32_t depth
LocalVariableTargetNode::depth.
pm_constant_id_t name
LocalVariableTargetNode::name.
struct pm_node * value
LocalVariableWriteNode::value.
uint32_t depth
LocalVariableWriteNode::depth.
pm_constant_id_t name
LocalVariableWriteNode::name.
This represents a range of bytes in the source string to which a node or token corresponds.
const uint8_t * start
A pointer to the start location of the range in the source.
const uint8_t * end
A pointer to the end location of the range in the source.
pm_string_t unescaped
MatchLastLineNode::unescaped.
struct pm_node * pattern
MatchPredicateNode::pattern.
struct pm_node * value
MatchPredicateNode::value.
struct pm_node * value
MatchRequiredNode::value.
struct pm_node * pattern
MatchRequiredNode::pattern.
struct pm_node_list targets
MatchWriteNode::targets.
struct pm_call_node * call
MatchWriteNode::call.
struct pm_node * constant_path
ModuleNode::constant_path.
struct pm_node * body
ModuleNode::body.
pm_constant_id_list_t locals
ModuleNode::locals.
pm_constant_id_t name
ModuleNode::name.
struct pm_node_list lefts
MultiTargetNode::lefts.
struct pm_node * rest
MultiTargetNode::rest.
struct pm_node_list rights
MultiTargetNode::rights.
struct pm_node * value
MultiWriteNode::value.
struct pm_node * rest
MultiWriteNode::rest.
struct pm_node_list rights
MultiWriteNode::rights.
struct pm_node_list lefts
MultiWriteNode::lefts.
A list of offsets of newlines in a string.
struct pm_arguments_node * arguments
NextNode::arguments.
A list of nodes in the source, most often used for lists of children.
size_t size
The number of nodes in the list.
struct pm_node ** nodes
The nodes in the list.
This is the base structure that represents a node in the syntax tree.
pm_node_type_t type
This represents the type of the node.
pm_node_flags_t flags
This represents any flags on the node.
pm_location_t location
This is the location of the node in the source.
NumberedReferenceReadNode.
OptionalKeywordParameterNode.
pm_constant_id_t name
OptionalKeywordParameterNode::name.
struct pm_node * value
OptionalKeywordParameterNode::value.
struct pm_node * value
OptionalParameterNode::value.
pm_constant_id_t name
OptionalParameterNode::name.
struct pm_node * left
OrNode::left.
struct pm_node * right
OrNode::right.
struct pm_node * rest
ParametersNode::rest.
struct pm_node_list requireds
ParametersNode::requireds.
struct pm_block_parameter_node * block
ParametersNode::block.
struct pm_node_list optionals
ParametersNode::optionals.
struct pm_node_list posts
ParametersNode::posts.
struct pm_node * keyword_rest
ParametersNode::keyword_rest.
struct pm_node_list keywords
ParametersNode::keywords.
struct pm_node * body
ParenthesesNode::body.
This struct represents the overall parser.
const pm_encoding_t * encoding
The encoding functions for the current file is attached to the parser as it's parsing so that it can ...
pm_constant_pool_t constant_pool
This constant pool keeps all of the constants defined throughout the file so that we can reference th...
pm_newline_list_t newline_list
This is the list of newline offsets in the source file.
struct pm_node * expression
PinnedExpressionNode::expression.
struct pm_node * variable
PinnedVariableNode::variable.
struct pm_statements_node * statements
PostExecutionNode::statements.
struct pm_statements_node * statements
PreExecutionNode::statements.
struct pm_statements_node * statements
ProgramNode::statements.
struct pm_node * right
RangeNode::right.
pm_location_t operator_loc
RangeNode::operator_loc.
struct pm_node * left
RangeNode::left.
pm_node_t base
The embedded base node.
pm_string_t unescaped
RegularExpressionNode::unescaped.
RequiredKeywordParameterNode.
pm_constant_id_t name
RequiredParameterNode::name.
struct pm_node * rescue_expression
RescueModifierNode::rescue_expression.
struct pm_node * expression
RescueModifierNode::expression.
struct pm_rescue_node * consequent
RescueNode::consequent.
struct pm_node * reference
RescueNode::reference.
struct pm_node_list exceptions
RescueNode::exceptions.
struct pm_statements_node * statements
RescueNode::statements.
pm_constant_id_list_t locals
SingletonClassNode::locals.
struct pm_node * expression
SingletonClassNode::expression.
struct pm_node * body
SingletonClassNode::body.
pm_string_t filepath
SourceFileNode::filepath.
struct pm_node * expression
SplatNode::expression.
struct pm_node_list body
StatementsNode::body.
pm_string_t unescaped
StringNode::unescaped.
A generic string type that can have various ownership semantics.
size_t length
The length of the string in bytes of memory.
struct pm_arguments_node * arguments
SuperNode::arguments.
struct pm_node * block
SuperNode::block.
struct pm_node_list names
UndefNode::names.
struct pm_else_node * consequent
UnlessNode::consequent.
struct pm_statements_node * statements
UnlessNode::statements.
struct pm_node * predicate
UnlessNode::predicate.
struct pm_statements_node * statements
UntilNode::statements.
struct pm_node * predicate
UntilNode::predicate.
struct pm_statements_node * statements
WhileNode::statements.
struct pm_node * predicate
WhileNode::predicate.
pm_string_t unescaped
XStringNode::unescaped.
struct pm_arguments_node * arguments
YieldNode::arguments.
struct rb_iseq_constant_body::@152 param
parameter information
uintptr_t ID
Type that represents a Ruby identifier such as a variable name.
uintptr_t VALUE
Type that represents a Ruby object.