diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2016-11-08 22:35:05 +0100 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2016-11-08 22:35:05 +0100 |
commit | 87e039d0160be16a9a242f74af2e90cdb9f97e12 (patch) | |
tree | 6d426cbcb065ba5dc1a7e10717d67a1e74987d88 | |
parent | 00a06b971531031103c25d650e2078c801afbe39 (diff) | |
download | busybox-w32-87e039d0160be16a9a242f74af2e90cdb9f97e12.tar.gz busybox-w32-87e039d0160be16a9a242f74af2e90cdb9f97e12.tar.bz2 busybox-w32-87e039d0160be16a9a242f74af2e90cdb9f97e12.zip |
hush: make getch/peek functions directly called
Indirect calls are more difficult to predict.
Unfortunately, on x64 direct call is 5 bytes while indirect "call (reg+ofs)"
is 3 bytes:
function old new delta
i_getch - 82 +82
i_peek - 63 +63
parse_stream 2531 2579 +48
parse_dollar 771 797 +26
parse_redirect 296 321 +25
add_till_closing_bracket 408 420 +12
encode_string 256 265 +9
i_peek_and_eat_bkslash_nl 93 99 +6
add_till_backquote 110 114 +4
parse_and_run_stream 139 141 +2
expand_vars_to_list 1143 1144 +1
static_peek 6 - -6
setup_string_in_str 39 18 -21
setup_file_in_str 40 19 -21
static_get 27 - -27
file_peek 52 - -52
file_get 65 - -65
------------------------------------------------------------------------------
(add/remove: 2/4 grow/shrink: 9/2 up/down: 278/-192) Total: 86 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | shell/hush.c | 51 |
1 files changed, 24 insertions, 27 deletions
diff --git a/shell/hush.c b/shell/hush.c index 57252a17a..2f07f4ac1 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -469,11 +469,7 @@ typedef struct in_str { | |||
469 | int peek_buf[2]; | 469 | int peek_buf[2]; |
470 | int last_char; | 470 | int last_char; |
471 | FILE *file; | 471 | FILE *file; |
472 | int (*get) (struct in_str *) FAST_FUNC; | ||
473 | int (*peek) (struct in_str *) FAST_FUNC; | ||
474 | } in_str; | 472 | } in_str; |
475 | #define i_getch(input) ((input)->get(input)) | ||
476 | #define i_peek(input) ((input)->peek(input)) | ||
477 | 473 | ||
478 | /* The descrip member of this structure is only used to make | 474 | /* The descrip member of this structure is only used to make |
479 | * debugging output pretty */ | 475 | * debugging output pretty */ |
@@ -2259,10 +2255,23 @@ static inline int fgetc_interactive(struct in_str *i) | |||
2259 | } | 2255 | } |
2260 | #endif /* INTERACTIVE */ | 2256 | #endif /* INTERACTIVE */ |
2261 | 2257 | ||
2262 | static int FAST_FUNC file_get(struct in_str *i) | 2258 | static int i_getch(struct in_str *i) |
2263 | { | 2259 | { |
2264 | int ch; | 2260 | int ch; |
2265 | 2261 | ||
2262 | if (!i->file) { | ||
2263 | /* string-based in_str */ | ||
2264 | ch = (unsigned char)*i->p; | ||
2265 | if (ch != '\0') { | ||
2266 | i->p++; | ||
2267 | i->last_char = ch; | ||
2268 | return ch; | ||
2269 | } | ||
2270 | return EOF; | ||
2271 | } | ||
2272 | |||
2273 | /* FILE-based in_str */ | ||
2274 | |||
2266 | #if ENABLE_FEATURE_EDITING | 2275 | #if ENABLE_FEATURE_EDITING |
2267 | /* This can be stdin, check line editing char[] buffer */ | 2276 | /* This can be stdin, check line editing char[] buffer */ |
2268 | if (i->p && *i->p != '\0') { | 2277 | if (i->p && *i->p != '\0') { |
@@ -2288,10 +2297,18 @@ static int FAST_FUNC file_get(struct in_str *i) | |||
2288 | return ch; | 2297 | return ch; |
2289 | } | 2298 | } |
2290 | 2299 | ||
2291 | static int FAST_FUNC file_peek(struct in_str *i) | 2300 | static int i_peek(struct in_str *i) |
2292 | { | 2301 | { |
2293 | int ch; | 2302 | int ch; |
2294 | 2303 | ||
2304 | if (!i->file) { | ||
2305 | /* string-based in_str */ | ||
2306 | /* Doesn't report EOF on NUL. None of the callers care. */ | ||
2307 | return (unsigned char)*i->p; | ||
2308 | } | ||
2309 | |||
2310 | /* FILE-based in_str */ | ||
2311 | |||
2295 | #if ENABLE_FEATURE_EDITING && ENABLE_HUSH_INTERACTIVE | 2312 | #if ENABLE_FEATURE_EDITING && ENABLE_HUSH_INTERACTIVE |
2296 | /* This can be stdin, check line editing char[] buffer */ | 2313 | /* This can be stdin, check line editing char[] buffer */ |
2297 | if (i->p && *i->p != '\0') | 2314 | if (i->p && *i->p != '\0') |
@@ -2318,23 +2335,6 @@ static int FAST_FUNC file_peek(struct in_str *i) | |||
2318 | return ch; | 2335 | return ch; |
2319 | } | 2336 | } |
2320 | 2337 | ||
2321 | static int FAST_FUNC static_get(struct in_str *i) | ||
2322 | { | ||
2323 | int ch = (unsigned char)*i->p; | ||
2324 | if (ch != '\0') { | ||
2325 | i->p++; | ||
2326 | i->last_char = ch; | ||
2327 | return ch; | ||
2328 | } | ||
2329 | return EOF; | ||
2330 | } | ||
2331 | |||
2332 | static int FAST_FUNC static_peek(struct in_str *i) | ||
2333 | { | ||
2334 | /* Doesn't report EOF on NUL. None of the callers care. */ | ||
2335 | return (unsigned char)*i->p; | ||
2336 | } | ||
2337 | |||
2338 | /* Only ever called if i_peek() was called, and did not return EOF. | 2338 | /* Only ever called if i_peek() was called, and did not return EOF. |
2339 | * IOW: we know the previous peek saw an ordinary char, not EOF, not NUL, | 2339 | * IOW: we know the previous peek saw an ordinary char, not EOF, not NUL, |
2340 | * not end-of-line. Therefore we never need to read a new editing line here. | 2340 | * not end-of-line. Therefore we never need to read a new editing line here. |
@@ -2370,8 +2370,6 @@ static int i_peek2(struct in_str *i) | |||
2370 | static void setup_file_in_str(struct in_str *i, FILE *f) | 2370 | static void setup_file_in_str(struct in_str *i, FILE *f) |
2371 | { | 2371 | { |
2372 | memset(i, 0, sizeof(*i)); | 2372 | memset(i, 0, sizeof(*i)); |
2373 | i->get = file_get; | ||
2374 | i->peek = file_peek; | ||
2375 | /* i->promptmode = 0; - PS1 (memset did it) */ | 2373 | /* i->promptmode = 0; - PS1 (memset did it) */ |
2376 | i->file = f; | 2374 | i->file = f; |
2377 | /* i->p = NULL; */ | 2375 | /* i->p = NULL; */ |
@@ -2380,9 +2378,8 @@ static void setup_file_in_str(struct in_str *i, FILE *f) | |||
2380 | static void setup_string_in_str(struct in_str *i, const char *s) | 2378 | static void setup_string_in_str(struct in_str *i, const char *s) |
2381 | { | 2379 | { |
2382 | memset(i, 0, sizeof(*i)); | 2380 | memset(i, 0, sizeof(*i)); |
2383 | i->get = static_get; | ||
2384 | i->peek = static_peek; | ||
2385 | /* i->promptmode = 0; - PS1 (memset did it) */ | 2381 | /* i->promptmode = 0; - PS1 (memset did it) */ |
2382 | /*i->file = NULL */; | ||
2386 | i->p = s; | 2383 | i->p = s; |
2387 | } | 2384 | } |
2388 | 2385 | ||