• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1from .error import VerificationError
2
3class CffiOp(object):
4    def __init__(self, op, arg):
5        self.op = op
6        self.arg = arg
7
8    def as_c_expr(self):
9        if self.op is None:
10            assert isinstance(self.arg, str)
11            return '(_cffi_opcode_t)(%s)' % (self.arg,)
12        classname = CLASS_NAME[self.op]
13        return '_CFFI_OP(_CFFI_OP_%s, %s)' % (classname, self.arg)
14
15    def as_python_bytes(self):
16        if self.op is None and self.arg.isdigit():
17            value = int(self.arg)     # non-negative: '-' not in self.arg
18            if value >= 2**31:
19                raise OverflowError("cannot emit %r: limited to 2**31-1"
20                                    % (self.arg,))
21            return format_four_bytes(value)
22        if isinstance(self.arg, str):
23            raise VerificationError("cannot emit to Python: %r" % (self.arg,))
24        return format_four_bytes((self.arg << 8) | self.op)
25
26    def __str__(self):
27        classname = CLASS_NAME.get(self.op, self.op)
28        return '(%s %s)' % (classname, self.arg)
29
30def format_four_bytes(num):
31    return '\\x%02X\\x%02X\\x%02X\\x%02X' % (
32        (num >> 24) & 0xFF,
33        (num >> 16) & 0xFF,
34        (num >>  8) & 0xFF,
35        (num      ) & 0xFF)
36
37OP_PRIMITIVE       = 1
38OP_POINTER         = 3
39OP_ARRAY           = 5
40OP_OPEN_ARRAY      = 7
41OP_STRUCT_UNION    = 9
42OP_ENUM            = 11
43OP_FUNCTION        = 13
44OP_FUNCTION_END    = 15
45OP_NOOP            = 17
46OP_BITFIELD        = 19
47OP_TYPENAME        = 21
48OP_CPYTHON_BLTN_V  = 23   # varargs
49OP_CPYTHON_BLTN_N  = 25   # noargs
50OP_CPYTHON_BLTN_O  = 27   # O  (i.e. a single arg)
51OP_CONSTANT        = 29
52OP_CONSTANT_INT    = 31
53OP_GLOBAL_VAR      = 33
54OP_DLOPEN_FUNC     = 35
55OP_DLOPEN_CONST    = 37
56OP_GLOBAL_VAR_F    = 39
57OP_EXTERN_PYTHON   = 41
58
59PRIM_VOID          = 0
60PRIM_BOOL          = 1
61PRIM_CHAR          = 2
62PRIM_SCHAR         = 3
63PRIM_UCHAR         = 4
64PRIM_SHORT         = 5
65PRIM_USHORT        = 6
66PRIM_INT           = 7
67PRIM_UINT          = 8
68PRIM_LONG          = 9
69PRIM_ULONG         = 10
70PRIM_LONGLONG      = 11
71PRIM_ULONGLONG     = 12
72PRIM_FLOAT         = 13
73PRIM_DOUBLE        = 14
74PRIM_LONGDOUBLE    = 15
75
76PRIM_WCHAR         = 16
77PRIM_INT8          = 17
78PRIM_UINT8         = 18
79PRIM_INT16         = 19
80PRIM_UINT16        = 20
81PRIM_INT32         = 21
82PRIM_UINT32        = 22
83PRIM_INT64         = 23
84PRIM_UINT64        = 24
85PRIM_INTPTR        = 25
86PRIM_UINTPTR       = 26
87PRIM_PTRDIFF       = 27
88PRIM_SIZE          = 28
89PRIM_SSIZE         = 29
90PRIM_INT_LEAST8    = 30
91PRIM_UINT_LEAST8   = 31
92PRIM_INT_LEAST16   = 32
93PRIM_UINT_LEAST16  = 33
94PRIM_INT_LEAST32   = 34
95PRIM_UINT_LEAST32  = 35
96PRIM_INT_LEAST64   = 36
97PRIM_UINT_LEAST64  = 37
98PRIM_INT_FAST8     = 38
99PRIM_UINT_FAST8    = 39
100PRIM_INT_FAST16    = 40
101PRIM_UINT_FAST16   = 41
102PRIM_INT_FAST32    = 42
103PRIM_UINT_FAST32   = 43
104PRIM_INT_FAST64    = 44
105PRIM_UINT_FAST64   = 45
106PRIM_INTMAX        = 46
107PRIM_UINTMAX       = 47
108PRIM_FLOATCOMPLEX  = 48
109PRIM_DOUBLECOMPLEX = 49
110PRIM_CHAR16        = 50
111PRIM_CHAR32        = 51
112
113_NUM_PRIM          = 52
114_UNKNOWN_PRIM          = -1
115_UNKNOWN_FLOAT_PRIM    = -2
116_UNKNOWN_LONG_DOUBLE   = -3
117
118_IO_FILE_STRUCT        = -1
119
120PRIMITIVE_TO_INDEX = {
121    'char':               PRIM_CHAR,
122    'short':              PRIM_SHORT,
123    'int':                PRIM_INT,
124    'long':               PRIM_LONG,
125    'long long':          PRIM_LONGLONG,
126    'signed char':        PRIM_SCHAR,
127    'unsigned char':      PRIM_UCHAR,
128    'unsigned short':     PRIM_USHORT,
129    'unsigned int':       PRIM_UINT,
130    'unsigned long':      PRIM_ULONG,
131    'unsigned long long': PRIM_ULONGLONG,
132    'float':              PRIM_FLOAT,
133    'double':             PRIM_DOUBLE,
134    'long double':        PRIM_LONGDOUBLE,
135    'float _Complex':     PRIM_FLOATCOMPLEX,
136    'double _Complex':    PRIM_DOUBLECOMPLEX,
137    '_Bool':              PRIM_BOOL,
138    'wchar_t':            PRIM_WCHAR,
139    'char16_t':           PRIM_CHAR16,
140    'char32_t':           PRIM_CHAR32,
141    'int8_t':             PRIM_INT8,
142    'uint8_t':            PRIM_UINT8,
143    'int16_t':            PRIM_INT16,
144    'uint16_t':           PRIM_UINT16,
145    'int32_t':            PRIM_INT32,
146    'uint32_t':           PRIM_UINT32,
147    'int64_t':            PRIM_INT64,
148    'uint64_t':           PRIM_UINT64,
149    'intptr_t':           PRIM_INTPTR,
150    'uintptr_t':          PRIM_UINTPTR,
151    'ptrdiff_t':          PRIM_PTRDIFF,
152    'size_t':             PRIM_SIZE,
153    'ssize_t':            PRIM_SSIZE,
154    'int_least8_t':       PRIM_INT_LEAST8,
155    'uint_least8_t':      PRIM_UINT_LEAST8,
156    'int_least16_t':      PRIM_INT_LEAST16,
157    'uint_least16_t':     PRIM_UINT_LEAST16,
158    'int_least32_t':      PRIM_INT_LEAST32,
159    'uint_least32_t':     PRIM_UINT_LEAST32,
160    'int_least64_t':      PRIM_INT_LEAST64,
161    'uint_least64_t':     PRIM_UINT_LEAST64,
162    'int_fast8_t':        PRIM_INT_FAST8,
163    'uint_fast8_t':       PRIM_UINT_FAST8,
164    'int_fast16_t':       PRIM_INT_FAST16,
165    'uint_fast16_t':      PRIM_UINT_FAST16,
166    'int_fast32_t':       PRIM_INT_FAST32,
167    'uint_fast32_t':      PRIM_UINT_FAST32,
168    'int_fast64_t':       PRIM_INT_FAST64,
169    'uint_fast64_t':      PRIM_UINT_FAST64,
170    'intmax_t':           PRIM_INTMAX,
171    'uintmax_t':          PRIM_UINTMAX,
172    }
173
174F_UNION         = 0x01
175F_CHECK_FIELDS  = 0x02
176F_PACKED        = 0x04
177F_EXTERNAL      = 0x08
178F_OPAQUE        = 0x10
179
180G_FLAGS = dict([('_CFFI_' + _key, globals()[_key])
181                for _key in ['F_UNION', 'F_CHECK_FIELDS', 'F_PACKED',
182                             'F_EXTERNAL', 'F_OPAQUE']])
183
184CLASS_NAME = {}
185for _name, _value in list(globals().items()):
186    if _name.startswith('OP_') and isinstance(_value, int):
187        CLASS_NAME[_value] = _name[3:]
188