platform/shared/ruby/compile.c in rhodes-3.1.1 vs platform/shared/ruby/compile.c in rhodes-3.2.0.beta.1
- old
+ new
@@ -15,10 +15,13 @@
#include "vm_core.h"
#include "iseq.h"
#include "insns.inc"
#include "insns_info.inc"
+#define numberof(array) (int)(sizeof(array) / sizeof((array)[0]))
+#define FIXNUM_INC(n, i) ((n)+(INT2FIX(i)&~FIXNUM_FLAG))
+#define FIXNUM_OR(n, i) ((n)|INT2FIX(i))
typedef struct iseq_link_element {
enum {
ISEQ_ELEMENT_NONE = INT2FIX(0x00),
ISEQ_ELEMENT_LABEL = INT2FIX(0x01),
@@ -164,18 +167,18 @@
#define NEW_LABEL(l) new_label_body(iseq, l)
#define iseq_filename(iseq) \
(((rb_iseq_t*)DATA_PTR(iseq))->filename)
-#define NEW_ISEQVAL(node, name, type) \
- new_child_iseq(iseq, node, name, 0, type)
+#define iseq_filepath(iseq) \
+ (((rb_iseq_t*)DATA_PTR(iseq))->filepath)
-#define NEW_CHILD_ISEQVAL(node, name, type) \
- new_child_iseq(iseq, node, name, iseq->self, type)
+#define NEW_ISEQVAL(node, name, type, line_no) \
+ new_child_iseq(iseq, node, name, 0, type, line_no)
-#define NEW_SPECIAQL_BLOCK_ISEQVAL(iseq, sym) \
- new_child_iseq(iseq, iseq->node, iseq->name, iseq->parent_iseq, iseq->type, sym)
+#define NEW_CHILD_ISEQVAL(node, name, type, line_no) \
+ new_child_iseq(iseq, node, name, iseq->self, type, line_no)
/* add instructions */
#define ADD_SEQ(seq1, seq2) \
APPEND_LIST(seq1, seq2)
@@ -220,12 +223,13 @@
(VALUE)id, (VALUE)argc, (VALUE)block, (VALUE)flag))
#define ADD_TRACE(seq, line, event) \
do { \
if ((event) == RUBY_EVENT_LINE && iseq->coverage && \
- RARRAY_PTR(iseq->coverage)[(line) - 1] == Qnil) { \
+ (line) != iseq->compile_data->last_coverable_line) { \
RARRAY_PTR(iseq->coverage)[(line) - 1] = INT2FIX(0); \
+ iseq->compile_data->last_coverable_line = (line); \
ADD_INSN1(seq, line, trace, INT2FIX(RUBY_EVENT_COVERAGE)); \
} \
if (iseq->compile_data->option->trace_instruction) { \
ADD_INSN1(seq, line, trace, INT2FIX(event)); \
} \
@@ -250,16 +254,16 @@
/* compile node */
#define COMPILE(anchor, desc, node) \
(debug_compile("== " desc "\n", \
iseq_compile_each(iseq, anchor, node, 0)))
-/* compile node, this node's value will be poped */
+/* compile node, this node's value will be popped */
#define COMPILE_POPED(anchor, desc, node) \
(debug_compile("== " desc "\n", \
iseq_compile_each(iseq, anchor, node, 1)))
-/* compile node, which is poped when 'poped' is true */
+/* compile node, which is popped when 'poped' is true */
#define COMPILE_(anchor, desc, node, poped) \
(debug_compile("== " desc "\n", \
iseq_compile_each(iseq, anchor, node, poped)))
#define OPERAND_AT(insn, idx) \
@@ -325,11 +329,11 @@
static int calc_sp_depth(int depth, INSN *iobj);
static void ADD_ELEM(ISEQ_ARG_DECLARE LINK_ANCHOR *anchor, LINK_ELEMENT *elem);
static INSN *new_insn_body(rb_iseq_t *iseq, int line_no, int insn_id, int argc, ...);
-static LABEL *new_label_body(rb_iseq_t *iseq, int line);
+static LABEL *new_label_body(rb_iseq_t *iseq, long line);
static ADJUST *new_adjust_body(rb_iseq_t *iseq, LABEL *label, int line);
static int iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *anchor, NODE * n, int);
static int iseq_setup(rb_iseq_t *iseq, LINK_ANCHOR *anchor);
static int iseq_optimize(rb_iseq_t *iseq, LINK_ANCHOR *anchor);
@@ -445,17 +449,17 @@
ADD_CATCH_ENTRY(CATCH_TYPE_REDO, start, end, 0, start);
ADD_CATCH_ENTRY(CATCH_TYPE_NEXT, start, end, 0, end);
break;
}
case ISEQ_TYPE_CLASS: {
- ADD_TRACE(ret, nd_line(node), RUBY_EVENT_CLASS);
+ ADD_TRACE(ret, FIX2INT(iseq->line_no), RUBY_EVENT_CLASS);
COMPILE(ret, "scoped node", node->nd_body);
ADD_TRACE(ret, nd_line(node), RUBY_EVENT_END);
break;
}
case ISEQ_TYPE_METHOD: {
- ADD_TRACE(ret, nd_line(node), RUBY_EVENT_CALL);
+ ADD_TRACE(ret, FIX2INT(iseq->line_no), RUBY_EVENT_CALL);
COMPILE(ret, "scoped node", node->nd_body);
ADD_TRACE(ret, nd_line(node), RUBY_EVENT_RETURN);
break;
}
default: {
@@ -511,17 +515,17 @@
#if OPT_DIRECT_THREADED_CODE
const void * const *table = rb_vm_get_insns_address_table();
#else
const void * const *table = rb_vm_get_insns_address_table();
#endif
- int i;
+ unsigned long i;
iseq->iseq_encoded = ALLOC_N(VALUE, iseq->iseq_size);
MEMCPY(iseq->iseq_encoded, iseq->iseq, VALUE, iseq->iseq_size);
for (i = 0; i < iseq->iseq_size; /* */ ) {
- int insn = iseq->iseq_encoded[i];
+ int insn = (int)iseq->iseq_encoded[i];
int len = insn_len(insn);
iseq->iseq_encoded[i] = (VALUE)table[insn];
i += len;
}
#else
@@ -832,11 +836,11 @@
#define debug_list(anc) debug_list(iseq, anc)
#endif
#endif
static LABEL *
-new_label_body(rb_iseq_t *iseq, int line)
+new_label_body(rb_iseq_t *iseq, long line)
{
LABEL *labelobj = compile_data_alloc_label(iseq);
labelobj->link.type = ISEQ_ELEMENT_LABEL;
labelobj->link.next = 0;
@@ -861,10 +865,11 @@
static INSN *
new_insn_core(rb_iseq_t *iseq, int line_no,
int insn_id, int argc, VALUE *argv)
{
INSN *iobj = compile_data_alloc_insn(iseq);
+ /* printf("insn_id: %d, line: %d\n", insn_id, line_no); */
iobj->link.type = ISEQ_ELEMENT_INSN;
iobj->link.next = 0;
iobj->insn_id = insn_id;
iobj->line_no = line_no;
@@ -901,23 +906,23 @@
(VALUE *)compile_data_alloc(iseq, sizeof(VALUE) * 5);
operands[0] = id;
operands[1] = argc;
operands[2] = block;
operands[3] = flag;
- operands[4] = 0;
+ operands[4] = INT2FIX(iseq->ic_size++);
iobj = new_insn_core(iseq, line_no, BIN(send), 5, operands);
return iobj;
}
static VALUE
new_child_iseq(rb_iseq_t *iseq, NODE *node,
- VALUE name, VALUE parent, VALUE type)
+ VALUE name, VALUE parent, VALUE type, int line_no)
{
VALUE ret;
debugs("[new_child_iseq]> ---------------------------------------\n");
- ret = rb_iseq_new_with_opt(node, name, iseq_filename(iseq->self),
+ ret = rb_iseq_new_with_opt(node, name, iseq_filename(iseq->self), iseq_filepath(iseq->self), INT2FIX(line_no),
parent, type, iseq->compile_data->option);
debugs("[new_child_iseq]< ---------------------------------------\n");
iseq_add_mark_object(iseq, ret);
return ret;
}
@@ -978,11 +983,11 @@
iseq_set_exception_local_table(rb_iseq_t *iseq)
{
ID id_dollar_bang;
CONST_ID(id_dollar_bang, "#$!");
- iseq->local_table = (ID *)ALLOC_N(ID *, 1);
+ iseq->local_table = (ID *)ALLOC_N(ID, 1);
iseq->local_table_size = 1;
iseq->local_size = iseq->local_table_size + 1;
iseq->local_table[0] = id_dollar_bang;
return COMPILE_OK;
}
@@ -1052,22 +1057,22 @@
rb_bug("iseq_set_arguments: NODE_ARGS is expected, but %s",
ruby_node_name(nd_type(node_args)));
}
/*
- * new argument infromation:
+ * new argument information:
* NODE_ARGS [m: int, o: NODE_OPT_ARG, ->]
* NODE_ARGS_AUX [r: ID, b: ID, ->]
* NODE_ARGS_AUX [Pst: id, Plen: int, init: NODE*]
* optarg information:
* NODE_OPT_ARGS [idx, expr, next ->]
* init arg:
* NODE_AND(m_init, p_init)
* if "r" is 1, it's means "{|x,|}" type block parameter.
*/
- iseq->argc = node_args->nd_frml;
+ iseq->argc = (int)node_args->nd_frml;
debugs(" - argc: %d\n", iseq->argc);
if (node_aux) {
rest_id = node_aux->nd_rest;
if (rest_id == 1) {
@@ -1078,19 +1083,19 @@
node_aux = node_aux->nd_next;
if (node_aux) {
ID post_start_id = node_aux->nd_pid;
iseq->arg_post_start = get_dyna_var_idx_at_raw(iseq, post_start_id);
- iseq->arg_post_len = node_aux->nd_plen;
+ iseq->arg_post_len = (int)node_aux->nd_plen;
node_init = node_aux->nd_next;
}
}
if (node_opt) {
NODE *node = node_opt;
LABEL *label;
- VALUE labels = rb_ary_new();
+ VALUE labels = rb_ary_tmp_new(1);
int i = 0, j;
while (node) {
label = NEW_LABEL(nd_line(node));
rb_ary_push(labels, (VALUE)label | 1);
@@ -1110,10 +1115,11 @@
iseq->arg_opt_table = ALLOC_N(VALUE, i);
MEMCPY(iseq->arg_opt_table, RARRAY_PTR(labels), VALUE, i);
for (j = 0; j < i; j++) {
iseq->arg_opt_table[j] &= ~1;
}
+ rb_ary_clear(labels);
}
else {
iseq->arg_opts = 0;
}
@@ -1188,20 +1194,20 @@
iseq_set_local_table(rb_iseq_t *iseq, ID *tbl)
{
int size;
if (tbl) {
- size = *tbl;
+ size = (int)*tbl;
tbl++;
}
else {
size = 0;
}
if (size > 0) {
- iseq->local_table = (ID *)ALLOC_N(ID *, size);
- MEMCPY(iseq->local_table, tbl, ID *, size);
+ iseq->local_table = (ID *)ALLOC_N(ID, size);
+ MEMCPY(iseq->local_table, tbl, ID, size);
}
iseq->local_size = iseq->local_table_size = size;
iseq->local_size += 1;
/*
@@ -1230,18 +1236,18 @@
return rb_str_hash_cmp(lit, val);
}
return !rb_eql(lit, val);
}
-static int
+static st_index_t
cdhash_hash(VALUE a)
{
- if (SPECIAL_CONST_P(a)) return (int)a;
+ if (SPECIAL_CONST_P(a)) return (st_index_t)a;
if (TYPE(a) == T_STRING) return rb_str_hash(a);
{
VALUE hval = rb_hash(a);
- return (int)FIX2LONG(hval);
+ return (st_index_t)FIX2LONG(hval);
}
}
static const struct st_hash_type cdhash_type = {
cdhash_cmp,
@@ -1277,11 +1283,11 @@
}
case ISEQ_ELEMENT_LABEL:
{
lobj = (LABEL *)list;
lobj->position = pos;
- lobj->set = Qtrue;
+ lobj->set = TRUE;
break;
}
case ISEQ_ELEMENT_NONE:
{
/* ignore */
@@ -1307,10 +1313,12 @@
}
/* make instruction sequence */
generated_iseq = ALLOC_N(VALUE, pos);
insn_info_table = ALLOC_N(struct iseq_insn_info_entry, k);
+ iseq->ic_entries = ALLOC_N(struct iseq_inline_cache_entry, iseq->ic_size);
+ MEMZERO(iseq->ic_entries, struct iseq_inline_cache_entry, iseq->ic_size);
list = FIRST_ELEMENT(anchor);
k = pos = sp = 0;
while (list) {
@@ -1328,19 +1336,19 @@
if (sp > stack_max) {
stack_max = sp;
}
/* fprintf(stderr, "insn: %-16s, sp: %d\n", insn_name(iobj->insn_id), sp); */
-
operands = iobj->operands;
insn = iobj->insn_id;
generated_iseq[pos] = insn;
types = insn_op_types(insn);
len = insn_len(insn);
/* operand check */
if (iobj->operand_size != len - 1) {
+ /* printf("operand size miss! (%d, %d)\n", iobj->operand_size, len); */
dump_disasm_list(list);
rb_compile_error(RSTRING_PTR(iseq->filename), iobj->line_no,
"operand size miss! (%d for %d)",
iobj->operand_size, len - 1);
xfree(generated_iseq);
@@ -1354,11 +1362,11 @@
switch (type) {
case TS_OFFSET:
{
/* label(destination position) */
lobj = (LABEL *)operands[j];
- if (lobj->set != Qtrue) {
+ if (!lobj->set) {
rb_compile_error(RSTRING_PTR(iseq->filename), iobj->line_no,
"unknown label");
}
if (lobj->sp == -1) {
lobj->sp = sp;
@@ -1380,11 +1388,11 @@
for (i=0; i < RARRAY_LEN(lits); i+=2) {
VALUE obj = rb_ary_entry(lits, i);
VALUE lv = rb_ary_entry(lits, i+1);
lobj = (LABEL *)(lv & ~1);
- if (lobj->set != Qtrue) {
+ if (!lobj->set) {
rb_compile_error(RSTRING_PTR(iseq->filename), iobj->line_no,
"unknown label");
}
if (!st_lookup(rb_hash_tbl(map), obj, 0)) {
rb_hash_aset(map, obj, INT2FIX(lobj->position - (pos+len)));
@@ -1392,10 +1400,11 @@
else {
rb_compile_warning(RSTRING_PTR(iseq->filename), iobj->line_no,
"duplicated when clause is ignored");
}
}
+ hide_obj(map);
generated_iseq[pos + 1 + j] = map;
iseq_add_mark_object(iseq, map);
break;
}
case TS_LINDEX:
@@ -1421,22 +1430,26 @@
iseq_add_mark_object(iseq, v);
break;
}
case TS_IC: /* inline cache */
{
- VALUE v = (VALUE)NEW_INLINE_CACHE_ENTRY();
- generated_iseq[pos + 1 + j] = v;
- iseq_add_mark_object(iseq, v);
+ int ic_index = FIX2INT(operands[j]);
+ IC ic = &iseq->ic_entries[ic_index];
+ if (UNLIKELY(ic_index >= iseq->ic_size)) {
+ rb_bug("iseq_set_sequence: ic_index overflow: index: %d, size: %d",
+ ic_index, iseq->ic_size);
+ }
+ generated_iseq[pos + 1 + j] = (VALUE)ic;
break;
}
case TS_ID: /* ID */
generated_iseq[pos + 1 + j] = SYM2ID(operands[j]);
break;
case TS_GENTRY:
{
- struct global_entry *entry =
- (struct global_entry *)(operands[j] & (~1));
+ struct rb_global_entry *entry =
+ (struct rb_global_entry *)(operands[j] & (~1));
generated_iseq[pos + 1 + j] = (VALUE)entry;
}
break;
default:
rb_compile_error(RSTRING_PTR(iseq->filename), iobj->line_no,
@@ -1540,11 +1553,11 @@
{
VALUE *tptr, *ptr;
int tlen, i;
struct iseq_catch_table_entry *entry;
- tlen = RARRAY_LEN(iseq->compile_data->catch_table_ary);
+ tlen = (int)RARRAY_LEN(iseq->compile_data->catch_table_ary);
tptr = RARRAY_PTR(iseq->compile_data->catch_table_ary);
iseq->catch_table = tlen ? ALLOC_N(struct iseq_catch_table_entry, tlen) : 0;
iseq->catch_table_size = tlen;
@@ -1759,40 +1772,36 @@
INSN *piobj = (INSN *)get_prev_insn((INSN *)list);
if (piobj->insn_id == BIN(send) &&
piobj->operands[2] == 0 /* block */
) {
- piobj->operands[3] = INT2FIX(FIX2INT(piobj->operands[3]) | VM_CALL_TAILCALL_BIT);
+ piobj->operands[3] = FIXNUM_OR(piobj->operands[3], VM_CALL_TAILCALL_BIT);
}
}
return COMPILE_OK;
}
static int
-insn_set_specialized_instruction(INSN *iobj, int insn_id)
+insn_set_specialized_instruction(rb_iseq_t *iseq, INSN *iobj, int insn_id)
{
- iobj->insn_id = insn_id;
- iobj->operand_size = 0;
- return COMPILE_OK;
-}
+ int i, old_opsize = iobj->operand_size;
-static int
-insn_set_specialized_instruction_with_ic(INSN *iobj, int insn_id, int n)
-{
- int i;
iobj->insn_id = insn_id;
- iobj->operand_size = n;
+ iobj->operand_size = insn_len(insn_id) - 1;
+ /* printf("iobj->operand_size: %d\n", iobj->operand_size); */
- /* max of n is 4 */
- for (i=0; i<n; i++) {
- iobj->operands[i] = Qnil;
+ if (iobj->operand_size > old_opsize) {
+ iobj->operands = (VALUE *)compile_data_alloc(iseq, iobj->operand_size);
}
+ for (i=0; i<iobj->operand_size; i++) {
+ iobj->operands[i] = INT2FIX(iseq->ic_size++);
+ }
+
return COMPILE_OK;
}
-
static int
iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj)
{
if (iobj->insn_id == BIN(send)) {
ID mid = SYM2ID(OPERAND_AT(iobj, 0));
@@ -1802,69 +1811,66 @@
/* TODO: should be more sophisticated search */
if (block == 0 && flag == INT2FIX(0)) {
if (argc == 0) {
if (mid == idLength) {
- insn_set_specialized_instruction(iobj, BIN(opt_length));
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_length));
}
+ else if (mid == idSize) {
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_size));
+ }
else if (mid == idSucc) {
- insn_set_specialized_instruction(iobj, BIN(opt_succ));
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_succ));
}
else if (mid == idNot) {
- insn_set_specialized_instruction_with_ic(iobj, BIN(opt_not), 1);
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_not));
}
}
else if (argc == 1) {
if (0) {
}
else if (mid == idPLUS) {
- insn_set_specialized_instruction(iobj, BIN(opt_plus));
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_plus));
}
else if (mid == idMINUS) {
- insn_set_specialized_instruction(iobj, BIN(opt_minus));
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_minus));
}
else if (mid == idMULT) {
- insn_set_specialized_instruction(iobj, BIN(opt_mult));
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_mult));
}
else if (mid == idDIV) {
- insn_set_specialized_instruction(iobj, BIN(opt_div));
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_div));
}
else if (mid == idMOD) {
- insn_set_specialized_instruction(iobj, BIN(opt_mod));
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_mod));
}
else if (mid == idEq) {
- insn_set_specialized_instruction_with_ic(iobj, BIN(opt_eq), 1);
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_eq));
}
else if (mid == idNeq) {
- insn_set_specialized_instruction_with_ic(iobj, BIN(opt_neq), 2);
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_neq));
}
else if (mid == idLT) {
- insn_set_specialized_instruction(iobj, BIN(opt_lt));
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_lt));
}
else if (mid == idLE) {
- insn_set_specialized_instruction(iobj, BIN(opt_le));
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_le));
}
else if (mid == idGT) {
- insn_set_specialized_instruction(iobj, BIN(opt_gt));
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_gt));
}
else if (mid == idGE) {
- insn_set_specialized_instruction(iobj, BIN(opt_ge));
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_ge));
}
else if (mid == idLTLT) {
- insn_set_specialized_instruction(iobj, BIN(opt_ltlt));
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_ltlt));
}
else if (mid == idAREF) {
- insn_set_specialized_instruction(iobj, BIN(opt_aref));
+ insn_set_specialized_instruction(iseq, iobj, BIN(opt_aref));
}
}
}
-
- if (argc > 0) {
- if (mid == idSend || mid == id__send__ ) {
- OPERAND_AT(iobj, 3) |= INT2FIX(VM_CALL_SEND_BIT);
- }
- }
}
return COMPILE_OK;
}
static int
@@ -1939,20 +1945,21 @@
iseq_insns_unification(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
{
#if OPT_INSTRUCTIONS_UNIFICATION
LINK_ELEMENT *list;
INSN *iobj, *niobj;
- int id, j, k;
+ int id, k;
+ intptr_t j;
list = FIRST_ELEMENT(anchor);
while (list) {
if (list->type == ISEQ_ELEMENT_INSN) {
iobj = (INSN *)list;
id = iobj->insn_id;
if (unified_insns_data[id] != 0) {
const int *const *entry = unified_insns_data[id];
- for (j = 1; j < (int)entry[0]; j++) {
+ for (j = 1; j < (intptr_t)entry[0]; j++) {
const int *unified = entry[j];
LINK_ELEMENT *li = list->next;
for (k = 2; k < unified[1]; k++) {
if (li->type != ISEQ_ELEMENT_INSN ||
((INSN *)li)->insn_id != unified[k]) {
@@ -2149,14 +2156,18 @@
static int
compile_dstr_fragments(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int *cntp)
{
NODE *list = node->nd_next;
VALUE lit = node->nd_lit;
- int cnt = 1;
+ int cnt = 0;
debugp_param("nd_lit", lit);
- ADD_INSN1(ret, nd_line(node), putobject, node->nd_lit);
+ if (!NIL_P(lit)) {
+ hide_obj(lit);
+ cnt++;
+ ADD_INSN1(ret, nd_line(node), putobject, lit);
+ }
while (list) {
COMPILE(ret, "each string", list->nd_head);
cnt++;
list = list->nd_next;
@@ -2210,16 +2221,16 @@
break;
}
case NODE_LIT: /* NODE_LIT is always not true */
case NODE_TRUE:
case NODE_STR:
- /* printf("useless conditon eliminate (%s)\n", ruby_node_name(nd_type(cond))); */
+ /* printf("useless condition eliminate (%s)\n", ruby_node_name(nd_type(cond))); */
ADD_INSNL(ret, nd_line(cond), jump, then_label);
break;
case NODE_FALSE:
case NODE_NIL:
- /* printf("useless conditon eliminate (%s)\n", ruby_node_name(nd_type(cond))); */
+ /* printf("useless condition eliminate (%s)\n", ruby_node_name(nd_type(cond))); */
ADD_INSNL(ret, nd_line(cond), jump, else_label);
break;
default:
COMPILE(ret, "branch condition", cond);
ADD_INSNL(ret, nd_line(cond), branchunless, else_label);
@@ -2232,11 +2243,11 @@
static int
compile_array_(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE* node_root,
VALUE opt_p, int poped)
{
NODE *node = node_root;
- int len = node->nd_alen, line = nd_line(node), i=0;
+ int len = (int)node->nd_alen, line = (int)nd_line(node), i=0;
DECL_ANCHOR(anchor);
INIT_ANCHOR(anchor);
if (nd_type(node) != NODE_ZARRAY) {
while (node) {
@@ -2268,11 +2279,11 @@
node = node_root;
while (node) {
rb_ary_push(ary, node->nd_head->nd_lit);
node = node->nd_next;
}
-
+ OBJ_FREEZE(ary);
iseq_add_mark_object_compile_time(iseq, ary);
ADD_INSN1(ret, nd_line(node_root), duparray, ary);
}
}
else {
@@ -2345,11 +2356,11 @@
COMPILE_POPED(ret, "masgn lhs (NODE_ATTRASGN)", node);
POP_ELEMENT(ret); /* pop pop insn */
iobj = (INSN *)POP_ELEMENT(ret); /* pop send insn */
dupidx = iobj->operands[1];
- dupidx = INT2FIX(FIX2INT(dupidx) + 1);
+ dupidx = FIXNUM_INC(dupidx, 1);
iobj->operands[1] = dupidx;
ADD_INSN1(ret, nd_line(node), topn, dupidx);
ADD_ELEM(ret, (LINK_ELEMENT *)iobj);
ADD_INSN(ret, nd_line(node), pop); /* result */
@@ -2388,11 +2399,11 @@
static int
compile_massign_opt(rb_iseq_t *iseq, LINK_ANCHOR *ret,
NODE *rhsn, NODE *orig_lhsn)
{
VALUE mem[64];
- const int memsize = sizeof(mem) / sizeof(mem[0]);
+ const int memsize = numberof(mem);
int memindex = 0;
int llen = 0, rlen = 0;
int i;
NODE *lhsn = orig_lhsn;
@@ -2429,11 +2440,11 @@
llen++;
}
while (rhsn) {
if (llen <= rlen) {
- COMPILE_POPED(ret, "masgn val (poped)", rhsn->nd_head);
+ COMPILE_POPED(ret, "masgn val (popped)", rhsn->nd_head);
}
else {
COMPILE(ret, "masgn val", rhsn->nd_head);
}
rhsn = rhsn->nd_next;
@@ -2483,11 +2494,11 @@
if (lhs_splat) {
if (nd_type(splatn) == NODE_POSTARG) {
/*a, b, *r, p1, p2 */
NODE *postn = splatn->nd_2nd;
NODE *restn = splatn->nd_1st;
- int num = postn->nd_alen;
+ int num = (int)postn->nd_alen;
int flag = 0x02 | (((VALUE)restn == (VALUE)-1) ? 0x00 : 0x01);
ADD_INSN2(ret, nd_line(splatn), expandarray,
INT2FIX(num), INT2FIX(flag));
@@ -2548,11 +2559,12 @@
COMPILE(ret, "nd_else->nd_head", cpath->nd_head);
return Qfalse;
}
else {
/* class at cbase Foo */
- ADD_INSN1(ret, nd_line(cpath), putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CBASE));
+ ADD_INSN1(ret, nd_line(cpath), putspecialobject,
+ INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE));
return Qtrue;
}
}
static int
@@ -2612,11 +2624,11 @@
return 1;
case NODE_GVAR:
ADD_INSN(ret, nd_line(node), putnil);
ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_GVAR),
- ((VALUE)node->nd_entry) | 1, needstr);
+ ID2SYM(node->nd_entry->id), needstr);
return 1;
case NODE_CVAR:
ADD_INSN(ret, nd_line(node), putnil);
ADD_INSN3(ret, nd_line(node), defined, INT2FIX(DEFINED_CVAR),
@@ -2655,17 +2667,17 @@
/* method dispatch */
case NODE_CALL:
case NODE_VCALL:
case NODE_FCALL:
case NODE_ATTRASGN:{
- int self = Qtrue;
+ int self = TRUE;
switch (type) {
case NODE_ATTRASGN:
if (node->nd_recv == (NODE *)1) break;
case NODE_CALL:
- self = Qfalse;
+ self = FALSE;
break;
default:
/* through */;
}
if (!lfinish[1]) {
@@ -2680,11 +2692,11 @@
LABEL *lend = NEW_LABEL(nd_line(node));
VALUE rescue = NEW_CHILD_ISEQVAL(NEW_NIL(),
rb_str_concat(rb_str_new2
("defined guard in "),
iseq->name),
- ISEQ_TYPE_DEFINED_GUARD);
+ ISEQ_TYPE_DEFINED_GUARD, 0);
defined_expr(iseq, ret, node->nd_recv, lfinish, Qfalse);
ADD_INSNL(ret, nd_line(node), branchunless, lfinish[1]);
ADD_LABEL(ret, lstart);
@@ -2949,11 +2961,11 @@
ADD_INSN(ret, iseq->compile_data->last_line, putnil);
}
return COMPILE_OK;
}
- iseq->compile_data->last_line = nd_line(node);
+ iseq->compile_data->last_line = (int)nd_line(node);
debug_node_start(node);
type = nd_type(node);
if (node->flags & NODE_FL_NEWLINE) {
@@ -3008,11 +3020,11 @@
NODE *tempnode = node;
LABEL *endlabel, *elselabel;
DECL_ANCHOR(head);
DECL_ANCHOR(body_seq);
DECL_ANCHOR(cond_seq);
- VALUE special_literals = rb_ary_new();
+ VALUE special_literals = rb_ary_tmp_new(1);
INIT_ANCHOR(head);
INIT_ANCHOR(body_seq);
INIT_ANCHOR(cond_seq);
if (node->nd_head == 0) {
@@ -3115,45 +3127,35 @@
ADD_LABEL(body_seq, l1);
COMPILE_(body_seq, "when", node->nd_body, poped);
ADD_INSNL(body_seq, nd_line(node), jump, endlabel);
vals = node->nd_head;
- if (vals && nd_type(vals) == NODE_ARRAY) {
+ if (!vals) {
+ rb_bug("NODE_WHEN: must be NODE_ARRAY, but 0");
+ }
+ switch (nd_type(vals)) {
+ case NODE_ARRAY:
while (vals) {
val = vals->nd_head;
COMPILE(ret, "when2", val);
ADD_INSNL(ret, nd_line(val), branchif, l1);
vals = vals->nd_next;
}
+ break;
+ case NODE_SPLAT:
+ case NODE_ARGSCAT:
+ case NODE_ARGSPUSH:
+ ADD_INSN(ret, nd_line(vals), putnil);
+ COMPILE(ret, "when2/cond splat", vals);
+ ADD_INSN1(ret, nd_line(vals), checkincludearray, Qfalse);
+ ADD_INSN(ret, nd_line(vals), pop);
+ ADD_INSNL(ret, nd_line(vals), branchif, l1);
+ break;
+ default:
+ rb_bug("NODE_WHEN: unknown node (%s)",
+ ruby_node_name(nd_type(vals)));
}
- else if (nd_type(vals) == NODE_SPLAT ||
- nd_type(vals) == NODE_ARGSCAT ||
- nd_type(vals) == NODE_ARGSPUSH) {
-
- NODE *val = vals->nd_head;
-
- if (nd_type(vals) == NODE_ARGSCAT || nd_type(vals) == NODE_ARGSPUSH) {
- NODE *vs = vals->nd_head;
- val = vals->nd_body;
-
- while (vs) {
- NODE* val = vs->nd_head;
- COMPILE(ret, "when/argscat", val);
- ADD_INSNL(ret, nd_line(val), branchif, l1);
- vs = vs->nd_next;
- }
- }
-
- ADD_INSN(ret, nd_line(val), putnil);
- COMPILE(ret, "when2/splat", val);
- ADD_INSN1(ret, nd_line(val), checkincludearray, Qfalse);
- ADD_INSN(ret, nd_line(val), pop);
- ADD_INSNL(ret, nd_line(val), branchif, l1);
- }
- else {
- rb_bug("err");
- }
node = node->nd_next;
}
/* else */
COMPILE_(ret, "else", node, poped);
ADD_INSNL(ret, nd_line(orig_node), jump, endlabel);
@@ -3167,11 +3169,11 @@
case NODE_WHILE:
case NODE_UNTIL:{
LABEL *prev_start_label = iseq->compile_data->start_label;
LABEL *prev_end_label = iseq->compile_data->end_label;
LABEL *prev_redo_label = iseq->compile_data->redo_label;
- VALUE prev_loopval_popped = iseq->compile_data->loopval_popped;
+ int prev_loopval_popped = iseq->compile_data->loopval_popped;
struct iseq_compile_data_ensure_node_stack enl;
LABEL *next_label = iseq->compile_data->start_label = NEW_LABEL(nd_line(node)); /* next */
LABEL *redo_label = iseq->compile_data->redo_label = NEW_LABEL(nd_line(node)); /* redo */
@@ -3258,20 +3260,20 @@
if (nd_type(node) == NODE_FOR) {
COMPILE(ret, "iter caller (for)", node->nd_iter);
iseq->compile_data->current_block =
NEW_CHILD_ISEQVAL(node->nd_body, make_name_for_block(iseq),
- ISEQ_TYPE_BLOCK);
+ ISEQ_TYPE_BLOCK, nd_line(node));
mid = idEach;
ADD_SEND_R(ret, nd_line(node), ID2SYM(idEach), INT2FIX(0),
iseq->compile_data->current_block, INT2FIX(0));
}
else {
iseq->compile_data->current_block =
NEW_CHILD_ISEQVAL(node->nd_body, make_name_for_block(iseq),
- ISEQ_TYPE_BLOCK);
+ ISEQ_TYPE_BLOCK, nd_line(node));
COMPILE(ret, "iter caller", node->nd_iter);
}
ADD_LABEL(ret, retry_end_l);
if (poped) {
@@ -3355,10 +3357,13 @@
COMPILE(ret, "next val/valid syntax?", node->nd_stts);
add_ensure_iseq(ret, iseq, 0);
ADD_ADJUST(ret, nd_line(node), iseq->compile_data->redo_label);
ADD_INSNL(ret, nd_line(node), jump, iseq->compile_data->start_label);
ADD_ADJUST_RESTORE(ret, splabel);
+ if (!poped) {
+ ADD_INSN(ret, nd_line(node), putnil);
+ }
}
else if (iseq->compile_data->end_label) {
LABEL *splabel = NEW_LABEL(0);
debugs("next in block\n");
ADD_LABEL(ret, splabel);
@@ -3420,10 +3425,13 @@
ADD_LABEL(ret, splabel);
ADD_ADJUST(ret, nd_line(node), iseq->compile_data->redo_label);
add_ensure_iseq(ret, iseq, 0);
ADD_INSNL(ret, nd_line(node), jump, iseq->compile_data->redo_label);
ADD_ADJUST_RESTORE(ret, splabel);
+ if (!poped) {
+ ADD_INSN(ret, nd_line(node), putnil);
+ }
}
else if (iseq->type == ISEQ_TYPE_EVAL) {
redo_in_eval:
COMPILE_ERROR((ERROR_ARGS "Can't escape from eval with redo"));
}
@@ -3501,11 +3509,11 @@
LABEL *lend = NEW_LABEL(nd_line(node));
LABEL *lcont = NEW_LABEL(nd_line(node));
VALUE rescue = NEW_CHILD_ISEQVAL(
node->nd_resq,
rb_str_concat(rb_str_new2("rescue in "), iseq->name),
- ISEQ_TYPE_RESCUE);
+ ISEQ_TYPE_RESCUE, nd_line(node));
ADD_LABEL(ret, lstart);
COMPILE(ret, "rescue head", node->nd_head);
ADD_LABEL(ret, lend);
if (node->nd_else) {
@@ -3517,11 +3525,11 @@
if (poped) {
ADD_INSN(ret, nd_line(node), pop);
}
- /* resgister catch entry */
+ /* register catch entry */
ADD_CATCH_ENTRY(CATCH_TYPE_RESCUE, lstart, lend, rescue, lcont);
ADD_CATCH_ENTRY(CATCH_TYPE_RETRY, lend, lcont, 0, lstart);
break;
}
case NODE_RESBODY:{
@@ -3583,11 +3591,11 @@
DECL_ANCHOR(ensr);
VALUE ensure = NEW_CHILD_ISEQVAL(node->nd_ensr,
rb_str_concat(rb_str_new2
("ensure in "),
iseq->name),
- ISEQ_TYPE_ENSURE);
+ ISEQ_TYPE_ENSURE, nd_line(node));
LABEL *lstart = NEW_LABEL(nd_line(node));
LABEL *lend = NEW_LABEL(nd_line(node));
LABEL *lcont = NEW_LABEL(nd_line(node));
struct ensure_range er;
struct iseq_compile_data_ensure_node_stack enl;
@@ -3697,23 +3705,24 @@
case NODE_IASGN2:{
COMPILE(ret, "lvalue", node->nd_value);
if (!poped) {
ADD_INSN(ret, nd_line(node), dup);
}
- ADD_INSN1(ret, nd_line(node), setinstancevariable,
- ID2SYM(node->nd_vid));
+ ADD_INSN2(ret, nd_line(node), setinstancevariable,
+ ID2SYM(node->nd_vid), INT2FIX(iseq->ic_size++));
break;
}
case NODE_CDECL:{
COMPILE(ret, "lvalue", node->nd_value);
if (!poped) {
ADD_INSN(ret, nd_line(node), dup);
}
if (node->nd_vid) {
- ADD_INSN1(ret, nd_line(node), putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CBASE));
+ ADD_INSN1(ret, nd_line(node), putspecialobject,
+ INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE));
ADD_INSN1(ret, nd_line(node), setconstant, ID2SYM(node->nd_vid));
}
else {
compile_cpath(ret, iseq, node->nd_else);
ADD_INSN1(ret, nd_line(node), setconstant, ID2SYM(node->nd_else->nd_mid));
@@ -3732,41 +3741,51 @@
case NODE_OP_ASGN1: {
DECL_ANCHOR(args);
VALUE argc;
unsigned long flag = 0;
ID id = node->nd_mid;
+ int boff = 0;
/*
* a[x] (op)= y
*
- * eval a # a
- * eval x # a x
- * dupn 2 # a x a x
- * send :[] # a x a[x]
- * eval y # a x a[x] y
- * send op # a x a[x]+y
- * send []= # ret
+ * nil # nil
+ * eval a # nil a
+ * eval x # nil a x
+ * dupn 2 # nil a x a x
+ * send :[] # nil a x a[x]
+ * eval y # nil a x a[x] y
+ * send op # nil a x ret
+ * setn 3 # ret a x ret
+ * send []= # ret ?
+ * pop # ret
*/
/*
* nd_recv[nd_args->nd_body] (nd_mid)= nd_args->nd_head;
* NODE_OP_ASGN nd_recv
* nd_args->nd_head
* nd_args->nd_body
* nd_mid
*/
+ if (!poped) {
+ ADD_INSN(ret, nd_line(node), putnil);
+ }
COMPILE(ret, "NODE_OP_ASGN1 recv", node->nd_recv);
- if (nd_type(node->nd_args->nd_body) != NODE_ZARRAY) {
+ switch (nd_type(node->nd_args->nd_head)) {
+ case NODE_ZARRAY:
+ argc = INT2FIX(0);
+ break;
+ case NODE_BLOCK_PASS:
+ boff = 1;
+ default:
INIT_ANCHOR(args);
- argc = setup_args(iseq, args, node->nd_args->nd_body, &flag);
+ argc = setup_args(iseq, args, node->nd_args->nd_head, &flag);
ADD_SEQ(ret, args);
}
- else {
- argc = INT2FIX(0);
- }
- ADD_INSN1(ret, nd_line(node), dupn, INT2FIX(FIX2INT(argc)+1));
+ ADD_INSN1(ret, nd_line(node), dupn, FIXNUM_INC(argc, 1 + boff));
ADD_SEND_R(ret, nd_line(node), ID2SYM(idAREF), argc, Qfalse, LONG2FIX(flag));
if (id == 0 || id == 1) {
/* 0: or, 1: and
a[x] ||= y
@@ -3778,60 +3797,84 @@
end
*/
LABEL *label = NEW_LABEL(nd_line(node));
LABEL *lfin = NEW_LABEL(nd_line(node));
+ ADD_INSN(ret, nd_line(node), dup);
if (id == 0) {
/* or */
- ADD_INSN(ret, nd_line(node), dup);
ADD_INSNL(ret, nd_line(node), branchif, label);
- ADD_INSN(ret, nd_line(node), pop);
}
else {
/* and */
- ADD_INSN(ret, nd_line(node), dup);
ADD_INSNL(ret, nd_line(node), branchunless, label);
- ADD_INSN(ret, nd_line(node), pop);
}
+ ADD_INSN(ret, nd_line(node), pop);
- COMPILE(ret, "NODE_OP_ASGN1 args->head: ", node->nd_args->nd_head);
+ COMPILE(ret, "NODE_OP_ASGN1 args->body: ", node->nd_args->nd_body);
+ if (!poped) {
+ ADD_INSN1(ret, nd_line(node), setn, FIXNUM_INC(argc, 2+boff));
+ }
if (flag & VM_CALL_ARGS_SPLAT_BIT) {
ADD_INSN1(ret, nd_line(node), newarray, INT2FIX(1));
+ if (boff > 0) {
+ ADD_INSN1(ret, nd_line(node), dupn, INT2FIX(3));
+ ADD_INSN(ret, nd_line(node), swap);
+ ADD_INSN(ret, nd_line(node), pop);
+ }
ADD_INSN(ret, nd_line(node), concatarray);
+ if (boff > 0) {
+ ADD_INSN1(ret, nd_line(node), setn, INT2FIX(3));
+ ADD_INSN(ret, nd_line(node), pop);
+ ADD_INSN(ret, nd_line(node), pop);
+ }
ADD_SEND_R(ret, nd_line(node), ID2SYM(idASET),
argc, Qfalse, LONG2FIX(flag));
}
else {
+ if (boff > 0)
+ ADD_INSN(ret, nd_line(node), swap);
ADD_SEND_R(ret, nd_line(node), ID2SYM(idASET),
- INT2FIX(FIX2INT(argc) + 1), Qfalse, LONG2FIX(flag));
+ FIXNUM_INC(argc, 1), Qfalse, LONG2FIX(flag));
}
+ ADD_INSN(ret, nd_line(node), pop);
ADD_INSNL(ret, nd_line(node), jump, lfin);
ADD_LABEL(ret, label);
- if (id == 0 || id == 1) { /* 0: or, 1: and */
- ADD_INSN(ret, nd_line(node), swap);
- ADD_INSN(ret, nd_line(node), pop);
- ADD_INSN(ret, nd_line(node), swap);
- ADD_INSN(ret, nd_line(node), pop);
+ if (!poped) {
+ ADD_INSN1(ret, nd_line(node), setn, FIXNUM_INC(argc, 2+boff));
}
+ ADD_INSN1(ret, nd_line(node), adjuststack, FIXNUM_INC(argc, 2+boff));
ADD_LABEL(ret, lfin);
}
else {
- COMPILE(ret, "NODE_OP_ASGN1 args->head: ", node->nd_args->nd_head);
+ COMPILE(ret, "NODE_OP_ASGN1 args->body: ", node->nd_args->nd_body);
ADD_SEND(ret, nd_line(node), ID2SYM(id), INT2FIX(1));
+ if (!poped) {
+ ADD_INSN1(ret, nd_line(node), setn, FIXNUM_INC(argc, 2+boff));
+ }
if (flag & VM_CALL_ARGS_SPLAT_BIT) {
ADD_INSN1(ret, nd_line(node), newarray, INT2FIX(1));
+ if (boff > 0) {
+ ADD_INSN1(ret, nd_line(node), dupn, INT2FIX(3));
+ ADD_INSN(ret, nd_line(node), swap);
+ ADD_INSN(ret, nd_line(node), pop);
+ }
ADD_INSN(ret, nd_line(node), concatarray);
+ if (boff > 0) {
+ ADD_INSN1(ret, nd_line(node), setn, INT2FIX(3));
+ ADD_INSN(ret, nd_line(node), pop);
+ ADD_INSN(ret, nd_line(node), pop);
+ }
ADD_SEND_R(ret, nd_line(node), ID2SYM(idASET),
argc, Qfalse, LONG2FIX(flag));
}
else {
+ if (boff > 0)
+ ADD_INSN(ret, nd_line(node), swap);
ADD_SEND_R(ret, nd_line(node), ID2SYM(idASET),
- INT2FIX(FIX2INT(argc) + 1), Qfalse, LONG2FIX(flag));
+ FIXNUM_INC(argc, 1), Qfalse, LONG2FIX(flag));
}
- }
-
- if (poped) {
ADD_INSN(ret, nd_line(node), pop);
}
break;
}
@@ -3851,26 +3894,30 @@
# or
dup # r o o
if lcfin # r o
pop # r
eval v # r v
- send a= # v
- jump lfin # v
+ swap # v r
+ topn 1 # v r v
+ send a= # v ?
+ jump lfin # v ?
lcfin: # r o
swap # o r
+
+ lfin: # o ?
pop # o
- lfin: # v
-
# and
dup # r o o
unless lcfin
pop # r
eval v # r v
- send a= # v
- jump lfin # v
+ swap # v r
+ topn 1 # v r v
+ send a= # v ?
+ jump lfin # v ?
# others
eval v # r o v
send ?? # r w
send a= # w
@@ -3890,30 +3937,36 @@
else {
ADD_INSNL(ret, nd_line(node), branchunless, lcfin);
}
ADD_INSN(ret, nd_line(node), pop);
COMPILE(ret, "NODE_OP_ASGN2 val", node->nd_value);
+ ADD_INSN(ret, nd_line(node), swap);
+ ADD_INSN1(ret, nd_line(node), topn, INT2FIX(1));
ADD_SEND(ret, nd_line(node), ID2SYM(node->nd_next->nd_aid),
INT2FIX(1));
ADD_INSNL(ret, nd_line(node), jump, lfin);
ADD_LABEL(ret, lcfin);
ADD_INSN(ret, nd_line(node), swap);
- ADD_INSN(ret, nd_line(node), pop);
ADD_LABEL(ret, lfin);
+ ADD_INSN(ret, nd_line(node), pop);
+ if (poped) {
+ /* we can apply more optimize */
+ ADD_INSN(ret, nd_line(node), pop);
+ }
}
else {
COMPILE(ret, "NODE_OP_ASGN2 val", node->nd_value);
ADD_SEND(ret, nd_line(node), ID2SYM(node->nd_next->nd_mid),
INT2FIX(1));
+ if (!poped) {
+ ADD_INSN(ret, nd_line(node), swap);
+ ADD_INSN1(ret, nd_line(node), topn, INT2FIX(1));
+ }
ADD_SEND(ret, nd_line(node), ID2SYM(node->nd_next->nd_aid),
INT2FIX(1));
- }
-
- if (poped) {
- /* we can apply more optimize */
ADD_INSN(ret, nd_line(node), pop);
}
break;
}
case NODE_OP_ASGN_AND:
@@ -3991,11 +4044,10 @@
ID goto_id;
ID label_id;
VALUE label;
VALUE label_sym;
-
CONST_ID(goto_id, "__goto__");
CONST_ID(label_id, "__label__");
if (nd_type(node) == NODE_FCALL &&
(mid == goto_id || mid == label_id)) {
@@ -4023,11 +4075,11 @@
}
break;
}
}
#endif
- /* reciever */
+ /* receiver */
if (type == NODE_CALL) {
COMPILE(recv, "recv", node->nd_recv);
}
else if (type == NODE_FCALL || type == NODE_VCALL) {
ADD_CALL_RECEIVER(recv, nd_line(node));
@@ -4133,11 +4185,11 @@
}
}
}
}
- /* dummy reciever */
+ /* dummy receiver */
ADD_INSN1(ret, nd_line(node), putobject,
nd_type(node) == NODE_ZSUPER ? Qfalse : Qtrue);
ADD_SEQ(ret, args);
ADD_INSN3(ret, nd_line(node), invokesuper,
argc, parent_block, LONG2FIX(flag));
@@ -4198,14 +4250,13 @@
break;
}
case NODE_RETURN:{
rb_iseq_t *is = iseq;
- while (is) {
- if (is->type == ISEQ_TYPE_TOP || is->type == ISEQ_TYPE_CLASS) {
+ if (is) {
+ if (is->type == ISEQ_TYPE_TOP) {
COMPILE_ERROR((ERROR_ARGS "Invalid return"));
- break;
}
else {
LABEL *splabel = 0;
if (is->type == ISEQ_TYPE_METHOD) {
@@ -4216,10 +4267,11 @@
COMPILE(ret, "return nd_stts (return val)", node->nd_stts);
if (is->type == ISEQ_TYPE_METHOD) {
add_ensure_iseq(ret, iseq, 1);
+ ADD_TRACE(ret, nd_line(node), RUBY_EVENT_RETURN);
ADD_INSN(ret, nd_line(node), leave);
ADD_ADJUST_RESTORE(ret, splabel);
if (!poped) {
ADD_INSN(ret, nd_line(node), putnil);
@@ -4229,22 +4281,21 @@
ADD_INSN1(ret, nd_line(node), throw, INT2FIX(0x01) /* TAG_RETURN */ );
if (poped) {
ADD_INSN(ret, nd_line(node), pop);
}
}
- break;
}
}
break;
}
case NODE_YIELD:{
DECL_ANCHOR(args);
VALUE argc;
unsigned long flag = 0;
INIT_ANCHOR(args);
- if (iseq->type == ISEQ_TYPE_TOP || iseq->type == ISEQ_TYPE_CLASS) {
+ if (iseq->type == ISEQ_TYPE_TOP) {
COMPILE_ERROR((ERROR_ARGS "Invalid yield"));
}
if (node->nd_head) {
argc = setup_args(iseq, args, node->nd_head, &flag);
@@ -4292,26 +4343,25 @@
break;
}
case NODE_IVAR:{
debugi("nd_vid", node->nd_vid);
if (!poped) {
- ADD_INSN1(ret, nd_line(node), getinstancevariable,
- ID2SYM(node->nd_vid));
+ ADD_INSN2(ret, nd_line(node), getinstancevariable,
+ ID2SYM(node->nd_vid), INT2FIX(iseq->ic_size++));
}
break;
}
case NODE_CONST:{
debugi("nd_vid", node->nd_vid);
if (iseq->compile_data->option->inline_const_cache) {
- LABEL *lstart = NEW_LABEL(nd_line(node));
LABEL *lend = NEW_LABEL(nd_line(node));
+ int ic_index = iseq->ic_size++;
- ADD_LABEL(ret, lstart);
- ADD_INSN2(ret, nd_line(node), getinlinecache, 0, lend);
+ ADD_INSN2(ret, nd_line(node), getinlinecache, lend, INT2FIX(ic_index));
ADD_INSN1(ret, nd_line(node), getconstant, ID2SYM(node->nd_vid));
- ADD_INSN1(ret, nd_line(node), setinlinecache, lstart);
+ ADD_INSN1(ret, nd_line(node), setinlinecache, INT2FIX(ic_index));
ADD_LABEL(ret, lend);
}
else {
ADD_INSN(ret, nd_line(node), putnil);
ADD_INSN1(ret, nd_line(node), getconstant, ID2SYM(node->nd_vid));
@@ -4356,15 +4406,15 @@
ADD_INSN1(recv, nd_line(node), putobject, node->nd_lit);
ADD_INSN2(val, nd_line(node), getspecial, INT2FIX(0),
INT2FIX(0));
break;
case NODE_MATCH2:
- COMPILE(recv, "reciever", node->nd_recv);
+ COMPILE(recv, "receiver", node->nd_recv);
COMPILE(val, "value", node->nd_value);
break;
case NODE_MATCH3:
- COMPILE(recv, "reciever", node->nd_value);
+ COMPILE(recv, "receiver", node->nd_value);
COMPILE(val, "value", node->nd_recv);
break;
}
if (iseq->compile_data->option->specialized_instruction) {
@@ -4401,11 +4451,11 @@
break;
}
case NODE_STR:{
debugp_param("nd_lit", node->nd_lit);
if (!poped) {
- hide_obj(node->nd_lit);
+ OBJ_FREEZE(node->nd_lit);
ADD_INSN1(ret, nd_line(node), putstring, node->nd_lit);
}
break;
}
case NODE_DSTR:{
@@ -4415,10 +4465,11 @@
ADD_INSN(ret, nd_line(node), pop);
}
break;
}
case NODE_XSTR:{
+ OBJ_FREEZE(node->nd_lit);
ADD_CALL_RECEIVER(ret, nd_line(node));
ADD_INSN1(ret, nd_line(node), putobject, node->nd_lit);
ADD_CALL(ret, nd_line(node), ID2SYM(idBackquote), INT2FIX(1));
if (poped) {
@@ -4455,38 +4506,55 @@
}
break;
}
case NODE_DREGX_ONCE:{
/* TODO: once? */
- LABEL *lstart = NEW_LABEL(nd_line(node));
LABEL *lend = NEW_LABEL(nd_line(node));
+ int ic_index = iseq->ic_size++;
- ADD_LABEL(ret, lstart);
- ADD_INSN2(ret, nd_line(node), onceinlinecache, 0, lend);
+ ADD_INSN2(ret, nd_line(node), onceinlinecache, lend, INT2FIX(ic_index));
ADD_INSN(ret, nd_line(node), pop);
compile_dregx(iseq, ret, node);
- ADD_INSN1(ret, nd_line(node), setinlinecache, lstart);
+ ADD_INSN1(ret, nd_line(node), setinlinecache, INT2FIX(ic_index));
ADD_LABEL(ret, lend);
if (poped) {
ADD_INSN(ret, nd_line(node), pop);
}
break;
}
case NODE_ARGSCAT:{
- COMPILE(ret, "argscat head", node->nd_head);
- COMPILE(ret, "argscat body", node->nd_body);
- ADD_INSN(ret, nd_line(node), concatarray);
+ if (poped) {
+ COMPILE(ret, "argscat head", node->nd_head);
+ ADD_INSN1(ret, nd_line(node), splatarray, Qfalse);
+ ADD_INSN(ret, nd_line(node), pop);
+ COMPILE(ret, "argscat body", node->nd_body);
+ ADD_INSN1(ret, nd_line(node), splatarray, Qfalse);
+ ADD_INSN(ret, nd_line(node), pop);
+ }
+ else {
+ COMPILE(ret, "argscat head", node->nd_head);
+ COMPILE(ret, "argscat body", node->nd_body);
+ ADD_INSN(ret, nd_line(node), concatarray);
+ }
break;
}
case NODE_ARGSPUSH:{
- COMPILE(ret, "arsgpush head", node->nd_head);
- COMPILE(ret, "argspush body", node->nd_body);
- ADD_INSN1(ret, nd_line(node), newarray, INT2FIX(1));
- ADD_INSN(ret, nd_line(node), concatarray);
+ if (poped) {
+ COMPILE(ret, "arsgpush head", node->nd_head);
+ ADD_INSN1(ret, nd_line(node), splatarray, Qfalse);
+ ADD_INSN(ret, nd_line(node), pop);
+ COMPILE_(ret, "argspush body", node->nd_body, poped);
+ }
+ else {
+ COMPILE(ret, "arsgpush head", node->nd_head);
+ COMPILE_(ret, "argspush body", node->nd_body, poped);
+ ADD_INSN1(ret, nd_line(node), newarray, INT2FIX(1));
+ ADD_INSN(ret, nd_line(node), concatarray);
+ }
break;
}
case NODE_SPLAT:{
COMPILE(ret, "splat", node->nd_head);
ADD_INSN1(ret, nd_line(node), splatarray, Qfalse);
@@ -4497,11 +4565,11 @@
break;
}
case NODE_DEFN:{
VALUE iseqval = NEW_ISEQVAL(node->nd_defn,
rb_str_dup(rb_id2str(node->nd_mid)),
- ISEQ_TYPE_METHOD);
+ ISEQ_TYPE_METHOD, nd_line(node));
debugp_param("defn/iseq", iseqval);
ADD_INSN1(ret, nd_line(node), putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
ADD_INSN1(ret, nd_line(node), putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CBASE));
@@ -4517,11 +4585,11 @@
break;
}
case NODE_DEFS:{
VALUE iseqval = NEW_ISEQVAL(node->nd_defn,
rb_str_dup(rb_id2str(node->nd_mid)),
- ISEQ_TYPE_METHOD);
+ ISEQ_TYPE_METHOD, nd_line(node));
debugp_param("defs/iseq", iseqval);
ADD_INSN1(ret, nd_line(node), putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
COMPILE(ret, "defs: recv", node->nd_recv);
@@ -4571,11 +4639,11 @@
case NODE_CLASS:{
VALUE iseqval =
NEW_CHILD_ISEQVAL(
node->nd_body,
rb_sprintf("<class:%s>", rb_id2name(node->nd_cpath->nd_mid)),
- ISEQ_TYPE_CLASS);
+ ISEQ_TYPE_CLASS, nd_line(node));
compile_cpath(ret, iseq, node->nd_cpath);
COMPILE(ret, "super", node->nd_super);
ADD_INSN3(ret, nd_line(node), defineclass,
ID2SYM(node->nd_cpath->nd_mid), iseqval, INT2FIX(0));
@@ -4586,11 +4654,11 @@
}
case NODE_MODULE:{
VALUE iseqval = NEW_CHILD_ISEQVAL(
node->nd_body,
rb_sprintf("<module:%s>", rb_id2name(node->nd_cpath->nd_mid)),
- ISEQ_TYPE_CLASS);
+ ISEQ_TYPE_CLASS, nd_line(node));
compile_cpath(ret, iseq, node->nd_cpath);
ADD_INSN (ret, nd_line(node), putnil); /* dummy */
ADD_INSN3(ret, nd_line(node), defineclass,
ID2SYM(node->nd_cpath->nd_mid), iseqval, INT2FIX(2));
@@ -4601,11 +4669,11 @@
}
case NODE_SCLASS:{
ID singletonclass;
VALUE iseqval =
NEW_ISEQVAL(node->nd_body, rb_str_new2("singletonclass"),
- ISEQ_TYPE_CLASS);
+ ISEQ_TYPE_CLASS, nd_line(node));
COMPILE(ret, "sclass#recv", node->nd_recv);
ADD_INSN (ret, nd_line(node), putnil);
CONST_ID(singletonclass, "singletonclass");
ADD_INSN3(ret, nd_line(node), defineclass,
@@ -4617,31 +4685,31 @@
break;
}
case NODE_COLON2:{
if (rb_is_const_id(node->nd_mid)) {
/* constant */
- LABEL *lstart = NEW_LABEL(nd_line(node));
LABEL *lend = NEW_LABEL(nd_line(node));
+ int ic_index = iseq->ic_size++;
+
DECL_ANCHOR(pref);
DECL_ANCHOR(body);
INIT_ANCHOR(pref);
INIT_ANCHOR(body);
compile_colon2(iseq, node, pref, body);
if (LIST_SIZE_ZERO(pref)) {
if (iseq->compile_data->option->inline_const_cache) {
- ADD_LABEL(ret, lstart);
- ADD_INSN2(ret, nd_line(node), getinlinecache, 0, lend);
+ ADD_INSN2(ret, nd_line(node), getinlinecache, lend, INT2FIX(ic_index));
}
else {
ADD_INSN(ret, nd_line(node), putnil);
}
ADD_SEQ(ret, body);
if (iseq->compile_data->option->inline_const_cache) {
- ADD_INSN1(ret, nd_line(node), setinlinecache, lstart);
+ ADD_INSN1(ret, nd_line(node), setinlinecache, INT2FIX(ic_index));
ADD_LABEL(ret, lend);
}
}
else {
ADD_SEQ(ret, pref);
@@ -4659,37 +4727,37 @@
ADD_INSN(ret, nd_line(node), pop);
}
break;
}
case NODE_COLON3:{
- LABEL *lstart = NEW_LABEL(nd_line(node));
LABEL *lend = NEW_LABEL(nd_line(node));
- debugi("colon3#nd_mid", node->nd_mid);
+ int ic_index = iseq->ic_size++;
+ debugi("colon3#nd_mid", node->nd_mid);
+
/* add cache insn */
if (iseq->compile_data->option->inline_const_cache) {
- ADD_LABEL(ret, lstart);
- ADD_INSN2(ret, nd_line(node), getinlinecache, 0, lend);
+ ADD_INSN2(ret, nd_line(node), getinlinecache, lend, INT2FIX(ic_index));
ADD_INSN(ret, nd_line(node), pop);
}
ADD_INSN1(ret, nd_line(node), putobject, rb_cObject);
ADD_INSN1(ret, nd_line(node), getconstant, ID2SYM(node->nd_mid));
if (iseq->compile_data->option->inline_const_cache) {
- ADD_INSN1(ret, nd_line(node), setinlinecache, lstart);
+ ADD_INSN1(ret, nd_line(node), setinlinecache, INT2FIX(ic_index));
ADD_LABEL(ret, lend);
}
if (poped) {
ADD_INSN(ret, nd_line(node), pop);
}
break;
}
case NODE_DOT2:
case NODE_DOT3:{
- int flag = type == NODE_DOT2 ? INT2FIX(0) : INT2FIX(1);
+ VALUE flag = type == NODE_DOT2 ? INT2FIX(0) : INT2FIX(1);
COMPILE(ret, "min", (NODE *) node->nd_beg);
COMPILE(ret, "max", (NODE *) node->nd_end);
if (poped) {
ADD_INSN(ret, nd_line(node), pop);
ADD_INSN(ret, nd_line(node), pop);
@@ -4706,10 +4774,11 @@
LABEL *ltrue = NEW_LABEL(nd_line(node));
VALUE key = rb_sprintf("flipflag/%s-%p-%d",
RSTRING_PTR(iseq->name), (void *)iseq,
iseq->compile_data->flip_cnt++);
+ hide_obj(key);
iseq_add_mark_object_compile_time(iseq, key);
ADD_INSN2(ret, nd_line(node), getspecial, key, INT2FIX(0));
ADD_INSNL(ret, nd_line(node), branchif, lend);
/* *flip == 0 */
@@ -4790,34 +4859,34 @@
case NODE_DEFINED:{
if (!poped) {
LABEL *lfinish[2];
lfinish[0] = NEW_LABEL(nd_line(node));
lfinish[1] = 0;
+ ADD_INSN(ret, nd_line(node), putnil);
defined_expr(iseq, ret, node->nd_head, lfinish, Qtrue);
+ ADD_INSN(ret, nd_line(node), swap);
+ ADD_INSN(ret, nd_line(node), pop);
if (lfinish[1]) {
- ADD_INSNL(ret, nd_line(node), jump, lfinish[0]);
ADD_LABEL(ret, lfinish[1]);
- ADD_INSN(ret, nd_line(node), putnil);
}
ADD_LABEL(ret, lfinish[0]);
}
break;
}
case NODE_POSTEXE:{
- LABEL *lstart = NEW_LABEL(nd_line(node));
LABEL *lend = NEW_LABEL(nd_line(node));
- VALUE block = NEW_CHILD_ISEQVAL(node->nd_body, make_name_for_block(iseq), ISEQ_TYPE_BLOCK);
+ VALUE block = NEW_CHILD_ISEQVAL(node->nd_body, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, nd_line(node));
+ int ic_index = iseq->ic_size++;
- ADD_LABEL(ret, lstart);
- ADD_INSN2(ret, nd_line(node), onceinlinecache, 0, lend);
+ ADD_INSN2(ret, nd_line(node), onceinlinecache, lend, INT2FIX(ic_index));
ADD_INSN(ret, nd_line(node), pop);
ADD_INSN1(ret, nd_line(node), putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
ADD_INSN1(ret, nd_line(node), putiseq, block);
ADD_SEND (ret, nd_line(node), ID2SYM(id_core_set_postexe), INT2FIX(1));
- ADD_INSN1(ret, nd_line(node), setinlinecache, lstart);
+ ADD_INSN1(ret, nd_line(node), setinlinecache, INT2FIX(ic_index));
ADD_LABEL(ret, lend);
if (poped) {
ADD_INSN(ret, nd_line(node), pop);
}
@@ -4859,17 +4928,17 @@
ADD_SEQ(ret, recv);
ADD_SEQ(ret, args);
if (flag & VM_CALL_ARGS_BLOCKARG_BIT) {
ADD_INSN1(ret, nd_line(node), topn, INT2FIX(1));
- ADD_INSN1(ret, nd_line(node), setn, INT2FIX(FIX2INT(argc) + 3));
+ ADD_INSN1(ret, nd_line(node), setn, FIXNUM_INC(argc, 3));
ADD_INSN (ret, nd_line(node), pop);
}
else {
- ADD_INSN1(ret, nd_line(node), setn, INT2FIX(FIX2INT(argc) + 1));
+ ADD_INSN1(ret, nd_line(node), setn, FIXNUM_INC(argc, 1));
+ }
}
- }
else {
ADD_SEQ(ret, recv);
ADD_SEQ(ret, args);
}
ADD_SEND_R(ret, nd_line(node), ID2SYM(node->nd_mid), argc, 0, LONG2FIX(flag));
@@ -4896,11 +4965,11 @@
COMPILE_(ret, "body", node->nd_body, poped);
break;
}
case NODE_LAMBDA:{
/* compile same as lambda{...} */
- VALUE block = NEW_CHILD_ISEQVAL(node->nd_body, make_name_for_block(iseq), ISEQ_TYPE_BLOCK);
+ VALUE block = NEW_CHILD_ISEQVAL(node->nd_body, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, nd_line(node));
VALUE argc = INT2FIX(0);
ADD_CALL_RECEIVER(ret, nd_line(node));
ADD_CALL_WITH_BLOCK(ret, nd_line(node), ID2SYM(idLambda), argc, block);
if (poped) {
@@ -4908,11 +4977,11 @@
}
break;
}
default:
rb_bug("iseq_compile_each: unknown node: %s", ruby_node_name(type));
- return Qnil;
+ return COMPILE_NG;
}
debug_node_end();
return COMPILE_OK;
}
@@ -4940,19 +5009,19 @@
}
static VALUE
insn_data_to_s_detail(INSN *iobj)
{
- VALUE str = rb_str_new(0, 0);
+ VALUE str = rb_sprintf("%-16s", insn_name(iobj->insn_id));
- str = rb_sprintf("%-16s", insn_name(iobj->insn_id));
if (iobj->operands) {
const char *types = insn_op_types(iobj->insn_id);
int j;
for (j = 0; types[j]; j++) {
char type = types[j];
+ printf("str: %"PRIxVALUE", type: %c\n", str, type);
switch (type) {
case TS_OFFSET: /* label(destination position) */
{
LABEL *lobj = (LABEL *)OPERAND_AT(iobj, j);
@@ -4979,16 +5048,16 @@
case TS_ID: /* ID */
rb_str_concat(str, rb_inspect(OPERAND_AT(iobj, j)));
break;
case TS_GENTRY:
{
- struct global_entry *entry = (struct global_entry *)
+ struct rb_global_entry *entry = (struct rb_global_entry *)
(OPERAND_AT(iobj, j) & (~1));
rb_str_cat2(str, rb_id2name(entry->id));
}
case TS_IC: /* method cache */
- rb_str_cat2(str, "<ic>");
+ rb_str_catf(str, "<ic:%d>", FIX2INT(OPERAND_AT(iobj, j)));
break;
case TS_CDHASH: /* case/when condition cache */
rb_str_cat2(str, "<ch>");
break;
default:{
@@ -5053,11 +5122,11 @@
VALUE
rb_insns_name_array(void)
{
VALUE ary = rb_ary_new();
int i;
- for (i = 0; i < sizeof(insn_name_info) / sizeof(insn_name_info[0]); i++) {
+ for (i = 0; i < numberof(insn_name_info); i++) {
rb_ary_push(ary, rb_obj_freeze(rb_str_new2(insn_name_info[i])));
}
return rb_obj_freeze(ary);
}
@@ -5081,10 +5150,11 @@
static VALUE
get_exception_sym2type(VALUE sym)
{
#undef rb_intern
#define rb_intern(str) rb_intern_const(str)
+ VALUE sym_inspect;
static VALUE symRescue, symEnsure, symRetry;
static VALUE symBreak, symRedo, symNext;
if (symRescue == 0) {
symRescue = ID2SYM(rb_intern("rescue"));
@@ -5099,12 +5169,13 @@
if (sym == symEnsure) return CATCH_TYPE_ENSURE;
if (sym == symRetry) return CATCH_TYPE_RETRY;
if (sym == symBreak) return CATCH_TYPE_BREAK;
if (sym == symRedo) return CATCH_TYPE_REDO;
if (sym == symNext) return CATCH_TYPE_NEXT;
+ sym_inspect = rb_inspect(sym);
rb_raise(rb_eSyntaxError, "invalid exception symbol: %s",
- RSTRING_PTR(rb_inspect(sym)));
+ StringValuePtr(sym_inspect));
return 0;
}
static int
iseq_build_exception(rb_iseq_t *iseq, struct st_table *labels_table,
@@ -5126,11 +5197,11 @@
type = get_exception_sym2type(ptr[0]);
if (ptr[1] == Qnil) {
eiseqval = 0;
}
else {
- eiseqval = ruby_iseq_load(ptr[1], iseq->self, Qnil);
+ eiseqval = rb_iseq_load(ptr[1], iseq->self, Qnil);
}
lstart = register_label(iseq, labels_table, ptr[2]);
lend = register_label(iseq, labels_table, ptr[3]);
lcont = register_label(iseq, labels_table, ptr[4]);
@@ -5157,14 +5228,14 @@
static int
iseq_build_body(rb_iseq_t *iseq, LINK_ANCHOR *anchor,
VALUE body, struct st_table *labels_table)
{
- /* TODO: body should be freezed */
+ /* TODO: body should be frozen */
VALUE *ptr = RARRAY_PTR(body);
- int len = RARRAY_LEN(body);
- int i, j;
+ long i, len = RARRAY_LEN(body);
+ int j;
int line_no = 0;
/*
* index -> LABEL *label
*/
static struct st_table *insn_table;
@@ -5183,11 +5254,11 @@
else if (FIXNUM_P(obj)) {
line_no = NUM2INT(obj);
}
else if (TYPE(obj) == T_ARRAY) {
VALUE *argv = 0;
- int argc = RARRAY_LEN(obj) - 1;
+ int argc = RARRAY_LENINT(obj) - 1;
VALUE insn_id;
VALUE insn;
insn = (argc < 0) ? Qnil : RARRAY_PTR(obj)[0];
if (st_lookup(insn_table, insn, &insn_id) == 0) {
@@ -5224,11 +5295,11 @@
break;
case TS_ISEQ:
{
if (op != Qnil) {
if (TYPE(op) == T_ARRAY) {
- argv[j] = ruby_iseq_load(op, iseq->self, Qnil);
+ argv[j] = rb_iseq_load(op, iseq->self, Qnil);
}
else if (CLASS_OF(op) == rb_cISeq) {
argv[j] = op;
}
else {
@@ -5244,12 +5315,13 @@
case TS_GENTRY:
op = rb_convert_type(op, T_SYMBOL, "Symbol", "to_sym");
argv[j] = (VALUE)rb_global_entry(SYM2ID(op));
break;
case TS_IC:
- argv[j] = (VALUE)NEW_INLINE_CACHE_ENTRY();
- iseq_add_mark_object(iseq, argv[j]);
+ argv[j] = op;
+ if (NUM2INT(op) >= iseq->ic_size)
+ iseq->ic_size = NUM2INT(op) + 1;
break;
case TS_ID:
argv[j] = rb_convert_type(op, T_SYMBOL,
"Symbol", "to_sym");
break;
@@ -5263,20 +5335,21 @@
LABEL *label =
register_label(iseq, labels_table, sym);
rb_ary_store(op, i+1, (VALUE)label | 1);
}
argv[j] = op;
+ iseq_add_mark_object_compile_time(iseq, op);
}
break;
default:
rb_raise(rb_eSyntaxError, "unknown operand: %c", insn_op_type(insn_id, j));
}
}
}
ADD_ELEM(anchor,
(LINK_ELEMENT*)new_insn_core(iseq, line_no,
- insn_id, argc, argv));
+ (enum ruby_vminsn_type)insn_id, argc, argv));
}
else {
rb_raise(rb_eTypeError, "unexpected object for instruction");
}
}
@@ -5288,29 +5361,34 @@
#define CHECK_ARRAY(v) rb_convert_type(v, T_ARRAY, "Array", "to_ary")
#define CHECK_STRING(v) rb_convert_type(v, T_STRING, "String", "to_str")
#define CHECK_SYMBOL(v) rb_convert_type(v, T_SYMBOL, "Symbol", "to_sym")
static inline VALUE CHECK_INTEGER(VALUE v) {NUM2LONG(v); return v;}
+//RHO : misc
VALUE
rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE locals, VALUE args,
- VALUE exception, VALUE body)
+ VALUE exception, VALUE body, VALUE misc)
+//RHO
{
int i;
ID *tbl;
struct st_table *labels_table = st_init_numtable();
DECL_ANCHOR(anchor);
INIT_ANCHOR(anchor);
- iseq->local_table_size = RARRAY_LEN(locals);
- iseq->local_table = tbl = (ID *)ALLOC_N(ID *, iseq->local_table_size);
- iseq->local_size = iseq->local_table_size + 1;
+ iseq->local_table_size = RARRAY_LENINT(locals);
+ iseq->local_table = tbl = (ID *)ALLOC_N(ID, iseq->local_table_size);
+ //RHO
+ iseq->local_size = FIX2INT(rb_hash_aref(misc, ID2SYM(rb_intern("local_size"))));
+ //iseq->local_size = iseq->local_table_size + 1;
+ //RHO
for (i=0; i<RARRAY_LEN(locals); i++) {
VALUE lv = RARRAY_PTR(locals)[i];
- tbl[i] = FIXNUM_P(lv) ? FIX2INT(lv) : SYM2ID(CHECK_SYMBOL(lv));
+ tbl[i] = FIXNUM_P(lv) ? (ID)FIX2LONG(lv) : SYM2ID(CHECK_SYMBOL(lv));
}
/* args */
if (FIXNUM_P(args)) {
iseq->arg_size = iseq->argc = FIX2INT(args);
@@ -5329,11 +5407,11 @@
iseq->argc = FIX2INT(argc);
iseq->arg_rest = FIX2INT(arg_rest);
iseq->arg_post_len = FIX2INT(arg_post_len);
iseq->arg_post_start = FIX2INT(arg_post_start);
iseq->arg_block = FIX2INT(arg_block);
- iseq->arg_opts = RARRAY_LEN(arg_opt_labels);
+ iseq->arg_opts = RARRAY_LENINT(arg_opt_labels);
iseq->arg_opt_table = (VALUE *)ALLOC_N(VALUE, iseq->arg_opts);
if (iseq->arg_block != -1) {
iseq->arg_size = iseq->arg_block + 1;
}
@@ -5411,10 +5489,10 @@
}
int
rb_parse_in_eval(void)
{
- return GET_THREAD()->parse_in_eval != 0;
+ return GET_THREAD()->parse_in_eval > 0;
}
int
rb_parse_in_main(void)
{