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:
M | func.c | | | 82 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | func.h | | | 16 | +++++++++++++++- |
M | lua.stx | | | 30 | +++++++++++++++++++----------- |
M | luadebug.h | | | 9 | +++++++-- |
M | opcode.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);