From 2c580a0afb8dbaf7070a9819b7e81ebde5737ff9 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Tue, 29 Jul 1997 17:38:45 -0300 Subject: new way to handle global state during compilation. --- lua.stx | 309 +++++++++++++++++++++++++++++++++------------------------------- 1 file changed, 161 insertions(+), 148 deletions(-) (limited to 'lua.stx') 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 #include @@ -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 {$$=pc;} expr1 DO PrepJump block PrepJump END + | WHILE {$$=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 - ($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 - ($2)); } - | REPEAT {$$=pc;} block UNTIL expr1 PrepJump + | REPEAT {$$=currState->pc;} block UNTIL expr1 PrepJump { - basepc[$6] = IFFUPJMP; - code_word_at(basepc+$6+1, pc - ($2)); + currState->f->code[$6] = IFFUPJMP; + code_word_at($6+1, currState->pc - ($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 : {$$ = nlocalvar;} statlist ret +block : {$$ = currState->nlocalvar;} statlist ret { - if (nlocalvar != $1) - { - if (lua_debug) - for (; nlocalvar > $1; nlocalvar--) - luaI_unregisterlocalvar(lua_linenumber); - else - nlocalvar = $1; - lua_codeadjust (0); - } + if (currState->nlocalvar != $1) { + for (; currState->nlocalvar > $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); - $$ = pc; code_word(0); + $$ = currState->pc; code_word(0); } '{' fieldlist '}' { - code_word_at(basepc+$1, $3); + code_word_at($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 */ } ; -- cgit v1.2.3-55-g6feb