mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Skip nil? method call in if conditionals.
Compile `if expr.nil?` to use `OP_JMPNIL` instead of calls.
This commit is contained in:
@@ -1558,7 +1558,7 @@ codegen(codegen_scope *s, node *tree, int val)
|
|||||||
|
|
||||||
case NODE_IF:
|
case NODE_IF:
|
||||||
{
|
{
|
||||||
int pos1, pos2;
|
int pos1, pos2, nil_p = FALSE;
|
||||||
node *elsepart = tree->cdr->cdr->car;
|
node *elsepart = tree->cdr->cdr->car;
|
||||||
|
|
||||||
if (!tree->car) {
|
if (!tree->car) {
|
||||||
@@ -1575,38 +1575,55 @@ codegen(codegen_scope *s, node *tree, int val)
|
|||||||
case NODE_NIL:
|
case NODE_NIL:
|
||||||
codegen(s, elsepart, val);
|
codegen(s, elsepart, val);
|
||||||
goto exit;
|
goto exit;
|
||||||
|
case NODE_CALL:
|
||||||
|
{
|
||||||
|
node *n = tree->car->cdr;
|
||||||
|
mrb_sym mid = nsym(n->cdr->car);
|
||||||
|
mrb_sym mnil = mrb_intern_lit(s->mrb, "nil?");
|
||||||
|
if (mid == mnil && n->cdr->cdr->car == NULL) {
|
||||||
|
nil_p = TRUE;
|
||||||
|
codegen(s, n->car, VAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!nil_p) {
|
||||||
|
codegen(s, tree->car, VAL);
|
||||||
}
|
}
|
||||||
codegen(s, tree->car, VAL);
|
|
||||||
pop();
|
pop();
|
||||||
if (val || tree->cdr->car) {
|
if (val || tree->cdr->car) {
|
||||||
pos1 = genjmp2(s, OP_JMPNOT, cursp(), 0, val);
|
if (nil_p) {
|
||||||
|
pos2 = genjmp2(s, OP_JMPNIL, cursp(), 0, val);
|
||||||
|
pos1 = genjmp(s, OP_JMP, 0);
|
||||||
|
dispatch(s, pos2);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pos1 = genjmp2(s, OP_JMPNOT, cursp(), 0, val);
|
||||||
|
}
|
||||||
codegen(s, tree->cdr->car, val);
|
codegen(s, tree->cdr->car, val);
|
||||||
if (elsepart) {
|
if (val) pop();
|
||||||
if (val) pop();
|
if (elsepart || val) {
|
||||||
pos2 = genjmp(s, OP_JMP, 0);
|
pos2 = genjmp(s, OP_JMP, 0);
|
||||||
dispatch(s, pos1);
|
dispatch(s, pos1);
|
||||||
codegen(s, elsepart, val);
|
codegen(s, elsepart, val);
|
||||||
dispatch(s, pos2);
|
dispatch(s, pos2);
|
||||||
}
|
}
|
||||||
else if (val) {
|
|
||||||
pop();
|
|
||||||
pos2 = genjmp(s, OP_JMP, 0);
|
|
||||||
dispatch(s, pos1);
|
|
||||||
genop_1(s, OP_LOADNIL, cursp());
|
|
||||||
dispatch(s, pos2);
|
|
||||||
push();
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
dispatch(s, pos1);
|
dispatch(s, pos1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { /* empty then-part */
|
else { /* empty then-part */
|
||||||
if (elsepart) {
|
if (elsepart) {
|
||||||
pos1 = genjmp2(s, OP_JMPIF, cursp(), 0, val);
|
if (nil_p) {
|
||||||
|
pos1 = genjmp2(s, OP_JMPNIL, cursp(), 0, val);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pos1 = genjmp2(s, OP_JMPIF, cursp(), 0, val);
|
||||||
|
}
|
||||||
codegen(s, elsepart, val);
|
codegen(s, elsepart, val);
|
||||||
dispatch(s, pos1);
|
dispatch(s, pos1);
|
||||||
}
|
}
|
||||||
else if (val) {
|
else if (val && !nil_p) {
|
||||||
genop_1(s, OP_LOADNIL, cursp());
|
genop_1(s, OP_LOADNIL, cursp());
|
||||||
push();
|
push();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user