1
0
mirror of https://github.com/lua/lua.git synced 2025-01-28 06:03:00 +08:00

new way to handle global state during compilation.

This commit is contained in:
Roberto Ierusalimschy 1997-07-29 17:38:45 -03:00
parent 05e8b0ae80
commit 2c580a0afb
4 changed files with 164 additions and 188 deletions

35
func.c
View File

@ -9,9 +9,6 @@
static TFunc *function_root = NULL;
static LocVar *currvars = NULL;
static int numcurrvars = 0;
static int maxcurrvars = 0;
/*
@ -105,38 +102,6 @@ void lua_funcinfo (lua_Object func, char **filename, int *linedefined)
}
}
/*
** Stores information to know that variable has been declared in given line
*/
void luaI_registerlocalvar (TaggedString *varname, int line)
{
if (numcurrvars >= maxcurrvars)
maxcurrvars = growvector(&currvars, maxcurrvars, LocVar, "", MAX_WORD);
currvars[numcurrvars].varname = varname;
currvars[numcurrvars].line = line;
numcurrvars++;
}
/*
** Stores information to know that variable has been out of scope in given line
*/
void luaI_unregisterlocalvar (int line)
{
luaI_registerlocalvar(NULL, line);
}
/*
** Copies "currvars" into a new area and store it in function header.
** The values (varname = NULL, line = -1) signal the end of vector.
*/
void luaI_closelocalvars (TFunc *func)
{
func->locvars = newvector (numcurrvars+1, LocVar);
memcpy (func->locvars, currvars, numcurrvars*sizeof(LocVar));
func->locvars[numcurrvars].varname = NULL;
func->locvars[numcurrvars].line = -1;
numcurrvars = 0; /* prepares for next function */
}
/*
** Look for n-esim local variable at line "line" in function "func".

5
func.h
View File

@ -1,5 +1,5 @@
/*
** $Id: func.h,v 1.9 1997/05/14 18:38:29 roberto Exp roberto $
** $Id: func.h,v 1.10 1997/07/29 19:44:02 roberto Exp roberto $
*/
#ifndef func_h
@ -36,9 +36,6 @@ void luaI_insertfunction (TFunc *f);
void luaI_initTFunc (TFunc *f);
void luaI_freefunc (TFunc *f);
void luaI_registerlocalvar (TaggedString *varname, int line);
void luaI_unregisterlocalvar (int line);
void luaI_closelocalvars (TFunc *func);
char *luaI_getlocalname (TFunc *func, int local_number, int line);
#endif

309
lua.stx
View File

@ -1,6 +1,6 @@
%{
char *rcs_luastx = "$Id: lua.stx,v 3.46 1997/03/31 14:19:01 roberto Exp roberto $";
char *rcs_luastx = "$Id: lua.stx,v 3.47 1997/06/19 17:46:12 roberto Exp roberto $";
#include <stdio.h>
#include <stdlib.h>
@ -28,16 +28,21 @@ int yyparse (void);
#endif
#ifndef CODE_BLOCK
#define CODE_BLOCK 256
#define CODE_BLOCK 1000
#endif
static int maxcode;
static int maxmain;
static int maxcurr;
static Byte *funcCode = NULL;
static Byte **initcode;
static Byte *basepc;
static int maincode;
static int pc;
#define MAXLOCALS 32
/* state needed to generate code for a given function */
struct State {
TFunc *f; /* current function header */
int codesize;
int pc; /* next position to code */
TaggedString *localvar[MAXLOCALS]; /* store local variable names */
int nlocalvar; /* number of active local variables */
int nvars; /* total number of local variables (for debugging information) */
int maxvars; /* = -1 if no debug information */
} stateMain, stateFunc, *currState;
#define MAXVAR 32
@ -45,9 +50,6 @@ static Long varbuffer[MAXVAR]; /* variables in an assignment list;
it's long to store negative Word values */
static int nvarbuffer=0; /* number of variables at a list */
#define MAXLOCALS 32
static TaggedString *localvar[MAXLOCALS]; /* store local variable names */
static int nlocalvar=0; /* number of local variables */
#define MAXFIELDS FIELDS_PER_FLUSH*2
@ -62,43 +64,44 @@ static void yyerror (char *s)
static void check_space (int i)
{
if (pc+i>maxcurr-1) /* 1 byte free to code HALT of main code */
maxcurr = growvector(&basepc, maxcurr, Byte, codeEM, MAX_INT);
if (currState->pc+i >= currState->codesize)
currState->codesize = growvector(&currState->f->code, currState->codesize,
Byte, codeEM, MAX_INT);
}
static void code_byte (Byte c)
{
check_space(1);
basepc[pc++] = c;
}
static void code_word (Word n)
{
check_space(sizeof(Word));
memcpy(basepc+pc, &n, sizeof(Word));
pc += sizeof(Word);
check_space(1);
currState->f->code[currState->pc++] = c;
}
static void code_float (real n)
{
check_space(sizeof(real));
memcpy(basepc+pc, &n, sizeof(real));
pc += sizeof(real);
memcpy(currState->f->code+currState->pc, &n, sizeof(real));
currState->pc += sizeof(real);
}
static void code_code (TFunc *tf)
{
check_space(sizeof(TFunc *));
memcpy(basepc+pc, &tf, sizeof(TFunc *));
pc += sizeof(TFunc *);
memcpy(currState->f->code+currState->pc, &tf, sizeof(TFunc *));
currState->pc += sizeof(TFunc *);
}
static void code_word_at (Byte *p, int n)
static void code_word_at (int pc, int n)
{
Word w = n;
if (w != n)
yyerror("block too big");
memcpy(p, &w, sizeof(Word));
memcpy(currState->f->code+pc, &w, sizeof(Word));
}
static void code_word (Word n)
{
check_space(sizeof(Word));
memcpy(currState->f->code+currState->pc, &n, sizeof(Word));
currState->pc += sizeof(Word);
}
static void flush_record (int n)
@ -124,20 +127,39 @@ static void flush_list (int m, int n)
code_byte(n);
}
static void luaI_registerlocalvar (TaggedString *varname, int line)
{
if (currState->maxvars != -1) { /* debug information? */
if (currState->nvars >= currState->maxvars)
currState->maxvars = growvector(&currState->f->locvars,
currState->maxvars, LocVar, "", MAX_WORD);
currState->f->locvars[currState->nvars].varname = varname;
currState->f->locvars[currState->nvars].line = line;
currState->nvars++;
}
}
static void luaI_unregisterlocalvar (int line)
{
luaI_registerlocalvar(NULL, line);
}
static void store_localvar (TaggedString *name, int n)
{
if (nlocalvar+n < MAXLOCALS)
localvar[nlocalvar+n] = name;
else
yyerror ("too many local variables");
if (lua_debug)
luaI_registerlocalvar(name, lua_linenumber);
if (currState->nlocalvar+n < MAXLOCALS)
currState->localvar[currState->nlocalvar+n] = name;
else
yyerror ("too many local variables");
luaI_registerlocalvar(name, lua_linenumber);
}
static void add_localvar (TaggedString *name)
{
store_localvar(name, 0);
nlocalvar++;
currState->nlocalvar++;
}
static void add_varbuffer (Long var)
@ -189,9 +211,9 @@ static void code_number (float f)
static int lua_localname (TaggedString *n)
{
int i;
for (i=nlocalvar-1; i >= 0; i--)
if (n == localvar[i]) return i; /* local var */
return -1; /* global var */
for (i=currState->nlocalvar-1; i >= 0; i--)
if (n == currState->localvar[i]) return i; /* local var */
return -1; /* global var */
}
/*
@ -224,53 +246,66 @@ static void lua_pushvar (Long number)
static void lua_codeadjust (int n)
{
if (n+nlocalvar == 0)
code_byte(ADJUST0);
else
{
code_byte(ADJUST);
code_byte(n+nlocalvar);
}
n += currState->nlocalvar;
if (n == 0)
code_byte(ADJUST0);
else {
code_byte(ADJUST);
code_byte(n);
}
}
static void change2main (void)
static void init_state (TFunc *f)
{
/* (re)store main values */
pc=maincode; basepc=*initcode; maxcurr=maxmain;
nlocalvar=0;
luaI_initTFunc(f);
currState->nlocalvar = 0;
currState->f = f;
currState->pc = 0;
currState->codesize = CODE_BLOCK;
f->code = newvector(CODE_BLOCK, Byte);
if (lua_debug) {
currState->nvars = 0;
currState->maxvars = 0;
}
else
currState->maxvars = -1; /* flag no debug information */
}
static void savemain (void)
{
/* save main values */
maincode=pc; *initcode=basepc; maxmain=maxcurr;
}
static void init_func (void)
{
if (funcCode == NULL) /* first function */
{
funcCode = newvector(CODE_BLOCK, Byte);
maxcode = CODE_BLOCK;
}
savemain(); /* save main values */
/* set func values */
pc=0; basepc=funcCode; maxcurr=maxcode;
nlocalvar = 0;
currState = &stateFunc;
init_state(new(TFunc));
luaI_codedebugline(lua_linenumber);
}
static void codereturn (void)
{
if (nlocalvar == 0)
if (currState->nlocalvar == 0)
code_byte(RETCODE0);
else
{
code_byte(RETCODE);
code_byte(nlocalvar);
code_byte(currState->nlocalvar);
}
}
static void close_func (void)
{
codereturn();
code_byte(ENDCODE);
currState->f->code = shrinkvector(currState->f->code, currState->pc, Byte);
if (currState->maxvars != -1) { /* debug information? */
luaI_registerlocalvar(NULL, -1); /* flag end of vector */
currState->f->locvars = shrinkvector(currState->f->locvars,
currState->nvars, LocVar);
}
}
void luaI_codedebugline (int line)
{
static int lastline = 0;
@ -286,23 +321,20 @@ static int adjust_functioncall (Long exp, int i)
{
if (exp <= 0)
return -exp; /* exp is -list length */
else
{
int temp = basepc[exp];
basepc[exp] = i;
else {
int temp = currState->f->code[exp];
currState->f->code[exp] = i;
return temp+i;
}
}
static void adjust_mult_assign (int vars, Long exps, int temps)
{
if (exps > 0)
{ /* must correct function call */
int diff = vars - basepc[exps];
if (exps > 0) { /* must correct function call */
int diff = vars - currState->f->code[exps];
if (diff >= 0)
adjust_functioncall(exps, diff);
else
{
else {
adjust_functioncall(exps, 0);
lua_codeadjust(temps);
}
@ -315,15 +347,15 @@ static int close_parlist (int dots)
{
if (!dots)
lua_codeadjust(0);
else
{
else {
code_byte(VARARGS);
code_byte(nlocalvar);
code_byte(currState->nlocalvar);
add_localvar(luaI_createfixedstring("arg"));
}
return lua_linenumber;
}
static void storesinglevar (Long v)
{
if (v > 0) /* global var */
@ -345,6 +377,7 @@ static void storesinglevar (Long v)
code_byte(STOREINDEXED0);
}
static void lua_codestore (int i)
{
if (varbuffer[i] != 0) /* global or local var */
@ -370,18 +403,23 @@ static void lua_codestore (int i)
static void codeIf (Long thenAdd, Long elseAdd)
{
Long elseinit = elseAdd+sizeof(Word)+1;
if (pc == elseinit) /* no else */
{
pc -= sizeof(Word)+1;
elseinit = pc;
if (currState->pc == elseinit) { /* no else */
currState->pc -= sizeof(Word)+1;
elseinit = currState->pc;
}
else
{
basepc[elseAdd] = JMP;
code_word_at(basepc+elseAdd+1, pc-elseinit);
else {
currState->f->code[elseAdd] = JMP;
code_word_at(elseAdd+1, currState->pc-elseinit);
}
basepc[thenAdd] = IFFJMP;
code_word_at(basepc+thenAdd+1,elseinit-(thenAdd+sizeof(Word)+1));
currState->f->code[thenAdd] = IFFJMP;
code_word_at(thenAdd+1, elseinit-(thenAdd+sizeof(Word)+1));
}
static void code_shortcircuit (int pc, Byte jmp)
{
currState->f->code[pc] = jmp;
code_word_at(pc+1, currState->pc - (pc + sizeof(Word)+1));
}
@ -390,19 +428,11 @@ static void codeIf (Long thenAdd, Long elseAdd)
*/
void lua_parse (TFunc *tf)
{
initcode = &(tf->code);
*initcode = newvector(CODE_BLOCK, Byte);
maincode = 0;
maxmain = CODE_BLOCK;
change2main();
if (yyparse ()) lua_error("parse error");
savemain();
(*initcode)[maincode++] = RETCODE0;
tf->size = maincode;
#if LISTING
{ static void PrintCode (Byte *c, Byte *end);
PrintCode(*initcode,*initcode+maincode); }
#endif
currState = &stateMain;
init_state(tf);
if (yyparse ()) lua_error("parse error");
currState = &stateMain;
close_func();
}
@ -484,21 +514,10 @@ funcname : var { $$ =$1; init_func(); }
body : '(' parlist ')' block END
{
codereturn();
$$ = new(TFunc);
luaI_initTFunc($$);
$$->size = pc;
$$->code = newvector(pc, Byte);
close_func();
$$ = currState->f;
$$->lineDefined = $2;
memcpy($$->code, basepc, pc*sizeof(Byte));
if (lua_debug)
luaI_closelocalvars($$);
/* save func values */
funcCode = basepc; maxcode=maxcurr;
#if LISTING
PrintCode(funcCode,funcCode+pc);
#endif
change2main(); /* change back to main code */
currState = &stateMain; /* change back to main code */
}
;
@ -511,18 +530,18 @@ sc : /* empty */ | ';' ;
stat : IF expr1 THEN PrepJump block PrepJump elsepart END
{ codeIf($4, $6); }
| WHILE {$<vLong>$=pc;} expr1 DO PrepJump block PrepJump END
| WHILE {$<vLong>$=currState->pc;} expr1 DO PrepJump block PrepJump END
{
basepc[$5] = IFFJMP;
code_word_at(basepc+$5+1, pc - ($5 + sizeof(Word)+1));
basepc[$7] = UPJMP;
code_word_at(basepc+$7+1, pc - ($<vLong>2));
currState->f->code[$5] = IFFJMP;
code_word_at($5+1, currState->pc - ($5+sizeof(Word)+1));
currState->f->code[$7] = UPJMP;
code_word_at($7+1, currState->pc - ($<vLong>2));
}
| REPEAT {$<vLong>$=pc;} block UNTIL expr1 PrepJump
| REPEAT {$<vLong>$=currState->pc;} block UNTIL expr1 PrepJump
{
basepc[$6] = IFFUPJMP;
code_word_at(basepc+$6+1, pc - ($<vLong>2));
currState->f->code[$6] = IFFUPJMP;
code_word_at($6+1, currState->pc - ($<vLong>2));
}
| varlist1 '=' exprlist1
@ -531,14 +550,14 @@ stat : IF expr1 THEN PrepJump block PrepJump elsepart END
int i;
adjust_mult_assign(nvarbuffer, $3, $1 * 2 + nvarbuffer);
for (i=nvarbuffer-1; i>=0; i--)
lua_codestore (i);
lua_codestore(i);
if ($1 > 1 || ($1 == 1 && varbuffer[0] != 0))
lua_codeadjust (0);
lua_codeadjust(0);
}
}
| functioncall {;}
| LOCAL localdeclist decinit
{ nlocalvar += $2;
{ currState->nlocalvar += $2;
adjust_mult_assign($2, $3, 0);
}
;
@ -549,17 +568,13 @@ elsepart : /* empty */
{ codeIf($4, $6); }
;
block : {$<vInt>$ = nlocalvar;} statlist ret
block : {$<vInt>$ = currState->nlocalvar;} statlist ret
{
if (nlocalvar != $<vInt>1)
{
if (lua_debug)
for (; nlocalvar > $<vInt>1; nlocalvar--)
luaI_unregisterlocalvar(lua_linenumber);
else
nlocalvar = $<vInt>1;
lua_codeadjust (0);
}
if (currState->nlocalvar != $<vInt>1) {
for (; currState->nlocalvar > $<vInt>1; currState->nlocalvar--)
luaI_unregisterlocalvar(lua_linenumber);
lua_codeadjust(0);
}
}
;
@ -573,9 +588,9 @@ ret : /* empty */
PrepJump : /* empty */
{
$$ = pc;
$$ = currState->pc;
code_byte(0); /* open space */
code_word (0);
code_word(0);
}
;
@ -609,26 +624,24 @@ expr : '(' expr ')' { $$ = $2; }
| NOT expr1 { code_byte(NOTOP); $$ = 0;}
| expr1 AND PrepJump {code_byte(POP); } expr1
{
basepc[$3] = ONFJMP;
code_word_at(basepc+$3+1, pc - ($3 + sizeof(Word)+1));
$$ = 0;
code_shortcircuit($3, ONFJMP);
$$ = 0;
}
| expr1 OR PrepJump {code_byte(POP); } expr1
{
basepc[$3] = ONTJMP;
code_word_at(basepc+$3+1, pc - ($3 + sizeof(Word)+1));
$$ = 0;
code_shortcircuit($3, ONTJMP);
$$ = 0;
}
;
table :
{
code_byte(CREATEARRAY);
$<vLong>$ = pc; code_word(0);
$<vLong>$ = currState->pc; code_word(0);
}
'{' fieldlist '}'
{
code_word_at(basepc+$<vLong>1, $3);
code_word_at($<vLong>1, $3);
}
;
@ -636,7 +649,7 @@ functioncall : funcvalue funcParams
{
code_byte(CALLFUNC);
code_byte($1+$2);
$$ = pc;
$$ = currState->pc;
code_byte(0); /* may be modified by other rules */
}
;

View File

@ -1,7 +1,7 @@
/*
** mem.c
** memory manager for lua
** $Id: luamem.h,v 1.8 1996/05/24 14:31:10 roberto Exp roberto $
** $Id: luamem.h,v 1.9 1997/03/31 14:10:11 roberto Exp roberto $
*/
#ifndef luamem_h
@ -34,6 +34,7 @@ int luaI_growvector (void **block, unsigned long nelems, int size,
#define newvector(n,s) ((s *)luaI_malloc((n)*sizeof(s)))
#define growvector(old,n,s,e,l) \
(luaI_growvector((void**)old,n,sizeof(s),e,l))
#define shrinkvector(v,n,t) ((t *)luaI_realloc(v,(n)*sizeof(t)))
#endif