Browse Source

new way to handle global state during compilation.

Roberto Ierusalimschy 28 years ago
parent
commit
2c580a0afb
4 changed files with 164 additions and 188 deletions
  1. 0 35
      func.c
  2. 1 4
      func.h
  3. 161 148
      lua.stx
  4. 2 1
      luamem.h

+ 0 - 35
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".

+ 1 - 4
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

+ 161 - 148
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 */
 	}
 	     ;

+ 2 - 1
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