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 
23 namespace lldb_private {
24 
25 class ScriptInterpreterLocker {
26 public:
27   ScriptInterpreterLocker() = default;
28 
29   virtual ~ScriptInterpreterLocker() = default;
30 
31 private:
32   DISALLOW_COPY_AND_ASSIGN(ScriptInterpreterLocker);
33 };
34 
35 class ScriptInterpreter : public PluginInterface {
36 public:
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 
484 protected:
485   Debugger &m_debugger;
486   lldb::ScriptLanguage m_script_lang;
487 };
488 
489 } // namespace lldb_private
490 
491 #endif // liblldb_ScriptInterpreter_h_
492