@@ -32,6 +32,98 @@ class ScriptedPythonInterface : virtual public ScriptedInterface {
32
32
ScriptedPythonInterface (ScriptInterpreterPythonImpl &interpreter);
33
33
~ScriptedPythonInterface () override = default ;
34
34
35
+ template <typename ... Args>
36
+ llvm::Expected<StructuredData::GenericSP>
37
+ CreatePluginObject (llvm::StringRef class_name,
38
+ StructuredData::Generic *script_obj, Args... args) {
39
+ using namespace python ;
40
+ using Locker = ScriptInterpreterPythonImpl::Locker;
41
+
42
+ bool has_class_name = !class_name.empty ();
43
+ bool has_interpreter_dict =
44
+ !(llvm::StringRef (m_interpreter.GetDictionaryName ()).empty ());
45
+ if (!has_class_name && !has_interpreter_dict && !script_obj) {
46
+ if (!has_class_name)
47
+ return llvm::createStringError (llvm::inconvertibleErrorCode (),
48
+ " Missing script class name." );
49
+ else if (!has_interpreter_dict)
50
+ return llvm::createStringError (
51
+ llvm::inconvertibleErrorCode (),
52
+ " Invalid script interpreter dictionary." );
53
+ else
54
+ return llvm::createStringError (llvm::inconvertibleErrorCode (),
55
+ " Missing scripting object." );
56
+ }
57
+
58
+ Locker py_lock (&m_interpreter, Locker::AcquireLock | Locker::NoSTDIN,
59
+ Locker::FreeLock);
60
+
61
+ PythonObject result = {};
62
+
63
+ if (script_obj) {
64
+ result = PythonObject (PyRefType::Borrowed,
65
+ static_cast <PyObject *>(script_obj->GetValue ()));
66
+ } else {
67
+ auto dict =
68
+ PythonModule::MainModule ().ResolveName <python::PythonDictionary>(
69
+ m_interpreter.GetDictionaryName ());
70
+ if (!dict.IsAllocated ()) {
71
+ return llvm::createStringError (
72
+ llvm::inconvertibleErrorCode (),
73
+ " Could not find interpreter dictionary: %s" ,
74
+ m_interpreter.GetDictionaryName ());
75
+ }
76
+
77
+ auto method =
78
+ PythonObject::ResolveNameWithDictionary<python::PythonCallable>(
79
+ class_name, dict);
80
+ if (!method.IsAllocated ())
81
+ return llvm::createStringError (llvm::inconvertibleErrorCode (),
82
+ " Could not find script class: %s" ,
83
+ class_name.data ());
84
+
85
+ std::tuple<Args...> original_args = std::forward_as_tuple (args...);
86
+ auto transformed_args = TransformArgs (original_args);
87
+
88
+ std::string error_string;
89
+ llvm::Expected<PythonCallable::ArgInfo> arg_info = method.GetArgInfo ();
90
+ if (!arg_info) {
91
+ llvm::handleAllErrors (
92
+ arg_info.takeError (),
93
+ [&](PythonException &E) { error_string.append (E.ReadBacktrace ()); },
94
+ [&](const llvm::ErrorInfoBase &E) {
95
+ error_string.append (E.message ());
96
+ });
97
+ return llvm::createStringError (llvm::inconvertibleErrorCode (),
98
+ error_string);
99
+ }
100
+
101
+ llvm::Expected<PythonObject> expected_return_object =
102
+ llvm::createStringError (llvm::inconvertibleErrorCode (),
103
+ " Resulting object is not initialized." );
104
+
105
+ std::apply (
106
+ [&method, &expected_return_object](auto &&...args ) {
107
+ llvm::consumeError (expected_return_object.takeError ());
108
+ expected_return_object = method (args...);
109
+ },
110
+ transformed_args);
111
+
112
+ if (llvm::Error e = expected_return_object.takeError ())
113
+ return e;
114
+ result = std::move (expected_return_object.get ());
115
+ }
116
+
117
+ if (!result.IsValid ())
118
+ return llvm::createStringError (
119
+ llvm::inconvertibleErrorCode (),
120
+ " Resulting object is not a valid Python Object." );
121
+
122
+ m_object_instance_sp = StructuredData::GenericSP (
123
+ new StructuredPythonObject (std::move (result)));
124
+ return m_object_instance_sp;
125
+ }
126
+
35
127
protected:
36
128
template <typename T = StructuredData::ObjectSP>
37
129
T ExtractValueFromPythonObject (python::PythonObject &p, Status &error) {
@@ -83,10 +175,6 @@ class ScriptedPythonInterface : virtual public ScriptedInterface {
83
175
84
176
PythonObject py_return = std::move (expected_return_object.get ());
85
177
86
- if (!py_return.IsAllocated ())
87
- return ErrorWithMessage<T>(caller_signature, " Returned object is null." ,
88
- error);
89
-
90
178
// Now that we called the python method with the transformed arguments,
91
179
// we need to interate again over both the original and transformed
92
180
// parameter pack, and transform back the parameter that were passed in
@@ -97,6 +185,8 @@ class ScriptedPythonInterface : virtual public ScriptedInterface {
97
185
caller_signature,
98
186
" Couldn't re-assign reference and pointer arguments." , error);
99
187
188
+ if (!py_return.IsAllocated ())
189
+ return {};
100
190
return ExtractValueFromPythonObject<T>(py_return, error);
101
191
}
102
192
@@ -122,6 +212,14 @@ class ScriptedPythonInterface : virtual public ScriptedInterface {
122
212
return python::SWIGBridge::ToSWIGWrapper (arg);
123
213
}
124
214
215
+ python::PythonObject Transform (const StructuredDataImpl &arg) {
216
+ return python::SWIGBridge::ToSWIGWrapper (arg);
217
+ }
218
+
219
+ python::PythonObject Transform (lldb::ExecutionContextRefSP arg) {
220
+ return python::SWIGBridge::ToSWIGWrapper (arg);
221
+ }
222
+
125
223
python::PythonObject Transform (lldb::ProcessAttachInfoSP arg) {
126
224
return python::SWIGBridge::ToSWIGWrapper (arg);
127
225
}
0 commit comments