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:]