JSObject * JSAbstractFramePtr::callObject(JSContext *cx) { AbstractFramePtr frame(*this); if (!frame.isFunctionFrame()) return nullptr; JSObject *o = GetDebugScopeForFrame(cx, frame, pc()); /* * Given that fp is a function frame and GetDebugScopeForFrame always fills * in missing scopes, we can expect to find fp's CallObject on 'o'. Note: * - GetDebugScopeForFrame wraps every ScopeObject (missing or not) with * a DebugScopeObject proxy. * - If fp is an eval-in-function, then fp has no callobj of its own and * JS_GetFrameCallObject will return the innermost function's callobj. */ while (o) { ScopeObject &scope = o->as<DebugScopeObject>().scope(); if (scope.is<CallObject>()) return o; o = o->enclosingScope(); } return nullptr; }
JS_GetFrameCallObject(JSContext *cx, JSStackFrame *fpArg) { StackFrame *fp = Valueify(fpArg); JS_ASSERT(cx->stack.space().containsSlow(fp)); if (!fp->isFunctionFrame()) return NULL; JSObject *o = GetDebugScopeForFrame(cx, fp); /* * Given that fp is a function frame and GetDebugScopeForFrame always fills * in missing scopes, we can expect to find fp's CallObject on 'o'. Note: * - GetDebugScopeForFrame wraps every ScopeObject (missing or not) with * a DebugScopeObject proxy. * - If fp is an eval-in-function, then fp has no callobj of its own and * JS_GetFrameCallObject will return the innermost function's callobj. */ while (o) { ScopeObject &scope = o->asDebugScope().scope(); if (scope.isCall()) return o; o = o->enclosingScope(); } return NULL; }
CallObject & ScriptFrameIter::callObj() const { JS_ASSERT(callee()->isHeavyweight()); JSObject *pobj = scopeChain(); while (!pobj->is<CallObject>()) pobj = pobj->enclosingScope(); return pobj->as<CallObject>(); }
CallObject & FrameIter::callObj(JSContext *cx) const { MOZ_ASSERT(calleeTemplate()->isHeavyweight()); JSObject *pobj = scopeChain(cx); while (!pobj->is<CallObject>()) pobj = pobj->enclosingScope(); return pobj->as<CallObject>(); }
CallObject & RematerializedFrame::callObj() const { MOZ_ASSERT(hasCallObj()); JSObject *scope = scopeChain(); while (!scope->is<CallObject>()) scope = scope->enclosingScope(); return scope->as<CallObject>(); }
// We should be able to assert this for *any* fp->scopeChain(). static void AssertInnerizedScopeChain(JSContext *cx, JSObject &scopeobj) { #ifdef DEBUG for (JSObject *o = &scopeobj; o; o = o->enclosingScope()) { if (JSObjectOp op = o->getClass()->ext.innerObject) { Rooted<JSObject*> obj(cx, o); JS_ASSERT(op(cx, obj) == o); } } #endif }