From 6a861d82e6a46fca38565946dac1e604c8bcd093 Mon Sep 17 00:00:00 2001 From: Siu Kwan Lam Date: Wed, 23 Jan 2013 14:50:17 -0600 Subject: [PATCH] Implement SmallVector_Type, pycapsule_new --- newbinding/binding.py | 14 ++--------- newbinding/gen.py | 21 ++++++++++++++++- newbinding/include/llvm_binding/binding.h | 9 +++++--- .../include/llvm_binding/capsule_context.h | 22 ++++++++++++++++++ newbinding/include/llvm_binding/extra.h | 23 +++++++++++++++++++ newbinding/include/llvm_binding/llvm_extra.h | 20 +--------------- newbinding/src/SmallVector.py | 5 ++++ newbinding/test2.py | 7 +++--- 8 files changed, 82 insertions(+), 39 deletions(-) create mode 100644 newbinding/include/llvm_binding/extra.h create mode 100644 newbinding/src/SmallVector.py diff --git a/newbinding/binding.py b/newbinding/binding.py index 57d7c7d..c9de593 100644 --- a/newbinding/binding.py +++ b/newbinding/binding.py @@ -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 diff --git a/newbinding/gen.py b/newbinding/gen.py index bfde891..d73b29a 100644 --- a/newbinding/gen.py +++ b/newbinding/gen.py @@ -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) diff --git a/newbinding/include/llvm_binding/binding.h b/newbinding/include/llvm_binding/binding.h index f7bfde6..58a8ad0 100644 --- a/newbinding/include/llvm_binding/binding.h +++ b/newbinding/include/llvm_binding/binding.h @@ -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; -} \ No newline at end of file +} + diff --git a/newbinding/include/llvm_binding/capsule_context.h b/newbinding/include/llvm_binding/capsule_context.h index dacfc89..a4070dc 100644 --- a/newbinding/include/llvm_binding/capsule_context.h +++ b/newbinding/include/llvm_binding/capsule_context.h @@ -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_ diff --git a/newbinding/include/llvm_binding/extra.h b/newbinding/include/llvm_binding/extra.h new file mode 100644 index 0000000..23548ff --- /dev/null +++ b/newbinding/include/llvm_binding/extra.h @@ -0,0 +1,23 @@ +#include +#include + +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 +}; diff --git a/newbinding/include/llvm_binding/llvm_extra.h b/newbinding/include/llvm_binding/llvm_extra.h index 620c3e2..f920a47 100644 --- a/newbinding/include/llvm_binding/llvm_extra.h +++ b/newbinding/include/llvm_binding/llvm_extra.h @@ -32,25 +32,7 @@ private: void operator = (const raw_svector_ostream_helper&); }; +typedef SmallVector SmallVector_Type; -class SmallVector_Type : public SmallVector { -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 diff --git a/newbinding/src/SmallVector.py b/newbinding/src/SmallVector.py new file mode 100644 index 0000000..225c720 --- /dev/null +++ b/newbinding/src/SmallVector.py @@ -0,0 +1,5 @@ +from binding import * +from namespace import llvm + +SmallVector_Type = llvm.Class() +delete = SmallVector_Type.delete() diff --git a/newbinding/test2.py b/newbinding/test2.py index 6cb8a06..6f087c2 100644 --- a/newbinding/test2.py +++ b/newbinding/test2.py @@ -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)