Major redesign of function call handling.

Drop call gates. Use function headers, dispatched like bytecodes.
Emit BC_FUNCF/BC_FUNCV bytecode at PC 0 for all Lua functions.
C functions and ASM fast functions get extra bytecodes.
Modify internal calling convention: new base in BASE (formerly in RA).
Can now use better C function wrapper semantics (dynamic on/off).
Prerequisite for call hooks with zero-overhead if disabled.
Prerequisite for compiling recursive calls.
Prerequisite for efficient 32/64 bit prototype guards.
This commit is contained in:
Mike Pall
2010-02-13 04:51:56 +01:00
parent 4f8d7be8ea
commit c93138b59e
34 changed files with 4410 additions and 4264 deletions

View File

@@ -1036,7 +1036,10 @@ static void fs_fixup_bc(FuncState *fs, GCproto *pt, BCIns *bc, BCLine *lineinfo)
setmref(pt->lineinfo, lineinfo);
pt->sizebc = n;
bc[n] = ~0u; /* Close potentially uninitialized gap between bc and kgc. */
for (i = 0; i < n; i++) {
bc[0] = BCINS_AD((fs->flags & PROTO_IS_VARARG) ? BC_FUNCV : BC_FUNCF,
fs->framesize, 0);
lineinfo[0] = fs->linedefined;
for (i = 1; i < n; i++) {
bc[i] = base[i].ins;
lineinfo[i] = base[i].line;
}
@@ -1181,7 +1184,6 @@ static GCproto *fs_finish(LexState *ls, BCLine line)
pt->flags = fs->flags;
pt->numparams = fs->numparams;
pt->framesize = fs->framesize;
pt->linedefined = fs->linedefined;
pt->lastlinedefined = line;
fs_fixup_bc(fs, pt, (BCIns *)((char *)pt + sizeof(GCproto)),
@@ -1416,29 +1418,30 @@ static void parse_chunk(LexState *ls);
/* Parse body of a function. */
static void parse_body(LexState *ls, ExpDesc *e, int needself, BCLine line)
{
FuncState cfs, *fs = ls->fs;
FuncState fs, *pfs = ls->fs;
BCReg kidx;
BCLine lastline;
GCproto *pt;
ptrdiff_t oldbase = fs->bcbase - ls->bcstack;
fs_init(ls, &cfs);
cfs.linedefined = line;
cfs.numparams = (uint8_t)parse_params(ls, needself);
cfs.bcbase = fs->bcbase + fs->pc;
cfs.bclim = fs->bclim - fs->pc;
ptrdiff_t oldbase = pfs->bcbase - ls->bcstack;
fs_init(ls, &fs);
fs.linedefined = line;
fs.numparams = (uint8_t)parse_params(ls, needself);
fs.bcbase = pfs->bcbase + pfs->pc;
fs.bclim = pfs->bclim - pfs->pc;
bcemit_AD(&fs, BC_FUNCF, 0, 0); /* Placeholder. */
parse_chunk(ls);
lastline = ls->linenumber;
lex_match(ls, TK_end, TK_function, line);
pt = fs_finish(ls, lastline);
fs->bcbase = ls->bcstack + oldbase; /* May have been reallocated. */
fs->bclim = (BCPos)(ls->sizebcstack - oldbase);
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. */
kidx = const_gc(fs, obj2gco(pt), LJ_TPROTO);
expr_init(e, VRELOCABLE, bcemit_AD(fs, BC_FNEW, 0, kidx));
if (!(fs->flags & PROTO_HAS_FNEW)) {
if (fs->flags & PROTO_HAS_RETURN)
fs->flags |= PROTO_FIXUP_RETURN;
fs->flags |= PROTO_HAS_FNEW;
kidx = const_gc(pfs, obj2gco(pt), LJ_TPROTO);
expr_init(e, VRELOCABLE, bcemit_AD(pfs, BC_FNEW, 0, kidx));
if (!(pfs->flags & PROTO_HAS_FNEW)) {
if (pfs->flags & PROTO_HAS_RETURN)
pfs->flags |= PROTO_FIXUP_RETURN;
pfs->flags |= PROTO_HAS_FNEW;
}
}
@@ -2227,6 +2230,7 @@ GCproto *lj_parse(LexState *ls)
fs.bcbase = NULL;
fs.bclim = 0;
fs.flags |= PROTO_IS_VARARG; /* Main chunk is always a vararg func. */
bcemit_AD(&fs, BC_FUNCV, 0, 0); /* Placeholder. */
lj_lex_next(ls); /* Read-ahead first token. */
parse_chunk(ls);
if (ls->token != TK_eof)