ObjectData *FrameInjection::GetThis(bool skip /* = false */) { FrameInjection *t = ThreadInfo::s_threadInfo->m_top; if (t && skip) { t = t->m_prev; } if (t) { return t->getObjectV(); } return NULL; }
CStrRef FrameInjection::GetStaticClassName(ThreadInfo *info) { ASSERT(info); for (FrameInjection *t = info->m_top; t; t = t->m_prev) { if (t != info->m_top) { if (t->m_staticClass) return *t->m_staticClass; } ObjectData *obj = t->getObjectV(); if (obj) { return obj->o_getClassName(); } } return empty_string; }
CStrRef FrameInjection::GetStaticClassName(ThreadInfo *info) { ASSERT(info); for (FrameInjection *t = info->m_top; t; t = t->m_prev) { if (t != info->m_top) { if (t->m_staticClass) return *t->m_staticClass; } ObjectData *obj = t->getObjectV(); if (obj) { return obj->o_getClassName(); } if (!(t->m_flags & (PseudoMain|BuiltinFunction|StaticMethod|ObjectMethod))) { break; } } return empty_string; }
Array FrameInjection::GetBacktrace(bool skip /* = false */, bool withSelf /* = false */, bool withThis /* = true */) { Array bt = Array::Create(); FrameInjection *t = ThreadInfo::s_threadInfo->m_top; if (skip && t) { t = t->m_prev; } // This is used by onError with extended exceptions if (withSelf && t) { String filename = t->getFileName(); // If the top frame is not an extension function, // add it to the trace if (filename != "") { Array frame = Array::Create(); frame.set(s_file, filename, true); frame.set(s_line, t->m_line, true); bt.append(frame); } } while (t && (RuntimeOption::InjectedStackTraceLimit < 0 || bt.size() < RuntimeOption::InjectedStackTraceLimit)) { Array frame = Array::Create(); if (t->m_prev) { String file = t->m_prev->getFileName(); if (!file.empty() && t->m_prev->m_line) { frame.set(s_file, file, true); frame.set(s_line, t->m_prev->m_line, true); } } else if (t->m_flags & PseudoMain) { // Stop at top, don't include top file break; } if (t->m_flags & PseudoMain) { frame.set(s_function, "include", true); frame.set(s_args, Array::Create(t->getFileName()), true); } else { const char *c = strstr(t->m_name, "::"); if (c) { frame.set(s_function, String(c + 2), true); frame.set(s_class, t->getClassName()->copy(), true); if (ObjectData *obj = t->getObjectV()) { if (withThis) { frame.set(s_object, Object(obj), true); } frame.set(s_type, "->", true); } else { frame.set(s_type, "::", true); } } else { frame.set(s_function, t->m_name, true); } Array args = t->getArgs(); if (!args.isNull()) { frame.set(s_args, args, true); } else { frame.set(s_args, Array::Create(), true); } } bt.append(frame); t = t->m_prev; } return bt; }