Fixed register windows of OP_SENDs generated by NODE_{SCALL,CASE,YIELD,UNDEF}; ref #3783

This commit is contained in:
Christopher Aue
2017-08-22 14:42:59 +02:00
parent 64e5208404
commit c6596cf26a
2 changed files with 40 additions and 1 deletions
+4 -1
View File
@@ -870,7 +870,7 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe)
genop(s, MKOP_A(OP_LOADNIL, cursp()));
push();
genop(s, MKOP_AB(OP_MOVE, cursp(), recv));
push(); pop(); /* space for a block */
push_n(2); pop_n(2); /* space for one arg and a block */
pop();
idx = new_msym(s, mrb_intern_lit(s->mrb, "=="));
genop(s, MKOP_ABC(OP_EQ, cursp(), idx, 1));
@@ -1542,6 +1542,7 @@ codegen(codegen_scope *s, node *tree, int val)
codegen(s, n->car, VAL);
if (head) {
genop(s, MKOP_AB(OP_MOVE, cursp(), head));
push_n(2); pop_n(2); /* space for one arg and a block */
pop();
if (nint(n->car->car) == NODE_SPLAT) {
genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "__case_eqq")), 1));
@@ -2049,6 +2050,7 @@ codegen(codegen_scope *s, node *tree, int val)
push();
}
}
push();pop(); /* space for a block */
pop_n(n+1);
genop(s, MKOP_ABx(OP_BLKPUSH, cursp(), (ainfo<<4)|(lv & 0xf)));
if (sendv) n = CALL_MAXARGS;
@@ -2644,6 +2646,7 @@ codegen(codegen_scope *s, node *tree, int val)
t = t->cdr;
num++;
}
push();pop(); /* space for a block */
pop();
if (num < CALL_MAXARGS) {
pop_n(num);
+36
View File
@@ -73,3 +73,39 @@ assert('negate literal register alignment') do
assert_equal [2], a
end
assert('register window of calls (#3783)') do
# NODE_SCALL
assert_nothing_raised do
Object.new&.__id__
end
# NODE_CASE
assert_nothing_raised do
case 1
when nil
end
end
# NODE_CASE with splat
assert_nothing_raised do
case 1
when *nil
end
end
# NODE_YIELD
def check_node_yield
yield
end
assert_nothing_raised do
check_node_yield{}
end
# NODE_UNDEF
assert_nothing_raised do
class << Object.new
undef send
end
end
end