Home | History | Annotate | Download | only in python-yasm
      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