diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1996-02-07 16:10:27 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 1996-02-07 16:10:27 -0200 |
commit | 5a3a1fe458a7eab402f5386e4dcb8282c94ff068 (patch) | |
tree | fc315159d0b00d3e726c0a538e40b6acdaa3e013 | |
parent | 56fb06b6f5eaea4f3dba32af1cc476a99b678497 (diff) | |
download | lua-5a3a1fe458a7eab402f5386e4dcb8282c94ff068.tar.gz lua-5a3a1fe458a7eab402f5386e4dcb8282c94ff068.tar.bz2 lua-5a3a1fe458a7eab402f5386e4dcb8282c94ff068.zip |
debug interface functions to manipulated local variables:
"lua_getlocal" and "lua_setlocal".
-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); |