1 # Python bindings for Yasm: Pyrex input file for bytecode.h 2 # 3 # Copyright (C) 2006 Michael Urman, Peter Johnson 4 # 5 # Redistribution and use in source and binary forms, with or without 6 # modification, are permitted provided that the following conditions 7 # are met: 8 # 1. Redistributions of source code must retain the above copyright 9 # notice, this list of conditions and the following disclaimer. 10 # 2. Redistributions in binary form must reproduce the above copyright 11 # notice, this list of conditions and the following disclaimer in the 12 # documentation and/or other materials provided with the distribution. 13 # 14 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' 15 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE 18 # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 # POSSIBILITY OF SUCH DAMAGE. 25 26 cdef class Bytecode: 27 cdef yasm_bytecode *bc 28 29 cdef object __weakref__ # make weak-referenceable 30 31 def __cinit__(self, bc): 32 self.bc = NULL 33 if PyCObject_Check(bc): 34 self.bc = <yasm_bytecode *>__get_voidp(bc, Bytecode) 35 else: 36 raise NotImplementedError 37 38 def __dealloc__(self): 39 # Only free if we're not part of a section; if we're part of a section 40 # the section takes care of freeing the bytecodes. 41 if self.bc.section == NULL: 42 yasm_bc_destroy(self.bc) 43 44 property len: 45 def __get__(self): return self.bc.len 46 def __set__(self, value): self.bc.len = value 47 property mult_int: 48 def __get__(self): return self.bc.mult_int 49 def __set__(self, value): self.bc.mult_int = value 50 property line: 51 def __get__(self): return self.bc.line 52 def __set__(self, value): self.bc.line = value 53 property offset: 54 def __get__(self): return self.bc.offset 55 def __set__(self, value): self.bc.offset = value 56 property bc_index: 57 def __get__(self): return self.bc.bc_index 58 def __set__(self, value): self.bc.bc_index = value 59 property symbols: 60 # Someday extend this to do something modifiable, e.g. return a 61 # list-like object. 62 def __get__(self): 63 cdef yasm_symrec *sym 64 cdef int i 65 if self.bc.symrecs == NULL: 66 return [] 67 s = [] 68 i = 0 69 sym = self.bc.symrecs[i] 70 while sym != NULL: 71 s.append(__make_symbol(sym)) 72 i = i+1 73 sym = self.bc.symrecs[i] 74 return s 75 76 # 77 # Keep Bytecode reference paired with bc using weak references. 78 # This is broken in Pyrex 0.9.4.1; Pyrex 0.9.5 has a working version. 79 # 80 81 from weakref import WeakValueDictionary as __weakvaldict 82 __bytecode_map = __weakvaldict() 83 #__bytecode_map = {} 84 85 cdef object __make_bytecode(yasm_bytecode *bc): 86 __error_check() 87 vptr = PyCObject_FromVoidPtr(bc, NULL) 88 data = __bytecode_map.get(vptr, None) 89 if data: 90 return data 91 bcobj = Bytecode(__pass_voidp(bc, Bytecode)) 92 __bytecode_map[vptr] = bcobj 93 return bcobj 94 95 # Org bytecode 96 def __org__new__(cls, start, value=0, line=0): 97 cdef yasm_bytecode *bc 98 bc = yasm_bc_create_org(start, line, value) 99 obj = Bytecode.__new__(cls, __pass_voidp(bc, Bytecode)) 100 __bytecode_map[PyCObject_FromVoidPtr(bc, NULL)] = obj 101 return obj 102 __org__new__ = staticmethod(__org__new__) 103 class Org(Bytecode): 104 __new__ = __org__new__ 105 106 107 #cdef class Section: 108