Skip to content

Commit b20b52f

Browse files
committed
runtime: Add atexit callbacks
1 parent fee2c03 commit b20b52f

4 files changed

Lines changed: 43 additions & 1 deletion

File tree

src/executable/bytecode/BytecodeProgram.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,11 @@ int BytecodeProgram::execute(VirtualMachine *vm)
144144
std::cout << exception->format_traceback() << std::endl;
145145
}
146146

147+
{
148+
[[maybe_unused]] auto push_result = vm->push_frame(1, 0, 0);
149+
[[maybe_unused]] auto final_result = interpreter.finalise();
150+
}
151+
147152
return result.is_ok() ? EXIT_SUCCESS : EXIT_FAILURE;
148153
}
149154

src/interpreter/Interpreter.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
#include <cstdio>
2929
#include <filesystem>
30+
#include <ranges>
3031
#include <unistd.h>
3132

3233
namespace fs = std::filesystem;
@@ -495,4 +496,32 @@ void Interpreter::visit_graph(::Cell::Visitor &visitor)
495496
if (m_codec_error_registry) visitor.visit(*m_codec_error_registry);
496497
if (m_codec_search_path) visitor.visit(*m_codec_search_path);
497498
if (m_codec_search_path_cache) visitor.visit(*m_codec_search_path_cache);
499+
500+
for (auto [callback, args] : m_callbacks) {
501+
if (callback) visitor.visit(*callback);
502+
if (args) visitor.visit(*args);
503+
}
504+
}
505+
506+
void Interpreter::register_callback(PyObject *callback, PyTuple *args)
507+
{
508+
m_callbacks.emplace_back(callback, args);
509+
}
510+
511+
void Interpreter::unregister_callback(PyObject *callback)
512+
{
513+
m_callbacks.erase(
514+
std::ranges::remove(m_callbacks, callback, [](const auto &el) { return std::get<0>(el); })
515+
.begin(),
516+
m_callbacks.end());
517+
}
518+
519+
PyResult<std::monostate> Interpreter::finalise()
520+
{
521+
// TODO: capture exceptions, and raise last one
522+
for (auto [callback, args] : m_callbacks) {
523+
[[maybe_unused]] auto result = callback->call(args, nullptr);
524+
}
525+
526+
return Ok(std::monostate{});
498527
}

src/interpreter/Interpreter.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include <string>
88
#include <string_view>
9+
#include <variant>
910

1011
class BytecodeProgram;
1112

@@ -34,6 +35,7 @@ class Interpreter
3435
py::PyDict *m_codec_search_path_cache{ nullptr };
3536
std::string m_entry_script;
3637
std::vector<std::string> m_argv;
38+
std::vector<std::tuple<py::PyObject *, py::PyTuple *>> m_callbacks;
3739

3840
public:
3941
struct Config
@@ -89,6 +91,8 @@ class Interpreter
8991
void setup(std::shared_ptr<BytecodeProgram> &&program);
9092
void setup_main_interpreter(std::shared_ptr<BytecodeProgram> &&program);
9193

94+
py::PyResult<std::monostate> finalise();
95+
9296
const std::string &entry_script() const { return m_entry_script; }
9397
const std::vector<std::string> &argv() const { return m_argv; }
9498

@@ -107,6 +111,10 @@ class Interpreter
107111
py::PyTuple *args,
108112
py::PyDict *kwargs);
109113

114+
115+
void register_callback(py::PyObject *callback, py::PyTuple *args);
116+
void unregister_callback(py::PyObject *callback);
117+
110118
void visit_graph(::Cell::Visitor &);
111119

112120
private:

src/repl/repl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,4 +230,4 @@ int main(int argc, char **argv)
230230
// }
231231

232232
return EXIT_SUCCESS;
233-
}
233+
}

0 commit comments

Comments
 (0)