Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'break' is not emitted in some cases #20

Open
AdamMil opened this issue Jan 21, 2019 · 2 comments
Open

'break' is not emitted in some cases #20

AdamMil opened this issue Jan 21, 2019 · 2 comments

Comments

@AdamMil
Copy link

AdamMil commented Jan 21, 2019

Consider this small script:

while(true) {
  if(!this.condition) {
    if(--n <= 0) { break; }
  }
}

When compiled and decompiled, the output is:

while (true) {
        if (!this.condition) {
                if (--this.n <= 0) {
                }
        }
}

The 'break' statement is missing, resulting in an infinite loop.

@AdamMil
Copy link
Author

AdamMil commented Jan 21, 2019

While debugging, I notice this:

void NutFunction::DecompileJCMP(VMState& state, int condVar, int offsetIp, int iterVar, int cmpOp) const
{
    ...
    bool bCanBreak = (state.m_BlockState.inLoop || state.m_BlockState.inSwitch);

Here, m_BlockState refers to the 'if' statement and .inLoop is false. However, m_BlockState.parent refers to the loop and has .inLoop true. I think either bCanBreak needs to examine the chain of parent blocks, or inLoop needs to be propagated from parent to child.

I changed the code to:

bool bCanBreak = false;
for (BlockState *p = &state.m_BlockState; !bCanBreak && p; p = p->parent)
{
    bCanBreak = (p->inLoop || p->inSwitch);
}

And got the correct output for my example. But I'm not sure that's the correct change.

@AdamMil
Copy link
Author

AdamMil commented Jan 21, 2019

Perhaps elseEnd > prevBlockState.blockEnd also needs to be fixed to compare against the containing loop or switch end?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant