aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2023-06-17 19:20:31 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2023-06-17 19:21:28 +0200
commit822590f5e29c613dd1401ba4309c0684426fc4f4 (patch)
tree339a5e104e751aebd392b44cd7a59fa5dada2556
parent19a74a54ded98b28c672d38b79ea9f313f2d89db (diff)
downloadbusybox-w32-822590f5e29c613dd1401ba4309c0684426fc4f4.tar.gz
busybox-w32-822590f5e29c613dd1401ba4309c0684426fc4f4.tar.bz2
busybox-w32-822590f5e29c613dd1401ba4309c0684426fc4f4.zip
shell/math: eliminate some redundant stores on return code path
function old new delta evaluate_string 1432 1412 -20 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--shell/math.c43
1 files changed, 23 insertions, 20 deletions
diff --git a/shell/math.c b/shell/math.c
index 3e339a5ec..4b56d1397 100644
--- a/shell/math.c
+++ b/shell/math.c
@@ -303,21 +303,21 @@ arith_lookup_val(arith_state_t *math_state, var_or_num_t *t)
303static NOINLINE const char* 303static NOINLINE const char*
304arith_apply(arith_state_t *math_state, operator op, var_or_num_t *numstack, var_or_num_t **numstackptr) 304arith_apply(arith_state_t *math_state, operator op, var_or_num_t *numstack, var_or_num_t **numstackptr)
305{ 305{
306#define NUMPTR (*numstackptr) 306#define NUMSTACKPTR (*numstackptr)
307 307
308 var_or_num_t *top_of_stack; 308 var_or_num_t *top_of_stack;
309 arith_t rez; 309 arith_t rez;
310 310
311 /* There is no operator that can work without arguments */ 311 /* There is no operator that can work without arguments */
312 if (NUMPTR == numstack) 312 if (NUMSTACKPTR == numstack)
313 goto syntax_err; 313 goto syntax_err;
314 314
315 top_of_stack = NUMPTR - 1; 315 top_of_stack = NUMSTACKPTR - 1;
316 316
317 if (op == TOK_CONDITIONAL_SEP) { 317 if (op == TOK_CONDITIONAL_SEP) {
318 /* "expr1 ? expr2 : expr3" operation */ 318 /* "expr1 ? expr2 : expr3" operation */
319 var_or_num_t *expr1 = &top_of_stack[-2]; 319 var_or_num_t *expr1 = &top_of_stack[-2];
320 NUMPTR = expr1 + 1; 320 NUMSTACKPTR = expr1 + 1;
321 if (expr1 < numstack) /* Example: $((2:3)) */ 321 if (expr1 < numstack) /* Example: $((2:3)) */
322 return "malformed ?: operator"; 322 return "malformed ?: operator";
323 if (expr1->val != 0) /* select expr2 or expr3 */ 323 if (expr1->val != 0) /* select expr2 or expr3 */
@@ -348,12 +348,17 @@ arith_apply(arith_state_t *math_state, operator op, var_or_num_t *numstack, var_
348 goto syntax_err; /* no */ 348 goto syntax_err; /* no */
349 349
350 /* Pop numstack */ 350 /* Pop numstack */
351 NUMPTR = top_of_stack; /* this decrements NUMPTR */ 351 NUMSTACKPTR = top_of_stack; /* this decrements NUMSTACKPTR */
352 top_of_stack--; /* now points to left side */ 352 top_of_stack--; /* now points to left side */
353 353
354 if (math_state->evaluation_disabled) { 354 if (math_state->evaluation_disabled) {
355 dbg("binary op %02x skipped", op); 355 dbg("binary op %02x skipped", op);
356 goto ret_NULL; 356 goto ret_NULL;
357 /* bash 5.2.12 does not execute "2/0" in disabled
358 * branches of ?: (and thus does not complain),
359 * but complains about negative exp: "2**-1".
360 * I don't think we need to emulate that.
361 */
357 } 362 }
358 363
359 right_side_val = rez; 364 right_side_val = rez;
@@ -457,7 +462,7 @@ arith_apply(arith_state_t *math_state, operator op, var_or_num_t *numstack, var_
457 return NULL; 462 return NULL;
458 syntax_err: 463 syntax_err:
459 return "arithmetic syntax error"; 464 return "arithmetic syntax error";
460#undef NUMPTR 465#undef NUMSTACKPTR
461} 466}
462 467
463/* longest must be first */ 468/* longest must be first */
@@ -630,8 +635,7 @@ evaluate_string(arith_state_t *math_state, const char *expr)
630 if (*expr == '\0') { 635 if (*expr == '\0') {
631 if (expr == start_expr) { 636 if (expr == start_expr) {
632 /* Null expression */ 637 /* Null expression */
633 numstack->val = 0; 638 return 0;
634 goto ret;
635 } 639 }
636 640
637 /* This is only reached after all tokens have been extracted from the 641 /* This is only reached after all tokens have been extracted from the
@@ -650,9 +654,9 @@ evaluate_string(arith_state_t *math_state, const char *expr)
650 /* At this point, we're done with the expression */ 654 /* At this point, we're done with the expression */
651 if (numstackptr != numstack + 1) { 655 if (numstackptr != numstack + 1) {
652 /* if there is not exactly one result, it's bad */ 656 /* if there is not exactly one result, it's bad */
653 goto err; 657 goto syntax_err;
654 } 658 }
655 goto ret; 659 return numstack->val;
656 } 660 }
657 661
658 p = endofname(expr); 662 p = endofname(expr);
@@ -697,7 +701,7 @@ evaluate_string(arith_state_t *math_state, const char *expr)
697 * a new number or name. Example: 09v09v09v09v09v09v09v09v09v 701 * a new number or name. Example: 09v09v09v09v09v09v09v09v09v
698 */ 702 */
699 if (isalnum(*expr) || *expr == '_') 703 if (isalnum(*expr) || *expr == '_')
700 goto err; 704 goto syntax_err;
701 if (errno) 705 if (errno)
702 numstackptr->val = 0; /* bash compat */ 706 numstackptr->val = 0; /* bash compat */
703 goto push_num; 707 goto push_num;
@@ -750,7 +754,7 @@ evaluate_string(arith_state_t *math_state, const char *expr)
750 if (*p == '\0') { 754 if (*p == '\0') {
751 /* No next element, operator not found */ 755 /* No next element, operator not found */
752 //math_state->syntax_error_at = expr; 756 //math_state->syntax_error_at = expr;
753 goto err; 757 goto syntax_err;
754 } 758 }
755 } 759 }
756 /* NB: expr now points past the operator */ 760 /* NB: expr now points past the operator */
@@ -812,7 +816,7 @@ evaluate_string(arith_state_t *math_state, const char *expr)
812 /* binary, ternary or RPAREN */ 816 /* binary, ternary or RPAREN */
813 if (lasttok != TOK_NUM) { 817 if (lasttok != TOK_NUM) {
814 /* must be preceded by a num */ 818 /* must be preceded by a num */
815 goto err; 819 goto syntax_err;
816 } 820 }
817 /* if op is RPAREN: 821 /* if op is RPAREN:
818 * while opstack is not empty: 822 * while opstack is not empty:
@@ -883,7 +887,7 @@ dbg(" numstack:%d val:%lld '%s'", (int)(numstackptr - numstack), numstackptr[
883 } /* while (opstack not empty) */ 887 } /* while (opstack not empty) */
884 888
885 if (op == TOK_RPAREN) /* unpaired RPAREN? */ 889 if (op == TOK_RPAREN) /* unpaired RPAREN? */
886 goto err; 890 goto syntax_err;
887 check_cond: 891 check_cond:
888 if (op == TOK_CONDITIONAL) { 892 if (op == TOK_CONDITIONAL) {
889 /* We just now evaluated EXPR before "?". 893 /* We just now evaluated EXPR before "?".
@@ -914,20 +918,19 @@ dbg(" numstack:%d val:%lld '%s'", (int)(numstackptr - numstack), numstackptr[
914 } else if (ternary_level == math_state->evaluation_disabled) { 918 } else if (ternary_level == math_state->evaluation_disabled) {
915 math_state->evaluation_disabled = 0; 919 math_state->evaluation_disabled = 0;
916 dbg("':' entered: evaluation_disabled=CLEAR"); 920 dbg("':' entered: evaluation_disabled=CLEAR");
917 } /* else: ternary_level > nonzero evaluation_disabled: we are in nested ?:, in its disabled branch */ 921 } /* else: ternary_level > evaluation_disabled && evaluation_disabled != 0 */
918 /* do nothing */ 922 /* We are in nested "?:" while in outer "?:" disabled branch */
923 /* do_nothing */
919 } 924 }
920 goto tok_found1; 925 goto tok_found1;
921 } 926 }
922 } /* while (1) */ 927 } /* while (1) */
923 928
924 err: 929 syntax_err:
925 errmsg = "arithmetic syntax error"; 930 errmsg = "arithmetic syntax error";
926 err_with_custom_msg: 931 err_with_custom_msg:
927 numstack->val = -1;
928 ret:
929 math_state->errmsg = errmsg; 932 math_state->errmsg = errmsg;
930 return numstack->val; 933 return -1;
931} 934}
932 935
933arith_t FAST_FUNC 936arith_t FAST_FUNC