Implement SmallVector_Type, pycapsule_new
This commit is contained in:
parent
ef4c0d3be3
commit
6a861d82e6
8 changed files with 82 additions and 39 deletions
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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_
|
||||
|
||||
|
|
|
|||
23
newbinding/include/llvm_binding/extra.h
Normal file
23
newbinding/include/llvm_binding/extra.h
Normal 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
|
||||
};
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
5
newbinding/src/SmallVector.py
Normal file
5
newbinding/src/SmallVector.py
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
from binding import *
|
||||
from namespace import llvm
|
||||
|
||||
SmallVector_Type = llvm.Class()
|
||||
delete = SmallVector_Type.delete()
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue