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;
}
String FrameInjection::GetContainingFileName(bool skip /* = false */) {
  FrameInjection *t = ThreadInfo::s_threadInfo->m_top;
  if (t && skip) {
    t = t->m_prev;
  }
  if (t) {
    return t->getFileName();
  }
  return "";
}
static String get_current_alias() {
  DECLARE_THREAD_INFO;
  FrameInjection *fi;
  for (fi = info->m_top; fi; fi= fi->getPrev()) {
    if (fi->isEvalFrame()) {
      break;
    }
  }
  EvalFrameInjection *efi = static_cast<EvalFrameInjection*>(fi);
  return (efi) ? efi->getEnv().getCalleeAlias() : String();
}
Exemple #4
0
void eval_set_callee_alias(CStrRef alias) {
  DECLARE_THREAD_INFO;
  FrameInjection *fi;
  for (fi = info->m_top; fi; fi= fi->getPrev()) {
    if (fi->isEvalFrame()) {
      break;
    }
  }
  EvalFrameInjection *efi = static_cast<EvalFrameInjection*>(fi);
  if (efi) efi->getEnv().setCalleeAlias(alias);
}
FrameInjection *FrameInjection::GetStackFrame(int level) {
  FrameInjection *frame = ThreadInfo::s_threadInfo->m_top;
  for (int i = 0; i < level && frame; i++) {
    while (frame && (frame->m_flags & PseudoMain)) {
      frame = frame->getPrev();
    }
    if (frame) {
      frame = frame->getPrev();
    }
  }
  return frame;
}
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;
}
Eval::VariableEnvironment *
FrameInjection::GetVariableEnvironment(bool skip /* = false */) {
  FrameInjection *t = ThreadInfo::s_threadInfo->m_top;
  if (skip && t) {
    t = t->m_prev;
  }
  if (t && t->isEvalFrame()) {
    Eval::EvalFrameInjection* efi =
      static_cast<Eval::EvalFrameInjection*>(t);
    return &(efi->getEnv());
  }
  return NULL;
}
bool CmdVariable::onServer(DebuggerProxy *proxy) {
  FrameInjection *frame = ThreadInfo::s_threadInfo->m_top;
  for (int i = 0; i < m_frame && frame; i++) {
    frame = frame->getPrev();
  }
  m_global = (!frame || !frame->getPrev());

  if (frame) {
    EvalFrameInjection *eframe = dynamic_cast<EvalFrameInjection*>(frame);
    if (eframe) {
      m_variables = eframe->getEnv().getDefinedVariables();
      m_variables.remove("GLOBALS");
    }
  }
  return proxy->send(this);
}
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;
}
Exemple #10
0
CStrRef FrameInjection::GetClassName(bool skip /* = false */) {
  FrameInjection *t = ThreadInfo::s_threadInfo->m_top;
  if (t && skip) {
    t = t->m_prev;
  }
  // If we have included a file inside a class method or called a builtin
  // function, we should walk up to find that class
  if (t) {
    while (t->m_prev && t->getClassName().empty() &&
           t->m_flags & (PseudoMain | BuiltinFunction)) {
      t = t->m_prev;
    }
    CStrRef name = t->getClassName();
    if (!name.empty()) {
      return name;
    }
  }
  return empty_string;
}
Exemple #11
0
bool eval_get_call_info_hook(const CallInfo *&ci, void *&extra, const char *s,
                             int64 hash /* = -1 */) {
  const Eval::Function *fs = Eval::RequestEvalState::findFunction(s);
  if (fs) {
    ci = fs->getCallInfo();
    if (extra) {
      DECLARE_THREAD_INFO;
      EvalFrameInjection *efi = NULL;
      for (FrameInjection *fi = info->m_top; fi; fi= fi->getPrev()) {
        efi = dynamic_cast<EvalFrameInjection*>(fi);
       if (efi) break;
      }
      ASSERT(efi);
      efi->getEnv().setClosure(extra);
    }
    extra = (void*)fs;
    return true;
  }
  return false;
}
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) {
    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->m_class->copy(), true);
        if (!t->m_object.isNull()) {
          if (withThis) {
            frame.set(s_object, t->m_object, 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;
}
Exemple #13
0
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, and has actually been
    // entered (i.e. has a real line number) add it to the trace
    if (filename != "" && t->m_line != 0) {
      Array frame = Array::Create();
      frame.set(s_file, filename, true);
      frame.set(s_line, t->m_line, true);
      bt.append(frame);
    }
  }
  Array sbt = bt;
  FrameInjection *st = t;
  while (t && (RuntimeOption::InjectedStackTraceLimit < 0 ||
               bt.size() < RuntimeOption::InjectedStackTraceLimit)) {
    Array frame = t->getStackFrame(withSelf, withThis);
    if (frame.isNull()) return bt;
    bt.append(frame);
    t = t->m_prev;
  }
  if (!t) return bt;
  // The stack depth has exceeded the limit. Re-construct bt to include the
  // top and bottom frames. This is considered more useful in cases such as
  // infinite recursion.
  ASSERT(bt.size() == RuntimeOption::InjectedStackTraceLimit);
  int half = RuntimeOption::InjectedStackTraceLimit / 2;

  // start over, get the top half
  bt = sbt;
  t = st;
  while (t && bt.size() < half) {
    Array frame = t->getStackFrame(withSelf, withThis);
    if (frame.isNull()) assert(false);
    bt.append(frame);
    t = t->m_prev;
  }
  // then the bottom half
  std::vector<FrameInjection *> remainingFrames;
  while (t) {
    if (!t->m_prev && (t->m_flags & PseudoMain)) break;
    remainingFrames.push_back(t);
    t = t->m_prev;
  }
  int remaining = remainingFrames.size();
  int omitted = remaining - half;
  assert(omitted >= 0);
  if (omitted > 0) {
    std::string tmp("(...) ");
    tmp += boost::lexical_cast<std::string>(omitted) +
           " omitted frame" + ((omitted > 1) ? "s" : "");
    Array frame;
    frame.set(s_function, tmp);
    bt.append(frame);
  }
  for (int i = omitted; i < remaining; i++) {
    Array frame = remainingFrames[i]->getStackFrame(withSelf, withThis);
    if (frame.isNull()) assert(false);
    bt.append(frame);
  }
  return bt;
}