summaryrefslogtreecommitdiff
path: root/apps/plugins/lua/ldebug.c
diff options
context:
space:
mode:
authorRichard Quirk <richard.quirk@gmail.com>2014-03-19 19:31:31 +0100
committerMarcin Bukat <marcin.bukat@gmail.com>2014-04-02 20:31:54 +0200
commit36378988ad4059982742f05f5eb50580b456840a (patch)
treeee70be810d894566c5e351f21a1ebb79be742a85 /apps/plugins/lua/ldebug.c
parent020f16a1c7d5bc9a302671cef03f56ac735e20c5 (diff)
downloadrockbox-36378988ad4059982742f05f5eb50580b456840a.tar.gz
rockbox-36378988ad4059982742f05f5eb50580b456840a.zip
Update lua plugin to 5.2.3
Prior to this patch the Lua plugin used version 5.1.4. This change reduces the number of modifications in the Lua source using some new defines and because the upstream source is now more flexible. Unless otherwise stated, l*.[ch] files are taken unmodified from the upstream lua-5.2.3. fscanf.c: file descriptors in rockbox are just ints, they are hidden behind a void* now so liolib requires less modifications. fscanf is updated to use void* too. getc.c: this is a new file required for getc implementation in lauxlib.c lauxlib.c: LoadF replaced FILE* with int, the rockbox file descriptor int are cast to FILE* (actually void* due to typedef). getc uses the PREFIX version. stdin is not used, as per 5.1.4. lbaselib.c: now uses strspn in the number parsing. print uses DEBUGF now rather than being commented out. lbitlib.c: use the built-in version from 5.2.3 rather than Reuben Thomas's external library. Backwards compatible and adds some new bit operations. ldo.c: the LUAI_THROW/TRY defines are now in the core lua code, so have been removed from rockconf.h liolib.c: here the implementation has changed to use the LStream from the original source, and cast the FILE* pointers to int. This has reduced the number of modifications from the upstream version. llex.c: the only change from upstream is to remove the locale include. lmathlib.c: updated from the 5.2.3 version and re-applied the changes that were made vs 5.1.4 for random numbers and to remove unsupported float functions. loadlib.c: upstream version, with the 5.1.4 changes for missing functions. lobject.c: upstream version, with ctype.h added and sprintf changed to snprintf. loslib.c: upstream version with locale.h removed and 5.1.4 changes for unsupportable functions. lstrlib.c: sprintf changed to snprintf. ltable.c: upstream with the hashnum function from 5.1.4 to avoid frexp in luai_hashnum. luaconf.h: updated to 5.2.3 version, restored relevant parts from the original 5.1.4 configuration. The COMPAT defines that are no longer available are not included. lundump.c: VERSION macro conflicts with the core Rockbox equivalent. rocklib.c: luaL_reg is no longer available, replaced by luaL_Reg equivalent. Moved checkboolean/optboolean functions to this file and out of core lua files. luaL_getn is no longer available, replaced by luaL_rawlen. luaL_register is deprecated, use the newlib/setfuncs replacements. rli_init has to be called before setting up the newlib to avoid overwriting the rb table. rocklib_aux.pl: use rli_checkboolean from rocklib.c. rocklua.c: new default bits library used, update the library loading code with idiomatic 5.2 code. strcspn.c: no longer needed, but strspn.c is required for strspn in lbaselib.c Change-Id: I0c7945c755f79083afe98ec117e1e8cf13de2651 Reviewed-on: http://gerrit.rockbox.org/774 Tested: Richard Quirk <richard.quirk@gmail.com> Reviewed-by: Marcin Bukat <marcin.bukat@gmail.com>
Diffstat (limited to 'apps/plugins/lua/ldebug.c')
-rw-r--r--apps/plugins/lua/ldebug.c625
1 files changed, 290 insertions, 335 deletions
diff --git a/apps/plugins/lua/ldebug.c b/apps/plugins/lua/ldebug.c
index 50ad3d3803..20d663efff 100644
--- a/apps/plugins/lua/ldebug.c
+++ b/apps/plugins/lua/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 2.29.1.6 2008/05/08 16:56:26 roberto Exp $ 2** $Id: ldebug.c,v 2.90.1.3 2013/05/16 16:04:15 roberto Exp $
3** Debug Interface 3** Debug Interface
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -30,23 +30,20 @@
30 30
31 31
32 32
33#define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_TCCL)
34
35
33static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name); 36static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
34 37
35 38
36static int currentpc (lua_State *L, CallInfo *ci) { 39static int currentpc (CallInfo *ci) {
37 if (!isLua(ci)) return -1; /* function is not a Lua function? */ 40 lua_assert(isLua(ci));
38 if (ci == L->ci) 41 return pcRel(ci->u.l.savedpc, ci_func(ci)->p);
39 ci->savedpc = L->savedpc;
40 return pcRel(ci->savedpc, ci_func(ci)->l.p);
41} 42}
42 43
43 44
44static int currentline (lua_State *L, CallInfo *ci) { 45static int currentline (CallInfo *ci) {
45 int pc = currentpc(L, ci); 46 return getfuncline(ci_func(ci)->p, currentpc(ci));
46 if (pc < 0)
47 return -1; /* only active lua functions have current-line information */
48 else
49 return getline(ci_func(ci)->l.p, pc);
50} 47}
51 48
52 49
@@ -58,6 +55,8 @@ LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
58 mask = 0; 55 mask = 0;
59 func = NULL; 56 func = NULL;
60 } 57 }
58 if (isLua(L->ci))
59 L->oldpc = L->ci->u.l.savedpc;
61 L->hook = func; 60 L->hook = func;
62 L->basehookcount = count; 61 L->basehookcount = count;
63 resethookcount(L); 62 resethookcount(L);
@@ -84,19 +83,13 @@ LUA_API int lua_gethookcount (lua_State *L) {
84LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { 83LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
85 int status; 84 int status;
86 CallInfo *ci; 85 CallInfo *ci;
86 if (level < 0) return 0; /* invalid (negative) level */
87 lua_lock(L); 87 lua_lock(L);
88 for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) { 88 for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous)
89 level--; 89 level--;
90 if (f_isLua(ci)) /* Lua function? */ 90 if (level == 0 && ci != &L->base_ci) { /* level found? */
91 level -= ci->tailcalls; /* skip lost tail calls */
92 }
93 if (level == 0 && ci > L->base_ci) { /* level found? */
94 status = 1; 91 status = 1;
95 ar->i_ci = cast_int(ci - L->base_ci); 92 ar->i_ci = ci;
96 }
97 else if (level < 0) { /* level is of a lost tail call? */
98 status = 1;
99 ar->i_ci = 0;
100 } 93 }
101 else status = 0; /* no such level */ 94 else status = 0; /* no such level */
102 lua_unlock(L); 95 lua_unlock(L);
@@ -104,43 +97,78 @@ LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
104} 97}
105 98
106 99
107static Proto *getluaproto (CallInfo *ci) { 100static const char *upvalname (Proto *p, int uv) {
108 return (isLua(ci) ? ci_func(ci)->l.p : NULL); 101 TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name);
102 if (s == NULL) return "?";
103 else return getstr(s);
109} 104}
110 105
111 106
112static const char *findlocal (lua_State *L, CallInfo *ci, int n) { 107static const char *findvararg (CallInfo *ci, int n, StkId *pos) {
113 const char *name; 108 int nparams = clLvalue(ci->func)->p->numparams;
114 Proto *fp = getluaproto(ci); 109 if (n >= ci->u.l.base - ci->func - nparams)
115 if (fp && (name = luaF_getlocalname(fp, n, currentpc(L, ci))) != NULL) 110 return NULL; /* no such vararg */
116 return name; /* is a local variable in a Lua function */
117 else { 111 else {
118 StkId limit = (ci == L->ci) ? L->top : (ci+1)->func; 112 *pos = ci->func + nparams + n;
119 if (limit - ci->base >= n && n > 0) /* is 'n' inside 'ci' stack? */ 113 return "(*vararg)"; /* generic name for any vararg */
120 return "(*temporary)"; 114 }
115}
116
117
118static const char *findlocal (lua_State *L, CallInfo *ci, int n,
119 StkId *pos) {
120 const char *name = NULL;
121 StkId base;
122 if (isLua(ci)) {
123 if (n < 0) /* access to vararg values? */
124 return findvararg(ci, -n, pos);
125 else {
126 base = ci->u.l.base;
127 name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci));
128 }
129 }
130 else
131 base = ci->func + 1;
132 if (name == NULL) { /* no 'standard' name? */
133 StkId limit = (ci == L->ci) ? L->top : ci->next->func;
134 if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */
135 name = "(*temporary)"; /* generic name for any valid slot */
121 else 136 else
122 return NULL; 137 return NULL; /* no name */
123 } 138 }
139 *pos = base + (n - 1);
140 return name;
124} 141}
125 142
126 143
127LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { 144LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
128 CallInfo *ci = L->base_ci + ar->i_ci; 145 const char *name;
129 const char *name = findlocal(L, ci, n);
130 lua_lock(L); 146 lua_lock(L);
131 if (name) 147 if (ar == NULL) { /* information about non-active function? */
132 luaA_pushobject(L, ci->base + (n - 1)); 148 if (!isLfunction(L->top - 1)) /* not a Lua function? */
149 name = NULL;
150 else /* consider live variables at function start (parameters) */
151 name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0);
152 }
153 else { /* active function; get information through 'ar' */
154 StkId pos = 0; /* to avoid warnings */
155 name = findlocal(L, ar->i_ci, n, &pos);
156 if (name) {
157 setobj2s(L, L->top, pos);
158 api_incr_top(L);
159 }
160 }
133 lua_unlock(L); 161 lua_unlock(L);
134 return name; 162 return name;
135} 163}
136 164
137 165
138LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { 166LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
139 CallInfo *ci = L->base_ci + ar->i_ci; 167 StkId pos = 0; /* to avoid warnings */
140 const char *name = findlocal(L, ci, n); 168 const char *name = findlocal(L, ar->i_ci, n, &pos);
141 lua_lock(L); 169 lua_lock(L);
142 if (name) 170 if (name)
143 setobjs2s(L, ci->base + (n - 1), L->top - 1); 171 setobjs2s(L, pos, L->top - 1);
144 L->top--; /* pop value */ 172 L->top--; /* pop value */
145 lua_unlock(L); 173 lua_unlock(L);
146 return name; 174 return name;
@@ -148,55 +176,45 @@ LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
148 176
149 177
150static void funcinfo (lua_Debug *ar, Closure *cl) { 178static void funcinfo (lua_Debug *ar, Closure *cl) {
151 if (cl->c.isC) { 179 if (noLuaClosure(cl)) {
152 ar->source = "=[C]"; 180 ar->source = "=[C]";
153 ar->linedefined = -1; 181 ar->linedefined = -1;
154 ar->lastlinedefined = -1; 182 ar->lastlinedefined = -1;
155 ar->what = "C"; 183 ar->what = "C";
156 } 184 }
157 else { 185 else {
158 ar->source = getstr(cl->l.p->source); 186 Proto *p = cl->l.p;
159 ar->linedefined = cl->l.p->linedefined; 187 ar->source = p->source ? getstr(p->source) : "=?";
160 ar->lastlinedefined = cl->l.p->lastlinedefined; 188 ar->linedefined = p->linedefined;
189 ar->lastlinedefined = p->lastlinedefined;
161 ar->what = (ar->linedefined == 0) ? "main" : "Lua"; 190 ar->what = (ar->linedefined == 0) ? "main" : "Lua";
162 } 191 }
163 luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); 192 luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
164} 193}
165 194
166 195
167static void info_tailcall (lua_Debug *ar) {
168 ar->name = ar->namewhat = "";
169 ar->what = "tail";
170 ar->lastlinedefined = ar->linedefined = ar->currentline = -1;
171 ar->source = "=(tail call)";
172 luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
173 ar->nups = 0;
174}
175
176
177static void collectvalidlines (lua_State *L, Closure *f) { 196static void collectvalidlines (lua_State *L, Closure *f) {
178 if (f == NULL || f->c.isC) { 197 if (noLuaClosure(f)) {
179 setnilvalue(L->top); 198 setnilvalue(L->top);
199 api_incr_top(L);
180 } 200 }
181 else { 201 else {
182 Table *t = luaH_new(L, 0, 0);
183 int *lineinfo = f->l.p->lineinfo;
184 int i; 202 int i;
185 for (i=0; i<f->l.p->sizelineinfo; i++) 203 TValue v;
186 setbvalue(luaH_setnum(L, t, lineinfo[i]), 1); 204 int *lineinfo = f->l.p->lineinfo;
187 sethvalue(L, L->top, t); 205 Table *t = luaH_new(L); /* new table to store active lines */
206 sethvalue(L, L->top, t); /* push it on stack */
207 api_incr_top(L);
208 setbvalue(&v, 1); /* boolean 'true' to be the value of all indices */
209 for (i = 0; i < f->l.p->sizelineinfo; i++) /* for all lines with code */
210 luaH_setint(L, t, lineinfo[i], &v); /* table[line] = true */
188 } 211 }
189 incr_top(L);
190} 212}
191 213
192 214
193static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, 215static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
194 Closure *f, CallInfo *ci) { 216 Closure *f, CallInfo *ci) {
195 int status = 1; 217 int status = 1;
196 if (f == NULL) {
197 info_tailcall(ar);
198 return status;
199 }
200 for (; *what; what++) { 218 for (; *what; what++) {
201 switch (*what) { 219 switch (*what) {
202 case 'S': { 220 case 'S': {
@@ -204,15 +222,31 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
204 break; 222 break;
205 } 223 }
206 case 'l': { 224 case 'l': {
207 ar->currentline = (ci) ? currentline(L, ci) : -1; 225 ar->currentline = (ci && isLua(ci)) ? currentline(ci) : -1;
208 break; 226 break;
209 } 227 }
210 case 'u': { 228 case 'u': {
211 ar->nups = f->c.nupvalues; 229 ar->nups = (f == NULL) ? 0 : f->c.nupvalues;
230 if (noLuaClosure(f)) {
231 ar->isvararg = 1;
232 ar->nparams = 0;
233 }
234 else {
235 ar->isvararg = f->l.p->is_vararg;
236 ar->nparams = f->l.p->numparams;
237 }
238 break;
239 }
240 case 't': {
241 ar->istailcall = (ci) ? ci->callstatus & CIST_TAIL : 0;
212 break; 242 break;
213 } 243 }
214 case 'n': { 244 case 'n': {
215 ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL; 245 /* calling function is a known Lua function? */
246 if (ci && !(ci->callstatus & CIST_TAIL) && isLua(ci->previous))
247 ar->namewhat = getfuncname(L, ci->previous, &ar->name);
248 else
249 ar->namewhat = NULL;
216 if (ar->namewhat == NULL) { 250 if (ar->namewhat == NULL) {
217 ar->namewhat = ""; /* not found */ 251 ar->namewhat = ""; /* not found */
218 ar->name = NULL; 252 ar->name = NULL;
@@ -231,29 +265,30 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
231 265
232LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { 266LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
233 int status; 267 int status;
234 Closure *f = NULL; 268 Closure *cl;
235 CallInfo *ci = NULL; 269 CallInfo *ci;
270 StkId func;
236 lua_lock(L); 271 lua_lock(L);
237 if (*what == '>') { 272 if (*what == '>') {
238 StkId func = L->top - 1; 273 ci = NULL;
239 luai_apicheck(L, ttisfunction(func)); 274 func = L->top - 1;
275 api_check(L, ttisfunction(func), "function expected");
240 what++; /* skip the '>' */ 276 what++; /* skip the '>' */
241 f = clvalue(func);
242 L->top--; /* pop function */ 277 L->top--; /* pop function */
243 } 278 }
244 else if (ar->i_ci != 0) { /* no tail call? */ 279 else {
245 ci = L->base_ci + ar->i_ci; 280 ci = ar->i_ci;
281 func = ci->func;
246 lua_assert(ttisfunction(ci->func)); 282 lua_assert(ttisfunction(ci->func));
247 f = clvalue(ci->func);
248 } 283 }
249 status = auxgetinfo(L, what, ar, f, ci); 284 cl = ttisclosure(func) ? clvalue(func) : NULL;
285 status = auxgetinfo(L, what, ar, cl, ci);
250 if (strchr(what, 'f')) { 286 if (strchr(what, 'f')) {
251 if (f == NULL) setnilvalue(L->top); 287 setobjs2s(L, L->top, func);
252 else setclvalue(L, L->top, f); 288 api_incr_top(L);
253 incr_top(L);
254 } 289 }
255 if (strchr(what, 'L')) 290 if (strchr(what, 'L'))
256 collectvalidlines(L, f); 291 collectvalidlines(L, cl);
257 lua_unlock(L); 292 lua_unlock(L);
258 return status; 293 return status;
259} 294}
@@ -261,315 +296,231 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
261 296
262/* 297/*
263** {====================================================== 298** {======================================================
264** Symbolic Execution and code checker 299** Symbolic Execution
265** ======================================================= 300** =======================================================
266*/ 301*/
267 302
268#define check(x) if (!(x)) return 0; 303static const char *getobjname (Proto *p, int lastpc, int reg,
304 const char **name);
269 305
270#define checkjump(pt,pc) check(0 <= pc && pc < pt->sizecode)
271 306
272#define checkreg(pt,reg) check((reg) < (pt)->maxstacksize) 307/*
273 308** find a "name" for the RK value 'c'
274 309*/
275 310static void kname (Proto *p, int pc, int c, const char **name) {
276static int precheck (const Proto *pt) { 311 if (ISK(c)) { /* is 'c' a constant? */
277 check(pt->maxstacksize <= MAXSTACK); 312 TValue *kvalue = &p->k[INDEXK(c)];
278 check(pt->numparams+(pt->is_vararg & VARARG_HASARG) <= pt->maxstacksize); 313 if (ttisstring(kvalue)) { /* literal constant? */
279 check(!(pt->is_vararg & VARARG_NEEDSARG) || 314 *name = svalue(kvalue); /* it is its own name */
280 (pt->is_vararg & VARARG_HASARG)); 315 return;
281 check(pt->sizeupvalues <= pt->nups); 316 }
282 check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0); 317 /* else no reasonable name found */
283 check(pt->sizecode > 0 && GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN); 318 }
284 return 1; 319 else { /* 'c' is a register */
285} 320 const char *what = getobjname(p, pc, c, name); /* search for 'c' */
286 321 if (what && *what == 'c') { /* found a constant name? */
287 322 return; /* 'name' already filled */
288#define checkopenop(pt,pc) luaG_checkopenop((pt)->code[(pc)+1])
289
290int luaG_checkopenop (Instruction i) {
291 switch (GET_OPCODE(i)) {
292 case OP_CALL:
293 case OP_TAILCALL:
294 case OP_RETURN:
295 case OP_SETLIST: {
296 check(GETARG_B(i) == 0);
297 return 1;
298 } 323 }
299 default: return 0; /* invalid instruction after an open call */ 324 /* else no reasonable name found */
300 } 325 }
326 *name = "?"; /* no reasonable name found */
301} 327}
302 328
303 329
304static int checkArgMode (const Proto *pt, int r, enum OpArgMask mode) { 330static int filterpc (int pc, int jmptarget) {
305 switch (mode) { 331 if (pc < jmptarget) /* is code conditional (inside a jump)? */
306 case OpArgN: check(r == 0); break; 332 return -1; /* cannot know who sets that register */
307 case OpArgU: break; 333 else return pc; /* current position sets that register */
308 case OpArgR: checkreg(pt, r); break;
309 case OpArgK:
310 check(ISK(r) ? INDEXK(r) < pt->sizek : r < pt->maxstacksize);
311 break;
312 }
313 return 1;
314} 334}
315 335
316 336
317static Instruction symbexec (const Proto *pt, int lastpc, int reg) { 337/*
338** try to find last instruction before 'lastpc' that modified register 'reg'
339*/
340static int findsetreg (Proto *p, int lastpc, int reg) {
318 int pc; 341 int pc;
319 int last; /* stores position of last instruction that changed `reg' */ 342 int setreg = -1; /* keep last instruction that changed 'reg' */
320 last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */ 343 int jmptarget = 0; /* any code before this address is conditional */
321 check(precheck(pt));
322 for (pc = 0; pc < lastpc; pc++) { 344 for (pc = 0; pc < lastpc; pc++) {
323 Instruction i = pt->code[pc]; 345 Instruction i = p->code[pc];
324 OpCode op = GET_OPCODE(i); 346 OpCode op = GET_OPCODE(i);
325 int a = GETARG_A(i); 347 int a = GETARG_A(i);
326 int b = 0;
327 int c = 0;
328 check(op < NUM_OPCODES);
329 checkreg(pt, a);
330 switch (getOpMode(op)) {
331 case iABC: {
332 b = GETARG_B(i);
333 c = GETARG_C(i);
334 check(checkArgMode(pt, b, getBMode(op)));
335 check(checkArgMode(pt, c, getCMode(op)));
336 break;
337 }
338 case iABx: {
339 b = GETARG_Bx(i);
340 if (getBMode(op) == OpArgK) check(b < pt->sizek);
341 break;
342 }
343 case iAsBx: {
344 b = GETARG_sBx(i);
345 if (getBMode(op) == OpArgR) {
346 int dest = pc+1+b;
347 check(0 <= dest && dest < pt->sizecode);
348 if (dest > 0) {
349 int j;
350 /* check that it does not jump to a setlist count; this
351 is tricky, because the count from a previous setlist may
352 have the same value of an invalid setlist; so, we must
353 go all the way back to the first of them (if any) */
354 for (j = 0; j < dest; j++) {
355 Instruction d = pt->code[dest-1-j];
356 if (!(GET_OPCODE(d) == OP_SETLIST && GETARG_C(d) == 0)) break;
357 }
358 /* if 'j' is even, previous value is not a setlist (even if
359 it looks like one) */
360 check((j&1) == 0);
361 }
362 }
363 break;
364 }
365 }
366 if (testAMode(op)) {
367 if (a == reg) last = pc; /* change register `a' */
368 }
369 if (testTMode(op)) {
370 check(pc+2 < pt->sizecode); /* check skip */
371 check(GET_OPCODE(pt->code[pc+1]) == OP_JMP);
372 }
373 switch (op) { 348 switch (op) {
374 case OP_LOADBOOL: {
375 if (c == 1) { /* does it jump? */
376 check(pc+2 < pt->sizecode); /* check its jump */
377 check(GET_OPCODE(pt->code[pc+1]) != OP_SETLIST ||
378 GETARG_C(pt->code[pc+1]) != 0);
379 }
380 break;
381 }
382 case OP_LOADNIL: { 349 case OP_LOADNIL: {
383 if (a <= reg && reg <= b) 350 int b = GETARG_B(i);
384 last = pc; /* set registers from `a' to `b' */ 351 if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */
385 break; 352 setreg = filterpc(pc, jmptarget);
386 }
387 case OP_GETUPVAL:
388 case OP_SETUPVAL: {
389 check(b < pt->nups);
390 break;
391 }
392 case OP_GETGLOBAL:
393 case OP_SETGLOBAL: {
394 check(ttisstring(&pt->k[b]));
395 break;
396 }
397 case OP_SELF: {
398 checkreg(pt, a+1);
399 if (reg == a+1) last = pc;
400 break;
401 }
402 case OP_CONCAT: {
403 check(b < c); /* at least two operands */
404 break;
405 }
406 case OP_TFORLOOP: {
407 check(c >= 1); /* at least one result (control variable) */
408 checkreg(pt, a+2+c); /* space for results */
409 if (reg >= a+2) last = pc; /* affect all regs above its base */
410 break; 353 break;
411 } 354 }
412 case OP_FORLOOP: 355 case OP_TFORCALL: {
413 case OP_FORPREP: 356 if (reg >= a + 2) /* affect all regs above its base */
414 checkreg(pt, a+3); 357 setreg = filterpc(pc, jmptarget);
415 /* go through */
416 case OP_JMP: {
417 int dest = pc+1+b;
418 /* not full check and jump is forward and do not skip `lastpc'? */
419 if (reg != NO_REG && pc < dest && dest <= lastpc)
420 pc += b; /* do the jump */
421 break; 358 break;
422 } 359 }
423 case OP_CALL: 360 case OP_CALL:
424 case OP_TAILCALL: { 361 case OP_TAILCALL: {
425 if (b != 0) { 362 if (reg >= a) /* affect all registers above base */
426 checkreg(pt, a+b-1); 363 setreg = filterpc(pc, jmptarget);
427 }
428 c--; /* c = num. returns */
429 if (c == LUA_MULTRET) {
430 check(checkopenop(pt, pc));
431 }
432 else if (c != 0)
433 checkreg(pt, a+c-1);
434 if (reg >= a) last = pc; /* affect all registers above base */
435 break; 364 break;
436 } 365 }
437 case OP_RETURN: { 366 case OP_JMP: {
438 b--; /* b = num. returns */ 367 int b = GETARG_sBx(i);
439 if (b > 0) checkreg(pt, a+b-1); 368 int dest = pc + 1 + b;
440 break; 369 /* jump is forward and do not skip `lastpc'? */
441 } 370 if (pc < dest && dest <= lastpc) {
442 case OP_SETLIST: { 371 if (dest > jmptarget)
443 if (b > 0) checkreg(pt, a + b); 372 jmptarget = dest; /* update 'jmptarget' */
444 if (c == 0) {
445 pc++;
446 check(pc < pt->sizecode - 1);
447 } 373 }
448 break; 374 break;
449 } 375 }
450 case OP_CLOSURE: { 376 case OP_TEST: {
451 int nup, j; 377 if (reg == a) /* jumped code can change 'a' */
452 check(b < pt->sizep); 378 setreg = filterpc(pc, jmptarget);
453 nup = pt->p[b]->nups;
454 check(pc + nup < pt->sizecode);
455 for (j = 1; j <= nup; j++) {
456 OpCode op1 = GET_OPCODE(pt->code[pc + j]);
457 check(op1 == OP_GETUPVAL || op1 == OP_MOVE);
458 }
459 if (reg != NO_REG) /* tracing? */
460 pc += nup; /* do not 'execute' these pseudo-instructions */
461 break; 379 break;
462 } 380 }
463 case OP_VARARG: { 381 default:
464 check((pt->is_vararg & VARARG_ISVARARG) && 382 if (testAMode(op) && reg == a) /* any instruction that set A */
465 !(pt->is_vararg & VARARG_NEEDSARG)); 383 setreg = filterpc(pc, jmptarget);
466 b--;
467 if (b == LUA_MULTRET) check(checkopenop(pt, pc));
468 checkreg(pt, a+b-1);
469 break; 384 break;
470 }
471 default: break;
472 } 385 }
473 } 386 }
474 return pt->code[last]; 387 return setreg;
475}
476
477#undef check
478#undef checkjump
479#undef checkreg
480
481/* }====================================================== */
482
483
484int luaG_checkcode (const Proto *pt) {
485 return (symbexec(pt, pt->sizecode, NO_REG) != 0);
486} 388}
487 389
488 390
489static const char *kname (Proto *p, int c) { 391static const char *getobjname (Proto *p, int lastpc, int reg,
490 if (ISK(c) && ttisstring(&p->k[INDEXK(c)]))
491 return svalue(&p->k[INDEXK(c)]);
492 else
493 return "?";
494}
495
496
497static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos,
498 const char **name) { 392 const char **name) {
499 if (isLua(ci)) { /* a Lua function? */ 393 int pc;
500 Proto *p = ci_func(ci)->l.p; 394 *name = luaF_getlocalname(p, reg + 1, lastpc);
501 int pc = currentpc(L, ci); 395 if (*name) /* is a local? */
502 Instruction i; 396 return "local";
503 *name = luaF_getlocalname(p, stackpos+1, pc); 397 /* else try symbolic execution */
504 if (*name) /* is a local? */ 398 pc = findsetreg(p, lastpc, reg);
505 return "local"; 399 if (pc != -1) { /* could find instruction? */
506 i = symbexec(p, pc, stackpos); /* try symbolic execution */ 400 Instruction i = p->code[pc];
507 lua_assert(pc != -1); 401 OpCode op = GET_OPCODE(i);
508 switch (GET_OPCODE(i)) { 402 switch (op) {
509 case OP_GETGLOBAL: {
510 int g = GETARG_Bx(i); /* global index */
511 lua_assert(ttisstring(&p->k[g]));
512 *name = svalue(&p->k[g]);
513 return "global";
514 }
515 case OP_MOVE: { 403 case OP_MOVE: {
516 int a = GETARG_A(i); 404 int b = GETARG_B(i); /* move from 'b' to 'a' */
517 int b = GETARG_B(i); /* move from `b' to `a' */ 405 if (b < GETARG_A(i))
518 if (b < a) 406 return getobjname(p, pc, b, name); /* get name for 'b' */
519 return getobjname(L, ci, b, name); /* get name for `b' */
520 break; 407 break;
521 } 408 }
409 case OP_GETTABUP:
522 case OP_GETTABLE: { 410 case OP_GETTABLE: {
523 int k = GETARG_C(i); /* key index */ 411 int k = GETARG_C(i); /* key index */
524 *name = kname(p, k); 412 int t = GETARG_B(i); /* table index */
525 return "field"; 413 const char *vn = (op == OP_GETTABLE) /* name of indexed variable */
414 ? luaF_getlocalname(p, t + 1, pc)
415 : upvalname(p, t);
416 kname(p, pc, k, name);
417 return (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field";
526 } 418 }
527 case OP_GETUPVAL: { 419 case OP_GETUPVAL: {
528 int u = GETARG_B(i); /* upvalue index */ 420 *name = upvalname(p, GETARG_B(i));
529 *name = p->upvalues ? getstr(p->upvalues[u]) : "?";
530 return "upvalue"; 421 return "upvalue";
531 } 422 }
423 case OP_LOADK:
424 case OP_LOADKX: {
425 int b = (op == OP_LOADK) ? GETARG_Bx(i)
426 : GETARG_Ax(p->code[pc + 1]);
427 if (ttisstring(&p->k[b])) {
428 *name = svalue(&p->k[b]);
429 return "constant";
430 }
431 break;
432 }
532 case OP_SELF: { 433 case OP_SELF: {
533 int k = GETARG_C(i); /* key index */ 434 int k = GETARG_C(i); /* key index */
534 *name = kname(p, k); 435 kname(p, pc, k, name);
535 return "method"; 436 return "method";
536 } 437 }
537 default: break; 438 default: break; /* go through to return NULL */
538 } 439 }
539 } 440 }
540 return NULL; /* no useful name found */ 441 return NULL; /* could not find reasonable name */
541} 442}
542 443
543 444
544static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { 445static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
545 Instruction i; 446 TMS tm;
546 if ((isLua(ci) && ci->tailcalls > 0) || !isLua(ci - 1)) 447 Proto *p = ci_func(ci)->p; /* calling function */
547 return NULL; /* calling function is not Lua (or is unknown) */ 448 int pc = currentpc(ci); /* calling instruction index */
548 ci--; /* calling function */ 449 Instruction i = p->code[pc]; /* calling instruction */
549 i = ci_func(ci)->l.p->code[currentpc(L, ci)]; 450 switch (GET_OPCODE(i)) {
550 if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL || 451 case OP_CALL:
551 GET_OPCODE(i) == OP_TFORLOOP) 452 case OP_TAILCALL: /* get function name */
552 return getobjname(L, ci, GETARG_A(i), name); 453 return getobjname(p, pc, GETARG_A(i), name);
553 else 454 case OP_TFORCALL: { /* for iterator */
554 return NULL; /* no useful name can be found */ 455 *name = "for iterator";
456 return "for iterator";
457 }
458 /* all other instructions can call only through metamethods */
459 case OP_SELF:
460 case OP_GETTABUP:
461 case OP_GETTABLE: tm = TM_INDEX; break;
462 case OP_SETTABUP:
463 case OP_SETTABLE: tm = TM_NEWINDEX; break;
464 case OP_EQ: tm = TM_EQ; break;
465 case OP_ADD: tm = TM_ADD; break;
466 case OP_SUB: tm = TM_SUB; break;
467 case OP_MUL: tm = TM_MUL; break;
468 case OP_DIV: tm = TM_DIV; break;
469 case OP_MOD: tm = TM_MOD; break;
470 case OP_POW: tm = TM_POW; break;
471 case OP_UNM: tm = TM_UNM; break;
472 case OP_LEN: tm = TM_LEN; break;
473 case OP_LT: tm = TM_LT; break;
474 case OP_LE: tm = TM_LE; break;
475 case OP_CONCAT: tm = TM_CONCAT; break;
476 default:
477 return NULL; /* else no useful name can be found */
478 }
479 *name = getstr(G(L)->tmname[tm]);
480 return "metamethod";
555} 481}
556 482
483/* }====================================================== */
484
485
557 486
558/* only ANSI way to check whether a pointer points to an array */ 487/*
488** only ANSI way to check whether a pointer points to an array
489** (used only for error messages, so efficiency is not a big concern)
490*/
559static int isinstack (CallInfo *ci, const TValue *o) { 491static int isinstack (CallInfo *ci, const TValue *o) {
560 StkId p; 492 StkId p;
561 for (p = ci->base; p < ci->top; p++) 493 for (p = ci->u.l.base; p < ci->top; p++)
562 if (o == p) return 1; 494 if (o == p) return 1;
563 return 0; 495 return 0;
564} 496}
565 497
566 498
567void luaG_typeerror (lua_State *L, const TValue *o, const char *op) { 499static const char *getupvalname (CallInfo *ci, const TValue *o,
500 const char **name) {
501 LClosure *c = ci_func(ci);
502 int i;
503 for (i = 0; i < c->nupvalues; i++) {
504 if (c->upvals[i]->v == o) {
505 *name = upvalname(c->p, i);
506 return "upvalue";
507 }
508 }
509 return NULL;
510}
511
512
513l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
514 CallInfo *ci = L->ci;
568 const char *name = NULL; 515 const char *name = NULL;
569 const char *t = luaT_typenames[ttype(o)]; 516 const char *t = objtypename(o);
570 const char *kind = (isinstack(L->ci, o)) ? 517 const char *kind = NULL;
571 getobjname(L, L->ci, cast_int(o - L->base), &name) : 518 if (isLua(ci)) {
572 NULL; 519 kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */
520 if (!kind && isinstack(ci, o)) /* no? try a register */
521 kind = getobjname(ci_func(ci)->p, currentpc(ci),
522 cast_int(o - ci->u.l.base), &name);
523 }
573 if (kind) 524 if (kind)
574 luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)", 525 luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)",
575 op, kind, name, t); 526 op, kind, name, t);
@@ -578,14 +529,14 @@ void luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
578} 529}
579 530
580 531
581void luaG_concaterror (lua_State *L, StkId p1, StkId p2) { 532l_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
582 if (ttisstring(p1) || ttisnumber(p1)) p1 = p2; 533 if (ttisstring(p1) || ttisnumber(p1)) p1 = p2;
583 lua_assert(!ttisstring(p1) && !ttisnumber(p1)); 534 lua_assert(!ttisstring(p1) && !ttisnumber(p1));
584 luaG_typeerror(L, p1, "concatenate"); 535 luaG_typeerror(L, p1, "concatenate");
585} 536}
586 537
587 538
588void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) { 539l_noret luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
589 TValue temp; 540 TValue temp;
590 if (luaV_tonumber(p1, &temp) == NULL) 541 if (luaV_tonumber(p1, &temp) == NULL)
591 p2 = p1; /* first operand is wrong */ 542 p2 = p1; /* first operand is wrong */
@@ -593,14 +544,13 @@ void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
593} 544}
594 545
595 546
596int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { 547l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
597 const char *t1 = luaT_typenames[ttype(p1)]; 548 const char *t1 = objtypename(p1);
598 const char *t2 = luaT_typenames[ttype(p2)]; 549 const char *t2 = objtypename(p2);
599 if (t1[2] == t2[2]) 550 if (t1 == t2)
600 luaG_runerror(L, "attempt to compare two %s values", t1); 551 luaG_runerror(L, "attempt to compare two %s values", t1);
601 else 552 else
602 luaG_runerror(L, "attempt to compare %s with %s", t1, t2); 553 luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
603 return 0;
604} 554}
605 555
606 556
@@ -608,27 +558,32 @@ static void addinfo (lua_State *L, const char *msg) {
608 CallInfo *ci = L->ci; 558 CallInfo *ci = L->ci;
609 if (isLua(ci)) { /* is Lua code? */ 559 if (isLua(ci)) { /* is Lua code? */
610 char buff[LUA_IDSIZE]; /* add file:line information */ 560 char buff[LUA_IDSIZE]; /* add file:line information */
611 int line = currentline(L, ci); 561 int line = currentline(ci);
612 luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE); 562 TString *src = ci_func(ci)->p->source;
563 if (src)
564 luaO_chunkid(buff, getstr(src), LUA_IDSIZE);
565 else { /* no source available; use "?" instead */
566 buff[0] = '?'; buff[1] = '\0';
567 }
613 luaO_pushfstring(L, "%s:%d: %s", buff, line, msg); 568 luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
614 } 569 }
615} 570}
616 571
617 572
618void luaG_errormsg (lua_State *L) { 573l_noret luaG_errormsg (lua_State *L) {
619 if (L->errfunc != 0) { /* is there an error handling function? */ 574 if (L->errfunc != 0) { /* is there an error handling function? */
620 StkId errfunc = restorestack(L, L->errfunc); 575 StkId errfunc = restorestack(L, L->errfunc);
621 if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR); 576 if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
622 setobjs2s(L, L->top, L->top - 1); /* move argument */ 577 setobjs2s(L, L->top, L->top - 1); /* move argument */
623 setobjs2s(L, L->top - 1, errfunc); /* push function */ 578 setobjs2s(L, L->top - 1, errfunc); /* push function */
624 incr_top(L); 579 L->top++;
625 luaD_call(L, L->top - 2, 1); /* call it */ 580 luaD_call(L, L->top - 2, 1, 0); /* call it */
626 } 581 }
627 luaD_throw(L, LUA_ERRRUN); 582 luaD_throw(L, LUA_ERRRUN);
628} 583}
629 584
630 585
631void luaG_runerror (lua_State *L, const char *fmt, ...) { 586l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
632 va_list argp; 587 va_list argp;
633 va_start(argp, fmt); 588 va_start(argp, fmt);
634 addinfo(L, luaO_pushvfstring(L, fmt, argp)); 589 addinfo(L, luaO_pushvfstring(L, fmt, argp));