From 49967097edb65dad65ed87f7ff9d531bf562919b Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 30 Aug 2019 15:51:18 +0900 Subject: Skip `nil?` method call in `if` conditionals. Compile `if expr.nil?` to use `OP_JMPNIL` instead of calls. --- mrbgems/mruby-compiler/core/codegen.c | 47 ++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index d397ace8c..c0986893c 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -1558,7 +1558,7 @@ codegen(codegen_scope *s, node *tree, int val) case NODE_IF: { - int pos1, pos2; + int pos1, pos2, nil_p = FALSE; node *elsepart = tree->cdr->cdr->car; if (!tree->car) { @@ -1575,26 +1575,38 @@ codegen(codegen_scope *s, node *tree, int val) case NODE_NIL: codegen(s, elsepart, val); 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(); if (val || tree->cdr->car) { - pos1 = genjmp2(s, OP_JMPNOT, cursp(), 0, val); - codegen(s, tree->cdr->car, val); - if (elsepart) { - if (val) pop(); - pos2 = genjmp(s, OP_JMP, 0); - dispatch(s, pos1); - codegen(s, elsepart, val); + if (nil_p) { + pos2 = genjmp2(s, OP_JMPNIL, cursp(), 0, val); + pos1 = genjmp(s, OP_JMP, 0); dispatch(s, pos2); } - else if (val) { - pop(); + else { + pos1 = genjmp2(s, OP_JMPNOT, cursp(), 0, val); + } + codegen(s, tree->cdr->car, val); + if (val) pop(); + if (elsepart || val) { pos2 = genjmp(s, OP_JMP, 0); dispatch(s, pos1); - genop_1(s, OP_LOADNIL, cursp()); + codegen(s, elsepart, val); dispatch(s, pos2); - push(); } else { dispatch(s, pos1); @@ -1602,11 +1614,16 @@ codegen(codegen_scope *s, node *tree, int val) } else { /* empty then-part */ 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); dispatch(s, pos1); } - else if (val) { + else if (val && !nil_p) { genop_1(s, OP_LOADNIL, cursp()); push(); } -- cgit v1.2.3