diff options
| -rw-r--r-- | func.c | 82 | ||||
| -rw-r--r-- | func.h | 16 | ||||
| -rw-r--r-- | lua.stx | 30 | ||||
| -rw-r--r-- | luadebug.h | 9 | ||||
| -rw-r--r-- | opcode.c | 37 |
5 files changed, 157 insertions, 17 deletions
| @@ -6,10 +6,25 @@ | |||
| 6 | #include "func.h" | 6 | #include "func.h" |
| 7 | #include "opcode.h" | 7 | #include "opcode.h" |
| 8 | 8 | ||
| 9 | #define LOCALVARINITSIZE 10 | ||
| 10 | |||
| 9 | static TFunc *function_root = NULL; | 11 | static TFunc *function_root = NULL; |
| 12 | static LocVar *currvars = NULL; | ||
| 13 | static int numcurrvars = 0; | ||
| 14 | static int maxcurrvars = 0; | ||
| 10 | 15 | ||
| 11 | 16 | ||
| 12 | /* | 17 | /* |
| 18 | ** Initialize TFunc struct | ||
| 19 | */ | ||
| 20 | void luaI_initTFunc (TFunc *f) | ||
| 21 | { | ||
| 22 | f->code = NULL; | ||
| 23 | f->lineDefined = 0; | ||
| 24 | f->locvars = NULL; | ||
| 25 | } | ||
| 26 | |||
| 27 | /* | ||
| 13 | ** Insert function in list for GC | 28 | ** Insert function in list for GC |
| 14 | */ | 29 | */ |
| 15 | void luaI_insertfunction (TFunc *f) | 30 | void luaI_insertfunction (TFunc *f) |
| @@ -77,3 +92,70 @@ void lua_funcinfo (lua_Object func, char **filename, int *linedefined) | |||
| 77 | } | 92 | } |
| 78 | } | 93 | } |
| 79 | 94 | ||
| 95 | /* | ||
| 96 | ** Stores information to know that variable has been declared in given line | ||
| 97 | */ | ||
| 98 | void luaI_registerlocalvar (TreeNode *varname, int line) | ||
| 99 | { | ||
| 100 | if (numcurrvars >= maxcurrvars) | ||
| 101 | if (currvars == NULL) | ||
| 102 | { | ||
| 103 | maxcurrvars = LOCALVARINITSIZE; | ||
| 104 | currvars = newvector (maxcurrvars, LocVar); | ||
| 105 | } | ||
| 106 | else | ||
| 107 | { | ||
| 108 | maxcurrvars *= 2; | ||
| 109 | currvars = growvector (currvars, maxcurrvars, LocVar); | ||
| 110 | } | ||
| 111 | currvars[numcurrvars].varname = varname; | ||
| 112 | currvars[numcurrvars].line = line; | ||
| 113 | numcurrvars++; | ||
| 114 | } | ||
| 115 | |||
| 116 | /* | ||
| 117 | ** Stores information to know that variable has been out of scope in given line | ||
| 118 | */ | ||
| 119 | void luaI_unregisterlocalvar (int line) | ||
| 120 | { | ||
| 121 | luaI_registerlocalvar(NULL, line); | ||
| 122 | } | ||
| 123 | |||
| 124 | /* | ||
| 125 | ** Copies "currvars" into a new area and store it in function header. | ||
| 126 | ** The values (varname = NULL, line = -1) signal the end of vector. | ||
| 127 | */ | ||
| 128 | void luaI_closelocalvars (TFunc *func) | ||
| 129 | { | ||
| 130 | func->locvars = newvector (numcurrvars+1, LocVar); | ||
| 131 | memcpy (func->locvars, currvars, numcurrvars*sizeof(LocVar)); | ||
| 132 | func->locvars[numcurrvars].varname = NULL; | ||
| 133 | func->locvars[numcurrvars].line = -1; | ||
| 134 | numcurrvars = 0; /* prepares for next function */ | ||
| 135 | } | ||
| 136 | |||
| 137 | /* | ||
| 138 | ** Look for n-esim local variable at line "line" in function "func". | ||
| 139 | ** Returns NULL if not found. | ||
| 140 | */ | ||
| 141 | char *luaI_getlocalname (TFunc *func, int local_number, int line) | ||
| 142 | { | ||
| 143 | int count = 0; | ||
| 144 | char *varname = NULL; | ||
| 145 | LocVar *lv = func->locvars; | ||
| 146 | if (lv == NULL) | ||
| 147 | return NULL; | ||
| 148 | for (; lv->line != -1 && lv->line < line; lv++) | ||
| 149 | { | ||
| 150 | if (lv->varname) /* register */ | ||
| 151 | { | ||
| 152 | if (++count == local_number) | ||
| 153 | varname = lv->varname->ts.str; | ||
| 154 | } | ||
| 155 | else /* unregister */ | ||
| 156 | if (--count < local_number) | ||
| 157 | varname = NULL; | ||
| 158 | } | ||
| 159 | return varname; | ||
| 160 | } | ||
| 161 | |||
| @@ -4,8 +4,15 @@ | |||
| 4 | #include "types.h" | 4 | #include "types.h" |
| 5 | #include "lua.h" | 5 | #include "lua.h" |
| 6 | 6 | ||
| 7 | typedef struct LocVar | ||
| 8 | { | ||
| 9 | TreeNode *varname; /* NULL signals end of scope */ | ||
| 10 | int line; | ||
| 11 | } LocVar; | ||
| 12 | |||
| 13 | |||
| 7 | /* | 14 | /* |
| 8 | ** Header para funcoes. | 15 | ** Function Headers |
| 9 | */ | 16 | */ |
| 10 | typedef struct TFunc | 17 | typedef struct TFunc |
| 11 | { | 18 | { |
| @@ -15,10 +22,17 @@ typedef struct TFunc | |||
| 15 | Byte *code; | 22 | Byte *code; |
| 16 | int lineDefined; | 23 | int lineDefined; |
| 17 | char *fileName; | 24 | char *fileName; |
| 25 | LocVar *locvars; | ||
| 18 | } TFunc; | 26 | } TFunc; |
| 19 | 27 | ||
| 20 | Long luaI_funccollector (void); | 28 | Long luaI_funccollector (void); |
| 21 | void luaI_insertfunction (TFunc *f); | 29 | void luaI_insertfunction (TFunc *f); |
| 22 | 30 | ||
| 31 | void luaI_initTFunc (TFunc *f); | ||
| 32 | |||
| 33 | void luaI_registerlocalvar (TreeNode *varname, int line); | ||
| 34 | void luaI_unregisterlocalvar (int line); | ||
| 35 | void luaI_closelocalvars (TFunc *func); | ||
| 36 | char *luaI_getlocalname (TFunc *func, int local_number, int line); | ||
| 23 | 37 | ||
| 24 | #endif | 38 | #endif |
| @@ -1,11 +1,12 @@ | |||
| 1 | %{ | 1 | %{ |
| 2 | 2 | ||
| 3 | char *rcs_luastx = "$Id: lua.stx,v 3.27 1996/01/23 17:50:29 roberto Exp $"; | 3 | char *rcs_luastx = "$Id: lua.stx,v 3.28 1996/02/05 13:26:01 roberto Exp roberto $"; |
| 4 | 4 | ||
| 5 | #include <stdio.h> | 5 | #include <stdio.h> |
| 6 | #include <stdlib.h> | 6 | #include <stdlib.h> |
| 7 | #include <string.h> | 7 | #include <string.h> |
| 8 | 8 | ||
| 9 | #include "luadebug.h" | ||
| 9 | #include "mem.h" | 10 | #include "mem.h" |
| 10 | #include "opcode.h" | 11 | #include "opcode.h" |
| 11 | #include "hash.h" | 12 | #include "hash.h" |
| @@ -51,6 +52,7 @@ static int nlocalvar=0; /* number of local variables */ | |||
| 51 | static Word fields[MAXFIELDS]; /* fieldnames to be flushed */ | 52 | static Word fields[MAXFIELDS]; /* fieldnames to be flushed */ |
| 52 | static int nfields=0; | 53 | static int nfields=0; |
| 53 | 54 | ||
| 55 | int lua_debug = 0; | ||
| 54 | 56 | ||
| 55 | /* Internal functions */ | 57 | /* Internal functions */ |
| 56 | 58 | ||
| @@ -149,20 +151,20 @@ static void flush_list (int m, int n) | |||
| 149 | code_byte(n); | 151 | code_byte(n); |
| 150 | } | 152 | } |
| 151 | 153 | ||
| 152 | static void add_localvar (TreeNode *name) | ||
| 153 | { | ||
| 154 | if (nlocalvar < MAXLOCALS) | ||
| 155 | localvar[nlocalvar++] = name; | ||
| 156 | else | ||
| 157 | yyerror ("too many local variables"); | ||
| 158 | } | ||
| 159 | |||
| 160 | static void store_localvar (TreeNode *name, int n) | 154 | static void store_localvar (TreeNode *name, int n) |
| 161 | { | 155 | { |
| 162 | if (nlocalvar+n < MAXLOCALS) | 156 | if (nlocalvar+n < MAXLOCALS) |
| 163 | localvar[nlocalvar+n] = name; | 157 | localvar[nlocalvar+n] = name; |
| 164 | else | 158 | else |
| 165 | yyerror ("too many local variables"); | 159 | yyerror ("too many local variables"); |
| 160 | if (lua_debug) | ||
| 161 | luaI_registerlocalvar(name, lua_linenumber); | ||
| 162 | } | ||
| 163 | |||
| 164 | static void add_localvar (TreeNode *name) | ||
| 165 | { | ||
| 166 | store_localvar(name, 0); | ||
| 167 | nlocalvar++; | ||
| 166 | } | 168 | } |
| 167 | 169 | ||
| 168 | static void add_varbuffer (Long var) | 170 | static void add_varbuffer (Long var) |
| @@ -391,7 +393,6 @@ static void codeIf (Long thenAdd, Long elseAdd) | |||
| 391 | */ | 393 | */ |
| 392 | void lua_parse (TFunc *tf) | 394 | void lua_parse (TFunc *tf) |
| 393 | { | 395 | { |
| 394 | lua_debug = 0; | ||
| 395 | initcode = &(tf->code); | 396 | initcode = &(tf->code); |
| 396 | *initcode = newvector(CODE_BLOCK, Byte); | 397 | *initcode = newvector(CODE_BLOCK, Byte); |
| 397 | maincode = 0; | 398 | maincode = 0; |
| @@ -492,11 +493,14 @@ body : '(' parlist ')' block END | |||
| 492 | { | 493 | { |
| 493 | codereturn(); | 494 | codereturn(); |
| 494 | $$ = new(TFunc); | 495 | $$ = new(TFunc); |
| 496 | luaI_initTFunc($$); | ||
| 495 | $$->size = pc; | 497 | $$->size = pc; |
| 496 | $$->code = newvector(pc, Byte); | 498 | $$->code = newvector(pc, Byte); |
| 497 | $$->fileName = lua_parsedfile; | 499 | $$->fileName = lua_parsedfile; |
| 498 | $$->lineDefined = $2; | 500 | $$->lineDefined = $2; |
| 499 | memcpy($$->code, basepc, pc*sizeof(Byte)); | 501 | memcpy($$->code, basepc, pc*sizeof(Byte)); |
| 502 | if (lua_debug) | ||
| 503 | luaI_closelocalvars($$); | ||
| 500 | /* save func values */ | 504 | /* save func values */ |
| 501 | funcCode = basepc; maxcode=maxcurr; | 505 | funcCode = basepc; maxcode=maxcurr; |
| 502 | #if LISTING | 506 | #if LISTING |
| @@ -557,7 +561,11 @@ block : {$<vInt>$ = nlocalvar;} statlist ret | |||
| 557 | { | 561 | { |
| 558 | if (nlocalvar != $<vInt>1) | 562 | if (nlocalvar != $<vInt>1) |
| 559 | { | 563 | { |
| 560 | nlocalvar = $<vInt>1; | 564 | if (lua_debug) |
| 565 | for (; nlocalvar > $<vInt>1; nlocalvar--) | ||
| 566 | luaI_unregisterlocalvar(lua_linenumber); | ||
| 567 | else | ||
| 568 | nlocalvar = $<vInt>1; | ||
| 561 | lua_codeadjust (0); | 569 | lua_codeadjust (0); |
| 562 | } | 570 | } |
| 563 | } | 571 | } |
| @@ -2,7 +2,7 @@ | |||
| 2 | ** LUA - Linguagem para Usuarios de Aplicacao | 2 | ** LUA - Linguagem para Usuarios de Aplicacao |
| 3 | ** Grupo de Tecnologia em Computacao Grafica | 3 | ** Grupo de Tecnologia em Computacao Grafica |
| 4 | ** TeCGraf - PUC-Rio | 4 | ** TeCGraf - PUC-Rio |
| 5 | ** $Id: luadebug.h,v 1.2 1995/10/26 14:21:56 roberto Exp $ | 5 | ** $Id: luadebug.h,v 1.3 1996/01/09 20:22:44 roberto Exp roberto $ |
| 6 | */ | 6 | */ |
| 7 | 7 | ||
| 8 | 8 | ||
| @@ -14,11 +14,16 @@ | |||
| 14 | typedef void (*lua_LHFunction) (int line); | 14 | typedef void (*lua_LHFunction) (int line); |
| 15 | typedef void (*lua_CHFunction) (lua_Object func, char *file, int line); | 15 | typedef void (*lua_CHFunction) (lua_Object func, char *file, int line); |
| 16 | 16 | ||
| 17 | lua_Object lua_stackedfunction(int level); | 17 | lua_Object lua_stackedfunction (int level); |
| 18 | void lua_funcinfo (lua_Object func, char **filename, int *linedefined); | 18 | void lua_funcinfo (lua_Object func, char **filename, int *linedefined); |
| 19 | int lua_currentline (lua_Object func); | 19 | int lua_currentline (lua_Object func); |
| 20 | char *lua_getobjname (lua_Object o, char **name); | 20 | char *lua_getobjname (lua_Object o, char **name); |
| 21 | lua_LHFunction lua_setlinehook (lua_LHFunction hook); | 21 | lua_LHFunction lua_setlinehook (lua_LHFunction hook); |
| 22 | lua_CHFunction lua_setcallhook (lua_CHFunction hook); | 22 | lua_CHFunction lua_setcallhook (lua_CHFunction hook); |
| 23 | 23 | ||
| 24 | lua_Object lua_getlocal (lua_Object func, int local_number, char **name); | ||
| 25 | int lua_setlocal (lua_Object func, int local_number); | ||
| 26 | |||
| 27 | extern int lua_debug; | ||
| 28 | |||
| 24 | #endif | 29 | #endif |
| @@ -3,7 +3,7 @@ | |||
| 3 | ** TecCGraf - PUC-Rio | 3 | ** TecCGraf - PUC-Rio |
| 4 | */ | 4 | */ |
| 5 | 5 | ||
| 6 | char *rcs_opcode="$Id: opcode.c,v 3.53 1996/01/23 18:43:07 roberto Exp roberto $"; | 6 | char *rcs_opcode="$Id: opcode.c,v 3.54 1996/01/30 15:25:23 roberto Exp roberto $"; |
| 7 | 7 | ||
| 8 | #include <setjmp.h> | 8 | #include <setjmp.h> |
| 9 | #include <stdlib.h> | 9 | #include <stdlib.h> |
| @@ -441,6 +441,38 @@ int lua_currentline (lua_Object func) | |||
| 441 | } | 441 | } |
| 442 | 442 | ||
| 443 | 443 | ||
| 444 | lua_Object lua_getlocal (lua_Object func, int local_number, char **name) | ||
| 445 | { | ||
| 446 | Object *f = luaI_Address(func); | ||
| 447 | *name = luaI_getlocalname(f->value.tf, local_number, lua_currentline(func)); | ||
| 448 | if (*name) | ||
| 449 | { | ||
| 450 | /* if "*name", there must be a LUA_T_LINE */ | ||
| 451 | /* therefore, f+2 points to function base */ | ||
| 452 | return Ref((f+2)+(local_number-1)); | ||
| 453 | } | ||
| 454 | else | ||
| 455 | return LUA_NOOBJECT; | ||
| 456 | } | ||
| 457 | |||
| 458 | int lua_setlocal (lua_Object func, int local_number) | ||
| 459 | { | ||
| 460 | Object *f = Address(func); | ||
| 461 | char *name = luaI_getlocalname(f->value.tf, local_number, lua_currentline(func)); | ||
| 462 | adjustC(1); | ||
| 463 | --top; | ||
| 464 | if (name) | ||
| 465 | { | ||
| 466 | /* if "name", there must be a LUA_T_LINE */ | ||
| 467 | /* therefore, f+2 points to function base */ | ||
| 468 | *((f+2)+(local_number-1)) = *top; | ||
| 469 | return 1; | ||
| 470 | } | ||
| 471 | else | ||
| 472 | return 0; | ||
| 473 | } | ||
| 474 | |||
| 475 | |||
| 444 | /* | 476 | /* |
| 445 | ** Execute a protected call. Assumes that function is at CBase and | 477 | ** Execute a protected call. Assumes that function is at CBase and |
| 446 | ** parameters are on top of it. Leave nResults on the stack. | 478 | ** parameters are on top of it. Leave nResults on the stack. |
| @@ -480,9 +512,8 @@ static int do_protectedmain (void) | |||
| 480 | adjustC(1); /* one slot for the pseudo-function */ | 512 | adjustC(1); /* one slot for the pseudo-function */ |
| 481 | stack[CBase].tag = LUA_T_FUNCTION; | 513 | stack[CBase].tag = LUA_T_FUNCTION; |
| 482 | stack[CBase].value.tf = &tf; | 514 | stack[CBase].value.tf = &tf; |
| 483 | tf.lineDefined = 0; | 515 | luaI_initTFunc(&tf); |
| 484 | tf.fileName = lua_parsedfile; | 516 | tf.fileName = lua_parsedfile; |
| 485 | tf.code = NULL; | ||
| 486 | if (setjmp(myErrorJmp) == 0) | 517 | if (setjmp(myErrorJmp) == 0) |
| 487 | { | 518 | { |
| 488 | lua_parse(&tf); | 519 | lua_parse(&tf); |
