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:
Siu Kwan Lam 2013-01-22 10:09:14 -06:00
commit a12c4da93d
23 changed files with 1477 additions and 0 deletions

View 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;
}

View 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_

View 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);
}
};

View 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&);
};
}