JSValue JSJavaScriptCallFrame::scopeType(ExecState* exec) { if (!impl().scopeChain()) return jsUndefined(); if (!exec->argument(0).isInt32()) return jsUndefined(); int index = exec->argument(0).asInt32(); DebuggerScope* scopeChain = impl().scopeChain(); DebuggerScope::iterator end = scopeChain->end(); bool foundLocalScope = false; for (DebuggerScope::iterator iter = scopeChain->begin(); iter != end; ++iter) { DebuggerScope* scope = iter.get(); if (!foundLocalScope && scope->isFunctionOrEvalScope()) { // First function scope is the local scope, each successive one is a closure. if (!index) return jsNumber(JSJavaScriptCallFrame::LOCAL_SCOPE); foundLocalScope = true; } if (!index) { if (scope->isCatchScope()) return jsNumber(JSJavaScriptCallFrame::CATCH_SCOPE); if (scope->isFunctionNameScope()) return jsNumber(JSJavaScriptCallFrame::FUNCTION_NAME_SCOPE); if (scope->isWithScope()) return jsNumber(JSJavaScriptCallFrame::WITH_SCOPE); if (scope->isGlobalScope()) { ASSERT(++iter == end); return jsNumber(JSJavaScriptCallFrame::GLOBAL_SCOPE); } ASSERT(scope->isFunctionOrEvalScope()); return jsNumber(JSJavaScriptCallFrame::CLOSURE_SCOPE); } --index; } ASSERT_NOT_REACHED(); return jsUndefined(); }
JSValue JSJavaScriptCallFrame::scopeChain(ExecState* exec) const { if (!impl().scopeChain()) return jsNull(); DebuggerScope* scopeChain = impl().scopeChain(); DebuggerScope::iterator iter = scopeChain->begin(); DebuggerScope::iterator 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, nullptr, globalObject(), list); }