diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-02-09 16:37:33 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-02-09 16:37:33 -0200 |
commit | c81404cae57e40d0fa5dd1eb48237ca7e77c4d89 (patch) | |
tree | 368a1ab4b5a27b5fbc5c8137d28586ea605ac97b /ldebug.c | |
parent | b6ce59043396110b95de4d772b4541d65661f62e (diff) | |
download | lua-c81404cae57e40d0fa5dd1eb48237ca7e77c4d89.tar.gz lua-c81404cae57e40d0fa5dd1eb48237ca7e77c4d89.tar.bz2 lua-c81404cae57e40d0fa5dd1eb48237ca7e77c4d89.zip |
first version of code verification
Diffstat (limited to 'ldebug.c')
-rw-r--r-- | ldebug.c | 169 |
1 files changed, 123 insertions, 46 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 | ||