Line data Source code
1 : /*
2 : ** $Id: ldebug.c,v 2.29.1.6 2008/05/08 16:56:26 roberto Exp $
3 : ** Debug Interface
4 : ** See Copyright Notice in lua.h
5 : */
6 :
7 :
8 : #include <stdarg.h>
9 : #include <stddef.h>
10 : #include <string.h>
11 :
12 :
13 : #define ldebug_c
14 : #define LUA_CORE
15 :
16 : #include "lua.h"
17 :
18 : #include "lapi.h"
19 : #include "lcode.h"
20 : #include "ldebug.h"
21 : #include "ldo.h"
22 : #include "lfunc.h"
23 : #include "lobject.h"
24 : #include "lopcodes.h"
25 : #include "lstate.h"
26 : #include "lstring.h"
27 : #include "ltable.h"
28 : #include "ltm.h"
29 : #include "lvm.h"
30 :
31 :
32 :
33 : static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name);
34 :
35 :
36 498 : static int currentpc (lua_State *L, CallInfo *ci) {
37 498 : if (!isLua(ci)) return -1; /* function is not a Lua function? */
38 444 : if (ci == L->ci)
39 261 : ci->savedpc = L->savedpc;
40 444 : return pcRel(ci->savedpc, ci_func(ci)->l.p);
41 : }
42 :
43 :
44 337 : static int currentline (lua_State *L, CallInfo *ci) {
45 337 : int pc = currentpc(L, ci);
46 337 : if (pc < 0)
47 54 : return -1; /* only active lua functions have current-line information */
48 : else
49 283 : return getline(ci_func(ci)->l.p, pc);
50 : }
51 :
52 :
53 : /*
54 : ** this function can be called asynchronous (e.g. during a signal)
55 : */
56 2 : LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
57 2 : if (func == NULL || mask == 0) { /* turn off hooks? */
58 1 : mask = 0;
59 1 : func = NULL;
60 : }
61 2 : L->hook = func;
62 2 : L->basehookcount = count;
63 2 : resethookcount(L);
64 2 : L->hookmask = cast_byte(mask);
65 2 : return 1;
66 : }
67 :
68 :
69 3 : LUA_API lua_Hook lua_gethook (lua_State *L) {
70 3 : return L->hook;
71 : }
72 :
73 :
74 3 : LUA_API int lua_gethookmask (lua_State *L) {
75 3 : return L->hookmask;
76 : }
77 :
78 :
79 3 : LUA_API int lua_gethookcount (lua_State *L) {
80 3 : return L->basehookcount;
81 : }
82 :
83 :
84 240 : LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) {
85 : int status;
86 : CallInfo *ci;
87 : lua_lock(L);
88 460 : for (ci = L->ci; level > 0 && ci > L->base_ci; ci--) {
89 220 : level--;
90 220 : if (f_isLua(ci)) /* Lua function? */
91 23 : level -= ci->tailcalls; /* skip lost tail calls */
92 : }
93 240 : if (level == 0 && ci > L->base_ci) { /* level found? */
94 211 : status = 1;
95 211 : ar->i_ci = cast_int(ci - L->base_ci);
96 : }
97 29 : else if (level < 0) { /* level is of a lost tail call? */
98 0 : status = 1;
99 0 : ar->i_ci = 0;
100 : }
101 29 : else status = 0; /* no such level */
102 : lua_unlock(L);
103 240 : return status;
104 : }
105 :
106 :
107 191 : static Proto *getluaproto (CallInfo *ci) {
108 191 : return (isLua(ci) ? ci_func(ci)->l.p : NULL);
109 : }
110 :
111 :
112 3 : static const char *findlocal (lua_State *L, CallInfo *ci, int n) {
113 : const char *name;
114 3 : Proto *fp = getluaproto(ci);
115 3 : if (fp && (name = luaF_getlocalname(fp, n, currentpc(L, ci))) != NULL)
116 0 : return name; /* is a local variable in a Lua function */
117 : else {
118 3 : StkId limit = (ci == L->ci) ? L->top : (ci+1)->func;
119 3 : if (limit - ci->base >= n && n > 0) /* is 'n' inside 'ci' stack? */
120 2 : return "(*temporary)";
121 : else
122 1 : return NULL;
123 : }
124 : }
125 :
126 :
127 1 : LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) {
128 1 : CallInfo *ci = L->base_ci + ar->i_ci;
129 1 : const char *name = findlocal(L, ci, n);
130 : lua_lock(L);
131 1 : if (name)
132 1 : luaA_pushobject(L, ci->base + (n - 1));
133 : lua_unlock(L);
134 1 : return name;
135 : }
136 :
137 :
138 2 : LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
139 2 : CallInfo *ci = L->base_ci + ar->i_ci;
140 2 : const char *name = findlocal(L, ci, n);
141 : lua_lock(L);
142 2 : if (name)
143 1 : setobjs2s(L, ci->base + (n - 1), L->top - 1);
144 2 : L->top--; /* pop value */
145 : lua_unlock(L);
146 2 : return name;
147 : }
148 :
149 :
150 150 : static void funcinfo (lua_Debug *ar, Closure *cl) {
151 150 : if (cl->c.isC) {
152 54 : ar->source = "=[C]";
153 54 : ar->linedefined = -1;
154 54 : ar->lastlinedefined = -1;
155 54 : ar->what = "C";
156 : }
157 : else {
158 96 : ar->source = getstr(cl->l.p->source);
159 96 : ar->linedefined = cl->l.p->linedefined;
160 96 : ar->lastlinedefined = cl->l.p->lastlinedefined;
161 96 : ar->what = (ar->linedefined == 0) ? "main" : "Lua";
162 : }
163 150 : luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
164 150 : }
165 :
166 :
167 0 : static void info_tailcall (lua_Debug *ar) {
168 0 : ar->name = ar->namewhat = "";
169 0 : ar->what = "tail";
170 0 : ar->lastlinedefined = ar->linedefined = ar->currentline = -1;
171 0 : ar->source = "=(tail call)";
172 0 : luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE);
173 0 : ar->nups = 0;
174 0 : }
175 :
176 :
177 1 : static void collectvalidlines (lua_State *L, Closure *f) {
178 1 : if (f == NULL || f->c.isC) {
179 0 : setnilvalue(L->top);
180 : }
181 : else {
182 1 : Table *t = luaH_new(L, 0, 0);
183 1 : int *lineinfo = f->l.p->lineinfo;
184 : int i;
185 26 : for (i=0; i<f->l.p->sizelineinfo; i++)
186 25 : setbvalue(luaH_setnum(L, t, lineinfo[i]), 1);
187 1 : sethvalue(L, L->top, t);
188 : }
189 1 : incr_top(L);
190 1 : }
191 :
192 :
193 211 : static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
194 : Closure *f, CallInfo *ci) {
195 211 : int status = 1;
196 211 : if (f == NULL) {
197 0 : info_tailcall(ar);
198 0 : return status;
199 : }
200 588 : for (; *what; what++) {
201 377 : switch (*what) {
202 150 : case 'S': {
203 150 : funcinfo(ar, f);
204 150 : break;
205 : }
206 150 : case 'l': {
207 150 : ar->currentline = (ci) ? currentline(L, ci) : -1;
208 150 : break;
209 : }
210 2 : case 'u': {
211 2 : ar->nups = f->c.nupvalues;
212 2 : break;
213 : }
214 56 : case 'n': {
215 56 : ar->namewhat = (ci) ? getfuncname(L, ci, &ar->name) : NULL;
216 56 : if (ar->namewhat == NULL) {
217 12 : ar->namewhat = ""; /* not found */
218 12 : ar->name = NULL;
219 : }
220 56 : break;
221 : }
222 18 : case 'L':
223 : case 'f': /* handled by lua_getinfo */
224 18 : break;
225 1 : default: status = 0; /* invalid option */
226 : }
227 : }
228 211 : return status;
229 : }
230 :
231 :
232 211 : LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) {
233 : int status;
234 211 : Closure *f = NULL;
235 211 : CallInfo *ci = NULL;
236 : lua_lock(L);
237 211 : if (*what == '>') {
238 3 : StkId func = L->top - 1;
239 : luai_apicheck(L, ttisfunction(func));
240 3 : what++; /* skip the '>' */
241 3 : f = clvalue(func);
242 3 : L->top--; /* pop function */
243 : }
244 208 : else if (ar->i_ci != 0) { /* no tail call? */
245 208 : ci = L->base_ci + ar->i_ci;
246 : lua_assert(ttisfunction(ci->func));
247 208 : f = clvalue(ci->func);
248 : }
249 211 : status = auxgetinfo(L, what, ar, f, ci);
250 211 : if (strchr(what, 'f')) {
251 17 : if (f == NULL) setnilvalue(L->top);
252 17 : else setclvalue(L, L->top, f);
253 17 : incr_top(L);
254 : }
255 211 : if (strchr(what, 'L'))
256 1 : collectvalidlines(L, f);
257 : lua_unlock(L);
258 211 : return status;
259 : }
260 :
261 :
262 : /*
263 : ** {======================================================
264 : ** Symbolic Execution and code checker
265 : ** =======================================================
266 : */
267 :
268 : #define check(x) if (!(x)) return 0;
269 :
270 : #define checkjump(pt,pc) check(0 <= pc && pc < pt->sizecode)
271 :
272 : #define checkreg(pt,reg) check((reg) < (pt)->maxstacksize)
273 :
274 :
275 :
276 120 : static int precheck (const Proto *pt) {
277 120 : check(pt->maxstacksize <= MAXSTACK);
278 120 : check(pt->numparams+(pt->is_vararg & VARARG_HASARG) <= pt->maxstacksize);
279 120 : check(!(pt->is_vararg & VARARG_NEEDSARG) ||
280 : (pt->is_vararg & VARARG_HASARG));
281 120 : check(pt->sizeupvalues <= pt->nups);
282 120 : check(pt->sizelineinfo == pt->sizecode || pt->sizelineinfo == 0);
283 120 : check(pt->sizecode > 0 && GET_OPCODE(pt->code[pt->sizecode-1]) == OP_RETURN);
284 120 : return 1;
285 : }
286 :
287 :
288 : #define checkopenop(pt,pc) luaG_checkopenop((pt)->code[(pc)+1])
289 :
290 2 : int luaG_checkopenop (Instruction i) {
291 2 : switch (GET_OPCODE(i)) {
292 2 : case OP_CALL:
293 : case OP_TAILCALL:
294 : case OP_RETURN:
295 : case OP_SETLIST: {
296 2 : check(GETARG_B(i) == 0);
297 2 : return 1;
298 : }
299 0 : default: return 0; /* invalid instruction after an open call */
300 : }
301 : }
302 :
303 :
304 814 : static int checkArgMode (const Proto *pt, int r, enum OpArgMask mode) {
305 814 : switch (mode) {
306 164 : case OpArgN: check(r == 0); break;
307 443 : case OpArgU: break;
308 130 : case OpArgR: checkreg(pt, r); break;
309 77 : case OpArgK:
310 77 : check(ISK(r) ? INDEXK(r) < pt->sizek : r < pt->maxstacksize);
311 77 : break;
312 : }
313 814 : return 1;
314 : }
315 :
316 :
317 120 : static Instruction symbexec (const Proto *pt, int lastpc, int reg) {
318 : int pc;
319 : int last; /* stores position of last instruction that changed `reg' */
320 120 : last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */
321 120 : check(precheck(pt));
322 932 : for (pc = 0; pc < lastpc; pc++) {
323 812 : Instruction i = pt->code[pc];
324 812 : OpCode op = GET_OPCODE(i);
325 812 : int a = GETARG_A(i);
326 812 : int b = 0;
327 812 : int c = 0;
328 812 : check(op < NUM_OPCODES);
329 812 : checkreg(pt, a);
330 812 : switch (getOpMode(op)) {
331 407 : case iABC: {
332 407 : b = GETARG_B(i);
333 407 : c = GETARG_C(i);
334 407 : check(checkArgMode(pt, b, getBMode(op)));
335 407 : check(checkArgMode(pt, c, getCMode(op)));
336 407 : break;
337 : }
338 377 : case iABx: {
339 377 : b = GETARG_Bx(i);
340 377 : if (getBMode(op) == OpArgK) check(b < pt->sizek);
341 377 : break;
342 : }
343 28 : case iAsBx: {
344 28 : b = GETARG_sBx(i);
345 28 : if (getBMode(op) == OpArgR) {
346 28 : int dest = pc+1+b;
347 28 : check(0 <= dest && dest < pt->sizecode);
348 28 : 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 26 : for (j = 0; j < dest; j++) {
355 26 : Instruction d = pt->code[dest-1-j];
356 26 : 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 26 : check((j&1) == 0);
361 : }
362 : }
363 28 : break;
364 : }
365 : }
366 812 : if (testAMode(op)) {
367 722 : if (a == reg) last = pc; /* change register `a' */
368 : }
369 812 : if (testTMode(op)) {
370 25 : check(pc+2 < pt->sizecode); /* check skip */
371 25 : check(GET_OPCODE(pt->code[pc+1]) == OP_JMP);
372 : }
373 812 : switch (op) {
374 31 : case OP_LOADBOOL: {
375 31 : if (c == 1) { /* does it jump? */
376 0 : check(pc+2 < pt->sizecode); /* check its jump */
377 0 : check(GET_OPCODE(pt->code[pc+1]) != OP_SETLIST ||
378 : GETARG_C(pt->code[pc+1]) != 0);
379 : }
380 31 : break;
381 : }
382 16 : case OP_LOADNIL: {
383 16 : if (a <= reg && reg <= b)
384 2 : last = pc; /* set registers from `a' to `b' */
385 16 : break;
386 : }
387 60 : case OP_GETUPVAL:
388 : case OP_SETUPVAL: {
389 60 : check(b < pt->nups);
390 60 : break;
391 : }
392 184 : case OP_GETGLOBAL:
393 : case OP_SETGLOBAL: {
394 184 : check(ttisstring(&pt->k[b]));
395 184 : break;
396 : }
397 6 : case OP_SELF: {
398 6 : checkreg(pt, a+1);
399 6 : if (reg == a+1) last = pc;
400 6 : break;
401 : }
402 0 : case OP_CONCAT: {
403 0 : check(b < c); /* at least two operands */
404 0 : break;
405 : }
406 0 : case OP_TFORLOOP: {
407 0 : check(c >= 1); /* at least one result (control variable) */
408 0 : checkreg(pt, a+2+c); /* space for results */
409 0 : if (reg >= a+2) last = pc; /* affect all regs above its base */
410 0 : break;
411 : }
412 0 : case OP_FORLOOP:
413 : case OP_FORPREP:
414 0 : checkreg(pt, a+3);
415 : /* go through */
416 : case OP_JMP: {
417 28 : int dest = pc+1+b;
418 : /* not full check and jump is forward and do not skip `lastpc'? */
419 28 : if (reg != NO_REG && pc < dest && dest <= lastpc)
420 26 : pc += b; /* do the jump */
421 28 : break;
422 : }
423 110 : case OP_CALL:
424 : case OP_TAILCALL: {
425 110 : if (b != 0) {
426 110 : checkreg(pt, a+b-1);
427 : }
428 110 : c--; /* c = num. returns */
429 110 : if (c == LUA_MULTRET) {
430 0 : check(checkopenop(pt, pc));
431 : }
432 110 : else if (c != 0)
433 36 : checkreg(pt, a+c-1);
434 110 : if (reg >= a) last = pc; /* affect all registers above base */
435 110 : break;
436 : }
437 17 : case OP_RETURN: {
438 17 : b--; /* b = num. returns */
439 17 : if (b > 0) checkreg(pt, a+b-1);
440 17 : break;
441 : }
442 8 : case OP_SETLIST: {
443 8 : if (b > 0) checkreg(pt, a + b);
444 8 : if (c == 0) {
445 0 : pc++;
446 0 : check(pc < pt->sizecode - 1);
447 : }
448 8 : break;
449 : }
450 22 : case OP_CLOSURE: {
451 : int nup, j;
452 22 : check(b < pt->sizep);
453 22 : nup = pt->p[b]->nups;
454 22 : check(pc + nup < pt->sizecode);
455 29 : for (j = 1; j <= nup; j++) {
456 7 : OpCode op1 = GET_OPCODE(pt->code[pc + j]);
457 7 : check(op1 == OP_GETUPVAL || op1 == OP_MOVE);
458 : }
459 22 : if (reg != NO_REG) /* tracing? */
460 16 : pc += nup; /* do not 'execute' these pseudo-instructions */
461 22 : break;
462 : }
463 2 : case OP_VARARG: {
464 2 : check((pt->is_vararg & VARARG_ISVARARG) &&
465 : !(pt->is_vararg & VARARG_NEEDSARG));
466 2 : b--;
467 2 : if (b == LUA_MULTRET) check(checkopenop(pt, pc));
468 2 : checkreg(pt, a+b-1);
469 2 : break;
470 : }
471 328 : default: break;
472 : }
473 : }
474 120 : return pt->code[last];
475 : }
476 :
477 : #undef check
478 : #undef checkjump
479 : #undef checkreg
480 :
481 : /* }====================================================== */
482 :
483 :
484 14 : int luaG_checkcode (const Proto *pt) {
485 14 : return (symbexec(pt, pt->sizecode, NO_REG) != 0);
486 : }
487 :
488 :
489 24 : static const char *kname (Proto *p, int c) {
490 24 : if (ISK(c) && ttisstring(&p->k[INDEXK(c)]))
491 24 : return svalue(&p->k[INDEXK(c)]);
492 : else
493 0 : return "?";
494 : }
495 :
496 :
497 118 : static const char *getobjname (lua_State *L, CallInfo *ci, int stackpos,
498 : const char **name) {
499 118 : if (isLua(ci)) { /* a Lua function? */
500 117 : Proto *p = ci_func(ci)->l.p;
501 117 : int pc = currentpc(L, ci);
502 : Instruction i;
503 117 : *name = luaF_getlocalname(p, stackpos+1, pc);
504 117 : if (*name) /* is a local? */
505 11 : return "local";
506 106 : i = symbexec(p, pc, stackpos); /* try symbolic execution */
507 : lua_assert(pc != -1);
508 106 : switch (GET_OPCODE(i)) {
509 20 : case OP_GETGLOBAL: {
510 20 : int g = GETARG_Bx(i); /* global index */
511 : lua_assert(ttisstring(&p->k[g]));
512 20 : *name = svalue(&p->k[g]);
513 20 : return "global";
514 : }
515 0 : case OP_MOVE: {
516 0 : int a = GETARG_A(i);
517 0 : int b = GETARG_B(i); /* move from `b' to `a' */
518 0 : if (b < a)
519 0 : return getobjname(L, ci, b, name); /* get name for `b' */
520 0 : break;
521 : }
522 22 : case OP_GETTABLE: {
523 22 : int k = GETARG_C(i); /* key index */
524 22 : *name = kname(p, k);
525 22 : return "field";
526 : }
527 41 : case OP_GETUPVAL: {
528 41 : int u = GETARG_B(i); /* upvalue index */
529 41 : *name = p->upvalues ? getstr(p->upvalues[u]) : "?";
530 41 : return "upvalue";
531 : }
532 2 : case OP_SELF: {
533 2 : int k = GETARG_C(i); /* key index */
534 2 : *name = kname(p, k);
535 2 : return "method";
536 : }
537 21 : default: break;
538 : }
539 : }
540 22 : return NULL; /* no useful name found */
541 : }
542 :
543 :
544 55 : static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
545 : Instruction i;
546 55 : if ((isLua(ci) && ci->tailcalls > 0) || !isLua(ci - 1))
547 11 : return NULL; /* calling function is not Lua (or is unknown) */
548 44 : ci--; /* calling function */
549 44 : i = ci_func(ci)->l.p->code[currentpc(L, ci)];
550 44 : if (GET_OPCODE(i) == OP_CALL || GET_OPCODE(i) == OP_TAILCALL ||
551 0 : GET_OPCODE(i) == OP_TFORLOOP)
552 44 : return getobjname(L, ci, GETARG_A(i), name);
553 : else
554 0 : return NULL; /* no useful name can be found */
555 : }
556 :
557 :
558 : /* only ANSI way to check whether a pointer points to an array */
559 110 : static int isinstack (CallInfo *ci, const TValue *o) {
560 : StkId p;
561 185 : for (p = ci->base; p < ci->top; p++)
562 149 : if (o == p) return 1;
563 36 : return 0;
564 : }
565 :
566 :
567 110 : void luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
568 110 : const char *name = NULL;
569 110 : const char *t = luaT_typenames[ttype(o)];
570 110 : const char *kind = (isinstack(L->ci, o)) ?
571 110 : getobjname(L, L->ci, cast_int(o - L->base), &name) :
572 : NULL;
573 110 : if (kind)
574 52 : luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)",
575 : op, kind, name, t);
576 : else
577 58 : luaG_runerror(L, "attempt to %s a %s value", op, t);
578 0 : }
579 :
580 :
581 9 : void luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
582 9 : if (ttisstring(p1) || ttisnumber(p1)) p1 = p2;
583 : lua_assert(!ttisstring(p1) && !ttisnumber(p1));
584 9 : luaG_typeerror(L, p1, "concatenate");
585 0 : }
586 :
587 :
588 78 : void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
589 : TValue temp;
590 78 : if (luaV_tonumber(p1, &temp) == NULL)
591 51 : p2 = p1; /* first operand is wrong */
592 78 : luaG_typeerror(L, p2, "perform arithmetic on");
593 0 : }
594 :
595 :
596 74 : int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
597 74 : const char *t1 = luaT_typenames[ttype(p1)];
598 74 : const char *t2 = luaT_typenames[ttype(p2)];
599 74 : if (t1[2] == t2[2])
600 28 : luaG_runerror(L, "attempt to compare two %s values", t1);
601 : else
602 46 : luaG_runerror(L, "attempt to compare %s with %s", t1, t2);
603 0 : return 0;
604 : }
605 :
606 :
607 192 : static void addinfo (lua_State *L, const char *msg) {
608 192 : CallInfo *ci = L->ci;
609 192 : if (isLua(ci)) { /* is Lua code? */
610 : char buff[LUA_IDSIZE]; /* add file:line information */
611 188 : int line = currentline(L, ci);
612 188 : luaO_chunkid(buff, getstr(getluaproto(ci)->source), LUA_IDSIZE);
613 188 : luaO_pushfstring(L, "%s:%d: %s", buff, line, msg);
614 : }
615 192 : }
616 :
617 :
618 337 : void luaG_errormsg (lua_State *L) {
619 337 : if (L->errfunc != 0) { /* is there an error handling function? */
620 7 : StkId errfunc = restorestack(L, L->errfunc);
621 7 : if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR);
622 6 : setobjs2s(L, L->top, L->top - 1); /* move argument */
623 6 : setobjs2s(L, L->top - 1, errfunc); /* push function */
624 6 : incr_top(L);
625 6 : luaD_call(L, L->top - 2, 1); /* call it */
626 : }
627 336 : luaD_throw(L, LUA_ERRRUN);
628 0 : }
629 :
630 :
631 192 : void luaG_runerror (lua_State *L, const char *fmt, ...) {
632 : va_list argp;
633 192 : va_start(argp, fmt);
634 192 : addinfo(L, luaO_pushvfstring(L, fmt, argp));
635 192 : va_end(argp);
636 192 : luaG_errormsg(L);
637 0 : }
638 :
|