diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2023-06-17 19:20:31 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2023-06-17 19:21:28 +0200 |
commit | 822590f5e29c613dd1401ba4309c0684426fc4f4 (patch) | |
tree | 339a5e104e751aebd392b44cd7a59fa5dada2556 | |
parent | 19a74a54ded98b28c672d38b79ea9f313f2d89db (diff) | |
download | busybox-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.c | 43 |
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) | |||
303 | static NOINLINE const char* | 303 | static NOINLINE const char* |
304 | arith_apply(arith_state_t *math_state, operator op, var_or_num_t *numstack, var_or_num_t **numstackptr) | 304 | arith_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 | ||
933 | arith_t FAST_FUNC | 936 | arith_t FAST_FUNC |