Implement SmallVector_Type, pycapsule_new

This commit is contained in:
Siu Kwan Lam 2013-01-23 14:50:17 -06:00
commit 6a861d82e6
8 changed files with 82 additions and 39 deletions

View file

@ -58,23 +58,13 @@ def mangle(name):
name = _re_mangle_pattern.sub(repl, name)
return name.replace('::', '_')
def pycapsule_new(println, ptr, name, clsname, dtor=NULL):
def pycapsule_new(println, ptr, name, clsname):
# build capsule
name_soften = mangle(name)
var = new_symbol('pycap_%s' % name_soften)
fmt = 'PyObject* %(var)s = PyCapsule_New(%(ptr)s, "%(name)s", %(dtor)s);'
fmt = 'PyObject* %(var)s = pycapsule_new(%(ptr)s, "%(name)s", "%(clsname)s");'
println(fmt % locals())
println('if (!%(var)s) return NULL;' % locals())
# build context
fmt = 'new CapsuleContext("%(clsname)s")'
context = declare(println, 'CapsuleContext*', fmt % locals())
fmt = 'PyCapsule_SetContext(%(var)s, (void*)%(context)s)'
err = declare(println, 'int', fmt % locals())
println('if (%(err)s) return NULL;' % locals())
return var

View file

@ -81,7 +81,8 @@ class Context(object):
for name, cls in self.classes.items():
table = cls.mangled_name
println('{ "%(name)s", %(table)s },' % locals())
println('{ NULL },')
println('{ "extra", extra_methodtable },')
println('{ NULL }')
println('};')
println('')
@ -92,6 +93,23 @@ class Context(object):
def generate_py(self, println):
println('import _api, capsule')
println('')
# wraps all extras
extra_wrapper = '''
def _init_extra_wrapper():
def wrap(callee):
def _wrapped(*args):
args = map(capsule.unwrap, args)
ret = callee(*args)
return capsule.wrap(ret)
return _wrapped
for k in dir(_api.extra):
v = getattr(_api.extra, k)
if not k.startswith('__') and callable(v):
globals()[k] = wrap(v)
_init_extra_wrapper()
'''
println(extra_wrapper)
println('')
# global function
for name in self.functions:
println('def %(name)s(*args):' % locals())
@ -190,6 +208,7 @@ def populate_headers(println):
'llvm_binding/binding.h',
'llvm_binding/llvm_extra.h',
'llvm_binding/capsule_context.h',
'llvm_binding/extra.h', # extra submodule to add
]
for inc in includes:
println('#include "%s"' % inc)

View file

@ -51,10 +51,12 @@ create_python_submodule(PyObject* parent, const char* name,
strcpy(fullname + len_parent + 1, name);
PyObject* submod = create_python_module(fullname, methtable);
delete [] fullname;
if (!submod)
if (!submod){
return NULL;
if( -1 == PyModule_AddObject(parent, name, submod) )
}
if (-1 == PyModule_AddObject(parent, name, submod)) {
return NULL;
}
return submod;
}
@ -70,4 +72,5 @@ int populate_submodules(PyObject* parent, SubModuleEntry* entries){
return 0;
}
return 1;
}
}

View file

@ -15,5 +15,27 @@ struct CapsuleContext {
};
static
PyObject* pycapsule_new(void* ptr,
const char* basename,
const char* classname=NULL)
{
if (!classname) {
classname = basename;
}
PyObject* cap = PyCapsule_New(ptr, basename, NULL);
if (!cap) {
PyErr_SetString(PyExc_TypeError, "Error creating new PyCapsule");
return NULL;
}
CapsuleContext* context = new CapsuleContext(classname);
if (PyCapsule_SetContext(cap, context)) {
return NULL;
}
return cap;
}
#endif //LLVMPY_CAPSULE_CONTEXT_H_

View file

@ -0,0 +1,23 @@
#include <Python.h>
#include <llvm/ADT/SmallVector.h>
static
PyObject* small_vector_from_types(PyObject* self, PyObject* args) {
using llvm::Type;
using llvm::SmallVector_Type;
SmallVector_Type* SV = new SmallVector_Type;
Py_ssize_t size = PyTuple_Size(args);
for (Py_ssize_t i = 0; i < size; ++i) {
PyObject* cap = PyTuple_GetItem(args, i);
Type* type = (Type*)PyCapsule_GetPointer(cap, "llvm::Type");
SV->push_back(type);
}
return pycapsule_new(SV, "llvm::SmallVector_Type");
}
static PyMethodDef extra_methodtable[] = {
#define method(func) { #func, (PyCFunction)func, METH_VARARGS, NULL }
method( small_vector_from_types ),
{ NULL }
#undef method
};

View file

@ -32,25 +32,7 @@ private:
void operator = (const raw_svector_ostream_helper&);
};
typedef SmallVector<Type*, 8> SmallVector_Type;
class SmallVector_Type : public SmallVector<Type*, 8> {
public:
static
SmallVector_Type* fromPySequence(PyObject* obj) {
SmallVector_Type* SV = new SmallVector_Type;
Py_ssize_t sz = PySequence_Size(obj);
for (Py_ssize_t i = 0; i < sz; ++i) {
PyObject* item = PySequence_GetItem(obj, i);
PyObject* cap = PyObject_GetAttrString(item, "_ptr");
Type* type = (Type*)PyCapsule_GetPointer(cap, "llvm::Type");
SV->push_back(type);
Py_XDECREF(cap);
Py_XDECREF(item);
}
return SV;
}
};
} // end namespace llvm

View file

@ -0,0 +1,5 @@
from binding import *
from namespace import llvm
SmallVector_Type = llvm.Class()
delete = SmallVector_Type.delete()

View file

@ -1,4 +1,5 @@
import api
import _capsule
api.capsule.set_debug(True)
context = api.getGlobalContext()
@ -26,12 +27,10 @@ print int1ty.isIntegerTy(1)
fnty = api.FunctionType.get(int1ty, False)
fnty.dump()
print
types = [int1ty, api.Type.getIntNTy(context, 21)]
sv = api.SmallVector_Type.fromPySequence(types)
fnty = api.FunctionType.get(int1ty, sv, False)
svt = api.small_vector_from_types(*types)
fnty = api.FunctionType.get(int1ty, svt, False)
os2 = api.raw_svector_ostream_helper.create()
fnty.print_(os2)