90
97
static int insn_data_length(INSN *iobj);
91
98
static int insn_data_line_no(INSN *iobj);
92
99
static int calc_sp_depth(int depth, INSN *iobj);
93
static int insn_ret_num(int insn);
95
101
static void ADD_ELEM(LINK_ANCHOR *anchor, LINK_ELEMENT *elem);
97
static INSN *new_insn_body(rb_iseq_t *iseq, int line_no,
98
int insn_id, int argc, ...);
103
static INSN *new_insn_body(rb_iseq_t *iseq, int line_no, int insn_id, int argc, ...);
99
104
static LABEL *new_label_body(rb_iseq_t *iseq, int line);
101
static int iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *anchor,
106
static int iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *anchor, NODE * n, int);
103
107
static int iseq_setup(rb_iseq_t *iseq, LINK_ANCHOR *anchor);
105
108
static int iseq_optimize(rb_iseq_t *iseq, LINK_ANCHOR *anchor);
106
109
static int iseq_insns_unification(rb_iseq_t *iseq, LINK_ANCHOR *anchor);
107
static int set_sequence_stackcaching(rb_iseq_t *iseq, LINK_ANCHOR *anchor);
108
static int set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor);
110
static int set_exception_table(rb_iseq_t *iseq);
111
static int set_local_table(rb_iseq_t *iseq, ID *tbl);
112
static int set_local_table_eval(rb_iseq_t *iseq, ID *tbl);
113
static int set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *anchor, NODE * node);
114
static NODE *set_block_local_tbl(rb_iseq_t *iseq, NODE * node,
115
LINK_ANCHOR *anchor);
116
static int set_exception_tbl(rb_iseq_t *iseq);
117
static int set_optargs_table(rb_iseq_t *iseq);
111
static int iseq_set_local_table(rb_iseq_t *iseq, ID *tbl);
112
static int iseq_set_exception_local_table(rb_iseq_t *iseq);
113
static int iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *anchor, NODE * node);
115
static int iseq_set_sequence_stackcaching(rb_iseq_t *iseq, LINK_ANCHOR *anchor);
116
static int iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor);
117
static int iseq_set_exception_table(rb_iseq_t *iseq);
118
static int iseq_set_optargs_table(rb_iseq_t *iseq);
120
121
iseq_add_mark_object(rb_iseq_t *iseq, VALUE v)
122
rb_ary_push(iseq->iseq_mark_ary, v);
123
if (!SPECIAL_CONST_P(v)) {
124
rb_ary_push(iseq->mark_ary, v);
123
126
return COMPILE_OK;
127
130
iseq_add_mark_object_compile_time(rb_iseq_t *iseq, VALUE v)
129
rb_ary_push(iseq->compile_data->mark_ary, v);
132
if (!SPECIAL_CONST_P(v)) {
133
rb_ary_push(iseq->compile_data->mark_ary, v);
130
135
return COMPILE_OK;
134
#include "optinsn.inc"
136
#if OPT_INSTRUCTIONS_UNIFICATION
137
#include "optunifs.inc"
141
rb_iseq_compile(VALUE self, NODE *node)
139
iseq_compile(VALUE self, NODE *node)
143
141
DECL_ANCHOR(ret);
145
144
GetISeqPtr(self, iseq);
163
163
/* wide range catch handler must put at last */
164
164
ADD_CATCH_ENTRY(CATCH_TYPE_REDO, start, end, 0, start);
165
165
ADD_CATCH_ENTRY(CATCH_TYPE_NEXT, start, end, 0, end);
168
if (iseq->type == ISEQ_TYPE_CLASS) {
169
ADD_TRACE(ret, nd_line(node), RUBY_EVENT_CLASS);
170
COMPILE(ret, "scoped node", node->nd_body);
171
ADD_TRACE(ret, nd_line(node), RUBY_EVENT_END);
173
else if (iseq->type == ISEQ_TYPE_METHOD) {
174
ADD_TRACE(ret, nd_line(node), RUBY_EVENT_CALL);
175
COMPILE(ret, "scoped node", node->nd_body);
176
ADD_TRACE(ret, nd_line(node), RUBY_EVENT_RETURN);
179
COMPILE(ret, "scoped node", node->nd_body);
168
case ISEQ_TYPE_CLASS: {
169
ADD_TRACE(ret, nd_line(node), RUBY_EVENT_CLASS);
170
COMPILE(ret, "scoped node", node->nd_body);
171
ADD_TRACE(ret, nd_line(node), RUBY_EVENT_END);
174
case ISEQ_TYPE_METHOD: {
175
ADD_TRACE(ret, nd_line(node), RUBY_EVENT_CALL);
176
COMPILE(ret, "scoped node", node->nd_body);
177
ADD_TRACE(ret, nd_line(node), RUBY_EVENT_RETURN);
181
COMPILE(ret, "scoped node", node->nd_body);
184
if (iseq->type == ISEQ_TYPE_METHOD ||
185
iseq->type == ISEQ_TYPE_CLASS ||
186
iseq->type == ISEQ_TYPE_BLOCK ||
187
iseq->type == ISEQ_TYPE_EVAL ||
188
iseq->type == ISEQ_TYPE_TOP) {
190
rb_bug("compile/should not be reached: %s:%d", __FILE__, __LINE__);
192
else if (iseq->type == ISEQ_TYPE_RESCUE) {
193
set_exception_tbl(iseq);
187
switch (iseq->type) {
188
case ISEQ_TYPE_METHOD:
189
case ISEQ_TYPE_CLASS:
190
case ISEQ_TYPE_BLOCK:
193
rb_compile_error(ERROR_ARGS "compile/should not be reached: %s:%d",
196
case ISEQ_TYPE_RESCUE:
197
iseq_set_exception_local_table(iseq);
194
198
COMPILE(ret, "rescue", node);
196
else if (iseq->type == ISEQ_TYPE_ENSURE) {
197
set_exception_tbl(iseq);
200
case ISEQ_TYPE_ENSURE:
201
iseq_set_exception_local_table(iseq);
198
202
COMPILE_POPED(ret, "ensure", node);
200
else if (iseq->type == ISEQ_TYPE_DEFINED_GUARD) {
204
case ISEQ_TYPE_DEFINED_GUARD:
201
205
COMPILE(ret, "defined guard", node);
204
208
rb_bug("unknown scope");
210
212
if (iseq->type == ISEQ_TYPE_RESCUE || iseq->type == ISEQ_TYPE_ENSURE) {
211
213
ADD_INSN2(ret, 0, getdynamic, INT2FIX(1), INT2FIX(0));
212
214
ADD_INSN1(ret, 0, throw, INT2FIX(0) /* continue throw */ );
218
220
return iseq_setup(iseq, ret);
221
VALUE th_eval(void *);
224
iseq_translate_direct_threaded_code(rb_iseq_t *iseq)
224
iseq_translate_threaded_code(rb_iseq_t *iseq)
226
226
#if OPT_DIRECT_THREADED_CODE || OPT_CALL_THREADED_CODE
228
228
#if OPT_DIRECT_THREADED_CODE
229
void **table = (void **)th_eval(0);
229
const void *const *table = (const void **)vm_eval(0);
231
extern void **insns_address_table();
232
void **table = get_insns_address_table();
231
extern const void *const *get_insns_address_table();
232
const void *const *table = get_insns_address_table();
236
iseq->iseq_encoded = ALLOC_N(VALUE, iseq->size);
237
MEMCPY(iseq->iseq_encoded, iseq->iseq, VALUE, iseq->size);
236
iseq->iseq_encoded = ALLOC_N(VALUE, iseq->iseq_size);
237
MEMCPY(iseq->iseq_encoded, iseq->iseq, VALUE, iseq->iseq_size);
239
for (i = 0; i < iseq->size; /* */ ) {
239
for (i = 0; i < iseq->iseq_size; /* */ ) {
240
240
int insn = iseq->iseq_encoded[i];
241
241
int len = insn_len(insn);
242
242
iseq->iseq_encoded[i] = (VALUE)table[insn];
652
659
/* debugs("[compile step 2] (iseq_array_to_linkedlist)\n"); */
656
662
dump_disasm_list(FIRST_ELEMENT(anchor));
659
664
debugs("[compile step 3.1 (iseq_optimize)]\n");
660
665
iseq_optimize(iseq, anchor);
663
668
dump_disasm_list(FIRST_ELEMENT(anchor));
666
670
if (iseq->compile_data->option->instructions_unification) {
667
671
debugs("[compile step 3.2 (iseq_insns_unification)]\n");
668
672
iseq_insns_unification(iseq, anchor);
670
dump_disasm_list(FIRST_ELEMENT(anchor));
674
dump_disasm_list(FIRST_ELEMENT(anchor));
674
677
if (iseq->compile_data->option->stack_caching) {
675
debugs("[compile step 3.3 (set_sequence_stackcaching)]\n");
676
set_sequence_stackcaching(iseq, anchor);
678
debugs("[compile step 3.3 (iseq_set_sequence_stackcaching)]\n");
679
iseq_set_sequence_stackcaching(iseq, anchor);
678
dump_disasm_list(FIRST_ELEMENT(anchor));
681
dump_disasm_list(FIRST_ELEMENT(anchor));
682
debugs("[compile step 4.1 (set_sequence)]\n");
683
set_sequence(iseq, anchor);
684
debugs("[compile step 4.1 (iseq_set_sequence)]\n");
685
iseq_set_sequence(iseq, anchor);
685
687
dump_disasm_list(FIRST_ELEMENT(anchor));
689
debugs("[compile step 4.2 (set_exception_table)]\n");
690
set_exception_table(iseq);
689
debugs("[compile step 4.2 (iseq_set_exception_table)]\n");
690
iseq_set_exception_table(iseq);
692
692
debugs("[compile step 4.3 (set_optargs_table)] \n");
693
set_optargs_table(iseq);
693
iseq_set_optargs_table(iseq);
695
debugs("[compile step 5 (iseq_translate_direct_threaded_code)] \n");
696
iseq_translate_direct_threaded_code(iseq);
695
debugs("[compile step 5 (iseq_translate_threaded_code)] \n");
696
iseq_translate_threaded_code(iseq);
699
698
if (CPDEBUG > 1) {
700
699
VALUE str = ruby_iseq_disasm(iseq->self);
757
748
get_dyna_var_idx(rb_iseq_t *iseq, ID id, int *level, int *ls)
750
int lv = 0, idx = -1;
762
if ((idx = get_dyna_var_idx_at_raw(iseq, id)) >= 0) {
764
*ls = iseq->local_size;
753
idx = get_dyna_var_idx_at_raw(iseq, id);
767
757
iseq = iseq->parent_iseq;
771
rb_bug("get_dyna_var_idx: -1");
762
rb_bug("get_dyna_var_idx: -1");
766
*ls = iseq->local_size;
776
set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE *node_args)
771
iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE *node_args)
778
debugs("set_arguments: %s\n", node_args ? "" : "0");
773
debugs("iseq_set_arguments: %s\n", node_args ? "" : "0");
781
776
NODE *node_aux = node_args->nd_next;
782
int mandatory_len = 0;
783
777
NODE *node_opt = node_args->nd_opt;
786
ID post_start_id = 0;
788
781
NODE *node_init = 0;
789
int d = iseq->local_size - iseq->local_table_size;
791
783
if (nd_type(node_args) != NODE_ARGS) {
792
rb_bug("set_arguments: NODE_ARGS is expected, but %s",
784
rb_bug("iseq_set_arguments: NODE_ARGS is expected, but %s",
793
785
ruby_node_name(nd_type(node_args)));
797
789
* new argument infromation:
798
* NODE_ARGS [m: int, o: NODE_OPT_ARG, ->]
799
* NODE_ARGS_AUX [r: ID, b: ID, ->]
800
* NODE_ARGS_AUX [Pst: id, Plen: int, init: NODE*]
790
* NODE_ARGS [m: int, o: NODE_OPT_ARG, ->]
791
* NODE_ARGS_AUX [r: ID, b: ID, ->]
792
* NODE_ARGS_AUX [Pst: id, Plen: int, init: NODE*]
801
793
* optarg information:
802
* NODE_OPT_ARGS [idx, expr, ->]
794
* NODE_OPT_ARGS [idx, expr, next ->]
804
796
* NODE_AND(m_init, p_init)
797
* if "r" is 1, it's means "{|x,|}" type block parameter.
807
800
iseq->argc = node_args->nd_frml;
864
iseq->arg_rest = get_dyna_var_idx_at_raw(iseq, rest_id) + d;
862
iseq->arg_rest = get_dyna_var_idx_at_raw(iseq, rest_id);
866
864
if (iseq->arg_rest == -1) {
867
865
rb_bug("arg_rest: -1");
872
* if rest.length < post_len
873
* raise ArgumentError
884
* branchunless :success
886
* put "wrong number of arugments (%d of %d)"
898
LABEL *lsuccess = NEW_LABEL(nd_line(node_args));
901
#define GET_LOCAL(idx) do { \
902
if (iseq->type == ISEQ_TYPE_METHOD) { \
903
ADD_INSN1(optargs, nd_line(node_args), getlocal, INT2FIX(iseq->local_size - (idx) + 1)); \
906
ADD_INSN2(optargs, nd_line(node_args), getdynamic, INT2FIX(iseq->local_size - (idx)), INT2FIX(0)); \
910
#define SET_LOCAL(idx) do { \
911
if (iseq->type == ISEQ_TYPE_METHOD) { \
912
ADD_INSN1(optargs, nd_line(node_args), setlocal, INT2FIX(iseq->local_size - (idx) + 1)); \
915
ADD_INSN2(optargs, nd_line(node_args), setdynamic, INT2FIX(iseq->local_size - (idx)), INT2FIX(0)); \
919
GET_LOCAL(iseq->arg_rest);
920
ADD_SEND (optargs, nd_line(node_args), ID2SYM(idLength), INT2FIX(0));
921
ADD_INSN1(optargs, nd_line(node_args), putobject, INT2FIX(1));
922
ADD_SEND (optargs, nd_line(node_args), ID2SYM(idLT), INT2FIX(1));
923
ADD_INSNL(optargs, nd_line(node_args), branchunless, lsuccess);
924
ADD_CALL_RECEIVER(optargs, nd_line(node_args));
927
ADD_INSN1(optargs, nd_line(node_args), putobject, rb_eArgError);
928
ADD_INSN1(optargs, nd_line(node_args), putstring, rb_str_new2("wrong number of arguments"));
929
ADD_SEND (optargs, nd_line(node_args), ID2SYM(rb_intern("new")), INT2FIX(1));
930
ADD_CALL (optargs, nd_line(node_args), ID2SYM(rb_intern("raise")), INT2FIX(1));
931
ADD_INSN (optargs, nd_line(node_args), pop); /* dummy */
933
ADD_LABEL(optargs, lsuccess);
935
for (i=0; i<post_len; i++) {
936
GET_LOCAL(iseq->arg_rest);
937
ADD_SEND (optargs, nd_line(node_args), ID2SYM(rb_intern("pop")),
939
SET_LOCAL(iseq->arg_rest + i + 1);
942
iseq->arg_post_len = post_len;
868
if (iseq->arg_post_start == 0) {
869
iseq->arg_post_start = iseq->arg_rest + 1;
949
iseq->arg_block = get_dyna_var_idx_at_raw(iseq, block_id) + d;
874
iseq->arg_block = get_dyna_var_idx_at_raw(iseq, block_id);
952
if (iseq->arg_opts != 0 || iseq->arg_rest != -1 || iseq->arg_block != -1) {
877
if (iseq->arg_opts != 0 || iseq->arg_post_len != 0 ||
878
iseq->arg_rest != -1 || iseq->arg_block != -1) {
953
879
iseq->arg_simple = 0;
881
/* set arg_size: size of arguments */
882
if (iseq->arg_block != -1) {
883
iseq->arg_size = iseq->arg_block + 1;
885
else if (iseq->arg_post_len) {
886
iseq->arg_size = iseq->arg_post_start + iseq->arg_post_len;
888
else if (iseq->arg_rest != -1) {
889
iseq->arg_size = iseq->arg_rest + 1;
891
else if (iseq->arg_opts) {
892
iseq->arg_size = iseq->argc + iseq->arg_opts - 1;
895
iseq->arg_size = iseq->argc;
956
899
iseq->arg_simple = 1;
900
iseq->arg_size = iseq->argc;
903
if (iseq->type == ISEQ_TYPE_BLOCK) {
904
if (iseq->arg_opts == 0 && iseq->arg_post_len == 0 && iseq->arg_rest == -1) {
905
if (iseq->argc == 1 && last_comma == 0) {
907
iseq->arg_simple |= 0x02;
913
iseq->arg_simple = 1;
959
916
return COMPILE_OK;
963
set_local_table(rb_iseq_t *iseq, ID *tbl)
920
iseq_set_local_table(rb_iseq_t *iseq, ID *tbl)
1895
compile_array(rb_iseq_t *iseq,
1896
LINK_ANCHOR *ret, NODE * node_root, VALUE opt_p)
1844
compile_array_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE* node_root,
1845
VALUE opt_p, int poped)
1898
1847
NODE *node = node_root;
1899
1848
int len = node->nd_alen, line = nd_line(node), i=0;
1900
1849
DECL_ANCHOR(anchor);
1903
if (nd_type(node) != NODE_ARRAY) {
1904
rb_bug("compile_array: This node is not NODE_ARRAY, but %s",
1905
ruby_node_name(nd_type(node)));
1851
INIT_ANCHOR(anchor);
1852
if (nd_type(node) != NODE_ZARRAY) {
1854
if (nd_type(node) != NODE_ARRAY) {
1855
rb_bug("compile_array: This node is not NODE_ARRAY, but %s",
1856
ruby_node_name(nd_type(node)));
1909
if (opt_p && nd_type(node->nd_head) != NODE_LIT) {
1860
if (opt_p && nd_type(node->nd_head) != NODE_LIT) {
1863
COMPILE_(anchor, "array element", node->nd_head, poped);
1864
node = node->nd_next;
1912
COMPILE(anchor, "array element", node->nd_head);
1913
node = node->nd_next;
1916
1868
if (len != i) {
1917
if (0) rb_bug("node error: compile_array (%d: %d-%d)",
1918
nd_line(node_root), len, i);
1870
rb_bug("node error: compile_array (%d: %d-%d)",
1871
(int)nd_line(node_root), len, i);
1922
1876
if (opt_p == Qtrue) {
1923
VALUE ary = rb_ary_new();
1926
rb_ary_push(ary, node->nd_head->nd_lit);
1927
node = node->nd_next;
1878
VALUE ary = rb_ary_new();
1881
rb_ary_push(ary, node->nd_head->nd_lit);
1882
node = node->nd_next;
1930
iseq_add_mark_object_compile_time(iseq, ary);
1931
ADD_INSN1(ret, nd_line(node_root), duparray, ary);
1885
iseq_add_mark_object_compile_time(iseq, ary);
1886
ADD_INSN1(ret, nd_line(node_root), duparray, ary);
1934
ADD_INSN1(anchor, line, newarray, INT2FIX(len));
1891
ADD_INSN1(anchor, line, newarray, INT2FIX(len));
1935
1893
APPEND_LIST(ret, anchor);
1899
compile_array(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE* node_root, VALUE opt_p)
1901
return compile_array_(iseq, ret, node_root, opt_p, 0);
1941
1905
case_when_optimizable_literal(NODE * node)
1943
if (nd_type(node) == NODE_LIT) {
1907
switch (nd_type(node)) {
1944
1909
VALUE v = node->nd_lit;
1945
1910
if (SYMBOL_P(v) || rb_obj_is_kind_of(v, rb_cNumeric)) {
1949
else if (nd_type(node) == NODE_STR) {
1950
1916
return node->nd_lit;
2002
1967
ADD_INSN(ret, nd_line(node), pop); /* rhs */
2007
COMPILE_POPED(ret, "nest masgn lhs", node);
1971
DECL_ANCHOR(anchor);
1972
INIT_ANCHOR(anchor);
1973
COMPILE_POPED(anchor, "nest masgn lhs", node);
1974
REMOVE_ELEM(FIRST_ELEMENT(anchor));
1975
ADD_SEQ(ret, anchor);
2012
DECL_ANCHOR(anchor);
2013
COMPILE_POPED(anchor, "masgn lhs", node);
2014
/* dump_disasm_list(FIRST_ELEMENT(anchor)); */
2015
REMOVE_ELEM(FIRST_ELEMENT(anchor));
2016
/* dump_disasm_list(FIRST_ELEMENT(anchor)); */
2017
ADD_SEQ(ret, anchor);
2018
/* ADD_ELEM(ret, LAST_ELEMENT(anchor)); */
1979
DECL_ANCHOR(anchor);
1980
INIT_ANCHOR(anchor);
1981
COMPILE_POPED(anchor, "masgn lhs", node);
1982
REMOVE_ELEM(FIRST_ELEMENT(anchor));
1983
ADD_SEQ(ret, anchor);
2022
1987
return COMPILE_OK;
1991
compile_massign_opt_lhs(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *lhsn)
1994
compile_massign_opt_lhs(iseq, ret, lhsn->nd_next);
1995
compile_massign_lhs(iseq, ret, lhsn->nd_head);
2026
compile_massign(rb_iseq_t *iseq, LINK_ANCHOR *ret,
2027
NODE * rhsn, NODE * splatn, NODE * lhsn, int llen)
2000
compile_massign_opt(rb_iseq_t *iseq, LINK_ANCHOR *ret,
2001
NODE *rhsn, NODE *orig_lhsn)
2030
compile_massign(iseq, ret, rhsn, splatn, lhsn->nd_next, llen + 1);
2031
make_masgn_lhs(iseq, ret, lhsn->nd_head);
2005
VALUE *mem = ALLOCA_N(VALUE, memsize);
2006
int llen = 0, rlen = 0;
2008
NODE *lhsn = orig_lhsn;
2010
#define MEMORY(v) { \
2012
if (memindex == memsize) return 0; \
2013
for (i=0; i<memindex; i++) { \
2014
if (mem[i] == (v)) return 0; \
2016
mem[memindex++] = (v); \
2019
if (rhsn == 0 || nd_type(rhsn) != NODE_ARRAY) {
2036
if (splatn && (VALUE)splatn != -1) {
2024
NODE *ln = lhsn->nd_head;
2025
switch (nd_type(ln)) {
2030
case NODE_DASGN_CURR:
2041
switch (nd_type(rhsn)) {
2043
int rlen = rhsn->nd_alen;
2044
int max = rlen > llen ? rlen : llen;
2047
for (i = 0; i < max; i++) {
2048
if (i < rlen && i < llen) {
2050
COMPILE(ret, "masgn val1", rhsn->nd_head);
2051
rhsn = rhsn->nd_next;
2053
else if (i < rlen) {
2056
/* a, *b = x, y, z */
2058
COMPILE(ret, "masgn rhs for lhs splat",
2060
rhsn = rhsn->nd_next;
2065
/* a, b = c, d, e */
2066
COMPILE_POPED(ret, "masgn rhs (popped)",
2068
rhsn = rhsn->nd_next;
2071
else if (i < llen) {
2072
/* a, b, c = c, d */
2073
ADD_INSN(ret, 0, putnil);
2078
ADD_INSN1(ret, 0, newarray, INT2FIX(si));
2083
COMPILE(ret, "rhs to ary", rhsn->nd_head);
2084
ADD_INSN2(ret, nd_line(rhsn), expandarray, INT2FIX(llen),
2085
INT2FIX(lhs_splat));
2089
COMPILE(ret, "rhs to ary (splat)", rhsn->nd_head);
2090
ADD_INSN2(ret, nd_line(rhsn), expandarray, INT2FIX(llen),
2091
INT2FIX(lhs_splat));
2095
COMPILE(ret, "rhs to argscat", rhsn);
2096
ADD_INSN2(ret, nd_line(rhsn), expandarray,
2097
INT2FIX(llen), INT2FIX(lhs_splat));
2100
COMPILE(ret, "rhs to ary (splat/default)", rhsn);
2101
ADD_INSN2(ret, nd_line(rhsn), expandarray, INT2FIX(llen),
2102
INT2FIX(lhs_splat));
2103
/* rb_bug("unknown rhs: %s", ruby_node_name(nd_type(rhsn))); */
2039
lhsn = lhsn->nd_next;
2045
COMPILE_POPED(ret, "masgn val (poped)", rhsn->nd_head);
2107
/* nested massign */
2108
ADD_INSN2(ret, 0, expandarray, INT2FIX(llen), INT2FIX(lhs_splat));
2048
COMPILE(ret, "masgn val", rhsn->nd_head);
2050
rhsn = rhsn->nd_next;
2055
for (i=0; i<llen-rlen; i++) {
2056
ADD_INSN(ret, nd_line(orig_lhsn), putnil);
2060
compile_massign_opt_lhs(iseq, ret, orig_lhsn);
2065
compile_massign(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *node, int poped)
2067
NODE *rhsn = node->nd_value;
2068
NODE *splatn = node->nd_args;
2069
NODE *lhsn = node->nd_head;
2070
int lhs_splat = (splatn && (VALUE)splatn != (VALUE)-1) ? 1 : 0;
2072
if (!poped || splatn || !compile_massign_opt(iseq, ret, rhsn, lhsn)) {
2074
DECL_ANCHOR(lhsseq);
2076
INIT_ANCHOR(lhsseq);
2079
compile_massign_lhs(iseq, lhsseq, lhsn->nd_head);
2081
lhsn = lhsn->nd_next;
2084
COMPILE(ret, "normal masgn rhs", rhsn);
2087
ADD_INSN(ret, nd_line(node), dup);
2090
ADD_INSN2(ret, nd_line(node), expandarray,
2091
INT2FIX(llen), INT2FIX(lhs_splat));
2092
ADD_SEQ(ret, lhsseq);
2111
2094
if (lhs_splat) {
2112
make_masgn_lhs(iseq, ret, splatn);
2095
if (nd_type(splatn) == NODE_POSTARG) {
2096
/*a, b, *r, p1, p2 */
2097
NODE *postn = splatn->nd_2nd;
2098
NODE *restn = splatn->nd_1st;
2099
int num = postn->nd_alen;
2100
int flag = 0x02 | (((VALUE)restn == (VALUE)-1) ? 0x00 : 0x01);
2102
ADD_INSN2(ret, nd_line(splatn), expandarray,
2103
INT2FIX(num), INT2FIX(flag));
2105
if ((VALUE)restn != (VALUE)-1) {
2106
compile_massign_lhs(iseq, ret, restn);
2109
compile_massign_lhs(iseq, ret, postn->nd_head);
2110
postn = postn->nd_next;
2115
compile_massign_lhs(iseq, ret, splatn);
2115
2119
return COMPILE_OK;
2904
2882
ADD_SEND_R(ret, nd_line(node), ID2SYM(idEach), INT2FIX(0),
2905
2883
iseq->compile_data->current_block, INT2FIX(0));
2907
ADD_INSN(ret, nd_line(node), pop);
2911
2886
iseq->compile_data->current_block =
2912
2887
NEW_CHILD_ISEQVAL(node->nd_body, make_name_for_block(iseq),
2913
2888
ISEQ_TYPE_BLOCK);
2914
COMPILE_(ret, "iter caller", node->nd_iter, poped);
2889
COMPILE(ret, "iter caller", node->nd_iter);
2916
2891
ADD_LABEL(ret, retry_end_l);
2894
ADD_INSN(ret, nd_line(node), pop);
2917
2897
iseq->compile_data->current_block = prevblock;
2919
ADD_CATCH_ENTRY(CATCH_TYPE_RETRY, retry_label, retry_end_l, 0,
2899
ADD_CATCH_ENTRY(CATCH_TYPE_RETRY, retry_label, retry_end_l, 0, retry_label);
2900
ADD_CATCH_ENTRY(CATCH_TYPE_BREAK, retry_label, retry_end_l, 0, retry_end_l);
2923
2904
case NODE_BREAK:{
2960
2941
ip = ip->parent_iseq;
2962
COMPILE_ERROR(("Illegal break"));
2943
COMPILE_ERROR((ERROR_ARGS "Illegal break"));
2966
2947
case NODE_NEXT:{
2967
2948
unsigned long level = 0;
2949
int pop_after_throw = 0;
2969
2951
if (iseq->compile_data->redo_label != 0) {
2970
add_ensure_iseq(ret, iseq);
2971
ADD_INSNL(ret, nd_line(node), jump,
2972
iseq->compile_data->start_label);
2952
/* next in while loop */
2953
debugs("next in while\n");
2954
pop_after_throw = 1;
2974
2957
else if (iseq->compile_data->end_label) {
2958
debugs("next in block\n");
2959
ADD_INSN (ret, nd_line(node), emptstack);
2975
2960
COMPILE(ret, "next val", node->nd_stts);
2976
2961
add_ensure_iseq(ret, iseq);
2977
2962
ADD_INSNL(ret, nd_line(node), jump,
2978
2963
iseq->compile_data->end_label);
2980
2965
else if (iseq->type == ISEQ_TYPE_EVAL) {
2981
COMPILE_ERROR(("Can't escape from eval with next"));
2966
COMPILE_ERROR((ERROR_ARGS "Can't escape from eval with next"));
2984
rb_iseq_t *ip = iseq->parent_iseq;
2986
2973
level = 0x8000;
2987
if (ip->type == ISEQ_TYPE_BLOCK) {
2974
if (ip->compile_data->redo_label != 0) {
2978
else if (ip->type == ISEQ_TYPE_BLOCK) {
2988
2979
level |= 0x4000;
2991
else if (ip->compile_data->redo_label != 0) {
2994
2982
ip = ip->parent_iseq;
2997
2985
COMPILE(ret, "next val", node->nd_stts);
2998
add_ensure_iseq(ret, iseq);
2999
2986
ADD_INSN1(ret, nd_line(node), throw,
3000
2987
INT2FIX(level | 0x03) /* TAG_NEXT */ );
2988
if (pop_after_throw) {
2989
ADD_INSN(ret, nd_line(node), pop);
3003
COMPILE_ERROR(("Illegal next"));
2993
COMPILE_ERROR((ERROR_ARGS "Illegal next"));
3008
2998
case NODE_REDO:{
2999
int pop_after_throw = 0;
3009
3000
if (iseq->compile_data->redo_label) {
3001
debugs("redo in while");
3003
pop_after_throw = 1;
3010
3006
add_ensure_iseq(ret, iseq);
3011
3007
ADD_INSNL(ret, nd_line(node), jump,
3012
3008
iseq->compile_data->redo_label);
3013
3009
if (!poped) { /* for stack consistency */
3014
3010
ADD_INSN(ret, nd_line(node), putnil);
3017
3014
else if (iseq->type == ISEQ_TYPE_EVAL) {
3018
COMPILE_ERROR(("Can't escape from eval with redo"));
3015
COMPILE_ERROR((ERROR_ARGS "Can't escape from eval with redo"));
3020
3017
else if (iseq->compile_data->start_label) {
3018
ADD_INSN (ret, nd_line(node), emptstack);
3019
add_ensure_iseq(ret, iseq);
3021
3020
ADD_INSNL(ret, nd_line(node), jump,
3022
3021
iseq->compile_data->start_label);
3023
3022
if (!poped) { /* for stack consistency */
3633
3640
for (j = 0; j < liseq->arg_opts - 1; j++) {
3634
3641
int idx = liseq->local_size - (i + j);
3635
ADD_INSN1(args, nd_line(node), getlocal,
3642
ADD_INSN1(args, nd_line(node), getlocal, INT2FIX(idx));
3639
3645
argc = INT2FIX(i);
3642
if (liseq->arg_rest) {
3643
/* rest arguments */
3645
if (liseq->arg_rest == -1) {
3648
if (liseq->arg_rest != -1) {
3650
int idx = liseq->local_size - liseq->arg_rest;
3651
ADD_INSN1(args, nd_line(node), getlocal, INT2FIX(idx));
3652
argc = INT2FIX(liseq->arg_rest + 1);
3653
flag |= VM_CALL_ARGS_SPLAT_BIT;
3656
if (liseq->arg_post_len) {
3657
/* post arguments */
3658
int post_len = liseq->arg_post_len;
3659
int post_start = liseq->arg_post_start;
3661
if (liseq->arg_rest != -1) {
3663
for (j=0; j<post_len; j++) {
3664
int idx = liseq->local_size - (post_start + j);
3665
ADD_INSN1(args, nd_line(node), getlocal, INT2FIX(idx));
3667
ADD_INSN1(args, nd_line(node), newarray, INT2FIX(j));
3668
ADD_INSN (args, nd_line(node), concatarray);
3669
/* argc is setteled at above */
3649
int idx = liseq->local_size - liseq->arg_rest + 1;
3650
ADD_INSN1(args, nd_line(node), getlocal,
3652
argc = INT2FIX(liseq->arg_rest);
3653
flag |= VM_CALL_ARGS_SPLAT_BIT;
3673
for (j=0; j<post_len; j++) {
3674
int idx = liseq->local_size - (post_start + j);
3675
ADD_INSN1(args, nd_line(node), getlocal, INT2FIX(idx));
3677
argc = INT2FIX(post_len + post_start);
3659
3683
/* dummy reciever */
3660
3684
ADD_INSN1(ret, nd_line(node), putobject,
3661
3685
nd_type(node) == NODE_ZSUPER ? Qfalse : Qtrue);
3662
3686
ADD_SEQ(ret, args);
3663
3687
ADD_INSN3(ret, nd_line(node), invokesuper,
3664
argc, parent_block, INT2FIX(flag));
3688
argc, parent_block, LONG2FIX(flag));
3667
3691
ADD_INSN(ret, nd_line(node), pop);
3753
3774
case NODE_YIELD:{
3754
3775
DECL_ANCHOR(args);
3756
3777
unsigned long flag = 0;
3758
3780
if (iseq->type == ISEQ_TYPE_TOP || iseq->type == ISEQ_TYPE_CLASS) {
3759
COMPILE_ERROR(("Illegal yield"));
3781
COMPILE_ERROR((ERROR_ARGS "Illegal yield"));
3762
3784
if (node->nd_head) {
3763
if (nd_type(node->nd_head) == NODE_ARRAY) {
3766
argc = node->nd_head->nd_alen;
3767
compile_array(iseq, args, node->nd_head, Qfalse);
3769
debugs("argc: %d\n", argc);
3772
if (nd_type(node->nd_head) == NODE_ARGSCAT) {
3773
if (node->nd_state == Qtrue) {
3774
flag |= VM_CALL_ARGS_SPLAT_BIT;
3777
argc = node->nd_head->nd_head->nd_alen + 1;
3778
compile_array(iseq, args, node->nd_head->nd_head, Qfalse);
3781
COMPILE(args, "args(cat: splat)",
3782
node->nd_head->nd_body);
3784
else if (nd_type(node->nd_head) == NODE_SPLAT) {
3785
if (node->nd_state == Qtrue) {
3786
flag |= VM_CALL_ARGS_SPLAT_BIT;
3790
COMPILE(args, "splat", node->nd_head->nd_head);
3793
COMPILE(args, "nd_head(1)", node->nd_head);
3785
argc = setup_args(iseq, args, node->nd_head, &flag);
3801
3791
ADD_SEQ(ret, args);
3802
ADD_INSN2(ret, nd_line(node), invokeblock, INT2FIX(argc),
3792
ADD_INSN2(ret, nd_line(node), invokeblock, argc, LONG2FIX(flag));
3806
3795
ADD_INSN(ret, nd_line(node), pop);
4829
4798
DECL_ANCHOR(anchor);
4800
INIT_ANCHOR(anchor);
4831
4801
if (iseq->type == ISEQ_TYPE_METHOD ||
4832
4802
iseq->type == ISEQ_TYPE_TOP ||
4833
4803
iseq->type == ISEQ_TYPE_CLASS) {
4837
iseq->local_size = opt + RARRAY_LEN(locals);
4838
iseq->local_table_size = iseq->local_size;
4839
iseq->local_table = (ID *)ALLOC_N(ID *, iseq->local_size);
4840
tbl = iseq->local_table + opt;
4807
iseq->local_table_size = opt + RARRAY_LEN(locals);
4808
iseq->local_table = tbl = (ID *)ALLOC_N(ID *, iseq->local_table_size);
4809
iseq->local_size = opt + iseq->local_table_size;
4842
4811
for (i=0; i<RARRAY_LEN(locals); i++) {
4843
tbl[i] = SYM2ID(RARRAY_PTR(locals)[i]);
4812
VALUE lv = RARRAY_PTR(locals)[i];
4813
tbl[i] = FIXNUM_P(lv) ? FIX2INT(lv) : SYM2ID(CHECK_SYMBOL(lv));
4847
4817
if (FIXNUM_P(args)) {
4848
iseq->argc = FIX2INT(args);
4818
iseq->arg_size = iseq->argc = FIX2INT(args);
4849
4819
iseq->arg_simple = 1;
4855
* [label1, label2, ...] # opt labels
4860
* argc (Fixnum) # arg_simple
4863
VALUE argc = rb_ary_entry(args, i++);
4864
VALUE arg_opts = rb_ary_entry(args, i++);
4865
VALUE arg_opt_labels = rb_ary_entry(args, i++);
4866
VALUE arg_rest = rb_ary_entry(args, i++);
4867
VALUE arg_block = rb_ary_entry(args, i++);
4823
VALUE argc = CHECK_INTEGER(rb_ary_entry(args, i++));
4824
VALUE arg_opts = CHECK_INTEGER(rb_ary_entry(args, i++));
4825
VALUE arg_opt_labels = CHECK_ARRAY(rb_ary_entry(args, i++));
4826
VALUE arg_post_len = CHECK_INTEGER(rb_ary_entry(args, i++));
4827
VALUE arg_post_start = CHECK_INTEGER(rb_ary_entry(args, i++));
4828
VALUE arg_rest = CHECK_INTEGER(rb_ary_entry(args, i++));
4829
VALUE arg_block = CHECK_INTEGER(rb_ary_entry(args, i++));
4869
4831
iseq->argc = FIX2INT(argc);
4870
4832
iseq->arg_opts = FIX2INT(arg_opts);
4871
4833
iseq->arg_rest = FIX2INT(arg_rest);
4834
iseq->arg_post_len = FIX2INT(arg_post_len);
4835
iseq->arg_post_start = FIX2INT(arg_post_start);
4872
4836
iseq->arg_block = FIX2INT(arg_block);
4837
iseq->arg_opt_table = (VALUE *)ALLOC_N(VALUE, iseq->arg_opts);
4874
iseq->arg_opt_tbl = (VALUE *)ALLOC_N(VALUE, iseq->arg_opts);
4839
if (iseq->arg_block != -1) {
4840
iseq->arg_size = iseq->arg_block + 1;
4842
else if (iseq->arg_post_len) {
4843
iseq->arg_size = iseq->arg_post_start + iseq->arg_post_len;
4845
else if (iseq->arg_rest != -1) {
4846
iseq->arg_size = iseq->arg_rest + 1;
4849
iseq->arg_size = iseq->argc + iseq->arg_opts;
4876
4852
for (i=0; i<RARRAY_LEN(arg_opt_labels); i++) {
4877
iseq->arg_opt_tbl[i] =
4853
iseq->arg_opt_table[i] =
4878
4854
(VALUE)register_label(iseq, labels_table,
4879
4855
rb_ary_entry(arg_opt_labels, i));