Bug 17932 - "ASSERTION FAILED: type != Continue" with do/while and try/finally
Summary: "ASSERTION FAILED: type != Continue" with do/while and try/finally
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: 528+ (Nightly build)
Hardware: Mac OS X 10.5
: P2 Normal
Assignee: Nobody
URL:
Keywords: HasReduction, InRadar
Depends on:
Blocks: 13638
  Show dependency treegraph
 
Reported: 2008-03-18 18:38 PDT by Jesse Ruderman
Modified: 2008-06-08 21:49 PDT (History)
4 users (show)

See Also:


Attachments
Test cases (4.42 KB, patch)
2008-06-08 21:42 PDT, Cameron Zwarich (cpst)
oliver: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jesse Ruderman 2008-03-18 18:38:47 PDT
This script:

  do try { continue; } finally { } while (0);

triggers an assertion failure in a Debug ToT testksj:

ASSERTION FAILED: type != Continue
(/Users/jruderman/WebKit/JavaScriptCore/kjs/ExecState.h:117 void KJS::ExecState::setCompletionType(KJS::ComplType))

The script doesn't seem to cause any problems in a Release (as opposed to Debug) build.
Comment 1 Mark Rowe (bdash) 2008-03-18 18:59:45 PDT
<rdar://problem/5806712>
Comment 2 Mark Rowe (bdash) 2008-03-18 21:56:30 PDT
TryNode::execute saves the current completion type before executing the "finally" block, and then uses setCompletionType to restore it afterwards:

    if (m_finallyBlock) {
        ComplType savedCompletionType = exec->completionType();
        JSValue* finallyResult = m_finallyBlock->execute(exec);
        if (exec->completionType() != Normal)
            result = finallyResult;
        else
            exec->setCompletionType(savedCompletionType);
    }

setCompletionType is implemented thusly:
        // Only for use in the implementation of execute().
        void setCompletionType(ComplType type)
        {
            ASSERT(type != Break);
            ASSERT(type != Continue);
            m_completionType = type;
        }

I suspect that this could lead to an actual bug in a release build if a targeted break or continue was used inside the "finally" block, as the target is not saved and restored.
Comment 3 Mark Rowe (bdash) 2008-03-18 22:20:08 PDT
Yup, the following code behaves differently in JSCore vs SpiderMonkey:

do {
  try {
    print('continuing outer loop');
    continue;
  } finally {
    innerLoop:
    while (1) {
      print('breaking out of innerLoop');
      break innerLoop;
    }
  }
} while (1);

JSCore prints:
continuing outer loop
breaking out of innerLoop

and then exits.  SpiderMonkey prints:
continuing outer loop
breaking out of innerLoop
continuing outer loop
breaking out of innerLoop
continuing outer loop
breaking out of innerLoop
[.. and so on ..]


When the outer DoWhileNode checks exec->breakOrContinueTarget(), the target is still set to "innerLoop" from the break statement within the "finally" block.
Comment 4 Cameron Zwarich (cpst) 2008-06-07 21:21:24 PDT
This is fixed by SquirrelFish. I will write a layout test for this bug and some similar issues that came up during SquirrelFish development.
Comment 5 Cameron Zwarich (cpst) 2008-06-08 21:42:39 PDT
Created attachment 21588 [details]
Test cases

Here are some test cases so we can close this bug.
Comment 6 Oliver Hunt 2008-06-08 21:43:44 PDT
Comment on attachment 21588 [details]
Test cases

r=me
Comment 7 Cameron Zwarich (cpst) 2008-06-08 21:49:01 PDT
Landed in r34461.