tree: 1e03140e4ddd05e6fa3c166cbdb0fbe4be71e21b [search]
  1. abi.h
  2. abi_arm64.cc
  3. abi_arm64.h
  4. abi_null.h
  5. abi_riscv64.cc
  6. abi_riscv64.h
  7. abi_x64.cc
  8. abi_x64.h
  9. bitfield.cc
  10. bitfield.h
  11. bitfield_unittest.cc
  12. BUILD.gn
  13. builtin_types.cc
  14. builtin_types.h
  15. builtin_types_unittest.cc
  16. cast.cc
  17. cast.h
  18. cast_unittest.cc
  19. eval_callback.h
  20. eval_context.cc
  21. eval_context.h
  22. eval_context_impl.cc
  23. eval_context_impl.h
  24. eval_context_impl_unittest.cc
  25. eval_dwarf_expr.cc
  26. eval_dwarf_expr.h
  27. eval_dwarf_expr_unittest.cc
  28. eval_operators.cc
  29. eval_operators.h
  30. eval_operators_unittest.cc
  31. eval_test_support.cc
  32. eval_test_support.h
  33. expr.cc
  34. expr.h
  35. expr_language.cc
  36. expr_language.h
  37. expr_language_unittest.cc
  38. expr_node.cc
  39. expr_node.h
  40. expr_node_unittest.cc
  41. expr_number_utils.cc
  42. expr_number_utils.h
  43. expr_parser.cc
  44. expr_parser.h
  45. expr_parser_fuzzer.cc
  46. expr_parser_unittest.cc
  47. expr_token.h
  48. expr_token_type.cc
  49. expr_token_type.h
  50. expr_tokenizer.cc
  51. expr_tokenizer.h
  52. expr_tokenizer_unittest.cc
  53. expr_unittest.cc
  54. expr_value.cc
  55. expr_value.h
  56. expr_value_source.cc
  57. expr_value_source.h
  58. expr_value_source_unittest.cc
  59. expr_value_unittest.cc
  60. find_name.cc
  61. find_name.h
  62. find_name_unittest.cc
  63. format.cc
  64. format.h
  65. format_node.cc
  66. format_node.h
  67. format_options.h
  68. format_test_support.cc
  69. format_test_support.h
  70. format_unittest.cc
  71. found_member.cc
  72. found_member.h
  73. found_name.cc
  74. found_name.h
  75. identifier_glob.cc
  76. identifier_glob.h
  77. identifier_glob_unittest.cc
  78. index_walker.cc
  79. index_walker.h
  80. index_walker_unittest.cc
  81. keywords.cc
  82. keywords.h
  83. local_expr_value.h
  84. mock_eval_context.cc
  85. mock_eval_context.h
  86. mock_expr_node.cc
  87. mock_expr_node.h
  88. number_parser.cc
  89. number_parser.h
  90. number_parser_unittest.cc
  91. operator_keyword.cc
  92. operator_keyword.h
  93. operator_keyword_unittest.cc
  94. parse_special_identifier.cc
  95. parse_special_identifier.h
  96. parse_special_identifier_unittest.cc
  97. parse_string.cc
  98. parse_string.h
  99. parse_string_unittest.cc
  100. parsed_identifier.cc
  101. parsed_identifier.h
  102. parsed_identifier_unittest.cc
  103. permissive_input_location.cc
  104. permissive_input_location.h
  105. permissive_input_location_unittest.cc
  106. pretty_rust_tuple.cc
  107. pretty_rust_tuple.h
  108. pretty_rust_tuple_unittest.cc
  109. pretty_std_string.cc
  110. pretty_std_string.h
  111. pretty_std_string_unittest.cc
  112. pretty_type.cc
  113. pretty_type.h
  114. pretty_type_manager.cc
  115. pretty_type_manager.h
  116. pretty_type_manager_unittest.cc
  117. pretty_type_unittest.cc
  118. README.md
  119. register_utils.cc
  120. register_utils.h
  121. resolve_array.cc
  122. resolve_array.h
  123. resolve_array_unittest.cc
  124. resolve_base.cc
  125. resolve_base.h
  126. resolve_base_unittest.cc
  127. resolve_collection.cc
  128. resolve_collection.h
  129. resolve_collection_unittest.cc
  130. resolve_const_value.cc
  131. resolve_const_value.h
  132. resolve_function.cc
  133. resolve_function.h
  134. resolve_ptr_ref.cc
  135. resolve_ptr_ref.h
  136. resolve_ptr_ref_unittest.cc
  137. resolve_type.cc
  138. resolve_type.h
  139. resolve_type_unittest.cc
  140. resolve_variant.cc
  141. resolve_variant.h
  142. resolve_variant_unittest.cc
  143. return_value.cc
  144. return_value.h
  145. return_value_unittest.cc
  146. template_type_extractor.cc
  147. template_type_extractor.h
  148. template_type_extractor_unittest.cc
  149. test_eval_context_impl.h
  150. variable_decl.cc
  151. variable_decl.h
  152. variable_decl_unittest.cc
  153. vector_register_format.cc
  154. vector_register_format.h
  155. vector_register_format_unittest.cc
  156. virtual_base_test_setup.cc
  157. virtual_base_test_setup.h
  158. virtual_inheritance_test_setup.cc
  159. virtual_inheritance_test_setup.h
  160. vm_exec.cc
  161. vm_exec.h
  162. vm_exec_unittest.cc
  163. vm_op.cc
  164. vm_op.h
  165. vm_op_type.cc
  166. vm_op_type.h
  167. vm_stream.cc
  168. vm_stream.h
  169. vm_stream_unittest.cc
src/developer/debug/zxdb/expr/README.md

Expression Evaluation (zxdb/expr)

//src/developer/debug/zxdb/expr parses and evaluates C, C++, and Rust console expressions (Layer 3), such as expressions passed to print. Do not confuse these high-level console expressions with low-level DWARF location expressions in zxdb/symbols.

Main Components

The expression evaluator consists of four stages:

  • Tokenizer (expr_tokenizer.cc): Splits input text into a stream of ExprToken objects for the parser.
  • Parser (expr_parser.cc): Parses the token stream into an abstract syntax tree (AST) of ExprNode objects.
  • Abstract Syntax Tree & Bytecode VM (expr_node.cc, vm_exec.cc): Each ExprNode subclass emits bytecode (EmitBytecode) into a VmStream, which the stack-based virtual machine executes.
  • Expression Value (expr_value.cc): ExprValue pairs a DWARF Type reference with raw bytes and an ExprValueSource origin descriptor.

Integration with Symbols and Process State

AST nodes and the bytecode VM do not reference ProcessSymbols or Process directly, which keeps expression evaluation unit-testable in isolation.

Instead, AST and VM operations query the abstract EvalContext interface. In live sessions, EvalContextImpl implements EvalContext using ProcessSymbols and a SymbolDataProvider backed by the target process.

Helper Components

Additional files in this directory resolve names and types during evaluation:

  • Name lookup (find_name.*, found_*): Resolves identifiers to variables, members, types, and functions across lexical blocks and module indices.
  • Data resolution (resolve_*): Reads arrays, base and derived classes, struct members, pointers, references, and Rust enums/tuples.
  • Identifier parsing (parsed_identifier.*, template_type_extractor.*): Parses qualified identifiers and extracts template parameter lists.

Interface

Public headers expose these evaluation, parsing, VM, and formatting APIs:

  • zxdb::EvalExpression, zxdb::EvalExpressions, zxdb::ValueToAddressAndSize, zxdb::EvalCallback: Top-level asynchronous expression evaluation entry points (expr.h, eval_callback.h).
  • zxdb::ExprTokenizer, zxdb::ExprToken, zxdb::ExprParser, zxdb::ExprLanguage, zxdb::DwarfLangToExprLanguage, zxdb::FileNameToLanguage: Lexical tokenizer and recursive-descent parser for C/C++ (ExprLanguage::kC) and Rust (ExprLanguage::kRust) (expr_tokenizer.h, expr_parser.h, expr_language.h).
  • zxdb::ExprNode (expr_node.h): Base AST node that emits VmStream bytecode. Subclasses include AddressOfExprNode, ArrayAccessExprNode, BinaryOpExprNode, BlockExprNode, BreakExprNode, CastExprNode, ConditionExprNode, DereferenceExprNode, FunctionCallExprNode, IdentifierExprNode, LiteralExprNode, LocalVarExprNode, LoopExprNode, MemberAccessExprNode, SizeofExprNode, TypeExprNode, UnaryOpExprNode, and VariableDeclExprNode.
  • zxdb::VmOp, zxdb::VmStream, zxdb::VmExec, zxdb::VmStreamToString, zxdb::VmBytecodeForwardJumper, zxdb::VmBytecodeForwardJump, zxdb::VmBytecodeForwardJumpIfFalse, zxdb::VmBytecodePushBreak: Stack-based bytecode representation and asynchronous execution engine (vm_op.h, vm_stream.h, vm_exec.h).
  • zxdb::ExprValue, zxdb::ErrOrValue, zxdb::ErrOrValueVector, zxdb::ExprValueSource: Typed value containers and origin descriptors (kTemporary, kMemory, kRegister, kConstant, kComposite, kLocal) (expr_value.h, expr_value_source.h).
  • zxdb::EvalContext, zxdb::EvalContextImpl, zxdb::Abi, zxdb::AbiX64, zxdb::AbiArm64, zxdb::AbiRiscv64: Evaluation context and target ABI implementations (eval_context.h, eval_context_impl.h, abi.h).
  • zxdb::ParsedIdentifier, zxdb::ParsedIdentifierComponent, zxdb::FoundName, zxdb::FindNameContext, zxdb::FindNameOptions, zxdb::FindName, zxdb::VisitLocalVariables, zxdb::FindLocalVariable, zxdb::FindMember, zxdb::FindMemberOnThis, zxdb::FindIndexedName, zxdb::FindIndexedNameInModule: Identifier types and symbol lookup routines (parsed_identifier.h, found_name.h, find_name.h).
  • Data resolution and operator helpers (resolve_*.h, eval_dwarf_expr.h, eval_operators.h): zxdb::ResolveArray, zxdb::ResolveArrayItem, zxdb::PromoteToDerived, zxdb::PromotePtrRefToDerived, zxdb::ResolveMember, zxdb::ResolveMemberByPointer, zxdb::ResolveInherited, zxdb::ResolvePointer, and zxdb::EnsureResolveReference. Also exposes zxdb::GetConcreteType, zxdb::FindTypeDefinition, zxdb::ResolveVariant, zxdb::DwarfExprToValue, zxdb::AsyncDwarfExprEval, zxdb::EvalBinaryOperator, and zxdb::EvalUnaryOperator.
  • zxdb::FormatNode, zxdb::FormatOptions, zxdb::FillFormatNodeValue, zxdb::FillFormatNodeDescription, zxdb::PrettyType, zxdb::PrettyTypeManager, zxdb::PrettyStdString, zxdb::PrettyRustTuple: Value formatting tree nodes and type pretty-printers (format_node.h, format.h, pretty_type.h, pretty_type_manager.h).

Invariants

Callers and implementations must preserve these invariants:

  • Every ExprNode::EmitBytecode() method must pop any temporary values it pushes and leave one ExprValue on the VM stack (statements push an empty ExprValue).
  • When VmStream execution finishes without error, the VM stack holds one ExprValue containing the final result.
  • VmBytecodeForwardJumper (and subclasses VmBytecodeForwardJump, VmBytecodeForwardJumpIfFalse, VmBytecodePushBreak) asserts on destruction if the caller registered a jump source without calling JumpToHere().
  • VmOp::SetJumpDest() asserts unless the opcode is kJump, kJumpIfFalse, or kPushBreak.
  • ExprValue::GetAs<T>() asserts if the internal byte buffer size does not equal sizeof(T).
  • ExprValueSource::SetBits() requires is_bitfield() (bit_size() != 0) to be true.
  • TypeExprNode::concrete_type() is never null. GetConcreteType() and FindTypeDefinition() return null only when the input type is null or does not resolve to a Type.
  • Call AsyncDwarfExprEval::Eval() at most once per instance. The evaluator holds a self-reference until asynchronous execution finishes.
  • DwarfLangToExprLanguage() maps all non-Rust DWARF languages to ExprLanguage::kC.

Side Effects

Evaluating expressions produces these target and tree side effects:

  • Reads target memory and registers asynchronously via SymbolDataProvider during bytecode execution, pointer dereferencing, member resolution, vtable lookup, and FormatNode evaluation.
  • Writes target memory, CPU registers, or VM-local variables when evaluating assignments against an ExprValue with source kMemory, kRegister, or kLocal.
  • Calls completion callbacks (EvalCallback, fit::deferred_callback) synchronously or asynchronously. FillFormatNodeValue and FillFormatNodeDescription always run their callback even if FormatNode destructs, whereas EvalContext::GetNamedValue drops its callback if EvalContext destructs first.
  • Updates FormatNode state, value, description, error status, and child trees in place during FillFormatNodeValue, FillFormatNodeDescription, and PrettyType::Format.

Verification

Run these commands to build and test zxdb/expr:

  • Build: fx build //src/developer/debug/zxdb/expr
  • Test: fx test zxdb_tests