mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-25 14:32:53 +00:00
[python-bindings] Added OpCode like support for all enumerations with unittests.
Also fixed some trailing whitespace issues. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@201929 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
a6e734d2ed
commit
0ee9a84cac
@ -20,6 +20,7 @@ from ctypes import c_uint
|
||||
|
||||
__all__ = [
|
||||
"lib",
|
||||
"Enums",
|
||||
"OpCode",
|
||||
"MemoryBuffer",
|
||||
"Module",
|
||||
@ -32,42 +33,116 @@ __all__ = [
|
||||
]
|
||||
|
||||
lib = get_library()
|
||||
Enums = []
|
||||
|
||||
class OpCode(object):
|
||||
"""Represents an individual OpCode enumeration."""
|
||||
|
||||
_value_map = {}
|
||||
class LLVMEnumeration(object):
|
||||
"""Represents an individual LLVM enumeration."""
|
||||
|
||||
def __init__(self, name, value):
|
||||
self.name = name
|
||||
self.value = value
|
||||
|
||||
def __repr__(self):
|
||||
return 'OpCode.%s' % self.name
|
||||
return '%s.%s' % (self.__class__.__name__,
|
||||
self.name)
|
||||
|
||||
@staticmethod
|
||||
def from_value(value):
|
||||
"""Obtain an OpCode instance from a numeric value."""
|
||||
result = OpCode._value_map.get(value, None)
|
||||
@classmethod
|
||||
def from_value(cls, value):
|
||||
"""Obtain an enumeration instance from a numeric value."""
|
||||
result = cls._value_map.get(value, None)
|
||||
|
||||
if result is None:
|
||||
raise ValueError('Unknown OpCode: %d' % value)
|
||||
raise ValueError('Unknown %s: %d' % (cls.__name__,
|
||||
value))
|
||||
|
||||
return result
|
||||
|
||||
@staticmethod
|
||||
def register(name, value):
|
||||
"""Registers a new OpCode enumeration.
|
||||
@classmethod
|
||||
def register(cls, name, value):
|
||||
"""Registers a new enumeration.
|
||||
|
||||
This is called by this module for each enumeration defined in
|
||||
enumerations. You should not need to call this outside this module.
|
||||
"""
|
||||
if value in OpCode._value_map:
|
||||
raise ValueError('OpCode value already registered: %d' % value)
|
||||
if value in cls._value_map:
|
||||
raise ValueError('%s value already registered: %d' % (cls.__name__,
|
||||
value))
|
||||
enum = cls(name, value)
|
||||
cls._value_map[value] = enum
|
||||
setattr(cls, name, enum)
|
||||
#print cls, name, value
|
||||
|
||||
opcode = OpCode(name, value)
|
||||
OpCode._value_map[value] = opcode
|
||||
setattr(OpCode, name, opcode)
|
||||
class Attribute(LLVMEnumeration):
|
||||
"""Represents an individual Attribute enumeration."""
|
||||
|
||||
_value_map = {}
|
||||
|
||||
def __init__(self, name, value):
|
||||
super(Attribute, self).__init__(name, value)
|
||||
|
||||
class OpCode(LLVMEnumeration):
|
||||
"""Represents an individual OpCode enumeration."""
|
||||
|
||||
_value_map = {}
|
||||
|
||||
def __init__(self, name, value):
|
||||
super(OpCode, self).__init__(name, value)
|
||||
|
||||
class TypeKind(LLVMEnumeration):
|
||||
"""Represents an individual TypeKind enumeration."""
|
||||
|
||||
_value_map = {}
|
||||
|
||||
def __init__(self, name, value):
|
||||
super(TypeKind, self).__init__(name, value)
|
||||
|
||||
class Linkage(LLVMEnumeration):
|
||||
"""Represents an individual Linkage enumeration."""
|
||||
|
||||
_value_map = {}
|
||||
|
||||
def __init__(self, name, value):
|
||||
super(Linkage, self).__init__(name, value)
|
||||
|
||||
class Visibility(LLVMEnumeration):
|
||||
"""Represents an individual visibility enumeration."""
|
||||
|
||||
_value_map = {}
|
||||
|
||||
def __init__(self, name, value):
|
||||
super(Visibility, self).__init__(name, value)
|
||||
|
||||
class CallConv(LLVMEnumeration):
|
||||
"""Represents an individual calling convention enumeration."""
|
||||
|
||||
_value_map = {}
|
||||
|
||||
def __init__(self, name, value):
|
||||
super(CallConv, self).__init__(name, value)
|
||||
|
||||
class IntPredicate(LLVMEnumeration):
|
||||
"""Represents an individual IntPredicate enumeration."""
|
||||
|
||||
_value_map = {}
|
||||
|
||||
def __init__(self, name, value):
|
||||
super(IntPredicate, self).__init__(name, value)
|
||||
|
||||
class RealPredicate(LLVMEnumeration):
|
||||
"""Represents an individual RealPredicate enumeration."""
|
||||
|
||||
_value_map = {}
|
||||
|
||||
def __init__(self, name, value):
|
||||
super(RealPredicate, self).__init__(name, value)
|
||||
|
||||
class LandingPadClauseTy(LLVMEnumeration):
|
||||
"""Represents an individual LandingPadClauseTy enumeration."""
|
||||
|
||||
_value_map = {}
|
||||
|
||||
def __init__(self, name, value):
|
||||
super(LandingPadClauseTy, self).__init__(name, value)
|
||||
|
||||
class MemoryBuffer(LLVMObject):
|
||||
"""Represents an opaque memory buffer."""
|
||||
@ -516,8 +591,25 @@ def register_library(library):
|
||||
library.LLVMGetInstructionOpcode.restype = c_uint
|
||||
|
||||
def register_enumerations():
|
||||
for name, value in enumerations.OpCodes:
|
||||
OpCode.register(name, value)
|
||||
if Enums:
|
||||
return None
|
||||
enums = [
|
||||
(Attribute, enumerations.Attributes),
|
||||
(OpCode, enumerations.OpCodes),
|
||||
(TypeKind, enumerations.TypeKinds),
|
||||
(Linkage, enumerations.Linkages),
|
||||
(Visibility, enumerations.Visibility),
|
||||
(CallConv, enumerations.CallConv),
|
||||
(IntPredicate, enumerations.IntPredicate),
|
||||
(RealPredicate, enumerations.RealPredicate),
|
||||
(LandingPadClauseTy, enumerations.LandingPadClauseTy),
|
||||
]
|
||||
s = set([])
|
||||
for enum_class, enum_spec in enums:
|
||||
for name, value in enum_spec:
|
||||
print name, value
|
||||
enum_class.register(name, value)
|
||||
return enums
|
||||
|
||||
def initialize_llvm():
|
||||
c = Context.GetGlobalContext()
|
||||
@ -536,5 +628,5 @@ def initialize_llvm():
|
||||
lib.LLVMInitializeTarget(p)
|
||||
|
||||
register_library(lib)
|
||||
register_enumerations()
|
||||
Enums = register_enumerations()
|
||||
initialize_llvm()
|
||||
|
@ -1,20 +1,30 @@
|
||||
from .base import TestBase
|
||||
from ..core import OpCode
|
||||
from ..core import MemoryBuffer
|
||||
from ..core import PassRegistry
|
||||
from ..core import Context
|
||||
from ..core import Module
|
||||
from ..core import Enums
|
||||
from ..core import OpCode
|
||||
from ..bit_reader import parse_bitcode
|
||||
|
||||
class TestCore(TestBase):
|
||||
def test_opcode(self):
|
||||
self.assertTrue(hasattr(OpCode, 'Ret'))
|
||||
self.assertTrue(isinstance(OpCode.Ret, OpCode))
|
||||
self.assertEqual(OpCode.Ret.value, 1)
|
||||
def test_enumerations(self):
|
||||
for enum_cls, enum_spec in Enums:
|
||||
for enum_name, enum_value in enum_spec:
|
||||
# First make sure that enum_cls has the name of the enum as an
|
||||
# attribute. People will access these values as
|
||||
# EnumCls.EnumName.
|
||||
self.assertTrue(hasattr(enum_cls, enum_name))
|
||||
v_attr = getattr(enum_cls, enum_name)
|
||||
self.assertTrue(isinstance(v_attr, enum_cls))
|
||||
|
||||
op = OpCode.from_value(1)
|
||||
self.assertTrue(isinstance(op, OpCode))
|
||||
self.assertEqual(op, OpCode.Ret)
|
||||
# Then make sure that the value returned for this attribute is
|
||||
# correct in both ways.
|
||||
self.assertEqual(v_attr.value, enum_value)
|
||||
|
||||
e = enum_cls.from_value(enum_value)
|
||||
self.assertTrue(isinstance(e, enum_cls))
|
||||
self.assertEqual(e, v_attr)
|
||||
|
||||
def test_memory_buffer_create_from_file(self):
|
||||
source = self.get_test_file()
|
||||
@ -61,7 +71,7 @@ class TestCore(TestBase):
|
||||
target = "thumbv7-apple-ios5.0.0"
|
||||
m.target = target
|
||||
m.print_module_to_file("test2.ll")
|
||||
|
||||
|
||||
def test_module_function_iteration(self):
|
||||
m = parse_bitcode(MemoryBuffer(filename=self.get_test_bc()))
|
||||
i = 0
|
||||
@ -81,19 +91,19 @@ class TestCore(TestBase):
|
||||
def test_function_basicblock_iteration(self):
|
||||
m = parse_bitcode(MemoryBuffer(filename=self.get_test_bc()))
|
||||
i = 0
|
||||
|
||||
|
||||
bb_list = ['b1', 'b2', 'end']
|
||||
|
||||
|
||||
f = m.first
|
||||
while f.name != "f6":
|
||||
f = f.next
|
||||
|
||||
|
||||
# Forward
|
||||
for bb in f:
|
||||
self.assertEqual(bb.name, bb_list[i])
|
||||
bb.dump()
|
||||
i += 1
|
||||
|
||||
|
||||
# Backwards
|
||||
for bb in reversed(f):
|
||||
i -= 1
|
||||
@ -103,12 +113,12 @@ class TestCore(TestBase):
|
||||
def test_basicblock_instruction_iteration(self):
|
||||
m = parse_bitcode(MemoryBuffer(filename=self.get_test_bc()))
|
||||
i = 0
|
||||
|
||||
|
||||
inst_list = [('arg1', OpCode.ExtractValue),
|
||||
('arg2', OpCode.ExtractValue),
|
||||
('', OpCode.Call),
|
||||
('', OpCode.Ret)]
|
||||
|
||||
|
||||
bb = m.first.first
|
||||
|
||||
# Forward
|
||||
|
Loading…
Reference in New Issue
Block a user