|
I have produced a very small patch which only makes adjustments in lvm.c to the OP_FORLOOP and OP_FORPREP opcodes to solve the issue of the edge case where math.maxinteger or math.mininteger are used, or where the sign bit overflowed. Now the following test cases all correctly work and no assertions are thrown: local reps = 0 for i = math.mininteger, math.mininteger, -1 do reps = reps + 1 end assert(reps == 1) reps = 0 for i = math.maxinteger, math.maxinteger do reps = reps + 1 end assert(reps == 1) reps = 0 for i = 0x7FFFFFFFFFFFFFF8,0x7FFFFFFFFFFFFFFF do reps = reps + 1 end assert(reps == 8) reps = 0 for i = 0x7FFFFFFFFFFFFFFF,0x7FFFFFFFFFFFFFF8,-1 do reps = reps + 1 end assert(reps == 8) Also, the Lua test suite runs correctly with one small modification in db.lua, attached as test.patch along with loopfix.patch. My patch makes two small changes; First, to prevent the overflow edge cases from triggering the initial loop value is left unaltered and instead the step value is subtracted from the loop limit variable. Second, the determination if the loop should be run at least once or not now happens in OP_FORPREP, if the loop is not to be run the entire loop body is skipped... otherwise, the loop body will always execute first before the OP_FORLOOP opcode for the loop is encountered. These two changes fix all the recently described edge cases with for loops so far as I can tell, as well as remaining compatible with all tests in the Lua test suite. Please let me know if I have overlooked something with how this code performs, thanks! ~Paige
Attachment:
loopfix.patch
Description: Binary data
Attachment:
test.diff
Description: Binary data