Mercurial > vba-clojure
diff src/lua/ldebug.c @ 11:27763b933818
raise lua sources up one level
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 11:07:39 -0600 |
parents | src/lua/src/ldebug.c@f9f4f1b99eed |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/lua/ldebug.c Sat Mar 03 11:07:39 2012 -0600 1.3 @@ -0,0 +1,638 @@ 1.4 +/* 1.5 +** $Id: ldebug.c,v 2.29.1.6 2008/05/08 16:56:26 roberto Exp $ 1.6 +** Debug Interface 1.7 +** See Copyright Notice in lua.h 1.8 +*/ 1.9 + 1.10 + 1.11 +#include <stdarg.h> 1.12 +#include <stddef.h> 1.13 +#include <string.h> 1.14 + 1.15 + 1.16 +#define ldebug_c 1.17 +#define LUA_CORE 1.18 + 1.19 +#include "lua.h" 1.20 + 1.21 +#include "lapi.h" 1.22 +#include "lcode.h" 1.23 +#include "ldebug.h" 1.24 +#include "ldo.h" 1.25 +#include "lfunc.h" 1.26 +#include "lobject.h" 1.27 +#include "lopcodes.h" 1.28 +#include "lstate.h" 1.29 +#include "lstring.h" 1.30 +#include "ltable.h" 1.31 +#include "ltm.h" 1.32 +#include "lvm.h" 1.33 + 1.34 + 1.35 + 1.36 +static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name); 1.37 + 1.38 + 1.39 +static int currentpc (lua_State *L, CallInfo *ci) { 1.40 + if (!isLua(ci)) return -1; /* function is not a Lua function? */ 1.41 + if (ci == L->ci) 1.42 + ci->savedpc = L->savedpc; 1.43 + return pcRel(ci->savedpc, ci_func(ci)->l.p); 1.44 +} 1.45 + 1.46 + 1.47 +static int currentline (lua_State *L, CallInfo *ci) { 1.48 + int pc = currentpc(L, ci); 1.49 + if (pc < 0) 1.50 + return -1; /* only active lua functions have current-line information */ 1.51 + else 1.52 + return getline(ci_func(ci)->l.p, pc); 1.53 +} 1.54 + 1.55 + 1.56 +/* 1.57 +** this function can be called asynchronous (e.g. during a signal) 1.58 +*/ 1.59 +LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { 1.60 + if (func == NULL || mask == 0) { /* turn off hooks? */ 1.61 + mask = 0; 1.62 + func = NULL; 1.63 + } 1.64 + L->hook = func; 1.65 + L->basehookcount = count; 1.66 + resethookcount(L); 1.67 + L->hookmask = cast_byte(mask); 1.68 + return 1; 1.69 +} 1.70 + 1.71 + 1.72 +LUA_API lua_Hook lua_gethook (lua_State *L) { 1.73 + return L->hook; 1.74 +} 1.75 + 1.76 + 1.77 +LUA_API int lua_gethookmask (lua_State *L) { 1.78 + return L->hookmask; 1.79 +} 1.80 + 1.81 + 1.82 +LUA_API int lua_gethookcount (lua_State *L) { 1.83 + return L->basehookcount; 1.84 +} 1.85 + 1.86 + 1.87 +LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { 1.88 + int status; 1.89 + CallInfo *ci; 1.90 + lua_lock(L); 1.91 + for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) { 1.92 + level--; 1.93 + if (f_isLua(ci)) /* Lua function? */ 1.94 + level -= ci->tailcalls; /* skip lost tail calls */ 1.95 + } 1.96 + if (level == 0 && ci > L->base_ci) { /* level found? */ 1.97 + status = 1; 1.98 + ar->i_ci = cast_int(ci - L->base_ci); 1.99 + } 1.100 + else if (level < 0) { /* level is of a lost tail call? */ 1.101 + status = 1; 1.102 + ar->i_ci = 0; 1.103 + } 1.104 + else status = 0; /* no such level */ 1.105 + lua_unlock(L); 1.106 + return status; 1.107 +} 1.108 + 1.109 + 1.110 +static Proto *getluaproto (CallInfo *ci) { 1.111 + return (isLua(ci) ? ci_func(ci)->l.p : NULL); 1.112 +} 1.113 + 1.114 + 1.115 +static const char *findlocal (lua_State *L, CallInfo *ci, int n) { 1.116 + const char *name; 1.117 + Proto *fp = getluaproto(ci); 1.118 + if (fp && (name = luaF_getlocalname(fp, n, currentpc(L, ci))) != NULL) 1.119 + return name; /* is a local variable in a Lua function */ 1.120 + else { 1.121 + StkId limit = (ci == L->ci) ? L->top : (ci+1)->func; 1.122 + if (limit - ci->base >= n && n > 0) /* is 'n' inside 'ci' stack? */ 1.123 + return "(*temporary)"; 1.124 + else 1.125 + return NULL; 1.126 + } 1.127 +} 1.128 + 1.129 + 1.130 +LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { 1.131 + CallInfo *ci = L->base_ci + ar->i_ci; 1.132 + const char *name = findlocal(L, ci, n); 1.133 + lua_lock(L); 1.134 + if (name) 1.135 + luaA_pushobject(L, ci->base + (n - 1)); 1.136 + lua_unlock(L); 1.137 + return name; 1.138 +} 1.139 + 1.140 + 1.141 +LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { 1.142 + CallInfo *ci = L->base_ci + ar->i_ci; 1.143 + const char *name = findlocal(L, ci, n); 1.144 + lua_lock(L); 1.145 + if (name) 1.146 + setobjs2s(L, ci->base + (n - 1), L->top - 1); 1.147 + L->top--; /* pop value */ 1.148 + lua_unlock(L); 1.149 + return name; 1.150 +} 1.151 + 1.152 + 1.153 +static void funcinfo (lua_Debug *ar, Closure *cl) { 1.154 + if (cl->c.isC) { 1.155 + ar->source = "=[C]"; 1.156 + ar->linedefined = -1; 1.157 + ar->lastlinedefined = -1; 1.158 + ar->what = "C"; 1.159 + } 1.160 + else { 1.161 + ar->source = getstr(cl->l.p->source); 1.162 + ar->linedefined = cl->l.p->linedefined; 1.163 + ar->lastlinedefined = cl->l.p->lastlinedefined; 1.164 + ar->what = (ar->linedefined == 0) ? "main" : "Lua"; 1.165 + } 1.166 + luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); 1.167 +} 1.168 + 1.169 + 1.170 +static void info_tailcall (lua_Debug *ar) { 1.171 + ar->name = ar->namewhat = ""; 1.172 + ar->what = "tail"; 1.173 + ar->lastlinedefined = ar->linedefined = ar->currentline = -1; 1.174 + ar->source = "=(tail call)"; 1.175 + luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); 1.176 + ar->nups = 0; 1.177 +} 1.178 + 1.179 + 1.180 +static void collectvalidlines (lua_State *L, Closure *f) { 1.181 + if (f == NULL || f->c.isC) { 1.182 + setnilvalue(L->top); 1.183 + } 1.184 + else { 1.185 + Table *t = luaH_new(L, 0, 0); 1.186 + int *lineinfo = f->l.p->lineinfo; 1.187 + int i; 1.188 + for (i=0; i<f->l.p->sizelineinfo; i++) 1.189 + setbvalue(luaH_setnum(L, t, lineinfo[i]), 1); 1.190 + sethvalue(L, L->top, t); 1.191 + } 1.192 + incr_top(L); 1.193 +} 1.194 + 1.195 + 1.196 +static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, 1.197 + Closure *f, CallInfo *ci) { 1.198 + int status = 1; 1.199 + if (f == NULL) { 1.200 + info_tailcall(ar); 1.201 + return status; 1.202 + } 1.203 + for (; *what; what++) { 1.204 + switch (*what) { 1.205 + case 'S': { 1.206 + funcinfo(ar, f); 1.207 + break; 1.208 + } 1.209 + case 'l': { 1.210 + ar->currentline = (ci) ? currentline(L, ci) : -1; 1.211 + break; 1.212 + } 1.213 + case 'u': { 1.214 + ar->nups = f->c.nupvalues; 1.215 + break; 1.216 + } 1.217 + case 'n': { 1.218 + ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL; 1.219 + if (ar->namewhat == NULL) { 1.220 + ar->namewhat = ""; /* not found */ 1.221 + ar->name = NULL; 1.222 + } 1.223 + break; 1.224 + } 1.225 + case 'L': 1.226 + case 'f': /* handled by lua_getinfo */ 1.227 + break; 1.228 + default: status = 0; /* invalid option */ 1.229 + } 1.230 + } 1.231 + return status; 1.232 +} 1.233 + 1.234 + 1.235 +LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { 1.236 + int status; 1.237 + Closure *f = NULL; 1.238 + CallInfo *ci = NULL; 1.239 + lua_lock(L); 1.240 + if (*what == '>') { 1.241 + StkId func = L->top - 1; 1.242 + luai_apicheck(L, ttisfunction(func)); 1.243 + what++; /* skip the '>' */ 1.244 + f = clvalue(func); 1.245 + L->top--; /* pop function */ 1.246 + } 1.247 + else if (ar->i_ci != 0) { /* no tail call? */ 1.248 + ci = L->base_ci + ar->i_ci; 1.249 + lua_assert(ttisfunction(ci->func)); 1.250 + f = clvalue(ci->func); 1.251 + } 1.252 + status = auxgetinfo(L, what, ar, f, ci); 1.253 + if (strchr(what, 'f')) { 1.254 + if (f == NULL) setnilvalue(L->top); 1.255 + else setclvalue(L, L->top, f); 1.256 + incr_top(L); 1.257 + } 1.258 + if (strchr(what, 'L')) 1.259 + collectvalidlines(L, f); 1.260 + lua_unlock(L); 1.261 + return status; 1.262 +} 1.263 + 1.264 + 1.265 +/* 1.266 +** {====================================================== 1.267 +** Symbolic Execution and code checker 1.268 +** ======================================================= 1.269 +*/ 1.270 + 1.271 +#define check(x) if (!(x)) return 0; 1.272 + 1.273 +#define checkjump(pt,pc) check(0 <= pc && pc < pt->sizecode) 1.274 + 1.275 +#define checkreg(pt,reg) check((reg) < (pt)->maxstacksize) 1.276 + 1.277 + 1.278 + 1.279 +static int precheck (const Proto *pt) { 1.280 + check(pt->maxstacksize <= MAXSTACK); 1.281 + check(pt->numparams+(pt->is_vararg & VARARG_HASARG) <= pt->maxstacksize); 1.282 + check(!(pt->is_vararg & VARARG_NEEDSARG) || 1.283 + (pt->is_vararg & VARARG_HASARG)); 1.284 + check(pt->sizeupvalues <= pt->nups); 1.285 + check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0); 1.286 + check(pt->sizecode > 0 && GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN); 1.287 + return 1; 1.288 +} 1.289 + 1.290 + 1.291 +#define checkopenop(pt,pc) luaG_checkopenop((pt)->code[(pc)+1]) 1.292 + 1.293 +int luaG_checkopenop (Instruction i) { 1.294 + switch (GET_OPCODE(i)) { 1.295 + case OP_CALL: 1.296 + case OP_TAILCALL: 1.297 + case OP_RETURN: 1.298 + case OP_SETLIST: { 1.299 + check(GETARG_B(i) == 0); 1.300 + return 1; 1.301 + } 1.302 + default: return 0; /* invalid instruction after an open call */ 1.303 + } 1.304 +} 1.305 + 1.306 + 1.307 +static int checkArgMode (const Proto *pt, int r, enum OpArgMask mode) { 1.308 + switch (mode) { 1.309 + case OpArgN: check(r == 0); break; 1.310 + case OpArgU: break; 1.311 + case OpArgR: checkreg(pt, r); break; 1.312 + case OpArgK: 1.313 + check(ISK(r) ? INDEXK(r) < pt->sizek : r < pt->maxstacksize); 1.314 + break; 1.315 + } 1.316 + return 1; 1.317 +} 1.318 + 1.319 + 1.320 +static Instruction symbexec (const Proto *pt, int lastpc, int reg) { 1.321 + int pc; 1.322 + int last; /* stores position of last instruction that changed `reg' */ 1.323 + last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */ 1.324 + check(precheck(pt)); 1.325 + for (pc = 0; pc < lastpc; pc++) { 1.326 + Instruction i = pt->code[pc]; 1.327 + OpCode op = GET_OPCODE(i); 1.328 + int a = GETARG_A(i); 1.329 + int b = 0; 1.330 + int c = 0; 1.331 + check(op < NUM_OPCODES); 1.332 + checkreg(pt, a); 1.333 + switch (getOpMode(op)) { 1.334 + case iABC: { 1.335 + b = GETARG_B(i); 1.336 + c = GETARG_C(i); 1.337 + check(checkArgMode(pt, b, getBMode(op))); 1.338 + check(checkArgMode(pt, c, getCMode(op))); 1.339 + break; 1.340 + } 1.341 + case iABx: { 1.342 + b = GETARG_Bx(i); 1.343 + if (getBMode(op) == OpArgK) check(b < pt->sizek); 1.344 + break; 1.345 + } 1.346 + case iAsBx: { 1.347 + b = GETARG_sBx(i); 1.348 + if (getBMode(op) == OpArgR) { 1.349 + int dest = pc+1+b; 1.350 + check(0 <= dest && dest < pt->sizecode); 1.351 + if (dest > 0) { 1.352 + int j; 1.353 + /* check that it does not jump to a setlist count; this 1.354 + is tricky, because the count from a previous setlist may 1.355 + have the same value of an invalid setlist; so, we must 1.356 + go all the way back to the first of them (if any) */ 1.357 + for (j = 0; j < dest; j++) { 1.358 + Instruction d = pt->code[dest-1-j]; 1.359 + if (!(GET_OPCODE(d) == OP_SETLIST && GETARG_C(d) == 0)) break; 1.360 + } 1.361 + /* if 'j' is even, previous value is not a setlist (even if 1.362 + it looks like one) */ 1.363 + check((j&1) == 0); 1.364 + } 1.365 + } 1.366 + break; 1.367 + } 1.368 + } 1.369 + if (testAMode(op)) { 1.370 + if (a == reg) last = pc; /* change register `a' */ 1.371 + } 1.372 + if (testTMode(op)) { 1.373 + check(pc+2 < pt->sizecode); /* check skip */ 1.374 + check(GET_OPCODE(pt->code[pc+1]) == OP_JMP); 1.375 + } 1.376 + switch (op) { 1.377 + case OP_LOADBOOL: { 1.378 + if (c == 1) { /* does it jump? */ 1.379 + check(pc+2 < pt->sizecode); /* check its jump */ 1.380 + check(GET_OPCODE(pt->code[pc+1]) != OP_SETLIST || 1.381 + GETARG_C(pt->code[pc+1]) != 0); 1.382 + } 1.383 + break; 1.384 + } 1.385 + case OP_LOADNIL: { 1.386 + if (a <= reg && reg <= b) 1.387 + last = pc; /* set registers from `a' to `b' */ 1.388 + break; 1.389 + } 1.390 + case OP_GETUPVAL: 1.391 + case OP_SETUPVAL: { 1.392 + check(b < pt->nups); 1.393 + break; 1.394 + } 1.395 + case OP_GETGLOBAL: 1.396 + case OP_SETGLOBAL: { 1.397 + check(ttisstring(&pt->k[b])); 1.398 + break; 1.399 + } 1.400 + case OP_SELF: { 1.401 + checkreg(pt, a+1); 1.402 + if (reg == a+1) last = pc; 1.403 + break; 1.404 + } 1.405 + case OP_CONCAT: { 1.406 + check(b < c); /* at least two operands */ 1.407 + break; 1.408 + } 1.409 + case OP_TFORLOOP: { 1.410 + check(c >= 1); /* at least one result (control variable) */ 1.411 + checkreg(pt, a+2+c); /* space for results */ 1.412 + if (reg >= a+2) last = pc; /* affect all regs above its base */ 1.413 + break; 1.414 + } 1.415 + case OP_FORLOOP: 1.416 + case OP_FORPREP: 1.417 + checkreg(pt, a+3); 1.418 + /* go through */ 1.419 + case OP_JMP: { 1.420 + int dest = pc+1+b; 1.421 + /* not full check and jump is forward and do not skip `lastpc'? */ 1.422 + if (reg != NO_REG && pc < dest && dest <= lastpc) 1.423 + pc += b; /* do the jump */ 1.424 + break; 1.425 + } 1.426 + case OP_CALL: 1.427 + case OP_TAILCALL: { 1.428 + if (b != 0) { 1.429 + checkreg(pt, a+b-1); 1.430 + } 1.431 + c--; /* c = num. returns */ 1.432 + if (c == LUA_MULTRET) { 1.433 + check(checkopenop(pt, pc)); 1.434 + } 1.435 + else if (c != 0) 1.436 + checkreg(pt, a+c-1); 1.437 + if (reg >= a) last = pc; /* affect all registers above base */ 1.438 + break; 1.439 + } 1.440 + case OP_RETURN: { 1.441 + b--; /* b = num. returns */ 1.442 + if (b > 0) checkreg(pt, a+b-1); 1.443 + break; 1.444 + } 1.445 + case OP_SETLIST: { 1.446 + if (b > 0) checkreg(pt, a + b); 1.447 + if (c == 0) { 1.448 + pc++; 1.449 + check(pc < pt->sizecode - 1); 1.450 + } 1.451 + break; 1.452 + } 1.453 + case OP_CLOSURE: { 1.454 + int nup, j; 1.455 + check(b < pt->sizep); 1.456 + nup = pt->p[b]->nups; 1.457 + check(pc + nup < pt->sizecode); 1.458 + for (j = 1; j <= nup; j++) { 1.459 + OpCode op1 = GET_OPCODE(pt->code[pc + j]); 1.460 + check(op1 == OP_GETUPVAL || op1 == OP_MOVE); 1.461 + } 1.462 + if (reg != NO_REG) /* tracing? */ 1.463 + pc += nup; /* do not 'execute' these pseudo-instructions */ 1.464 + break; 1.465 + } 1.466 + case OP_VARARG: { 1.467 + check((pt->is_vararg & VARARG_ISVARARG) && 1.468 + !(pt->is_vararg & VARARG_NEEDSARG)); 1.469 + b--; 1.470 + if (b == LUA_MULTRET) check(checkopenop(pt, pc)); 1.471 + checkreg(pt, a+b-1); 1.472 + break; 1.473 + } 1.474 + default: break; 1.475 + } 1.476 + } 1.477 + return pt->code[last]; 1.478 +} 1.479 + 1.480 +#undef check 1.481 +#undef checkjump 1.482 +#undef checkreg 1.483 + 1.484 +/* }====================================================== */ 1.485 + 1.486 + 1.487 +int luaG_checkcode (const Proto *pt) { 1.488 + return (symbexec(pt, pt->sizecode, NO_REG) != 0); 1.489 +} 1.490 + 1.491 + 1.492 +static const char *kname (Proto *p, int c) { 1.493 + if (ISK(c) && ttisstring(&p->k[INDEXK(c)])) 1.494 + return svalue(&p->k[INDEXK(c)]); 1.495 + else 1.496 + return "?"; 1.497 +} 1.498 + 1.499 + 1.500 +static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos, 1.501 + const char **name) { 1.502 + if (isLua(ci)) { /* a Lua function? */ 1.503 + Proto *p = ci_func(ci)->l.p; 1.504 + int pc = currentpc(L, ci); 1.505 + Instruction i; 1.506 + *name = luaF_getlocalname(p, stackpos+1, pc); 1.507 + if (*name) /* is a local? */ 1.508 + return "local"; 1.509 + i = symbexec(p, pc, stackpos); /* try symbolic execution */ 1.510 + lua_assert(pc != -1); 1.511 + switch (GET_OPCODE(i)) { 1.512 + case OP_GETGLOBAL: { 1.513 + int g = GETARG_Bx(i); /* global index */ 1.514 + lua_assert(ttisstring(&p->k[g])); 1.515 + *name = svalue(&p->k[g]); 1.516 + return "global"; 1.517 + } 1.518 + case OP_MOVE: { 1.519 + int a = GETARG_A(i); 1.520 + int b = GETARG_B(i); /* move from `b' to `a' */ 1.521 + if (b < a) 1.522 + return getobjname(L, ci, b, name); /* get name for `b' */ 1.523 + break; 1.524 + } 1.525 + case OP_GETTABLE: { 1.526 + int k = GETARG_C(i); /* key index */ 1.527 + *name = kname(p, k); 1.528 + return "field"; 1.529 + } 1.530 + case OP_GETUPVAL: { 1.531 + int u = GETARG_B(i); /* upvalue index */ 1.532 + *name = p->upvalues ? getstr(p->upvalues[u]) : "?"; 1.533 + return "upvalue"; 1.534 + } 1.535 + case OP_SELF: { 1.536 + int k = GETARG_C(i); /* key index */ 1.537 + *name = kname(p, k); 1.538 + return "method"; 1.539 + } 1.540 + default: break; 1.541 + } 1.542 + } 1.543 + return NULL; /* no useful name found */ 1.544 +} 1.545 + 1.546 + 1.547 +static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { 1.548 + Instruction i; 1.549 + if ((isLua(ci) && ci->tailcalls > 0) || !isLua(ci - 1)) 1.550 + return NULL; /* calling function is not Lua (or is unknown) */ 1.551 + ci--; /* calling function */ 1.552 + i = ci_func(ci)->l.p->code[currentpc(L, ci)]; 1.553 + if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL || 1.554 + GET_OPCODE(i) == OP_TFORLOOP) 1.555 + return getobjname(L, ci, GETARG_A(i), name); 1.556 + else 1.557 + return NULL; /* no useful name can be found */ 1.558 +} 1.559 + 1.560 + 1.561 +/* only ANSI way to check whether a pointer points to an array */ 1.562 +static int isinstack (CallInfo *ci, const TValue *o) { 1.563 + StkId p; 1.564 + for (p = ci->base; p < ci->top; p++) 1.565 + if (o == p) return 1; 1.566 + return 0; 1.567 +} 1.568 + 1.569 + 1.570 +void luaG_typeerror (lua_State *L, const TValue *o, const char *op) { 1.571 + const char *name = NULL; 1.572 + const char *t = luaT_typenames[ttype(o)]; 1.573 + const char *kind = (isinstack(L->ci, o)) ? 1.574 + getobjname(L, L->ci, cast_int(o - L->base), &name) : 1.575 + NULL; 1.576 + if (kind) 1.577 + luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)", 1.578 + op, kind, name, t); 1.579 + else 1.580 + luaG_runerror(L, "attempt to %s a %s value", op, t); 1.581 +} 1.582 + 1.583 + 1.584 +void luaG_concaterror (lua_State *L, StkId p1, StkId p2) { 1.585 + if (ttisstring(p1) || ttisnumber(p1)) p1 = p2; 1.586 + lua_assert(!ttisstring(p1) && !ttisnumber(p1)); 1.587 + luaG_typeerror(L, p1, "concatenate"); 1.588 +} 1.589 + 1.590 + 1.591 +void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) { 1.592 + TValue temp; 1.593 + if (luaV_tonumber(p1, &temp) == NULL) 1.594 + p2 = p1; /* first operand is wrong */ 1.595 + luaG_typeerror(L, p2, "perform arithmetic on"); 1.596 +} 1.597 + 1.598 + 1.599 +int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { 1.600 + const char *t1 = luaT_typenames[ttype(p1)]; 1.601 + const char *t2 = luaT_typenames[ttype(p2)]; 1.602 + if (t1[2] == t2[2]) 1.603 + luaG_runerror(L, "attempt to compare two %s values", t1); 1.604 + else 1.605 + luaG_runerror(L, "attempt to compare %s with %s", t1, t2); 1.606 + return 0; 1.607 +} 1.608 + 1.609 + 1.610 +static void addinfo (lua_State *L, const char *msg) { 1.611 + CallInfo *ci = L->ci; 1.612 + if (isLua(ci)) { /* is Lua code? */ 1.613 + char buff[LUA_IDSIZE]; /* add file:line information */ 1.614 + int line = currentline(L, ci); 1.615 + luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE); 1.616 + luaO_pushfstring(L, "%s:%d: %s", buff, line, msg); 1.617 + } 1.618 +} 1.619 + 1.620 + 1.621 +void luaG_errormsg (lua_State *L) { 1.622 + if (L->errfunc != 0) { /* is there an error handling function? */ 1.623 + StkId errfunc = restorestack(L, L->errfunc); 1.624 + if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR); 1.625 + setobjs2s(L, L->top, L->top - 1); /* move argument */ 1.626 + setobjs2s(L, L->top - 1, errfunc); /* push function */ 1.627 + incr_top(L); 1.628 + luaD_call(L, L->top - 2, 1); /* call it */ 1.629 + } 1.630 + luaD_throw(L, LUA_ERRRUN); 1.631 +} 1.632 + 1.633 + 1.634 +void luaG_runerror (lua_State *L, const char *fmt, ...) { 1.635 + va_list argp; 1.636 + va_start(argp, fmt); 1.637 + addinfo(L, luaO_pushvfstring(L, fmt, argp)); 1.638 + va_end(argp); 1.639 + luaG_errormsg(L); 1.640 +} 1.641 +