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 26cdef 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 81from weakref import WeakValueDictionary as __weakvaldict 82__bytecode_map = __weakvaldict() 83#__bytecode_map = {} 84 85cdef 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 96def __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__) 103class Org(Bytecode): 104 __new__ = __org__new__ 105 106 107#cdef class Section: 108