google-code-export / asdec

Automatically exported from code.google.com/p/asdec
1 stars 0 forks source link

Do-While and while loops inside if #21

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Hi. I found recently a little error, which causes asdec to fail.
The problem is in the block where asdec analyses if - jump instructions.

Flex source code.

public function testDoWhile():void{
    var i:int = 0;
    var test:Boolean = false;
    if (test)
    {
    do
        {
        if (i++ > 0)
        break;

        }while(true);
    }
}

public function testWhile():void{
    var i:int = 0;
    var test:Boolean = false;
    if (test)
    {
        while(true){
if (i++ > 0)
    break;
        }       
    }
}

If current instruction is IfTypeIns and it points on instruction that is 
preceeded by JumpIns, then asdec tries to find out if it is return block or 
part of some loop or 'else' block.

//AVM2Code.java line 1537
if (code.get(targetIns - 1).definition instanceof JumpIns) {

   if ((targetIns - 2 > ip) && ((code.get(targetIns - 2).definition instanceof ReturnValueIns) || (code.get(targetIns - 2).definition instanceof ReturnVoidIns) || (code.get(targetIns - 2).definition instanceof ThrowIns))) {
      hasElse = false;
      hasReturn = true;
   } else {
      int jumpAddr = targetAddr + code.get(targetIns - 1).operands[0];
      int jumpPos = adr2pos(jumpAddr);
      hasElse = true;

      for (Loop l : loopList) {
         if (l.loopBreak == jumpPos) {
            hasElse = false;
            break;
         }
      }
      if (hasElse) {
         if (adr2pos(jumpAddr) > end + 1) {
            hasElse = false;
            //throw new ConvertException("Unknown pattern: forward jump outside of the block");
         }
      }
   }
}
...

At this point asdec thinks that back jump is an 'else' block and tries to 
handle the code respectively.
In fact, back jump could be a part of 'do-while' of 'while' loop, which is not 
found yet by asdec.
I think we should check the address of jump instruction for this case.
Here is the exapmle patch.

//AVM2Code.java line 1547
for (Loop l : loopList) {
   if (l.loopBreak == jumpPos) {
      hasElse = false;
      break;
   }
}
//need to check, if it's back jump, then it might be the end of
//"if (condition ) { do { ... } while(condition); }"
//or "if(condigion) { while(condition) { ... } }"
if (jumpPos > ip && jumpPos < targetIns - 1) {
    hasElse = false;
}
//end of change
if (hasElse) {
   if (adr2pos(jumpAddr) > end + 1) {
      hasElse = false;
      //throw new ConvertException("Unknown pattern: forward jump outside of the block");
   }
}

Original issue reported on code.google.com by snoozamo...@gmail.com on 27 Dec 2012 at 9:08

GoogleCodeExporter commented 9 years ago
Hi, thank you for the change.
I added your change to the code, it is in the repository, will be in next 
release.

Original comment by jindra.p...@gmail.com on 28 Dec 2012 at 9:05