aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2016-11-08 22:35:05 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2016-11-08 22:35:05 +0100
commit87e039d0160be16a9a242f74af2e90cdb9f97e12 (patch)
tree6d426cbcb065ba5dc1a7e10717d67a1e74987d88
parent00a06b971531031103c25d650e2078c801afbe39 (diff)
downloadbusybox-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.c51
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
2262static int FAST_FUNC file_get(struct in_str *i) 2258static 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
2291static int FAST_FUNC file_peek(struct in_str *i) 2300static 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
2321static 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
2332static 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)
2370static void setup_file_in_str(struct in_str *i, FILE *f) 2370static 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)
2380static void setup_string_in_str(struct in_str *i, const char *s) 2378static 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