aboutsummaryrefslogtreecommitdiff
path: root/ldebug.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldebug.c')
-rw-r--r--ldebug.c360
1 files changed, 195 insertions, 165 deletions
diff --git a/ldebug.c b/ldebug.c
index f8369d2d..9cb65a1f 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 1.75 2001/03/26 14:31:49 roberto Exp roberto $ 2** $Id: ldebug.c,v 1.76 2001/04/06 18:25:00 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*/
@@ -22,6 +22,7 @@
22#include "ltable.h" 22#include "ltable.h"
23#include "ltm.h" 23#include "ltm.h"
24#include "luadebug.h" 24#include "luadebug.h"
25#include "lvm.h"
25 26
26 27
27 28
@@ -298,6 +299,10 @@ LUA_API int lua_getinfo (lua_State *L, const l_char *what, lua_Debug *ar) {
298 299
299#define check(x) if (!(x)) return 0; 300#define check(x) if (!(x)) return 0;
300 301
302#define checkjump(pt,pc) check(0 <= pc && pc < pt->sizecode)
303
304#define checkreg(pt,reg) check((reg) < (pt)->maxstacksize)
305
301 306
302static int checklineinfo (const Proto *pt) { 307static int checklineinfo (const Proto *pt) {
303 int *lineinfo = pt->lineinfo; 308 int *lineinfo = pt->lineinfo;
@@ -318,231 +323,199 @@ static int precheck (const Proto *pt) {
318} 323}
319 324
320 325
321/* value for non-initialized entries in array stacklevel */ 326static int checkopenop (Instruction i) {
322#define SL_EMPTY 255 327 OpCode op = GET_OPCODE(i);
323 328 switch (op) {
324#define checkjump(pt,sl,top,pc) if (!checkjump_aux(pt,sl,top,pc)) return 0; 329 case OP_CALL:
325 330 case OP_RETURN: {
326static int checkjump_aux (const Proto *pt, lu_byte *sl, int top, int pc) { 331 check(GETARG_B(i) == NO_REG);
327 check(0 <= pc && pc < pt->sizecode); 332 return 1;
328 if (sl == NULL) return 1; /* not full checking */ 333 }
329 if (sl[pc] == SL_EMPTY) 334 case OP_SETLISTO: return 1;
330 sl[pc] = (lu_byte)top; 335 default: return 0; /* invalid instruction after an open call */
331 else 336 }
332 check(sl[pc] == top);
333 return 1;
334} 337}
335 338
336 339
337static Instruction luaG_symbexec (lua_State *L, const Proto *pt, 340static Instruction luaG_symbexec (const Proto *pt, int lastpc, int reg) {
338 int lastpc, int stackpos) {
339 int stack[MAXSTACK]; /* stores last instruction that changed a stack entry */
340 lu_byte *sl = NULL;
341 int top;
342 int pc; 341 int pc;
343 if (stackpos < 0) { /* full check? */ 342 int last; /* stores position of last instruction that changed `reg' */
344 int i; 343 last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */
345 sl = luaO_openspace(L, pt->sizecode, lu_byte); 344 if (reg == NO_REG) /* full check? */
346 for (i=0; i<pt->sizecode; i++) /* initialize stack-level array */
347 sl[i] = SL_EMPTY;
348 check(precheck(pt)); 345 check(precheck(pt));
349 } 346 for (pc = 0; pc < lastpc; pc++) {
350 top = pt->numparams; 347 const Instruction i = pt->code[pc];
351 pc = 0;
352 if (pt->is_vararg) /* varargs? */
353 top++; /* `arg' */
354 if (sl) sl[0] = (lu_byte)top;
355 while (pc < lastpc) {
356 const Instruction i = pt->code[pc++];
357 OpCode op = GET_OPCODE(i); 348 OpCode op = GET_OPCODE(i);
358 int arg1 = 0; 349 int a = GETARG_A(i);
359 int arg2 = 0; 350 int b = 0;
360 int push, pop; 351 int c = 0;
361 check(op < NUM_OPCODES); 352#undef check
362 push = (int)luaK_opproperties[op].push; 353#define check(x) if (!(x)) { \
363 pop = (int)luaK_opproperties[op].pop; 354printf(">>>%d %d %d %d %d %d\n", op, a, b, c, pt->maxstacksize, pt->sizek); \
364 switch ((enum Mode)luaK_opproperties[op].mode) { 355return 0; }
365 case iO: break; 356 switch (getOpMode(op)) {
366 case iU: arg1 = GETARG_U(i); check(arg1 >= 0); break; 357 case iABC: {
367 case iS: arg1 = GETARG_S(i); break; 358 b = GETARG_B(i);
368 case iAB: 359 c = GETARG_C(i);
369 arg1 = GETARG_A(i); arg2 = GETARG_B(i); check(arg1 >= 0); break; 360 if (testOpMode(op, OpModeBreg)) {
370 } 361 checkreg(pt, b);
371 switch (op) { 362 check(c < pt->maxstacksize ||
372 case OP_RETURN: { 363 (c >= MAXSTACK && c-MAXSTACK < pt->sizek));
373 check(arg1 <= top); 364 }
374 pop = top-arg1;
375 break; 365 break;
376 } 366 }
377 case OP_CALL: { 367 case iABc: {
378 if (arg2 == MULT_RET) arg2 = 1; 368 b = GETARG_Bc(i);
379 check(arg1 < top); 369 if (testOpMode(op, OpModeK)) check(b < pt->sizek);
380 pop = top-arg1;
381 push = arg2;
382 break; 370 break;
383 } 371 }
384 case OP_PUSHNIL: { 372 case iAsBc: {
385 check(arg1 > 0); 373 b = GETARG_sBc(i);
386 push = arg1;
387 break; 374 break;
388 } 375 }
389 case OP_POP: { 376 }
390 pop = arg1; 377 if (testOpMode(op, OpModeAreg)) checkreg(pt, a);
378 if (testOpMode(op, OpModesetA)) {
379 if (a == reg) last = pc; /* change register `a' */
380 }
381 if (testOpMode(op, OpModeT))
382 check(GET_OPCODE(pt->code[pc+1]) == OP_CJMP);
383 switch (op) {
384 case OP_LOADNIL: {
385 if (a <= reg && reg <= b)
386 last = pc; /* set registers from `a' to `b' */
391 break; 387 break;
392 } 388 }
393 case OP_PUSHSTRING: 389 case OP_LOADUPVAL: {
394 case OP_GETGLOBAL: 390 check(b < pt->nupvalues);
395 case OP_GETDOTTED:
396 case OP_PUSHSELF:
397 case OP_SETGLOBAL: {
398 check(arg1 < pt->sizekstr);
399 break; 391 break;
400 } 392 }
401 case OP_PUSHNUM: 393 case OP_GETGLOBAL:
402 case OP_PUSHNEGNUM: { 394 case OP_SETGLOBAL: {
403 check(arg1 < pt->sizeknum); 395 check(ttype(&pt->k[b]) == LUA_TSTRING);
404 break; 396 break;
405 } 397 }
406 case OP_PUSHUPVALUE: { 398 case OP_SELF: {
407 check(arg1 < pt->nupvalues); 399 checkreg(pt, a+1);
400 if (reg == a+1) last = pc;
408 break; 401 break;
409 } 402 }
410 case OP_GETLOCAL: 403 case OP_CONCAT: {
411 case OP_GETINDEXED: 404 check(b < c); /* at least two operands */
412 case OP_SETLOCAL: {
413 check(arg1 < top);
414 break; 405 break;
415 } 406 }
416 case OP_SETTABLE: { 407 case OP_JMP:
417 check(3 <= arg1 && arg1 <= top); 408 case OP_CJMP: {
418 pop = arg2; 409 int dest = pc+1+b;
410 check(0 <= dest && dest < pt->sizecode);
411 /* not full check and jump is forward and do not skip `lastpc'? */
412 if (reg != NO_REG && pc < dest && dest <= lastpc)
413 pc += b; /* do the jump */
419 break; 414 break;
420 } 415 }
421 case OP_SETLIST: { 416 case OP_TESTT:
422 check(arg2 >= 0); 417 case OP_TESTF: {
423 pop = top-arg2-1; 418 if (a != NO_REG)
419 checkreg(pt, a);
424 break; 420 break;
425 } 421 }
426 case OP_SETMAP: { 422 case OP_NILJMP: {
427 check(arg1 >= 0); 423 check(pc+2 < pt->sizecode); /* check its jump */
428 pop = top-arg1-1;
429 break; 424 break;
430 } 425 }
431 case OP_CONCAT: { 426 case OP_CALL: {
432 pop = arg1; 427 if (b == NO_REG) b = pt->maxstacksize;
428 if (c == NO_REG) {
429 check(checkopenop(pt->code[pc+1]));
430 c = 1;
431 }
432 check(b > a);
433 checkreg(pt, b-1);
434 checkreg(pt, a+c-1);
435 if (reg >= a) last = pc; /* affect all registers above base */
433 break; 436 break;
434 } 437 }
435 case OP_CLOSURE: { 438 case OP_RETURN: {
436 check(arg1 < pt->sizekproto); 439 if (b == NO_REG) b = pt->maxstacksize;
437 check(arg2 == pt->kproto[arg1]->nupvalues); 440 checkreg(pt, b-1);
438 pop = arg2;
439 break; 441 break;
440 } 442 }
441 case OP_JMPNE: 443 case OP_FORPREP:
442 case OP_JMPEQ: 444 case OP_TFORPREP: {
443 case OP_JMPLT: 445 int dest = pc-b; /* jump is negated here */
444 case OP_JMPLE: 446 check(0 <= dest && dest < pt->sizecode &&
445 case OP_JMPGT: 447 GET_OPCODE(pt->code[dest]) == op+1);
446 case OP_JMPGE:
447 case OP_JMPT:
448 case OP_JMPF:
449 case OP_JMP: {
450 checkjump(pt, sl, top-pop, pc+arg1);
451 break; 448 break;
452 } 449 }
453 case OP_FORLOOP: 450 case OP_FORLOOP:
454 case OP_LFORLOOP: 451 case OP_TFORLOOP: {
455 case OP_JMPONT: 452 int dest = pc+b;
456 case OP_JMPONF: { 453 check(0 <= dest && dest < pt->sizecode &&
457 int newpc = pc+arg1; 454 pt->code[dest] == SET_OPCODE(i, op-1));
458 checkjump(pt, sl, top, newpc); 455 checkreg(pt, a + ((op == OP_FORLOOP) ? 2 : 3));
459 /* jump is forward and do not skip `lastpc' and not full check? */
460 if (pc < newpc && newpc <= lastpc && stackpos >= 0) {
461 stack[top-1] = pc-1; /* value comes from `and'/`or' */
462 pc = newpc; /* do the jump */
463 pop = 0; /* do not pop */
464 }
465 break;
466 }
467 case OP_PUSHNILJMP: {
468 check(GET_OPCODE(pt->code[pc]) == OP_PUSHINT); /* only valid sequence */
469 break; 456 break;
470 } 457 }
471 case OP_FORPREP: { 458 case OP_SETLIST: {
472 int endfor = pc-arg1-1; /* jump is `negative' here */ 459 checkreg(pt, a + (b&(LFIELDS_PER_FLUSH-1)) + 1);
473 check(top >= 3);
474 checkjump(pt, sl, top+push, endfor);
475 check(GET_OPCODE(pt->code[endfor]) == OP_FORLOOP);
476 check(GETARG_S(pt->code[endfor]) == arg1);
477 break;
478 }
479 case OP_LFORPREP: {
480 int endfor = pc-arg1-1; /* jump is `negative' here */
481 check(top >= 1);
482 checkjump(pt, sl, top+push, endfor);
483 check(GET_OPCODE(pt->code[endfor]) == OP_LFORLOOP);
484 check(GETARG_S(pt->code[endfor]) == arg1);
485 break; 460 break;
486 } 461 }
487 case OP_PUSHINT: 462 case OP_CLOSURE: {
488 case OP_GETTABLE: 463 check(b < pt->sizekproto);
489 case OP_CREATETABLE: 464 checkreg(pt, a + pt->kproto[b]->nupvalues - 1);
490 case OP_ADD:
491 case OP_ADDI:
492 case OP_SUB:
493 case OP_MULT:
494 case OP_DIV:
495 case OP_POW:
496 case OP_MINUS:
497 case OP_NOT: {
498 break; 465 break;
499 } 466 }
467 default: break;
500 } 468 }
501 top -= pop;
502 check(0 <= top && top+push <= pt->maxstacksize);
503 while (push--) stack[top++] = pc-1;
504 checkjump(pt, sl, top, pc);
505 } 469 }
506 return (stackpos >= 0) ? pt->code[stack[stackpos]] : 1; 470 return pt->code[last];
507} 471}
508 472
509/* }====================================================== */ 473/* }====================================================== */
510 474
511 475
512int luaG_checkcode (lua_State *L, const Proto *pt) { 476int luaG_checkcode (const Proto *pt) {
513 return luaG_symbexec(L, pt, pt->sizecode-1, -1); 477 return luaG_symbexec(pt, pt->sizecode, NO_REG);
514} 478}
515 479
516 480
517static const l_char *getobjname (lua_State *L, StkId obj, const l_char **name) { 481static const l_char *getobjname (lua_State *L, StkId obj, const l_char **name) {
518 CallInfo *ci = ci_stack(L, obj); 482 CallInfo *ci = ci_stack(L, obj);
519 if (!isLmark(ci)) 483 if (isLmark(ci)) { /* an active Lua function? */
520 return NULL; /* not an active Lua function */
521 else {
522 Proto *p = ci_func(ci)->f.l; 484 Proto *p = ci_func(ci)->f.l;
523 int pc = currentpc(ci); 485 int pc = currentpc(ci);
524 int stackpos = obj - ci->base; 486 int stackpos = obj - ci->base;
525 Instruction i = luaG_symbexec(L, p, pc, stackpos); 487 Instruction i;
488 *name = luaF_getlocalname(p, stackpos+1, pc);
489 if (*name) /* is a local? */
490 return l_s("local");
491 i = luaG_symbexec(p, pc, stackpos); /* try symbolic execution */
526 lua_assert(pc != -1); 492 lua_assert(pc != -1);
527 switch (GET_OPCODE(i)) { 493 switch (GET_OPCODE(i)) {
528 case OP_GETGLOBAL: { 494 case OP_GETGLOBAL: {
529 *name = getstr(p->kstr[GETARG_U(i)]); 495 lua_assert(ttype(&p->k[GETARG_Bc(i)]) == LUA_TSTRING);
496 *name = getstr(tsvalue(&p->k[GETARG_Bc(i)]));
530 return l_s("global"); 497 return l_s("global");
531 } 498 }
532 case OP_GETLOCAL: { 499 case OP_MOVE: {
533 *name = luaF_getlocalname(p, GETARG_U(i)+1, pc); 500 int a = GETARG_A(i);
534 lua_assert(*name); 501 int b = GETARG_B(i); /* move from `b' to `a' */
535 return l_s("local"); 502 if (b < a)
503 return getobjname(L, ci->base+b, name); /* get name for `b' */
504 break;
536 } 505 }
537 case OP_PUSHSELF: 506 case OP_GETTABLE:
538 case OP_GETDOTTED: { 507 case OP_SELF: {
539 *name = getstr(p->kstr[GETARG_U(i)]); 508 int c = GETARG_C(i) - MAXSTACK;
540 return l_s("field"); 509 if (c >= 0 && ttype(&p->k[c]) == LUA_TSTRING) {
510 *name = getstr(tsvalue(&p->k[c]));
511 return l_s("field");
512 }
513 break;
541 } 514 }
542 default: 515 default: break;
543 return NULL; /* no useful name found */
544 } 516 }
545 } 517 }
518 return NULL; /* no useful name found */
546} 519}
547 520
548 521
@@ -576,10 +549,18 @@ void luaG_typeerror (lua_State *L, StkId o, const l_char *op) {
576} 549}
577 550
578 551
579void luaG_binerror (lua_State *L, StkId p1, int t, const l_char *op) { 552void luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
580 if (ttype(p1) == t) p1++; 553 if (ttype(p1) == LUA_TSTRING) p1 = p2;
581 lua_assert(ttype(p1) != t); 554 lua_assert(ttype(p1) != LUA_TSTRING);
582 luaG_typeerror(L, p1, op); 555 luaG_typeerror(L, p1, l_s("concat"));
556}
557
558
559void luaG_aritherror (lua_State *L, StkId p1, TObject *p2) {
560 TObject temp;
561 if (luaV_tonumber(p1, &temp) != NULL)
562 p1 = p2; /* first operand is OK; error is in the second */
563 luaG_typeerror(L, p1, l_s("perform arithmetic on"));
583} 564}
584 565
585 566
@@ -592,3 +573,52 @@ void luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2) {
592 luaO_verror(L, l_s("attempt to compare %.10s with %.10s"), t1, t2); 573 luaO_verror(L, l_s("attempt to compare %.10s with %.10s"), t1, t2);
593} 574}
594 575
576
577
578#define opmode(t,a,b,c,sa,k,m) (((t)<<OpModeT) | \
579 ((a)<<OpModeAreg) | ((b)<<OpModeBreg) | ((c)<<OpModeCreg) | \
580 ((sa)<<OpModesetA) | ((k)<<OpModeK) | (m))
581
582
583const unsigned char luaG_opmodes[] = {
584/* T A B C sA K mode opcode */
585 opmode(0,1,1,0, 1,0,iABC), /* OP_MOVE */
586 opmode(0,1,0,0, 1,1,iABc), /* OP_LOADK */
587 opmode(0,1,0,0, 1,0,iAsBc), /* OP_LOADINT */
588 opmode(0,1,1,0, 1,0,iABC), /* OP_LOADNIL */
589 opmode(0,1,0,0, 1,0,iABc), /* OP_LOADUPVAL */
590 opmode(0,1,0,0, 1,1,iABc), /* OP_GETGLOBAL */
591 opmode(0,1,1,1, 1,0,iABC), /* OP_GETTABLE */
592 opmode(0,1,0,0, 0,1,iABc), /* OP_SETGLOBAL */
593 opmode(0,1,1,1, 0,0,iABC), /* OP_SETTABLE */
594 opmode(0,1,0,0, 1,0,iABc), /* OP_NEWTABLE */
595 opmode(0,1,1,1, 1,0,iABC), /* OP_SELF */
596 opmode(0,1,1,1, 1,0,iABC), /* OP_ADD */
597 opmode(0,1,1,1, 1,0,iABC), /* OP_SUB */
598 opmode(0,1,1,1, 1,0,iABC), /* OP_MUL */
599 opmode(0,1,1,1, 1,0,iABC), /* OP_DIV */
600 opmode(0,1,1,1, 1,0,iABC), /* OP_POW */
601 opmode(0,1,1,0, 1,0,iABC), /* OP_UNM */
602 opmode(0,1,1,0, 1,0,iABC), /* OP_NOT */
603 opmode(0,1,1,1, 1,0,iABC), /* OP_CONCAT */
604 opmode(0,0,0,0, 0,0,iAsBc), /* OP_JMP */
605 opmode(0,0,0,0, 0,0,iAsBc), /* OP_CJMP */
606 opmode(1,0,1,1, 0,0,iABC), /* OP_TESTEQ */
607 opmode(1,0,1,1, 0,0,iABC), /* OP_TESTNE */
608 opmode(1,0,1,1, 0,0,iABC), /* OP_TESTLT */
609 opmode(1,0,1,1, 0,0,iABC), /* OP_TESTLE */
610 opmode(1,0,1,1, 0,0,iABC), /* OP_TESTGT */
611 opmode(1,0,1,1, 0,0,iABC), /* OP_TESTGE */
612 opmode(1,0,1,0, 1,0,iABC), /* OP_TESTT */
613 opmode(1,0,1,0, 1,0,iABC), /* OP_TESTF */
614 opmode(0,1,0,0, 1,0,iAsBc), /* OP_NILJMP */
615 opmode(0,1,0,0, 0,0,iABC), /* OP_CALL */
616 opmode(0,1,0,0, 0,0,iABC), /* OP_RETURN */
617 opmode(0,1,0,0, 0,0,iAsBc), /* OP_FORPREP */
618 opmode(0,1,0,0, 0,0,iAsBc), /* OP_FORLOOP */
619 opmode(0,1,0,0, 0,0,iAsBc), /* OP_TFORPREP */
620 opmode(0,1,0,0, 0,0,iAsBc), /* OP_TFORLOOP */
621 opmode(0,1,0,0, 0,0,iABc), /* OP_SETLIST */
622 opmode(0,1,0,0, 0,0,iABc), /* OP_SETLIST0 */
623 opmode(0,1,0,0, 0,0,iABc) /* OP_CLOSURE */
624};