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(); }