From 3c0157f4262813efd0b0d8284810ff5a9e71d96a Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Thu, 28 Feb 2013 02:31:30 +0100 Subject: [PATCH] String buffer refactoring, part 3. Switch to pointers for start/end of buffer in lexer. --- src/lj_bcread.c | 88 ++++++++++++++++++++++--------------------------- src/lj_lex.c | 18 +++++----- src/lj_lex.h | 4 +-- src/lj_lib.c | 2 +- 4 files changed, 50 insertions(+), 62 deletions(-) diff --git a/src/lj_bcread.c b/src/lj_bcread.c index 5be34757..fcc2aa1d 100644 --- a/src/lj_bcread.c +++ b/src/lj_bcread.c @@ -43,7 +43,7 @@ static LJ_NOINLINE void bcread_error(LexState *ls, ErrMsg em) lj_err_throw(L, LUA_ERRSYNTAX); } -/* Refill buffer if needed. */ +/* Refill buffer. */ static LJ_NOINLINE void bcread_fill(LexState *ls, MSize len, int need) { lua_assert(len != 0); @@ -51,61 +51,61 @@ static LJ_NOINLINE void bcread_fill(LexState *ls, MSize len, int need) bcread_error(ls, LJ_ERR_BCBAD); do { const char *buf; - size_t size; - if (ls->n) { /* Copy remainder to buffer. */ + size_t sz; + char *p = sbufB(&ls->sb); + MSize n = (MSize)(ls->pe - ls->p); + if (n) { /* Copy remainder to buffer. */ if (sbuflen(&ls->sb)) { /* Move down in buffer. */ - lua_assert(ls->p + ls->n == sbufP(&ls->sb)); - if (ls->n != sbuflen(&ls->sb)) - memmove(sbufB(&ls->sb), ls->p, ls->n); + lua_assert(ls->pe == sbufP(&ls->sb)); + if (ls->p != p) memmove(p, ls->p, n); } else { /* Copy from buffer provided by reader. */ - memcpy(lj_buf_need(ls->L, &ls->sb, len), ls->p, ls->n); + p = lj_buf_need(ls->L, &ls->sb, len); + memcpy(p, ls->p, n); } - ls->p = sbufB(&ls->sb); + ls->p = p; + ls->pe = p + n; } - setsbufP(&ls->sb, sbufB(&ls->sb) + ls->n); - buf = ls->rfunc(ls->L, ls->rdata, &size); /* Get more data from reader. */ - if (buf == NULL || size == 0) { /* EOF? */ + setsbufP(&ls->sb, p + n); + buf = ls->rfunc(ls->L, ls->rdata, &sz); /* Get more data from reader. */ + if (buf == NULL || sz == 0) { /* EOF? */ if (need) bcread_error(ls, LJ_ERR_BCBAD); ls->c = -1; /* Only bad if we get called again. */ break; } - if (sbuflen(&ls->sb)) { /* Append to buffer. */ - MSize n = sbuflen(&ls->sb) + (MSize)size; - char *p = lj_buf_need(ls->L, &ls->sb, n < len ? len : n); - memcpy(sbufP(&ls->sb), buf, size); - setsbufP(&ls->sb, sbufB(&ls->sb) + n); - ls->n = n; + if (n) { /* Append to buffer. */ + n += (MSize)sz; + p = lj_buf_need(ls->L, &ls->sb, n < len ? len : n); + memcpy(sbufP(&ls->sb), buf, sz); + setsbufP(&ls->sb, p + n); ls->p = p; + ls->pe = p + n; } else { /* Return buffer provided by reader. */ - ls->n = (MSize)size; ls->p = buf; + ls->pe = buf + sz; } - } while (ls->n < len); + } while (ls->p + len > ls->pe); } /* Need a certain number of bytes. */ static LJ_AINLINE void bcread_need(LexState *ls, MSize len) { - if (LJ_UNLIKELY(ls->n < len)) + if (LJ_UNLIKELY(ls->p + len > ls->pe)) bcread_fill(ls, len, 1); } /* Want to read up to a certain number of bytes, but may need less. */ static LJ_AINLINE void bcread_want(LexState *ls, MSize len) { - if (LJ_UNLIKELY(ls->n < len)) + if (LJ_UNLIKELY(ls->p + len > ls->pe)) bcread_fill(ls, len, 0); } -#define bcread_dec(ls) check_exp(ls->n > 0, ls->n--) -#define bcread_consume(ls, len) check_exp(ls->n >= (len), ls->n -= (len)) - /* Return memory block from buffer. */ -static uint8_t *bcread_mem(LexState *ls, MSize len) +static LJ_AINLINE uint8_t *bcread_mem(LexState *ls, MSize len) { uint8_t *p = (uint8_t *)ls->p; - bcread_consume(ls, len); - ls->p = (char *)p + len; + ls->p += len; + lua_assert(ls->p <= ls->pe); return p; } @@ -118,25 +118,15 @@ static void bcread_block(LexState *ls, void *q, MSize len) /* Read byte from buffer. */ static LJ_AINLINE uint32_t bcread_byte(LexState *ls) { - bcread_dec(ls); + lua_assert(ls->p < ls->pe); return (uint32_t)(uint8_t)*ls->p++; } /* Read ULEB128 value from buffer. */ -static uint32_t bcread_uleb128(LexState *ls) +static LJ_AINLINE uint32_t bcread_uleb128(LexState *ls) { - const uint8_t *p = (const uint8_t *)ls->p; - uint32_t v = *p++; - if (LJ_UNLIKELY(v >= 0x80)) { - int sh = 0; - v &= 0x7f; - do { - v |= ((*p & 0x7f) << (sh += 7)); - bcread_dec(ls); - } while (*p++ >= 0x80); - } - bcread_dec(ls); - ls->p = (char *)p; + uint32_t v = lj_buf_ruleb128(&ls->p); + lua_assert(ls->p <= ls->pe); return v; } @@ -150,11 +140,10 @@ static uint32_t bcread_uleb128_33(LexState *ls) v &= 0x3f; do { v |= ((*p & 0x7f) << (sh += 7)); - bcread_dec(ls); } while (*p++ >= 0x80); } - bcread_dec(ls); ls->p = (char *)p; + lua_assert(ls->p <= ls->pe); return v; } @@ -438,24 +427,25 @@ GCproto *lj_bcread(LexState *ls) bcread_error(ls, LJ_ERR_BCFMT); for (;;) { /* Process all prototypes in the bytecode dump. */ GCproto *pt; - MSize len, startn; + MSize len; + const char *startp; /* Read length. */ - if (ls->n > 0 && ls->p[0] == 0) { /* Shortcut EOF. */ - ls->n--; ls->p++; + if (ls->p < ls->pe && ls->p[0] == 0) { /* Shortcut EOF. */ + ls->p++; break; } bcread_want(ls, 5); len = bcread_uleb128(ls); if (!len) break; /* EOF */ bcread_need(ls, len); - startn = ls->n; + startp = ls->p; pt = lj_bcread_proto(ls); - if (len != startn - ls->n) + if (ls->p != startp + len) bcread_error(ls, LJ_ERR_BCBAD); setprotoV(L, L->top, pt); incr_top(L); } - if ((int32_t)ls->n > 0 || L->top-1 != bcread_oldtop(L, ls)) + if (ls->p < ls->pe || L->top-1 != bcread_oldtop(L, ls)) bcread_error(ls, LJ_ERR_BCBAD); /* Pop off last prototype. */ L->top--; diff --git a/src/lj_lex.c b/src/lj_lex.c index 2c5128e7..5a8f1003 100644 --- a/src/lj_lex.c +++ b/src/lj_lex.c @@ -45,17 +45,17 @@ TKDEF(TKSTR1, TKSTR2) static LJ_NOINLINE LexChar lex_more(LexState *ls) { size_t sz; - const char *buf = ls->rfunc(ls->L, ls->rdata, &sz); - if (buf == NULL || sz == 0) return LEX_EOF; - ls->n = (MSize)sz - 1; - ls->p = buf; - return (LexChar)(uint8_t)*ls->p++; + const char *p = ls->rfunc(ls->L, ls->rdata, &sz); + if (p == NULL || sz == 0) return LEX_EOF; + ls->pe = p + sz; + ls->p = p + 1; + return (LexChar)(uint8_t)p[0]; } /* Get next character. */ static LJ_AINLINE LexChar lex_next(LexState *ls) { - return (ls->c = ls->n ? (ls->n--,(LexChar)(uint8_t)*ls->p++) : lex_more(ls)); + return (ls->c = ls->p < ls->pe ? (LexChar)(uint8_t)*ls->p++ : lex_more(ls)); } /* Save character. */ @@ -368,8 +368,7 @@ int lj_lex_setup(lua_State *L, LexState *ls) int header = 0; ls->L = L; ls->fs = NULL; - ls->n = 0; - ls->p = NULL; + ls->pe = ls->p = NULL; ls->vstack = NULL; ls->sizevstack = 0; ls->vtop = 0; @@ -379,9 +378,8 @@ int lj_lex_setup(lua_State *L, LexState *ls) ls->linenumber = 1; ls->lastline = 1; lex_next(ls); /* Read-ahead first char. */ - if (ls->c == 0xef && ls->n >= 2 && (uint8_t)ls->p[0] == 0xbb && + if (ls->c == 0xef && ls->p + 2 <= ls->pe && (uint8_t)ls->p[0] == 0xbb && (uint8_t)ls->p[1] == 0xbf) { /* Skip UTF-8 BOM (if buffered). */ - ls->n -= 2; ls->p += 2; lex_next(ls); header = 1; diff --git a/src/lj_lex.h b/src/lj_lex.h index 71a7c1de..3e76e72a 100644 --- a/src/lj_lex.h +++ b/src/lj_lex.h @@ -54,11 +54,11 @@ typedef struct LexState { struct lua_State *L; /* Lua state. */ TValue tokval; /* Current token value. */ TValue lookaheadval; /* Lookahead token value. */ + const char *p; /* Current position in input buffer. */ + const char *pe; /* End of input buffer. */ LexChar c; /* Current character. */ LexToken tok; /* Current token. */ LexToken lookahead; /* Lookahead token. */ - MSize n; /* Bytes left in input buffer. */ - const char *p; /* Current position in input buffer. */ SBuf sb; /* String buffer for tokens. */ lua_Reader rfunc; /* Reader callback. */ void *rdata; /* Reader callback data. */ diff --git a/src/lj_lib.c b/src/lj_lib.c index 79c2c99a..b6aa97a0 100644 --- a/src/lj_lib.c +++ b/src/lj_lib.c @@ -55,7 +55,7 @@ static const uint8_t *lib_read_lfunc(lua_State *L, const uint8_t *p, GCtab *tab) memset(&ls, 0, sizeof(ls)); ls.L = L; ls.p = (const char *)(p+len); - ls.n = ~(MSize)0; + ls.pe = (const char *)~(uintptr_t)0; ls.c = -1; ls.level = (BCDUMP_F_STRIP|(LJ_BE*BCDUMP_F_BE)); ls.chunkname = name;