Exemplo n.º 1
0
// A AsyncESuspend is used in the codegen for an async function to setup
// a Continuation and return a wait handle so execution can continue
// later. We have just completed a AsyncESuspend, so the new
// Continuation is available, and it can predict where execution will
// resume.
void CmdNext::stepAfterAsyncESuspend() {
  auto topObj = g_context->getStack().topTV()->m_data.pobj;
  assert(topObj->instanceof(c_AsyncFunctionWaitHandle::classof()));
  auto wh = static_cast<c_AsyncFunctionWaitHandle*>(topObj);
  auto func = wh->getActRec()->m_func;
  Offset nextInst = wh->getNextExecutionOffset();
  assert(nextInst != InvalidAbsoluteOffset);
  m_stepContTag = wh->getActRec();
  TRACE(2,
        "CmdNext: patch for cont step after AsyncESuspend at '%s' offset %d\n",
        func->fullName()->data(), nextInst);
  m_stepCont = StepDestination(func->unit(), nextInst);
}
Exemplo n.º 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->getActRec();
      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);
}