Completed binding for most of ExecutionEngine
This commit is contained in:
parent
25b498c8fa
commit
78f9c9a610
9 changed files with 391 additions and 9 deletions
|
|
@ -25,6 +25,45 @@ int py_str_to(PyObject *strobj, llvm::StringRef &strref){
|
|||
return 1;
|
||||
}
|
||||
|
||||
static
|
||||
int py_str_to(PyObject *strobj, std::string &strref){
|
||||
// type check
|
||||
if (!PyString_Check(strobj)) {
|
||||
// raises TypeError
|
||||
PyErr_SetString(PyExc_TypeError, "Expecting a str");
|
||||
return 0;
|
||||
}
|
||||
// get len and buffer
|
||||
const char * buf = PyString_AsString(strobj);
|
||||
if (!buf) {
|
||||
// raises TypeError
|
||||
return 0;
|
||||
}
|
||||
// set output
|
||||
strref = std::string(buf);
|
||||
// success
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int py_str_to(PyObject *strobj, const char* &strref){
|
||||
// type check
|
||||
if (!PyString_Check(strobj)) {
|
||||
// raises TypeError
|
||||
PyErr_SetString(PyExc_TypeError, "Expecting a str");
|
||||
return 0;
|
||||
}
|
||||
// get buffer
|
||||
strref = PyString_AsString(strobj);
|
||||
if (!strref) {
|
||||
// raises TypeError
|
||||
return 0;
|
||||
}
|
||||
// success
|
||||
return 1;
|
||||
}
|
||||
|
||||
static
|
||||
int py_int_to(PyObject *intobj, unsigned & val){
|
||||
if (!PyInt_Check(intobj)) {
|
||||
|
|
@ -37,6 +76,70 @@ int py_int_to(PyObject *intobj, unsigned & val){
|
|||
return 1;
|
||||
}
|
||||
|
||||
static
|
||||
int py_int_to(PyObject *intobj, unsigned long long & val){
|
||||
if (!PyInt_Check(intobj)) {
|
||||
// raise TypeError
|
||||
puts(PyString_AsString(PyObject_Str(PyObject_Type(intobj))));
|
||||
PyErr_SetString(PyExc_TypeError, "Expecting an int 2");
|
||||
return 0;
|
||||
}
|
||||
val = PyInt_AsUnsignedLongLongMask(intobj);
|
||||
// success
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
static
|
||||
int py_int_to(PyObject *intobj, size_t & val){
|
||||
unsigned long long ull;
|
||||
if (py_int_to(intobj, ull)) {
|
||||
val = (size_t)ull;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int py_int_to(PyObject *intobj, void* & val){
|
||||
if (!PyLong_Check(intobj)) {
|
||||
// raise TypeError
|
||||
PyErr_SetString(PyExc_TypeError, "Expecting an int");
|
||||
return 0;
|
||||
}
|
||||
val = PyLong_FromVoidPtr(intobj);
|
||||
// success
|
||||
return 1;
|
||||
}
|
||||
|
||||
static
|
||||
int py_float_to(PyObject *floatobj, double & val){
|
||||
if (!PyFloat_Check(floatobj)) {
|
||||
// raise TypeError
|
||||
PyErr_SetString(PyExc_TypeError, "Expecting a float");
|
||||
return 0;
|
||||
}
|
||||
val = PyFloat_AsDouble(floatobj);
|
||||
if (PyErr_Occurred()){
|
||||
return 0;
|
||||
}
|
||||
// success
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int py_float_to(PyObject *floatobj, float & val){
|
||||
double db;
|
||||
int status = py_float_to(floatobj, db);
|
||||
if (status)
|
||||
val = db;
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
int py_bool_to(PyObject *boolobj, bool & val){
|
||||
if (!PyBool_Check(boolobj)) {
|
||||
|
|
@ -78,8 +181,18 @@ PyObject* py_bool_from(bool val){
|
|||
}
|
||||
|
||||
static
|
||||
PyObject* py_int_from(int val){
|
||||
return PyInt_FromLong(val);
|
||||
PyObject* py_int_from(const long long & val){
|
||||
return PyLong_FromLongLong(val);
|
||||
}
|
||||
|
||||
static
|
||||
PyObject* py_int_from(void * addr){
|
||||
return PyLong_FromVoidPtr(addr);
|
||||
}
|
||||
|
||||
static
|
||||
PyObject* py_float_from(const double& val) {
|
||||
return PyFloat_FromDouble(val);
|
||||
}
|
||||
|
||||
// casting
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include <llvm/Function.h>
|
||||
#include <llvm/Support/raw_ostream.h>
|
||||
#include <llvm/ExecutionEngine/ExecutionEngine.h>
|
||||
#include <llvm/ExecutionEngine/GenericValue.h>
|
||||
|
||||
namespace extra{
|
||||
using namespace llvm;
|
||||
|
|
@ -234,3 +235,108 @@ llvm::ExecutionEngine* ExecutionEngine_createJIT(
|
|||
PyFile_WriteString(ErrorStr.c_str(), errout);
|
||||
return ee;
|
||||
}
|
||||
|
||||
static
|
||||
llvm::GenericValue* GenericValue_CreateInt(llvm::Type* Ty, unsigned long long N,
|
||||
bool IsSigned)
|
||||
{
|
||||
// Shamelessly copied from LLVM
|
||||
llvm::GenericValue *GenVal = new llvm::GenericValue();
|
||||
GenVal->IntVal = llvm::APInt(Ty->getIntegerBitWidth(), N, IsSigned);
|
||||
return GenVal;
|
||||
}
|
||||
|
||||
static
|
||||
llvm::GenericValue* GenericValue_CreateFloat(float Val)
|
||||
{
|
||||
llvm::GenericValue *GenVal = new llvm::GenericValue();
|
||||
GenVal->FloatVal = Val;
|
||||
return GenVal;
|
||||
}
|
||||
|
||||
static
|
||||
llvm::GenericValue* GenericValue_CreateDouble(double Val)
|
||||
{
|
||||
llvm::GenericValue *GenVal = new llvm::GenericValue();
|
||||
GenVal->DoubleVal = Val;
|
||||
return GenVal;
|
||||
}
|
||||
|
||||
static
|
||||
llvm::GenericValue* GenericValue_CreatePointer(void * Ptr)
|
||||
{
|
||||
llvm::GenericValue *GenVal = new llvm::GenericValue();
|
||||
GenVal->PointerVal = Ptr;
|
||||
return GenVal;
|
||||
}
|
||||
|
||||
static
|
||||
unsigned GenericValue_ValueIntWidth(llvm::GenericValue *GenValRef)
|
||||
{
|
||||
return GenValRef->IntVal.getBitWidth();
|
||||
}
|
||||
|
||||
static
|
||||
unsigned long long GenericValue_ToUnsignedInt(llvm::GenericValue* GenVal)
|
||||
{
|
||||
return GenVal->IntVal.getZExtValue();
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
long long GenericValue_ToSignedInt(llvm::GenericValue* GenVal)
|
||||
{
|
||||
return GenVal->IntVal.getSExtValue();
|
||||
}
|
||||
|
||||
static
|
||||
void* GenericValue_ToPointer(llvm::GenericValue* GenVal)
|
||||
{
|
||||
return GenVal->PointerVal;
|
||||
}
|
||||
|
||||
static
|
||||
double GenericValue_ToFloat(llvm::GenericValue* GenVal, llvm::Type* Ty)
|
||||
{
|
||||
switch (Ty->getTypeID()) {
|
||||
case llvm::Type::FloatTyID:
|
||||
return GenVal->FloatVal;
|
||||
default:
|
||||
// Behavior undefined if type is not a float or a double
|
||||
return GenVal->DoubleVal;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
PyObject* ExecutionEngine_RunFunction(llvm::ExecutionEngine* EE,
|
||||
llvm::Function* Fn, PyObject* Args)
|
||||
{
|
||||
using namespace llvm;
|
||||
const char * GVN = "llvm::GenericValue";
|
||||
if (!PyTuple_Check(Args)) {
|
||||
PyErr_SetString(PyExc_TypeError, "Expect a tuple of args.");
|
||||
return NULL;
|
||||
}
|
||||
std::vector<GenericValue> vec_args;
|
||||
Py_ssize_t nargs = PyTuple_Size(Args);
|
||||
vec_args.reserve(nargs);
|
||||
for (Py_ssize_t i = 0; i < nargs; ++i) {
|
||||
PyObject* obj = PyTuple_GetItem(Args, i);
|
||||
if (!obj) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "Failed to index into args?");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GenericValue* gv = static_cast<GenericValue*>(
|
||||
PyCapsule_GetPointer(obj, GVN));
|
||||
|
||||
if (!gv) {
|
||||
return NULL;
|
||||
}
|
||||
vec_args.push_back(*gv);
|
||||
}
|
||||
|
||||
GenericValue ret = EE->runFunction(Fn, vec_args);
|
||||
return pycapsule_new(new GenericValue(ret), GVN);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue