String FrameInjection::getFileName() { if (m_flags & PseudoMain) { return m_name[0] == '_' ? m_name : m_name + 10; } if (isEvalFrame()) { Eval::EvalFrameInjection *efi = static_cast<Eval::EvalFrameInjection*>(this); return efi->getFileNameEval(); } if (isParserFrame()) { Eval::ParserFrameInjection *pfi = static_cast<Eval::ParserFrameInjection*>(this); return pfi->getFileName(); } const char *c = strstr(m_name, "::"); const char *f = NULL; if (c) { f = SourceInfo::TheSourceInfo.getClassDeclaringFile(getClassName()); } else { f = SourceInfo::TheSourceInfo.getFunctionDeclaringFile(m_name); } if (f != NULL) { return f; } return null_string; }
ObjectData *FrameInjection::getObjectV() const { if (isObjectMethodFrame()) { const FrameInjectionObjectMethod* ofi = static_cast<const FrameInjectionObjectMethod*>(this); return ofi->getThis(); } else if (isEvalFrame()) { const Eval::EvalFrameInjection* efi = static_cast<const Eval::EvalFrameInjection*>(this); return efi->getThis(); } else if (m_flags & PseudoMain) { const FrameInjectionFunction *ffi = static_cast<const FrameInjectionFunction*>(this); return ffi->getThis(); } return NULL; }
CStrRef FrameInjection::getClassName() const { if (isEvalFrame()) { const Eval::EvalFrameInjection *efi = static_cast<const Eval::EvalFrameInjection*>(this); return efi->getClass(); } // Otherwise, parse the name and lookup from ClassInfo const char *c = strstr(m_name, "::"); if (!c) return empty_string; String cls(m_name, c - m_name, CopyString); const ClassInfo *classInfo = ClassInfo::FindClass(cls); if (classInfo) { CStrRef clsRef = classInfo->getName(); if (!clsRef.isNull()) { return clsRef; } } return empty_string; }
ObjectData *FrameInjection::getObjectV() const { // Must check first: an EvalFrame can also be // an ObjectMethodFrame (but its still implemented // using EvalFrameInjection). if (UNLIKELY(isEvalFrame())) { const Eval::EvalFrameInjection* efi = static_cast<const Eval::EvalFrameInjection*>(this); return efi->getThis(); } if (LIKELY(isObjectMethodFrame())) { const FrameInjectionObjectMethod* ofi = static_cast<const FrameInjectionObjectMethod*>(this); return ofi->getThis(); } if (m_flags & PseudoMain) { const FrameInjectionFunction *ffi = static_cast<const FrameInjectionFunction*>(this); return ffi->getThis(); } return NULL; }
Array FrameInjection::getStackFrame(bool withSelf, bool withThis) { Array frame = Array::Create(); if (m_prev) { String file = m_prev->getFileName(); if (!file.empty() && m_prev->m_line) { frame.set(s_file, file, true); frame.set(s_line, m_prev->m_line, true); } } else if (m_flags & PseudoMain) { // Stop at top, don't include top file return Array(); } if (m_flags & PseudoMain) { frame.set(s_function, "include", true); frame.set(s_args, Array::Create(getFileName()), true); } else { const char *c = strstr(m_name, "::"); const char *f = m_name; if (c) { f = c + 2; frame.set(s_class, getClassName()->copy(), true); if (ObjectData *obj = getObjectV()) { if (withThis) { frame.set(s_object, Object(obj), true); } frame.set(s_type, "->", true); } else { frame.set(s_type, "::", true); } } ASSERT(f); switch (f[0]) { case ParserBase::CharClosure: frame.set(s_function, s_closureBrackets, true); break; case ParserBase::CharContinuationFromClosure: frame.set(s_function, s_closureGenBrackets, true); break; default: if (const char *c = strstr(f, "$$")) { frame.set(s_function, String(f, c - f, CopyString), true); } else { if (isEvalFrame()) { frame.set(s_function, String(f, CopyString), true); } else { frame.set(s_function, f, true); } } break; } Array args = getArgs(); if (!args.isNull()) { frame.set(s_args, args, true); } else { frame.set(s_args, Array::Create(), true); } } return frame; }