diff options
Diffstat (limited to '')
| -rw-r--r-- | ldebug.c | 169 | ||||
| -rw-r--r-- | ldebug.h | 3 | ||||
| -rw-r--r-- | lparser.c | 4 |
3 files changed, 128 insertions, 48 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldebug.c,v 1.59 2001/02/02 15:13:05 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 1.60 2001/02/07 18:13:49 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 | */ |
| @@ -106,20 +106,20 @@ int luaG_getline (int *lineinfo, int pc, int refline, int *prefi) { | |||
| 106 | return -1; /* no line info or function is not active */ | 106 | return -1; /* no line info or function is not active */ |
| 107 | refi = prefi ? *prefi : 0; | 107 | refi = prefi ? *prefi : 0; |
| 108 | if (lineinfo[refi] < 0) | 108 | if (lineinfo[refi] < 0) |
| 109 | refline += -lineinfo[refi++]; | 109 | refline += -lineinfo[refi++]; |
| 110 | lua_assert(lineinfo[refi] >= 0); | 110 | lua_assert(lineinfo[refi] >= 0); |
| 111 | while (lineinfo[refi] > pc) { | 111 | while (lineinfo[refi] > pc) { |
| 112 | refline--; | 112 | refline--; |
| 113 | refi--; | 113 | refi--; |
| 114 | if (lineinfo[refi] < 0) | 114 | if (lineinfo[refi] < 0) |
| 115 | refline -= -lineinfo[refi--]; | 115 | refline -= -lineinfo[refi--]; |
| 116 | lua_assert(lineinfo[refi] >= 0); | 116 | lua_assert(lineinfo[refi] >= 0); |
| 117 | } | 117 | } |
| 118 | for (;;) { | 118 | for (;;) { |
| 119 | int nextline = refline + 1; | 119 | int nextline = refline + 1; |
| 120 | int nextref = refi + 1; | 120 | int nextref = refi + 1; |
| 121 | if (lineinfo[nextref] < 0) | 121 | if (lineinfo[nextref] < 0) |
| 122 | nextline += -lineinfo[nextref++]; | 122 | nextline += -lineinfo[nextref++]; |
| 123 | lua_assert(lineinfo[nextref] >= 0); | 123 | lua_assert(lineinfo[nextref] >= 0); |
| 124 | if (lineinfo[nextref] > pc) | 124 | if (lineinfo[nextref] > pc) |
| 125 | break; | 125 | break; |
| @@ -248,7 +248,7 @@ static const char *travglobals (lua_State *L, const TObject *o) { | |||
| 248 | int i; | 248 | int i; |
| 249 | for (i=0; i<g->size; i++) { | 249 | for (i=0; i<g->size; i++) { |
| 250 | if (luaO_equalObj(o, val(node(g, i))) && | 250 | if (luaO_equalObj(o, val(node(g, i))) && |
| 251 | ttype_key(node(g, i)) == LUA_TSTRING) | 251 | ttype_key(node(g, i)) == LUA_TSTRING) |
| 252 | return tsvalue_key(node(g, i))->str; | 252 | return tsvalue_key(node(g, i))->str; |
| 253 | } | 253 | } |
| 254 | return NULL; | 254 | return NULL; |
| @@ -321,12 +321,8 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { | |||
| 321 | */ | 321 | */ |
| 322 | 322 | ||
| 323 | 323 | ||
| 324 | static int pushpc (int *stack, int pc, int top, int n) { | 324 | #define check(x) if (!(x)) return 0; |
| 325 | while (n--) | 325 | #define checkjump(pt, pc) check(0 <= (pc) && (pc) < (pt)->sizecode) |
| 326 | stack[top++] = pc-1; | ||
| 327 | return top; | ||
| 328 | } | ||
| 329 | |||
| 330 | 326 | ||
| 331 | static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos) { | 327 | static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos) { |
| 332 | int stack[MAXSTACK]; /* stores last instruction that changed a stack entry */ | 328 | int stack[MAXSTACK]; /* stores last instruction that changed a stack entry */ |
| @@ -335,78 +331,159 @@ static Instruction luaG_symbexec (const Proto *pt, int lastpc, int stackpos) { | |||
| 335 | int pc = 0; | 331 | int pc = 0; |
| 336 | if (pt->is_vararg) /* varargs? */ | 332 | if (pt->is_vararg) /* varargs? */ |
| 337 | top++; /* `arg' */ | 333 | top++; /* `arg' */ |
| 334 | check (top <= pt->maxstacksize && pt->maxstacksize <= MAXSTACK); | ||
| 338 | while (pc < lastpc) { | 335 | while (pc < lastpc) { |
| 339 | const Instruction i = code[pc++]; | 336 | const Instruction i = code[pc++]; |
| 340 | lua_assert(0 <= top && top <= pt->maxstacksize); | 337 | OpCode op = GET_OPCODE(i); |
| 341 | switch (GET_OPCODE(i)) { | 338 | int push = (int)luaK_opproperties[op].push; |
| 339 | int pop = (int)luaK_opproperties[op].pop; | ||
| 340 | int arg1 = 0; | ||
| 341 | int arg2 = 0; | ||
| 342 | switch ((enum Mode)luaK_opproperties[op].mode) { | ||
| 343 | case iO: break; | ||
| 344 | case iU: arg1 = GETARG_U(i); break; | ||
| 345 | case iS: arg1 = GETARG_S(i); break; | ||
| 346 | case iAB: arg1 = GETARG_A(i); arg2 = GETARG_B(i); break; | ||
| 347 | } | ||
| 348 | check(0 <= top && top <= pt->maxstacksize); | ||
| 349 | switch (op) { | ||
| 342 | case OP_RETURN: { | 350 | case OP_RETURN: { |
| 343 | lua_assert(top >= GETARG_U(i)); | 351 | pop = top-arg1; |
| 344 | top = GETARG_U(i); | ||
| 345 | break; | 352 | break; |
| 346 | } | 353 | } |
| 347 | case OP_TAILCALL: { | 354 | case OP_CALL: { |
| 348 | lua_assert(top >= GETARG_A(i)); | 355 | if (arg2 == MULT_RET) arg2 = 1; |
| 349 | top = GETARG_B(i); | 356 | pop = top-arg1; |
| 357 | push = arg2; | ||
| 350 | break; | 358 | break; |
| 351 | } | 359 | } |
| 352 | case OP_CALL: { | 360 | case OP_TAILCALL: { |
| 353 | int nresults = GETARG_B(i); | 361 | check(arg1 <= top); |
| 354 | if (nresults == MULT_RET) nresults = 1; | 362 | pop = top-arg2; |
| 355 | lua_assert(top >= GETARG_A(i)); | ||
| 356 | top = pushpc(stack, pc, GETARG_A(i), nresults); | ||
| 357 | break; | 363 | break; |
| 358 | } | 364 | } |
| 359 | case OP_PUSHNIL: { | 365 | case OP_PUSHNIL: { |
| 360 | top = pushpc(stack, pc, top, GETARG_U(i)); | 366 | check(arg1 > 0); |
| 367 | push = arg1; | ||
| 361 | break; | 368 | break; |
| 362 | } | 369 | } |
| 363 | case OP_POP: { | 370 | case OP_POP: { |
| 364 | top -= GETARG_U(i); | 371 | pop = arg1; |
| 372 | break; | ||
| 373 | } | ||
| 374 | case OP_PUSHSTRING: | ||
| 375 | case OP_GETGLOBAL: | ||
| 376 | case OP_GETDOTTED: | ||
| 377 | case OP_PUSHSELF: | ||
| 378 | case OP_SETGLOBAL: { | ||
| 379 | check(arg1 < pt->sizekstr); | ||
| 380 | break; | ||
| 381 | } | ||
| 382 | case OP_PUSHNUM: | ||
| 383 | case OP_PUSHNEGNUM: { | ||
| 384 | check(arg1 < pt->sizeknum); | ||
| 385 | break; | ||
| 386 | } | ||
| 387 | case OP_PUSHUPVALUE: { | ||
| 388 | /* ?? */ | ||
| 389 | break; | ||
| 390 | } | ||
| 391 | case OP_GETLOCAL: | ||
| 392 | case OP_GETINDEXED: | ||
| 393 | case OP_SETLOCAL: { | ||
| 394 | check(arg1 < top); | ||
| 395 | break; | ||
| 396 | } | ||
| 397 | case OP_SETTABLE: { | ||
| 398 | check(2 <= arg1 && arg1 <= top); | ||
| 399 | pop = arg2; | ||
| 365 | break; | 400 | break; |
| 366 | } | 401 | } |
| 367 | case OP_SETTABLE: | ||
| 368 | case OP_SETLIST: { | 402 | case OP_SETLIST: { |
| 369 | top -= GETARG_B(i); | 403 | pop = arg2; |
| 404 | check(top-pop >= 1); /* there must be a table below the list */ | ||
| 370 | break; | 405 | break; |
| 371 | } | 406 | } |
| 372 | case OP_SETMAP: { | 407 | case OP_SETMAP: { |
| 373 | top -= 2*GETARG_U(i); | 408 | pop = 2*arg1; |
| 409 | check(top-pop >= 1); | ||
| 374 | break; | 410 | break; |
| 375 | } | 411 | } |
| 376 | case OP_CONCAT: { | 412 | case OP_CONCAT: { |
| 377 | top -= GETARG_U(i); | 413 | pop = arg1; |
| 378 | stack[top++] = pc-1; | ||
| 379 | break; | 414 | break; |
| 380 | } | 415 | } |
| 381 | case OP_CLOSURE: { | 416 | case OP_CLOSURE: { |
| 382 | top -= GETARG_B(i); | 417 | /* ?? */ |
| 383 | stack[top++] = pc-1; | 418 | pop = arg2; |
| 419 | break; | ||
| 420 | } | ||
| 421 | case OP_JMPNE: | ||
| 422 | case OP_JMPEQ: | ||
| 423 | case OP_JMPLT: | ||
| 424 | case OP_JMPLE: | ||
| 425 | case OP_JMPGT: | ||
| 426 | case OP_JMPGE: | ||
| 427 | case OP_JMPT: | ||
| 428 | case OP_JMPF: | ||
| 429 | case OP_JMP: | ||
| 430 | case OP_FORLOOP: | ||
| 431 | case OP_LFORLOOP: { | ||
| 432 | checkjump(pt, pc+arg1); | ||
| 433 | break; | ||
| 434 | } | ||
| 435 | case OP_PUSHNILJMP: { | ||
| 436 | checkjump(pt, pc+1); | ||
| 384 | break; | 437 | break; |
| 385 | } | 438 | } |
| 386 | case OP_JMPONT: | 439 | case OP_JMPONT: |
| 387 | case OP_JMPONF: { | 440 | case OP_JMPONF: { |
| 388 | int newpc = pc + GETARG_S(i); | 441 | int newpc = pc + arg1; |
| 389 | /* jump is forward and do not skip `lastpc'? */ | 442 | checkjump(pt, newpc); |
| 390 | if (pc < newpc && newpc <= lastpc) { | 443 | /* jump is forward and do not skip `lastpc' and not full check? */ |
| 444 | if (pc < newpc && newpc <= lastpc && stackpos >= 0) { | ||
| 391 | stack[top-1] = pc-1; /* value comes from `and'/`or' */ | 445 | stack[top-1] = pc-1; /* value comes from `and'/`or' */ |
| 392 | pc = newpc; /* do the jump */ | 446 | pc = newpc; /* do the jump */ |
| 447 | pop = 0; /* do not pop */ | ||
| 393 | } | 448 | } |
| 394 | else | ||
| 395 | top--; /* do not jump; pop value */ | ||
| 396 | break; | 449 | break; |
| 397 | } | 450 | } |
| 398 | default: { | 451 | case OP_FORPREP: { |
| 399 | OpCode op = GET_OPCODE(i); | 452 | check(top >= 3); |
| 400 | int push = (int)luaK_opproperties[op].push; | 453 | checkjump(pt, pc-arg1); /* jump is `negative' here */ |
| 401 | int pop = (int)luaK_opproperties[op].pop; | 454 | break; |
| 402 | lua_assert(push != VD && pop != VD); | 455 | } |
| 403 | lua_assert(0 <= top-pop && top+push <= pt->maxstacksize); | 456 | case OP_LFORPREP: { |
| 404 | top -= pop; | 457 | check(top >= 1); |
| 405 | top = pushpc(stack, pc, top, push); | 458 | checkjump(pt, pc-arg1); /* jump is `negative' here */ |
| 459 | break; | ||
| 460 | } | ||
| 461 | case OP_PUSHINT: | ||
| 462 | case OP_GETTABLE: | ||
| 463 | case OP_CREATETABLE: | ||
| 464 | case OP_ADD: | ||
| 465 | case OP_ADDI: | ||
| 466 | case OP_SUB: | ||
| 467 | case OP_MULT: | ||
| 468 | case OP_DIV: | ||
| 469 | case OP_POW: | ||
| 470 | case OP_MINUS: | ||
| 471 | case OP_NOT: { | ||
| 472 | break; | ||
| 406 | } | 473 | } |
| 407 | } | 474 | } |
| 475 | check(0 <= pop && 0 <= push); | ||
| 476 | check(0 <= top-pop && top+(push-pop) <= pt->maxstacksize); | ||
| 477 | top -= pop; | ||
| 478 | while (push--) stack[top++] = pc-1; | ||
| 408 | } | 479 | } |
| 409 | return code[stack[stackpos]]; | 480 | check(GET_OPCODE(code[pt->sizecode-1]) == OP_RETURN); |
| 481 | return (stackpos >= 0) ? code[stack[stackpos]] : 1; | ||
| 482 | } | ||
| 483 | |||
| 484 | |||
| 485 | int luaG_checkcode (const Proto *pt) { | ||
| 486 | return luaG_symbexec(pt, pt->sizecode-1, -1); | ||
| 410 | } | 487 | } |
| 411 | 488 | ||
| 412 | 489 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldebug.h,v 1.7 2000/10/05 12:14:08 roberto Exp roberto $ | 2 | ** $Id: ldebug.h,v 1.8 2001/02/07 18:13:49 roberto Exp roberto $ |
| 3 | ** Auxiliary functions from Debug Interface module | 3 | ** Auxiliary functions from Debug Interface module |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -16,6 +16,7 @@ void luaG_typeerror (lua_State *L, StkId o, const char *op); | |||
| 16 | void luaG_binerror (lua_State *L, StkId p1, int t, const char *op); | 16 | void luaG_binerror (lua_State *L, StkId p1, int t, const char *op); |
| 17 | int luaG_getline (int *lineinfo, int pc, int refline, int *refi); | 17 | int luaG_getline (int *lineinfo, int pc, int refline, int *refi); |
| 18 | void luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2); | 18 | void luaG_ordererror (lua_State *L, const TObject *p1, const TObject *p2); |
| 19 | int luaG_checkcode (const Proto *pt); | ||
| 19 | 20 | ||
| 20 | 21 | ||
| 21 | #endif | 22 | #endif |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lparser.c,v 1.129 2001/02/05 17:48:52 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.130 2001/02/08 11:19:10 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 | */ |
| @@ -11,6 +11,7 @@ | |||
| 11 | #include "lua.h" | 11 | #include "lua.h" |
| 12 | 12 | ||
| 13 | #include "lcode.h" | 13 | #include "lcode.h" |
| 14 | #include "ldebug.h" | ||
| 14 | #include "lfunc.h" | 15 | #include "lfunc.h" |
| 15 | #include "llex.h" | 16 | #include "llex.h" |
| 16 | #include "lmem.h" | 17 | #include "lmem.h" |
| @@ -351,6 +352,7 @@ static void close_func (LexState *ls) { | |||
| 351 | luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->nlineinfo+1, int); | 352 | luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->nlineinfo+1, int); |
| 352 | f->lineinfo[fs->nlineinfo++] = MAX_INT; /* end flag */ | 353 | f->lineinfo[fs->nlineinfo++] = MAX_INT; /* end flag */ |
| 353 | f->sizelineinfo = fs->nlineinfo; | 354 | f->sizelineinfo = fs->nlineinfo; |
| 355 | lua_assert(luaG_checkcode(f)); | ||
| 354 | ls->fs = fs->prev; | 356 | ls->fs = fs->prev; |
| 355 | lua_assert(fs->bl == NULL); | 357 | lua_assert(fs->bl == NULL); |
| 356 | } | 358 | } |
