Init commit for work on new binding
This contains the foundation for the new binding as well as early work on Module and Type.
This commit is contained in:
parent
b793e72189
commit
a12c4da93d
23 changed files with 1477 additions and 0 deletions
73
newbinding/include/llvm_binding/binding.h
Normal file
73
newbinding/include/llvm_binding/binding.h
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
#include <Python.h>
|
||||
#include <cstring>
|
||||
|
||||
#if (PY_MAJOR_VERSION >= 3)
|
||||
|
||||
static
|
||||
PyObject*
|
||||
create_python_module(const char *name, PyMethodDef* methtable){
|
||||
PyModuleDef module_def_tmp = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
name,
|
||||
NULL,
|
||||
-1,
|
||||
methtable,
|
||||
NULL, NULL, NULL, NULL
|
||||
};
|
||||
|
||||
PyModuleDef* module_def = new PyModuleDef(module_def_tmp); // will leak??
|
||||
PyObject* module = PyModule_Create(module_def);
|
||||
if (module == NULL){
|
||||
delete module_def;
|
||||
return NULL;
|
||||
}
|
||||
return module;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static
|
||||
PyObject*
|
||||
create_python_module(const char *name, PyMethodDef* methtable){
|
||||
PyObject* module = Py_InitModule(name, methtable);
|
||||
if (module == NULL) return NULL;
|
||||
return module;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static
|
||||
PyObject*
|
||||
create_python_submodule(PyObject* parent, const char* name,
|
||||
PyMethodDef* methtable)
|
||||
{
|
||||
const char* parentname = PyModule_GetName(parent);
|
||||
const unsigned len_parent = strlen(parentname);
|
||||
const unsigned len_sub = strlen(name);
|
||||
const unsigned len = len_parent + 1 + len_sub;
|
||||
char* fullname = new char[len + 1];
|
||||
strcpy(fullname, parentname);
|
||||
fullname[len_parent] = '.';
|
||||
strcpy(fullname + len_parent + 1, name);
|
||||
PyObject* submod = create_python_module(fullname, methtable);
|
||||
delete [] fullname;
|
||||
if (!submod)
|
||||
return NULL;
|
||||
if( -1 == PyModule_AddObject(parent, name, submod) )
|
||||
return NULL;
|
||||
return submod;
|
||||
}
|
||||
|
||||
struct SubModuleEntry{
|
||||
const char* name;
|
||||
PyMethodDef* methtable;
|
||||
};
|
||||
|
||||
static
|
||||
int populate_submodules(PyObject* parent, SubModuleEntry* entries){
|
||||
for(SubModuleEntry* iter = entries; iter->name; ++iter){
|
||||
if (!create_python_submodule(parent, iter->name, iter->methtable))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
48
newbinding/include/llvm_binding/capsule_context.h
Normal file
48
newbinding/include/llvm_binding/capsule_context.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
#ifndef LLVMPY_CAPSULE_CONTEXT_H_
|
||||
#define LLVMPY_CAPSULE_CONTEXT_H_
|
||||
#include <iostream>
|
||||
#include <ctime>
|
||||
|
||||
typedef PyObject* Destructor_Fn;
|
||||
|
||||
static bool CapsuleContextDebug = false;
|
||||
|
||||
struct CapsuleContext {
|
||||
const char* className;
|
||||
Destructor_Fn destructor;
|
||||
|
||||
CapsuleContext(const char* cn, Destructor_Fn dtor=NULL)
|
||||
: className(cn), destructor(dtor) { }
|
||||
};
|
||||
|
||||
void capsule_destructor(PyObject* capsule){
|
||||
using std::cerr;
|
||||
using std::endl;
|
||||
CapsuleContext* context = (CapsuleContext*)PyCapsule_GetContext(capsule);
|
||||
if (context->destructor) {
|
||||
if (CapsuleContextDebug) {
|
||||
cerr << clock()
|
||||
<< " == DEBUG =="
|
||||
<< " destroy pointer: "
|
||||
<< context->className
|
||||
<< endl;
|
||||
}
|
||||
PyObject_CallMethodObjArgs(context->destructor, capsule, NULL);
|
||||
} else {
|
||||
if (CapsuleContextDebug) {
|
||||
cerr << clock()
|
||||
<< " == DEBUG =="
|
||||
<< " keep pointer alive: "
|
||||
<< context->className
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
delete context;
|
||||
}
|
||||
|
||||
void enable_capsule_dtor_debug(bool enabled){
|
||||
CapsuleContextDebug = enabled;
|
||||
}
|
||||
|
||||
#endif //LLVMPY_CAPSULE_CONTEXT_H_
|
||||
|
||||
93
newbinding/include/llvm_binding/conversion.h
Normal file
93
newbinding/include/llvm_binding/conversion.h
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
#include <Python.h>
|
||||
#include <llvm/Support/Casting.h>
|
||||
#include <llvm/ADT/StringRef.h>
|
||||
|
||||
// python object unwrapper
|
||||
|
||||
static
|
||||
int py_str_to(PyObject *strobj, llvm::StringRef &strref){
|
||||
// type check
|
||||
if (!PyString_Check(strobj)) {
|
||||
// raises TypeError
|
||||
PyErr_SetString(PyExc_TypeError, "Expecting a str");
|
||||
return 0;
|
||||
}
|
||||
// get len and buffer
|
||||
const Py_ssize_t len = PyString_Size(strobj);
|
||||
const char * buf = PyString_AsString(strobj);
|
||||
if (!buf) {
|
||||
// raises TypeError
|
||||
return 0;
|
||||
}
|
||||
// set output
|
||||
strref = llvm::StringRef(buf, len);
|
||||
// success
|
||||
return 1;
|
||||
}
|
||||
|
||||
static
|
||||
int py_int_to(PyObject *intobj, unsigned & val){
|
||||
if (!PyInt_Check(intobj)) {
|
||||
// raise TypeError
|
||||
PyErr_SetString(PyExc_TypeError, "Expecting an int");
|
||||
return 0;
|
||||
}
|
||||
val = PyInt_AsUnsignedLongMask(intobj);
|
||||
// success
|
||||
return 1;
|
||||
}
|
||||
|
||||
static
|
||||
int py_bool_to(PyObject *boolobj, bool & val){
|
||||
if (!PyBool_Check(boolobj)) {
|
||||
// raise TypeError
|
||||
PyErr_SetString(PyExc_TypeError, "Expecting a bool");
|
||||
return 0;
|
||||
}
|
||||
if (boolobj == Py_True) {
|
||||
val = true;
|
||||
} else if (boolobj == Py_False) {
|
||||
val = false;
|
||||
} else {
|
||||
PyErr_SetString(PyExc_TypeError, "Invalid boolean object");
|
||||
return 0;
|
||||
}
|
||||
// success
|
||||
return 1;
|
||||
}
|
||||
|
||||
// python object wrapper
|
||||
|
||||
static
|
||||
PyObject* py_str_from(const std::string &str){
|
||||
return PyString_FromStringAndSize(str.c_str(), str.size());
|
||||
}
|
||||
|
||||
static
|
||||
PyObject* py_bool_from(bool val){
|
||||
if (val) {
|
||||
Py_RETURN_TRUE;
|
||||
} else {
|
||||
Py_RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
PyObject* py_int_from(int val){
|
||||
return PyInt_FromLong(val);
|
||||
}
|
||||
|
||||
// casting
|
||||
template<class Td>
|
||||
struct typecast {
|
||||
template<class Ts> static
|
||||
Td* from(Ts* src) {
|
||||
return llvm::dyn_cast<Td>(src);
|
||||
}
|
||||
|
||||
static
|
||||
Td* from(void* src) {
|
||||
return static_cast<Td*>(src);
|
||||
}
|
||||
};
|
||||
|
||||
34
newbinding/include/llvm_binding/extra.h
Normal file
34
newbinding/include/llvm_binding/extra.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
#include <Python.h>
|
||||
#include <llvm/ADT/SmallVector.h>
|
||||
#include <llvm/Support/raw_ostream.h>
|
||||
|
||||
namespace llvm{
|
||||
|
||||
class raw_svector_ostream_helper: public raw_svector_ostream {
|
||||
SmallVectorImpl<char> *SV;
|
||||
public:
|
||||
static
|
||||
raw_svector_ostream_helper* create(){
|
||||
SmallVectorImpl<char>* sv = new SmallVector<char, 16>();
|
||||
return new raw_svector_ostream_helper(sv);
|
||||
}
|
||||
|
||||
~raw_svector_ostream_helper(){
|
||||
delete SV;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
explicit
|
||||
raw_svector_ostream_helper(SmallVectorImpl<char>* sv)
|
||||
: raw_svector_ostream(*sv), SV(sv) {}
|
||||
|
||||
private:
|
||||
// no copy
|
||||
raw_svector_ostream_helper(const raw_svector_ostream_helper&);
|
||||
// no assign
|
||||
void operator = (const raw_svector_ostream_helper&);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue