diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2013-07-10 17:32:36 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2013-07-10 17:32:36 -0300 |
| commit | 98d76cdcae713851872fa9ae1e76fcc09298d824 (patch) | |
| tree | bf4cb7e86772d0e22410aa30143e455fb2342436 | |
| parent | 2f8c51a5529686959c6f6c5a8e899127b16c345d (diff) | |
| download | lua-98d76cdcae713851872fa9ae1e76fcc09298d824.tar.gz lua-98d76cdcae713851872fa9ae1e76fcc09298d824.tar.bz2 lua-98d76cdcae713851872fa9ae1e76fcc09298d824.zip | |
bug: Wrong error message in some short-cut expressions
| -rw-r--r-- | ldebug.c | 30 |
1 files changed, 19 insertions, 11 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ldebug.c,v 2.94 2013/04/29 16:58:10 roberto Exp roberto $ | 2 | ** $Id: ldebug.c,v 2.95 2013/05/06 17:21:59 roberto Exp $ |
| 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 | ||
| 330 | static 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 | */ |
| 333 | static int findsetreg (Proto *p, int lastpc, int reg) { | 340 | static 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,33 @@ 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) |
| 362 | break; | 372 | jmptarget = dest; /* update 'jmptarget' */ |
| 363 | } | 373 | } |
| 364 | case OP_TEST: { | ||
| 365 | if (reg == a) setreg = pc; /* jumped code can change 'a' */ | ||
| 366 | break; | 374 | break; |
| 367 | } | 375 | } |
| 368 | default: | 376 | default: |
| 369 | if (testAMode(op) && reg == a) /* any instruction that set A */ | 377 | if (testAMode(op) && reg == a) /* any instruction that set A */ |
| 370 | setreg = pc; | 378 | setreg = filterpc(pc, jmptarget); |
| 371 | break; | 379 | break; |
| 372 | } | 380 | } |
| 373 | } | 381 | } |
