diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2021-07-22 11:39:52 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2021-07-22 11:39:52 +0900 |
| commit | d0fed63414b499cccb75141ea1509ba6ffd28a73 (patch) | |
| tree | 6b8aa6d4430e2b4a1f2807c2dc12ba89cbdfa9ce /mrbgems/mruby-compiler | |
| parent | 3e9ed1cca2cbd5a4295846e001f3ee834e534ab1 (diff) | |
| download | mruby-d0fed63414b499cccb75141ea1509ba6ffd28a73.tar.gz mruby-d0fed63414b499cccb75141ea1509ba6ffd28a73.zip | |
codegen.c: add constant folding for unary numeric operators (+, -, ~).
Diffstat (limited to 'mrbgems/mruby-compiler')
| -rw-r--r-- | mrbgems/mruby-compiler/core/codegen.c | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 4fd3feb08..2b14eead7 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -549,7 +549,7 @@ gen_return(codegen_scope *s, uint8_t op, uint16_t src) } static mrb_bool -get_int_operand(struct mrb_insn_data *data, int32_t *n) +get_int_operand(struct mrb_insn_data *data, mrb_int *n) { switch (data->insn) { case OP_LOADI__1: @@ -571,7 +571,7 @@ get_int_operand(struct mrb_insn_data *data, int32_t *n) return TRUE; case OP_LOADI32: - *n = (int32_t)((uint32_t)data->b<<16)+data->c; + *n = (mrb_int)((uint32_t)data->b<<16)+data->c; return TRUE; default: @@ -589,7 +589,7 @@ gen_addsub(codegen_scope *s, uint8_t op, uint16_t dst) } else { struct mrb_insn_data data = mrb_last_insn(s); - int32_t n; + mrb_int n; if (!get_int_operand(&data, &n)) { /* not integer immediate */ @@ -859,17 +859,23 @@ gen_int(codegen_scope *s, uint16_t dst, mrb_int i) } static void -gen_uminus(codegen_scope *s, uint16_t dst) +gen_uniop(codegen_scope *s, mrb_sym sym, uint16_t dst) { struct mrb_insn_data data = mrb_last_insn(s); - int32_t n; + mrb_int n; if (get_int_operand(&data, &n)) { s->pc = s->lastpc; - gen_int(s, dst, -n); + if (sym == MRB_OPSYM_2(s->mrb, minus)) { + n = -n; + } + else if (sym == MRB_OPSYM_2(s->mrb, neg)) { + n = ~n; + } + gen_int(s, dst, n); } else { - genop_3(s, OP_SEND, dst, new_sym(s, MRB_OPSYM_2(s->mrb, minus)), 0); + genop_3(s, OP_SEND, dst, new_sym(s, sym), 0); } } @@ -1348,6 +1354,12 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe) else if (!noop && sym == MRB_OPSYM_2(s->mrb, eq) && n == 1) { genop_1(s, OP_EQ, cursp()); } + else if (!noop && n == 0 && + (sym == MRB_OPSYM_2(s->mrb, plus) || + sym == MRB_OPSYM_2(s->mrb, minus) || + sym == MRB_OPSYM_2(s->mrb, neg))) { + gen_uniop(s, sym, cursp()); + } else { int idx = new_sym(s, sym); @@ -2708,7 +2720,7 @@ codegen(codegen_scope *s, node *tree, int val) codegen(s, tree, VAL); pop(); push_n(2);pop_n(2); /* space for receiver&block */ - gen_uminus(s, cursp()); + gen_uniop(s, MRB_OPSYM_2(s->mrb, minus), cursp()); push(); } else { |
