1//===-- ScriptInterpreter.h -------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef liblldb_ScriptInterpreter_h_
10#define liblldb_ScriptInterpreter_h_
11
12#include "lldb/lldb-private.h"
13
14#include "lldb/Breakpoint/BreakpointOptions.h"
15#include "lldb/Core/PluginInterface.h"
16#include "lldb/Core/SearchFilter.h"
17#include "lldb/Utility/Broadcaster.h"
18#include "lldb/Utility/Status.h"
19#include "lldb/Utility/StructuredData.h"
20
21#include "lldb/Host/PseudoTerminal.h"
22
23namespace lldb_private {
24
25class ScriptInterpreterLocker {
26public:
27  ScriptInterpreterLocker() = default;
28
29  virtual ~ScriptInterpreterLocker() = default;
30
31private:
32  DISALLOW_COPY_AND_ASSIGN(ScriptInterpreterLocker);
33};
34
35class ScriptInterpreter : public PluginInterface {
36public:
37  enum ScriptReturnType {
38    eScriptReturnTypeCharPtr,
39    eScriptReturnTypeBool,
40    eScriptReturnTypeShortInt,
41    eScriptReturnTypeShortIntUnsigned,
42    eScriptReturnTypeInt,
43    eScriptReturnTypeIntUnsigned,
44    eScriptReturnTypeLongInt,
45    eScriptReturnTypeLongIntUnsigned,
46    eScriptReturnTypeLongLong,
47    eScriptReturnTypeLongLongUnsigned,
48    eScriptReturnTypeFloat,
49    eScriptReturnTypeDouble,
50    eScriptReturnTypeChar,
51    eScriptReturnTypeCharStrOrNone,
52    eScriptReturnTypeOpaqueObject
53  };
54
55  ScriptInterpreter(Debugger &debugger, lldb::ScriptLanguage script_lang);
56
57  ~ScriptInterpreter() override;
58
59  struct ExecuteScriptOptions {
60  public:
61    ExecuteScriptOptions()
62        : m_enable_io(true), m_set_lldb_globals(true), m_maskout_errors(true) {}
63
64    bool GetEnableIO() const { return m_enable_io; }
65
66    bool GetSetLLDBGlobals() const { return m_set_lldb_globals; }
67
68    // If this is true then any exceptions raised by the script will be
69    // cleared with PyErr_Clear().   If false then they will be left for
70    // the caller to clean up
71    bool GetMaskoutErrors() const { return m_maskout_errors; }
72
73    ExecuteScriptOptions &SetEnableIO(bool enable) {
74      m_enable_io = enable;
75      return *this;
76    }
77
78    ExecuteScriptOptions &SetSetLLDBGlobals(bool set) {
79      m_set_lldb_globals = set;
80      return *this;
81    }
82
83    ExecuteScriptOptions &SetMaskoutErrors(bool maskout) {
84      m_maskout_errors = maskout;
85      return *this;
86    }
87
88  private:
89    bool m_enable_io;
90    bool m_set_lldb_globals;
91    bool m_maskout_errors;
92  };
93
94  virtual bool Interrupt() { return false; }
95
96  virtual bool ExecuteOneLine(
97      llvm::StringRef command, CommandReturnObject *result,
98      const ExecuteScriptOptions &options = ExecuteScriptOptions()) = 0;
99
100  virtual void ExecuteInterpreterLoop() = 0;
101
102  virtual bool ExecuteOneLineWithReturn(
103      llvm::StringRef in_string, ScriptReturnType return_type, void *ret_value,
104      const ExecuteScriptOptions &options = ExecuteScriptOptions()) {
105    return true;
106  }
107
108  virtual Status ExecuteMultipleLines(
109      const char *in_string,
110      const ExecuteScriptOptions &options = ExecuteScriptOptions()) {
111    Status error;
112    error.SetErrorString("not implemented");
113    return error;
114  }
115
116  virtual Status
117  ExportFunctionDefinitionToInterpreter(StringList &function_def) {
118    Status error;
119    error.SetErrorString("not implemented");
120    return error;
121  }
122
123  virtual Status GenerateBreakpointCommandCallbackData(
124      StringList &input,
125      std::string &output,
126      bool has_extra_args) {
127    Status error;
128    error.SetErrorString("not implemented");
129    return error;
130  }
131
132  virtual bool GenerateWatchpointCommandCallbackData(StringList &input,
133                                                     std::string &output) {
134    return false;
135  }
136
137  virtual bool GenerateTypeScriptFunction(const char *oneliner,
138                                          std::string &output,
139                                          const void *name_token = nullptr) {
140    return false;
141  }
142
143  virtual bool GenerateTypeScriptFunction(StringList &input,
144                                          std::string &output,
145                                          const void *name_token = nullptr) {
146    return false;
147  }
148
149  virtual bool GenerateScriptAliasFunction(StringList &input,
150                                           std::string &output) {
151    return false;
152  }
153
154  virtual bool GenerateTypeSynthClass(StringList &input, std::string &output,
155                                      const void *name_token = nullptr) {
156    return false;
157  }
158
159  virtual bool GenerateTypeSynthClass(const char *oneliner, std::string &output,
160                                      const void *name_token = nullptr) {
161    return false;
162  }
163
164  virtual StructuredData::ObjectSP
165  CreateSyntheticScriptedProvider(const char *class_name,
166                                  lldb::ValueObjectSP valobj) {
167    return StructuredData::ObjectSP();
168  }
169
170  virtual StructuredData::GenericSP
171  CreateScriptCommandObject(const char *class_name) {
172    return StructuredData::GenericSP();
173  }
174
175  virtual StructuredData::GenericSP
176  CreateFrameRecognizer(const char *class_name) {
177    return StructuredData::GenericSP();
178  }
179
180  virtual lldb::ValueObjectListSP GetRecognizedArguments(
181      const StructuredData::ObjectSP &implementor,
182      lldb::StackFrameSP frame_sp) {
183    return lldb::ValueObjectListSP();
184  }
185
186  virtual StructuredData::GenericSP
187  OSPlugin_CreatePluginObject(const char *class_name,
188                              lldb::ProcessSP process_sp) {
189    return StructuredData::GenericSP();
190  }
191
192  virtual StructuredData::DictionarySP
193  OSPlugin_RegisterInfo(StructuredData::ObjectSP os_plugin_object_sp) {
194    return StructuredData::DictionarySP();
195  }
196
197  virtual StructuredData::ArraySP
198  OSPlugin_ThreadsInfo(StructuredData::ObjectSP os_plugin_object_sp) {
199    return StructuredData::ArraySP();
200  }
201
202  virtual StructuredData::StringSP
203  OSPlugin_RegisterContextData(StructuredData::ObjectSP os_plugin_object_sp,
204                               lldb::tid_t thread_id) {
205    return StructuredData::StringSP();
206  }
207
208  virtual StructuredData::DictionarySP
209  OSPlugin_CreateThread(StructuredData::ObjectSP os_plugin_object_sp,
210                        lldb::tid_t tid, lldb::addr_t context) {
211    return StructuredData::DictionarySP();
212  }
213
214  virtual StructuredData::ObjectSP
215  CreateScriptedThreadPlan(const char *class_name,
216                           StructuredDataImpl *args_data,
217                           std::string &error_str,
218                           lldb::ThreadPlanSP thread_plan_sp) {
219    return StructuredData::ObjectSP();
220  }
221
222  virtual bool
223  ScriptedThreadPlanExplainsStop(StructuredData::ObjectSP implementor_sp,
224                                 Event *event, bool &script_error) {
225    script_error = true;
226    return true;
227  }
228
229  virtual bool
230  ScriptedThreadPlanShouldStop(StructuredData::ObjectSP implementor_sp,
231                               Event *event, bool &script_error) {
232    script_error = true;
233    return true;
234  }
235
236  virtual bool
237  ScriptedThreadPlanIsStale(StructuredData::ObjectSP implementor_sp,
238                            bool &script_error) {
239    script_error = true;
240    return true;
241  }
242
243  virtual lldb::StateType
244  ScriptedThreadPlanGetRunState(StructuredData::ObjectSP implementor_sp,
245                                bool &script_error) {
246    script_error = true;
247    return lldb::eStateStepping;
248  }
249
250  virtual StructuredData::GenericSP
251  CreateScriptedBreakpointResolver(const char *class_name,
252                                   StructuredDataImpl *args_data,
253                                   lldb::BreakpointSP &bkpt_sp) {
254    return StructuredData::GenericSP();
255  }
256
257  virtual bool
258  ScriptedBreakpointResolverSearchCallback(StructuredData::GenericSP implementor_sp,
259                                           SymbolContext *sym_ctx)
260  {
261    return false;
262  }
263
264  virtual lldb::SearchDepth
265  ScriptedBreakpointResolverSearchDepth(StructuredData::GenericSP implementor_sp)
266  {
267    return lldb::eSearchDepthModule;
268  }
269
270  virtual StructuredData::ObjectSP
271  LoadPluginModule(const FileSpec &file_spec, lldb_private::Status &error) {
272    return StructuredData::ObjectSP();
273  }
274
275  virtual StructuredData::DictionarySP
276  GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target,
277                     const char *setting_name, lldb_private::Status &error) {
278    return StructuredData::DictionarySP();
279  }
280
281  virtual Status GenerateFunction(const char *signature,
282                                  const StringList &input) {
283    Status error;
284    error.SetErrorString("unimplemented");
285    return error;
286  }
287
288  virtual void CollectDataForBreakpointCommandCallback(
289      std::vector<BreakpointOptions *> &options, CommandReturnObject &result);
290
291  virtual void
292  CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options,
293                                          CommandReturnObject &result);
294
295  /// Set the specified text as the callback for the breakpoint.
296  Status
297  SetBreakpointCommandCallback(std::vector<BreakpointOptions *> &bp_options_vec,
298                               const char *callback_text);
299
300  virtual Status SetBreakpointCommandCallback(BreakpointOptions *bp_options,
301                                              const char *callback_text) {
302    Status error;
303    error.SetErrorString("unimplemented");
304    return error;
305  }
306
307  /// This one is for deserialization:
308  virtual Status SetBreakpointCommandCallback(
309      BreakpointOptions *bp_options,
310      std::unique_ptr<BreakpointOptions::CommandData> &data_up) {
311    Status error;
312    error.SetErrorString("unimplemented");
313    return error;
314  }
315
316  Status SetBreakpointCommandCallbackFunction(
317      std::vector<BreakpointOptions *> &bp_options_vec,
318      const char *function_name, StructuredData::ObjectSP extra_args_sp);
319
320  /// Set a script function as the callback for the breakpoint.
321  virtual Status
322  SetBreakpointCommandCallbackFunction(
323      BreakpointOptions *bp_options,
324      const char *function_name,
325      StructuredData::ObjectSP extra_args_sp) {
326    Status error;
327    error.SetErrorString("unimplemented");
328    return error;
329  }
330
331  /// Set a one-liner as the callback for the watchpoint.
332  virtual void SetWatchpointCommandCallback(WatchpointOptions *wp_options,
333                                            const char *oneliner) {}
334
335  virtual bool GetScriptedSummary(const char *function_name,
336                                  lldb::ValueObjectSP valobj,
337                                  StructuredData::ObjectSP &callee_wrapper_sp,
338                                  const TypeSummaryOptions &options,
339                                  std::string &retval) {
340    return false;
341  }
342
343  virtual void Clear() {
344    // Clean up any ref counts to SBObjects that might be in global variables
345  }
346
347  virtual size_t
348  CalculateNumChildren(const StructuredData::ObjectSP &implementor,
349                       uint32_t max) {
350    return 0;
351  }
352
353  virtual lldb::ValueObjectSP
354  GetChildAtIndex(const StructuredData::ObjectSP &implementor, uint32_t idx) {
355    return lldb::ValueObjectSP();
356  }
357
358  virtual int
359  GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor,
360                          const char *child_name) {
361    return UINT32_MAX;
362  }
363
364  virtual bool
365  UpdateSynthProviderInstance(const StructuredData::ObjectSP &implementor) {
366    return false;
367  }
368
369  virtual bool MightHaveChildrenSynthProviderInstance(
370      const StructuredData::ObjectSP &implementor) {
371    return true;
372  }
373
374  virtual lldb::ValueObjectSP
375  GetSyntheticValue(const StructuredData::ObjectSP &implementor) {
376    return nullptr;
377  }
378
379  virtual ConstString
380  GetSyntheticTypeName(const StructuredData::ObjectSP &implementor) {
381    return ConstString();
382  }
383
384  virtual bool
385  RunScriptBasedCommand(const char *impl_function, llvm::StringRef args,
386                        ScriptedCommandSynchronicity synchronicity,
387                        lldb_private::CommandReturnObject &cmd_retobj,
388                        Status &error,
389                        const lldb_private::ExecutionContext &exe_ctx) {
390    return false;
391  }
392
393  virtual bool RunScriptBasedCommand(
394      StructuredData::GenericSP impl_obj_sp, llvm::StringRef args,
395      ScriptedCommandSynchronicity synchronicity,
396      lldb_private::CommandReturnObject &cmd_retobj, Status &error,
397      const lldb_private::ExecutionContext &exe_ctx) {
398    return false;
399  }
400
401  virtual bool RunScriptFormatKeyword(const char *impl_function,
402                                      Process *process, std::string &output,
403                                      Status &error) {
404    error.SetErrorString("unimplemented");
405    return false;
406  }
407
408  virtual bool RunScriptFormatKeyword(const char *impl_function, Thread *thread,
409                                      std::string &output, Status &error) {
410    error.SetErrorString("unimplemented");
411    return false;
412  }
413
414  virtual bool RunScriptFormatKeyword(const char *impl_function, Target *target,
415                                      std::string &output, Status &error) {
416    error.SetErrorString("unimplemented");
417    return false;
418  }
419
420  virtual bool RunScriptFormatKeyword(const char *impl_function,
421                                      StackFrame *frame, std::string &output,
422                                      Status &error) {
423    error.SetErrorString("unimplemented");
424    return false;
425  }
426
427  virtual bool RunScriptFormatKeyword(const char *impl_function,
428                                      ValueObject *value, std::string &output,
429                                      Status &error) {
430    error.SetErrorString("unimplemented");
431    return false;
432  }
433
434  virtual bool GetDocumentationForItem(const char *item, std::string &dest) {
435    dest.clear();
436    return false;
437  }
438
439  virtual bool
440  GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp,
441                               std::string &dest) {
442    dest.clear();
443    return false;
444  }
445
446  virtual uint32_t
447  GetFlagsForCommandObject(StructuredData::GenericSP cmd_obj_sp) {
448    return 0;
449  }
450
451  virtual bool GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp,
452                                           std::string &dest) {
453    dest.clear();
454    return false;
455  }
456
457  virtual bool CheckObjectExists(const char *name) { return false; }
458
459  virtual bool
460  LoadScriptingModule(const char *filename, bool init_session,
461                      lldb_private::Status &error,
462                      StructuredData::ObjectSP *module_sp = nullptr);
463
464  virtual bool IsReservedWord(const char *word) { return false; }
465
466  virtual std::unique_ptr<ScriptInterpreterLocker> AcquireInterpreterLock();
467
468  const char *GetScriptInterpreterPtyName();
469
470  int GetMasterFileDescriptor();
471
472  virtual llvm::Expected<unsigned>
473  GetMaxPositionalArgumentsForCallable(const llvm::StringRef &callable_name) {
474    return llvm::createStringError(
475    llvm::inconvertibleErrorCode(), "Unimplemented function");
476  }
477
478  static std::string LanguageToString(lldb::ScriptLanguage language);
479
480  static lldb::ScriptLanguage StringToLanguage(const llvm::StringRef &string);
481
482  lldb::ScriptLanguage GetLanguage() { return m_script_lang; }
483
484protected:
485  Debugger &m_debugger;
486  lldb::ScriptLanguage m_script_lang;
487};
488
489} // namespace lldb_private
490
491#endif // liblldb_ScriptInterpreter_h_
492