JSValue JSJavaScriptCallFrame::scopeChain(ExecState* exec) const
{
    if (!impl()->scopeChain())
        return jsNull();

    JSScope* scopeChain = impl()->scopeChain();
    ScopeChainIterator iter = scopeChain->begin();
    ScopeChainIterator end = scopeChain->end();

    // we must always have something in the scope chain
    ASSERT(iter != end);

    MarkedArgumentBuffer list;
    do {
        list.append(iter.get());
        ++iter;
    } while (iter != end);

    return constructArray(exec, 0, globalObject(), list);
}
JSValue JSJavaScriptCallFrame::scopeType(ExecState* exec)
{
    if (!impl().scopeChain())
        return jsUndefined();

    if (!exec->argument(0).isInt32())
        return jsUndefined();
    int index = exec->argument(0).asInt32();

    JSScope* scopeChain = impl().scopeChain();
    ScopeChainIterator end = scopeChain->end();

    // FIXME: We should be identifying and returning CATCH_SCOPE appropriately.

    bool foundLocalScope = false;
    for (ScopeChainIterator iter = scopeChain->begin(); iter != end; ++iter) {
        JSObject* scope = iter.get();
        if (scope->isActivationObject()) {
            if (!foundLocalScope) {
                // First activation object is local scope, each successive activation object is closure.
                if (!index)
                    return jsNumber(JSJavaScriptCallFrame::LOCAL_SCOPE);
                foundLocalScope = true;
            } else if (!index)
                return jsNumber(JSJavaScriptCallFrame::CLOSURE_SCOPE);
        }

        if (!index) {
            // Last in the chain is global scope.
            if (++iter == end)
                return jsNumber(JSJavaScriptCallFrame::GLOBAL_SCOPE);
            return jsNumber(JSJavaScriptCallFrame::WITH_SCOPE);
        }

        --index;
    }

    ASSERT_NOT_REACHED();
    return jsUndefined();
}
JSValue JSJavaScriptCallFrame::scopeType(ExecState* exec)
{
    if (!impl()->scopeChain())
        return jsUndefined();

    if (!exec->argument(0).isInt32())
        return jsUndefined();
    int index = exec->argument(0).asInt32();

    JSScope* scopeChain = impl()->scopeChain();
    ScopeChainIterator end = scopeChain->end();

    bool foundLocalScope = false;
    for (ScopeChainIterator iter = scopeChain->begin(); iter != end; ++iter) {
        JSObject* scope = iter.get();
        if (scope->isActivationObject()) {
            if (!foundLocalScope) {
                // First activation object is local scope, each successive activation object is closure.
                if (!index)
                    return jsJavaScriptCallFrameLOCAL_SCOPE(exec, JSValue(), Identifier());
                foundLocalScope = true;
            } else if (!index)
                return jsJavaScriptCallFrameCLOSURE_SCOPE(exec, JSValue(), Identifier());
        }

        if (!index) {
            // Last in the chain is global scope.
            if (++iter == end)
                return jsJavaScriptCallFrameGLOBAL_SCOPE(exec, JSValue(), Identifier());
            return jsJavaScriptCallFrameWITH_SCOPE(exec, JSValue(), Identifier());
        }

        --index;
    }
    return jsUndefined();
}