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