]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/python/lib/gdb/dap/evaluate.py
4fc0f31486cbd822546e6c84a820a3c34aff7160
[thirdparty/binutils-gdb.git] / gdb / python / lib / gdb / dap / evaluate.py
1 # Copyright 2022, 2023 Free Software Foundation, Inc.
2
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 3 of the License, or
6 # (at your option) any later version.
7 #
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
12 #
13 # You should have received a copy of the GNU General Public License
14 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
16 import gdb
17 import gdb.printing
18
19 # This is deprecated in 3.9, but required in older versions.
20 from typing import Optional
21
22 from .frames import frame_for_id
23 from .server import request
24 from .startup import send_gdb_with_response, in_gdb_thread
25 from .varref import find_variable, VariableReference
26
27
28 class EvaluateResult(VariableReference):
29 def __init__(self, value):
30 super().__init__(None, value, "result")
31
32
33 # Helper function to evaluate an expression in a certain frame.
34 @in_gdb_thread
35 def _evaluate(expr, frame_id):
36 global_context = True
37 if frame_id is not None:
38 frame = frame_for_id(frame_id)
39 frame.select()
40 global_context = False
41 val = gdb.parse_and_eval(expr, global_context=global_context)
42 ref = EvaluateResult(val)
43 return ref.to_object()
44
45
46 # Helper function to evaluate a gdb command in a certain frame.
47 @in_gdb_thread
48 def _repl(command, frame_id):
49 if frame_id is not None:
50 frame = frame_for_id(frame_id)
51 frame.select()
52 val = gdb.execute(command, from_tty=True, to_string=True)
53 return {
54 "result": val,
55 "variablesReference": 0,
56 }
57
58
59 # FIXME supportsVariableType handling
60 @request("evaluate")
61 def eval_request(
62 *,
63 expression: str,
64 frameId: Optional[int] = None,
65 context: str = "variables",
66 **args,
67 ):
68 if context in ("watch", "variables"):
69 # These seem to be expression-like.
70 return send_gdb_with_response(lambda: _evaluate(expression, frameId))
71 elif context == "repl":
72 return send_gdb_with_response(lambda: _repl(expression, frameId))
73 else:
74 raise Exception(f'unknown evaluate context "{context}"')
75
76
77 @in_gdb_thread
78 def _variables(ref, start, count):
79 var = find_variable(ref)
80 children = var.fetch_children(start, count)
81 return [x.to_object() for x in children]
82
83
84 @request("variables")
85 # Note that we ignore the 'filter' field. That seems to be
86 # specific to javascript.
87 def variables(*, variablesReference: int, start: int = 0, count: int = 0, **args):
88 result = send_gdb_with_response(
89 lambda: _variables(variablesReference, start, count)
90 )
91 return {"variables": result}