diff --git a/src/lj_bcread.c b/src/lj_bcread.c index 3afd8250be..2d84c46736 100644 --- a/src/lj_bcread.c +++ b/src/lj_bcread.c @@ -152,7 +152,7 @@ static uint32_t bcread_uleb128_33(LexState *ls) static void bcread_dbg(LexState *ls, GCproto *pt, MSize sizedbg) { uint32_t *lineinfo = (uint32_t*)proto_lineinfo(pt); - bcread_block(ls, lineinfo, sizedbg); + bcread_block(ls, (void*)lineinfo, sizedbg); /* Swap lineinfo if the endianess differs. */ if (bcread_swap(ls)) { int i; @@ -164,9 +164,7 @@ static void bcread_dbg(LexState *ls, GCproto *pt, MSize sizedbg) static const void *bcread_varinfo(GCproto *pt) { const uint8_t *p = proto_uvinfo(pt); - MSize n = pt->sizeuv; - if (n) while (*p++ || --n) ; - return p; + return p + pt->sizeuv; } /* Read a single constant key/value of a template table. */ @@ -300,7 +298,7 @@ GCproto *lj_bcread_proto(LexState *ls) { GCproto *pt; MSize framesize, numparams, flags, sizeuv, sizekgc, sizekn, sizebc, sizept; - MSize ofsk, ofsuv, ofsdbg; + MSize ofsk, ofsuv, ofsdbg, ofsdeclname = 0; MSize sizedbg = 0; BCLine firstline = 0, numline = 0; @@ -317,6 +315,7 @@ GCproto *lj_bcread_proto(LexState *ls) if (sizedbg) { firstline = bcread_uleb128(ls); numline = bcread_uleb128(ls); + ofsdeclname = bcread_uleb128(ls); } } @@ -364,12 +363,14 @@ GCproto *lj_bcread_proto(LexState *ls) MSize sizeli = (sizebc-1) * sizeof(BCLine); setmref(pt->lineinfo, (char *)pt + ofsdbg); setmref(pt->uvinfo, (char *)pt + ofsdbg + sizeli); + setmref(pt->declname, (char *)pt + ofsdbg + ofsdeclname); bcread_dbg(ls, pt, sizedbg); setmref(pt->varinfo, bcread_varinfo(pt)); } else { setmref(pt->lineinfo, NULL); setmref(pt->uvinfo, NULL); setmref(pt->varinfo, NULL); + setmref(pt->declname, NULL); } return pt; } diff --git a/src/lj_bcwrite.c b/src/lj_bcwrite.c index 69bb430f91..e46e2b8757 100644 --- a/src/lj_bcwrite.c +++ b/src/lj_bcwrite.c @@ -210,7 +210,7 @@ static char *bcwrite_bytecode(BCWriteCtx *ctx, char *p, GCproto *pt) /* Write prototype. */ static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt) { - MSize sizedbg = 0; + MSize sizedbg = 0, ofsdeclname = 0; char *p; /* Recursively write children of prototype. */ @@ -238,12 +238,15 @@ static void bcwrite_proto(BCWriteCtx *ctx, GCproto *pt) p = lj_strfmt_wuleb128(p, pt->sizekn); p = lj_strfmt_wuleb128(p, pt->sizebc-1); if (!ctx->strip) { - if (proto_lineinfo(pt)) + if (proto_lineinfo(pt)) { sizedbg = pt->sizept - (MSize)((char *)proto_lineinfo(pt) - (char *)pt); + ofsdeclname = (MSize)((char*)proto_declname(pt) - (char *)proto_lineinfo(pt)); + } p = lj_strfmt_wuleb128(p, sizedbg); if (sizedbg) { p = lj_strfmt_wuleb128(p, pt->firstline); p = lj_strfmt_wuleb128(p, pt->numline); + p = lj_strfmt_wuleb128(p, ofsdeclname); } } diff --git a/src/lj_lex.c b/src/lj_lex.c index a2cc6b2f52..2265c8836d 100644 --- a/src/lj_lex.c +++ b/src/lj_lex.c @@ -54,7 +54,9 @@ static LJ_NOINLINE LexChar lex_more(LexState *ls) /* Get next character. */ static LJ_AINLINE LexChar lex_next(LexState *ls) { - return (ls->c = ls->p < ls->pe ? (LexChar)(uint8_t)*ls->p++ : lex_more(ls)); + LexChar c = (ls->c = ls->p < ls->pe ? (LexChar)(uint8_t)*ls->p++ : lex_more(ls)); + if (ls->log && ls->log < ls->logend) *ls->log++ = c; + return c; } /* Save character. */ @@ -399,6 +401,8 @@ int lj_lex_setup(lua_State *L, LexState *ls) ls->lookahead = TK_eof; /* No look-ahead token. */ ls->linenumber = 1; ls->lastline = 1; + ls->log = NULL; + ls->logend = NULL; lex_next(ls); /* Read-ahead first char. */ 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). */ @@ -489,6 +493,20 @@ void lj_lex_error(LexState *ls, LexToken tok, ErrMsg em, ...) va_end(argp); } +/* Log the next input characters to a bounded buffer. */ +void lj_lex_log(LexState *ls, char *log, int size) +{ + ls->log = log; + ls->logend = log + size-1; +} + +/* Stop logging input characters. */ +void lj_lex_endlog(LexState *ls) +{ + ls->log = NULL; + ls->logend = NULL; +} + /* Initialize strings for reserved words. */ void lj_lex_init(lua_State *L) { diff --git a/src/lj_lex.h b/src/lj_lex.h index 33fa865726..5d6e7d9eb7 100644 --- a/src/lj_lex.h +++ b/src/lj_lex.h @@ -73,6 +73,8 @@ typedef struct LexState { BCInsLine *bcstack; /* Stack for bytecode instructions/line numbers. */ MSize sizebcstack; /* Size of bytecode stack. */ uint32_t level; /* Syntactical nesting level. */ + char *log; /* Current position where input should be logged. */ + char *logend; /* Last position where input can be logged. */ } LexState; LJ_FUNC int lj_lex_setup(lua_State *L, LexState *ls); @@ -80,6 +82,8 @@ LJ_FUNC void lj_lex_cleanup(lua_State *L, LexState *ls); LJ_FUNC void lj_lex_next(LexState *ls); LJ_FUNC LexToken lj_lex_lookahead(LexState *ls); LJ_FUNC const char *lj_lex_token2str(LexState *ls, LexToken tok); +LJ_FUNC void lj_lex_log(LexState *ls, char *log, int size); +LJ_FUNC void lj_lex_endlog(LexState *ls); LJ_FUNC_NORET void lj_lex_error(LexState *ls, LexToken tok, ErrMsg em, ...); LJ_FUNC void lj_lex_init(lua_State *L); diff --git a/src/lj_obj.h b/src/lj_obj.h index 7586aa55bf..fc6022ef83 100644 --- a/src/lj_obj.h +++ b/src/lj_obj.h @@ -314,6 +314,7 @@ typedef struct GCproto { MRef lineinfo; /* Map from bytecode ins. to source line. */ MRef uvinfo; /* Upvalue names. */ MRef varinfo; /* Names and compressed extents of local variables. */ + MRef declname; /* Declared name of function (null-terminated). */ } GCproto; /* Flags for prototype. */ @@ -347,6 +348,7 @@ typedef struct GCproto { #define proto_lineinfo(pt) (mref((pt)->lineinfo, const uint32_t)) #define proto_uvinfo(pt) (mref((pt)->uvinfo, const uint8_t)) #define proto_varinfo(pt) (mref((pt)->varinfo, const uint8_t)) +#define proto_declname(pt) (mref((pt)->declname, const char)) /* -- Upvalue object ------------------------------------------------------ */ diff --git a/src/lj_parse.c b/src/lj_parse.c index 1b50a640b5..e9672f00d8 100644 --- a/src/lj_parse.c +++ b/src/lj_parse.c @@ -1366,7 +1366,8 @@ static void fs_fixup_line(FuncState *fs, GCproto *pt, } /* Prepare variable info for prototype. */ -static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar) +static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar, + size_t *ofsdeclname, const char *declname) { VarInfo *vs =ls->vstack, *ve; MSize i, n; @@ -1404,14 +1405,24 @@ static size_t fs_prep_var(LexState *ls, FuncState *fs, size_t *ofsvar) } } lj_buf_putb(&ls->sb, '\0'); /* Terminator for varinfo. */ + /* Store function declaration name. */ + *ofsdeclname = sbuflen(&ls->sb); + { + char *p; + int len = strlen(declname) + 1; + p = lj_buf_more(&ls->sb, len); + p = lj_buf_wmem(p, declname, len); + setsbufP(&ls->sb, p); + } return sbuflen(&ls->sb); } /* Fixup variable info for prototype. */ -static void fs_fixup_var(LexState *ls, GCproto *pt, uint8_t *p, size_t ofsvar) +static void fs_fixup_var(LexState *ls, GCproto *pt, uint8_t *p, size_t ofsvar, size_t ofsdeclname) { setmref(pt->uvinfo, p); setmref(pt->varinfo, (char *)p + ofsvar); + setmref(pt->declname, (char*)p + ofsdeclname); memcpy(p, sbufB(&ls->sb), sbuflen(&ls->sb)); /* Copy from temp. buffer. */ } @@ -1466,12 +1477,12 @@ static void fs_fixup_ret(FuncState *fs) } /* Finish a FuncState and return the new prototype. */ -static GCproto *fs_finish(LexState *ls, BCLine line) +static GCproto *fs_finish(LexState *ls, BCLine line, char *declname) { lua_State *L = ls->L; FuncState *fs = ls->fs; BCLine numline = line - fs->linedefined; - size_t sizept, ofsk, ofsuv, ofsli, ofsdbg, ofsvar; + size_t sizept, ofsk, ofsuv, ofsli, ofsdbg, ofsvar, ofsdeclname; GCproto *pt; /* Apply final fixups. */ @@ -1483,7 +1494,7 @@ static GCproto *fs_finish(LexState *ls, BCLine line) ofsk = sizept; sizept += fs->nkn*sizeof(TValue); ofsuv = sizept; sizept += ((fs->nuv+1)&~1)*2; ofsli = sizept; sizept += fs_prep_line(fs, numline); - ofsdbg = sizept; sizept += fs_prep_var(ls, fs, &ofsvar); + ofsdbg = sizept; sizept += fs_prep_var(ls, fs, &ofsvar, &ofsdeclname, declname); /* Allocate prototype and initialize its fields. */ pt = (GCproto *)lj_mem_newgco(L, (MSize)sizept); @@ -1501,7 +1512,7 @@ static GCproto *fs_finish(LexState *ls, BCLine line) fs_fixup_k(fs, pt, (void *)((char *)pt + ofsk)); fs_fixup_uv1(fs, pt, (uint16_t *)((char *)pt + ofsuv)); fs_fixup_line(fs, pt, (void *)((char *)pt + ofsli), numline); - fs_fixup_var(ls, pt, (uint8_t *)((char *)pt + ofsdbg), ofsvar); + fs_fixup_var(ls, pt, (uint8_t *)((char *)pt + ofsdbg), ofsvar, ofsdeclname); L->top--; /* Pop table of constants. */ ls->vtop = fs->vbase; /* Reset variable stack. */ @@ -1742,7 +1753,8 @@ static BCReg parse_params(LexState *ls, int needself) static void parse_chunk(LexState *ls); /* Parse body of a function. */ -static void parse_body(LexState *ls, ExpDesc *e, int needself, BCLine line) +static void parse_body(LexState *ls, ExpDesc *e, int needself, BCLine line, + char *declname) { FuncState fs, *pfs = ls->fs; FuncScope bl; @@ -1757,7 +1769,7 @@ static void parse_body(LexState *ls, ExpDesc *e, int needself, BCLine line) bcemit_AD(&fs, BC_FUNCF, 0, 0); /* Placeholder. */ parse_chunk(ls); if (ls->tok != TK_end) lex_match(ls, TK_end, TK_function, line); - pt = fs_finish(ls, (ls->lastline = ls->linenumber)); + pt = fs_finish(ls, (ls->lastline = ls->linenumber), declname); pfs->bcbase = ls->bcstack + oldbase; /* May have been reallocated. */ pfs->bclim = (BCPos)(ls->sizebcstack - oldbase); /* Store new prototype in the constant array of the parent. */ @@ -1908,7 +1920,7 @@ static void expr_simple(LexState *ls, ExpDesc *v) return; case TK_function: lj_lex_next(ls); - parse_body(ls, v, 0, ls->linenumber); + parse_body(ls, v, 0, ls->linenumber, ""); return; default: expr_primary(ls, v); @@ -2137,9 +2149,24 @@ static void parse_call_assign(LexState *ls) } } +/* Convert the logged input into a canonical function declaration name. */ +static char *log_declname(char *log) +{ + char *end = log + strlen(log) - 1; + /* Strip off trailing chars e.g. change "myfunc (X" to "myfunc". */ + while (end > log && *end != '(') end--; /* Rewind to '('. */ + if (*end != '(') return log; else end--; /* Skip '(' if present. */ + while (end > log && *end == ' ') end--; /* Rewind over spaces. */ + *(end+1) = '\0'; /* Truncate. */ + return log; +} + /* Parse 'local' statement. */ static void parse_local(LexState *ls) { + char log[128]; + memset(&log[0], 0, sizeof(log)); + lj_lex_log(ls, &log[0], sizeof(log)-1); if (lex_opt(ls, TK_function)) { /* Local function declaration. */ ExpDesc v, b; FuncState *fs = ls->fs; @@ -2148,7 +2175,8 @@ static void parse_local(LexState *ls) v.u.s.aux = fs->varmap[fs->freereg]; bcreg_reserve(fs, 1); var_add(ls, 1); - parse_body(ls, &b, 0, ls->linenumber); + lj_lex_endlog(ls); /* Captured declared function name. */ + parse_body(ls, &b, 0, ls->linenumber, log_declname(log)); /* bcemit_store(fs, &v, &b) without setting VSTACK_VAR_RW. */ expr_free(fs, &b); expr_toreg(fs, &b, v.u.s.info); @@ -2157,6 +2185,7 @@ static void parse_local(LexState *ls) } else { /* Local variable declaration. */ ExpDesc e; BCReg nexps, nvars = 0; + lj_lex_endlog(ls); /* Not used for variables. */ do { /* Collect LHS. */ var_new(ls, nvars++, lex_str(ls)); } while (lex_opt(ls, ',')); @@ -2177,6 +2206,9 @@ static void parse_func(LexState *ls, BCLine line) FuncState *fs; ExpDesc v, b; int needself = 0; + char log[128]; + memset(log, 0, sizeof(log)); + lj_lex_log(ls, log, sizeof(log)-1); lj_lex_next(ls); /* Skip 'function'. */ /* Parse function name. */ var_lookup(ls, &v); @@ -2186,7 +2218,8 @@ static void parse_func(LexState *ls, BCLine line) needself = 1; expr_field(ls, &v); } - parse_body(ls, &b, needself, line); + lj_lex_endlog(ls); + parse_body(ls, &b, needself, line, log_declname(log)); fs = ls->fs; bcemit_store(fs, &v, &b); fs->bcbase[fs->pc - 1].line = line; /* Set line for the store. */ @@ -2616,7 +2649,7 @@ GCproto *lj_parse(LexState *ls) parse_chunk(ls); if (ls->tok != TK_eof) err_token(ls, TK_eof); - pt = fs_finish(ls, ls->linenumber); + pt = fs_finish(ls, ls->linenumber, ""); L->top--; /* Drop chunkname. */ lua_assert(fs.prev == NULL); lua_assert(ls->fs == NULL); diff --git a/src/reusevm/lj_vm.S b/src/reusevm/lj_vm.S index c0abc094f8..3ff330bcb4 100644 --- a/src/reusevm/lj_vm.S +++ b/src/reusevm/lj_vm.S @@ -797,7 +797,7 @@ lj_BC_CALLT: .byte 20,72,139,93,32,139,11,15,182,233,15,182,205,72,131,195 .byte 4,65,255,36,238,247,195,3,0,0,0,117,228,15,182,75 .byte 253,72,247,217,76,139,124,202,224,73,193,231,17,73,193,239 - .byte 17,77,139,127,32,77,139,127,184,235,198,72,131,235,3,247 + .byte 17,77,139,127,32,77,139,127,176,235,198,72,131,235,3,247 .byte 195,7,0,0,0,117,15,72,41,218,73,137,215,72,139,90 .byte 248,233,119,255,255,255,131,195,3,233,111,255,255,255 @@ -881,7 +881,7 @@ lj_BC_RET: .byte 111,240,73,131,199,8,131,232,1,117,239,139,4,36,15,182 .byte 107,255,57,197,119,51,15,182,75,253,72,247,217,72,141,84 .byte 202,240,76,139,122,240,73,193,231,17,73,193,239,17,77,139 - .byte 127,32,77,139,127,184,139,3,15,182,204,15,182,232,72,131 + .byte 127,32,77,139,127,176,139,3,15,182,204,15,182,232,72,131 .byte 195,4,193,232,16,65,255,36,238,73,199,71,240,255,255,255 .byte 255,73,131,199,8,72,131,192,1,235,183,72,141,107,253,247 .byte 197,7,0,0,0,15,133,154,5,0,0,72,41,234,72,1 @@ -895,7 +895,7 @@ lj_BC_RET0: .byte 72,139,90,248,137,4,36,247,195,3,0,0,0,117,71,56 .byte 67,255,119,51,15,182,75,253,72,247,217,72,141,84,202,240 .byte 76,139,122,240,73,193,231,17,73,193,239,17,77,139,127,32 - .byte 77,139,127,184,139,3,15,182,204,15,182,232,72,131,195,4 + .byte 77,139,127,176,139,3,15,182,204,15,182,232,72,131,195,4 .byte 193,232,16,65,255,36,238,72,199,68,194,232,255,255,255,255 .byte 72,131,192,1,235,185,72,141,107,253,247,197,7,0,0,0 .byte 15,133,41,5,0,0,72,41,234,235,149 @@ -908,7 +908,7 @@ lj_BC_RET1: .byte 193,225,3,72,139,90,248,137,4,36,247,195,3,0,0,0 .byte 117,79,72,139,44,10,72,137,106,240,56,67,255,119,51,15 .byte 182,75,253,72,247,217,72,141,84,202,240,76,139,122,240,73 - .byte 193,231,17,73,193,239,17,77,139,127,32,77,139,127,184,139 + .byte 193,231,17,73,193,239,17,77,139,127,32,77,139,127,176,139 .byte 3,15,182,204,15,182,232,72,131,195,4,193,232,16,65,255 .byte 36,238,72,199,68,194,232,255,255,255,255,72,131,192,1,235 .byte 185,72,141,107,253,247,197,7,0,0,0,15,133,179,4,0 @@ -1045,8 +1045,8 @@ lj_BC_FUNCF: .type lj_BC_IFUNCF, @function .size lj_BC_IFUNCF, 68 lj_BC_IFUNCF: - .byte 76,139,123,180,72,139,108,36,16,72,141,12,202,72,59,77 - .byte 48,15,135,81,3,0,0,15,182,75,158,57,200,118,19,139 + .byte 76,139,123,172,72,139,108,36,16,72,141,12,202,72,59,77 + .byte 48,15,135,81,3,0,0,15,182,75,150,57,200,118,19,139 .byte 3,15,182,204,15,182,232,72,131,195,4,193,232,16,65,255 .byte 36,238,72,199,68,194,248,255,255,255,255,131,192,1,57,200 .byte 118,240,235,219 @@ -1056,8 +1056,8 @@ lj_BC_IFUNCF: .type lj_BC_JFUNCF, @function .size lj_BC_JFUNCF, 58 lj_BC_JFUNCF: - .byte 76,139,123,180,72,139,108,36,16,72,141,12,202,72,59,77 - .byte 48,15,135,13,3,0,0,15,182,75,158,57,200,118,9,15 + .byte 76,139,123,172,72,139,108,36,16,72,141,12,202,72,59,77 + .byte 48,15,135,13,3,0,0,15,182,75,150,57,200,118,9,15 .byte 183,67,254,233,51,255,255,255,72,199,68,194,248,255,255,255 .byte 255,131,192,1,57,200,118,240,235,229 @@ -1075,10 +1075,10 @@ lj_BC_IFUNCV: .byte 141,44,197,11,0,0,0,72,141,68,194,8,76,139,122,240 .byte 72,137,104,248,76,137,120,240,72,139,108,36,16,72,141,12 .byte 200,72,59,77,48,15,135,185,2,0,0,72,137,209,72,137 - .byte 194,15,182,107,158,133,237,116,37,72,131,193,8,72,131,193 + .byte 194,15,182,107,150,133,237,116,37,72,131,193,8,72,131,193 .byte 8,72,57,209,115,47,76,139,121,240,76,137,56,72,131,192 .byte 8,72,199,65,240,255,255,255,255,131,237,1,117,223,76,139 - .byte 123,180,139,3,15,182,204,15,182,232,72,131,195,4,193,232 + .byte 123,172,139,3,15,182,204,15,182,232,72,131,195,4,193,232 .byte 16,65,255,36,238,72,199,0,255,255,255,255,72,131,192,8 .byte 131,237,1,117,240,235,215 @@ -1233,7 +1233,7 @@ lj_vm_growstack_v: .type lj_vm_growstack_f, @function .size lj_vm_growstack_f, 86 lj_vm_growstack_f: - .byte 72,141,68,194,248,15,182,75,159,72,131,195,4,72,137,85 + .byte 72,141,68,194,248,15,182,75,151,72,131,195,4,72,137,85 .byte 32,72,137,69,40,72,137,92,36,24,72,137,206,72,137,239 call lj_state_growstack .byte 72,139,85,32,72,139,69,40,72,139,106,240,72,193,229,17 @@ -1314,7 +1314,7 @@ lj_cont_dispatch: .byte 72,1,209,72,131,227,248,72,137,213,72,41,218,72,199,68 .byte 193,248,255,255,255,255,72,137,200,72,139,93,232,72,139,77 .byte 224,72,131,249,1,118,22,76,139,122,240,73,193,231,17,73 - .byte 193,239,17,77,139,127,32,77,139,127,184,255,225,15,132,22 + .byte 193,239,17,77,139,127,32,77,139,127,176,255,225,15,132,22 .byte 31,0,0,72,41,213,193,237,3,141,69,253,233,84,24,0 .byte 0 @@ -2477,7 +2477,7 @@ lj_cont_hook: .size lj_vm_hotloop, 66 lj_vm_hotloop: .byte 72,139,106,240,72,193,229,17,72,193,237,17,72,139,109,32 - .byte 15,182,69,163,72,141,4,194,72,139,108,36,16,72,137,85 + .byte 15,182,69,155,72,141,4,194,72,139,108,36,16,72,137,85 .byte 32,72,137,69,40,72,137,222,73,141,190,80,243,255,255,73 .byte 137,174,224,243,255,255,72,137,92,36,24 call lj_trace_hot @@ -2553,13 +2553,13 @@ lj_vm_exit_interp: .byte 114,7,69,137,150,48,241,255,255,76,139,105,248,76,139,33 .byte 72,137,204,133,192,15,136,134,0,0,0,72,139,108,36,16 .byte 137,4,36,76,139,122,240,73,193,231,17,73,193,239,17,77 - .byte 139,127,32,77,139,127,184,72,137,85,32,73,199,134,16,242 + .byte 139,127,32,77,139,127,176,72,137,85,32,73,199,134,16,242 .byte 255,255,0,0,0,0,69,139,150,40,241,255,255,65,199,134 .byte 40,241,255,255,255,255,255,255,139,3,15,182,204,15,182,232 .byte 72,131,195,4,193,232,16,131,253,89,114,8,131,253,97,115 .byte 7,139,4,36,65,255,36,238,72,139,66,248,169,3,0,0 .byte 0,117,238,15,182,64,253,72,247,216,76,139,124,194,224,73 - .byte 193,231,17,73,193,239,17,77,139,127,32,77,139,127,184,235 + .byte 193,231,17,73,193,239,17,77,139,127,32,77,139,127,176,235 .byte 208,72,247,216,72,137,239,72,137,198 call lj_err_throw