OperatingSystemGo::Goroutine OperatingSystemGo::CreateGoroutineAtIndex(uint64_t idx, Error &err) { err.Clear(); Goroutine result; ValueObjectSP g = m_allg_sp->GetSyntheticArrayMember(idx, true)->Dereference(err); if (err.Fail()) { return result; } ConstString name("goid"); ValueObjectSP val = g->GetChildMemberWithName(name, true); bool success = false; result.m_goid = val->GetValueAsUnsigned(0, &success); if (!success) { err.SetErrorToGenericError(); err.SetErrorString("unable to read goid"); return result; } name.SetCString("atomicstatus"); val = g->GetChildMemberWithName(name, true); result.m_status = (uint32_t)val->GetValueAsUnsigned(0, &success); if (!success) { err.SetErrorToGenericError(); err.SetErrorString("unable to read atomicstatus"); return result; } name.SetCString("sched"); val = g->GetChildMemberWithName(name, true); result.m_gobuf = val->GetAddressOf(false); name.SetCString("stack"); val = g->GetChildMemberWithName(name, true); name.SetCString("lo"); ValueObjectSP child = val->GetChildMemberWithName(name, true); result.m_lostack = child->GetValueAsUnsigned(0, &success); if (!success) { err.SetErrorToGenericError(); err.SetErrorString("unable to read stack.lo"); return result; } name.SetCString("hi"); child = val->GetChildMemberWithName(name, true); result.m_histack = child->GetValueAsUnsigned(0, &success); if (!success) { err.SetErrorToGenericError(); err.SetErrorString("unable to read stack.hi"); return result; } return result; }
ValueObjectSP GoUserExpression::GoInterpreter::VisitIndexExpr(const lldb_private::GoASTIndexExpr *e) { ValueObjectSP target = EvaluateExpr(e->GetX()); if (!target) return nullptr; ValueObjectSP index = EvaluateExpr(e->GetIndex()); if (!index) return nullptr; bool is_signed; if (!index->GetCompilerType().IsIntegerType(is_signed)) { m_error.SetErrorString("Unsupported index"); return nullptr; } size_t idx; if (is_signed) idx = index->GetValueAsSigned(0); else idx = index->GetValueAsUnsigned(0); if (GoASTContext::IsGoSlice(target->GetCompilerType())) { target = target->GetStaticValue(); ValueObjectSP cap = target->GetChildMemberWithName(ConstString("cap"), true); if (cap) { uint64_t capval = cap->GetValueAsUnsigned(0); if (idx >= capval) { m_error.SetErrorStringWithFormat("Invalid index %" PRIu64 " , cap = %" PRIu64, uint64_t(idx), capval); return nullptr; } } target = target->GetChildMemberWithName(ConstString("array"), true); if (target && m_use_dynamic != eNoDynamicValues) { ValueObjectSP dynamic = target->GetDynamicValue(m_use_dynamic); if (dynamic) target = dynamic; } if (!target) return nullptr; return target->GetSyntheticArrayMember(idx, true); } return target->GetChildAtIndex(idx, true); }
ValueObjectSP BitsetFrontEnd::GetChildAtIndex(size_t idx) { if (idx >= m_elements.size() || !m_first) return ValueObjectSP(); if (m_elements[idx]) return m_elements[idx]; ExecutionContext ctx = m_backend.GetExecutionContextRef().Lock(false); CompilerType type; ValueObjectSP chunk; // For small bitsets __first_ is not an array, but a plain size_t. if (m_first->GetCompilerType().IsArrayType(&type, nullptr, nullptr)) { llvm::Optional<uint64_t> bit_size = type.GetBitSize(ctx.GetBestExecutionContextScope()); if (!bit_size || *bit_size == 0) return {}; chunk = m_first->GetChildAtIndex(idx / *bit_size, true); } else { type = m_first->GetCompilerType(); chunk = m_first; } if (!type || !chunk) return {}; llvm::Optional<uint64_t> bit_size = type.GetBitSize(ctx.GetBestExecutionContextScope()); if (!bit_size || *bit_size == 0) return {}; size_t chunk_idx = idx % *bit_size; uint8_t value = !!(chunk->GetValueAsUnsigned(0) & (uint64_t(1) << chunk_idx)); DataExtractor data(&value, sizeof(value), m_byte_order, m_byte_size); m_elements[idx] = CreateValueObjectFromData(llvm::formatv("[{0}]", idx).str(), data, ctx, m_bool_type); return m_elements[idx]; }