Skip to content

Commit cb8d0d2

Browse files
committed
[lldb] Reimplment PyRun_String using the Python stable C API
Reimplement PyRun_String using Py_CompileString and PyEval_EvalCode, which are part of the stable C API. Part of #151617
1 parent 9fdb5e1 commit cb8d0d2

File tree

3 files changed

+46
-24
lines changed

3 files changed

+46
-24
lines changed

lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.cpp

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -498,9 +498,7 @@ PythonInteger::CreateStructuredSignedInteger() const {
498498

499499
// PythonBoolean
500500

501-
PythonBoolean::PythonBoolean(bool value) {
502-
SetValue(value);
503-
}
501+
PythonBoolean::PythonBoolean(bool value) { SetValue(value); }
504502

505503
bool PythonBoolean::Check(PyObject *py_obj) {
506504
return py_obj ? PyBool_Check(py_obj) : false;
@@ -856,15 +854,15 @@ PythonObject PythonCallable::operator()() {
856854
return PythonObject(PyRefType::Owned, PyObject_CallObject(m_py_obj, nullptr));
857855
}
858856

859-
PythonObject PythonCallable::
860-
operator()(std::initializer_list<PyObject *> args) {
857+
PythonObject
858+
PythonCallable::operator()(std::initializer_list<PyObject *> args) {
861859
PythonTuple arg_tuple(args);
862860
return PythonObject(PyRefType::Owned,
863861
PyObject_CallObject(m_py_obj, arg_tuple.get()));
864862
}
865863

866-
PythonObject PythonCallable::
867-
operator()(std::initializer_list<PythonObject> args) {
864+
PythonObject
865+
PythonCallable::operator()(std::initializer_list<PythonObject> args) {
868866
PythonTuple arg_tuple(args);
869867
return PythonObject(PyRefType::Owned,
870868
PyObject_CallObject(m_py_obj, arg_tuple.get()));
@@ -1424,8 +1422,7 @@ Error PythonScript::Init() {
14241422
auto builtins = PythonModule::BuiltinsModule();
14251423
if (Error error = globals.SetItem("__builtins__", builtins))
14261424
return error;
1427-
PyObject *o =
1428-
PyRun_String(script, Py_file_input, globals.get(), globals.get());
1425+
PyObject *o = RunString(script, Py_file_input, globals.get(), globals.get());
14291426
if (!o)
14301427
return exception();
14311428
Take<PythonObject>(o);
@@ -1469,11 +1466,33 @@ python::runStringMultiLine(const llvm::Twine &string,
14691466
const PythonDictionary &locals) {
14701467
if (!globals.IsValid() || !locals.IsValid())
14711468
return nullDeref();
1472-
PyObject *result = PyRun_String(NullTerminated(string), Py_file_input,
1473-
globals.get(), locals.get());
1469+
PyObject *result = RunString(NullTerminated(string), Py_file_input,
1470+
globals.get(), locals.get());
14741471
if (!result)
14751472
return exception();
14761473
return Take<PythonObject>(result);
14771474
}
14781475

1476+
namespace lldb_private {
1477+
namespace python {
1478+
PyObject *RunString(const char *str, int start, PyObject *globals,
1479+
PyObject *locals) {
1480+
const char *filename = "<string>";
1481+
1482+
// Compile the string into a code object.
1483+
PyObject *code = Py_CompileString(str, filename, start);
1484+
if (!code)
1485+
return nullptr;
1486+
1487+
// Execute the code object.
1488+
PyObject *result = PyEval_EvalCode(code, globals, locals);
1489+
1490+
// Clean up the code object.
1491+
Py_DECREF(code);
1492+
1493+
return result;
1494+
}
1495+
} // namespace python
1496+
} // namespace lldb_private
1497+
14791498
#endif

lldb/source/Plugins/ScriptInterpreter/Python/PythonDataObjects.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,8 @@ template <typename T, char F> struct PassthroughFormat {
194194
};
195195

196196
template <> struct PythonFormat<char *> : PassthroughFormat<char *, 's'> {};
197-
template <> struct PythonFormat<const char *> :
198-
PassthroughFormat<const char *, 's'> {};
197+
template <>
198+
struct PythonFormat<const char *> : PassthroughFormat<const char *, 's'> {};
199199
template <> struct PythonFormat<char> : PassthroughFormat<char, 'b'> {};
200200
template <>
201201
struct PythonFormat<unsigned char> : PassthroughFormat<unsigned char, 'B'> {};
@@ -780,6 +780,9 @@ class StructuredPythonObject : public StructuredData::Generic {
780780
operator=(const StructuredPythonObject &) = delete;
781781
};
782782

783+
PyObject *RunString(const char *str, int start, PyObject *globals,
784+
PyObject *locals);
785+
783786
} // namespace python
784787
} // namespace lldb_private
785788

lldb/unittests/ScriptInterpreter/Python/PythonDataObjectsTests.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -632,8 +632,8 @@ TEST_F(PythonDataObjectsTest, TestCallable) {
632632
ASSERT_FALSE(error);
633633

634634
{
635-
PyObject *o = PyRun_String("lambda x : x", Py_eval_input, globals.get(),
636-
globals.get());
635+
PyObject *o =
636+
RunString("lambda x : x", Py_eval_input, globals.get(), globals.get());
637637
ASSERT_FALSE(o == NULL);
638638
auto lambda = Take<PythonCallable>(o);
639639
auto arginfo = lambda.GetArgInfo();
@@ -642,8 +642,8 @@ TEST_F(PythonDataObjectsTest, TestCallable) {
642642
}
643643

644644
{
645-
PyObject *o = PyRun_String("lambda x,y=0: x", Py_eval_input, globals.get(),
646-
globals.get());
645+
PyObject *o = RunString("lambda x,y=0: x", Py_eval_input, globals.get(),
646+
globals.get());
647647
ASSERT_FALSE(o == NULL);
648648
auto lambda = Take<PythonCallable>(o);
649649
auto arginfo = lambda.GetArgInfo();
@@ -652,8 +652,8 @@ TEST_F(PythonDataObjectsTest, TestCallable) {
652652
}
653653

654654
{
655-
PyObject *o = PyRun_String("lambda x,y=0, **kw: x", Py_eval_input,
656-
globals.get(), globals.get());
655+
PyObject *o = RunString("lambda x,y=0, **kw: x", Py_eval_input,
656+
globals.get(), globals.get());
657657
ASSERT_FALSE(o == NULL);
658658
auto lambda = Take<PythonCallable>(o);
659659
auto arginfo = lambda.GetArgInfo();
@@ -662,8 +662,8 @@ TEST_F(PythonDataObjectsTest, TestCallable) {
662662
}
663663

664664
{
665-
PyObject *o = PyRun_String("lambda x,y,*a: x", Py_eval_input, globals.get(),
666-
globals.get());
665+
PyObject *o = RunString("lambda x,y,*a: x", Py_eval_input, globals.get(),
666+
globals.get());
667667
ASSERT_FALSE(o == NULL);
668668
auto lambda = Take<PythonCallable>(o);
669669
auto arginfo = lambda.GetArgInfo();
@@ -673,8 +673,8 @@ TEST_F(PythonDataObjectsTest, TestCallable) {
673673
}
674674

675675
{
676-
PyObject *o = PyRun_String("lambda x,y,*a,**kw: x", Py_eval_input,
677-
globals.get(), globals.get());
676+
PyObject *o = RunString("lambda x,y,*a,**kw: x", Py_eval_input,
677+
globals.get(), globals.get());
678678
ASSERT_FALSE(o == NULL);
679679
auto lambda = Take<PythonCallable>(o);
680680
auto arginfo = lambda.GetArgInfo();
@@ -713,7 +713,7 @@ class NewStyle(object):
713713
714714
)";
715715
PyObject *o =
716-
PyRun_String(script, Py_file_input, globals.get(), globals.get());
716+
RunString(script, Py_file_input, globals.get(), globals.get());
717717
ASSERT_FALSE(o == NULL);
718718
Take<PythonObject>(o);
719719

0 commit comments

Comments
 (0)