summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-07-29 17:38:45 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>1997-07-29 17:38:45 -0300
commit2c580a0afb8dbaf7070a9819b7e81ebde5737ff9 (patch)
tree6fd261bb3bd89e2b851cd1adaa290c17a6dcad67
parent05e8b0ae80bbeaf41ea849e9eff5d05074093560 (diff)
downloadlua-github-2c580a0afb8dbaf7070a9819b7e81ebde5737ff9.tar.gz
new way to handle global state during compilation.
-rw-r--r--func.c35
-rw-r--r--func.h5
-rw-r--r--lua.stx309
-rw-r--r--luamem.h3
4 files changed, 164 insertions, 188 deletions
diff --git a/func.c b/func.c
index b0792a65..1cf5b1e7 100644
--- a/func.c
+++ b/func.c
@@ -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".
diff --git a/func.h b/func.h
index 240baeb4..14f6554c 100644
--- a/func.h
+++ b/func.h
@@ -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
diff --git a/lua.stx b/lua.stx
index eb988675..9f6e56f3 100644
--- a/lua.stx
+++ b/lua.stx
@@ -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)
-{
- /* (re)store main values */
- pc=maincode; basepc=*initcode; maxcurr=maxmain;
- nlocalvar=0;
-}
-static void savemain (void)
+static void init_state (TFunc *f)
{
- /* save main values */
- maincode=pc; *initcode=basepc; maxmain=maxcurr;
+ 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 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 */
}
;
diff --git a/luamem.h b/luamem.h
index e338183d..8b88ee9b 100644
--- a/luamem.h
+++ b/luamem.h
@@ -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