diff --git a/CHANGELOG b/CHANGELOG index c50e19a..45d6a5f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,23 @@ -2013-02-04 0.12.2: +2014-04-28 0.12.5: +--------------------- + * Fixes memory leaks (#92) + * Fixes tarball (#99) + +2014-03-20 0.12.4: +--------------------- + * Add dylib_import_library and friends + * Fix BasicBlock downcast + * Module hashing + * Fix test script + +2014-02-18 0.12.3: +--------------------- + * Fix deprecation message for py2.6 + * Fix llvm_cbuilder for using deprecated_alloca + * Merged PR #88 by cantora + * Merged PR #94 by cgohlke + +2014-02-04 0.12.2: --------------------- * enhance wrapper efficiency by moving some capsule code into C++ * fix unclosed file handler in avx_support diff --git a/MANIFEST.in b/MANIFEST.in index 295794c..25a211d 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,5 +1,6 @@ -include CHANGELOG LICENSE README setup.py MANIFEST.in +include CHANGELOG LICENSE README.rst setup.py MANIFEST.in versioneer.py recursive-include llvm * +recursive-include llvmpy * recursive-include www * recursive-include test * recursive-include tools * diff --git a/README.rst b/README.rst index 0fbcd24..a1abf84 100644 --- a/README.rst +++ b/README.rst @@ -30,10 +30,13 @@ Quickstart to separate your custom build from the default system package. Please replace ``LLVM_INSTALL_PATH`` with your own path. -3. Run ``REQUIRES_RTTI=1 make`` to build. +3. Run ``REQUIRES_RTTI=1 make install`` to build and install. **Note**: With LLVM 3.2, the default build configuration has C++ RTTI disabled. However, llvmpy requires RTTI. + + **Note**: Use ``make -j2 install`` to enable concurrent build. + Replace ``2`` with the actual number of processor you have. 4. Get llvm-py and install it:: diff --git a/buildscripts/condarecipe/run_test.py b/buildscripts/condarecipe/run_test.py index 653515f..682b8d4 100644 --- a/buildscripts/condarecipe/run_test.py +++ b/buildscripts/condarecipe/run_test.py @@ -15,8 +15,8 @@ if sys.platform == 'darwin': s = {'64bit': 'x86_64', '32bit': 'x86'}[platform.architecture()[0]] assert target.triple.startswith(s + '-apple-darwin') -assert llvm.test(verbosity=2) == 0 -check_intrinsics.main() +assert llvm.test(verbosity=2, run_isolated=False) == 0 +#check_intrinsics.main() print('llvm.__version__: %s' % llvm.__version__) #assert llvm.__version__ == '0.12.0' diff --git a/llvm/__init__.py b/llvm/__init__.py index 11cf7bc..9b24112 100644 --- a/llvm/__init__.py +++ b/llvm/__init__.py @@ -34,14 +34,14 @@ def _extract_ptrs(objs): class LLVMException(Exception): pass -def test(verbosity=3): +def test(verbosity=3, run_isolated=True): """test(verbosity=1) -> TextTestResult Run self-test, and return the number of failures + errors """ from llvm.tests import run - result = run(verbosity=verbosity) + result = run(verbosity=verbosity, run_isolated=run_isolated) errct = len(result.failures) + len(result.errors) return errct diff --git a/llvm/core.py b/llvm/core.py index 650bb90..4db8135 100644 --- a/llvm/core.py +++ b/llvm/core.py @@ -452,12 +452,12 @@ class Module(llvm.Wrapper): """ return str(self._ptr) + def __hash__(self): + return id(self._ptr) + def __eq__(self, rhs): - assert isinstance(rhs, Module), type(rhs) if isinstance(rhs, Module): - return str(self) == str(rhs) - else: - return False + return self._ptr == rhs._ptr def __ne__(self, rhs): return not (self == rhs) diff --git a/llvm/deprecated.py b/llvm/deprecated.py index 98d695f..6db5fe7 100644 --- a/llvm/deprecated.py +++ b/llvm/deprecated.py @@ -15,7 +15,7 @@ def deprecated(func): @functools.wraps(func) def new_func(*args, **kwargs): warnings.warn_explicit( - "Call to deprecated function {}.".format(func.__name__), + "Call to deprecated function %s." % (func.__name__,), category=DeprecationWarning, filename=func.func_code.co_filename, lineno=func.func_code.co_firstlineno + 1 diff --git a/llvm/ee.py b/llvm/ee.py index c687eaa..f615b61 100644 --- a/llvm/ee.py +++ b/llvm/ee.py @@ -238,3 +238,27 @@ def dylib_add_symbol(name, ptr): def dylib_address_of_symbol(name): return api.llvm.sys.DynamicLibrary.SearchForAddressOfSymbol(name) + +def dylib_import_library(filename): + """Permanently import a dynamic library. + + Returns a DynamicLibrary object + + Raises RuntimeError + """ + return DynamicLibrary(filename) + + +class DynamicLibrary(object): + def __init__(self, filename): + """ + Raises RuntimeError + """ + self._ptr = api.llvm.sys.DynamicLibrary.getPermanentLibrary( + filename) + + def get_address_of_symbol(self, symbol): + """ + Get the address of `symbol` (str) as integer + """ + return self._ptr.getAddressOfSymbol(symbol) diff --git a/llvm/tests/__init__.py b/llvm/tests/__init__.py index 67102c7..0bc4223 100644 --- a/llvm/tests/__init__.py +++ b/llvm/tests/__init__.py @@ -12,7 +12,7 @@ tests = [] # stores unittest.TestCase objects isolated_tests = [] # stores modue name -def run(verbosity=1): +def run(verbosity=1, run_isolated=True): print('llvmpy is installed in: ' + os.path.dirname(__file__)) print('llvmpy version: ' + llvm.__version__) print(sys.version) @@ -48,7 +48,7 @@ def run(verbosity=1): testresult = runner.run(suite) print(hp.heap()) - if testresult: + if testresult and run_isolated: # Run isolated tests print("run isolated tests".center(80, '-')) diff --git a/llvm_cbuilder/builder.py b/llvm_cbuilder/builder.py index eaabd67..a2c0bda 100644 --- a/llvm_cbuilder/builder.py +++ b/llvm_cbuilder/builder.py @@ -349,7 +349,7 @@ class CBuilder(object): elif not isinstance(count, lc.Value): count = self.constant(types.int, count).value - ptr = self.builder.alloca_array(ty, count, name=name) + ptr = self.builder.alloca(ty, size=count, name=name) return CArray(self, ptr) def ret(self, val=None): diff --git a/llvmpy/gen/gen.py b/llvmpy/gen/gen.py index cd63b68..bb408a1 100644 --- a/llvmpy/gen/gen.py +++ b/llvmpy/gen/gen.py @@ -9,7 +9,7 @@ extern "C" { #if (PY_MAJOR_VERSION >= 3) -PyObject * +PyMODINIT_FUNC PyInit_%(module)s(void) { PyObject *module = create_python_module("%(module)s", meth_%(ns)s); diff --git a/llvmpy/include/llvm_binding/extra.h b/llvmpy/include/llvm_binding/extra.h index f8f7766..bdd86d3 100644 --- a/llvmpy/include/llvm_binding/extra.h +++ b/llvmpy/include/llvm_binding/extra.h @@ -40,7 +40,7 @@ namespace extra{ using namespace llvm; - + class raw_svector_ostream_helper: public raw_svector_ostream { SmallVectorImpl *SV; public: @@ -85,7 +85,7 @@ PyObject* make_raw_ostream_for_printing(PyObject* self, PyObject* args) { using extra::raw_svector_ostream_helper; using llvm::raw_svector_ostream; - + if (!PyArg_ParseTuple(args, "")) { return NULL; } @@ -99,7 +99,7 @@ PyObject* make_small_vector_from_types(PyObject* self, PyObject* args) { using llvm::Type; typedef llvm::SmallVector SmallVector_Type; - + SmallVector_Type* SV = new SmallVector_Type; Py_ssize_t size = PyTuple_Size(args); for (Py_ssize_t i = 0; i < size; ++i) { @@ -186,8 +186,8 @@ PyObject* iterator_to_pylist_deref(iterator begin, iterator end, { PyObject* list = PyList_New(0); for(; begin != end; ++begin) { - PyObject* cap = pycapsule_new(&*begin, capsuleName, className); - PyList_Append(list, cap); + auto_pyobject cap = pycapsule_new(&*begin, capsuleName, className); + PyList_Append(list, *cap); } return list; } @@ -198,8 +198,8 @@ PyObject* iterator_to_pylist(iterator begin, iterator end, { PyObject* list = PyList_New(0); for(; begin != end; ++begin) { - PyObject* cap = pycapsule_new(*begin, capsuleName, className); - PyList_Append(list, cap); + auto_pyobject cap = pycapsule_new(*begin, capsuleName, className); + PyList_Append(list, *cap); } return list; } @@ -420,7 +420,7 @@ PyObject* ExecutionEngine_RunFunction(llvm::ExecutionEngine* EE, PyErr_SetString(PyExc_RuntimeError, "Failed to index into args?"); return NULL; } - + GenericValue* gv = static_cast( PyCapsule_GetPointer(obj, GVN)); @@ -575,11 +575,11 @@ PyObject* TargetMachine_addPassesToEmitFile( bool status = TM->addPassesToEmitFile(PM, fso, FTy, disableVerify); if (status) { StringRef sr = rso.str(); - PyObject* buf = PyString_FromStringAndSize(sr.data(), sr.size()); + auto_pyobject buf = PyString_FromStringAndSize(sr.data(), sr.size()); if (!buf) { return NULL; } - if (-1 == PyFile_WriteObject(buf, Out, Py_PRINT_RAW)){ + if (-1 == PyFile_WriteObject(*buf, Out, Py_PRINT_RAW)){ return NULL; } Py_RETURN_TRUE; @@ -626,7 +626,7 @@ PyObject* Linker_LinkInModule(llvm::Linker* Linker, if (! failed) { Py_RETURN_FALSE; } else { - + auto_pyobject buf = PyBytes_FromString(errmsg.c_str()); if (NULL == callwrite(ErrMsg, *buf)){ return NULL; @@ -861,6 +861,27 @@ PyObject* DynamicLibrary_LoadLibraryPermanently(const char * Filename, } } +static +PyObject* DynamicLibrary_getPermanentLibrary(const char * Filename, + PyObject* ErrMsg = 0) +{ + using namespace llvm::sys; + std::string errmsg; + DynamicLibrary dylib = DynamicLibrary::getPermanentLibrary(Filename, &errmsg); + if (!dylib.isValid()) { + if (ErrMsg) { + auto_pyobject buf = PyBytes_FromString(errmsg.c_str()); + if (!callwrite(ErrMsg, *buf)) + return NULL; + } + PyErr_SetString(PyExc_RuntimeError, errmsg.c_str()); + return NULL; + } + return pycapsule_new(new DynamicLibrary(dylib), + "llvm::sys::DynamicLibrary", + "llvm::sys::DynamicLibrary"); +} + class PassRegistryEnumerator : public llvm::PassRegistrationListener{ public: PyObject* List; @@ -870,7 +891,8 @@ public: inline virtual void passEnumerate(const llvm::PassInfo * pass_info){ PyObject* passArg = PyString_FromString(pass_info->getPassArgument()); PyObject* passName = PyString_FromString(pass_info->getPassName()); - PyList_Append(List, Py_BuildValue("(OO)", passArg, passName)); + auto_pyobject pair = Py_BuildValue("(OO)", passArg, passName); + PyList_Append(List, *pair); } }; @@ -988,7 +1010,7 @@ fail: } static -PyObject* MCDisassembler_getInstruction(llvm::MCDisassembler *disasm, +PyObject* MCDisassembler_getInstruction(llvm::MCDisassembler *disasm, llvm::MCInst &instr, const llvm::MemoryObject ®ion, uint64_t address @@ -998,7 +1020,7 @@ PyObject* MCDisassembler_getInstruction(llvm::MCDisassembler *disasm, llvm::MCDisassembler::DecodeStatus status; size = 0; - status = disasm->getInstruction(instr, size, region, address, + status = disasm->getInstruction(instr, size, region, address, llvm::nulls(), llvm::nulls()); return Py_BuildValue("(i,i)", int(status), size); } @@ -1046,5 +1068,5 @@ PyObject* llvm_sys_isBigEndianHost() else Py_RETURN_FALSE; } -#endif +#endif diff --git a/llvmpy/src/BasicBlock.py b/llvmpy/src/BasicBlock.py index 6efe704..3c82e17 100644 --- a/llvmpy/src/BasicBlock.py +++ b/llvmpy/src/BasicBlock.py @@ -1,12 +1,13 @@ from binding import * from .namespace import llvm -from .Value import Function, BasicBlock +from .Value import Function, BasicBlock, Value from .Instruction import Instruction, TerminatorInst from .LLVMContext import LLVMContext from .ADT.StringRef import StringRef @BasicBlock class BasicBlock: + _downcast_ = Value Create = StaticMethod(ptr(BasicBlock), ref(LLVMContext), cast(str, StringRef), ptr(Function), diff --git a/llvmpy/src/Support/DynamicLibrary.py b/llvmpy/src/Support/DynamicLibrary.py index 7dce97a..e3b1d37 100644 --- a/llvmpy/src/Support/DynamicLibrary.py +++ b/llvmpy/src/Support/DynamicLibrary.py @@ -26,3 +26,10 @@ class DynamicLibrary: cast(str, StringRef), # symbolName cast(int, VoidPtr), # address ) + + getPermanentLibrary = CustomStaticMethod( + 'DynamicLibrary_getPermanentLibrary', + PyObjectPtr, + cast(str, ConstCharPtr), # filename + PyObjectPtr, # std::string * errmsg = 0 + ).require_only(1) diff --git a/test/inlineasm.py b/test/inlineasm.py index 64a4cbe..26ee4b5 100644 --- a/test/inlineasm.py +++ b/test/inlineasm.py @@ -3,7 +3,7 @@ # Import the llvm-py modules. from llvm import * from llvm.core import * -from llvm.test_llvmpy import TestCase +from llvm.tests.support import TestCase import logging import unittest diff --git a/test/loopvectorize.py b/test/loopvectorize.py index 2c12d5b..dc11cb3 100644 --- a/test/loopvectorize.py +++ b/test/loopvectorize.py @@ -2,7 +2,7 @@ from llvm.core import * from llvm.passes import * from llvm.ee import * import llvm -from llvm.test_llvmpy import TestCase +from llvm.tests.support import TestCase from os.path import dirname, join as join_path diff --git a/test/metadata.py b/test/metadata.py index 3228159..0062bcc 100644 --- a/test/metadata.py +++ b/test/metadata.py @@ -1,7 +1,7 @@ from __future__ import print_function import unittest -from llvm.test_llvmpy import TestCase +from llvm.tests.support import TestCase from llvm.core import * class TestMetaData(TestCase): diff --git a/test/tbaa.py b/test/tbaa.py index ad11081..4a24de8 100644 --- a/test/tbaa.py +++ b/test/tbaa.py @@ -1,6 +1,6 @@ from llvm.core import * from llvm.tbaa import * -from llvm.test_llvmpy import TestCase +from llvm.tests.support import TestCase import unittest class TestTBAABuilder(TestCase): diff --git a/test/test.py b/test/test.py index 3b46281..e23aca3 100644 --- a/test/test.py +++ b/test/test.py @@ -7,7 +7,7 @@ import unittest, sys, logging from llvm import * from llvm.core import * -from llvm.test_llvmpy import TestCase +from llvm.tests.support import TestCase class TestModule(TestCase): diff --git a/test/test_debuginfo.py b/test/test_debuginfo.py index b6a5d6f..d31563c 100644 --- a/test/test_debuginfo.py +++ b/test/test_debuginfo.py @@ -4,7 +4,7 @@ import unittest import llvm.ee from llvm.core import * from llvm import _dwarf, debuginfo -from llvm.test_llvmpy import TestCase +from llvm.tests.support import TestCase class TestDebugInfo(TestCase):