diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2021-08-01 20:32:10 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2021-08-01 20:33:41 +0900 |
| commit | 1315e8751e70937e4cf43ba9225ea0cfaa67689d (patch) | |
| tree | 92c7523efa77f7d879df9fcb6c9abb1a0d924e25 | |
| parent | 9dc801a79810760b6911b2856e20b27e04e64986 (diff) | |
| download | mruby-1315e8751e70937e4cf43ba9225ea0cfaa67689d.tar.gz mruby-1315e8751e70937e4cf43ba9225ea0cfaa67689d.zip | |
codegen.c: eliminate loop if condition is constant.
For example, `while false; ...; end` should be removed.
| -rw-r--r-- | mrbgems/mruby-compiler/core/codegen.c | 49 |
1 files changed, 28 insertions, 21 deletions
diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 8cc3bad7a..7d0b51740 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -2096,33 +2096,40 @@ codegen(codegen_scope *s, node *tree, int val) break; case NODE_WHILE: - { - struct loopinfo *lp = loop_push(s, LOOP_NORMAL); - uint32_t pos; - - if (!val) lp->acc = -1; - lp->pc0 = new_label(s); - codegen(s, tree->car, VAL); - pop(); - pos = genjmp2_0(s, OP_JMPNOT, cursp(), NOVAL); - lp->pc1 = new_label(s); - codegen(s, tree->cdr, NOVAL); - genjmp(s, OP_JMP, lp->pc0); - dispatch(s, pos); - loop_pop(s, val); - } - break; - case NODE_UNTIL: { struct loopinfo *lp = loop_push(s, LOOP_NORMAL); - uint32_t pos; + uint32_t pos = JMPLINK_START; if (!val) lp->acc = -1; lp->pc0 = new_label(s); - codegen(s, tree->car, VAL); - pop(); - pos = genjmp2_0(s, OP_JMPIF, cursp(), NOVAL); + switch (nint(tree->car->car)) { + case NODE_TRUE: + case NODE_INT: + case NODE_STR: + if (nt == NODE_UNTIL) { + if (val) genop_1(s, OP_LOADNIL, cursp()); + goto exit; + } + break; + case NODE_FALSE: + case NODE_NIL: + if (nt == NODE_WHILE) { + if (val) genop_1(s, OP_LOADNIL, cursp()); + goto exit; + } + break; + default: + codegen(s, tree->car, VAL); + pop(); + if (nt == NODE_WHILE) { + pos = genjmp2_0(s, OP_JMPNOT, cursp(), NOVAL); + } + else { + pos = genjmp2_0(s, OP_JMPIF, cursp(), NOVAL); + } + break; + } lp->pc1 = new_label(s); codegen(s, tree->cdr, NOVAL); genjmp(s, OP_JMP, lp->pc0); |
