Skip to content

Commit

Permalink
fix: function pointer binding
Browse files Browse the repository at this point in the history
  • Loading branch information
Ziqi-Yang committed Aug 8, 2024
1 parent a79d254 commit aa1ed2e
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 2,099 deletions.
2 changes: 1 addition & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
project = 'llvmpym'
copyright = '2024, Meow King'
author = 'Meow King'
release = '0.0.4'
release = '0.0.5'

# -- General configuration ---------------------------------------------------
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
Expand Down
9 changes: 2 additions & 7 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,8 @@ Status
"``BitWriter.h``", "``core``"
"", "``utils``"

- All functions that operates on lambda functions(function pointers) is not bound
or handled incorrectly. Typically those parameters'(or returned value's) type name ends
with `Hanlder` or `Callback`, e.g. `LLVMDiagnosticHandler`, `LLVMYieldCallback`. Though
very few API operates on lambda functions.

- All functions accepts or return a void pointer (`void *`) is not bound. Though
very few API accepts or return a void pointer.
- All functions accepts or return a void pointer (`void *`) is not bound (including
lambda functions/function pointers). Though very few API accepts or return a void pointer.


Table of contents
Expand Down
12 changes: 2 additions & 10 deletions example/el_psy_congaroo.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,2 @@
# Note use `pip install .` to install this package
# In `pip install --no-build-isolation -ve .` mode it won't work

import llvmpym.core as core

c = core.Context.get_global_context()
s = r'target triple = "unknown-unknown-unknown"'
mem_buf = core.MemoryBuffer.from_str(s, "")
res = c.parse_ir(mem_buf)
print(res)
from llvmpym import error_handling
error_handling.install_fatal_error_handler(lambda s: print(s))
24 changes: 18 additions & 6 deletions src/llvm/Core/miscClasses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <fmt/core.h>
#include <optional>
#include <stdexcept>
#include <functional>
#include "../types_priv.h"
#include "../utils_priv.h"
#include "utils.h"
Expand Down Expand Up @@ -1268,12 +1269,23 @@ void bindOtherClasses(nb::module_ &m) {
"will be available in the IR.\n"
"This can be used to save memory and runtime, "
"especially in release mode."))
.def("set_diagnostic_handler", // FIXME
[](PymContext &c, LLVMDiagnosticHandler handler, void * diagnosticContext){
return LLVMContextSetDiagnosticHandler(c.get(), handler, diagnosticContext);
},
"handler"_a, "diagnostic_context"_a,
"Set the diagnostic handler for this context.")
// .def("set_diagnostic_handler",
// [](PymContext &c,
// std::function<void(PymDiagnosticInfo, nb::any)> handler,
// nb::any diagnosticContext){
// static std::function<void(PymDiagnosticInfo, nb::any)> *callback =
// new std::function<void(PymDiagnosticInfo, nb::any)>(std::move(handler));
// return LLVMContextSetDiagnosticHandler
// (c.get(),
// [](LLVMDiagnosticInfoRef di, void * v) {
// if (callback) {
// (*callback)(PymDiagnosticInfo(di), nb::any(v)); // FIXME
// }
// },
// &diagnosticContext);
// },
// "handler"_a, "diagnostic_context"_a,
// "Set the diagnostic handler for this context.")
// .def("get_diagnostic_handler", FIXME
// [](PymContext &c) { return LLVMContextGetDiagnosticHandler(c.get()); },
// "Get the diagnostic handler of this context.")
Expand Down
9 changes: 8 additions & 1 deletion src/llvm/Disassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ namespace nb = nanobind;
using namespace nb::literals;

void populateDisassembler(nb::module_ &m) {
// m.def("create_disasm")
auto DisasmContextClass =
nb::class_<PymDisasmContext, PymLLVMObject<PymDisasmContext, LLVMDisasmContextRef>>
(m, "DisasmContext", "DisasmContext");

// DisasmContextClass
// .def("__init__",
// [](PymDisasmContext *dc, const char *tripleName, nb::any DisInfo,
// int tagType, LLVM));
}

23 changes: 20 additions & 3 deletions src/llvm/ErrorHandling.cpp
Original file line number Diff line number Diff line change
@@ -1,20 +1,37 @@
#include <nanobind/nanobind.h>
#include <nanobind/stl/function.h>
#include <nanobind/stl/shared_ptr.h>
#include <functional>
#include <llvm-c/ErrorHandling.h>
#include "ErrorHandling.h"
#include <memory>

namespace nb = nanobind;
using namespace nb::literals;

namespace nb = nanobind;
using namespace nb::literals;

void populateErrorHandling(nb::module_ &m) {
// FIXME doesn't work: https://github.com/wjakob/nanobind/discussions/616#discussioncomment-10097607
m.def("install_fatal_error_handler", &LLVMInstallFatalErrorHandler, "handler"_a,
m.def("install_fatal_error_handler",
[](std::function<void(const char*)> handler) {
// NOTE a raw pointer is required, which allows explicit control over the
// callback's lifetime, avoiding issues with the Python interpreter's shutdown process.
static std::function<void(const char*)> *callback =
new std::function<void(const char*)>(std::move(handler));

LLVMInstallFatalErrorHandler([](const char *reason) {
if (callback) {
(*callback)(reason);
}
});
},
"handler"_a,
"Install a fatal error handler. By default, if LLVM detects a fatal error, it"
"will call exit(1). This may not be appropriate in many contexts. For example,"
"doing exit(1) will bypass many crash reporting/tracing system tools. This"
"function allows you to install a callback that will be invoked prior to the"
"call to exit(1).");

m.def("reset_fatal_error_handler", &LLVMResetFatalErrorHandler,
"Reset the fatal error handler. This resets LLVM's fatal error handling"
"behavior to the default.");
Expand Down
59 changes: 40 additions & 19 deletions src/llvm/Support.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@
#include <vector>
#include <llvm-c/Support.h>

#include <iostream>

namespace nb = nanobind;
using namespace nb::literals;


void populateSupport(nb::module_ &m) {

m.def("load_library_permanently",
Expand All @@ -27,23 +30,41 @@ void populateSupport(nb::module_ &m) {
"the same way across LLVM versions.");


// FIXME seems not practical in python side
// m.def("search_for_address_of_symbol",
// [](const char *symbolName) {
// return LLVMSearchForAddressOfSymbol(symbolName);
// },
// "name"_a,
// "This function will search through all previously loaded dynamic"
// "libraries for the symbol symbolName. If it is found, the address of"
// "that symbol is returned. If not, null is returned.");

// m.def("add_symbol",
// [](const char *symbolName, nb::any symbolValue) {
// // the passed value is nb::any*, but not void *
// return LLVMAddSymbol(symbolName, &symbolValue);
// },
// "symbol_name"_a, "symbol_value"_a,
// "This functions permanently adds the symbol symbolName with the"
// "value symbolValue. These symbols are searched before any"
// "libraries.");
// FIXME
// can work, but the returned type is an capsule object, which can only be
// passed into binding functions, so if we want to do operation based on
// the returned address like `static_cast`, then we need to define a function
// for it
m.def("search_for_address_of_symbol",
[](const char *symbolName) {
return LLVMSearchForAddressOfSymbol(symbolName);
},
"name"_a,
"This function will search through all previously loaded dynamic"
"libraries for the symbol symbolName. If it is found, the address of"
"that symbol is returned. If not, null is returned.");

// seems to work correctly
// test example:
//
// for static void *x;
//
// [](nb::any a) {
// x = &a;
// }

// and then
// std::cout << x << std::endl;
// std::cout << *(static_cast<int *>(x)) << std::endl;
//
// 0x7fffffff7d20
// 1
m.def("add_symbol",
[](const char *symbolName, nb::any symbolValue) {
return LLVMAddSymbol(symbolName, &symbolValue);
},
"symbol_name"_a, "symbol_value"_a,
"This functions permanently adds the symbol symbolName with the"
"value symbolValue. These symbols are searched before any"
"libraries.");
}
Loading

0 comments on commit aa1ed2e

Please sign in to comment.