From: Michael Gottesman Date: Wed, 11 Sep 2013 00:23:14 +0000 (+0000) Subject: [python-bindings] Added code for loading a module from bitcode, getset its datalayout... X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=37a8807323672ab0bb366272e5a798b8e63752a4 [python-bindings] Added code for loading a module from bitcode, getset its datalayout, getset its target, dump it, print it to a file. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190458 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/bindings/python/llvm/bit_reader.py b/bindings/python/llvm/bit_reader.py new file mode 100644 index 00000000000..5bf5e22025a --- /dev/null +++ b/bindings/python/llvm/bit_reader.py @@ -0,0 +1,31 @@ + +from .common import LLVMObject +from .common import c_object_p +from .common import get_library +from . import enumerations +from .core import MemoryBuffer +from .core import Module +from .core import OpCode +from ctypes import POINTER +from ctypes import byref +from ctypes import c_char_p +from ctypes import cast +__all__ = ['parse_bitcode'] +lib = get_library() + +def parse_bitcode(mem_buffer): + """Input is .core.MemoryBuffer""" + module = c_object_p() + out = c_char_p(None) + result = lib.LLVMParseBitcode(mem_buffer, byref(module), byref(out)) + if result: + raise RuntimeError('LLVM Error: %s' % out.value) + m = Module(module) + m.take_ownership(mem_buffer) + return m + +def register_library(library): + library.LLVMParseBitcode.argtypes = [MemoryBuffer, POINTER(c_object_p), POINTER(c_char_p)] + library.LLVMParseBitcode.restype = bool + +register_library(lib) diff --git a/bindings/python/llvm/core.py b/bindings/python/llvm/core.py index 76d1b14e631..2072d2f18dc 100644 --- a/bindings/python/llvm/core.py +++ b/bindings/python/llvm/core.py @@ -16,10 +16,12 @@ from . import enumerations from ctypes import POINTER from ctypes import byref from ctypes import c_char_p +from ctypes import c_uint __all__ = [ "lib", "MemoryBuffer", + "Module", "Context", "PassRegistry" ] @@ -88,6 +90,45 @@ class MemoryBuffer(LLVMObject): def __len__(self): return lib.LLVMGetBufferSize(self) +class Module(LLVMObject): + """Represents the top-level structure of an llvm program in an opaque object.""" + + def __init__(self, module, name=None, context=None): + LLVMObject.__init__(self, module, disposer=lib.LLVMDisposeModule) + + @classmethod + def CreateWithName(cls, module_id): + m = Module(lib.LLVMModuleCreateWithName(module_id)) + c = Context.GetGlobalContext().take_ownership(m) + return m + + @property + def data_layout(self): + return lib.LLVMGetDataLayout(self) + + @data_layout.setter + def data_layout(self, new_data_layout): + """new_data_layout is a string.""" + lib.LLVMSetDataLayout(self, new_data_layout) + + @property + def target(self): + return lib.LLVMGetTarget(self) + + @target.setter + def target(self, new_target): + """new_target is a string.""" + lib.LLVMSetTarget(self, new_target) + + def dump(self): + lib.LLVMDumpModule(self) + + def print_module_to_file(self, filename): + out = c_char_p(None) + result = lib.LLVMPrintModuleToFile(self, filename, byref(out)) + if not result: + raise RuntimeError("LLVM Error: %s" % out.value) + class Context(LLVMObject): def __init__(self, context=None): @@ -172,6 +213,32 @@ def register_library(library): library.LLVMDisposeMemoryBuffer.argtypes = [MemoryBuffer] + # Module declarations + library.LLVMModuleCreateWithName.argtypes = [c_char_p] + library.LLVMModuleCreateWithName.restype = c_object_p + + library.LLVMDisposeModule.argtypes = [Module] + library.LLVMDisposeModule.restype = None + + library.LLVMGetDataLayout.argtypes = [Module] + library.LLVMGetDataLayout.restype = c_char_p + + library.LLVMSetDataLayout.argtypes = [Module, c_char_p] + library.LLVMSetDataLayout.restype = None + + library.LLVMGetTarget.argtypes = [Module] + library.LLVMGetTarget.restype = c_char_p + + library.LLVMSetTarget.argtypes = [Module, c_char_p] + library.LLVMSetTarget.restype = None + + library.LLVMDumpModule.argtypes = [Module] + library.LLVMDumpModule.restype = None + + library.LLVMPrintModuleToFile.argtypes = [Module, c_char_p, + POINTER(c_char_p)] + library.LLVMPrintModuleToFile.restype = bool + def register_enumerations(): for name, value in enumerations.OpCodes: OpCode.register(name, value) diff --git a/bindings/python/llvm/tests/base.py b/bindings/python/llvm/tests/base.py index 22da5fdbdd0..194f1a41192 100644 --- a/bindings/python/llvm/tests/base.py +++ b/bindings/python/llvm/tests/base.py @@ -33,3 +33,6 @@ class TestBase(unittest.TestCase): def get_test_file(self): return os.path.join(os.path.dirname(os.path.abspath(__file__)), "test_file") + + def get_test_bc(self): + return os.path.join(os.path.dirname(os.path.abspath(__file__)), "test.bc") diff --git a/bindings/python/llvm/tests/test.bc b/bindings/python/llvm/tests/test.bc new file mode 100644 index 00000000000..8d3d28fbc0d Binary files /dev/null and b/bindings/python/llvm/tests/test.bc differ diff --git a/bindings/python/llvm/tests/test_core.py b/bindings/python/llvm/tests/test_core.py index 3364a66cb55..e5fffbae59c 100644 --- a/bindings/python/llvm/tests/test_core.py +++ b/bindings/python/llvm/tests/test_core.py @@ -3,6 +3,7 @@ from ..core import OpCode from ..core import MemoryBuffer from ..core import PassRegistry from ..core import Context +from ..core import Module class TestCore(TestBase): def test_opcode(self): @@ -33,3 +34,29 @@ class TestCore(TestBase): def test_create_context(self): Context.GetGlobalContext() + + def test_create_module_with_name(self): + # Make sure we can not create a module without a LLVMModuleRef. + with self.assertRaises(RuntimeError): + m = Module() + m = Module.CreateWithName("test-module") + + def test_module_getset_datalayout(self): + m = Module.CreateWithName("test-module") + dl = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n32-S32" + m.datalayout = dl + self.assertEqual(m.datalayout, dl) + + def test_module_getset_target(self): + m = Module.CreateWithName("test-module") + m.target = "thumbv7-apple-ios5.0.0" + self.assertEqual(m.target, target) + + def test_module_print_module_to_file(self): + m = Module.CreateWithName("test") + dl = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:32:64-v128:32:128-a0:0:32-n32-S32" + m.datalayout = dl + target = "thumbv7-apple-ios5.0.0" + m.target = target + m.print_module_to_file("test2.ll") +