Example #1
0
bool CmdVariable::onServer(DebuggerProxy &proxy) {
  if (m_type == KindOfVariableAsync) {
    //we only do variable inspection on continuation wait handles
    auto frame = getWaitHandleAtAsyncStackPosition(m_frame);

    if (frame != nullptr) {
      auto fp = frame->actRec();
      if (fp != nullptr) {
        m_variables = getVariables(fp);
      }
    }
  }
  else if (m_frame < 0) {
    m_variables = g_context->m_globalVarEnv->getDefinedVariables();
    m_global = true;
  } else {
    m_variables = g_context->getLocalDefinedVariables(m_frame);
    m_global = g_context->getVarEnv(m_frame) == g_context->m_globalVarEnv;
  }

  if (m_global) {
    m_variables.remove(s_GLOBALS);
  }
  if (m_version == 1) {
    // Remove the values before sending to client.
    ArrayInit ret(m_variables->size(), ArrayInit::Map{});
    Variant v;
    for (ArrayIter iter(m_variables); iter; ++iter) {
      ret.add(iter.first().toString(), v);
    }
    m_variables = ret.toArray();
    m_version = 2;
  } else if (m_version == 2) {
    // Remove entries that do not match a non empty m_varName.
    if (!m_varName.empty()) {
      ArrayInit ret(1, ArrayInit::Map{});
      ret.add(m_varName, m_variables[m_varName]);
      m_variables = ret.toArray();
    }
    // Remove entries whose name or contents do not match a non empty m_filter
    if (!m_filter.empty()) {
      ArrayInit ret(m_variables.size(), ArrayInit::Map{});
      for (ArrayIter iter(m_variables); iter; ++iter) {
        String name = iter.first().toString();
        if (name.find(m_filter, 0, false) < 0) {
          String fullvalue = DebuggerClient::FormatVariable(iter.second(), -1);
          if (fullvalue.find(m_filter, 0, false) < 0) {
            continue;
          }
        }
        ret.add(name, iter.second());
      }
      m_variables = ret.toArray();
    }
  }

  return proxy.sendToClient(this);
}
Example #2
0
bool CmdVariable::onServer(DebuggerProxy &proxy) {
  if (m_type == KindOfVariableAsync) {
    //we only do variable inspection on continuation wait handles
    auto frame = getWaitHandleAtAsyncStackPosition(m_frame);

    if (frame != nullptr) {
      auto fp = frame->actRec();
      if (fp != nullptr) {
        m_variables = getDefinedVariables(fp);
      }
    }
  } else if (m_frame < 0) {
    m_variables = g_context->m_globalVarEnv->getDefinedVariables();
    m_global = true;
  } else {
    m_variables = g_context->getLocalDefinedVariables(m_frame);
    m_global = g_context->hasVarEnv(m_frame) == g_context->m_globalVarEnv;
    auto oThis = g_context->getThis();
    if (nullptr != oThis) {
      TypedValue tvThis;

      tvThis.m_type = KindOfObject;
      tvThis.m_data.pobj = oThis;

      Variant thisName(s_this);
      m_variables.add(thisName, tvAsVariant(&tvThis));
    }
  }

  if (m_global) {
    m_variables.remove(s_GLOBALS);
  }

  // Deprecated IDE uses this, so keep it around for now.  It expects all
  // variable values to be fully serialized across the wire.
  if (m_version == 0) {
    return proxy.sendToClient(this);
  }

  // Version 1 of this command means we want the names of all variables, but we
  // don't care about their values just yet.
  if (m_version == 1) {
    ArrayInit ret(m_variables->size(), ArrayInit::Map{});
    Variant v;
    for (ArrayIter iter(m_variables); iter; ++iter) {
      assert(iter.first().isString());
      ret.add(iter.first().toString(), v);
    }
    m_variables = ret.toArray();
    m_version = 2;
    return proxy.sendToClient(this);
  }

  // Version 2 of this command means we're trying to get the value of a single
  // variable.
  always_assert(m_version == 2);
  always_assert(!m_varName.empty());

  // Variable name might not exist.
  if (!m_variables.exists(m_varName, true /* isKey */)) {
    m_variables = Array::Create();
    return proxy.sendToClient(this);
  }

  auto const value = m_variables[m_varName];
  auto const result = m_formatMaxLen < 0
    ? DebuggerClient::FormatVariable(value)
    : DebuggerClient::FormatVariableWithLimit(value, m_formatMaxLen);
  m_variables = Array::Create(m_varName, result);

  // Remove the entry if its name or context does not match the filter.
  if (!m_filter.empty() && m_varName.find(m_filter, 0, false) < 0) {
    auto const fullvalue = DebuggerClient::FormatVariable(value);
    if (fullvalue.find(m_filter, 0, false) < 0) {
      m_variables = Array::Create();
    }
  }

  return proxy.sendToClient(this);
}