codegen.c: skip `-@` call if the argument is a literal integer.
MODIFY
mrbgems/mruby-compiler/core/codegen.c
mrbgems/mruby-compiler/core/codegen.c
@@ -858,6 +858,21 @@ gen_int(codegen_scope *s, uint16_t dst, mrb_int i)
}
}
+static void
+gen_uminus(codegen_scope *s, uint16_t dst)
+{
+ struct mrb_insn_data data = mrb_last_insn(s);
+ int32_t n;
+
+ if (get_int_operand(&data, &n)) {
+ s->pc = s->lastpc;
+ gen_int(s, dst, -n);
+ }
+ else {
+ genop_3(s, OP_SEND, dst, new_sym(s, MRB_OPSYM_2(s->mrb, minus)), 0);
+ }
+}
+
static int
node_len(node *tree)
{
@@ -2695,10 +2710,10 @@ codegen(codegen_scope *s, node *tree, int val)
default:
if (val) {
- int sym = new_sym(s, MRB_OPSYM_2(s->mrb, minus));
codegen(s, tree, VAL);
pop();
- genop_3(s, OP_SEND, cursp(), sym, 0);
+ push_n(2);pop_n(2); /* space for receiver&block */
+ gen_uminus(s, cursp());
push();
}
else {

MODIFY
mrbgems/mruby-compiler/core/parse.y
mrbgems/mruby-compiler/core/parse.y
@@ -1248,7 +1248,7 @@ call_with_block(parser_state *p, node *a, node *b)
}
static node*
-negate_lit(parser_state *p, node *n)
+new_negate(parser_state *p, node *n)
{
return cons((node*)NODE_NEGATE, n);
}
@@ -2292,11 +2292,11 @@ arg : lhs '=' arg_rhs
}
| tUMINUS_NUM tINTEGER tPOW arg
{
- $$ = call_uni_op(p, call_bin_op(p, $2, "**", $4), "-@");
+ $$ = new_negate(p, call_bin_op(p, $2, "**", $4));
}
| tUMINUS_NUM tFLOAT tPOW arg
{
- $$ = call_uni_op(p, call_bin_op(p, $2, "**", $4), "-@");
+ $$ = new_negate(p, call_bin_op(p, $2, "**", $4));
}
| tUPLUS arg
{
@@ -2304,7 +2304,7 @@ arg : lhs '=' arg_rhs
}
| tUMINUS arg
{
- $$ = call_uni_op(p, $2, "-@");
+ $$ = new_negate(p, $2);
}
| arg '|' arg
{
@@ -3463,11 +3463,11 @@ numeric : tINTEGER
| tFLOAT
| tUMINUS_NUM tINTEGER %prec tLOWEST
{
- $$ = negate_lit(p, $2);
+ $$ = new_negate(p, $2);
}
| tUMINUS_NUM tFLOAT %prec tLOWEST
{
- $$ = negate_lit(p, $2);
+ $$ = new_negate(p, $2);
}
;

MODIFY
mrbgems/mruby-compiler/core/y.tab.c
mrbgems/mruby-compiler/core/y.tab.c
@@ -1311,7 +1311,7 @@ call_with_block(parser_state *p, node *a, node *b)
}
static node*
-negate_lit(parser_state *p, node *n)
+new_negate(parser_state *p, node *n)
{
return cons((node*)NODE_NEGATE, n);
}
@@ -7376,7 +7376,7 @@ yyreduce:
case 219:
#line 2294 "mrbgems/mruby-compiler/core/parse.y"
{
- (yyval.nd) = call_uni_op(p, call_bin_op(p, (yyvsp[-2].nd), "**", (yyvsp[0].nd)), "-@");
+ (yyval.nd) = new_negate(p, call_bin_op(p, (yyvsp[-2].nd), "**", (yyvsp[0].nd)));
}
#line 7382 "mrbgems/mruby-compiler/core/y.tab.c"
break;
@@ -7384,7 +7384,7 @@ yyreduce:
case 220:
#line 2298 "mrbgems/mruby-compiler/core/parse.y"
{
- (yyval.nd) = call_uni_op(p, call_bin_op(p, (yyvsp[-2].nd), "**", (yyvsp[0].nd)), "-@");
+ (yyval.nd) = new_negate(p, call_bin_op(p, (yyvsp[-2].nd), "**", (yyvsp[0].nd)));
}
#line 7390 "mrbgems/mruby-compiler/core/y.tab.c"
break;
@@ -7400,7 +7400,7 @@ yyreduce:
case 222:
#line 2306 "mrbgems/mruby-compiler/core/parse.y"
{
- (yyval.nd) = call_uni_op(p, (yyvsp[0].nd), "-@");
+ (yyval.nd) = new_negate(p, (yyvsp[0].nd));
}
#line 7406 "mrbgems/mruby-compiler/core/y.tab.c"
break;
@@ -9183,7 +9183,7 @@ yyreduce:
case 477:
#line 3465 "mrbgems/mruby-compiler/core/parse.y"
{
- (yyval.nd) = negate_lit(p, (yyvsp[0].nd));
+ (yyval.nd) = new_negate(p, (yyvsp[0].nd));
}
#line 9189 "mrbgems/mruby-compiler/core/y.tab.c"
break;
@@ -9191,7 +9191,7 @@ yyreduce:
case 478:
#line 3469 "mrbgems/mruby-compiler/core/parse.y"
{
- (yyval.nd) = negate_lit(p, (yyvsp[0].nd));
+ (yyval.nd) = new_negate(p, (yyvsp[0].nd));
}
#line 9197 "mrbgems/mruby-compiler/core/y.tab.c"
break;

codegen.c: skip `-@` call if the argument is a literal integer.