1#===- core.py - Python LLVM Bindings -------------------------*- python -*--===#
2#
3#                     The LLVM Compiler Infrastructure
4#
5# This file is distributed under the University of Illinois Open Source
6# License. See LICENSE.TXT for details.
7#
8#===------------------------------------------------------------------------===#
9
10from .common import LLVMObject
11from .common import c_object_p
12from .common import get_library
13
14from . import enumerations
15
16from ctypes import POINTER
17from ctypes import byref
18from ctypes import c_char_p
19
20__all__ = [
21    "lib",
22    "MemoryBuffer",
23]
24
25lib = get_library()
26
27class OpCode(object):
28    """Represents an individual OpCode enumeration."""
29
30    _value_map = {}
31
32    def __init__(self, name, value):
33        self.name = name
34        self.value = value
35
36    def __repr__(self):
37        return 'OpCode.%s' % self.name
38
39    @staticmethod
40    def from_value(value):
41        """Obtain an OpCode instance from a numeric value."""
42        result = OpCode._value_map.get(value, None)
43
44        if result is None:
45            raise ValueError('Unknown OpCode: %d' % value)
46
47        return result
48
49    @staticmethod
50    def register(name, value):
51        """Registers a new OpCode enumeration.
52
53        This is called by this module for each enumeration defined in
54        enumerations. You should not need to call this outside this module.
55        """
56        if value in OpCode._value_map:
57            raise ValueError('OpCode value already registered: %d' % value)
58
59        opcode = OpCode(name, value)
60        OpCode._value_map[value] = opcode
61        setattr(OpCode, name, opcode)
62
63class MemoryBuffer(LLVMObject):
64    """Represents an opaque memory buffer."""
65
66    def __init__(self, filename=None):
67        """Create a new memory buffer.
68
69        Currently, we support creating from the contents of a file at the
70        specified filename.
71        """
72        if filename is None:
73            raise Exception("filename argument must be defined")
74
75        memory = c_object_p()
76        out = c_char_p(None)
77
78        result = lib.LLVMCreateMemoryBufferWithContentsOfFile(filename,
79                byref(memory), byref(out))
80
81        if result:
82            raise Exception("Could not create memory buffer: %s" % out.value)
83
84        LLVMObject.__init__(self, memory, disposer=lib.LLVMDisposeMemoryBuffer)
85
86def register_library(library):
87    library.LLVMCreateMemoryBufferWithContentsOfFile.argtypes = [c_char_p,
88            POINTER(c_object_p), POINTER(c_char_p)]
89    library.LLVMCreateMemoryBufferWithContentsOfFile.restype = bool
90
91    library.LLVMDisposeMemoryBuffer.argtypes = [MemoryBuffer]
92
93def register_enumerations():
94    for name, value in enumerations.OpCodes:
95        OpCode.register(name, value)
96
97register_library(lib)
98register_enumerations()
99