[git commit] hush: make getch/peek functions directly called

Denys Vlasenko vda.linux at googlemail.com
Tue Nov 8 21:35:05 UTC 2016


commit: https://git.busybox.net/busybox/commit/?id=87e039d0160be16a9a242f74af2e90cdb9f97e12
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

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 at googlemail.com>
---
 shell/hush.c | 51 ++++++++++++++++++++++++---------------------------
 1 file changed, 24 insertions(+), 27 deletions(-)

diff --git a/shell/hush.c b/shell/hush.c
index 57252a1..2f07f4a 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -469,11 +469,7 @@ typedef struct in_str {
 	int peek_buf[2];
 	int last_char;
 	FILE *file;
-	int (*get) (struct in_str *) FAST_FUNC;
-	int (*peek) (struct in_str *) FAST_FUNC;
 } in_str;
-#define i_getch(input) ((input)->get(input))
-#define i_peek(input)  ((input)->peek(input))
 
 /* The descrip member of this structure is only used to make
  * debugging output pretty */
@@ -2259,10 +2255,23 @@ static inline int fgetc_interactive(struct in_str *i)
 }
 #endif  /* INTERACTIVE */
 
-static int FAST_FUNC file_get(struct in_str *i)
+static int i_getch(struct in_str *i)
 {
 	int ch;
 
+	if (!i->file) {
+		/* string-based in_str */
+		ch = (unsigned char)*i->p;
+		if (ch != '\0') {
+			i->p++;
+			i->last_char = ch;
+			return ch;
+		}
+		return EOF;
+	}
+
+	/* FILE-based in_str */
+
 #if ENABLE_FEATURE_EDITING
 	/* This can be stdin, check line editing char[] buffer */
 	if (i->p && *i->p != '\0') {
@@ -2288,10 +2297,18 @@ static int FAST_FUNC file_get(struct in_str *i)
 	return ch;
 }
 
-static int FAST_FUNC file_peek(struct in_str *i)
+static int i_peek(struct in_str *i)
 {
 	int ch;
 
+	if (!i->file) {
+		/* string-based in_str */
+		/* Doesn't report EOF on NUL. None of the callers care. */
+		return (unsigned char)*i->p;
+	}
+
+	/* FILE-based in_str */
+
 #if ENABLE_FEATURE_EDITING && ENABLE_HUSH_INTERACTIVE
 	/* This can be stdin, check line editing char[] buffer */
 	if (i->p && *i->p != '\0')
@@ -2318,23 +2335,6 @@ static int FAST_FUNC file_peek(struct in_str *i)
 	return ch;
 }
 
-static int FAST_FUNC static_get(struct in_str *i)
-{
-	int ch = (unsigned char)*i->p;
-	if (ch != '\0') {
-		i->p++;
-		i->last_char = ch;
-		return ch;
-	}
-	return EOF;
-}
-
-static int FAST_FUNC static_peek(struct in_str *i)
-{
-	/* Doesn't report EOF on NUL. None of the callers care. */
-	return (unsigned char)*i->p;
-}
-
 /* Only ever called if i_peek() was called, and did not return EOF.
  * IOW: we know the previous peek saw an ordinary char, not EOF, not NUL,
  * 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)
 static void setup_file_in_str(struct in_str *i, FILE *f)
 {
 	memset(i, 0, sizeof(*i));
-	i->get = file_get;
-	i->peek = file_peek;
 	/* i->promptmode = 0; - PS1 (memset did it) */
 	i->file = f;
 	/* i->p = NULL; */
@@ -2380,9 +2378,8 @@ static void setup_file_in_str(struct in_str *i, FILE *f)
 static void setup_string_in_str(struct in_str *i, const char *s)
 {
 	memset(i, 0, sizeof(*i));
-	i->get = static_get;
-	i->peek = static_peek;
 	/* i->promptmode = 0; - PS1 (memset did it) */
+	/*i->file = NULL */;
 	i->p = s;
 }
 


More information about the busybox-cvs mailing list