summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ldebug.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/ldebug.c b/ldebug.c
index 92374d50..a585075c 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ldebug.c,v 2.90.1.1 2013/04/12 18:48:47 roberto Exp roberto $ 2** $Id: ldebug.c,v 2.90.1.2 2013/05/06 17:20:22 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*/
@@ -327,12 +327,20 @@ static void kname (Proto *p, int pc, int c, const char **name) {
327} 327}
328 328
329 329
330static int filterpc (int pc, int jmptarget) {
331 if (pc < jmptarget) /* is code conditional (inside a jump)? */
332 return -1; /* cannot know who sets that register */
333 else return pc; /* current position sets that register */
334}
335
336
330/* 337/*
331** try to find last instruction before 'lastpc' that modified register 'reg' 338** try to find last instruction before 'lastpc' that modified register 'reg'
332*/ 339*/
333static int findsetreg (Proto *p, int lastpc, int reg) { 340static int findsetreg (Proto *p, int lastpc, int reg) {
334 int pc; 341 int pc;
335 int setreg = -1; /* keep last instruction that changed 'reg' */ 342 int setreg = -1; /* keep last instruction that changed 'reg' */
343 int jmptarget = 0; /* any code before this address is conditional */
336 for (pc = 0; pc < lastpc; pc++) { 344 for (pc = 0; pc < lastpc; pc++) {
337 Instruction i = p->code[pc]; 345 Instruction i = p->code[pc];
338 OpCode op = GET_OPCODE(i); 346 OpCode op = GET_OPCODE(i);
@@ -341,33 +349,38 @@ static int findsetreg (Proto *p, int lastpc, int reg) {
341 case OP_LOADNIL: { 349 case OP_LOADNIL: {
342 int b = GETARG_B(i); 350 int b = GETARG_B(i);
343 if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */ 351 if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */
344 setreg = pc; 352 setreg = filterpc(pc, jmptarget);
345 break; 353 break;
346 } 354 }
347 case OP_TFORCALL: { 355 case OP_TFORCALL: {
348 if (reg >= a + 2) setreg = pc; /* affect all regs above its base */ 356 if (reg >= a + 2) /* affect all regs above its base */
357 setreg = filterpc(pc, jmptarget);
349 break; 358 break;
350 } 359 }
351 case OP_CALL: 360 case OP_CALL:
352 case OP_TAILCALL: { 361 case OP_TAILCALL: {
353 if (reg >= a) setreg = pc; /* affect all registers above base */ 362 if (reg >= a) /* affect all registers above base */
363 setreg = filterpc(pc, jmptarget);
354 break; 364 break;
355 } 365 }
356 case OP_JMP: { 366 case OP_JMP: {
357 int b = GETARG_sBx(i); 367 int b = GETARG_sBx(i);
358 int dest = pc + 1 + b; 368 int dest = pc + 1 + b;
359 /* jump is forward and do not skip `lastpc'? */ 369 /* jump is forward and do not skip `lastpc'? */
360 if (pc < dest && dest <= lastpc) 370 if (pc < dest && dest <= lastpc) {
361 pc += b; /* do the jump */ 371 if (dest > jmptarget)
372 jmptarget = dest; /* update 'jmptarget' */
373 }
362 break; 374 break;
363 } 375 }
364 case OP_TEST: { 376 case OP_TEST: {
365 if (reg == a) setreg = pc; /* jumped code can change 'a' */ 377 if (reg == a) /* jumped code can change 'a' */
378 setreg = filterpc(pc, jmptarget);
366 break; 379 break;
367 } 380 }
368 default: 381 default:
369 if (testAMode(op) && reg == a) /* any instruction that set A */ 382 if (testAMode(op) && reg == a) /* any instruction that set A */
370 setreg = pc; 383 setreg = filterpc(pc, jmptarget);
371 break; 384 break;
372 } 385 }
373 } 386 }