diff options
-rw-r--r-- | lcode.c | 19 | ||||
-rw-r--r-- | ldebug.c | 74 | ||||
-rw-r--r-- | ldo.c | 8 | ||||
-rw-r--r-- | lfunc.c | 9 | ||||
-rw-r--r-- | lfunc.h | 5 | ||||
-rw-r--r-- | lgc.c | 15 | ||||
-rw-r--r-- | lmem.c | 5 | ||||
-rw-r--r-- | lobject.c | 4 | ||||
-rw-r--r-- | lobject.h | 24 | ||||
-rw-r--r-- | lopcodes.h | 8 | ||||
-rw-r--r-- | lparser.c | 73 | ||||
-rw-r--r-- | lparser.h | 4 | ||||
-rw-r--r-- | ltests.c | 4 | ||||
-rw-r--r-- | lundump.c | 8 | ||||
-rw-r--r-- | lvm.c | 100 |
15 files changed, 201 insertions, 159 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lcode.c,v 1.37 2000/06/21 17:05:49 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 1.38 2000/06/21 18:13:56 roberto Exp roberto $ |
3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -283,7 +283,6 @@ static void luaK_testgo (FuncState *fs, expdesc *v, int invert, OpCode jump) { | |||
283 | prevpos = fs->pc-1; | 283 | prevpos = fs->pc-1; |
284 | previous = &fs->f->code[prevpos]; | 284 | previous = &fs->f->code[prevpos]; |
285 | LUA_ASSERT(L, *previous==previous_instruction(fs), "no jump allowed here"); | 285 | LUA_ASSERT(L, *previous==previous_instruction(fs), "no jump allowed here"); |
286 | LUA_ASSERT(L, GET_OPCODE(*previous) != OP_SETLINE, "no setline allowed here"); | ||
287 | if (!ISJUMP(GET_OPCODE(*previous))) | 286 | if (!ISJUMP(GET_OPCODE(*previous))) |
288 | prevpos = luaK_code1(fs, jump, NO_JUMP); | 287 | prevpos = luaK_code1(fs, jump, NO_JUMP); |
289 | else { /* last instruction is already a jump */ | 288 | else { /* last instruction is already a jump */ |
@@ -316,7 +315,6 @@ void luaK_tostack (LexState *ls, expdesc *v, int onlyone) { | |||
316 | FuncState *fs = ls->fs; | 315 | FuncState *fs = ls->fs; |
317 | if (!discharge(fs, v)) { /* `v' is an expression? */ | 316 | if (!discharge(fs, v)) { /* `v' is an expression? */ |
318 | OpCode previous = GET_OPCODE(fs->f->code[fs->pc-1]); | 317 | OpCode previous = GET_OPCODE(fs->f->code[fs->pc-1]); |
319 | LUA_ASSERT(L, previous != OP_SETLINE, "bad place to set line"); | ||
320 | if (!ISJUMP(previous) && v->u.l.f == NO_JUMP && v->u.l.t == NO_JUMP) { | 318 | if (!ISJUMP(previous) && v->u.l.f == NO_JUMP && v->u.l.t == NO_JUMP) { |
321 | /* expression has no jumps */ | 319 | /* expression has no jumps */ |
322 | if (onlyone) | 320 | if (onlyone) |
@@ -623,17 +621,15 @@ int luaK_code2 (FuncState *fs, OpCode o, int arg1, int arg2) { | |||
623 | case iS: i = CREATE_S(o, arg1); break; | 621 | case iS: i = CREATE_S(o, arg1); break; |
624 | case iAB: i = CREATE_AB(o, arg1, arg2); break; | 622 | case iAB: i = CREATE_AB(o, arg1, arg2); break; |
625 | } | 623 | } |
626 | /* check space for new instruction plus eventual SETLINE */ | 624 | if (fs->f->debug) { |
627 | luaM_growvector(fs->L, fs->f->code, fs->pc, 2, Instruction, | ||
628 | "code size overflow", MAX_INT); | ||
629 | /* check the need for SETLINE */ | ||
630 | if (fs->debug && fs->ls->lastline != fs->lastsetline) { | ||
631 | LexState *ls = fs->ls; | 625 | LexState *ls = fs->ls; |
632 | luaX_checklimit(ls, ls->lastline, MAXARG_U, "lines in a chunk"); | 626 | luaX_checklimit(ls, ls->lastline, MAXARG_U, "lines in a chunk"); |
633 | fs->f->code[fs->pc++] = CREATE_U(OP_SETLINE, ls->lastline); | 627 | luaM_growvector(fs->L, fs->f->lines, fs->pc, 1, int, "??", MAXARG_U); |
634 | fs->lastsetline = ls->lastline; | 628 | fs->f->lines[fs->pc] = ls->lastline; |
635 | } | 629 | } |
636 | /* put new instruction in code array */ | 630 | /* put new instruction in code array */ |
631 | luaM_growvector(fs->L, fs->f->code, fs->pc, 1, Instruction, | ||
632 | "code size overflow", MAX_INT); | ||
637 | fs->f->code[fs->pc] = i; | 633 | fs->f->code[fs->pc] = i; |
638 | return fs->pc++; | 634 | return fs->pc++; |
639 | } | 635 | } |
@@ -688,6 +684,5 @@ const struct OpProperties luaK_opproperties[NUM_OPCODES] = { | |||
688 | {iS, -3}, /* OP_FORLOOP */ | 684 | {iS, -3}, /* OP_FORLOOP */ |
689 | {iS, 3}, /* OP_LFORPREP */ | 685 | {iS, 3}, /* OP_LFORPREP */ |
690 | {iS, -4}, /* OP_LFORLOOP */ | 686 | {iS, -4}, /* OP_LFORLOOP */ |
691 | {iAB, VD}, /* OP_CLOSURE */ | 687 | {iAB, VD} /* OP_CLOSURE */ |
692 | {iU, 0} /* OP_SETLINE */ | ||
693 | }; | 688 | }; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldebug.c,v 1.22 2000/06/08 17:48:31 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 1.23 2000/06/12 13:52:05 roberto Exp roberto $ |
3 | ** Debug Interface | 3 | ** Debug Interface |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -23,22 +23,21 @@ | |||
23 | #include "luadebug.h" | 23 | #include "luadebug.h" |
24 | 24 | ||
25 | 25 | ||
26 | static const lua_Type normtype[] = { /* ORDER LUA_T */ | ||
27 | TAG_USERDATA, TAG_NUMBER, TAG_STRING, TAG_TABLE, | ||
28 | TAG_LCLOSURE, TAG_CCLOSURE, TAG_NIL, | ||
29 | TAG_LCLOSURE, TAG_CCLOSURE /* TAG_LMARK, TAG_CMARK */ | ||
30 | }; | ||
31 | |||
32 | 26 | ||
33 | static void setnormalized (TObject *d, const TObject *s) { | 27 | static void setnormalized (TObject *d, const TObject *s) { |
34 | d->value = s->value; | 28 | switch (s->ttype) { |
35 | d->ttype = normtype[ttype(s)]; | 29 | case TAG_CMARK: { |
36 | } | 30 | clvalue(d) = clvalue(s); |
37 | 31 | ttype(d) = TAG_CCLOSURE; | |
38 | 32 | break; | |
39 | 33 | } | |
40 | static int hasdebuginfo (lua_State *L, StkId f) { | 34 | case TAG_LMARK: { |
41 | return (f+1 < L->top && (f+1)->ttype == TAG_LINE); | 35 | clvalue(d) = infovalue(s)->func; |
36 | ttype(d) = TAG_LCLOSURE; | ||
37 | break; | ||
38 | } | ||
39 | default: *d = *s; | ||
40 | } | ||
42 | } | 41 | } |
43 | 42 | ||
44 | 43 | ||
@@ -88,22 +87,35 @@ int lua_getstack (lua_State *L, int level, lua_Debug *ar) { | |||
88 | 87 | ||
89 | static int lua_nups (StkId f) { | 88 | static int lua_nups (StkId f) { |
90 | switch (ttype(f)) { | 89 | switch (ttype(f)) { |
91 | case TAG_LCLOSURE: case TAG_CCLOSURE: | 90 | case TAG_LCLOSURE: case TAG_CCLOSURE: case TAG_CMARK: |
92 | case TAG_LMARK: case TAG_CMARK: | ||
93 | return clvalue(f)->nupvalues; | 91 | return clvalue(f)->nupvalues; |
92 | case TAG_LMARK: | ||
93 | return infovalue(f)->func->nupvalues; | ||
94 | default: | 94 | default: |
95 | return 0; | 95 | return 0; |
96 | } | 96 | } |
97 | } | 97 | } |
98 | 98 | ||
99 | 99 | ||
100 | static int lua_currentline (lua_State *L, StkId f) { | 100 | static int lua_currentline (StkId f) { |
101 | return hasdebuginfo(L, f) ? (f+1)->value.i : -1; | 101 | if (ttype(f) != TAG_LMARK) |
102 | return -1; /* only active lua functions have current-line information */ | ||
103 | else { | ||
104 | CallInfo *ci = infovalue(f); | ||
105 | int *lines = ci->func->f.l->lines; | ||
106 | if (!lines) return -1; /* no static debug information */ | ||
107 | else return lines[ci->pc]; | ||
108 | } | ||
109 | } | ||
110 | |||
111 | |||
112 | static int lua_currentpc (StkId f) { | ||
113 | return infovalue(f)->pc; | ||
102 | } | 114 | } |
103 | 115 | ||
104 | 116 | ||
105 | static Proto *getluaproto (StkId f) { | 117 | static Proto *getluaproto (StkId f) { |
106 | return (ttype(f) == TAG_LMARK) ? clvalue(f)->f.l : NULL; | 118 | return (ttype(f) == TAG_LMARK) ? infovalue(f)->func->f.l : NULL; |
107 | } | 119 | } |
108 | 120 | ||
109 | 121 | ||
@@ -111,12 +123,9 @@ int lua_getlocal (lua_State *L, const lua_Debug *ar, lua_Localvar *v) { | |||
111 | StkId f = ar->_func; | 123 | StkId f = ar->_func; |
112 | Proto *fp = getluaproto(f); | 124 | Proto *fp = getluaproto(f); |
113 | if (!fp) return 0; /* `f' is not a Lua function? */ | 125 | if (!fp) return 0; /* `f' is not a Lua function? */ |
114 | v->name = luaF_getlocalname(fp, v->index, lua_currentline(L, f)); | 126 | v->name = luaF_getlocalname(fp, v->index, lua_currentpc(f)); |
115 | if (!v->name) return 0; | 127 | if (!v->name) return 0; |
116 | /* if `name', there must be a TAG_LINE */ | 128 | v->value = luaA_putluaObject(L, (f+1)+(v->index-1)); |
117 | /* therefore, f+2 points to function base */ | ||
118 | LUA_ASSERT(L, ttype(f+1) == TAG_LINE, ""); | ||
119 | v->value = luaA_putluaObject(L, (f+2)+(v->index-1)); | ||
120 | return 1; | 129 | return 1; |
121 | } | 130 | } |
122 | 131 | ||
@@ -124,22 +133,27 @@ int lua_getlocal (lua_State *L, const lua_Debug *ar, lua_Localvar *v) { | |||
124 | int lua_setlocal (lua_State *L, const lua_Debug *ar, lua_Localvar *v) { | 133 | int lua_setlocal (lua_State *L, const lua_Debug *ar, lua_Localvar *v) { |
125 | StkId f = ar->_func; | 134 | StkId f = ar->_func; |
126 | Proto *fp = getluaproto(f); | 135 | Proto *fp = getluaproto(f); |
136 | UNUSED(L); | ||
127 | if (!fp) return 0; /* `f' is not a Lua function? */ | 137 | if (!fp) return 0; /* `f' is not a Lua function? */ |
128 | v->name = luaF_getlocalname(fp, v->index, lua_currentline(L, f)); | 138 | v->name = luaF_getlocalname(fp, v->index, lua_currentpc(f)); |
129 | if (!v->name || v->name[0] == '*') return 0; /* `*' starts private locals */ | 139 | if (!v->name || v->name[0] == '*') return 0; /* `*' starts private locals */ |
130 | LUA_ASSERT(L, ttype(f+1) == TAG_LINE, ""); | 140 | *((f+1)+(v->index-1)) = *v->value; |
131 | *((f+2)+(v->index-1)) = *v->value; | ||
132 | return 1; | 141 | return 1; |
133 | } | 142 | } |
134 | 143 | ||
135 | 144 | ||
136 | static void lua_funcinfo (lua_Debug *ar, StkId func) { | 145 | static void lua_funcinfo (lua_Debug *ar, StkId func) { |
137 | switch (ttype(func)) { | 146 | switch (ttype(func)) { |
138 | case TAG_LCLOSURE: case TAG_LMARK: | 147 | case TAG_LCLOSURE: |
139 | ar->source = clvalue(func)->f.l->source->str; | 148 | ar->source = clvalue(func)->f.l->source->str; |
140 | ar->linedefined = clvalue(func)->f.l->lineDefined; | 149 | ar->linedefined = clvalue(func)->f.l->lineDefined; |
141 | ar->what = "Lua"; | 150 | ar->what = "Lua"; |
142 | break; | 151 | break; |
152 | case TAG_LMARK: | ||
153 | ar->source = infovalue(func)->func->f.l->source->str; | ||
154 | ar->linedefined = infovalue(func)->func->f.l->lineDefined; | ||
155 | ar->what = "Lua"; | ||
156 | break; | ||
143 | case TAG_CCLOSURE: case TAG_CMARK: | 157 | case TAG_CCLOSURE: case TAG_CMARK: |
144 | ar->source = "(C)"; | 158 | ar->source = "(C)"; |
145 | ar->linedefined = -1; | 159 | ar->linedefined = -1; |
@@ -191,7 +205,7 @@ int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { | |||
191 | lua_funcinfo(ar, func); | 205 | lua_funcinfo(ar, func); |
192 | break; | 206 | break; |
193 | case 'l': | 207 | case 'l': |
194 | ar->currentline = lua_currentline(L, func); | 208 | ar->currentline = lua_currentline(func); |
195 | break; | 209 | break; |
196 | case 'u': | 210 | case 'u': |
197 | ar->nups = lua_nups(func); | 211 | ar->nups = lua_nups(func); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ldo.c,v 1.78 2000/06/12 13:52:05 roberto Exp roberto $ | 2 | ** $Id: ldo.c,v 1.79 2000/06/16 17:16:34 roberto Exp roberto $ |
3 | ** Stack and Call structure of Lua | 3 | ** Stack and Call structure of Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -185,10 +185,14 @@ void luaD_call (lua_State *L, StkId func, int nResults) { | |||
185 | retry: /* for `function' tag method */ | 185 | retry: /* for `function' tag method */ |
186 | switch (ttype(func)) { | 186 | switch (ttype(func)) { |
187 | case TAG_LCLOSURE: { | 187 | case TAG_LCLOSURE: { |
188 | CallInfo ci; | ||
189 | ci.func = clvalue(func); | ||
190 | ci.pc = 0; | ||
188 | ttype(func) = TAG_LMARK; | 191 | ttype(func) = TAG_LMARK; |
192 | infovalue(func) = &ci; | ||
189 | if (callhook) | 193 | if (callhook) |
190 | luaD_callHook(L, func, callhook, "call"); | 194 | luaD_callHook(L, func, callhook, "call"); |
191 | firstResult = luaV_execute(L, clvalue(func), func+1); | 195 | firstResult = luaV_execute(L, ci.func, func+1); |
192 | break; | 196 | break; |
193 | } | 197 | } |
194 | case TAG_CCLOSURE: { | 198 | case TAG_CCLOSURE: { |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lfunc.c,v 1.23 2000/05/30 19:00:31 roberto Exp roberto $ | 2 | ** $Id: lfunc.c,v 1.24 2000/06/12 13:52:05 roberto Exp roberto $ |
3 | ** Auxiliary functions to manipulate prototypes and closures | 3 | ** Auxiliary functions to manipulate prototypes and closures |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -35,6 +35,7 @@ Closure *luaF_newclosure (lua_State *L, int nelems) { | |||
35 | Proto *luaF_newproto (lua_State *L) { | 35 | Proto *luaF_newproto (lua_State *L) { |
36 | Proto *f = luaM_new(L, Proto); | 36 | Proto *f = luaM_new(L, Proto); |
37 | f->code = NULL; | 37 | f->code = NULL; |
38 | f->lines = NULL; | ||
38 | f->lineDefined = 0; | 39 | f->lineDefined = 0; |
39 | f->source = NULL; | 40 | f->source = NULL; |
40 | f->kstr = NULL; | 41 | f->kstr = NULL; |
@@ -59,6 +60,7 @@ void luaF_freeproto (lua_State *L, Proto *f) { | |||
59 | luaM_free(L, f->kstr); | 60 | luaM_free(L, f->kstr); |
60 | luaM_free(L, f->knum); | 61 | luaM_free(L, f->knum); |
61 | luaM_free(L, f->kproto); | 62 | luaM_free(L, f->kproto); |
63 | luaM_free(L, f->lines); | ||
62 | luaM_free(L, f); | 64 | luaM_free(L, f); |
63 | } | 65 | } |
64 | 66 | ||
@@ -73,14 +75,13 @@ void luaF_freeclosure (lua_State *L, Closure *c) { | |||
73 | ** Look for n-th local variable at line `line' in function `func'. | 75 | ** Look for n-th local variable at line `line' in function `func'. |
74 | ** Returns NULL if not found. | 76 | ** Returns NULL if not found. |
75 | */ | 77 | */ |
76 | const char *luaF_getlocalname (const Proto *func, | 78 | const char *luaF_getlocalname (const Proto *func, int local_number, int pc) { |
77 | int local_number, int line) { | ||
78 | int count = 0; | 79 | int count = 0; |
79 | const char *varname = NULL; | 80 | const char *varname = NULL; |
80 | LocVar *lv = func->locvars; | 81 | LocVar *lv = func->locvars; |
81 | if (lv == NULL) | 82 | if (lv == NULL) |
82 | return NULL; | 83 | return NULL; |
83 | for (; lv->line != -1 && lv->line < line; lv++) { | 84 | for (; lv->pc != -1 && lv->pc <= pc; lv++) { |
84 | if (lv->varname) { /* register */ | 85 | if (lv->varname) { /* register */ |
85 | if (++count == local_number) | 86 | if (++count == local_number) |
86 | varname = lv->varname->str; | 87 | varname = lv->varname->str; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lfunc.h,v 1.10 1999/12/27 17:33:22 roberto Exp roberto $ | 2 | ** $Id: lfunc.h,v 1.11 2000/03/10 18:37:44 roberto Exp roberto $ |
3 | ** Auxiliary functions to manipulate prototypes and closures | 3 | ** Auxiliary functions to manipulate prototypes and closures |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -17,8 +17,7 @@ Closure *luaF_newclosure (lua_State *L, int nelems); | |||
17 | void luaF_freeproto (lua_State *L, Proto *f); | 17 | void luaF_freeproto (lua_State *L, Proto *f); |
18 | void luaF_freeclosure (lua_State *L, Closure *c); | 18 | void luaF_freeclosure (lua_State *L, Closure *c); |
19 | 19 | ||
20 | const char *luaF_getlocalname (const Proto *func, | 20 | const char *luaF_getlocalname (const Proto *func, int local_number, int pc); |
21 | int local_number, int line); | ||
22 | 21 | ||
23 | 22 | ||
24 | #endif | 23 | #endif |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 1.56 2000/06/08 17:48:31 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 1.57 2000/06/12 13:52:05 roberto Exp roberto $ |
3 | ** Garbage Collector | 3 | ** Garbage Collector |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -41,7 +41,7 @@ static void protomark (lua_State *L, Proto *f) { | |||
41 | protomark(L, f->kproto[i]); | 41 | protomark(L, f->kproto[i]); |
42 | if (f->locvars) { /* is there debug information? */ | 42 | if (f->locvars) { /* is there debug information? */ |
43 | LocVar *lv; | 43 | LocVar *lv; |
44 | for (lv=f->locvars; lv->line != -1; lv++) /* mark local-variable names */ | 44 | for (lv=f->locvars; lv->pc != -1; lv++) /* mark local-variable names */ |
45 | if (lv->varname) strmark(L, lv->varname); | 45 | if (lv->varname) strmark(L, lv->varname); |
46 | } | 46 | } |
47 | } | 47 | } |
@@ -99,9 +99,16 @@ static int markobject (lua_State *L, TObject *o) { | |||
99 | case TAG_TABLE: | 99 | case TAG_TABLE: |
100 | tablemark(L, hvalue(o)); | 100 | tablemark(L, hvalue(o)); |
101 | break; | 101 | break; |
102 | case TAG_LCLOSURE: case TAG_LMARK: | 102 | case TAG_LCLOSURE: |
103 | protomark(L, clvalue(o)->f.l); | 103 | protomark(L, clvalue(o)->f.l); |
104 | /* go trhough */ | 104 | closuremark(L, clvalue(o)); |
105 | break; | ||
106 | case TAG_LMARK: { | ||
107 | Closure *cl = infovalue(o)->func; | ||
108 | protomark(L, cl->f.l); | ||
109 | closuremark(L, cl); | ||
110 | break; | ||
111 | } | ||
105 | case TAG_CCLOSURE: case TAG_CMARK: | 112 | case TAG_CCLOSURE: case TAG_CMARK: |
106 | closuremark(L, clvalue(o)); | 113 | closuremark(L, clvalue(o)); |
107 | break; | 114 | break; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lmem.c,v 1.32 2000/05/31 16:53:30 roberto Exp roberto $ | 2 | ** $Id: lmem.c,v 1.33 2000/06/12 13:52:05 roberto Exp roberto $ |
3 | ** Interface to Memory Manager | 3 | ** Interface to Memory Manager |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -47,7 +47,8 @@ | |||
47 | 47 | ||
48 | 48 | ||
49 | /* ensures maximum alignment for HEADER */ | 49 | /* ensures maximum alignment for HEADER */ |
50 | #define HEADER (sizeof(union { double d; char *s; long l; })) | 50 | union L_U { double d; char *s; long l; }; |
51 | #define HEADER (sizeof(union L_U)) | ||
51 | 52 | ||
52 | #define MARKSIZE 16 | 53 | #define MARKSIZE 16 |
53 | #define MARK 0x55 /* 01010101 (a nice pattern) */ | 54 | #define MARK 0x55 /* 01010101 (a nice pattern) */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lobject.c,v 1.40 2000/06/08 17:48:31 roberto Exp roberto $ | 2 | ** $Id: lobject.c,v 1.41 2000/06/12 13:52:05 roberto Exp roberto $ |
3 | ** Some generic functions over Lua objects | 3 | ** Some generic functions over Lua objects |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -16,7 +16,7 @@ | |||
16 | 16 | ||
17 | const char *const luaO_typenames[] = { /* ORDER LUA_T */ | 17 | const char *const luaO_typenames[] = { /* ORDER LUA_T */ |
18 | "userdata", "number", "string", "table", "function", "function", "nil", | 18 | "userdata", "number", "string", "table", "function", "function", "nil", |
19 | "function", "function", "line" | 19 | "function", "function" |
20 | }; | 20 | }; |
21 | 21 | ||
22 | 22 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lobject.h,v 1.66 2000/05/30 19:00:31 roberto Exp roberto $ | 2 | ** $Id: lobject.h,v 1.67 2000/06/08 18:27:13 roberto Exp roberto $ |
3 | ** Type definitions for Lua objects | 3 | ** Type definitions for Lua objects |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -46,9 +46,8 @@ typedef enum { | |||
46 | TAG_NIL, /* last "pre-defined" tag */ | 46 | TAG_NIL, /* last "pre-defined" tag */ |
47 | 47 | ||
48 | TAG_LMARK, /* mark for Lua closures */ | 48 | TAG_LMARK, /* mark for Lua closures */ |
49 | TAG_CMARK, /* mark for C closures */ | 49 | TAG_CMARK /* mark for C closures */ |
50 | 50 | ||
51 | TAG_LINE | ||
52 | } lua_Type; | 51 | } lua_Type; |
53 | 52 | ||
54 | /* tags for values visible from Lua == first user-created tag */ | 53 | /* tags for values visible from Lua == first user-created tag */ |
@@ -63,10 +62,10 @@ typedef enum { | |||
63 | 62 | ||
64 | typedef union { | 63 | typedef union { |
65 | struct TString *ts; /* TAG_STRING, TAG_USERDATA */ | 64 | struct TString *ts; /* TAG_STRING, TAG_USERDATA */ |
66 | struct Closure *cl; /* TAG_[CL]CLOSURE, TAG_[CL]MARK */ | 65 | struct Closure *cl; /* TAG_[CL]CLOSURE, TAG_CMARK */ |
67 | struct Hash *a; /* TAG_TABLE */ | 66 | struct Hash *a; /* TAG_TABLE */ |
67 | struct CallInfo *i; /* TAG_LMARK */ | ||
68 | Number n; /* TAG_NUMBER */ | 68 | Number n; /* TAG_NUMBER */ |
69 | int i; /* TAG_LINE */ | ||
70 | } Value; | 69 | } Value; |
71 | 70 | ||
72 | 71 | ||
@@ -76,6 +75,7 @@ typedef union { | |||
76 | #define tsvalue(o) ((o)->value.ts) | 75 | #define tsvalue(o) ((o)->value.ts) |
77 | #define clvalue(o) ((o)->value.cl) | 76 | #define clvalue(o) ((o)->value.cl) |
78 | #define hvalue(o) ((o)->value.a) | 77 | #define hvalue(o) ((o)->value.a) |
78 | #define infovalue(o) ((o)->value.i) | ||
79 | #define svalue(o) (tsvalue(o)->str) | 79 | #define svalue(o) (tsvalue(o)->str) |
80 | 80 | ||
81 | 81 | ||
@@ -119,8 +119,10 @@ typedef struct Proto { | |||
119 | struct Proto **kproto; /* functions defined inside the function */ | 119 | struct Proto **kproto; /* functions defined inside the function */ |
120 | int nkproto; /* size of `kproto' */ | 120 | int nkproto; /* size of `kproto' */ |
121 | Instruction *code; /* ends with opcode ENDCODE */ | 121 | Instruction *code; /* ends with opcode ENDCODE */ |
122 | int *lines; /* source line that generated each opcode */ | ||
122 | int lineDefined; | 123 | int lineDefined; |
123 | TString *source; | 124 | TString *source; |
125 | int debug; /* flag for debug information */ | ||
124 | int numparams; | 126 | int numparams; |
125 | int is_vararg; | 127 | int is_vararg; |
126 | int maxstacksize; | 128 | int maxstacksize; |
@@ -130,7 +132,7 @@ typedef struct Proto { | |||
130 | 132 | ||
131 | typedef struct LocVar { | 133 | typedef struct LocVar { |
132 | TString *varname; /* NULL signals end of scope */ | 134 | TString *varname; /* NULL signals end of scope */ |
133 | int line; | 135 | int pc; |
134 | } LocVar; | 136 | } LocVar; |
135 | 137 | ||
136 | 138 | ||
@@ -165,6 +167,16 @@ typedef struct Hash { | |||
165 | } Hash; | 167 | } Hash; |
166 | 168 | ||
167 | 169 | ||
170 | /* | ||
171 | ** informations about a call (for debugging) | ||
172 | */ | ||
173 | typedef struct CallInfo { | ||
174 | int pc; /* current pc of called function */ | ||
175 | int line; /* current line */ | ||
176 | struct Closure *func; /* function being called */ | ||
177 | } CallInfo; | ||
178 | |||
179 | |||
168 | extern const char *const luaO_typenames[]; | 180 | extern const char *const luaO_typenames[]; |
169 | extern const TObject luaO_nilobject; | 181 | extern const TObject luaO_nilobject; |
170 | 182 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lopcodes.h,v 1.63 2000/06/05 14:56:18 roberto Exp roberto $ | 2 | ** $Id: lopcodes.h,v 1.64 2000/06/21 17:05:49 roberto Exp roberto $ |
3 | ** Opcodes for Lua virtual machine | 3 | ** Opcodes for Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -146,13 +146,11 @@ OP_FORLOOP,/* J */ | |||
146 | OP_LFORPREP,/* J */ | 146 | OP_LFORPREP,/* J */ |
147 | OP_LFORLOOP,/* J */ | 147 | OP_LFORLOOP,/* J */ |
148 | 148 | ||
149 | OP_CLOSURE,/* A B v_b-v_1 closure(KPROTO[a], v_1-v_b) */ | 149 | OP_CLOSURE/* A B v_b-v_1 closure(KPROTO[a], v_1-v_b) */ |
150 | |||
151 | OP_SETLINE/* U - - LINE=u */ | ||
152 | 150 | ||
153 | } OpCode; | 151 | } OpCode; |
154 | 152 | ||
155 | #define NUM_OPCODES ((int)OP_SETLINE+1) | 153 | #define NUM_OPCODES ((int)OP_CLOSURE+1) |
156 | 154 | ||
157 | 155 | ||
158 | #define ISJUMP(o) (OP_JMPNE <= (o) && (o) <= OP_JMP) | 156 | #define ISJUMP(o) (OP_JMPNE <= (o) && (o) <= OP_JMP) |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 1.97 2000/06/19 18:26:23 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.98 2000/06/21 18:13:56 roberto Exp roberto $ |
3 | ** LL(1) Parser and code generator for Lua | 3 | ** LL(1) Parser and code generator for Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -152,19 +152,19 @@ static int checkname (LexState *ls) { | |||
152 | } | 152 | } |
153 | 153 | ||
154 | 154 | ||
155 | static void luaI_registerlocalvar (LexState *ls, TString *varname, int line) { | 155 | static void luaI_registerlocalvar (LexState *ls, TString *varname, int pc) { |
156 | FuncState *fs = ls->fs; | 156 | FuncState *fs = ls->fs; |
157 | if (fs->debug) { | 157 | if (fs->f->debug) { |
158 | Proto *f = fs->f; | 158 | Proto *f = fs->f; |
159 | luaM_growvector(ls->L, f->locvars, fs->nvars, 1, LocVar, "", MAX_INT); | 159 | luaM_growvector(ls->L, f->locvars, fs->nvars, 1, LocVar, "", MAX_INT); |
160 | f->locvars[fs->nvars].varname = varname; | 160 | f->locvars[fs->nvars].varname = varname; |
161 | f->locvars[fs->nvars].line = line; | 161 | f->locvars[fs->nvars].pc = pc; |
162 | fs->nvars++; | 162 | fs->nvars++; |
163 | } | 163 | } |
164 | } | 164 | } |
165 | 165 | ||
166 | 166 | ||
167 | static void store_localvar (LexState *ls, TString *name, int n) { | 167 | static void new_localvar (LexState *ls, TString *name, int n) { |
168 | FuncState *fs = ls->fs; | 168 | FuncState *fs = ls->fs; |
169 | luaX_checklimit(ls, fs->nlocalvar+n+1, MAXLOCALS, "local variables"); | 169 | luaX_checklimit(ls, fs->nlocalvar+n+1, MAXLOCALS, "local variables"); |
170 | fs->localvar[fs->nlocalvar+n] = name; | 170 | fs->localvar[fs->nlocalvar+n] = name; |
@@ -172,27 +172,27 @@ static void store_localvar (LexState *ls, TString *name, int n) { | |||
172 | 172 | ||
173 | 173 | ||
174 | static void adjustlocalvars (LexState *ls, int nvars) { | 174 | static void adjustlocalvars (LexState *ls, int nvars) { |
175 | int line = ls->fs->lastsetline; | ||
176 | FuncState *fs = ls->fs; | 175 | FuncState *fs = ls->fs; |
177 | int i; | 176 | int i; |
177 | /* `pc' is first opcode where variable is already active */ | ||
178 | for (i=fs->nlocalvar; i<fs->nlocalvar+nvars; i++) | 178 | for (i=fs->nlocalvar; i<fs->nlocalvar+nvars; i++) |
179 | luaI_registerlocalvar(ls, fs->localvar[i], line); | 179 | luaI_registerlocalvar(ls, fs->localvar[i], fs->pc); |
180 | fs->nlocalvar += nvars; | 180 | fs->nlocalvar += nvars; |
181 | } | 181 | } |
182 | 182 | ||
183 | 183 | ||
184 | static void removelocalvars (LexState *ls, int nvars) { | 184 | static void removelocalvars (LexState *ls, int nvars) { |
185 | int line = ls->fs->lastsetline; | 185 | FuncState *fs = ls->fs; |
186 | int i; | 186 | int i; |
187 | /* `pc' is first opcode where variable is already dead */ | ||
187 | for (i=0;i<nvars;i++) | 188 | for (i=0;i<nvars;i++) |
188 | luaI_registerlocalvar(ls, NULL, line); | 189 | luaI_registerlocalvar(ls, NULL, fs->pc); |
189 | ls->fs->nlocalvar -= nvars; | 190 | fs->nlocalvar -= nvars; |
190 | } | 191 | } |
191 | 192 | ||
192 | 193 | ||
193 | static void add_localvar (LexState *ls, const char *name) { | 194 | static void new_localvarstr (LexState *ls, const char *name, int n) { |
194 | store_localvar(ls, luaS_newfixed(ls->L, name), 0); | 195 | new_localvar(ls, luaS_newfixed(ls->L, name), n); |
195 | adjustlocalvars(ls, 1); | ||
196 | } | 196 | } |
197 | 197 | ||
198 | 198 | ||
@@ -277,8 +277,10 @@ static void code_params (LexState *ls, int nparams, int dots) { | |||
277 | luaX_checklimit(ls, fs->nlocalvar, MAXPARAMS, "parameters"); | 277 | luaX_checklimit(ls, fs->nlocalvar, MAXPARAMS, "parameters"); |
278 | fs->f->numparams = fs->nlocalvar; /* `self' could be there already */ | 278 | fs->f->numparams = fs->nlocalvar; /* `self' could be there already */ |
279 | fs->f->is_vararg = dots; | 279 | fs->f->is_vararg = dots; |
280 | if (dots) | 280 | if (dots) { |
281 | add_localvar(ls, "arg"); | 281 | new_localvarstr(ls, "arg", 0); |
282 | adjustlocalvars(ls, 1); | ||
283 | } | ||
282 | luaK_deltastack(fs, fs->nlocalvar); /* count parameters in the stack */ | 284 | luaK_deltastack(fs, fs->nlocalvar); /* count parameters in the stack */ |
283 | } | 285 | } |
284 | 286 | ||
@@ -320,7 +322,6 @@ static void open_func (LexState *ls, FuncState *fs) { | |||
320 | fs->stacklevel = 0; | 322 | fs->stacklevel = 0; |
321 | fs->nlocalvar = 0; | 323 | fs->nlocalvar = 0; |
322 | fs->nupvalues = 0; | 324 | fs->nupvalues = 0; |
323 | fs->lastsetline = 0; | ||
324 | fs->bl = NULL; | 325 | fs->bl = NULL; |
325 | fs->f = f; | 326 | fs->f = f; |
326 | f->source = ls->source; | 327 | f->source = ls->source; |
@@ -358,7 +359,7 @@ Proto *luaY_parser (lua_State *L, ZIO *z) { | |||
358 | luaX_setinput(L, &lexstate, z, luaS_new(L, zname(z))); | 359 | luaX_setinput(L, &lexstate, z, luaS_new(L, zname(z))); |
359 | open_func(&lexstate, &funcstate); | 360 | open_func(&lexstate, &funcstate); |
360 | next(&lexstate); /* read first token */ | 361 | next(&lexstate); /* read first token */ |
361 | funcstate.debug = L->debug; /* previous `next' may scan a pragma */ | 362 | funcstate.f->debug = L->debug; /* previous `next' may scan a pragma */ |
362 | chunk(&lexstate); | 363 | chunk(&lexstate); |
363 | check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected"); | 364 | check_condition(&lexstate, (lexstate.t.token == TK_EOS), "<eof> expected"); |
364 | close_func(&lexstate); | 365 | close_func(&lexstate); |
@@ -821,22 +822,23 @@ static void repeatstat (LexState *ls, int line) { | |||
821 | } | 822 | } |
822 | 823 | ||
823 | 824 | ||
824 | static void forbody (LexState *ls, OpCode prepfor, OpCode loopfor) { | 825 | static void forbody (LexState *ls, int nvar, OpCode prepfor, OpCode loopfor) { |
825 | /* forbody -> DO block END */ | 826 | /* forbody -> DO block END */ |
826 | FuncState *fs = ls->fs; | 827 | FuncState *fs = ls->fs; |
827 | int prep = luaK_code1(fs, prepfor, NO_JUMP); | 828 | int prep = luaK_code1(fs, prepfor, NO_JUMP); |
828 | int blockinit = luaK_getlabel(fs); | 829 | int blockinit = luaK_getlabel(fs); |
829 | check(ls, TK_DO); | 830 | check(ls, TK_DO); |
831 | adjustlocalvars(ls, nvar); /* scope for control variables */ | ||
830 | block(ls); | 832 | block(ls); |
831 | luaK_patchlist(fs, prep, luaK_getlabel(fs)); | 833 | luaK_patchlist(fs, prep, luaK_getlabel(fs)); |
832 | luaK_patchlist(fs, luaK_code1(fs, loopfor, NO_JUMP), blockinit); | 834 | luaK_patchlist(fs, luaK_code1(fs, loopfor, NO_JUMP), blockinit); |
835 | removelocalvars(ls, nvar); | ||
833 | } | 836 | } |
834 | 837 | ||
835 | 838 | ||
836 | static void fornum (LexState *ls, TString *varname) { | 839 | static void fornum (LexState *ls, TString *varname) { |
837 | /* fornum -> NAME = exp1,exp1[,exp1] forbody */ | 840 | /* fornum -> NAME = exp1,exp1[,exp1] forbody */ |
838 | FuncState *fs = ls->fs; | 841 | FuncState *fs = ls->fs; |
839 | store_localvar(ls, varname, 0); | ||
840 | check(ls, '='); | 842 | check(ls, '='); |
841 | exp1(ls); /* initial value */ | 843 | exp1(ls); /* initial value */ |
842 | check(ls, ','); | 844 | check(ls, ','); |
@@ -845,11 +847,10 @@ static void fornum (LexState *ls, TString *varname) { | |||
845 | exp1(ls); /* optional step */ | 847 | exp1(ls); /* optional step */ |
846 | else | 848 | else |
847 | luaK_code1(fs, OP_PUSHINT, 1); /* default step */ | 849 | luaK_code1(fs, OP_PUSHINT, 1); /* default step */ |
848 | adjustlocalvars(ls, 1); /* scope for control variables */ | 850 | new_localvar(ls, varname, 0); |
849 | add_localvar(ls, "*limit*"); | 851 | new_localvarstr(ls, "*limit*", 1); |
850 | add_localvar(ls, "*count*"); | 852 | new_localvarstr(ls, "*step*", 2); |
851 | forbody(ls, OP_FORPREP, OP_FORLOOP); | 853 | forbody(ls, 3, OP_FORPREP, OP_FORLOOP); |
852 | removelocalvars(ls, 3); | ||
853 | } | 854 | } |
854 | 855 | ||
855 | 856 | ||
@@ -864,13 +865,11 @@ static void forlist (LexState *ls, TString *indexname) { | |||
864 | "`in' expected"); | 865 | "`in' expected"); |
865 | next(ls); /* skip `in' */ | 866 | next(ls); /* skip `in' */ |
866 | exp1(ls); /* table */ | 867 | exp1(ls); /* table */ |
867 | add_localvar(ls, "*table*"); | 868 | new_localvarstr(ls, "*table*", 0); |
868 | add_localvar(ls, "*counter*"); | 869 | new_localvarstr(ls, "*counter*", 1); |
869 | store_localvar(ls, indexname, 0); | 870 | new_localvar(ls, indexname, 2); |
870 | store_localvar(ls, valname, 1); | 871 | new_localvar(ls, valname, 3); |
871 | adjustlocalvars(ls, 2); /* scope for control variable */ | 872 | forbody(ls, 4, OP_LFORPREP, OP_LFORLOOP); |
872 | forbody(ls, OP_LFORPREP, OP_LFORLOOP); | ||
873 | removelocalvars(ls, 4); | ||
874 | } | 873 | } |
875 | 874 | ||
876 | 875 | ||
@@ -931,7 +930,7 @@ static void localstat (LexState *ls) { | |||
931 | int nexps; | 930 | int nexps; |
932 | do { | 931 | do { |
933 | next(ls); /* skip LOCAL or ',' */ | 932 | next(ls); /* skip LOCAL or ',' */ |
934 | store_localvar(ls, str_checkname(ls), nvars++); | 933 | new_localvar(ls, str_checkname(ls), nvars++); |
935 | } while (ls->t.token == ','); | 934 | } while (ls->t.token == ','); |
936 | if (optional(ls, '=')) | 935 | if (optional(ls, '=')) |
937 | nexps = explist1(ls); | 936 | nexps = explist1(ls); |
@@ -1072,7 +1071,7 @@ static void parlist (LexState *ls) { | |||
1072 | do { | 1071 | do { |
1073 | switch (ls->t.token) { | 1072 | switch (ls->t.token) { |
1074 | case TK_DOTS: next(ls); dots = 1; break; | 1073 | case TK_DOTS: next(ls); dots = 1; break; |
1075 | case TK_NAME: store_localvar(ls, str_checkname(ls), nparams++); break; | 1074 | case TK_NAME: new_localvar(ls, str_checkname(ls), nparams++); break; |
1076 | default: luaK_error(ls, "<name> or `...' expected"); | 1075 | default: luaK_error(ls, "<name> or `...' expected"); |
1077 | } | 1076 | } |
1078 | } while (!dots && optional(ls, ',')); | 1077 | } while (!dots && optional(ls, ',')); |
@@ -1086,10 +1085,12 @@ static void body (LexState *ls, int needself, int line) { | |||
1086 | FuncState new_fs; | 1085 | FuncState new_fs; |
1087 | open_func(ls, &new_fs); | 1086 | open_func(ls, &new_fs); |
1088 | new_fs.f->lineDefined = line; | 1087 | new_fs.f->lineDefined = line; |
1089 | new_fs.debug = ls->L->debug; | 1088 | new_fs.f->debug = ls->L->debug; |
1090 | check(ls, '('); | 1089 | check(ls, '('); |
1091 | if (needself) | 1090 | if (needself) { |
1092 | add_localvar(ls, "self"); | 1091 | new_localvarstr(ls, "self", 0); |
1092 | adjustlocalvars(ls, 1); | ||
1093 | } | ||
1093 | parlist(ls); | 1094 | parlist(ls); |
1094 | check(ls, ')'); | 1095 | check(ls, ')'); |
1095 | chunk(ls); | 1096 | chunk(ls); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.h,v 1.17 2000/05/25 18:26:42 roberto Exp roberto $ | 2 | ** $Id: lparser.h,v 1.18 2000/06/21 18:13:56 roberto Exp roberto $ |
3 | ** LL(1) Parser and code generator for Lua | 3 | ** LL(1) Parser and code generator for Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -48,8 +48,6 @@ typedef struct FuncState { | |||
48 | int nlocalvar; /* number of active local variables */ | 48 | int nlocalvar; /* number of active local variables */ |
49 | int nupvalues; /* number of upvalues */ | 49 | int nupvalues; /* number of upvalues */ |
50 | int nvars; /* number of entries in f->locvars */ | 50 | int nvars; /* number of entries in f->locvars */ |
51 | int lastsetline; /* line where last SETLINE was issued */ | ||
52 | int debug; /* flag to generate debug information */ | ||
53 | struct Breaklabel *bl; /* chain of breakable blocks */ | 51 | struct Breaklabel *bl; /* chain of breakable blocks */ |
54 | expdesc upvalues[MAXUPVALUES]; /* upvalues */ | 52 | expdesc upvalues[MAXUPVALUES]; /* upvalues */ |
55 | TString *localvar[MAXLOCALS]; /* store local variable names */ | 53 | TString *localvar[MAXLOCALS]; /* store local variable names */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltests.c,v 1.25 2000/06/12 13:52:05 roberto Exp roberto $ | 2 | ** $Id: ltests.c,v 1.26 2000/06/21 17:05:49 roberto Exp roberto $ |
3 | ** Internal Module for Debugging of the Lua Implementation | 3 | ** Internal Module for Debugging of the Lua Implementation |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -58,7 +58,7 @@ static const char *const instrname[NUM_OPCODES] = { | |||
58 | "ADD", "ADDI", "SUB", "MULT", "DIV", "POW", "CONCAT", "MINUS", "NOT", | 58 | "ADD", "ADDI", "SUB", "MULT", "DIV", "POW", "CONCAT", "MINUS", "NOT", |
59 | "JMPNE", "JMPEQ", "JMPLT", "JMPLE", "JMPGT", "JMPGE", "JMPT", "JMPF", | 59 | "JMPNE", "JMPEQ", "JMPLT", "JMPLE", "JMPGT", "JMPGE", "JMPT", "JMPF", |
60 | "JMPONT", "JMPONF", "JMP", "PUSHNILJMP", "FORPREP", "FORLOOP", "LFORPREP", | 60 | "JMPONT", "JMPONF", "JMP", "PUSHNILJMP", "FORPREP", "FORLOOP", "LFORPREP", |
61 | "LFORLOOP", "CLOSURE", "SETLINE" | 61 | "LFORLOOP", "CLOSURE" |
62 | }; | 62 | }; |
63 | 63 | ||
64 | 64 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lundump.c,v 1.21 2000/05/08 19:32:53 roberto Exp roberto $ | 2 | ** $Id: lundump.c,v 1.22 2000/06/12 13:52:05 roberto Exp roberto $ |
3 | ** load bytecodes from files | 3 | ** load bytecodes from files |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -93,7 +93,7 @@ static TString* LoadString (lua_State* L, ZIO* Z) | |||
93 | static void SwapCode (lua_State* L, Instruction* code, int size, ZIO* Z) | 93 | static void SwapCode (lua_State* L, Instruction* code, int size, ZIO* Z) |
94 | { | 94 | { |
95 | unsigned char* p; | 95 | unsigned char* p; |
96 | int c; | 96 | unsigned char c; |
97 | if (sizeof(Instruction)==4) | 97 | if (sizeof(Instruction)==4) |
98 | while (size--) | 98 | while (size--) |
99 | { | 99 | { |
@@ -138,10 +138,10 @@ static void LoadLocals (lua_State* L, Proto* tf, ZIO* Z) | |||
138 | tf->locvars=luaM_newvector(L,n+1,LocVar); | 138 | tf->locvars=luaM_newvector(L,n+1,LocVar); |
139 | for (i=0; i<n; i++) | 139 | for (i=0; i<n; i++) |
140 | { | 140 | { |
141 | tf->locvars[i].line=LoadInt(L,Z,"too many lines"); | 141 | tf->locvars[i].pc=LoadInt(L,Z,"too many lines"); |
142 | tf->locvars[i].varname=LoadString(L,Z); | 142 | tf->locvars[i].varname=LoadString(L,Z); |
143 | } | 143 | } |
144 | tf->locvars[i].line=-1; /* flag end of vector */ | 144 | tf->locvars[i].pc=-1; /* flag end of vector */ |
145 | tf->locvars[i].varname=NULL; | 145 | tf->locvars[i].varname=NULL; |
146 | } | 146 | } |
147 | 147 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 1.115 2000/06/12 13:52:05 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.116 2000/06/19 18:04:41 roberto Exp roberto $ |
3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -67,6 +67,23 @@ int luaV_tostring (lua_State *L, TObject *obj) { /* LUA_NUMBER */ | |||
67 | } | 67 | } |
68 | 68 | ||
69 | 69 | ||
70 | static void traceexec (lua_State *L, StkId base, int pc) { | ||
71 | CallInfo *ci = infovalue(base-1); | ||
72 | int oldpc = ci->pc; | ||
73 | pc--; /* pc has been already incremented */ | ||
74 | ci->pc = pc; | ||
75 | if (L->linehook && ci->func->f.l->debug) { | ||
76 | int *lines = ci->func->f.l->lines; | ||
77 | LUA_ASSERT(L, lines, "must have debug information"); | ||
78 | /* calls linehook when jumps back (a loop) or enters a new line */ | ||
79 | if (pc <= oldpc || lines[pc] != ci->line) { | ||
80 | ci->line = lines[pc]; | ||
81 | luaD_lineHook(L, base-2, lines[pc]); | ||
82 | } | ||
83 | } | ||
84 | } | ||
85 | |||
86 | |||
70 | static Closure *luaV_closure (lua_State *L, lua_Type t, int nelems) { | 87 | static Closure *luaV_closure (lua_State *L, lua_Type t, int nelems) { |
71 | Closure *c = luaF_newclosure(L, nelems); | 88 | Closure *c = luaF_newclosure(L, nelems); |
72 | L->top -= nelems; | 89 | L->top -= nelems; |
@@ -226,13 +243,6 @@ static void call_arith (lua_State *L, StkId top, IMS event) { | |||
226 | } | 243 | } |
227 | 244 | ||
228 | 245 | ||
229 | static void addK (lua_State *L, StkId top, int k) { | ||
230 | ttype(top) = TAG_NUMBER; | ||
231 | nvalue(top) = (Number)k; | ||
232 | call_arith(L, top+1, IM_ADD); | ||
233 | } | ||
234 | |||
235 | |||
236 | static int luaV_strcomp (const TString *ls, const TString *rs) { | 246 | static int luaV_strcomp (const TString *ls, const TString *rs) { |
237 | const char *l = ls->str; | 247 | const char *l = ls->str; |
238 | size_t ll = ls->u.s.len; | 248 | size_t ll = ls->u.s.len; |
@@ -338,6 +348,7 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
338 | StkId top; /* keep top local, for performance */ | 348 | StkId top; /* keep top local, for performance */ |
339 | const Instruction *pc = tf->code; | 349 | const Instruction *pc = tf->code; |
340 | TString **kstr = tf->kstr; | 350 | TString **kstr = tf->kstr; |
351 | int debug = tf->debug; | ||
341 | luaD_checkstack(L, tf->maxstacksize+EXTRA_STACK); | 352 | luaD_checkstack(L, tf->maxstacksize+EXTRA_STACK); |
342 | if (tf->is_vararg) { /* varargs? */ | 353 | if (tf->is_vararg) { /* varargs? */ |
343 | adjust_varargs(L, base, tf->numparams); | 354 | adjust_varargs(L, base, tf->numparams); |
@@ -346,8 +357,13 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
346 | else | 357 | else |
347 | luaD_adjusttop(L, base, tf->numparams); | 358 | luaD_adjusttop(L, base, tf->numparams); |
348 | top = L->top; | 359 | top = L->top; |
360 | /* main loop of interpreter */ | ||
349 | for (;;) { | 361 | for (;;) { |
350 | Instruction i = *pc++; | 362 | Instruction i = *pc++; |
363 | if (debug) { | ||
364 | L->top = top; | ||
365 | traceexec(L, base, pc - tf->code); | ||
366 | } | ||
351 | switch (GET_OPCODE(i)) { | 367 | switch (GET_OPCODE(i)) { |
352 | 368 | ||
353 | case OP_END: | 369 | case OP_END: |
@@ -499,8 +515,11 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
499 | break; | 515 | break; |
500 | 516 | ||
501 | case OP_ADDI: | 517 | case OP_ADDI: |
502 | if (tonumber(top-1)) | 518 | if (tonumber(top-1)) { |
503 | addK(L, top, GETARG_S(i)); | 519 | ttype(top) = TAG_NUMBER; |
520 | nvalue(top) = (Number)GETARG_S(i); | ||
521 | call_arith(L, top+1, IM_ADD); | ||
522 | } | ||
504 | else | 523 | else |
505 | nvalue(top-1) += (Number)GETARG_S(i); | 524 | nvalue(top-1) += (Number)GETARG_S(i); |
506 | break; | 525 | break; |
@@ -622,35 +641,44 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
622 | lua_error(L, "`for' limit must be a number"); | 641 | lua_error(L, "`for' limit must be a number"); |
623 | if (tonumber(top-3)) | 642 | if (tonumber(top-3)) |
624 | lua_error(L, "`for' initial value must be a number"); | 643 | lua_error(L, "`for' initial value must be a number"); |
625 | /* number of steps */ | 644 | if (nvalue(top-1) > 0 ? |
626 | nvalue(top-2) = (nvalue(top-2)-nvalue(top-3))/nvalue(top-1); | 645 | nvalue(top-3) > nvalue(top-2) : |
627 | nvalue(top-3) -= nvalue(top-1); /* to be undone by first FORLOOP */ | 646 | nvalue(top-3) < nvalue(top-2)) { /* `empty' loop? */ |
628 | pc += GETARG_S(i); | 647 | top -= 3; /* remove control variables */ |
648 | pc += GETARG_S(i)+1; /* jump to loop end */ | ||
649 | } | ||
629 | break; | 650 | break; |
630 | 651 | ||
631 | case OP_FORLOOP: { | 652 | case OP_FORLOOP: { |
632 | LUA_ASSERT(L, ttype(top-1) == TAG_NUMBER, "invalid step"); | 653 | LUA_ASSERT(L, ttype(top-1) == TAG_NUMBER, "invalid step"); |
633 | LUA_ASSERT(L, ttype(top-2) == TAG_NUMBER, "invalid count"); | 654 | LUA_ASSERT(L, ttype(top-2) == TAG_NUMBER, "invalid limit"); |
634 | if (nvalue(top-2) < 0) | 655 | if (ttype(top-3) != TAG_NUMBER) |
656 | lua_error(L, "`for' index must be a number"); | ||
657 | nvalue(top-3) += nvalue(top-1); /* increment index */ | ||
658 | if (nvalue(top-1) > 0 ? | ||
659 | nvalue(top-3) > nvalue(top-2) : | ||
660 | nvalue(top-3) < nvalue(top-2)) | ||
635 | top -= 3; /* end loop: remove control variables */ | 661 | top -= 3; /* end loop: remove control variables */ |
636 | else { | 662 | else |
637 | nvalue(top-2)--; /* decrement count */ | 663 | pc += GETARG_S(i); /* repeat loop */ |
638 | if (ttype(top-3) != TAG_NUMBER) | ||
639 | lua_error(L, "`for' index must be a number"); | ||
640 | nvalue(top-3) += nvalue(top-1); /* increment index */ | ||
641 | pc += GETARG_S(i); | ||
642 | } | ||
643 | break; | 664 | break; |
644 | } | 665 | } |
645 | 666 | ||
646 | case OP_LFORPREP: { | 667 | case OP_LFORPREP: { |
647 | if (ttype(top-1) != TAG_TABLE) | 668 | if (ttype(top-1) != TAG_TABLE) |
648 | lua_error(L, "`for' table must be a table"); | 669 | lua_error(L, "`for' table must be a table"); |
649 | top += 3; /* counter + index,value */ | 670 | top++; /* counter */ |
650 | ttype(top-3) = TAG_NUMBER; | 671 | L->top = top; |
651 | nvalue(top-3) = 0.0; /* counter */ | 672 | ttype(top-1) = TAG_NUMBER; |
652 | ttype(top-2) = ttype(top-1) = TAG_NIL; | 673 | nvalue(top-1) = (Number)luaA_next(L, hvalue(top-2), 0); /* counter */ |
653 | pc += GETARG_S(i); | 674 | if (nvalue(top-1) == 0) { /* `empty' loop? */ |
675 | top -= 2; /* remove table and counter */ | ||
676 | pc += GETARG_S(i)+1; /* jump to loop end */ | ||
677 | } | ||
678 | else { | ||
679 | top += 2; /* index,value */ | ||
680 | LUA_ASSERT(L, top==L->top, "bad top"); | ||
681 | } | ||
654 | break; | 682 | break; |
655 | } | 683 | } |
656 | 684 | ||
@@ -678,22 +706,6 @@ StkId luaV_execute (lua_State *L, const Closure *cl, StkId base) { | |||
678 | luaC_checkGC(L); | 706 | luaC_checkGC(L); |
679 | break; | 707 | break; |
680 | 708 | ||
681 | case OP_SETLINE: | ||
682 | if ((base-1)->ttype != TAG_LINE) { | ||
683 | /* open space for LINE value */ | ||
684 | int n = top-base; | ||
685 | while (n--) base[n+1] = base[n]; | ||
686 | base++; | ||
687 | top++; | ||
688 | (base-1)->ttype = TAG_LINE; | ||
689 | } | ||
690 | (base-1)->value.i = GETARG_U(i); | ||
691 | if (L->linehook) { | ||
692 | L->top = top; | ||
693 | luaD_lineHook(L, base-2, GETARG_U(i)); | ||
694 | } | ||
695 | break; | ||
696 | |||
697 | } | 709 | } |
698 | } | 710 | } |
699 | } | 711 | } |