* compile.c, compile.h: fix to calculate correct stack depth
at each instruction. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@15251 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
1e039d96f3
commit
3b1c663ed9
@ -1,3 +1,8 @@
|
|||||||
|
Sat Jan 26 17:22:46 2008 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
|
* compile.c, compile.h: fix to calculate correct stack depth
|
||||||
|
at each instruction.
|
||||||
|
|
||||||
Sat Jan 26 09:41:02 2008 NARUSE, Yui <naruse@ruby-lang.org>
|
Sat Jan 26 09:41:02 2008 NARUSE, Yui <naruse@ruby-lang.org>
|
||||||
|
|
||||||
* lib/rexml/doctype.rb, test/rss/test_maker_itunes.rb: replace
|
* lib/rexml/doctype.rb, test/rss/test_maker_itunes.rb: replace
|
||||||
|
151
compile.c
151
compile.c
@ -348,7 +348,6 @@ ADD_ELEM(LINK_ANCHOR *anchor, LINK_ELEMENT *elem)
|
|||||||
verify_list("add", anchor);
|
verify_list("add", anchor);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0 /* unused */
|
|
||||||
/*
|
/*
|
||||||
* elem1, elemX => elem1, elem2, elemX
|
* elem1, elemX => elem1, elem2, elemX
|
||||||
*/
|
*/
|
||||||
@ -362,7 +361,6 @@ INSERT_ELEM_NEXT(LINK_ELEMENT *elem1, LINK_ELEMENT *elem2)
|
|||||||
elem2->next->prev = elem2;
|
elem2->next->prev = elem2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0 /* unused */
|
#if 0 /* unused */
|
||||||
/*
|
/*
|
||||||
@ -1007,8 +1005,11 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
|
|||||||
}
|
}
|
||||||
case ISEQ_ELEMENT_ADJUST:
|
case ISEQ_ELEMENT_ADJUST:
|
||||||
{
|
{
|
||||||
pos += 2 /* insn + 1 operand */;
|
ADJUST *adjust = (ADJUST *)list;
|
||||||
k++;
|
if (adjust->line_no != -1) {
|
||||||
|
pos += 2 /* insn + 1 operand */;
|
||||||
|
k++;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -1180,25 +1181,27 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
|
|||||||
sp = 0;
|
sp = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (orig_sp - sp > 0) {
|
if (adjust->line_no != -1) {
|
||||||
insn_info_table[k].line_no = adjust->line_no;
|
if (orig_sp - sp > 0) {
|
||||||
insn_info_table[k].position = pos;
|
insn_info_table[k].line_no = adjust->line_no;
|
||||||
insn_info_table[k].sp = sp;
|
insn_info_table[k].position = pos;
|
||||||
k++;
|
insn_info_table[k].sp = sp;
|
||||||
generated_iseq[pos++] = BIN(adjuststack);
|
k++;
|
||||||
generated_iseq[pos++] = orig_sp - sp;
|
generated_iseq[pos++] = BIN(adjuststack);
|
||||||
}
|
generated_iseq[pos++] = orig_sp - sp;
|
||||||
else if (orig_sp - sp == 0) {
|
}
|
||||||
/* jump to next insn */
|
else if (orig_sp - sp == 0) {
|
||||||
insn_info_table[k].line_no = adjust->line_no;
|
/* jump to next insn */
|
||||||
insn_info_table[k].position = pos;
|
insn_info_table[k].line_no = adjust->line_no;
|
||||||
insn_info_table[k].sp = sp;
|
insn_info_table[k].position = pos;
|
||||||
k++;
|
insn_info_table[k].sp = sp;
|
||||||
generated_iseq[pos++] = BIN(jump);
|
k++;
|
||||||
generated_iseq[pos++] = 0;
|
generated_iseq[pos++] = BIN(jump);
|
||||||
}
|
generated_iseq[pos++] = 0;
|
||||||
else {
|
}
|
||||||
rb_bug("iseq_set_sequence: adjust bug");
|
else {
|
||||||
|
rb_bug("iseq_set_sequence: adjust bug");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1209,7 +1212,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *anchor)
|
|||||||
list = list->next;
|
list = list->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0 /* XXX */
|
||||||
/* this check need dead code elimination */
|
/* this check need dead code elimination */
|
||||||
if (sp != 1) {
|
if (sp != 1) {
|
||||||
rb_bug("SP is not 0 on %s (%d)\n", RSTRING_PTR(iseq->name), sp);
|
rb_bug("SP is not 0 on %s (%d)\n", RSTRING_PTR(iseq->name), sp);
|
||||||
@ -1401,11 +1404,13 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
|
|||||||
* leave
|
* leave
|
||||||
*/
|
*/
|
||||||
INSN *eiobj = new_insn_core(iseq, iobj->line_no, BIN(leave),
|
INSN *eiobj = new_insn_core(iseq, iobj->line_no, BIN(leave),
|
||||||
diobj->operand_size,
|
diobj->operand_size, diobj->operands);
|
||||||
diobj->operands);
|
INSN *popiobj = new_insn_core(iseq, iobj->line_no,
|
||||||
|
BIN(pop), 0, 0);
|
||||||
/* replace */
|
/* replace */
|
||||||
REPLACE_ELEM((LINK_ELEMENT *)iobj, (LINK_ELEMENT *)eiobj);
|
REPLACE_ELEM((LINK_ELEMENT *)iobj, (LINK_ELEMENT *)eiobj);
|
||||||
iobj = eiobj;
|
INSERT_ELEM_NEXT((LINK_ELEMENT *)eiobj, (LINK_ELEMENT *)popiobj);
|
||||||
|
iobj = popiobj;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* useless jump elimination (if/unless destination):
|
* useless jump elimination (if/unless destination):
|
||||||
@ -2982,18 +2987,26 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
|
|||||||
|
|
||||||
if (iseq->compile_data->redo_label != 0) {
|
if (iseq->compile_data->redo_label != 0) {
|
||||||
/* while/until */
|
/* while/until */
|
||||||
add_ensure_iseq(ret, iseq);
|
LABEL *splabel = NEW_LABEL(0);
|
||||||
|
ADD_LABEL(ret, splabel);
|
||||||
ADD_ADJUST(ret, nd_line(node), iseq->compile_data->redo_label);
|
ADD_ADJUST(ret, nd_line(node), iseq->compile_data->redo_label);
|
||||||
COMPILE_(ret, "break val (while/until)", node->nd_stts,
|
COMPILE_(ret, "break val (while/until)", node->nd_stts, iseq->compile_data->loopval_popped);
|
||||||
iseq->compile_data->loopval_popped);
|
add_ensure_iseq(ret, iseq);
|
||||||
ADD_INSNL(ret, nd_line(node), jump, iseq->compile_data->end_label);
|
ADD_INSNL(ret, nd_line(node), jump, iseq->compile_data->end_label);
|
||||||
|
ADD_ADJUST_RESTORE(ret, splabel);
|
||||||
|
|
||||||
|
if (!poped) {
|
||||||
|
ADD_INSN(ret, nd_line(node), putnil);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (iseq->type == ISEQ_TYPE_BLOCK) {
|
else if (iseq->type == ISEQ_TYPE_BLOCK) {
|
||||||
break_by_insn:
|
break_by_insn:
|
||||||
/* escape from block */
|
/* escape from block */
|
||||||
COMPILE(ret, "break val (block)", node->nd_stts);
|
COMPILE(ret, "break val (block)", node->nd_stts);
|
||||||
ADD_INSN1(ret, nd_line(node), throw,
|
ADD_INSN1(ret, nd_line(node), throw, INT2FIX(level | 0x02) /* TAG_BREAK */ );
|
||||||
INT2FIX(level | 0x02) /* TAG_BREAK */ );
|
if (poped) {
|
||||||
|
ADD_INSN(ret, nd_line(node), pop);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (iseq->type == ISEQ_TYPE_EVAL) {
|
else if (iseq->type == ISEQ_TYPE_EVAL) {
|
||||||
break_in_eval:
|
break_in_eval:
|
||||||
@ -3026,21 +3039,29 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
|
|||||||
}
|
}
|
||||||
case NODE_NEXT:{
|
case NODE_NEXT:{
|
||||||
unsigned long level = 0;
|
unsigned long level = 0;
|
||||||
int pop_after_throw = 0;
|
|
||||||
|
|
||||||
if (iseq->compile_data->redo_label != 0) {
|
if (iseq->compile_data->redo_label != 0) {
|
||||||
|
LABEL *splabel = NEW_LABEL(0);
|
||||||
debugs("next in while loop\n");
|
debugs("next in while loop\n");
|
||||||
ADD_ADJUST(ret, nd_line(node), iseq->compile_data->redo_label);
|
ADD_LABEL(ret, splabel);
|
||||||
add_ensure_iseq(ret, iseq);
|
add_ensure_iseq(ret, iseq);
|
||||||
|
ADD_ADJUST(ret, nd_line(node), iseq->compile_data->redo_label);
|
||||||
ADD_INSNL(ret, nd_line(node), jump, iseq->compile_data->start_label);
|
ADD_INSNL(ret, nd_line(node), jump, iseq->compile_data->start_label);
|
||||||
|
ADD_ADJUST_RESTORE(ret, splabel);
|
||||||
}
|
}
|
||||||
else if (iseq->compile_data->end_label) {
|
else if (iseq->compile_data->end_label) {
|
||||||
|
LABEL *splabel = NEW_LABEL(0);
|
||||||
debugs("next in block\n");
|
debugs("next in block\n");
|
||||||
|
ADD_LABEL(ret, splabel);
|
||||||
ADD_ADJUST(ret, nd_line(node), iseq->compile_data->start_label);
|
ADD_ADJUST(ret, nd_line(node), iseq->compile_data->start_label);
|
||||||
COMPILE(ret, "next val", node->nd_stts);
|
COMPILE(ret, "next val", node->nd_stts);
|
||||||
add_ensure_iseq(ret, iseq);
|
add_ensure_iseq(ret, iseq);
|
||||||
ADD_INSNL(ret, nd_line(node), jump,
|
ADD_INSNL(ret, nd_line(node), jump, iseq->compile_data->end_label);
|
||||||
iseq->compile_data->end_label);
|
ADD_ADJUST_RESTORE(ret, splabel);
|
||||||
|
|
||||||
|
if (!poped) {
|
||||||
|
ADD_INSN(ret, nd_line(node), putnil);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (iseq->type == ISEQ_TYPE_EVAL) {
|
else if (iseq->type == ISEQ_TYPE_EVAL) {
|
||||||
next_in_eval:
|
next_in_eval:
|
||||||
@ -3067,9 +3088,9 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
|
|||||||
}
|
}
|
||||||
if (ip != 0) {
|
if (ip != 0) {
|
||||||
COMPILE(ret, "next val", node->nd_stts);
|
COMPILE(ret, "next val", node->nd_stts);
|
||||||
ADD_INSN1(ret, nd_line(node), throw,
|
ADD_INSN1(ret, nd_line(node), throw, INT2FIX(level | 0x03) /* TAG_NEXT */ );
|
||||||
INT2FIX(level | 0x03) /* TAG_NEXT */ );
|
|
||||||
if (pop_after_throw) {
|
if (poped) {
|
||||||
ADD_INSN(ret, nd_line(node), pop);
|
ADD_INSN(ret, nd_line(node), pop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3081,23 +3102,29 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
|
|||||||
}
|
}
|
||||||
case NODE_REDO:{
|
case NODE_REDO:{
|
||||||
if (iseq->compile_data->redo_label) {
|
if (iseq->compile_data->redo_label) {
|
||||||
|
LABEL *splabel = NEW_LABEL(0);
|
||||||
debugs("redo in while");
|
debugs("redo in while");
|
||||||
|
ADD_LABEL(ret, splabel);
|
||||||
ADD_ADJUST(ret, nd_line(node), iseq->compile_data->redo_label);
|
ADD_ADJUST(ret, nd_line(node), iseq->compile_data->redo_label);
|
||||||
add_ensure_iseq(ret, iseq);
|
add_ensure_iseq(ret, iseq);
|
||||||
ADD_INSNL(ret, nd_line(node), jump,
|
ADD_INSNL(ret, nd_line(node), jump, iseq->compile_data->redo_label);
|
||||||
iseq->compile_data->redo_label);
|
ADD_ADJUST_RESTORE(ret, splabel);
|
||||||
}
|
}
|
||||||
else if (iseq->type == ISEQ_TYPE_EVAL) {
|
else if (iseq->type == ISEQ_TYPE_EVAL) {
|
||||||
redo_in_eval:
|
redo_in_eval:
|
||||||
COMPILE_ERROR((ERROR_ARGS "Can't escape from eval with redo"));
|
COMPILE_ERROR((ERROR_ARGS "Can't escape from eval with redo"));
|
||||||
}
|
}
|
||||||
else if (iseq->compile_data->start_label) {
|
else if (iseq->compile_data->start_label) {
|
||||||
|
LABEL *splabel = NEW_LABEL(0);
|
||||||
|
|
||||||
|
debugs("redo in block");
|
||||||
|
ADD_LABEL(ret, splabel);
|
||||||
add_ensure_iseq(ret, iseq);
|
add_ensure_iseq(ret, iseq);
|
||||||
ADD_ADJUST(ret, nd_line(node), iseq->compile_data->start_label);
|
ADD_ADJUST(ret, nd_line(node), iseq->compile_data->start_label);
|
||||||
ADD_INSNL(ret, nd_line(node), jump,
|
ADD_INSNL(ret, nd_line(node), jump, iseq->compile_data->start_label);
|
||||||
iseq->compile_data->start_label);
|
ADD_ADJUST_RESTORE(ret, splabel);
|
||||||
if (!poped) { /* for stack consistency */
|
|
||||||
|
if (!poped) {
|
||||||
ADD_INSN(ret, nd_line(node), putnil);
|
ADD_INSN(ret, nd_line(node), putnil);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3121,8 +3148,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
|
|||||||
}
|
}
|
||||||
if (ip != 0) {
|
if (ip != 0) {
|
||||||
ADD_INSN(ret, nd_line(node), putnil);
|
ADD_INSN(ret, nd_line(node), putnil);
|
||||||
ADD_INSN1(ret, nd_line(node), throw,
|
ADD_INSN1(ret, nd_line(node), throw, INT2FIX(level | 0x05) /* TAG_REDO */ );
|
||||||
INT2FIX(level | 0x05) /* TAG_REDO */ );
|
|
||||||
|
if (poped) {
|
||||||
|
ADD_INSN(ret, nd_line(node), pop);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
COMPILE_ERROR((ERROR_ARGS "Invalid redo"));
|
COMPILE_ERROR((ERROR_ARGS "Invalid redo"));
|
||||||
@ -3133,8 +3163,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
|
|||||||
case NODE_RETRY:{
|
case NODE_RETRY:{
|
||||||
if (iseq->type == ISEQ_TYPE_RESCUE) {
|
if (iseq->type == ISEQ_TYPE_RESCUE) {
|
||||||
ADD_INSN(ret, nd_line(node), putnil);
|
ADD_INSN(ret, nd_line(node), putnil);
|
||||||
ADD_INSN1(ret, nd_line(node), throw,
|
ADD_INSN1(ret, nd_line(node), throw, INT2FIX(0x04) /* TAG_RETRY */ );
|
||||||
INT2FIX(0x04) /* TAG_RETRY */ );
|
|
||||||
|
|
||||||
if (poped) {
|
if (poped) {
|
||||||
ADD_INSN(ret, nd_line(node), pop);
|
ADD_INSN(ret, nd_line(node), pop);
|
||||||
@ -3153,11 +3182,10 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
|
|||||||
LABEL *lstart = NEW_LABEL(nd_line(node));
|
LABEL *lstart = NEW_LABEL(nd_line(node));
|
||||||
LABEL *lend = NEW_LABEL(nd_line(node));
|
LABEL *lend = NEW_LABEL(nd_line(node));
|
||||||
LABEL *lcont = NEW_LABEL(nd_line(node));
|
LABEL *lcont = NEW_LABEL(nd_line(node));
|
||||||
VALUE rescue = NEW_CHILD_ISEQVAL(node->nd_resq,
|
VALUE rescue = NEW_CHILD_ISEQVAL(
|
||||||
rb_str_concat(rb_str_new2
|
node->nd_resq,
|
||||||
("rescue in "),
|
rb_str_concat(rb_str_new2("rescue in "), iseq->name),
|
||||||
iseq->name),
|
ISEQ_TYPE_RESCUE);
|
||||||
ISEQ_TYPE_RESCUE);
|
|
||||||
|
|
||||||
ADD_LABEL(ret, lstart);
|
ADD_LABEL(ret, lstart);
|
||||||
COMPILE(ret, "rescue head", node->nd_head);
|
COMPILE(ret, "rescue head", node->nd_head);
|
||||||
@ -3840,8 +3868,11 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
LABEL *splabel = 0;
|
||||||
|
|
||||||
if (is->type == ISEQ_TYPE_METHOD) {
|
if (is->type == ISEQ_TYPE_METHOD) {
|
||||||
|
splabel = NEW_LABEL(0);
|
||||||
|
ADD_LABEL(ret, splabel);
|
||||||
ADD_ADJUST(ret, nd_line(node), 0);
|
ADD_ADJUST(ret, nd_line(node), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3850,8 +3881,10 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
|
|||||||
if (is->type == ISEQ_TYPE_METHOD) {
|
if (is->type == ISEQ_TYPE_METHOD) {
|
||||||
add_ensure_iseq(ret, iseq);
|
add_ensure_iseq(ret, iseq);
|
||||||
ADD_INSN(ret, nd_line(node), leave);
|
ADD_INSN(ret, nd_line(node), leave);
|
||||||
if (poped) {
|
ADD_ADJUST_RESTORE(ret, splabel);
|
||||||
ADD_INSN(ret, nd_line(node), pop);
|
|
||||||
|
if (!poped) {
|
||||||
|
ADD_INSN(ret, nd_line(node), putnil);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -4637,6 +4670,12 @@ dump_disasm_list(struct iseq_link_element *link)
|
|||||||
printf("[none]\n");
|
printf("[none]\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case ISEQ_ELEMENT_ADJUST:
|
||||||
|
{
|
||||||
|
ADJUST *adjust = (ADJUST *)link;
|
||||||
|
printf("adjust: [label: %d]\n", adjust->label->label_no);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
/* ignore */
|
/* ignore */
|
||||||
rb_raise(rb_eSyntaxError, "dump_disasm_list error: %ld\n", FIX2LONG(link->type));
|
rb_raise(rb_eSyntaxError, "dump_disasm_list error: %ld\n", FIX2LONG(link->type));
|
||||||
|
@ -167,6 +167,9 @@ r_value(VALUE value)
|
|||||||
#define ADD_ADJUST(seq, line, label) \
|
#define ADD_ADJUST(seq, line, label) \
|
||||||
ADD_ELEM(seq, (LINK_ELEMENT *) new_adjust_body(iseq, label, line))
|
ADD_ELEM(seq, (LINK_ELEMENT *) new_adjust_body(iseq, label, line))
|
||||||
|
|
||||||
|
#define ADD_ADJUST_RESTORE(seq, label) \
|
||||||
|
ADD_ELEM(seq, (LINK_ELEMENT *) new_adjust_body(iseq, label, -1))
|
||||||
|
|
||||||
#define ADD_CATCH_ENTRY(type, ls, le, iseqv, lc) \
|
#define ADD_CATCH_ENTRY(type, ls, le, iseqv, lc) \
|
||||||
(rb_ary_push(iseq->compile_data->catch_table_ary, \
|
(rb_ary_push(iseq->compile_data->catch_table_ary, \
|
||||||
rb_ary_new3(5, type, \
|
rb_ary_new3(5, type, \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user