<p>
This page tests for a crash due to insufficient marking of ExecStates. If
the test passes, you'll see a series of PASS messages below.
</p>

<pre id="console">
PASS: You didn't crash.
</pre>

<a id="a"></a>

<script>
function log(s)
{
    document.getElementById("console").appendChild(document.createTextNode(s + "\n"));
}

function shouldBe(a, aDescription, b)
{
    if (a == b) {
        log("PASS: " + aDescription + " should be " + b + " and is.");
    } else {
        log("FAIL: " + aDescription + " should be " + b + " but instead is " + a + ".");
    }
}

function FailureObject()
{
}

FailureObject.prototype.toString = function()
{
    return "FAIL"; // A marker to indicate that an object was collected and then overwritten by a FailureObject.
}

function gc()
{
    if (window.GCController)
        GCController.collect();
    else
        for (var i = 0; i < 10000; ++i) // Allocate a sufficient number of objects to force a GC.
            new FailureObject;
}

function gc1()
{
    var script = document.createElement("script");
    script.appendChild(document.createTextNode("gc()"));
    document.body.appendChild(script);
}

function gc2()
{
    var a = document.getElementById("a");
    a.href = "javascript:gc()";
    
    var event = document.createEvent("MouseEvent");
    event.initMouseEvent("click", true, true, document.defaultView, 1, 0, 0, 0, 0, false, false, false, false, 0, document);
    a.dispatchEvent(event);
}

function gc3()
{
    document.write("<" + "script" + "/>" + "gc()" + "</" + "script" + ">");
}

function f()
{
    // Allocate some activation data.
    var v1 = "1";
    var v2 = "2";
    var v3 = "3";
    var v4 = "4";
    var v5 = "5";

    // Globally evaluate a script that forces GC, using a few different mechanisms.
    gc1();
    gc2();
    gc3();

    /*
     * Some other ways to globally evaluate a script, which aren't tested here:
     * NPN_Evaluate
     * -[WebScriptObject evaluateWebScript:]
     * JSEvaluateScript
     * JavaJSObject::eval
     * javascript: URLs for elements other than <a>
     */

    // Now verify that our activation data wasn't collected, by using it in an interesting way.
    return v1 + v2 + v3 + v4 + v5;
}

if (window.testRunner)
    testRunner.dumpAsText();

shouldBe(f(), "f()", "12345");
</script>
