blob: 3084ec9d20679a82e662d37a6952e5b1574974cb [file] [log] [blame]
// Copyright 2019 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SRC_DEVELOPER_DEBUG_ZXDB_EXPR_ASYNC_DWARF_EXPR_EVAL_H_
#define SRC_DEVELOPER_DEBUG_ZXDB_EXPR_ASYNC_DWARF_EXPR_EVAL_H_
#include <vector>
#include "src/developer/debug/zxdb/expr/eval_callback.h"
#include "src/developer/debug/zxdb/expr/expr_value.h"
#include "src/developer/debug/zxdb/symbols/dwarf_expr_eval.h"
#include "src/lib/fxl/memory/ref_counted.h"
namespace zxdb {
class EvalContext;
class SymbolContext;
class Type;
// Manages evaluation of a DWARF expression (which might be asynchronous and need some tricky memory
// management), and constructs the proper type of ExprValue with the result.
//
// This keeps itself and the expression evaluator alive during the computation.
//
// Example:
//
// auto eval = fxl::MakeRefCounted<AsyncDwarfExprEval>(std::move(cb), std::move(type));
// eval->Eval(eval_context, symbol_context, expression);
//
class AsyncDwarfExprEval : public fxl::RefCountedThreadSafe<AsyncDwarfExprEval> {
public:
// Alows the expression evaluator to be set up before Eval() is called for cases where it needs
// initial state.
DwarfExprEval& dwarf_eval() { return dwarf_eval_; }
// Starts evaluation. It will take a reference to itself during execution and the callback passed
// into the constructor will be issued on completion. This can only be called once.
//
// The symbol context should be the one for the module the expression came from so that addresses
// within the expression can be interpreted correctly.
void Eval(const fxl::RefPtr<EvalContext>& context, const SymbolContext& expr_symbol_context,
const std::vector<uint8_t>& expr);
protected:
FRIEND_REF_COUNTED_THREAD_SAFE(AsyncDwarfExprEval);
FRIEND_MAKE_REF_COUNTED(AsyncDwarfExprEval);
// The passed-in callback will be executed if the DwarfExprEval returns success. It will have
// the given type.
//
// Note this class is derived from in a test so these need to be protected and virtual.
explicit AsyncDwarfExprEval(EvalCallback cb, fxl::RefPtr<Type> type)
: callback_(std::move(cb)), type_(std::move(type)) {}
virtual ~AsyncDwarfExprEval() = default;
void OnEvalComplete(const Err& err, const fxl::RefPtr<EvalContext>& context);
DwarfExprEval dwarf_eval_;
EvalCallback callback_;
// Not necessarily a concrete type, this is the type of the result the user will see.
fxl::RefPtr<Type> type_;
};
} // namespace zxdb
#endif // SRC_DEVELOPER_DEBUG_ZXDB_EXPR_ASYNC_DWARF_EXPR_EVAL_H_