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