diff --git a/newbinding/capsule.py b/newbinding/capsule.py index 47c32fb..eaef7da 100644 --- a/newbinding/capsule.py +++ b/newbinding/capsule.py @@ -52,8 +52,10 @@ def wrap(cap): '''Wrap a PyCapsule with the corresponding Wrapper class. If `cap` is not a PyCapsule, returns `cap` ''' - if not _capsule.check(cap): # bypass if cap is not a PyCapsule - return cap + if not _capsule.check(cap): + if isinstance(cap, list): + return map(wrap, cap) + return cap # bypass if cap is not a PyCapsule and not a list addr = _capsule.getPointer(cap) try: # find cached object by pointer address @@ -77,7 +79,7 @@ def wrap(cap): # do auto downcast pass else: - assert oldcls is newcls + assert oldcls is newcls, (cap, obj, oldcls, newcls) return obj def downcast(old, new): diff --git a/newbinding/include/llvm_binding/extra.h b/newbinding/include/llvm_binding/extra.h index 639a87c..9f2bd70 100644 --- a/newbinding/include/llvm_binding/extra.h +++ b/newbinding/include/llvm_binding/extra.h @@ -1,6 +1,7 @@ #include #include #include +#include #include @@ -11,12 +12,14 @@ namespace extra{ SmallVectorImpl *SV; public: static - raw_svector_ostream_helper* create(){ + raw_svector_ostream_helper* create() + { SmallVectorImpl* sv = new SmallVector(); return new raw_svector_ostream_helper(sv); } - ~raw_svector_ostream_helper(){ + ~raw_svector_ostream_helper() + { delete SV; } @@ -36,7 +39,8 @@ namespace extra{ } static -PyObject* make_raw_ostream_for_printing(PyObject* self, PyObject* args) { +PyObject* make_raw_ostream_for_printing(PyObject* self, PyObject* args) +{ using extra::raw_svector_ostream_helper; using llvm::raw_svector_ostream; @@ -49,7 +53,8 @@ PyObject* make_raw_ostream_for_printing(PyObject* self, PyObject* args) { } static -PyObject* make_small_vector_from_types(PyObject* self, PyObject* args) { +PyObject* make_small_vector_from_types(PyObject* self, PyObject* args) +{ using llvm::Type; typedef llvm::SmallVector SmallVector_Type; @@ -69,24 +74,88 @@ PyObject* make_small_vector_from_types(PyObject* self, PyObject* args) { return pycapsule_new(SV, "llvm::SmallVector"); } +static +PyObject* make_small_vector_from_values(PyObject* self, PyObject* args) +{ + using llvm::Value; + typedef llvm::SmallVector SmallVector_Value; + + SmallVector_Value* SV = new SmallVector_Value; + Py_ssize_t size = PyTuple_Size(args); + for (Py_ssize_t i = 0; i < size; ++i) { + PyObject* cap = PyTuple_GetItem(args, i); + if (!cap) { + return NULL; + } + Value* value = (Value*)PyCapsule_GetPointer(cap, "llvm::Value"); + if (!value) { + return NULL; + } + SV->push_back(value); + } + return pycapsule_new(SV, "llvm::SmallVector"); +} + + static PyMethodDef extra_methodtable[] = { #define method(func) { #func, (PyCFunction)func, METH_VARARGS, NULL } method( make_raw_ostream_for_printing ), method( make_small_vector_from_types ), + method( make_small_vector_from_values ), #undef method { NULL } }; //////////// - -PyObject* Value_use_iterator_to_list(llvm::Value* val){ - typedef llvm::Value::use_iterator iterator; +template +PyObject* iterator_to_pylist_deref(iterator begin, iterator end, + const char *capsuleName, const char *className) +{ PyObject* list = PyList_New(0); - for (iterator it = val->use_begin(), end = val->use_end(); it != end; ++it) { - PyObject* cap = pycapsule_new(*it, "llvm::Value", "llvm::User"); + for(; begin != end; ++begin) { + PyObject* cap = pycapsule_new(&*begin, capsuleName, className); PyList_Append(list, cap); } return list; } +template +PyObject* iterator_to_pylist(iterator begin, iterator end, + const char *capsuleName, const char *className) +{ + PyObject* list = PyList_New(0); + for(; begin != end; ++begin) { + PyObject* cap = pycapsule_new(*begin, capsuleName, className); + PyList_Append(list, cap); + } + return list; +} + +template +PyObject* iplist_to_pylist(iplist &IPL, const char * capsuleName, + const char* className){ + return iterator_to_pylist_deref(IPL.begin(), IPL.end(), capsuleName, + className); +} + +static +PyObject* Value_use_iterator_to_list(llvm::Value* val) +{ + return iterator_to_pylist(val->use_begin(), val->use_end(), + "llvm::Value", "llvm::User"); +} + +static +PyObject* Function_getArgumentList(llvm::Function* fn) +{ + return iplist_to_pylist(fn->getArgumentList(), "llvm::Value", + "llvm::Argument"); +} + +static +PyObject* Function_getBasicBlockList(llvm::Function* fn) +{ + return iplist_to_pylist(fn->getBasicBlockList(), "llvm::Value", + "llvm::BasicBlock"); +} \ No newline at end of file diff --git a/newbinding/src/Argument.py b/newbinding/src/Argument.py new file mode 100644 index 0000000..08b35be --- /dev/null +++ b/newbinding/src/Argument.py @@ -0,0 +1,9 @@ +from binding import * +from namespace import llvm +from Value import Argument + +@Argument +class Argument: + _include_ = 'llvm/Argument.h' + + diff --git a/newbinding/src/Function.py b/newbinding/src/Function.py index f069e30..5cebf84 100644 --- a/newbinding/src/Function.py +++ b/newbinding/src/Function.py @@ -1,6 +1,6 @@ from binding import * from namespace import llvm -from Value import GlobalValue, Constant, Function +from Value import GlobalValue, Constant, Function, Argument from Type import Type from DerivedTypes import FunctionType from LLVMContext import LLVMContext @@ -17,3 +17,5 @@ class Function: getIntrinsicID = Method(cast(Unsigned, int)) isIntrinsic = Method(cast(Bool, bool)) + getArgumentList = CustomMethod('Function_getArgumentList', PyObjectPtr) + getBasicBlockList = CustomMethod('Function_getBasicBlockList', PyObjectPtr) diff --git a/newbinding/src/IRBuilder.py b/newbinding/src/IRBuilder.py index 0919a67..41e6681 100644 --- a/newbinding/src/IRBuilder.py +++ b/newbinding/src/IRBuilder.py @@ -2,7 +2,10 @@ from binding import * from namespace import llvm from LLVMContext import LLVMContext from BasicBlock import BasicBlock -from Instruction import ReturnInst +from Instruction import ReturnInst, CallInst +from SmallVector import SmallVector_Value +from StringRef import StringRef +from Value import Value IRBuilder = llvm.Class() @@ -19,3 +22,17 @@ class IRBuilder: isNamePreserving = Method(cast(Bool, bool)) CreateRetVoid = Method(ptr(ReturnInst)) + CreateRet = Method(ptr(ReturnInst), ptr(Value)) + + _CreateCall = Method(ptr(CallInst), ptr(Value), ref(SmallVector_Value), + cast(str, StringRef)) + _CreateCall |= Method(ptr(CallInst), ptr(Value), ref(SmallVector_Value)) + _CreateCall.realname = 'CreateCall' + + @CustomPythonMethod + def CreateCall(self, *args): + import extra + args = list(args) + valuelist = args[1] + args[1] = extra.make_small_vector_from_values(*valuelist) + return IRBuilder._CreateCall(self, *args) diff --git a/newbinding/src/SmallVector.py b/newbinding/src/SmallVector.py index 55dadb1..594faf8 100644 --- a/newbinding/src/SmallVector.py +++ b/newbinding/src/SmallVector.py @@ -5,3 +5,9 @@ from namespace import llvm class SmallVector_Type: _realname_ = 'SmallVector' delete = Destructor() + +@llvm.Class() +class SmallVector_Value: + _realname_ = 'SmallVector' + delete = Destructor() + diff --git a/newbinding/src/Value.py b/newbinding/src/Value.py index 5345337..5b907bd 100644 --- a/newbinding/src/Value.py +++ b/newbinding/src/Value.py @@ -8,6 +8,7 @@ from StringRef import StringRef Value = llvm.Class() # forward declarations +Argument = llvm.Class(Value) User = llvm.Class(Value) BasicBlock = llvm.Class(Value) Constant = llvm.Class(User) diff --git a/newbinding/test2.py b/newbinding/test2.py index 3e54aee..a7a4ddd 100644 --- a/newbinding/test2.py +++ b/newbinding/test2.py @@ -63,11 +63,11 @@ builder.SetInsertPoint(bb) assert bb.getTerminator() is None -builder.CreateRetVoid() +arg0, arg1 = fn.getArgumentList() +print arg0, arg1 -assert not bb.empty() -assert bb.getTerminator() is not None - -print bb +ret = builder.CreateCall(fn, [arg0, arg1], '') +builder.CreateRet(ret) +print fn