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 19from ctypes import c_uint 20 21__all__ = [ 22 "lib", 23 "OpCode", 24 "MemoryBuffer", 25 "Module", 26 "Value", 27 "Function", 28 "BasicBlock", 29 "Instruction", 30 "Context", 31 "PassRegistry" 32] 33 34lib = get_library() 35 36class OpCode(object): 37 """Represents an individual OpCode enumeration.""" 38 39 _value_map = {} 40 41 def __init__(self, name, value): 42 self.name = name 43 self.value = value 44 45 def __repr__(self): 46 return 'OpCode.%s' % self.name 47 48 @staticmethod 49 def from_value(value): 50 """Obtain an OpCode instance from a numeric value.""" 51 result = OpCode._value_map.get(value, None) 52 53 if result is None: 54 raise ValueError('Unknown OpCode: %d' % value) 55 56 return result 57 58 @staticmethod 59 def register(name, value): 60 """Registers a new OpCode enumeration. 61 62 This is called by this module for each enumeration defined in 63 enumerations. You should not need to call this outside this module. 64 """ 65 if value in OpCode._value_map: 66 raise ValueError('OpCode value already registered: %d' % value) 67 68 opcode = OpCode(name, value) 69 OpCode._value_map[value] = opcode 70 setattr(OpCode, name, opcode) 71 72class MemoryBuffer(LLVMObject): 73 """Represents an opaque memory buffer.""" 74 75 def __init__(self, filename=None): 76 """Create a new memory buffer. 77 78 Currently, we support creating from the contents of a file at the 79 specified filename. 80 """ 81 if filename is None: 82 raise Exception("filename argument must be defined") 83 84 memory = c_object_p() 85 out = c_char_p(None) 86 87 result = lib.LLVMCreateMemoryBufferWithContentsOfFile(filename, 88 byref(memory), byref(out)) 89 90 if result: 91 raise Exception("Could not create memory buffer: %s" % out.value) 92 93 LLVMObject.__init__(self, memory, disposer=lib.LLVMDisposeMemoryBuffer) 94 95 def __len__(self): 96 return lib.LLVMGetBufferSize(self) 97 98class Value(LLVMObject): 99 100 def __init__(self, value): 101 LLVMObject.__init__(self, value) 102 103 @property 104 def name(self): 105 return lib.LLVMGetValueName(self) 106 107 def dump(self): 108 lib.LLVMDumpValue(self) 109 110 def get_operand(self, i): 111 return Value(lib.LLVMGetOperand(self, i)) 112 113 def set_operand(self, i, v): 114 return lib.LLVMSetOperand(self, i, v) 115 116 def __len__(self): 117 return lib.LLVMGetNumOperands(self) 118 119class Module(LLVMObject): 120 """Represents the top-level structure of an llvm program in an opaque object.""" 121 122 def __init__(self, module, name=None, context=None): 123 LLVMObject.__init__(self, module, disposer=lib.LLVMDisposeModule) 124 125 @classmethod 126 def CreateWithName(cls, module_id): 127 m = Module(lib.LLVMModuleCreateWithName(module_id)) 128 c = Context.GetGlobalContext().take_ownership(m) 129 return m 130 131 @property 132 def datalayout(self): 133 return lib.LLVMGetDataLayout(self) 134 135 @datalayout.setter 136 def datalayout(self, new_data_layout): 137 """new_data_layout is a string.""" 138 lib.LLVMSetDataLayout(self, new_data_layout) 139 140 @property 141 def target(self): 142 return lib.LLVMGetTarget(self) 143 144 @target.setter 145 def target(self, new_target): 146 """new_target is a string.""" 147 lib.LLVMSetTarget(self, new_target) 148 149 def dump(self): 150 lib.LLVMDumpModule(self) 151 152 class __function_iterator(object): 153 def __init__(self, module, reverse=False): 154 self.module = module 155 self.reverse = reverse 156 if self.reverse: 157 self.function = self.module.last 158 else: 159 self.function = self.module.first 160 161 def __iter__(self): 162 return self 163 164 def next(self): 165 if not isinstance(self.function, Function): 166 raise StopIteration("") 167 result = self.function 168 if self.reverse: 169 self.function = self.function.prev 170 else: 171 self.function = self.function.next 172 return result 173 174 def __iter__(self): 175 return Module.__function_iterator(self) 176 177 def __reversed__(self): 178 return Module.__function_iterator(self, reverse=True) 179 180 @property 181 def first(self): 182 return Function(lib.LLVMGetFirstFunction(self)) 183 184 @property 185 def last(self): 186 return Function(lib.LLVMGetLastFunction(self)) 187 188 def print_module_to_file(self, filename): 189 out = c_char_p(None) 190 # Result is inverted so 0 means everything was ok. 191 result = lib.LLVMPrintModuleToFile(self, filename, byref(out)) 192 if result: 193 raise RuntimeError("LLVM Error: %s" % out.value) 194 195class Function(Value): 196 197 def __init__(self, value): 198 Value.__init__(self, value) 199 200 @property 201 def next(self): 202 f = lib.LLVMGetNextFunction(self) 203 return f and Function(f) 204 205 @property 206 def prev(self): 207 f = lib.LLVMGetPreviousFunction(self) 208 return f and Function(f) 209 210 @property 211 def first(self): 212 b = lib.LLVMGetFirstBasicBlock(self) 213 return b and BasicBlock(b) 214 215 @property 216 def last(self): 217 b = lib.LLVMGetLastBasicBlock(self) 218 return b and BasicBlock(b) 219 220 class __bb_iterator(object): 221 def __init__(self, function, reverse=False): 222 self.function = function 223 self.reverse = reverse 224 if self.reverse: 225 self.bb = function.last 226 else: 227 self.bb = function.first 228 229 def __iter__(self): 230 return self 231 232 def next(self): 233 if not isinstance(self.bb, BasicBlock): 234 raise StopIteration("") 235 result = self.bb 236 if self.reverse: 237 self.bb = self.bb.prev 238 else: 239 self.bb = self.bb.next 240 return result 241 242 def __iter__(self): 243 return Function.__bb_iterator(self) 244 245 def __reversed__(self): 246 return Function.__bb_iterator(self, reverse=True) 247 248 def __len__(self): 249 return lib.LLVMCountBasicBlocks(self) 250 251class BasicBlock(LLVMObject): 252 253 def __init__(self, value): 254 LLVMObject.__init__(self, value) 255 256 @property 257 def next(self): 258 b = lib.LLVMGetNextBasicBlock(self) 259 return b and BasicBlock(b) 260 261 @property 262 def prev(self): 263 b = lib.LLVMGetPreviousBasicBlock(self) 264 return b and BasicBlock(b) 265 266 @property 267 def first(self): 268 i = lib.LLVMGetFirstInstruction(self) 269 return i and Instruction(i) 270 271 @property 272 def last(self): 273 i = lib.LLVMGetLastInstruction(self) 274 return i and Instruction(i) 275 276 def __as_value(self): 277 return Value(lib.LLVMBasicBlockAsValue(self)) 278 279 @property 280 def name(self): 281 return lib.LLVMGetValueName(self.__as_value()) 282 283 def dump(self): 284 lib.LLVMDumpValue(self.__as_value()) 285 286 def get_operand(self, i): 287 return Value(lib.LLVMGetOperand(self.__as_value(), 288 i)) 289 290 def set_operand(self, i, v): 291 return lib.LLVMSetOperand(self.__as_value(), 292 i, v) 293 294 def __len__(self): 295 return lib.LLVMGetNumOperands(self.__as_value()) 296 297 class __inst_iterator(object): 298 def __init__(self, bb, reverse=False): 299 self.bb = bb 300 self.reverse = reverse 301 if self.reverse: 302 self.inst = self.bb.last 303 else: 304 self.inst = self.bb.first 305 306 def __iter__(self): 307 return self 308 309 def next(self): 310 if not isinstance(self.inst, Instruction): 311 raise StopIteration("") 312 result = self.inst 313 if self.reverse: 314 self.inst = self.inst.prev 315 else: 316 self.inst = self.inst.next 317 return result 318 319 def __iter__(self): 320 return BasicBlock.__inst_iterator(self) 321 322 def __reversed__(self): 323 return BasicBlock.__inst_iterator(self, reverse=True) 324 325 326class Instruction(Value): 327 328 def __init__(self, value): 329 Value.__init__(self, value) 330 331 @property 332 def next(self): 333 i = lib.LLVMGetNextInstruction(self) 334 return i and Instruction(i) 335 336 @property 337 def prev(self): 338 i = lib.LLVMGetPreviousInstruction(self) 339 return i and Instruction(i) 340 341 @property 342 def opcode(self): 343 return OpCode.from_value(lib.LLVMGetInstructionOpcode(self)) 344 345class Context(LLVMObject): 346 347 def __init__(self, context=None): 348 if context is None: 349 context = lib.LLVMContextCreate() 350 LLVMObject.__init__(self, context, disposer=lib.LLVMContextDispose) 351 else: 352 LLVMObject.__init__(self, context) 353 354 @classmethod 355 def GetGlobalContext(cls): 356 return Context(lib.LLVMGetGlobalContext()) 357 358class PassRegistry(LLVMObject): 359 """Represents an opaque pass registry object.""" 360 361 def __init__(self): 362 LLVMObject.__init__(self, 363 lib.LLVMGetGlobalPassRegistry()) 364 365def register_library(library): 366 # Initialization/Shutdown declarations. 367 library.LLVMInitializeCore.argtypes = [PassRegistry] 368 library.LLVMInitializeCore.restype = None 369 370 library.LLVMInitializeTransformUtils.argtypes = [PassRegistry] 371 library.LLVMInitializeTransformUtils.restype = None 372 373 library.LLVMInitializeScalarOpts.argtypes = [PassRegistry] 374 library.LLVMInitializeScalarOpts.restype = None 375 376 library.LLVMInitializeObjCARCOpts.argtypes = [PassRegistry] 377 library.LLVMInitializeObjCARCOpts.restype = None 378 379 library.LLVMInitializeVectorization.argtypes = [PassRegistry] 380 library.LLVMInitializeVectorization.restype = None 381 382 library.LLVMInitializeInstCombine.argtypes = [PassRegistry] 383 library.LLVMInitializeInstCombine.restype = None 384 385 library.LLVMInitializeIPO.argtypes = [PassRegistry] 386 library.LLVMInitializeIPO.restype = None 387 388 library.LLVMInitializeInstrumentation.argtypes = [PassRegistry] 389 library.LLVMInitializeInstrumentation.restype = None 390 391 library.LLVMInitializeAnalysis.argtypes = [PassRegistry] 392 library.LLVMInitializeAnalysis.restype = None 393 394 library.LLVMInitializeIPA.argtypes = [PassRegistry] 395 library.LLVMInitializeIPA.restype = None 396 397 library.LLVMInitializeCodeGen.argtypes = [PassRegistry] 398 library.LLVMInitializeCodeGen.restype = None 399 400 library.LLVMInitializeTarget.argtypes = [PassRegistry] 401 library.LLVMInitializeTarget.restype = None 402 403 library.LLVMShutdown.argtypes = [] 404 library.LLVMShutdown.restype = None 405 406 # Pass Registry declarations. 407 library.LLVMGetGlobalPassRegistry.argtypes = [] 408 library.LLVMGetGlobalPassRegistry.restype = c_object_p 409 410 # Context declarations. 411 library.LLVMContextCreate.argtypes = [] 412 library.LLVMContextCreate.restype = c_object_p 413 414 library.LLVMContextDispose.argtypes = [Context] 415 library.LLVMContextDispose.restype = None 416 417 library.LLVMGetGlobalContext.argtypes = [] 418 library.LLVMGetGlobalContext.restype = c_object_p 419 420 # Memory buffer declarations 421 library.LLVMCreateMemoryBufferWithContentsOfFile.argtypes = [c_char_p, 422 POINTER(c_object_p), POINTER(c_char_p)] 423 library.LLVMCreateMemoryBufferWithContentsOfFile.restype = bool 424 425 library.LLVMGetBufferSize.argtypes = [MemoryBuffer] 426 427 library.LLVMDisposeMemoryBuffer.argtypes = [MemoryBuffer] 428 429 # Module declarations 430 library.LLVMModuleCreateWithName.argtypes = [c_char_p] 431 library.LLVMModuleCreateWithName.restype = c_object_p 432 433 library.LLVMDisposeModule.argtypes = [Module] 434 library.LLVMDisposeModule.restype = None 435 436 library.LLVMGetDataLayout.argtypes = [Module] 437 library.LLVMGetDataLayout.restype = c_char_p 438 439 library.LLVMSetDataLayout.argtypes = [Module, c_char_p] 440 library.LLVMSetDataLayout.restype = None 441 442 library.LLVMGetTarget.argtypes = [Module] 443 library.LLVMGetTarget.restype = c_char_p 444 445 library.LLVMSetTarget.argtypes = [Module, c_char_p] 446 library.LLVMSetTarget.restype = None 447 448 library.LLVMDumpModule.argtypes = [Module] 449 library.LLVMDumpModule.restype = None 450 451 library.LLVMPrintModuleToFile.argtypes = [Module, c_char_p, 452 POINTER(c_char_p)] 453 library.LLVMPrintModuleToFile.restype = bool 454 455 library.LLVMGetFirstFunction.argtypes = [Module] 456 library.LLVMGetFirstFunction.restype = c_object_p 457 458 library.LLVMGetLastFunction.argtypes = [Module] 459 library.LLVMGetLastFunction.restype = c_object_p 460 461 library.LLVMGetNextFunction.argtypes = [Function] 462 library.LLVMGetNextFunction.restype = c_object_p 463 464 library.LLVMGetPreviousFunction.argtypes = [Function] 465 library.LLVMGetPreviousFunction.restype = c_object_p 466 467 # Value declarations. 468 library.LLVMGetValueName.argtypes = [Value] 469 library.LLVMGetValueName.restype = c_char_p 470 471 library.LLVMDumpValue.argtypes = [Value] 472 library.LLVMDumpValue.restype = None 473 474 library.LLVMGetOperand.argtypes = [Value, c_uint] 475 library.LLVMGetOperand.restype = c_object_p 476 477 library.LLVMSetOperand.argtypes = [Value, Value, c_uint] 478 library.LLVMSetOperand.restype = None 479 480 library.LLVMGetNumOperands.argtypes = [Value] 481 library.LLVMGetNumOperands.restype = c_uint 482 483 # Basic Block Declarations. 484 library.LLVMGetFirstBasicBlock.argtypes = [Function] 485 library.LLVMGetFirstBasicBlock.restype = c_object_p 486 487 library.LLVMGetLastBasicBlock.argtypes = [Function] 488 library.LLVMGetLastBasicBlock.restype = c_object_p 489 490 library.LLVMGetNextBasicBlock.argtypes = [BasicBlock] 491 library.LLVMGetNextBasicBlock.restype = c_object_p 492 493 library.LLVMGetPreviousBasicBlock.argtypes = [BasicBlock] 494 library.LLVMGetPreviousBasicBlock.restype = c_object_p 495 496 library.LLVMGetFirstInstruction.argtypes = [BasicBlock] 497 library.LLVMGetFirstInstruction.restype = c_object_p 498 499 library.LLVMGetLastInstruction.argtypes = [BasicBlock] 500 library.LLVMGetLastInstruction.restype = c_object_p 501 502 library.LLVMBasicBlockAsValue.argtypes = [BasicBlock] 503 library.LLVMBasicBlockAsValue.restype = c_object_p 504 505 library.LLVMCountBasicBlocks.argtypes = [Function] 506 library.LLVMCountBasicBlocks.restype = c_uint 507 508 # Instruction Declarations. 509 library.LLVMGetNextInstruction.argtypes = [Instruction] 510 library.LLVMGetNextInstruction.restype = c_object_p 511 512 library.LLVMGetPreviousInstruction.argtypes = [Instruction] 513 library.LLVMGetPreviousInstruction.restype = c_object_p 514 515 library.LLVMGetInstructionOpcode.argtypes = [Instruction] 516 library.LLVMGetInstructionOpcode.restype = c_uint 517 518def register_enumerations(): 519 for name, value in enumerations.OpCodes: 520 OpCode.register(name, value) 521 522def initialize_llvm(): 523 c = Context.GetGlobalContext() 524 p = PassRegistry() 525 lib.LLVMInitializeCore(p) 526 lib.LLVMInitializeTransformUtils(p) 527 lib.LLVMInitializeScalarOpts(p) 528 lib.LLVMInitializeObjCARCOpts(p) 529 lib.LLVMInitializeVectorization(p) 530 lib.LLVMInitializeInstCombine(p) 531 lib.LLVMInitializeIPO(p) 532 lib.LLVMInitializeInstrumentation(p) 533 lib.LLVMInitializeAnalysis(p) 534 lib.LLVMInitializeIPA(p) 535 lib.LLVMInitializeCodeGen(p) 536 lib.LLVMInitializeTarget(p) 537 538register_library(lib) 539register_enumerations() 540initialize_llvm() 541