LLDB mainline
ScriptInterpreterPythonImpl.h
Go to the documentation of this file.
1//===-- ScriptInterpreterPythonImpl.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 LLDB_SOURCE_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H
10#define LLDB_SOURCE_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H
11
12// clang-format off
13// LLDB Python header must be included first
14#include "lldb-python.h"
15//clang-format on
16
17#include "PythonDataObjects.h"
19
20#include "lldb/Host/Terminal.h"
22
23#include "llvm/ADT/STLExtras.h"
24#include "llvm/ADT/StringRef.h"
25
26namespace lldb_private {
29public:
31
33
35
36 bool Interrupt() override;
37
38 bool ExecuteOneLine(
39 llvm::StringRef command, CommandReturnObject *result,
40 const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
41
42 void ExecuteInterpreterLoop() override;
43
45 llvm::StringRef in_string,
46 ScriptInterpreter::ScriptReturnType return_type, void *ret_value,
47 const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
48
50 const char *in_string,
51 const ExecuteScriptOptions &options = ExecuteScriptOptions()) override;
52
53 Status
55
56 bool GenerateTypeScriptFunction(StringList &input, std::string &output,
57 const void *name_token = nullptr) override;
58
59 bool GenerateTypeSynthClass(StringList &input, std::string &output,
60 const void *name_token = nullptr) override;
61
62 bool GenerateTypeSynthClass(const char *oneliner, std::string &output,
63 const void *name_token = nullptr) override;
64
65 // use this if the function code is just a one-liner script
66 bool GenerateTypeScriptFunction(const char *oneliner, std::string &output,
67 const void *name_token = nullptr) override;
68
70 std::string &output) override;
71
73 CreateSyntheticScriptedProvider(const char *class_name,
74 lldb::ValueObjectSP valobj) override;
75
77 CreateScriptCommandObject(const char *class_name) override;
78
81
83 CreateFrameRecognizer(const char *class_name) override;
84
87 lldb::StackFrameSP frame_sp) override;
88
89 bool ShouldHide(const StructuredData::ObjectSP &implementor,
90 lldb::StackFrameSP frame_sp) override;
91
93
95
97
100
102
104
107
110
112
114 LoadPluginModule(const FileSpec &file_spec,
115 lldb_private::Status &error) override;
116
118 GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target,
119 const char *setting_name,
120 lldb_private::Status &error) override;
121
122 size_t CalculateNumChildren(const StructuredData::ObjectSP &implementor,
123 uint32_t max) override;
124
126 GetChildAtIndex(const StructuredData::ObjectSP &implementor,
127 uint32_t idx) override;
128
129 llvm::Expected<uint32_t>
131 const char *child_name) override;
132
134 const StructuredData::ObjectSP &implementor) override;
135
137 const StructuredData::ObjectSP &implementor) override;
138
140 GetSyntheticValue(const StructuredData::ObjectSP &implementor) override;
141
143 GetSyntheticTypeName(const StructuredData::ObjectSP &implementor) override;
144
145 bool
146 RunScriptBasedCommand(const char *impl_function, llvm::StringRef args,
147 ScriptedCommandSynchronicity synchronicity,
149 Status &error,
150 const lldb_private::ExecutionContext &exe_ctx) override;
151
153 StructuredData::GenericSP impl_obj_sp, llvm::StringRef args,
154 ScriptedCommandSynchronicity synchronicity,
156 const lldb_private::ExecutionContext &exe_ctx) override;
157
159 StructuredData::GenericSP impl_obj_sp, Args &args,
160 ScriptedCommandSynchronicity synchronicity,
162 const lldb_private::ExecutionContext &exe_ctx) override;
163
164 std::optional<std::string>
166 Args &args) override;
167
169 StructuredData::GenericSP impl_obj_sp, std::vector<llvm::StringRef> &args,
170 size_t args_pos, size_t char_in_arg) override;
171
173 StructuredData::GenericSP impl_obj_sp, llvm::StringRef &long_options,
174 size_t char_in_arg) override;
175
176 Status GenerateFunction(const char *signature, const StringList &input,
177 bool is_callback) override;
178
180 std::string &output,
181 bool has_extra_args,
182 bool is_callback) override;
183
185 std::string &output,
186 bool is_callback) override;
187
188 bool GetScriptedSummary(const char *function_name, lldb::ValueObjectSP valobj,
189 StructuredData::ObjectSP &callee_wrapper_sp,
190 const TypeSummaryOptions &options,
191 std::string &retval) override;
192
193 bool FormatterCallbackFunction(const char *function_name,
194 lldb::TypeImplSP type_impl_sp) override;
195
196 bool GetDocumentationForItem(const char *item, std::string &dest) override;
197
199 std::string &dest) override;
200
201 uint32_t
203
205 std::string &dest) override;
206
209
212
214 ExecutionContext *exe_ctx,
215 llvm::StringRef long_option,
216 llvm::StringRef value) override;
217
219 StructuredData::GenericSP cmd_obj_sp) override;
220
221 bool CheckObjectExists(const char *name) override {
222 if (!name || !name[0])
223 return false;
224 std::string temp;
225 return GetDocumentationForItem(name, temp);
226 }
227
228 bool RunScriptFormatKeyword(const char *impl_function, Process *process,
229 std::string &output, Status &error) override;
230
231 bool RunScriptFormatKeyword(const char *impl_function, Thread *thread,
232 std::string &output, Status &error) override;
233
234 bool RunScriptFormatKeyword(const char *impl_function, Target *target,
235 std::string &output, Status &error) override;
236
237 bool RunScriptFormatKeyword(const char *impl_function, StackFrame *frame,
238 std::string &output, Status &error) override;
239
240 bool RunScriptFormatKeyword(const char *impl_function, ValueObject *value,
241 std::string &output, Status &error) override;
242
243 bool LoadScriptingModule(const char *filename,
244 const LoadScriptOptions &options,
246 StructuredData::ObjectSP *module_sp = nullptr,
247 FileSpec extra_search_dir = {},
248 lldb::TargetSP loaded_into_target_sp = {}) override;
249
250 bool IsReservedWord(const char *word) override;
251
252 std::unique_ptr<ScriptInterpreterLocker> AcquireInterpreterLock() override;
253
255 std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec,
256 CommandReturnObject &result) override;
257
258 void
259 CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options,
260 CommandReturnObject &result) override;
261
262 /// Set the callback body text into the callback for the breakpoint.
263 Status SetBreakpointCommandCallback(BreakpointOptions &bp_options,
264 const char *callback_body,
265 bool is_callback) override;
266
268 BreakpointOptions &bp_options, const char *function_name,
269 StructuredData::ObjectSP extra_args_sp) override;
270
271 /// This one is for deserialization:
273 BreakpointOptions &bp_options,
274 std::unique_ptr<BreakpointOptions::CommandData> &data_up) override;
275
276 Status SetBreakpointCommandCallback(BreakpointOptions &bp_options,
277 const char *command_body_text,
278 StructuredData::ObjectSP extra_args_sp,
279 bool uses_extra_args,
280 bool is_callback);
281
282 /// Set a one-liner as the callback for the watchpoint.
283 void SetWatchpointCommandCallback(WatchpointOptions *wp_options,
284 const char *user_input,
285 bool is_callback) override;
286
287 const char *GetDictionaryName() { return m_dictionary_name.c_str(); }
288
289 PyThreadState *GetThreadState() { return m_command_thread_state; }
290
291 void SetThreadState(PyThreadState *s) {
292 if (s)
294 }
295
296 // IOHandlerDelegate
297 void IOHandlerActivated(IOHandler &io_handler, bool interactive) override;
298
299 void IOHandlerInputComplete(IOHandler &io_handler,
300 std::string &data) override;
301
303
304 // PluginInterface protocol
305 llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
306
308 public:
309 enum OnEntry {
310 AcquireLock = 0x0001,
311 InitSession = 0x0002,
312 InitGlobals = 0x0004,
313 NoSTDIN = 0x0008
314 };
315
316 enum OnLeave {
317 FreeLock = 0x0001,
318 FreeAcquiredLock = 0x0002, // do not free the lock if we already held it
319 // when calling constructor
321 };
322
323 Locker(ScriptInterpreterPythonImpl *py_interpreter,
324 uint16_t on_entry = AcquireLock | InitSession,
325 uint16_t on_leave = FreeLock | TearDownSession,
326 lldb::FileSP in = nullptr, lldb::FileSP out = nullptr,
327 lldb::FileSP err = nullptr);
328
329 ~Locker() override;
330
331 private:
332 bool DoAcquireLock();
333
334 bool DoInitSession(uint16_t on_entry_flags, lldb::FileSP in,
335 lldb::FileSP out, lldb::FileSP err);
336
337 bool DoFreeLock();
338
339 bool DoTearDownSession();
340
343 PyGILState_STATE m_GILState;
344 };
345
346 static bool BreakpointCallbackFunction(void *baton,
348 lldb::user_id_t break_id,
349 lldb::user_id_t break_loc_id);
350 static bool WatchpointCallbackFunction(void *baton,
352 lldb::user_id_t watch_id);
353 static void Initialize();
354
366
367 enum class AddLocation { Beginning, End };
368
369 static void AddToSysPath(AddLocation location, std::string path);
370
371 bool EnterSession(uint16_t on_entry_flags, lldb::FileSP in, lldb::FileSP out,
372 lldb::FileSP err);
373
374 void LeaveSession();
375
376 uint32_t IsExecutingPython() {
377 std::lock_guard<std::mutex> guard(m_mutex);
378 return m_lock_count > 0;
379 }
380
382 std::lock_guard<std::mutex> guard(m_mutex);
383 return ++m_lock_count;
384 }
385
387 std::lock_guard<std::mutex> guard(m_mutex);
388 if (m_lock_count > 0)
389 --m_lock_count;
390 return m_lock_count;
391 }
392
398
400
402
404
405 llvm::Expected<unsigned> GetMaxPositionalArgumentsForCallable(
406 const llvm::StringRef &callable_name) override;
407
409
410 bool SetStdHandle(lldb::FileSP file, const char *py_name,
411 python::PythonObject &save_file, const char *mode);
412
421 std::string m_dictionary_name;
426 uint32_t m_lock_count;
427 std::mutex m_mutex;
429};
430
432public:
437
438 ~IOHandlerPythonInterpreter() override = default;
439
440 llvm::StringRef GetControlSequence(char ch) override {
441 static constexpr llvm::StringLiteral control_sequence("quit()\n");
442 if (ch == 'd')
443 return control_sequence;
444 return {};
445 }
446
447 void Run() override {
448 if (m_python) {
449 int stdin_fd = GetInputFD();
450 if (stdin_fd >= 0) {
451 Terminal terminal(stdin_fd);
452 TerminalState terminal_state(terminal);
453
454 if (terminal.IsATerminal()) {
455 // FIXME: error handling?
456 llvm::consumeError(terminal.SetCanonical(false));
457 llvm::consumeError(terminal.SetEcho(true));
458 }
459
461 m_python,
467
468 // The following call drops into the embedded interpreter loop and
469 // stays there until the user chooses to exit from the Python
470 // interpreter. This embedded interpreter will, as any Python code that
471 // performs I/O, unlock the GIL before a system call that can hang, and
472 // lock it when the syscall has returned.
473
474 // We need to surround the call to the embedded interpreter with calls
475 // to PyGILState_Ensure and PyGILState_Release (using the Locker
476 // above). This is because Python has a global lock which must be held
477 // whenever we want to touch any Python objects. Otherwise, if the user
478 // calls Python code, the interpreter state will be off, and things
479 // could hang (it's happened before).
480
481 StreamString run_string;
482 run_string.Printf("run_python_interpreter (%s)",
483 m_python->GetDictionaryName());
484 python::RunSimpleString(run_string.GetData());
485 }
486 }
487 SetIsDone(true);
488 }
489
490 void Cancel() override {}
491
492 bool Interrupt() override { return m_python->Interrupt(); }
493
494 void GotEOF() override {}
495
496protected:
498};
499
500} // namespace lldb_private
501
502#endif // LLDB_SOURCE_PLUGINS_SCRIPTINTERPRETER_PYTHON_SCRIPTINTERPRETERPYTHONIMPL_H
static llvm::raw_ostream & error(Stream &strm)
ScriptInterpreterPythonImpl::Locker Locker
A command line argument class.
Definition Args.h:33
A uniqued constant string class.
Definition ConstString.h:40
A class to manage flag bits.
Definition Debugger.h:100
"lldb/Target/ExecutionContext.h" A class that contains an execution context.
A file utility class.
Definition FileSpec.h:57
~IOHandlerPythonInterpreter() override=default
llvm::StringRef GetControlSequence(char ch) override
IOHandlerPythonInterpreter(Debugger &debugger, ScriptInterpreterPythonImpl *python)
IOHandler(Debugger &debugger, IOHandler::Type type)
Definition IOHandler.cpp:55
void SetIsDone(bool b)
Definition IOHandler.h:81
A plug-in interface definition class for debugging a process.
Definition Process.h:356
bool DoInitSession(uint16_t on_entry_flags, lldb::FileSP in, lldb::FileSP out, lldb::FileSP err)
Locker(ScriptInterpreterPythonImpl *py_interpreter, uint16_t on_entry=AcquireLock|InitSession, uint16_t on_leave=FreeLock|TearDownSession, lldb::FileSP in=nullptr, lldb::FileSP out=nullptr, lldb::FileSP err=nullptr)
SynchronicityHandler(lldb::DebuggerSP, ScriptedCommandSynchronicity)
bool GenerateTypeScriptFunction(StringList &input, std::string &output, const void *name_token=nullptr) override
Status GenerateFunction(const char *signature, const StringList &input, bool is_callback) override
bool GenerateScriptAliasFunction(StringList &input, std::string &output) override
lldb_private::Status ExecuteMultipleLines(const char *in_string, const ExecuteScriptOptions &options=ExecuteScriptOptions()) override
bool ShouldHide(const StructuredData::ObjectSP &implementor, lldb::StackFrameSP frame_sp) override
bool GenerateWatchpointCommandCallbackData(StringList &input, std::string &output, bool is_callback) override
StructuredData::DictionarySP HandleOptionArgumentCompletionForScriptedCommand(StructuredData::GenericSP impl_obj_sp, llvm::StringRef &long_options, size_t char_in_arg) override
bool RunScriptBasedParsedCommand(StructuredData::GenericSP impl_obj_sp, Args &args, ScriptedCommandSynchronicity synchronicity, lldb_private::CommandReturnObject &cmd_retobj, Status &error, const lldb_private::ExecutionContext &exe_ctx) override
void OptionParsingStartedForCommandObject(StructuredData::GenericSP cmd_obj_sp) override
bool GetLongHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, std::string &dest) override
lldb::ScriptedStopHookInterfaceSP CreateScriptedStopHookInterface() override
Status SetBreakpointCommandCallbackFunction(BreakpointOptions &bp_options, const char *function_name, StructuredData::ObjectSP extra_args_sp) override
Set a script function as the callback for the breakpoint.
lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() override
static bool BreakpointCallbackFunction(void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id)
StructuredData::DictionarySP GetDynamicSettings(StructuredData::ObjectSP plugin_module_sp, Target *target, const char *setting_name, lldb_private::Status &error) override
void CollectDataForWatchpointCommandCallback(WatchpointOptions *wp_options, CommandReturnObject &result) override
StructuredData::DictionarySP HandleArgumentCompletionForScriptedCommand(StructuredData::GenericSP impl_obj_sp, std::vector< llvm::StringRef > &args, size_t args_pos, size_t char_in_arg) override
bool RunScriptBasedCommand(const char *impl_function, llvm::StringRef args, ScriptedCommandSynchronicity synchronicity, lldb_private::CommandReturnObject &cmd_retobj, Status &error, const lldb_private::ExecutionContext &exe_ctx) override
lldb::ScriptedFrameProviderInterfaceSP CreateScriptedFrameProviderInterface() override
std::optional< std::string > GetRepeatCommandForScriptedCommand(StructuredData::GenericSP impl_obj_sp, Args &args) override
Status SetBreakpointCommandCallback(BreakpointOptions &bp_options, const char *callback_body, bool is_callback) override
Set the callback body text into the callback for the breakpoint.
StructuredData::ObjectSP GetArgumentsForCommandObject(StructuredData::GenericSP cmd_obj_sp) override
bool EnterSession(uint16_t on_entry_flags, lldb::FileSP in, lldb::FileSP out, lldb::FileSP err)
void SetWatchpointCommandCallback(WatchpointOptions *wp_options, const char *user_input, bool is_callback) override
Set a one-liner as the callback for the watchpoint.
lldb::ValueObjectSP GetSyntheticValue(const StructuredData::ObjectSP &implementor) override
std::unique_ptr< ScriptInterpreterLocker > AcquireInterpreterLock() override
void CollectDataForBreakpointCommandCallback(std::vector< std::reference_wrapper< BreakpointOptions > > &bp_options_vec, CommandReturnObject &result) override
bool UpdateSynthProviderInstance(const StructuredData::ObjectSP &implementor) override
static void AddToSysPath(AddLocation location, std::string path)
bool MightHaveChildrenSynthProviderInstance(const StructuredData::ObjectSP &implementor) override
bool LoadScriptingModule(const char *filename, const LoadScriptOptions &options, lldb_private::Status &error, StructuredData::ObjectSP *module_sp=nullptr, FileSpec extra_search_dir={}, lldb::TargetSP loaded_into_target_sp={}) override
StructuredData::GenericSP CreateFrameRecognizer(const char *class_name) override
ConstString GetSyntheticTypeName(const StructuredData::ObjectSP &implementor) override
Status GenerateBreakpointCommandCallbackData(StringList &input, std::string &output, bool has_extra_args, bool is_callback) override
lldb::OperatingSystemInterfaceSP CreateOperatingSystemInterface() override
bool SetOptionValueForCommandObject(StructuredData::GenericSP cmd_obj_sp, ExecutionContext *exe_ctx, llvm::StringRef long_option, llvm::StringRef value) override
llvm::Expected< uint32_t > GetIndexOfChildWithName(const StructuredData::ObjectSP &implementor, const char *child_name) override
bool FormatterCallbackFunction(const char *function_name, lldb::TypeImplSP type_impl_sp) override
Status ExportFunctionDefinitionToInterpreter(StringList &function_def) override
StructuredData::ObjectSP CreateSyntheticScriptedProvider(const char *class_name, lldb::ValueObjectSP valobj) override
bool ExecuteOneLine(llvm::StringRef command, CommandReturnObject *result, const ExecuteScriptOptions &options=ExecuteScriptOptions()) override
bool GetDocumentationForItem(const char *item, std::string &dest) override
In Python, a special attribute doc contains the docstring for an object (function,...
lldb::ScriptedHookInterfaceSP CreateScriptedHookInterface() override
uint32_t GetFlagsForCommandObject(StructuredData::GenericSP cmd_obj_sp) override
void IOHandlerInputComplete(IOHandler &io_handler, std::string &data) override
Called when a line or lines have been retrieved.
void IOHandlerActivated(IOHandler &io_handler, bool interactive) override
bool GetScriptedSummary(const char *function_name, lldb::ValueObjectSP valobj, StructuredData::ObjectSP &callee_wrapper_sp, const TypeSummaryOptions &options, std::string &retval) override
lldb::ScriptedFrameInterfaceSP CreateScriptedFrameInterface() override
lldb::ScriptedProcessInterfaceUP CreateScriptedProcessInterface() override
StructuredData::GenericSP CreateScriptCommandObject(const char *class_name) override
size_t CalculateNumChildren(const StructuredData::ObjectSP &implementor, uint32_t max) override
bool ExecuteOneLineWithReturn(llvm::StringRef in_string, ScriptInterpreter::ScriptReturnType return_type, void *ret_value, const ExecuteScriptOptions &options=ExecuteScriptOptions()) override
lldb::ScriptedBreakpointInterfaceSP CreateScriptedBreakpointInterface() override
bool RunScriptFormatKeyword(const char *impl_function, Process *process, std::string &output, Status &error) override
bool SetStdHandle(lldb::FileSP file, const char *py_name, python::PythonObject &save_file, const char *mode)
lldb::ValueObjectSP GetChildAtIndex(const StructuredData::ObjectSP &implementor, uint32_t idx) override
bool GenerateTypeSynthClass(StringList &input, std::string &output, const void *name_token=nullptr) override
StructuredData::ObjectSP CreateStructuredDataFromScriptObject(ScriptObject obj) override
StructuredData::ObjectSP GetOptionsForCommandObject(StructuredData::GenericSP cmd_obj_sp) override
StructuredData::ObjectSP LoadPluginModule(const FileSpec &file_spec, lldb_private::Status &error) override
bool GetShortHelpForCommandObject(StructuredData::GenericSP cmd_obj_sp, std::string &dest) override
llvm::Expected< unsigned > GetMaxPositionalArgumentsForCallable(const llvm::StringRef &callable_name) override
static bool WatchpointCallbackFunction(void *baton, StoppointCallbackContext *context, lldb::user_id_t watch_id)
static lldb::ScriptInterpreterSP CreateInstance(Debugger &debugger)
lldb::ValueObjectListSP GetRecognizedArguments(const StructuredData::ObjectSP &implementor, lldb::StackFrameSP frame_sp) override
lldb::ScriptedThreadPlanInterfaceSP CreateScriptedThreadPlanInterface() override
This base class provides an interface to stack frames.
Definition StackFrame.h:44
An error handling class.
Definition Status.h:118
General Outline: When we hit a breakpoint we need to package up whatever information is needed to eva...
const char * GetData() const
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition Stream.cpp:134
std::shared_ptr< Generic > GenericSP
std::shared_ptr< Dictionary > DictionarySP
std::shared_ptr< Object > ObjectSP
A RAII-friendly terminal state saving/restoring class.
Definition Terminal.h:99
llvm::Error SetEcho(bool enabled)
Definition Terminal.cpp:80
llvm::Error SetCanonical(bool enabled)
Definition Terminal.cpp:96
bool IsATerminal() const
Definition Terminal.cpp:35
int RunSimpleString(const char *str)
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::ScriptedHookInterface > ScriptedHookInterfaceSP
std::shared_ptr< lldb_private::ScriptedStopHookInterface > ScriptedStopHookInterfaceSP
std::shared_ptr< lldb_private::StackFrame > StackFrameSP
std::shared_ptr< lldb_private::ScriptInterpreter > ScriptInterpreterSP
std::shared_ptr< lldb_private::ScriptedThreadPlanInterface > ScriptedThreadPlanInterfaceSP
std::shared_ptr< lldb_private::ValueObject > ValueObjectSP
std::shared_ptr< lldb_private::OperatingSystemInterface > OperatingSystemInterfaceSP
std::shared_ptr< lldb_private::ScriptedBreakpointInterface > ScriptedBreakpointInterfaceSP
std::shared_ptr< lldb_private::ScriptedThreadInterface > ScriptedThreadInterfaceSP
std::shared_ptr< lldb_private::ValueObjectList > ValueObjectListSP
std::shared_ptr< lldb_private::Debugger > DebuggerSP
std::shared_ptr< lldb_private::ScriptedFrameProviderInterface > ScriptedFrameProviderInterfaceSP
uint64_t user_id_t
Definition lldb-types.h:82
std::shared_ptr< lldb_private::TypeImpl > TypeImplSP
std::shared_ptr< lldb_private::Target > TargetSP
std::shared_ptr< lldb_private::File > FileSP
std::unique_ptr< lldb_private::ScriptedProcessInterface > ScriptedProcessInterfaceUP
std::shared_ptr< lldb_private::ScriptedFrameInterface > ScriptedFrameInterfaceSP