EncodedJSValue DFG_OPERATION operationResolve(ExecState* exec, Identifier* propertyName) { ScopeChainNode* scopeChain = exec->scopeChain(); ScopeChainIterator iter = scopeChain->begin(); ScopeChainIterator end = scopeChain->end(); ASSERT(iter != end); do { JSObject* record = iter->get(); PropertySlot slot(record); if (record->getPropertySlot(exec, *propertyName, slot)) return JSValue::encode(slot.getValue(exec, *propertyName)); } while (++iter != end); return throwVMError(exec, createUndefinedVariableError(exec, *propertyName)); }
JSValue JSJavaScriptCallFrame::scopeChain(ExecState* exec) const { if (!impl()->scopeChain()) return jsNull(); ScopeChainNode* 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, 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(); ScopeChainNode* 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(); }