Compare commits

...

10 commits

Author SHA1 Message Date
Siu Kwan Lam
34900d2748 Update README.rst 2014-04-29 13:25:43 -05:00
Siu Kwan Lam
749b518b90 Update changelog 2014-04-28 11:06:48 -05:00
Siu Kwan Lam
c07fce0477 Update MANIFEST.in (#99) 2014-04-28 11:03:13 -05:00
Siu Kwan Lam
7f8476dd33 Fixing leaks (#92); thanks to ksshelt and eltjpm. 2014-04-04 15:14:47 -05:00
Siu Kwan Lam
57afefb069 Update change log 2014-03-20 15:00:11 -05:00
Siu Kwan Lam
0629ccb226 Allow BasicBlock downcast to Value 2014-03-19 11:33:01 -05:00
Siu Kwan Lam
6e4620edc6 Disable check_intrinsic 2014-03-13 13:47:09 -05:00
Siu Kwan Lam
2410267c8e Disable isolated test in conda build 2014-03-13 13:20:08 -05:00
Siu Kwan Lam
bc12aae8c1 Hashable Module and fix Module __eq__ 2014-03-11 15:17:06 -05:00
Siu Kwan Lam
6578412437 Add binding for dynamic library loading 2014-03-06 11:58:40 -06:00
11 changed files with 98 additions and 28 deletions

View file

@ -1,3 +1,15 @@
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: 2014-02-18 0.12.3:
--------------------- ---------------------
* Fix deprecation message for py2.6 * Fix deprecation message for py2.6

View file

@ -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 llvm *
recursive-include llvmpy *
recursive-include www * recursive-include www *
recursive-include test * recursive-include test *
recursive-include tools * recursive-include tools *

View file

@ -30,10 +30,13 @@ Quickstart
to separate your custom build from the default system package. Please to separate your custom build from the default system package. Please
replace ``LLVM_INSTALL_PATH`` with your own path. 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 **Note**: With LLVM 3.2, the default build configuration has C++ RTTI
disabled. However, llvmpy requires 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:: 4. Get llvm-py and install it::

View file

@ -15,8 +15,8 @@ if sys.platform == 'darwin':
s = {'64bit': 'x86_64', '32bit': 'x86'}[platform.architecture()[0]] s = {'64bit': 'x86_64', '32bit': 'x86'}[platform.architecture()[0]]
assert target.triple.startswith(s + '-apple-darwin') assert target.triple.startswith(s + '-apple-darwin')
assert llvm.test(verbosity=2) == 0 assert llvm.test(verbosity=2, run_isolated=False) == 0
check_intrinsics.main() #check_intrinsics.main()
print('llvm.__version__: %s' % llvm.__version__) print('llvm.__version__: %s' % llvm.__version__)
#assert llvm.__version__ == '0.12.0' #assert llvm.__version__ == '0.12.0'

View file

@ -34,14 +34,14 @@ def _extract_ptrs(objs):
class LLVMException(Exception): class LLVMException(Exception):
pass pass
def test(verbosity=3): def test(verbosity=3, run_isolated=True):
"""test(verbosity=1) -> TextTestResult """test(verbosity=1) -> TextTestResult
Run self-test, and return the number of failures + errors Run self-test, and return the number of failures + errors
""" """
from llvm.tests import run from llvm.tests import run
result = run(verbosity=verbosity) result = run(verbosity=verbosity, run_isolated=run_isolated)
errct = len(result.failures) + len(result.errors) errct = len(result.failures) + len(result.errors)
return errct return errct

View file

@ -452,12 +452,12 @@ class Module(llvm.Wrapper):
""" """
return str(self._ptr) return str(self._ptr)
def __hash__(self):
return id(self._ptr)
def __eq__(self, rhs): def __eq__(self, rhs):
assert isinstance(rhs, Module), type(rhs)
if isinstance(rhs, Module): if isinstance(rhs, Module):
return str(self) == str(rhs) return self._ptr == rhs._ptr
else:
return False
def __ne__(self, rhs): def __ne__(self, rhs):
return not (self == rhs) return not (self == rhs)

View file

@ -238,3 +238,27 @@ def dylib_add_symbol(name, ptr):
def dylib_address_of_symbol(name): def dylib_address_of_symbol(name):
return api.llvm.sys.DynamicLibrary.SearchForAddressOfSymbol(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)

View file

@ -12,7 +12,7 @@ tests = [] # stores unittest.TestCase objects
isolated_tests = [] # stores modue name 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 is installed in: ' + os.path.dirname(__file__))
print('llvmpy version: ' + llvm.__version__) print('llvmpy version: ' + llvm.__version__)
print(sys.version) print(sys.version)
@ -48,7 +48,7 @@ def run(verbosity=1):
testresult = runner.run(suite) testresult = runner.run(suite)
print(hp.heap()) print(hp.heap())
if testresult: if testresult and run_isolated:
# Run isolated tests # Run isolated tests
print("run isolated tests".center(80, '-')) print("run isolated tests".center(80, '-'))

View file

@ -40,7 +40,7 @@
namespace extra{ namespace extra{
using namespace llvm; using namespace llvm;
class raw_svector_ostream_helper: public raw_svector_ostream { class raw_svector_ostream_helper: public raw_svector_ostream {
SmallVectorImpl<char> *SV; SmallVectorImpl<char> *SV;
public: public:
@ -85,7 +85,7 @@ PyObject* make_raw_ostream_for_printing(PyObject* self, PyObject* args)
{ {
using extra::raw_svector_ostream_helper; using extra::raw_svector_ostream_helper;
using llvm::raw_svector_ostream; using llvm::raw_svector_ostream;
if (!PyArg_ParseTuple(args, "")) { if (!PyArg_ParseTuple(args, "")) {
return NULL; return NULL;
} }
@ -99,7 +99,7 @@ PyObject* make_small_vector_from_types(PyObject* self, PyObject* args)
{ {
using llvm::Type; using llvm::Type;
typedef llvm::SmallVector<llvm::Type*, 8> SmallVector_Type; typedef llvm::SmallVector<llvm::Type*, 8> SmallVector_Type;
SmallVector_Type* SV = new SmallVector_Type; SmallVector_Type* SV = new SmallVector_Type;
Py_ssize_t size = PyTuple_Size(args); Py_ssize_t size = PyTuple_Size(args);
for (Py_ssize_t i = 0; i < size; ++i) { 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); PyObject* list = PyList_New(0);
for(; begin != end; ++begin) { for(; begin != end; ++begin) {
PyObject* cap = pycapsule_new(&*begin, capsuleName, className); auto_pyobject cap = pycapsule_new(&*begin, capsuleName, className);
PyList_Append(list, cap); PyList_Append(list, *cap);
} }
return list; return list;
} }
@ -198,8 +198,8 @@ PyObject* iterator_to_pylist(iterator begin, iterator end,
{ {
PyObject* list = PyList_New(0); PyObject* list = PyList_New(0);
for(; begin != end; ++begin) { for(; begin != end; ++begin) {
PyObject* cap = pycapsule_new(*begin, capsuleName, className); auto_pyobject cap = pycapsule_new(*begin, capsuleName, className);
PyList_Append(list, cap); PyList_Append(list, *cap);
} }
return list; return list;
} }
@ -420,7 +420,7 @@ PyObject* ExecutionEngine_RunFunction(llvm::ExecutionEngine* EE,
PyErr_SetString(PyExc_RuntimeError, "Failed to index into args?"); PyErr_SetString(PyExc_RuntimeError, "Failed to index into args?");
return NULL; return NULL;
} }
GenericValue* gv = static_cast<GenericValue*>( GenericValue* gv = static_cast<GenericValue*>(
PyCapsule_GetPointer(obj, GVN)); PyCapsule_GetPointer(obj, GVN));
@ -575,11 +575,11 @@ PyObject* TargetMachine_addPassesToEmitFile(
bool status = TM->addPassesToEmitFile(PM, fso, FTy, disableVerify); bool status = TM->addPassesToEmitFile(PM, fso, FTy, disableVerify);
if (status) { if (status) {
StringRef sr = rso.str(); StringRef sr = rso.str();
PyObject* buf = PyString_FromStringAndSize(sr.data(), sr.size()); auto_pyobject buf = PyString_FromStringAndSize(sr.data(), sr.size());
if (!buf) { if (!buf) {
return NULL; return NULL;
} }
if (-1 == PyFile_WriteObject(buf, Out, Py_PRINT_RAW)){ if (-1 == PyFile_WriteObject(*buf, Out, Py_PRINT_RAW)){
return NULL; return NULL;
} }
Py_RETURN_TRUE; Py_RETURN_TRUE;
@ -626,7 +626,7 @@ PyObject* Linker_LinkInModule(llvm::Linker* Linker,
if (! failed) { if (! failed) {
Py_RETURN_FALSE; Py_RETURN_FALSE;
} else { } else {
auto_pyobject buf = PyBytes_FromString(errmsg.c_str()); auto_pyobject buf = PyBytes_FromString(errmsg.c_str());
if (NULL == callwrite(ErrMsg, *buf)){ if (NULL == callwrite(ErrMsg, *buf)){
return NULL; 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{ class PassRegistryEnumerator : public llvm::PassRegistrationListener{
public: public:
PyObject* List; PyObject* List;
@ -870,7 +891,8 @@ public:
inline virtual void passEnumerate(const llvm::PassInfo * pass_info){ inline virtual void passEnumerate(const llvm::PassInfo * pass_info){
PyObject* passArg = PyString_FromString(pass_info->getPassArgument()); PyObject* passArg = PyString_FromString(pass_info->getPassArgument());
PyObject* passName = PyString_FromString(pass_info->getPassName()); 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 static
PyObject* MCDisassembler_getInstruction(llvm::MCDisassembler *disasm, PyObject* MCDisassembler_getInstruction(llvm::MCDisassembler *disasm,
llvm::MCInst &instr, llvm::MCInst &instr,
const llvm::MemoryObject &region, const llvm::MemoryObject &region,
uint64_t address uint64_t address
@ -998,7 +1020,7 @@ PyObject* MCDisassembler_getInstruction(llvm::MCDisassembler *disasm,
llvm::MCDisassembler::DecodeStatus status; llvm::MCDisassembler::DecodeStatus status;
size = 0; size = 0;
status = disasm->getInstruction(instr, size, region, address, status = disasm->getInstruction(instr, size, region, address,
llvm::nulls(), llvm::nulls()); llvm::nulls(), llvm::nulls());
return Py_BuildValue("(i,i)", int(status), size); return Py_BuildValue("(i,i)", int(status), size);
} }
@ -1046,5 +1068,5 @@ PyObject* llvm_sys_isBigEndianHost()
else else
Py_RETURN_FALSE; Py_RETURN_FALSE;
} }
#endif #endif

View file

@ -1,12 +1,13 @@
from binding import * from binding import *
from .namespace import llvm from .namespace import llvm
from .Value import Function, BasicBlock from .Value import Function, BasicBlock, Value
from .Instruction import Instruction, TerminatorInst from .Instruction import Instruction, TerminatorInst
from .LLVMContext import LLVMContext from .LLVMContext import LLVMContext
from .ADT.StringRef import StringRef from .ADT.StringRef import StringRef
@BasicBlock @BasicBlock
class BasicBlock: class BasicBlock:
_downcast_ = Value
Create = StaticMethod(ptr(BasicBlock), ref(LLVMContext), Create = StaticMethod(ptr(BasicBlock), ref(LLVMContext),
cast(str, StringRef), cast(str, StringRef),
ptr(Function), ptr(Function),

View file

@ -26,3 +26,10 @@ class DynamicLibrary:
cast(str, StringRef), # symbolName cast(str, StringRef), # symbolName
cast(int, VoidPtr), # address cast(int, VoidPtr), # address
) )
getPermanentLibrary = CustomStaticMethod(
'DynamicLibrary_getPermanentLibrary',
PyObjectPtr,
cast(str, ConstCharPtr), # filename
PyObjectPtr, # std::string * errmsg = 0
).require_only(1)