|  | // 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_ |