cffi_opcode.py 5.8 KB

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