lua

A copy of the Lua development repository
Log | Files | Refs | README

commit 5a3a1fe458a7eab402f5386e4dcb8282c94ff068
parent 56fb06b6f5eaea4f3dba32af1cc476a99b678497
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date:   Wed,  7 Feb 1996 16:10:07 -0200

debug interface functions to manipulated local variables:
"lua_getlocal" and "lua_setlocal".

Diffstat:
Mfunc.c | 82+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mfunc.h | 16+++++++++++++++-
Mlua.stx | 30+++++++++++++++++++-----------
Mluadebug.h | 9+++++++--
Mopcode.c | 37++++++++++++++++++++++++++++++++++---
5 files changed, 157 insertions(+), 17 deletions(-)

diff --git a/func.c b/func.c @@ -6,10 +6,25 @@ #include "func.h" #include "opcode.h" +#define LOCALVARINITSIZE 10 + static TFunc *function_root = NULL; +static LocVar *currvars = NULL; +static int numcurrvars = 0; +static int maxcurrvars = 0; /* +** Initialize TFunc struct +*/ +void luaI_initTFunc (TFunc *f) +{ + f->code = NULL; + f->lineDefined = 0; + f->locvars = NULL; +} + +/* ** Insert function in list for GC */ void luaI_insertfunction (TFunc *f) @@ -77,3 +92,70 @@ 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 (TreeNode *varname, int line) +{ + if (numcurrvars >= maxcurrvars) + if (currvars == NULL) + { + maxcurrvars = LOCALVARINITSIZE; + currvars = newvector (maxcurrvars, LocVar); + } + else + { + maxcurrvars *= 2; + currvars = growvector (currvars, maxcurrvars, LocVar); + } + 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". +** Returns NULL if not found. +*/ +char *luaI_getlocalname (TFunc *func, int local_number, int line) +{ + int count = 0; + char *varname = NULL; + LocVar *lv = func->locvars; + if (lv == NULL) + return NULL; + for (; lv->line != -1 && lv->line < line; lv++) + { + if (lv->varname) /* register */ + { + if (++count == local_number) + varname = lv->varname->ts.str; + } + else /* unregister */ + if (--count < local_number) + varname = NULL; + } + return varname; +} + diff --git a/func.h b/func.h @@ -4,8 +4,15 @@ #include "types.h" #include "lua.h" +typedef struct LocVar +{ + TreeNode *varname; /* NULL signals end of scope */ + int line; +} LocVar; + + /* -** Header para funcoes. +** Function Headers */ typedef struct TFunc { @@ -15,10 +22,17 @@ typedef struct TFunc Byte *code; int lineDefined; char *fileName; + LocVar *locvars; } TFunc; Long luaI_funccollector (void); void luaI_insertfunction (TFunc *f); +void luaI_initTFunc (TFunc *f); + +void luaI_registerlocalvar (TreeNode *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 @@ -1,11 +1,12 @@ %{ -char *rcs_luastx = "$Id: lua.stx,v 3.27 1996/01/23 17:50:29 roberto Exp $"; +char *rcs_luastx = "$Id: lua.stx,v 3.28 1996/02/05 13:26:01 roberto Exp roberto $"; #include <stdio.h> #include <stdlib.h> #include <string.h> +#include "luadebug.h" #include "mem.h" #include "opcode.h" #include "hash.h" @@ -51,6 +52,7 @@ static int nlocalvar=0; /* number of local variables */ static Word fields[MAXFIELDS]; /* fieldnames to be flushed */ static int nfields=0; +int lua_debug = 0; /* Internal functions */ @@ -149,20 +151,20 @@ static void flush_list (int m, int n) code_byte(n); } -static void add_localvar (TreeNode *name) -{ - if (nlocalvar < MAXLOCALS) - localvar[nlocalvar++] = name; - else - yyerror ("too many local variables"); -} - static void store_localvar (TreeNode *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); +} + +static void add_localvar (TreeNode *name) +{ + store_localvar(name, 0); + nlocalvar++; } static void add_varbuffer (Long var) @@ -391,7 +393,6 @@ static void codeIf (Long thenAdd, Long elseAdd) */ void lua_parse (TFunc *tf) { - lua_debug = 0; initcode = &(tf->code); *initcode = newvector(CODE_BLOCK, Byte); maincode = 0; @@ -492,11 +493,14 @@ body : '(' parlist ')' block END { codereturn(); $$ = new(TFunc); + luaI_initTFunc($$); $$->size = pc; $$->code = newvector(pc, Byte); $$->fileName = lua_parsedfile; $$->lineDefined = $2; memcpy($$->code, basepc, pc*sizeof(Byte)); + if (lua_debug) + luaI_closelocalvars($$); /* save func values */ funcCode = basepc; maxcode=maxcurr; #if LISTING @@ -557,7 +561,11 @@ block : {$<vInt>$ = nlocalvar;} statlist ret { if (nlocalvar != $<vInt>1) { - nlocalvar = $<vInt>1; + if (lua_debug) + for (; nlocalvar > $<vInt>1; nlocalvar--) + luaI_unregisterlocalvar(lua_linenumber); + else + nlocalvar = $<vInt>1; lua_codeadjust (0); } } diff --git a/luadebug.h b/luadebug.h @@ -2,7 +2,7 @@ ** LUA - Linguagem para Usuarios de Aplicacao ** Grupo de Tecnologia em Computacao Grafica ** TeCGraf - PUC-Rio -** $Id: luadebug.h,v 1.2 1995/10/26 14:21:56 roberto Exp $ +** $Id: luadebug.h,v 1.3 1996/01/09 20:22:44 roberto Exp roberto $ */ @@ -14,11 +14,16 @@ typedef void (*lua_LHFunction) (int line); typedef void (*lua_CHFunction) (lua_Object func, char *file, int line); -lua_Object lua_stackedfunction(int level); +lua_Object lua_stackedfunction (int level); void lua_funcinfo (lua_Object func, char **filename, int *linedefined); int lua_currentline (lua_Object func); char *lua_getobjname (lua_Object o, char **name); lua_LHFunction lua_setlinehook (lua_LHFunction hook); lua_CHFunction lua_setcallhook (lua_CHFunction hook); +lua_Object lua_getlocal (lua_Object func, int local_number, char **name); +int lua_setlocal (lua_Object func, int local_number); + +extern int lua_debug; + #endif diff --git a/opcode.c b/opcode.c @@ -3,7 +3,7 @@ ** TecCGraf - PUC-Rio */ -char *rcs_opcode="$Id: opcode.c,v 3.53 1996/01/23 18:43:07 roberto Exp roberto $"; +char *rcs_opcode="$Id: opcode.c,v 3.54 1996/01/30 15:25:23 roberto Exp roberto $"; #include <setjmp.h> #include <stdlib.h> @@ -441,6 +441,38 @@ int lua_currentline (lua_Object func) } +lua_Object lua_getlocal (lua_Object func, int local_number, char **name) +{ + Object *f = luaI_Address(func); + *name = luaI_getlocalname(f->value.tf, local_number, lua_currentline(func)); + if (*name) + { + /* if "*name", there must be a LUA_T_LINE */ + /* therefore, f+2 points to function base */ + return Ref((f+2)+(local_number-1)); + } + else + return LUA_NOOBJECT; +} + +int lua_setlocal (lua_Object func, int local_number) +{ + Object *f = Address(func); + char *name = luaI_getlocalname(f->value.tf, local_number, lua_currentline(func)); + adjustC(1); + --top; + if (name) + { + /* if "name", there must be a LUA_T_LINE */ + /* therefore, f+2 points to function base */ + *((f+2)+(local_number-1)) = *top; + return 1; + } + else + return 0; +} + + /* ** Execute a protected call. Assumes that function is at CBase and ** parameters are on top of it. Leave nResults on the stack. @@ -480,9 +512,8 @@ static int do_protectedmain (void) adjustC(1); /* one slot for the pseudo-function */ stack[CBase].tag = LUA_T_FUNCTION; stack[CBase].value.tf = &tf; - tf.lineDefined = 0; + luaI_initTFunc(&tf); tf.fileName = lua_parsedfile; - tf.code = NULL; if (setjmp(myErrorJmp) == 0) { lua_parse(&tf);